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