13308Seric # include <stdio.h> 23313Seric # include "sendmail.h" 33308Seric # include <ctype.h> 43308Seric 5*4088Seric static char SccsId[] = "@(#)readcf.c 3.6 08/09/81"; 63308Seric 73308Seric /* 83308Seric ** READCF -- read control file. 93308Seric ** 103308Seric ** This routine reads the control file and builds the internal 113308Seric ** form. 123308Seric ** 133308Seric ** Parameters: 143308Seric ** cfname -- control file name. 153308Seric ** 163308Seric ** Returns: 173308Seric ** none. 183308Seric ** 193308Seric ** Side Effects: 203308Seric ** Builds several internal tables. 213308Seric */ 223308Seric 234072Seric struct rewrite *RewriteRules[10]; 243308Seric 253308Seric 263308Seric readcf(cfname) 273308Seric char *cfname; 283308Seric { 293308Seric FILE *cf; 303308Seric char buf[MAXLINE]; 313308Seric register char *p; 323308Seric struct rewrite *rwp = NULL; 333308Seric extern char **prescan(); 343308Seric extern char **copyplist(); 354061Seric int class; 364072Seric int ruleset = 0; 373308Seric 383308Seric cf = fopen(cfname, "r"); 393308Seric if (cf == NULL) 403308Seric { 413308Seric syserr("cannot open %s", cfname); 423308Seric exit(EX_OSFILE); 433308Seric } 443308Seric 453308Seric while (fgets(buf, sizeof buf, cf) != NULL) 463308Seric { 473308Seric p = rindex(buf, '\n'); 483308Seric if (p != NULL) 493308Seric *p = '\0'; 503308Seric 513308Seric switch (buf[0]) 523308Seric { 533308Seric case '\n': 543308Seric case '\0': 553308Seric case ' ': 563308Seric case '\t': 573308Seric case '#': /* comment */ 583308Seric break; 593308Seric 603308Seric case 'R': /* rewriting rule */ 613308Seric for (p = &buf[1]; *p != '\0' && *p != '\t'; p++) 623308Seric continue; 633308Seric 643308Seric if (*p == '\0') 653308Seric syserr("invalid rewrite line \"%s\"", buf); 663308Seric else 673308Seric { 683308Seric if (rwp == NULL) 694072Seric { 704072Seric RewriteRules[ruleset] = rwp = 714072Seric (struct rewrite *) xalloc(sizeof *rwp); 724072Seric } 733308Seric else 743308Seric { 753308Seric rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 763308Seric rwp = rwp->r_next; 773308Seric } 783308Seric rwp->r_next = NULL; 793308Seric 803308Seric rwp->r_lhs = prescan(&buf[1], '\t'); 813308Seric if (rwp->r_lhs != NULL) 823308Seric rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); 833308Seric while (*p == '\t') 843308Seric p++; 853308Seric rwp->r_rhs = prescan(p, '\t'); 863308Seric if (rwp->r_rhs != NULL) 873308Seric rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); 883308Seric } 893308Seric break; 903308Seric 914072Seric case 'S': /* select rewriting set */ 924072Seric ruleset = atoi(&buf[1]); 934072Seric rwp = NULL; 944072Seric break; 954072Seric 963308Seric case 'D': /* macro definition */ 973308Seric define(buf[1], newstr(&buf[2])); 983308Seric break; 993308Seric 1003387Seric case 'H': /* required header line */ 101*4088Seric (void) chompheader(&buf[1], TRUE); 1023387Seric break; 1033387Seric 1044061Seric case 'C': /* word class */ 1054061Seric class = buf[1]; 1064061Seric if (!isalpha(class)) 1074061Seric goto badline; 1084061Seric if (isupper(class)) 1094061Seric class -= 'A'; 1104061Seric else 1114061Seric class -= 'a'; 1124061Seric 1134061Seric /* scan the list of words and set class 'i' for all */ 1144061Seric for (p = &buf[2]; *p != '\0'; ) 1154061Seric { 1164061Seric register char *wd; 1174061Seric char delim; 1184061Seric register STAB *s; 1194061Seric 1204061Seric while (*p != '\0' && isspace(*p)) 1214061Seric p++; 1224061Seric wd = p; 1234061Seric while (*p != '\0' && !isspace(*p)) 1244061Seric p++; 1254061Seric delim = *p; 1264061Seric *p = '\0'; 1274061Seric if (wd[0] != '\0') 1284061Seric { 1294061Seric s = stab(wd, ST_ENTER); 1304061Seric s->s_class |= 1 << class; 1314061Seric } 1324061Seric *p = delim; 1334061Seric } 1344061Seric break; 1354061Seric 1363308Seric default: 1374061Seric badline: 1383308Seric syserr("unknown control line \"%s\"", buf); 1393308Seric } 1403308Seric } 1413308Seric 142*4088Seric # ifdef DEBUG 143*4088Seric if (Debug > 6) 144*4088Seric printrules(); 145*4088Seric # endif DEBUG 1463308Seric } 1473308Seric /* 1483308Seric ** PRINTRULES -- print rewrite rules (for debugging) 1493308Seric ** 1503308Seric ** Parameters: 1513308Seric ** none. 1523308Seric ** 1533308Seric ** Returns: 1543308Seric ** none. 1553308Seric ** 1563308Seric ** Side Effects: 1573308Seric ** prints rewrite rules. 1583308Seric */ 1593308Seric 1603308Seric printrules() 1613308Seric { 1623308Seric register struct rewrite *rwp; 1634072Seric register int ruleset; 1643308Seric 1654072Seric for (ruleset = 0; ruleset < 10; ruleset++) 1663308Seric { 1674072Seric if (RewriteRules[ruleset] == NULL) 1684072Seric continue; 1694072Seric printf("\n----Rule Set %d:\n", ruleset); 1703308Seric 1714072Seric for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 1723308Seric { 1734072Seric register char **av; 1744072Seric 1754072Seric printf("\n"); 1764072Seric for (av = rwp->r_lhs; *av != NULL; av++) 1774072Seric { 1784072Seric xputs(*av); 1794072Seric putchar('_'); 1804072Seric } 1814072Seric printf("\n\t"); 1824072Seric for (av = rwp->r_rhs; *av != NULL; av++) 1834072Seric { 1844072Seric xputs(*av); 1854072Seric putchar('_'); 1864072Seric } 1874072Seric printf("\n"); 1883308Seric } 1893308Seric } 1903308Seric } 191