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