1*3308Seric # include <stdio.h>
2*3308Seric # include "postbox.h"
3*3308Seric # include <ctype.h>
4*3308Seric 
5*3308Seric static char SccsId[] = "@(#)readcf.c	1.1	03/20/81";
6*3308Seric 
7*3308Seric /*
8*3308Seric **  READCF -- read control file.
9*3308Seric **
10*3308Seric **	This routine reads the control file and builds the internal
11*3308Seric **	form.
12*3308Seric **
13*3308Seric **	Parameters:
14*3308Seric **		cfname -- control file name.
15*3308Seric **
16*3308Seric **	Returns:
17*3308Seric **		none.
18*3308Seric **
19*3308Seric **	Side Effects:
20*3308Seric **		Builds several internal tables.
21*3308Seric */
22*3308Seric 
23*3308Seric struct rewrite	*RewriteRules;
24*3308Seric 
25*3308Seric 
26*3308Seric readcf(cfname)
27*3308Seric 	char *cfname;
28*3308Seric {
29*3308Seric 	FILE *cf;
30*3308Seric 	char buf[MAXLINE];
31*3308Seric 	register char *p;
32*3308Seric 	struct rewrite *rwp = NULL;
33*3308Seric 	extern char *xalloc();
34*3308Seric 	extern char **prescan();
35*3308Seric 	extern char **copyplist();
36*3308Seric 	extern char *rindex();
37*3308Seric 	extern char *newstr();
38*3308Seric 
39*3308Seric 	cf = fopen(cfname, "r");
40*3308Seric 	if (cf == NULL)
41*3308Seric 	{
42*3308Seric 		syserr("cannot open %s", cfname);
43*3308Seric 		exit(EX_OSFILE);
44*3308Seric 	}
45*3308Seric 
46*3308Seric 	while (fgets(buf, sizeof buf, cf) != NULL)
47*3308Seric 	{
48*3308Seric 		p = rindex(buf, '\n');
49*3308Seric 		if (p != NULL)
50*3308Seric 			*p = '\0';
51*3308Seric 
52*3308Seric 		switch (buf[0])
53*3308Seric 		{
54*3308Seric 		  case '\n':
55*3308Seric 		  case '\0':
56*3308Seric 		  case ' ':
57*3308Seric 		  case '\t':
58*3308Seric 		  case '#':		/* comment */
59*3308Seric 			break;
60*3308Seric 
61*3308Seric 		  case 'R':		/* rewriting rule */
62*3308Seric 			for (p = &buf[1]; *p != '\0' && *p != '\t'; p++)
63*3308Seric 				continue;
64*3308Seric 
65*3308Seric 			if (*p == '\0')
66*3308Seric 				syserr("invalid rewrite line \"%s\"", buf);
67*3308Seric 			else
68*3308Seric 			{
69*3308Seric 				if (rwp == NULL)
70*3308Seric 					RewriteRules = rwp = (struct rewrite *) xalloc(sizeof *rwp);
71*3308Seric 				else
72*3308Seric 				{
73*3308Seric 					rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
74*3308Seric 					rwp = rwp->r_next;
75*3308Seric 				}
76*3308Seric 				rwp->r_next = NULL;
77*3308Seric 
78*3308Seric 				rwp->r_lhs = prescan(&buf[1], '\t');
79*3308Seric 				if (rwp->r_lhs != NULL)
80*3308Seric 					rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
81*3308Seric 				while (*p == '\t')
82*3308Seric 					p++;
83*3308Seric 				rwp->r_rhs = prescan(p, '\t');
84*3308Seric 				if (rwp->r_rhs != NULL)
85*3308Seric 					rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);
86*3308Seric 			}
87*3308Seric 			break;
88*3308Seric 
89*3308Seric 		  case 'D':		/* macro definition */
90*3308Seric 			define(buf[1], newstr(&buf[2]));
91*3308Seric 			break;
92*3308Seric 
93*3308Seric 		  default:
94*3308Seric 			syserr("unknown control line \"%s\"", buf);
95*3308Seric 		}
96*3308Seric 	}
97*3308Seric 
98*3308Seric /*
99*3308Seric 	printrules();
100*3308Seric */
101*3308Seric }
102*3308Seric /*
103*3308Seric **  RWCRACK -- crack rewrite line.
104*3308Seric **
105*3308Seric **	Parameters:
106*3308Seric **		l -- line to crack.
107*3308Seric **
108*3308Seric **	Returns:
109*3308Seric **		local copy of cracked line.
110*3308Seric **
111*3308Seric **	Side Effects:
112*3308Seric **		none.
113*3308Seric */
114*3308Seric 
115*3308Seric char **
116*3308Seric rwcrack(l)
117*3308Seric 	register char *l;
118*3308Seric {
119*3308Seric 	char *av[MAXATOM];
120*3308Seric 	int ac = 0;
121*3308Seric 	register char **avp;
122*3308Seric 	char buf[MAXNAME];
123*3308Seric 	register char *b;
124*3308Seric 	bool wasdelim = FALSE;
125*3308Seric 	char *delims = ":@!^.";
126*3308Seric 	extern char *index();
127*3308Seric 	bool tchange;
128*3308Seric 	extern char *newstr(), *xalloc();
129*3308Seric 
130*3308Seric 	for (avp = av; *l != '\0' && *l != '\n'; avp++)
131*3308Seric 	{
132*3308Seric 		b = buf;
133*3308Seric 		tchange = FALSE;
134*3308Seric 		while (!tchange)
135*3308Seric 		{
136*3308Seric 			if (*l != '$')
137*3308Seric 			{
138*3308Seric 				if (wasdelim || index(delims, *l) != NULL)
139*3308Seric 					tchange = TRUE;
140*3308Seric 				wasdelim = (index(delims, *l) != NULL);
141*3308Seric 				if (wasdelim)
142*3308Seric 					tchange = TRUE;
143*3308Seric 				*b++ = *l++;
144*3308Seric 				continue;
145*3308Seric 			}
146*3308Seric 
147*3308Seric 			tchange = TRUE;
148*3308Seric 			switch (*++l)
149*3308Seric 			{
150*3308Seric 			  case '$':		/* literal $ */
151*3308Seric 				*b++ = *l;
152*3308Seric 				break;
153*3308Seric 
154*3308Seric 			  case '+':		/* match anything */
155*3308Seric 				*b++ = MATCHANY;
156*3308Seric 				*b++ = *++l;
157*3308Seric 				break;
158*3308Seric 
159*3308Seric 			  case '-':		/* match one token */
160*3308Seric 				*b++ = MATCHONE;
161*3308Seric 				*b++ = *++l;
162*3308Seric 				break;
163*3308Seric 
164*3308Seric 			  case '#':		/* canonical net name */
165*3308Seric 				*b++ = CANONNET;
166*3308Seric 				break;
167*3308Seric 
168*3308Seric 			  case '@':		/* canonical host name */
169*3308Seric 				*b++ = CANONHOST;
170*3308Seric 				break;
171*3308Seric 
172*3308Seric 			  case ':':		/* canonical user name */
173*3308Seric 				*b++ = CANONUSER;
174*3308Seric 				break;
175*3308Seric 
176*3308Seric 			  default:
177*3308Seric 				*b++ = '$';
178*3308Seric 				l--;
179*3308Seric 				break;
180*3308Seric 			}
181*3308Seric 			l++;
182*3308Seric 		}
183*3308Seric 
184*3308Seric 		/* save the argument we have collected */
185*3308Seric 		*b = '\0';
186*3308Seric 		*avp = newstr(buf);
187*3308Seric 		ac++;
188*3308Seric 	}
189*3308Seric 
190*3308Seric 	/* allocate new space for vector */
191*3308Seric 	ac++;
192*3308Seric 	*avp = NULL;
193*3308Seric 	avp = (char **) xalloc(ac * sizeof *av);
194*3308Seric 	bmove(av, avp, ac * sizeof *av);
195*3308Seric 
196*3308Seric 	return (avp);
197*3308Seric }
198*3308Seric /*
199*3308Seric **  PRINTRULES -- print rewrite rules (for debugging)
200*3308Seric **
201*3308Seric **	Parameters:
202*3308Seric **		none.
203*3308Seric **
204*3308Seric **	Returns:
205*3308Seric **		none.
206*3308Seric **
207*3308Seric **	Side Effects:
208*3308Seric **		prints rewrite rules.
209*3308Seric */
210*3308Seric 
211*3308Seric printrules()
212*3308Seric {
213*3308Seric 	register struct rewrite *rwp;
214*3308Seric 
215*3308Seric 	for (rwp = RewriteRules; rwp != NULL; rwp = rwp->r_next)
216*3308Seric 	{
217*3308Seric 		register char **av;
218*3308Seric 
219*3308Seric 		printf("\n");
220*3308Seric 		for (av = rwp->r_lhs; *av != NULL; av++)
221*3308Seric 		{
222*3308Seric 			xputs(*av);
223*3308Seric 			putchar('_');
224*3308Seric 		}
225*3308Seric 		printf("\n\t");
226*3308Seric 		for (av = rwp->r_rhs; *av != NULL; av++)
227*3308Seric 		{
228*3308Seric 			xputs(*av);
229*3308Seric 			putchar('_');
230*3308Seric 		}
231*3308Seric 		printf("\n");
232*3308Seric 	}
233*3308Seric }
234