13308Seric # include <stdio.h> 23313Seric # include "sendmail.h" 33308Seric # include <ctype.h> 43308Seric 5*3387Seric static char SccsId[] = "@(#)readcf.c 3.2 03/28/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 233308Seric struct rewrite *RewriteRules; 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 *xalloc(); 343308Seric extern char **prescan(); 353308Seric extern char **copyplist(); 363308Seric extern char *rindex(); 373308Seric extern char *newstr(); 383308Seric 393308Seric cf = fopen(cfname, "r"); 403308Seric if (cf == NULL) 413308Seric { 423308Seric syserr("cannot open %s", cfname); 433308Seric exit(EX_OSFILE); 443308Seric } 453308Seric 463308Seric while (fgets(buf, sizeof buf, cf) != NULL) 473308Seric { 483308Seric p = rindex(buf, '\n'); 493308Seric if (p != NULL) 503308Seric *p = '\0'; 513308Seric 523308Seric switch (buf[0]) 533308Seric { 543308Seric case '\n': 553308Seric case '\0': 563308Seric case ' ': 573308Seric case '\t': 583308Seric case '#': /* comment */ 593308Seric break; 603308Seric 613308Seric case 'R': /* rewriting rule */ 623308Seric for (p = &buf[1]; *p != '\0' && *p != '\t'; p++) 633308Seric continue; 643308Seric 653308Seric if (*p == '\0') 663308Seric syserr("invalid rewrite line \"%s\"", buf); 673308Seric else 683308Seric { 693308Seric if (rwp == NULL) 703308Seric RewriteRules = rwp = (struct rewrite *) xalloc(sizeof *rwp); 713308Seric else 723308Seric { 733308Seric rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 743308Seric rwp = rwp->r_next; 753308Seric } 763308Seric rwp->r_next = NULL; 773308Seric 783308Seric rwp->r_lhs = prescan(&buf[1], '\t'); 793308Seric if (rwp->r_lhs != NULL) 803308Seric rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); 813308Seric while (*p == '\t') 823308Seric p++; 833308Seric rwp->r_rhs = prescan(p, '\t'); 843308Seric if (rwp->r_rhs != NULL) 853308Seric rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); 863308Seric } 873308Seric break; 883308Seric 893308Seric case 'D': /* macro definition */ 903308Seric define(buf[1], newstr(&buf[2])); 913308Seric break; 923308Seric 93*3387Seric case 'H': /* required header line */ 94*3387Seric chompheader(&buf[1], H_DEFAULT); 95*3387Seric break; 96*3387Seric 973308Seric default: 983308Seric syserr("unknown control line \"%s\"", buf); 993308Seric } 1003308Seric } 1013308Seric 1023308Seric /* 1033308Seric printrules(); 1043308Seric */ 1053308Seric } 1063308Seric /* 1073308Seric ** RWCRACK -- crack rewrite line. 1083308Seric ** 1093308Seric ** Parameters: 1103308Seric ** l -- line to crack. 1113308Seric ** 1123308Seric ** Returns: 1133308Seric ** local copy of cracked line. 1143308Seric ** 1153308Seric ** Side Effects: 1163308Seric ** none. 1173308Seric */ 1183308Seric 1193308Seric char ** 1203308Seric rwcrack(l) 1213308Seric register char *l; 1223308Seric { 1233308Seric char *av[MAXATOM]; 1243308Seric int ac = 0; 1253308Seric register char **avp; 1263308Seric char buf[MAXNAME]; 1273308Seric register char *b; 1283308Seric bool wasdelim = FALSE; 1293308Seric char *delims = ":@!^."; 1303308Seric extern char *index(); 1313308Seric bool tchange; 1323308Seric extern char *newstr(), *xalloc(); 1333308Seric 1343308Seric for (avp = av; *l != '\0' && *l != '\n'; avp++) 1353308Seric { 1363308Seric b = buf; 1373308Seric tchange = FALSE; 1383308Seric while (!tchange) 1393308Seric { 1403308Seric if (*l != '$') 1413308Seric { 1423308Seric if (wasdelim || index(delims, *l) != NULL) 1433308Seric tchange = TRUE; 1443308Seric wasdelim = (index(delims, *l) != NULL); 1453308Seric if (wasdelim) 1463308Seric tchange = TRUE; 1473308Seric *b++ = *l++; 1483308Seric continue; 1493308Seric } 1503308Seric 1513308Seric tchange = TRUE; 1523308Seric switch (*++l) 1533308Seric { 1543308Seric case '$': /* literal $ */ 1553308Seric *b++ = *l; 1563308Seric break; 1573308Seric 1583308Seric case '+': /* match anything */ 1593308Seric *b++ = MATCHANY; 1603308Seric *b++ = *++l; 1613308Seric break; 1623308Seric 1633308Seric case '-': /* match one token */ 1643308Seric *b++ = MATCHONE; 1653308Seric *b++ = *++l; 1663308Seric break; 1673308Seric 1683308Seric case '#': /* canonical net name */ 1693308Seric *b++ = CANONNET; 1703308Seric break; 1713308Seric 1723308Seric case '@': /* canonical host name */ 1733308Seric *b++ = CANONHOST; 1743308Seric break; 1753308Seric 1763308Seric case ':': /* canonical user name */ 1773308Seric *b++ = CANONUSER; 1783308Seric break; 1793308Seric 1803308Seric default: 1813308Seric *b++ = '$'; 1823308Seric l--; 1833308Seric break; 1843308Seric } 1853308Seric l++; 1863308Seric } 1873308Seric 1883308Seric /* save the argument we have collected */ 1893308Seric *b = '\0'; 1903308Seric *avp = newstr(buf); 1913308Seric ac++; 1923308Seric } 1933308Seric 1943308Seric /* allocate new space for vector */ 1953308Seric ac++; 1963308Seric *avp = NULL; 1973308Seric avp = (char **) xalloc(ac * sizeof *av); 1983308Seric bmove(av, avp, ac * sizeof *av); 1993308Seric 2003308Seric return (avp); 2013308Seric } 2023308Seric /* 2033308Seric ** PRINTRULES -- print rewrite rules (for debugging) 2043308Seric ** 2053308Seric ** Parameters: 2063308Seric ** none. 2073308Seric ** 2083308Seric ** Returns: 2093308Seric ** none. 2103308Seric ** 2113308Seric ** Side Effects: 2123308Seric ** prints rewrite rules. 2133308Seric */ 2143308Seric 2153308Seric printrules() 2163308Seric { 2173308Seric register struct rewrite *rwp; 2183308Seric 2193308Seric for (rwp = RewriteRules; rwp != NULL; rwp = rwp->r_next) 2203308Seric { 2213308Seric register char **av; 2223308Seric 2233308Seric printf("\n"); 2243308Seric for (av = rwp->r_lhs; *av != NULL; av++) 2253308Seric { 2263308Seric xputs(*av); 2273308Seric putchar('_'); 2283308Seric } 2293308Seric printf("\n\t"); 2303308Seric for (av = rwp->r_rhs; *av != NULL; av++) 2313308Seric { 2323308Seric xputs(*av); 2333308Seric putchar('_'); 2343308Seric } 2353308Seric printf("\n"); 2363308Seric } 2373308Seric } 238