1 # include <stdio.h> 2 # include "sendmail.h" 3 # include <ctype.h> 4 5 static char SccsId[] = "@(#)readcf.c 3.5 08/08/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 *xalloc(); 34 extern char **prescan(); 35 extern char **copyplist(); 36 extern char *rindex(); 37 extern char *newstr(); 38 int class; 39 int ruleset = 0; 40 41 cf = fopen(cfname, "r"); 42 if (cf == NULL) 43 { 44 syserr("cannot open %s", cfname); 45 exit(EX_OSFILE); 46 } 47 48 while (fgets(buf, sizeof buf, cf) != NULL) 49 { 50 p = rindex(buf, '\n'); 51 if (p != NULL) 52 *p = '\0'; 53 54 switch (buf[0]) 55 { 56 case '\n': 57 case '\0': 58 case ' ': 59 case '\t': 60 case '#': /* comment */ 61 break; 62 63 case 'R': /* rewriting rule */ 64 for (p = &buf[1]; *p != '\0' && *p != '\t'; p++) 65 continue; 66 67 if (*p == '\0') 68 syserr("invalid rewrite line \"%s\"", buf); 69 else 70 { 71 if (rwp == NULL) 72 { 73 RewriteRules[ruleset] = rwp = 74 (struct rewrite *) xalloc(sizeof *rwp); 75 } 76 else 77 { 78 rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 79 rwp = rwp->r_next; 80 } 81 rwp->r_next = NULL; 82 83 rwp->r_lhs = prescan(&buf[1], '\t'); 84 if (rwp->r_lhs != NULL) 85 rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); 86 while (*p == '\t') 87 p++; 88 rwp->r_rhs = prescan(p, '\t'); 89 if (rwp->r_rhs != NULL) 90 rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); 91 } 92 break; 93 94 case 'S': /* select rewriting set */ 95 ruleset = atoi(&buf[1]); 96 rwp = NULL; 97 break; 98 99 case 'D': /* macro definition */ 100 define(buf[1], newstr(&buf[2])); 101 break; 102 103 case 'H': /* required header line */ 104 chompheader(&buf[1], TRUE); 105 break; 106 107 case 'C': /* word class */ 108 class = buf[1]; 109 if (!isalpha(class)) 110 goto badline; 111 if (isupper(class)) 112 class -= 'A'; 113 else 114 class -= 'a'; 115 116 /* scan the list of words and set class 'i' for all */ 117 for (p = &buf[2]; *p != '\0'; ) 118 { 119 register char *wd; 120 char delim; 121 register STAB *s; 122 123 while (*p != '\0' && isspace(*p)) 124 p++; 125 wd = p; 126 while (*p != '\0' && !isspace(*p)) 127 p++; 128 delim = *p; 129 *p = '\0'; 130 if (wd[0] != '\0') 131 { 132 s = stab(wd, ST_ENTER); 133 s->s_class |= 1 << class; 134 } 135 *p = delim; 136 } 137 break; 138 139 default: 140 badline: 141 syserr("unknown control line \"%s\"", buf); 142 } 143 } 144 145 /* 146 printrules(); 147 */ 148 } 149 /* 150 ** RWCRACK -- crack rewrite line. 151 ** 152 ** Parameters: 153 ** l -- line to crack. 154 ** 155 ** Returns: 156 ** local copy of cracked line. 157 ** 158 ** Side Effects: 159 ** none. 160 */ 161 162 char ** 163 rwcrack(l) 164 register char *l; 165 { 166 char *av[MAXATOM]; 167 int ac = 0; 168 register char **avp; 169 char buf[MAXNAME]; 170 register char *b; 171 bool wasdelim = FALSE; 172 char *delims = ":@!^."; 173 extern char *index(); 174 bool tchange; 175 extern char *newstr(), *xalloc(); 176 177 for (avp = av; *l != '\0' && *l != '\n'; avp++) 178 { 179 b = buf; 180 tchange = FALSE; 181 while (!tchange) 182 { 183 if (*l != '$') 184 { 185 if (wasdelim || index(delims, *l) != NULL) 186 tchange = TRUE; 187 wasdelim = (index(delims, *l) != NULL); 188 if (wasdelim) 189 tchange = TRUE; 190 *b++ = *l++; 191 continue; 192 } 193 194 tchange = TRUE; 195 switch (*++l) 196 { 197 case '$': /* literal $ */ 198 *b++ = *l; 199 break; 200 201 case '+': /* match anything */ 202 *b++ = MATCHANY; 203 *b++ = *++l; 204 break; 205 206 case '-': /* match one token */ 207 *b++ = MATCHONE; 208 *b++ = *++l; 209 break; 210 211 case '#': /* canonical net name */ 212 *b++ = CANONNET; 213 break; 214 215 case '@': /* canonical host name */ 216 *b++ = CANONHOST; 217 break; 218 219 case ':': /* canonical user name */ 220 *b++ = CANONUSER; 221 break; 222 223 default: 224 *b++ = '$'; 225 l--; 226 break; 227 } 228 l++; 229 } 230 231 /* save the argument we have collected */ 232 *b = '\0'; 233 *avp = newstr(buf); 234 ac++; 235 } 236 237 /* allocate new space for vector */ 238 ac++; 239 *avp = NULL; 240 avp = (char **) xalloc(ac * sizeof *av); 241 bmove(av, avp, ac * sizeof *av); 242 243 return (avp); 244 } 245 /* 246 ** PRINTRULES -- print rewrite rules (for debugging) 247 ** 248 ** Parameters: 249 ** none. 250 ** 251 ** Returns: 252 ** none. 253 ** 254 ** Side Effects: 255 ** prints rewrite rules. 256 */ 257 258 printrules() 259 { 260 register struct rewrite *rwp; 261 register int ruleset; 262 263 for (ruleset = 0; ruleset < 10; ruleset++) 264 { 265 if (RewriteRules[ruleset] == NULL) 266 continue; 267 printf("\n----Rule Set %d:\n", ruleset); 268 269 for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 270 { 271 register char **av; 272 273 printf("\n"); 274 for (av = rwp->r_lhs; *av != NULL; av++) 275 { 276 xputs(*av); 277 putchar('_'); 278 } 279 printf("\n\t"); 280 for (av = rwp->r_rhs; *av != NULL; av++) 281 { 282 xputs(*av); 283 putchar('_'); 284 } 285 printf("\n"); 286 } 287 } 288 } 289