xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.bin/rdist/gram.y (revision 1a90c98d7539778aeb0a1d20f735b66aaba17fca)
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);
28*1a90c98dSToomas Soome int yyerror(const 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 
55724c5febSToomas Soome %type <intval> OPTION options
56724c5febSToomas Soome %type <string> NAME STRING
57724c5febSToomas Soome %type <subcmd> INSTALL NOTIFY EXCEPT PATTERN SPECIAL cmdlist cmd
58724c5febSToomas Soome %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 
66724c5febSToomas Soome command:	  NAME EQUAL namelist {
677c478bd9Sstevel@tonic-gate 			(void) lookup($1, INSERT, $3);
687c478bd9Sstevel@tonic-gate 		}
69724c5febSToomas Soome 		| namelist ARROW namelist cmdlist {
707c478bd9Sstevel@tonic-gate 			insert(NULL, $1, $3, $4);
717c478bd9Sstevel@tonic-gate 		}
72724c5febSToomas Soome 		| NAME COLON namelist ARROW namelist cmdlist {
737c478bd9Sstevel@tonic-gate 			insert($1, $3, $5, $6);
747c478bd9Sstevel@tonic-gate 		}
75724c5febSToomas Soome 		| namelist DCOLON NAME cmdlist {
767c478bd9Sstevel@tonic-gate 			append(NULL, $1, $3, $4);
777c478bd9Sstevel@tonic-gate 		}
78724c5febSToomas Soome 		| 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 
84724c5febSToomas Soome namelist:	  NAME {
857c478bd9Sstevel@tonic-gate 			$$ = makenl($1);
867c478bd9Sstevel@tonic-gate 		}
87724c5febSToomas Soome 		| 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 		}
95724c5febSToomas Soome 		| 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 		}
109724c5febSToomas Soome 		| 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 
120724c5febSToomas Soome 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)
127*1a90c98dSToomas Soome 					(void) yyerror(
128*1a90c98dSToomas Soome 					    "only one name allowed\n");
1297c478bd9Sstevel@tonic-gate 				$1->sc_name = nl ? nl->n_name: NULL;
1307c478bd9Sstevel@tonic-gate 				if (nl)
1317c478bd9Sstevel@tonic-gate 					free(nl);
1327c478bd9Sstevel@tonic-gate 			}
1337c478bd9Sstevel@tonic-gate 			$$ = $1;
1347c478bd9Sstevel@tonic-gate 		}
135724c5febSToomas Soome 		| NOTIFY namelist SM {
1367c478bd9Sstevel@tonic-gate 			if ($2 != NULL)
1377c478bd9Sstevel@tonic-gate 				$1->sc_args = expand($2, E_VARS);
1387c478bd9Sstevel@tonic-gate 			$$ = $1;
1397c478bd9Sstevel@tonic-gate 		}
140724c5febSToomas Soome 		| EXCEPT namelist SM {
1417c478bd9Sstevel@tonic-gate 			if ($2 != NULL)
1427c478bd9Sstevel@tonic-gate 				$1->sc_args = expand($2, E_ALL);
1437c478bd9Sstevel@tonic-gate 			$$ = $1;
1447c478bd9Sstevel@tonic-gate 		}
145724c5febSToomas Soome 		| PATTERN namelist SM {
1467c478bd9Sstevel@tonic-gate 			struct namelist *nl;
1477c478bd9Sstevel@tonic-gate 			char *cp, *re_comp();
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 			/*
1507c478bd9Sstevel@tonic-gate 			 *	We dup the namelist in $2 because expand()
1517c478bd9Sstevel@tonic-gate 			 *	destroys the list referred to in its first
1527c478bd9Sstevel@tonic-gate 			 *	argument.
1537c478bd9Sstevel@tonic-gate 			 */
1547c478bd9Sstevel@tonic-gate 			for (nl = expand(dupnl($2), E_VARS); nl != NULL;
1557c478bd9Sstevel@tonic-gate 				nl = nl->n_next)
1567c478bd9Sstevel@tonic-gate 				if ((cp = re_comp(nl->n_name)) != NULL)
157*1a90c98dSToomas Soome 					(void) yyerror(cp);
1587c478bd9Sstevel@tonic-gate 			$1->sc_args = expand($2, E_VARS);
1597c478bd9Sstevel@tonic-gate 			$$ = $1;
1607c478bd9Sstevel@tonic-gate 		}
161724c5febSToomas Soome 		| SPECIAL opt_namelist STRING SM {
1627c478bd9Sstevel@tonic-gate 			if ($2 != NULL)
1637c478bd9Sstevel@tonic-gate 				$1->sc_args = expand($2, E_ALL);
1647c478bd9Sstevel@tonic-gate 			$1->sc_name = $3;
1657c478bd9Sstevel@tonic-gate 			$$ = $1;
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 		;
1687c478bd9Sstevel@tonic-gate 
169724c5febSToomas Soome options:	  /* VOID */ {
1707c478bd9Sstevel@tonic-gate 			$$ = 0;
1717c478bd9Sstevel@tonic-gate 		}
172724c5febSToomas Soome 		| options OPTION {
1737c478bd9Sstevel@tonic-gate 			$$ |= $2;
1747c478bd9Sstevel@tonic-gate 		}
1757c478bd9Sstevel@tonic-gate 		;
1767c478bd9Sstevel@tonic-gate 
177724c5febSToomas Soome opt_namelist:	  /* VOID */ {
1787c478bd9Sstevel@tonic-gate 			$$ = NULL;
1797c478bd9Sstevel@tonic-gate 		}
180724c5febSToomas Soome 		| namelist {
1817c478bd9Sstevel@tonic-gate 			$$ = $1;
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 		;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate %%
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate int	yylineno = 1;
1887c478bd9Sstevel@tonic-gate extern	FILE *fin;
1897c478bd9Sstevel@tonic-gate 
190740638c8Sbw int
yylex()1917c478bd9Sstevel@tonic-gate yylex()
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate 	static char yytext[INMAX];
1947c478bd9Sstevel@tonic-gate 	register int c;
1957c478bd9Sstevel@tonic-gate 	register char *cp1, *cp2;
1967c478bd9Sstevel@tonic-gate 	static char quotechars[] = "[]{}*?$";
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate again:
1997c478bd9Sstevel@tonic-gate 	switch (c = getc(fin)) {
2007c478bd9Sstevel@tonic-gate 	case EOF:  /* end of file */
2017c478bd9Sstevel@tonic-gate 		return(0);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	case '#':  /* start of comment */
2047c478bd9Sstevel@tonic-gate 		while ((c = getc(fin)) != EOF && c != '\n')
2057c478bd9Sstevel@tonic-gate 			;
2067c478bd9Sstevel@tonic-gate 		if (c == EOF)
2077c478bd9Sstevel@tonic-gate 			return(0);
208c15ff06aSToomas Soome 		/* FALLTHROUGH */
2097c478bd9Sstevel@tonic-gate 	case '\n':
2107c478bd9Sstevel@tonic-gate 		yylineno++;
2117c478bd9Sstevel@tonic-gate 	case ' ':
2127c478bd9Sstevel@tonic-gate 	case '\t':  /* skip blanks */
2137c478bd9Sstevel@tonic-gate 		goto again;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	case '=':  /* EQUAL */
2167c478bd9Sstevel@tonic-gate 		return(EQUAL);
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	case '(':  /* LP */
2197c478bd9Sstevel@tonic-gate 		return(LP);
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	case ')':  /* RP */
2227c478bd9Sstevel@tonic-gate 		return(RP);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	case ';':  /* SM */
2257c478bd9Sstevel@tonic-gate 		return(SM);
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	case '-':  /* -> */
2287c478bd9Sstevel@tonic-gate 		if ((c = getc(fin)) == '>')
2297c478bd9Sstevel@tonic-gate 			return(ARROW);
2307c478bd9Sstevel@tonic-gate 		ungetc(c, fin);
2317c478bd9Sstevel@tonic-gate 		c = '-';
2327c478bd9Sstevel@tonic-gate 		break;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	case '"':  /* STRING */
2357c478bd9Sstevel@tonic-gate 		cp1 = yytext;
2367c478bd9Sstevel@tonic-gate 		cp2 = &yytext[INMAX - 1];
2377c478bd9Sstevel@tonic-gate 		for (;;) {
2387c478bd9Sstevel@tonic-gate 			if (cp1 >= cp2) {
239*1a90c98dSToomas Soome 				(void) yyerror("command string too long\n");
2407c478bd9Sstevel@tonic-gate 				break;
2417c478bd9Sstevel@tonic-gate 			}
2427c478bd9Sstevel@tonic-gate 			c = getc(fin);
2437c478bd9Sstevel@tonic-gate 			if (c == EOF || c == '"')
2447c478bd9Sstevel@tonic-gate 				break;
2457c478bd9Sstevel@tonic-gate 			if (c == '\\') {
2467c478bd9Sstevel@tonic-gate 				if ((c = getc(fin)) == EOF) {
2477c478bd9Sstevel@tonic-gate 					*cp1++ = '\\';
2487c478bd9Sstevel@tonic-gate 					break;
2497c478bd9Sstevel@tonic-gate 				}
2507c478bd9Sstevel@tonic-gate 			}
2517c478bd9Sstevel@tonic-gate 			if (c == '\n') {
2527c478bd9Sstevel@tonic-gate 				yylineno++;
2537c478bd9Sstevel@tonic-gate 				c = ' '; /* can't send '\n' */
2547c478bd9Sstevel@tonic-gate 			}
2557c478bd9Sstevel@tonic-gate 			*cp1++ = c;
2567c478bd9Sstevel@tonic-gate 		}
2577c478bd9Sstevel@tonic-gate 		if (c != '"')
258*1a90c98dSToomas Soome 			(void) yyerror("missing closing '\"'\n");
2597c478bd9Sstevel@tonic-gate 		*cp1 = '\0';
2607c478bd9Sstevel@tonic-gate 		yylval.string = makestr(yytext);
2617c478bd9Sstevel@tonic-gate 		return(STRING);
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	case ':':  /* : or :: */
2647c478bd9Sstevel@tonic-gate 		if ((c = getc(fin)) == ':')
2657c478bd9Sstevel@tonic-gate 			return(DCOLON);
2667c478bd9Sstevel@tonic-gate 		ungetc(c, fin);
2677c478bd9Sstevel@tonic-gate 		return(COLON);
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 	cp1 = yytext;
2707c478bd9Sstevel@tonic-gate 	cp2 = &yytext[INMAX - 1];
2717c478bd9Sstevel@tonic-gate 	for (;;) {
2727c478bd9Sstevel@tonic-gate 		if (cp1 >= cp2) {
273*1a90c98dSToomas Soome 			(void) yyerror("input line too long\n");
2747c478bd9Sstevel@tonic-gate 			break;
2757c478bd9Sstevel@tonic-gate 		}
2767c478bd9Sstevel@tonic-gate 		if (c == '\\') {
2777c478bd9Sstevel@tonic-gate 			if ((c = getc(fin)) != EOF) {
2787c478bd9Sstevel@tonic-gate 				if (any(c, quotechars))
2797c478bd9Sstevel@tonic-gate 					c |= QUOTE;
2807c478bd9Sstevel@tonic-gate 			} else {
2817c478bd9Sstevel@tonic-gate 				*cp1++ = '\\';
2827c478bd9Sstevel@tonic-gate 				break;
2837c478bd9Sstevel@tonic-gate 			}
2847c478bd9Sstevel@tonic-gate 		}
2857c478bd9Sstevel@tonic-gate 		*cp1++ = c;
2867c478bd9Sstevel@tonic-gate 		c = getc(fin);
2877c478bd9Sstevel@tonic-gate 		if (c == EOF || any(c, " \"'\t()=;:\n")) {
2887c478bd9Sstevel@tonic-gate 			ungetc(c, fin);
2897c478bd9Sstevel@tonic-gate 			break;
2907c478bd9Sstevel@tonic-gate 		}
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 	*cp1 = '\0';
2937c478bd9Sstevel@tonic-gate 	if (yytext[0] == '-' && yytext[2] == '\0') {
2947c478bd9Sstevel@tonic-gate 		switch (yytext[1]) {
2957c478bd9Sstevel@tonic-gate 		case 'b':
2967c478bd9Sstevel@tonic-gate 			yylval.intval = COMPARE;
2977c478bd9Sstevel@tonic-gate 			return(OPTION);
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 		case 'R':
3007c478bd9Sstevel@tonic-gate 			yylval.intval = REMOVE;
3017c478bd9Sstevel@tonic-gate 			return(OPTION);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 		case 'v':
3047c478bd9Sstevel@tonic-gate 			yylval.intval = VERIFY;
3057c478bd9Sstevel@tonic-gate 			return(OPTION);
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 		case 'w':
3087c478bd9Sstevel@tonic-gate 			yylval.intval = WHOLE;
3097c478bd9Sstevel@tonic-gate 			return(OPTION);
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 		case 'y':
3127c478bd9Sstevel@tonic-gate 			yylval.intval = YOUNGER;
3137c478bd9Sstevel@tonic-gate 			return(OPTION);
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 		case 'h':
3167c478bd9Sstevel@tonic-gate 			yylval.intval = FOLLOW;
3177c478bd9Sstevel@tonic-gate 			return(OPTION);
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 		case 'i':
3207c478bd9Sstevel@tonic-gate 			yylval.intval = IGNLNKS;
3217c478bd9Sstevel@tonic-gate 			return(OPTION);
3227c478bd9Sstevel@tonic-gate 		}
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	if (!strcmp(yytext, "install"))
3257c478bd9Sstevel@tonic-gate 		c = INSTALL;
3267c478bd9Sstevel@tonic-gate 	else if (!strcmp(yytext, "notify"))
3277c478bd9Sstevel@tonic-gate 		c = NOTIFY;
3287c478bd9Sstevel@tonic-gate 	else if (!strcmp(yytext, "except"))
3297c478bd9Sstevel@tonic-gate 		c = EXCEPT;
3307c478bd9Sstevel@tonic-gate 	else if (!strcmp(yytext, "except_pat"))
3317c478bd9Sstevel@tonic-gate 		c = PATTERN;
3327c478bd9Sstevel@tonic-gate 	else if (!strcmp(yytext, "special"))
3337c478bd9Sstevel@tonic-gate 		c = SPECIAL;
3347c478bd9Sstevel@tonic-gate 	else {
3357c478bd9Sstevel@tonic-gate 		yylval.string = makestr(yytext);
3367c478bd9Sstevel@tonic-gate 		return(NAME);
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate 	yylval.subcmd = makesubcmd(c);
3397c478bd9Sstevel@tonic-gate 	return(c);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate 
342740638c8Sbw int
any(c,str)3437c478bd9Sstevel@tonic-gate any(c, str)
3447c478bd9Sstevel@tonic-gate 	register int c;
3457c478bd9Sstevel@tonic-gate 	register char *str;
3467c478bd9Sstevel@tonic-gate {
3477c478bd9Sstevel@tonic-gate 	while (*str)
3487c478bd9Sstevel@tonic-gate 		if (c == *str++)
3497c478bd9Sstevel@tonic-gate 			return(1);
3507c478bd9Sstevel@tonic-gate 	return(0);
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate /*
3547c478bd9Sstevel@tonic-gate  * Insert or append ARROW command to list of hosts to be updated.
3557c478bd9Sstevel@tonic-gate  */
356740638c8Sbw void
insert(label,files,hosts,subcmds)3577c478bd9Sstevel@tonic-gate insert(label, files, hosts, subcmds)
3587c478bd9Sstevel@tonic-gate 	char *label;
3597c478bd9Sstevel@tonic-gate 	struct namelist *files, *hosts;
3607c478bd9Sstevel@tonic-gate 	struct subcmd *subcmds;
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate 	register struct cmd *c, *prev, *nc;
3637c478bd9Sstevel@tonic-gate 	register struct namelist *h, *oldh;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	files = expand(files, E_VARS|E_SHELL);
3667c478bd9Sstevel@tonic-gate 	hosts = expand(hosts, E_ALL);
3677c478bd9Sstevel@tonic-gate if (debug) {
3687c478bd9Sstevel@tonic-gate 	printf("insert:  files = ");
3697c478bd9Sstevel@tonic-gate 	prnames(files);
3707c478bd9Sstevel@tonic-gate 	printf("insert:  hosts = ");
3717c478bd9Sstevel@tonic-gate 	prnames(hosts);
3727c478bd9Sstevel@tonic-gate 	if (cmds)
3737c478bd9Sstevel@tonic-gate 		prcmd(cmds);
3747c478bd9Sstevel@tonic-gate 	else
3757c478bd9Sstevel@tonic-gate 		printf("insert:  cmds NULL\n");
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate 	for (h = hosts; h != NULL; oldh = h, h = h->n_next, free(oldh)) {
3787c478bd9Sstevel@tonic-gate 		/*
3797c478bd9Sstevel@tonic-gate 		 * Search command list for an update to the same host.
3807c478bd9Sstevel@tonic-gate 		 */
3817c478bd9Sstevel@tonic-gate 		for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
3827c478bd9Sstevel@tonic-gate 			if (strcmp(c->c_name, h->n_name) == 0) {
3837c478bd9Sstevel@tonic-gate 				do {
3847c478bd9Sstevel@tonic-gate 					prev = c;
3857c478bd9Sstevel@tonic-gate 					c = c->c_next;
3867c478bd9Sstevel@tonic-gate 				} while (c != NULL &&
3877c478bd9Sstevel@tonic-gate 					strcmp(c->c_name, h->n_name) == 0);
3887c478bd9Sstevel@tonic-gate 				break;
3897c478bd9Sstevel@tonic-gate 			}
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 		/*
3927c478bd9Sstevel@tonic-gate 		 * Insert new command to update host.
3937c478bd9Sstevel@tonic-gate 		 */
3947c478bd9Sstevel@tonic-gate 		nc = ALLOC(cmd);
3957c478bd9Sstevel@tonic-gate 		if (nc == NULL)
3967c478bd9Sstevel@tonic-gate 			fatal("ran out of memory\n");
3977c478bd9Sstevel@tonic-gate 		nc->c_type = ARROW;
3987c478bd9Sstevel@tonic-gate 		nc->c_name = h->n_name;
3997c478bd9Sstevel@tonic-gate 		nc->c_label = label;
4007c478bd9Sstevel@tonic-gate 		nc->c_files = files;
4017c478bd9Sstevel@tonic-gate 		nc->c_cmds = subcmds;
4027c478bd9Sstevel@tonic-gate 		nc->c_next = c;
4037c478bd9Sstevel@tonic-gate 		if (prev == NULL)
4047c478bd9Sstevel@tonic-gate 			cmds = nc;
4057c478bd9Sstevel@tonic-gate 		else
4067c478bd9Sstevel@tonic-gate 			prev->c_next = nc;
4077c478bd9Sstevel@tonic-gate 		/* update last_cmd if appending nc to cmds */
4087c478bd9Sstevel@tonic-gate 		if (c == NULL)
4097c478bd9Sstevel@tonic-gate 			last_cmd = nc;
4107c478bd9Sstevel@tonic-gate 	}
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate /*
4147c478bd9Sstevel@tonic-gate  * Append DCOLON command to the end of the command list since these are always
4157c478bd9Sstevel@tonic-gate  * executed in the order they appear in the distfile.
4167c478bd9Sstevel@tonic-gate  */
417740638c8Sbw static void
append(label,files,stamp,subcmds)4187c478bd9Sstevel@tonic-gate append(label, files, stamp, subcmds)
4197c478bd9Sstevel@tonic-gate 	char *label;
4207c478bd9Sstevel@tonic-gate 	struct namelist *files;
4217c478bd9Sstevel@tonic-gate 	char *stamp;
4227c478bd9Sstevel@tonic-gate 	struct subcmd *subcmds;
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate 	register struct cmd *c;
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 	c = ALLOC(cmd);
4277c478bd9Sstevel@tonic-gate 	if (c == NULL)
4287c478bd9Sstevel@tonic-gate 		fatal("ran out of memory\n");
4297c478bd9Sstevel@tonic-gate 	c->c_type = DCOLON;
4307c478bd9Sstevel@tonic-gate 	c->c_name = stamp;
4317c478bd9Sstevel@tonic-gate 	c->c_label = label;
4327c478bd9Sstevel@tonic-gate 	c->c_files = expand(files, E_ALL);
4337c478bd9Sstevel@tonic-gate 	c->c_cmds = subcmds;
4347c478bd9Sstevel@tonic-gate 	c->c_next = NULL;
4357c478bd9Sstevel@tonic-gate 	if (cmds == NULL)
4367c478bd9Sstevel@tonic-gate 		cmds = last_cmd = c;
4377c478bd9Sstevel@tonic-gate 	else {
4387c478bd9Sstevel@tonic-gate 		last_cmd->c_next = c;
4397c478bd9Sstevel@tonic-gate 		last_cmd = c;
4407c478bd9Sstevel@tonic-gate 	}
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate /*
4447c478bd9Sstevel@tonic-gate  * Error printing routine in parser.
4457c478bd9Sstevel@tonic-gate  */
446*1a90c98dSToomas Soome int
yyerror(const char * s)447*1a90c98dSToomas Soome yyerror(const 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);
454*1a90c98dSToomas Soome 	return (0);
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate  * Return a copy of the string.
4597c478bd9Sstevel@tonic-gate  */
4607c478bd9Sstevel@tonic-gate char *
makestr(str)4617c478bd9Sstevel@tonic-gate makestr(str)
4627c478bd9Sstevel@tonic-gate 	char *str;
4637c478bd9Sstevel@tonic-gate {
4647c478bd9Sstevel@tonic-gate 	register char *cp, *s;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	str = cp = malloc(strlen(s = str) + 1);
4677c478bd9Sstevel@tonic-gate 	if (cp == NULL)
4687c478bd9Sstevel@tonic-gate 		fatal("ran out of memory\n");
4697c478bd9Sstevel@tonic-gate 	while (*cp++ = *s++)
4707c478bd9Sstevel@tonic-gate 		;
4717c478bd9Sstevel@tonic-gate 	return(str);
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate /*
4757c478bd9Sstevel@tonic-gate  * Allocate a namelist structure.
4767c478bd9Sstevel@tonic-gate  */
4777c478bd9Sstevel@tonic-gate struct namelist *
makenl(name)4787c478bd9Sstevel@tonic-gate makenl(name)
4797c478bd9Sstevel@tonic-gate 	char *name;
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate 	register struct namelist *nl;
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 	nl = ALLOC(namelist);
4847c478bd9Sstevel@tonic-gate 	if (nl == NULL)
4857c478bd9Sstevel@tonic-gate 		fatal("ran out of memory\n");
4867c478bd9Sstevel@tonic-gate 	nl->n_name = name;
4877c478bd9Sstevel@tonic-gate 	nl->n_next = NULL;
4887c478bd9Sstevel@tonic-gate 	return(nl);
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate /*
4927c478bd9Sstevel@tonic-gate  * Duplicate an existing namelist structure.  Only used by the PATTERN
4937c478bd9Sstevel@tonic-gate  * code, and then only because expand() is destructive.
4947c478bd9Sstevel@tonic-gate  */
4957c478bd9Sstevel@tonic-gate struct namelist *
dupnl(old)4967c478bd9Sstevel@tonic-gate dupnl(old)
4977c478bd9Sstevel@tonic-gate 	struct namelist *old;
4987c478bd9Sstevel@tonic-gate {
4997c478bd9Sstevel@tonic-gate 	struct namelist *n;
5007c478bd9Sstevel@tonic-gate 	struct namelist *new, *newhead = (struct namelist *) NULL;
5017c478bd9Sstevel@tonic-gate 	struct namelist *prev = (struct namelist *) NULL;
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	for (n = old; n; n = n->n_next) {
5047c478bd9Sstevel@tonic-gate 		new = ALLOC(namelist);
5057c478bd9Sstevel@tonic-gate 		if (new == (struct namelist *) NULL)
5067c478bd9Sstevel@tonic-gate 			fatal("ran out of memory\n");
5077c478bd9Sstevel@tonic-gate 		if (newhead == (struct namelist *) NULL)
5087c478bd9Sstevel@tonic-gate 			newhead = new;
5097c478bd9Sstevel@tonic-gate 		if (n->n_name) {
5107c478bd9Sstevel@tonic-gate 			if ((new->n_name = strdup(n->n_name)) == (char *) NULL)
5117c478bd9Sstevel@tonic-gate 				fatal("ran out of memory\n");
5127c478bd9Sstevel@tonic-gate 		} else
5137c478bd9Sstevel@tonic-gate 			new->n_name = (char *) NULL;
5147c478bd9Sstevel@tonic-gate 		if (prev)
5157c478bd9Sstevel@tonic-gate 			prev->n_next = new;
5167c478bd9Sstevel@tonic-gate 		prev = new;
5177c478bd9Sstevel@tonic-gate 	}
5187c478bd9Sstevel@tonic-gate 	if (prev)
5197c478bd9Sstevel@tonic-gate 		prev->n_next = (struct namelist *) NULL;
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	return (newhead);
5227c478bd9Sstevel@tonic-gate }
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate /*
5257c478bd9Sstevel@tonic-gate  * Make a sub command for lists of variables, commands, etc.
5267c478bd9Sstevel@tonic-gate  */
5277c478bd9Sstevel@tonic-gate struct subcmd *
makesubcmd(type,name)5287c478bd9Sstevel@tonic-gate makesubcmd(type, name)
5297c478bd9Sstevel@tonic-gate 	int type;
5307c478bd9Sstevel@tonic-gate 	register char *name;
5317c478bd9Sstevel@tonic-gate {
5327c478bd9Sstevel@tonic-gate 	register char *cp;
5337c478bd9Sstevel@tonic-gate 	register struct subcmd *sc;
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	sc = ALLOC(subcmd);
5367c478bd9Sstevel@tonic-gate 	if (sc == NULL)
5377c478bd9Sstevel@tonic-gate 		fatal("ran out of memory\n");
5387c478bd9Sstevel@tonic-gate 	sc->sc_type = type;
5397c478bd9Sstevel@tonic-gate 	sc->sc_args = NULL;
5407c478bd9Sstevel@tonic-gate 	sc->sc_next = NULL;
5417c478bd9Sstevel@tonic-gate 	sc->sc_name = NULL;
5427c478bd9Sstevel@tonic-gate 	return(sc);
5437c478bd9Sstevel@tonic-gate }
544