13308Seric # include <stdio.h> 2*3313Seric # include "sendmail.h" 33308Seric # include <ctype.h> 43308Seric 5*3313Seric static char SccsId[] = "@(#)readcf.c 3.1 03/20/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 933308Seric default: 943308Seric syserr("unknown control line \"%s\"", buf); 953308Seric } 963308Seric } 973308Seric 983308Seric /* 993308Seric printrules(); 1003308Seric */ 1013308Seric } 1023308Seric /* 1033308Seric ** RWCRACK -- crack rewrite line. 1043308Seric ** 1053308Seric ** Parameters: 1063308Seric ** l -- line to crack. 1073308Seric ** 1083308Seric ** Returns: 1093308Seric ** local copy of cracked line. 1103308Seric ** 1113308Seric ** Side Effects: 1123308Seric ** none. 1133308Seric */ 1143308Seric 1153308Seric char ** 1163308Seric rwcrack(l) 1173308Seric register char *l; 1183308Seric { 1193308Seric char *av[MAXATOM]; 1203308Seric int ac = 0; 1213308Seric register char **avp; 1223308Seric char buf[MAXNAME]; 1233308Seric register char *b; 1243308Seric bool wasdelim = FALSE; 1253308Seric char *delims = ":@!^."; 1263308Seric extern char *index(); 1273308Seric bool tchange; 1283308Seric extern char *newstr(), *xalloc(); 1293308Seric 1303308Seric for (avp = av; *l != '\0' && *l != '\n'; avp++) 1313308Seric { 1323308Seric b = buf; 1333308Seric tchange = FALSE; 1343308Seric while (!tchange) 1353308Seric { 1363308Seric if (*l != '$') 1373308Seric { 1383308Seric if (wasdelim || index(delims, *l) != NULL) 1393308Seric tchange = TRUE; 1403308Seric wasdelim = (index(delims, *l) != NULL); 1413308Seric if (wasdelim) 1423308Seric tchange = TRUE; 1433308Seric *b++ = *l++; 1443308Seric continue; 1453308Seric } 1463308Seric 1473308Seric tchange = TRUE; 1483308Seric switch (*++l) 1493308Seric { 1503308Seric case '$': /* literal $ */ 1513308Seric *b++ = *l; 1523308Seric break; 1533308Seric 1543308Seric case '+': /* match anything */ 1553308Seric *b++ = MATCHANY; 1563308Seric *b++ = *++l; 1573308Seric break; 1583308Seric 1593308Seric case '-': /* match one token */ 1603308Seric *b++ = MATCHONE; 1613308Seric *b++ = *++l; 1623308Seric break; 1633308Seric 1643308Seric case '#': /* canonical net name */ 1653308Seric *b++ = CANONNET; 1663308Seric break; 1673308Seric 1683308Seric case '@': /* canonical host name */ 1693308Seric *b++ = CANONHOST; 1703308Seric break; 1713308Seric 1723308Seric case ':': /* canonical user name */ 1733308Seric *b++ = CANONUSER; 1743308Seric break; 1753308Seric 1763308Seric default: 1773308Seric *b++ = '$'; 1783308Seric l--; 1793308Seric break; 1803308Seric } 1813308Seric l++; 1823308Seric } 1833308Seric 1843308Seric /* save the argument we have collected */ 1853308Seric *b = '\0'; 1863308Seric *avp = newstr(buf); 1873308Seric ac++; 1883308Seric } 1893308Seric 1903308Seric /* allocate new space for vector */ 1913308Seric ac++; 1923308Seric *avp = NULL; 1933308Seric avp = (char **) xalloc(ac * sizeof *av); 1943308Seric bmove(av, avp, ac * sizeof *av); 1953308Seric 1963308Seric return (avp); 1973308Seric } 1983308Seric /* 1993308Seric ** PRINTRULES -- print rewrite rules (for debugging) 2003308Seric ** 2013308Seric ** Parameters: 2023308Seric ** none. 2033308Seric ** 2043308Seric ** Returns: 2053308Seric ** none. 2063308Seric ** 2073308Seric ** Side Effects: 2083308Seric ** prints rewrite rules. 2093308Seric */ 2103308Seric 2113308Seric printrules() 2123308Seric { 2133308Seric register struct rewrite *rwp; 2143308Seric 2153308Seric for (rwp = RewriteRules; rwp != NULL; rwp = rwp->r_next) 2163308Seric { 2173308Seric register char **av; 2183308Seric 2193308Seric printf("\n"); 2203308Seric for (av = rwp->r_lhs; *av != NULL; av++) 2213308Seric { 2223308Seric xputs(*av); 2233308Seric putchar('_'); 2243308Seric } 2253308Seric printf("\n\t"); 2263308Seric for (av = rwp->r_rhs; *av != NULL; av++) 2273308Seric { 2283308Seric xputs(*av); 2293308Seric putchar('_'); 2303308Seric } 2313308Seric printf("\n"); 2323308Seric } 2333308Seric } 234