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