1 # include <stdio.h>
2 # include "sendmail.h"
3 # include <ctype.h>
4 
5 static char SccsId[] = "@(#)readcf.c	3.6	08/09/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[10];
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 **prescan();
34 	extern char **copyplist();
35 	int class;
36 	int ruleset = 0;
37 
38 	cf = fopen(cfname, "r");
39 	if (cf == NULL)
40 	{
41 		syserr("cannot open %s", cfname);
42 		exit(EX_OSFILE);
43 	}
44 
45 	while (fgets(buf, sizeof buf, cf) != NULL)
46 	{
47 		p = rindex(buf, '\n');
48 		if (p != NULL)
49 			*p = '\0';
50 
51 		switch (buf[0])
52 		{
53 		  case '\n':
54 		  case '\0':
55 		  case ' ':
56 		  case '\t':
57 		  case '#':		/* comment */
58 			break;
59 
60 		  case 'R':		/* rewriting rule */
61 			for (p = &buf[1]; *p != '\0' && *p != '\t'; p++)
62 				continue;
63 
64 			if (*p == '\0')
65 				syserr("invalid rewrite line \"%s\"", buf);
66 			else
67 			{
68 				if (rwp == NULL)
69 				{
70 					RewriteRules[ruleset] = rwp =
71 						(struct rewrite *) xalloc(sizeof *rwp);
72 				}
73 				else
74 				{
75 					rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
76 					rwp = rwp->r_next;
77 				}
78 				rwp->r_next = NULL;
79 
80 				rwp->r_lhs = prescan(&buf[1], '\t');
81 				if (rwp->r_lhs != NULL)
82 					rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
83 				while (*p == '\t')
84 					p++;
85 				rwp->r_rhs = prescan(p, '\t');
86 				if (rwp->r_rhs != NULL)
87 					rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);
88 			}
89 			break;
90 
91 		  case 'S':		/* select rewriting set */
92 			ruleset = atoi(&buf[1]);
93 			rwp = NULL;
94 			break;
95 
96 		  case 'D':		/* macro definition */
97 			define(buf[1], newstr(&buf[2]));
98 			break;
99 
100 		  case 'H':		/* required header line */
101 			(void) chompheader(&buf[1], TRUE);
102 			break;
103 
104 		  case 'C':		/* word class */
105 			class = buf[1];
106 			if (!isalpha(class))
107 				goto badline;
108 			if (isupper(class))
109 				class -= 'A';
110 			else
111 				class -= 'a';
112 
113 			/* scan the list of words and set class 'i' for all */
114 			for (p = &buf[2]; *p != '\0'; )
115 			{
116 				register char *wd;
117 				char delim;
118 				register STAB *s;
119 
120 				while (*p != '\0' && isspace(*p))
121 					p++;
122 				wd = p;
123 				while (*p != '\0' && !isspace(*p))
124 					p++;
125 				delim = *p;
126 				*p = '\0';
127 				if (wd[0] != '\0')
128 				{
129 					s = stab(wd, ST_ENTER);
130 					s->s_class |= 1 << class;
131 				}
132 				*p = delim;
133 			}
134 			break;
135 
136 		  default:
137 		  badline:
138 			syserr("unknown control line \"%s\"", buf);
139 		}
140 	}
141 
142 # ifdef DEBUG
143 	if (Debug > 6)
144 		printrules();
145 # endif DEBUG
146 }
147 /*
148 **  PRINTRULES -- print rewrite rules (for debugging)
149 **
150 **	Parameters:
151 **		none.
152 **
153 **	Returns:
154 **		none.
155 **
156 **	Side Effects:
157 **		prints rewrite rules.
158 */
159 
160 printrules()
161 {
162 	register struct rewrite *rwp;
163 	register int ruleset;
164 
165 	for (ruleset = 0; ruleset < 10; ruleset++)
166 	{
167 		if (RewriteRules[ruleset] == NULL)
168 			continue;
169 		printf("\n----Rule Set %d:\n", ruleset);
170 
171 		for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next)
172 		{
173 			register char **av;
174 
175 			printf("\n");
176 			for (av = rwp->r_lhs; *av != NULL; av++)
177 			{
178 				xputs(*av);
179 				putchar('_');
180 			}
181 			printf("\n\t");
182 			for (av = rwp->r_rhs; *av != NULL; av++)
183 			{
184 				xputs(*av);
185 				putchar('_');
186 			}
187 			printf("\n");
188 		}
189 	}
190 }
191