13308Seric # include <stdio.h>
2*3313Seric # include "sendmail.h"
33308Seric # include <ctype.h>
43308Seric 
5*3313Seric static char SccsId[] = "@(#)readcf.c	3.1	03/20/81";
63308Seric 
73308Seric /*
83308Seric **  READCF -- read control file.
93308Seric **
103308Seric **	This routine reads the control file and builds the internal
113308Seric **	form.
123308Seric **
133308Seric **	Parameters:
143308Seric **		cfname -- control file name.
153308Seric **
163308Seric **	Returns:
173308Seric **		none.
183308Seric **
193308Seric **	Side Effects:
203308Seric **		Builds several internal tables.
213308Seric */
223308Seric 
233308Seric struct rewrite	*RewriteRules;
243308Seric 
253308Seric 
263308Seric readcf(cfname)
273308Seric 	char *cfname;
283308Seric {
293308Seric 	FILE *cf;
303308Seric 	char buf[MAXLINE];
313308Seric 	register char *p;
323308Seric 	struct rewrite *rwp = NULL;
333308Seric 	extern char *xalloc();
343308Seric 	extern char **prescan();
353308Seric 	extern char **copyplist();
363308Seric 	extern char *rindex();
373308Seric 	extern char *newstr();
383308Seric 
393308Seric 	cf = fopen(cfname, "r");
403308Seric 	if (cf == NULL)
413308Seric 	{
423308Seric 		syserr("cannot open %s", cfname);
433308Seric 		exit(EX_OSFILE);
443308Seric 	}
453308Seric 
463308Seric 	while (fgets(buf, sizeof buf, cf) != NULL)
473308Seric 	{
483308Seric 		p = rindex(buf, '\n');
493308Seric 		if (p != NULL)
503308Seric 			*p = '\0';
513308Seric 
523308Seric 		switch (buf[0])
533308Seric 		{
543308Seric 		  case '\n':
553308Seric 		  case '\0':
563308Seric 		  case ' ':
573308Seric 		  case '\t':
583308Seric 		  case '#':		/* comment */
593308Seric 			break;
603308Seric 
613308Seric 		  case 'R':		/* rewriting rule */
623308Seric 			for (p = &buf[1]; *p != '\0' && *p != '\t'; p++)
633308Seric 				continue;
643308Seric 
653308Seric 			if (*p == '\0')
663308Seric 				syserr("invalid rewrite line \"%s\"", buf);
673308Seric 			else
683308Seric 			{
693308Seric 				if (rwp == NULL)
703308Seric 					RewriteRules = rwp = (struct rewrite *) xalloc(sizeof *rwp);
713308Seric 				else
723308Seric 				{
733308Seric 					rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
743308Seric 					rwp = rwp->r_next;
753308Seric 				}
763308Seric 				rwp->r_next = NULL;
773308Seric 
783308Seric 				rwp->r_lhs = prescan(&buf[1], '\t');
793308Seric 				if (rwp->r_lhs != NULL)
803308Seric 					rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
813308Seric 				while (*p == '\t')
823308Seric 					p++;
833308Seric 				rwp->r_rhs = prescan(p, '\t');
843308Seric 				if (rwp->r_rhs != NULL)
853308Seric 					rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);
863308Seric 			}
873308Seric 			break;
883308Seric 
893308Seric 		  case 'D':		/* macro definition */
903308Seric 			define(buf[1], newstr(&buf[2]));
913308Seric 			break;
923308Seric 
933308Seric 		  default:
943308Seric 			syserr("unknown control line \"%s\"", buf);
953308Seric 		}
963308Seric 	}
973308Seric 
983308Seric /*
993308Seric 	printrules();
1003308Seric */
1013308Seric }
1023308Seric /*
1033308Seric **  RWCRACK -- crack rewrite line.
1043308Seric **
1053308Seric **	Parameters:
1063308Seric **		l -- line to crack.
1073308Seric **
1083308Seric **	Returns:
1093308Seric **		local copy of cracked line.
1103308Seric **
1113308Seric **	Side Effects:
1123308Seric **		none.
1133308Seric */
1143308Seric 
1153308Seric char **
1163308Seric rwcrack(l)
1173308Seric 	register char *l;
1183308Seric {
1193308Seric 	char *av[MAXATOM];
1203308Seric 	int ac = 0;
1213308Seric 	register char **avp;
1223308Seric 	char buf[MAXNAME];
1233308Seric 	register char *b;
1243308Seric 	bool wasdelim = FALSE;
1253308Seric 	char *delims = ":@!^.";
1263308Seric 	extern char *index();
1273308Seric 	bool tchange;
1283308Seric 	extern char *newstr(), *xalloc();
1293308Seric 
1303308Seric 	for (avp = av; *l != '\0' && *l != '\n'; avp++)
1313308Seric 	{
1323308Seric 		b = buf;
1333308Seric 		tchange = FALSE;
1343308Seric 		while (!tchange)
1353308Seric 		{
1363308Seric 			if (*l != '$')
1373308Seric 			{
1383308Seric 				if (wasdelim || index(delims, *l) != NULL)
1393308Seric 					tchange = TRUE;
1403308Seric 				wasdelim = (index(delims, *l) != NULL);
1413308Seric 				if (wasdelim)
1423308Seric 					tchange = TRUE;
1433308Seric 				*b++ = *l++;
1443308Seric 				continue;
1453308Seric 			}
1463308Seric 
1473308Seric 			tchange = TRUE;
1483308Seric 			switch (*++l)
1493308Seric 			{
1503308Seric 			  case '$':		/* literal $ */
1513308Seric 				*b++ = *l;
1523308Seric 				break;
1533308Seric 
1543308Seric 			  case '+':		/* match anything */
1553308Seric 				*b++ = MATCHANY;
1563308Seric 				*b++ = *++l;
1573308Seric 				break;
1583308Seric 
1593308Seric 			  case '-':		/* match one token */
1603308Seric 				*b++ = MATCHONE;
1613308Seric 				*b++ = *++l;
1623308Seric 				break;
1633308Seric 
1643308Seric 			  case '#':		/* canonical net name */
1653308Seric 				*b++ = CANONNET;
1663308Seric 				break;
1673308Seric 
1683308Seric 			  case '@':		/* canonical host name */
1693308Seric 				*b++ = CANONHOST;
1703308Seric 				break;
1713308Seric 
1723308Seric 			  case ':':		/* canonical user name */
1733308Seric 				*b++ = CANONUSER;
1743308Seric 				break;
1753308Seric 
1763308Seric 			  default:
1773308Seric 				*b++ = '$';
1783308Seric 				l--;
1793308Seric 				break;
1803308Seric 			}
1813308Seric 			l++;
1823308Seric 		}
1833308Seric 
1843308Seric 		/* save the argument we have collected */
1853308Seric 		*b = '\0';
1863308Seric 		*avp = newstr(buf);
1873308Seric 		ac++;
1883308Seric 	}
1893308Seric 
1903308Seric 	/* allocate new space for vector */
1913308Seric 	ac++;
1923308Seric 	*avp = NULL;
1933308Seric 	avp = (char **) xalloc(ac * sizeof *av);
1943308Seric 	bmove(av, avp, ac * sizeof *av);
1953308Seric 
1963308Seric 	return (avp);
1973308Seric }
1983308Seric /*
1993308Seric **  PRINTRULES -- print rewrite rules (for debugging)
2003308Seric **
2013308Seric **	Parameters:
2023308Seric **		none.
2033308Seric **
2043308Seric **	Returns:
2053308Seric **		none.
2063308Seric **
2073308Seric **	Side Effects:
2083308Seric **		prints rewrite rules.
2093308Seric */
2103308Seric 
2113308Seric printrules()
2123308Seric {
2133308Seric 	register struct rewrite *rwp;
2143308Seric 
2153308Seric 	for (rwp = RewriteRules; rwp != NULL; rwp = rwp->r_next)
2163308Seric 	{
2173308Seric 		register char **av;
2183308Seric 
2193308Seric 		printf("\n");
2203308Seric 		for (av = rwp->r_lhs; *av != NULL; av++)
2213308Seric 		{
2223308Seric 			xputs(*av);
2233308Seric 			putchar('_');
2243308Seric 		}
2253308Seric 		printf("\n\t");
2263308Seric 		for (av = rwp->r_rhs; *av != NULL; av++)
2273308Seric 		{
2283308Seric 			xputs(*av);
2293308Seric 			putchar('_');
2303308Seric 		}
2313308Seric 		printf("\n");
2323308Seric 	}
2333308Seric }
234