17c478bd9Sstevel@tonic-gate %{
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California.
47c478bd9Sstevel@tonic-gate * All rights reserved.
57c478bd9Sstevel@tonic-gate *
67c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted
77c478bd9Sstevel@tonic-gate * provided that the above copyright notice and this paragraph are
87c478bd9Sstevel@tonic-gate * duplicated in all such forms and that any documentation,
97c478bd9Sstevel@tonic-gate * advertising materials, and other materials related to such
107c478bd9Sstevel@tonic-gate * distribution and use acknowledge that the software was developed
117c478bd9Sstevel@tonic-gate * by the University of California, Berkeley. The name of the
127c478bd9Sstevel@tonic-gate * University may not be used to endorse or promote products derived
137c478bd9Sstevel@tonic-gate * from this software without specific prior written permission.
147c478bd9Sstevel@tonic-gate *
157c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
167c478bd9Sstevel@tonic-gate * Use is subject to license terms.
177c478bd9Sstevel@tonic-gate */
187c478bd9Sstevel@tonic-gate
197c478bd9Sstevel@tonic-gate #include "defs.h"
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gate struct cmd *cmds = NULL;
227c478bd9Sstevel@tonic-gate struct cmd *last_cmd;
237c478bd9Sstevel@tonic-gate struct namelist *last_n;
247c478bd9Sstevel@tonic-gate struct subcmd *last_sc;
257c478bd9Sstevel@tonic-gate
26740638c8Sbw static void append(char *label, struct namelist *files, char *stamp,
27740638c8Sbw struct subcmd *subcmds);
28740638c8Sbw void yyerror(char *s);
29740638c8Sbw
307c478bd9Sstevel@tonic-gate %}
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate %term EQUAL 1
337c478bd9Sstevel@tonic-gate %term LP 2
347c478bd9Sstevel@tonic-gate %term RP 3
357c478bd9Sstevel@tonic-gate %term SM 4
367c478bd9Sstevel@tonic-gate %term ARROW 5
377c478bd9Sstevel@tonic-gate %term COLON 6
387c478bd9Sstevel@tonic-gate %term DCOLON 7
397c478bd9Sstevel@tonic-gate %term NAME 8
407c478bd9Sstevel@tonic-gate %term STRING 9
417c478bd9Sstevel@tonic-gate %term INSTALL 10
427c478bd9Sstevel@tonic-gate %term NOTIFY 11
437c478bd9Sstevel@tonic-gate %term EXCEPT 12
447c478bd9Sstevel@tonic-gate %term PATTERN 13
457c478bd9Sstevel@tonic-gate %term SPECIAL 14
467c478bd9Sstevel@tonic-gate %term OPTION 15
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate %union {
497c478bd9Sstevel@tonic-gate int intval;
507c478bd9Sstevel@tonic-gate char *string;
517c478bd9Sstevel@tonic-gate struct subcmd *subcmd;
527c478bd9Sstevel@tonic-gate struct namelist *namel;
537c478bd9Sstevel@tonic-gate }
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate %type <intval> OPTION, options
567c478bd9Sstevel@tonic-gate %type <string> NAME, STRING
577c478bd9Sstevel@tonic-gate %type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd
587c478bd9Sstevel@tonic-gate %type <namel> namelist, names, opt_namelist
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate %%
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate file: /* VOID */
637c478bd9Sstevel@tonic-gate | file command
647c478bd9Sstevel@tonic-gate ;
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate command: NAME EQUAL namelist = {
677c478bd9Sstevel@tonic-gate (void) lookup($1, INSERT, $3);
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate | namelist ARROW namelist cmdlist = {
707c478bd9Sstevel@tonic-gate insert(NULL, $1, $3, $4);
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate | NAME COLON namelist ARROW namelist cmdlist = {
737c478bd9Sstevel@tonic-gate insert($1, $3, $5, $6);
747c478bd9Sstevel@tonic-gate }
757c478bd9Sstevel@tonic-gate | namelist DCOLON NAME cmdlist = {
767c478bd9Sstevel@tonic-gate append(NULL, $1, $3, $4);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate | NAME COLON namelist DCOLON NAME cmdlist = {
797c478bd9Sstevel@tonic-gate append($1, $3, $5, $6);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate | error
827c478bd9Sstevel@tonic-gate ;
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate namelist: NAME = {
857c478bd9Sstevel@tonic-gate $$ = makenl($1);
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate | LP names RP = {
887c478bd9Sstevel@tonic-gate $$ = $2;
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate ;
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate names: /* VOID */ {
937c478bd9Sstevel@tonic-gate $$ = last_n = NULL;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate | names NAME = {
967c478bd9Sstevel@tonic-gate if (last_n == NULL)
977c478bd9Sstevel@tonic-gate $$ = last_n = makenl($2);
987c478bd9Sstevel@tonic-gate else {
997c478bd9Sstevel@tonic-gate last_n->n_next = makenl($2);
1007c478bd9Sstevel@tonic-gate last_n = last_n->n_next;
1017c478bd9Sstevel@tonic-gate $$ = $1;
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate ;
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate cmdlist: /* VOID */ {
1077c478bd9Sstevel@tonic-gate $$ = last_sc = NULL;
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate | cmdlist cmd = {
1107c478bd9Sstevel@tonic-gate if (last_sc == NULL)
1117c478bd9Sstevel@tonic-gate $$ = last_sc = $2;
1127c478bd9Sstevel@tonic-gate else {
1137c478bd9Sstevel@tonic-gate last_sc->sc_next = $2;
1147c478bd9Sstevel@tonic-gate last_sc = $2;
1157c478bd9Sstevel@tonic-gate $$ = $1;
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate ;
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate cmd: INSTALL options opt_namelist SM = {
1217c478bd9Sstevel@tonic-gate register struct namelist *nl;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate $1->sc_options = $2 | options;
1247c478bd9Sstevel@tonic-gate if ($3 != NULL) {
1257c478bd9Sstevel@tonic-gate nl = expand($3, E_VARS);
1267c478bd9Sstevel@tonic-gate if (nl && nl->n_next != NULL)
1277c478bd9Sstevel@tonic-gate yyerror("only one name allowed\n");
1287c478bd9Sstevel@tonic-gate $1->sc_name = nl ? nl->n_name: NULL;
1297c478bd9Sstevel@tonic-gate if (nl)
1307c478bd9Sstevel@tonic-gate free(nl);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate $$ = $1;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate | NOTIFY namelist SM = {
1357c478bd9Sstevel@tonic-gate if ($2 != NULL)
1367c478bd9Sstevel@tonic-gate $1->sc_args = expand($2, E_VARS);
1377c478bd9Sstevel@tonic-gate $$ = $1;
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate | EXCEPT namelist SM = {
1407c478bd9Sstevel@tonic-gate if ($2 != NULL)
1417c478bd9Sstevel@tonic-gate $1->sc_args = expand($2, E_ALL);
1427c478bd9Sstevel@tonic-gate $$ = $1;
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate | PATTERN namelist SM = {
1457c478bd9Sstevel@tonic-gate struct namelist *nl;
1467c478bd9Sstevel@tonic-gate char *cp, *re_comp();
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate * We dup the namelist in $2 because expand()
1507c478bd9Sstevel@tonic-gate * destroys the list referred to in its first
1517c478bd9Sstevel@tonic-gate * argument.
1527c478bd9Sstevel@tonic-gate */
1537c478bd9Sstevel@tonic-gate for (nl = expand(dupnl($2), E_VARS); nl != NULL;
1547c478bd9Sstevel@tonic-gate nl = nl->n_next)
1557c478bd9Sstevel@tonic-gate if ((cp = re_comp(nl->n_name)) != NULL)
1567c478bd9Sstevel@tonic-gate yyerror(cp);
1577c478bd9Sstevel@tonic-gate $1->sc_args = expand($2, E_VARS);
1587c478bd9Sstevel@tonic-gate $$ = $1;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate | SPECIAL opt_namelist STRING SM = {
1617c478bd9Sstevel@tonic-gate if ($2 != NULL)
1627c478bd9Sstevel@tonic-gate $1->sc_args = expand($2, E_ALL);
1637c478bd9Sstevel@tonic-gate $1->sc_name = $3;
1647c478bd9Sstevel@tonic-gate $$ = $1;
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate ;
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate options: /* VOID */ = {
1697c478bd9Sstevel@tonic-gate $$ = 0;
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate | options OPTION = {
1727c478bd9Sstevel@tonic-gate $$ |= $2;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate ;
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate opt_namelist: /* VOID */ = {
1777c478bd9Sstevel@tonic-gate $$ = NULL;
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate | namelist = {
1807c478bd9Sstevel@tonic-gate $$ = $1;
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate ;
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate %%
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate int yylineno = 1;
1877c478bd9Sstevel@tonic-gate extern FILE *fin;
1887c478bd9Sstevel@tonic-gate
189740638c8Sbw int
yylex()1907c478bd9Sstevel@tonic-gate yylex()
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate static char yytext[INMAX];
1937c478bd9Sstevel@tonic-gate register int c;
1947c478bd9Sstevel@tonic-gate register char *cp1, *cp2;
1957c478bd9Sstevel@tonic-gate static char quotechars[] = "[]{}*?$";
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate again:
1987c478bd9Sstevel@tonic-gate switch (c = getc(fin)) {
1997c478bd9Sstevel@tonic-gate case EOF: /* end of file */
2007c478bd9Sstevel@tonic-gate return(0);
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate case '#': /* start of comment */
2037c478bd9Sstevel@tonic-gate while ((c = getc(fin)) != EOF && c != '\n')
2047c478bd9Sstevel@tonic-gate ;
2057c478bd9Sstevel@tonic-gate if (c == EOF)
2067c478bd9Sstevel@tonic-gate return(0);
207*c15ff06aSToomas Soome /* FALLTHROUGH */
2087c478bd9Sstevel@tonic-gate case '\n':
2097c478bd9Sstevel@tonic-gate yylineno++;
2107c478bd9Sstevel@tonic-gate case ' ':
2117c478bd9Sstevel@tonic-gate case '\t': /* skip blanks */
2127c478bd9Sstevel@tonic-gate goto again;
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate case '=': /* EQUAL */
2157c478bd9Sstevel@tonic-gate return(EQUAL);
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate case '(': /* LP */
2187c478bd9Sstevel@tonic-gate return(LP);
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate case ')': /* RP */
2217c478bd9Sstevel@tonic-gate return(RP);
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate case ';': /* SM */
2247c478bd9Sstevel@tonic-gate return(SM);
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate case '-': /* -> */
2277c478bd9Sstevel@tonic-gate if ((c = getc(fin)) == '>')
2287c478bd9Sstevel@tonic-gate return(ARROW);
2297c478bd9Sstevel@tonic-gate ungetc(c, fin);
2307c478bd9Sstevel@tonic-gate c = '-';
2317c478bd9Sstevel@tonic-gate break;
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate case '"': /* STRING */
2347c478bd9Sstevel@tonic-gate cp1 = yytext;
2357c478bd9Sstevel@tonic-gate cp2 = &yytext[INMAX - 1];
2367c478bd9Sstevel@tonic-gate for (;;) {
2377c478bd9Sstevel@tonic-gate if (cp1 >= cp2) {
2387c478bd9Sstevel@tonic-gate yyerror("command string too long\n");
2397c478bd9Sstevel@tonic-gate break;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate c = getc(fin);
2427c478bd9Sstevel@tonic-gate if (c == EOF || c == '"')
2437c478bd9Sstevel@tonic-gate break;
2447c478bd9Sstevel@tonic-gate if (c == '\\') {
2457c478bd9Sstevel@tonic-gate if ((c = getc(fin)) == EOF) {
2467c478bd9Sstevel@tonic-gate *cp1++ = '\\';
2477c478bd9Sstevel@tonic-gate break;
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate if (c == '\n') {
2517c478bd9Sstevel@tonic-gate yylineno++;
2527c478bd9Sstevel@tonic-gate c = ' '; /* can't send '\n' */
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate *cp1++ = c;
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate if (c != '"')
2577c478bd9Sstevel@tonic-gate yyerror("missing closing '\"'\n");
2587c478bd9Sstevel@tonic-gate *cp1 = '\0';
2597c478bd9Sstevel@tonic-gate yylval.string = makestr(yytext);
2607c478bd9Sstevel@tonic-gate return(STRING);
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate case ':': /* : or :: */
2637c478bd9Sstevel@tonic-gate if ((c = getc(fin)) == ':')
2647c478bd9Sstevel@tonic-gate return(DCOLON);
2657c478bd9Sstevel@tonic-gate ungetc(c, fin);
2667c478bd9Sstevel@tonic-gate return(COLON);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate cp1 = yytext;
2697c478bd9Sstevel@tonic-gate cp2 = &yytext[INMAX - 1];
2707c478bd9Sstevel@tonic-gate for (;;) {
2717c478bd9Sstevel@tonic-gate if (cp1 >= cp2) {
2727c478bd9Sstevel@tonic-gate yyerror("input line too long\n");
2737c478bd9Sstevel@tonic-gate break;
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate if (c == '\\') {
2767c478bd9Sstevel@tonic-gate if ((c = getc(fin)) != EOF) {
2777c478bd9Sstevel@tonic-gate if (any(c, quotechars))
2787c478bd9Sstevel@tonic-gate c |= QUOTE;
2797c478bd9Sstevel@tonic-gate } else {
2807c478bd9Sstevel@tonic-gate *cp1++ = '\\';
2817c478bd9Sstevel@tonic-gate break;
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate }
2847c478bd9Sstevel@tonic-gate *cp1++ = c;
2857c478bd9Sstevel@tonic-gate c = getc(fin);
2867c478bd9Sstevel@tonic-gate if (c == EOF || any(c, " \"'\t()=;:\n")) {
2877c478bd9Sstevel@tonic-gate ungetc(c, fin);
2887c478bd9Sstevel@tonic-gate break;
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate *cp1 = '\0';
2927c478bd9Sstevel@tonic-gate if (yytext[0] == '-' && yytext[2] == '\0') {
2937c478bd9Sstevel@tonic-gate switch (yytext[1]) {
2947c478bd9Sstevel@tonic-gate case 'b':
2957c478bd9Sstevel@tonic-gate yylval.intval = COMPARE;
2967c478bd9Sstevel@tonic-gate return(OPTION);
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate case 'R':
2997c478bd9Sstevel@tonic-gate yylval.intval = REMOVE;
3007c478bd9Sstevel@tonic-gate return(OPTION);
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate case 'v':
3037c478bd9Sstevel@tonic-gate yylval.intval = VERIFY;
3047c478bd9Sstevel@tonic-gate return(OPTION);
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate case 'w':
3077c478bd9Sstevel@tonic-gate yylval.intval = WHOLE;
3087c478bd9Sstevel@tonic-gate return(OPTION);
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate case 'y':
3117c478bd9Sstevel@tonic-gate yylval.intval = YOUNGER;
3127c478bd9Sstevel@tonic-gate return(OPTION);
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate case 'h':
3157c478bd9Sstevel@tonic-gate yylval.intval = FOLLOW;
3167c478bd9Sstevel@tonic-gate return(OPTION);
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate case 'i':
3197c478bd9Sstevel@tonic-gate yylval.intval = IGNLNKS;
3207c478bd9Sstevel@tonic-gate return(OPTION);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate if (!strcmp(yytext, "install"))
3247c478bd9Sstevel@tonic-gate c = INSTALL;
3257c478bd9Sstevel@tonic-gate else if (!strcmp(yytext, "notify"))
3267c478bd9Sstevel@tonic-gate c = NOTIFY;
3277c478bd9Sstevel@tonic-gate else if (!strcmp(yytext, "except"))
3287c478bd9Sstevel@tonic-gate c = EXCEPT;
3297c478bd9Sstevel@tonic-gate else if (!strcmp(yytext, "except_pat"))
3307c478bd9Sstevel@tonic-gate c = PATTERN;
3317c478bd9Sstevel@tonic-gate else if (!strcmp(yytext, "special"))
3327c478bd9Sstevel@tonic-gate c = SPECIAL;
3337c478bd9Sstevel@tonic-gate else {
3347c478bd9Sstevel@tonic-gate yylval.string = makestr(yytext);
3357c478bd9Sstevel@tonic-gate return(NAME);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate yylval.subcmd = makesubcmd(c);
3387c478bd9Sstevel@tonic-gate return(c);
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate
341740638c8Sbw int
any(c,str)3427c478bd9Sstevel@tonic-gate any(c, str)
3437c478bd9Sstevel@tonic-gate register int c;
3447c478bd9Sstevel@tonic-gate register char *str;
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate while (*str)
3477c478bd9Sstevel@tonic-gate if (c == *str++)
3487c478bd9Sstevel@tonic-gate return(1);
3497c478bd9Sstevel@tonic-gate return(0);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate /*
3537c478bd9Sstevel@tonic-gate * Insert or append ARROW command to list of hosts to be updated.
3547c478bd9Sstevel@tonic-gate */
355740638c8Sbw void
insert(label,files,hosts,subcmds)3567c478bd9Sstevel@tonic-gate insert(label, files, hosts, subcmds)
3577c478bd9Sstevel@tonic-gate char *label;
3587c478bd9Sstevel@tonic-gate struct namelist *files, *hosts;
3597c478bd9Sstevel@tonic-gate struct subcmd *subcmds;
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate register struct cmd *c, *prev, *nc;
3627c478bd9Sstevel@tonic-gate register struct namelist *h, *oldh;
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate files = expand(files, E_VARS|E_SHELL);
3657c478bd9Sstevel@tonic-gate hosts = expand(hosts, E_ALL);
3667c478bd9Sstevel@tonic-gate if (debug) {
3677c478bd9Sstevel@tonic-gate printf("insert: files = ");
3687c478bd9Sstevel@tonic-gate prnames(files);
3697c478bd9Sstevel@tonic-gate printf("insert: hosts = ");
3707c478bd9Sstevel@tonic-gate prnames(hosts);
3717c478bd9Sstevel@tonic-gate if (cmds)
3727c478bd9Sstevel@tonic-gate prcmd(cmds);
3737c478bd9Sstevel@tonic-gate else
3747c478bd9Sstevel@tonic-gate printf("insert: cmds NULL\n");
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate for (h = hosts; h != NULL; oldh = h, h = h->n_next, free(oldh)) {
3777c478bd9Sstevel@tonic-gate /*
3787c478bd9Sstevel@tonic-gate * Search command list for an update to the same host.
3797c478bd9Sstevel@tonic-gate */
3807c478bd9Sstevel@tonic-gate for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
3817c478bd9Sstevel@tonic-gate if (strcmp(c->c_name, h->n_name) == 0) {
3827c478bd9Sstevel@tonic-gate do {
3837c478bd9Sstevel@tonic-gate prev = c;
3847c478bd9Sstevel@tonic-gate c = c->c_next;
3857c478bd9Sstevel@tonic-gate } while (c != NULL &&
3867c478bd9Sstevel@tonic-gate strcmp(c->c_name, h->n_name) == 0);
3877c478bd9Sstevel@tonic-gate break;
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate /*
3917c478bd9Sstevel@tonic-gate * Insert new command to update host.
3927c478bd9Sstevel@tonic-gate */
3937c478bd9Sstevel@tonic-gate nc = ALLOC(cmd);
3947c478bd9Sstevel@tonic-gate if (nc == NULL)
3957c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
3967c478bd9Sstevel@tonic-gate nc->c_type = ARROW;
3977c478bd9Sstevel@tonic-gate nc->c_name = h->n_name;
3987c478bd9Sstevel@tonic-gate nc->c_label = label;
3997c478bd9Sstevel@tonic-gate nc->c_files = files;
4007c478bd9Sstevel@tonic-gate nc->c_cmds = subcmds;
4017c478bd9Sstevel@tonic-gate nc->c_next = c;
4027c478bd9Sstevel@tonic-gate if (prev == NULL)
4037c478bd9Sstevel@tonic-gate cmds = nc;
4047c478bd9Sstevel@tonic-gate else
4057c478bd9Sstevel@tonic-gate prev->c_next = nc;
4067c478bd9Sstevel@tonic-gate /* update last_cmd if appending nc to cmds */
4077c478bd9Sstevel@tonic-gate if (c == NULL)
4087c478bd9Sstevel@tonic-gate last_cmd = nc;
4097c478bd9Sstevel@tonic-gate }
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate /*
4137c478bd9Sstevel@tonic-gate * Append DCOLON command to the end of the command list since these are always
4147c478bd9Sstevel@tonic-gate * executed in the order they appear in the distfile.
4157c478bd9Sstevel@tonic-gate */
416740638c8Sbw static void
append(label,files,stamp,subcmds)4177c478bd9Sstevel@tonic-gate append(label, files, stamp, subcmds)
4187c478bd9Sstevel@tonic-gate char *label;
4197c478bd9Sstevel@tonic-gate struct namelist *files;
4207c478bd9Sstevel@tonic-gate char *stamp;
4217c478bd9Sstevel@tonic-gate struct subcmd *subcmds;
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate register struct cmd *c;
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate c = ALLOC(cmd);
4267c478bd9Sstevel@tonic-gate if (c == NULL)
4277c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
4287c478bd9Sstevel@tonic-gate c->c_type = DCOLON;
4297c478bd9Sstevel@tonic-gate c->c_name = stamp;
4307c478bd9Sstevel@tonic-gate c->c_label = label;
4317c478bd9Sstevel@tonic-gate c->c_files = expand(files, E_ALL);
4327c478bd9Sstevel@tonic-gate c->c_cmds = subcmds;
4337c478bd9Sstevel@tonic-gate c->c_next = NULL;
4347c478bd9Sstevel@tonic-gate if (cmds == NULL)
4357c478bd9Sstevel@tonic-gate cmds = last_cmd = c;
4367c478bd9Sstevel@tonic-gate else {
4377c478bd9Sstevel@tonic-gate last_cmd->c_next = c;
4387c478bd9Sstevel@tonic-gate last_cmd = c;
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate }
4417c478bd9Sstevel@tonic-gate
4427c478bd9Sstevel@tonic-gate /*
4437c478bd9Sstevel@tonic-gate * Error printing routine in parser.
4447c478bd9Sstevel@tonic-gate */
445740638c8Sbw void
yyerror(s)4467c478bd9Sstevel@tonic-gate yyerror(s)
4477c478bd9Sstevel@tonic-gate char *s;
4487c478bd9Sstevel@tonic-gate {
4497c478bd9Sstevel@tonic-gate extern int yychar;
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate nerrs++;
4527c478bd9Sstevel@tonic-gate fflush(stdout);
4537c478bd9Sstevel@tonic-gate fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate /*
4577c478bd9Sstevel@tonic-gate * Return a copy of the string.
4587c478bd9Sstevel@tonic-gate */
4597c478bd9Sstevel@tonic-gate char *
makestr(str)4607c478bd9Sstevel@tonic-gate makestr(str)
4617c478bd9Sstevel@tonic-gate char *str;
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate register char *cp, *s;
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate str = cp = malloc(strlen(s = str) + 1);
4667c478bd9Sstevel@tonic-gate if (cp == NULL)
4677c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
4687c478bd9Sstevel@tonic-gate while (*cp++ = *s++)
4697c478bd9Sstevel@tonic-gate ;
4707c478bd9Sstevel@tonic-gate return(str);
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /*
4747c478bd9Sstevel@tonic-gate * Allocate a namelist structure.
4757c478bd9Sstevel@tonic-gate */
4767c478bd9Sstevel@tonic-gate struct namelist *
makenl(name)4777c478bd9Sstevel@tonic-gate makenl(name)
4787c478bd9Sstevel@tonic-gate char *name;
4797c478bd9Sstevel@tonic-gate {
4807c478bd9Sstevel@tonic-gate register struct namelist *nl;
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate nl = ALLOC(namelist);
4837c478bd9Sstevel@tonic-gate if (nl == NULL)
4847c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
4857c478bd9Sstevel@tonic-gate nl->n_name = name;
4867c478bd9Sstevel@tonic-gate nl->n_next = NULL;
4877c478bd9Sstevel@tonic-gate return(nl);
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate /*
4917c478bd9Sstevel@tonic-gate * Duplicate an existing namelist structure. Only used by the PATTERN
4927c478bd9Sstevel@tonic-gate * code, and then only because expand() is destructive.
4937c478bd9Sstevel@tonic-gate */
4947c478bd9Sstevel@tonic-gate struct namelist *
dupnl(old)4957c478bd9Sstevel@tonic-gate dupnl(old)
4967c478bd9Sstevel@tonic-gate struct namelist *old;
4977c478bd9Sstevel@tonic-gate {
4987c478bd9Sstevel@tonic-gate struct namelist *n;
4997c478bd9Sstevel@tonic-gate struct namelist *new, *newhead = (struct namelist *) NULL;
5007c478bd9Sstevel@tonic-gate struct namelist *prev = (struct namelist *) NULL;
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate for (n = old; n; n = n->n_next) {
5037c478bd9Sstevel@tonic-gate new = ALLOC(namelist);
5047c478bd9Sstevel@tonic-gate if (new == (struct namelist *) NULL)
5057c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
5067c478bd9Sstevel@tonic-gate if (newhead == (struct namelist *) NULL)
5077c478bd9Sstevel@tonic-gate newhead = new;
5087c478bd9Sstevel@tonic-gate if (n->n_name) {
5097c478bd9Sstevel@tonic-gate if ((new->n_name = strdup(n->n_name)) == (char *) NULL)
5107c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
5117c478bd9Sstevel@tonic-gate } else
5127c478bd9Sstevel@tonic-gate new->n_name = (char *) NULL;
5137c478bd9Sstevel@tonic-gate if (prev)
5147c478bd9Sstevel@tonic-gate prev->n_next = new;
5157c478bd9Sstevel@tonic-gate prev = new;
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate if (prev)
5187c478bd9Sstevel@tonic-gate prev->n_next = (struct namelist *) NULL;
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate return (newhead);
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate /*
5247c478bd9Sstevel@tonic-gate * Make a sub command for lists of variables, commands, etc.
5257c478bd9Sstevel@tonic-gate */
5267c478bd9Sstevel@tonic-gate struct subcmd *
makesubcmd(type,name)5277c478bd9Sstevel@tonic-gate makesubcmd(type, name)
5287c478bd9Sstevel@tonic-gate int type;
5297c478bd9Sstevel@tonic-gate register char *name;
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate register char *cp;
5327c478bd9Sstevel@tonic-gate register struct subcmd *sc;
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate sc = ALLOC(subcmd);
5357c478bd9Sstevel@tonic-gate if (sc == NULL)
5367c478bd9Sstevel@tonic-gate fatal("ran out of memory\n");
5377c478bd9Sstevel@tonic-gate sc->sc_type = type;
5387c478bd9Sstevel@tonic-gate sc->sc_args = NULL;
5397c478bd9Sstevel@tonic-gate sc->sc_next = NULL;
5407c478bd9Sstevel@tonic-gate sc->sc_name = NULL;
5417c478bd9Sstevel@tonic-gate return(sc);
5427c478bd9Sstevel@tonic-gate }
543