Annotation of 43BSDTahoe/usr.lib/sendmail/src/readcf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Eric P. Allman
                      3:  * Copyright (c) 1988 Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms are permitted
                      7:  * provided that the above copyright notice and this paragraph are
                      8:  * duplicated in all such forms and that any documentation,
                      9:  * advertising materials, and other materials related to such
                     10:  * distribution and use acknowledge that the software was developed
                     11:  * by the University of California, Berkeley.  The name of the
                     12:  * University may not be used to endorse or promote products derived
                     13:  * from this software without specific prior written permission.
                     14:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     16:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     17:  */
                     18: 
                     19: #ifndef lint
                     20: static char sccsid[] = "@(#)readcf.c   5.13 (Berkeley) 6/30/88";
                     21: #endif /* not lint */
                     22: 
                     23: # include "sendmail.h"
                     24: 
                     25: /*
                     26: **  READCF -- read control file.
                     27: **
                     28: **     This routine reads the control file and builds the internal
                     29: **     form.
                     30: **
                     31: **     The file is formatted as a sequence of lines, each taken
                     32: **     atomically.  The first character of each line describes how
                     33: **     the line is to be interpreted.  The lines are:
                     34: **             Dxval           Define macro x to have value val.
                     35: **             Cxword          Put word into class x.
                     36: **             Fxfile [fmt]    Read file for lines to put into
                     37: **                             class x.  Use scanf string 'fmt'
                     38: **                             or "%s" if not present.  Fmt should
                     39: **                             only produce one string-valued result.
                     40: **             Hname: value    Define header with field-name 'name'
                     41: **                             and value as specified; this will be
                     42: **                             macro expanded immediately before
                     43: **                             use.
                     44: **             Sn              Use rewriting set n.
                     45: **             Rlhs rhs        Rewrite addresses that match lhs to
                     46: **                             be rhs.
                     47: **             Mn arg=val...   Define mailer.  n is the internal name.
                     48: **                             Args specify mailer parameters.
                     49: **             Oxvalue         Set option x to value.
                     50: **             Pname=value     Set precedence name to value.
                     51: **
                     52: **     Parameters:
                     53: **             cfname -- control file name.
                     54: **
                     55: **     Returns:
                     56: **             none.
                     57: **
                     58: **     Side Effects:
                     59: **             Builds several internal tables.
                     60: */
                     61: 
                     62: readcf(cfname)
                     63:        char *cfname;
                     64: {
                     65:        FILE *cf;
                     66:        int ruleset = 0;
                     67:        char *q;
                     68:        char **pv;
                     69:        struct rewrite *rwp = NULL;
                     70:        char buf[MAXLINE];
                     71:        register char *p;
                     72:        extern char **prescan();
                     73:        extern char **copyplist();
                     74:        char exbuf[MAXLINE];
                     75:        char pvpbuf[PSBUFSIZE];
                     76:        extern char *fgetfolded();
                     77:        extern char *munchstring();
                     78: 
                     79:        cf = fopen(cfname, "r");
                     80:        if (cf == NULL)
                     81:        {
                     82:                syserr("cannot open %s", cfname);
                     83:                exit(EX_OSFILE);
                     84:        }
                     85: 
                     86:        FileName = cfname;
                     87:        LineNumber = 0;
                     88:        while (fgetfolded(buf, sizeof buf, cf) != NULL)
                     89:        {
                     90:                /* map $ into \001 (ASCII SOH) for macro expansion */
                     91:                for (p = buf; *p != '\0'; p++)
                     92:                {
                     93:                        if (*p != '$')
                     94:                                continue;
                     95: 
                     96:                        if (p[1] == '$')
                     97:                        {
                     98:                                /* actual dollar sign.... */
                     99:                                (void) strcpy(p, p + 1);
                    100:                                continue;
                    101:                        }
                    102: 
                    103:                        /* convert to macro expansion character */
                    104:                        *p = '\001';
                    105:                }
                    106: 
                    107:                /* interpret this line */
                    108:                switch (buf[0])
                    109:                {
                    110:                  case '\0':
                    111:                  case '#':             /* comment */
                    112:                        break;
                    113: 
                    114:                  case 'R':             /* rewriting rule */
                    115:                        for (p = &buf[1]; *p != '\0' && *p != '\t'; p++)
                    116:                                continue;
                    117: 
                    118:                        if (*p == '\0')
                    119:                        {
                    120:                                syserr("invalid rewrite line \"%s\"", buf);
                    121:                                break;
                    122:                        }
                    123: 
                    124:                        /* allocate space for the rule header */
                    125:                        if (rwp == NULL)
                    126:                        {
                    127:                                RewriteRules[ruleset] = rwp =
                    128:                                        (struct rewrite *) xalloc(sizeof *rwp);
                    129:                        }
                    130:                        else
                    131:                        {
                    132:                                rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
                    133:                                rwp = rwp->r_next;
                    134:                        }
                    135:                        rwp->r_next = NULL;
                    136: 
                    137:                        /* expand and save the LHS */
                    138:                        *p = '\0';
                    139:                        expand(&buf[1], exbuf, &exbuf[sizeof exbuf], CurEnv);
                    140:                        rwp->r_lhs = prescan(exbuf, '\t', pvpbuf);
                    141:                        if (rwp->r_lhs != NULL)
                    142:                                rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
                    143: 
                    144:                        /* expand and save the RHS */
                    145:                        while (*++p == '\t')
                    146:                                continue;
                    147:                        q = p;
                    148:                        while (*p != '\0' && *p != '\t')
                    149:                                p++;
                    150:                        *p = '\0';
                    151:                        expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv);
                    152:                        rwp->r_rhs = prescan(exbuf, '\t', pvpbuf);
                    153:                        if (rwp->r_rhs != NULL)
                    154:                                rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);
                    155:                        break;
                    156: 
                    157:                  case 'S':             /* select rewriting set */
                    158:                        ruleset = atoi(&buf[1]);
                    159:                        if (ruleset >= MAXRWSETS || ruleset < 0)
                    160:                        {
                    161:                                syserr("bad ruleset %d (%d max)", ruleset, MAXRWSETS);
                    162:                                ruleset = 0;
                    163:                        }
                    164:                        rwp = NULL;
                    165:                        break;
                    166: 
                    167:                  case 'D':             /* macro definition */
                    168:                        define(buf[1], newstr(munchstring(&buf[2])), CurEnv);
                    169:                        break;
                    170: 
                    171:                  case 'H':             /* required header line */
                    172:                        (void) chompheader(&buf[1], TRUE);
                    173:                        break;
                    174: 
                    175:                  case 'C':             /* word class */
                    176:                  case 'F':             /* word class from file */
                    177:                        /* read list of words from argument or file */
                    178:                        if (buf[0] == 'F')
                    179:                        {
                    180:                                /* read from file */
                    181:                                for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)
                    182:                                        continue;
                    183:                                if (*p == '\0')
                    184:                                        p = "%s";
                    185:                                else
                    186:                                {
                    187:                                        *p = '\0';
                    188:                                        while (isspace(*++p))
                    189:                                                continue;
                    190:                                }
                    191:                                fileclass(buf[1], &buf[2], p);
                    192:                                break;
                    193:                        }
                    194: 
                    195:                        /* scan the list of words and set class for all */
                    196:                        for (p = &buf[2]; *p != '\0'; )
                    197:                        {
                    198:                                register char *wd;
                    199:                                char delim;
                    200: 
                    201:                                while (*p != '\0' && isspace(*p))
                    202:                                        p++;
                    203:                                wd = p;
                    204:                                while (*p != '\0' && !isspace(*p))
                    205:                                        p++;
                    206:                                delim = *p;
                    207:                                *p = '\0';
                    208:                                if (wd[0] != '\0')
                    209:                                        setclass(buf[1], wd);
                    210:                                *p = delim;
                    211:                        }
                    212:                        break;
                    213: 
                    214:                  case 'M':             /* define mailer */
                    215:                        makemailer(&buf[1]);
                    216:                        break;
                    217: 
                    218:                  case 'O':             /* set option */
                    219:                        setoption(buf[1], &buf[2], TRUE, FALSE);
                    220:                        break;
                    221: 
                    222:                  case 'P':             /* set precedence */
                    223:                        if (NumPriorities >= MAXPRIORITIES)
                    224:                        {
                    225:                                toomany('P', MAXPRIORITIES);
                    226:                                break;
                    227:                        }
                    228:                        for (p = &buf[1]; *p != '\0' && *p != '=' && *p != '\t'; p++)
                    229:                                continue;
                    230:                        if (*p == '\0')
                    231:                                goto badline;
                    232:                        *p = '\0';
                    233:                        Priorities[NumPriorities].pri_name = newstr(&buf[1]);
                    234:                        Priorities[NumPriorities].pri_val = atoi(++p);
                    235:                        NumPriorities++;
                    236:                        break;
                    237: 
                    238:                  case 'T':             /* trusted user(s) */
                    239:                        p = &buf[1];
                    240:                        while (*p != '\0')
                    241:                        {
                    242:                                while (isspace(*p))
                    243:                                        p++;
                    244:                                q = p;
                    245:                                while (*p != '\0' && !isspace(*p))
                    246:                                        p++;
                    247:                                if (*p != '\0')
                    248:                                        *p++ = '\0';
                    249:                                if (*q == '\0')
                    250:                                        continue;
                    251:                                for (pv = TrustedUsers; *pv != NULL; pv++)
                    252:                                        continue;
                    253:                                if (pv >= &TrustedUsers[MAXTRUST])
                    254:                                {
                    255:                                        toomany('T', MAXTRUST);
                    256:                                        break;
                    257:                                }
                    258:                                *pv = newstr(q);
                    259:                        }
                    260:                        break;
                    261: 
                    262:                  default:
                    263:                  badline:
                    264:                        syserr("unknown control line \"%s\"", buf);
                    265:                }
                    266:        }
                    267:        FileName = NULL;
                    268: }
                    269: /*
                    270: **  TOOMANY -- signal too many of some option
                    271: **
                    272: **     Parameters:
                    273: **             id -- the id of the error line
                    274: **             maxcnt -- the maximum possible values
                    275: **
                    276: **     Returns:
                    277: **             none.
                    278: **
                    279: **     Side Effects:
                    280: **             gives a syserr.
                    281: */
                    282: 
                    283: toomany(id, maxcnt)
                    284:        char id;
                    285:        int maxcnt;
                    286: {
                    287:        syserr("too many %c lines, %d max", id, maxcnt);
                    288: }
                    289: /*
                    290: **  FILECLASS -- read members of a class from a file
                    291: **
                    292: **     Parameters:
                    293: **             class -- class to define.
                    294: **             filename -- name of file to read.
                    295: **             fmt -- scanf string to use for match.
                    296: **
                    297: **     Returns:
                    298: **             none
                    299: **
                    300: **     Side Effects:
                    301: **
                    302: **             puts all lines in filename that match a scanf into
                    303: **                     the named class.
                    304: */
                    305: 
                    306: fileclass(class, filename, fmt)
                    307:        int class;
                    308:        char *filename;
                    309:        char *fmt;
                    310: {
                    311:        FILE *f;
                    312:        char buf[MAXLINE];
                    313: 
                    314:        f = fopen(filename, "r");
                    315:        if (f == NULL)
                    316:        {
                    317:                syserr("cannot open %s", filename);
                    318:                return;
                    319:        }
                    320: 
                    321:        while (fgets(buf, sizeof buf, f) != NULL)
                    322:        {
                    323:                register STAB *s;
                    324:                register char *p;
                    325: # ifdef SCANF
                    326:                char wordbuf[MAXNAME+1];
                    327: 
                    328:                if (sscanf(buf, fmt, wordbuf) != 1)
                    329:                        continue;
                    330:                p = wordbuf;
                    331: # else SCANF
                    332:                p = buf;
                    333: # endif SCANF
                    334: 
                    335:                /*
                    336:                **  Break up the match into words.
                    337:                */
                    338: 
                    339:                while (*p != '\0')
                    340:                {
                    341:                        register char *q;
                    342: 
                    343:                        /* strip leading spaces */
                    344:                        while (isspace(*p))
                    345:                                p++;
                    346:                        if (*p == '\0')
                    347:                                break;
                    348: 
                    349:                        /* find the end of the word */
                    350:                        q = p;
                    351:                        while (*p != '\0' && !isspace(*p))
                    352:                                p++;
                    353:                        if (*p != '\0')
                    354:                                *p++ = '\0';
                    355: 
                    356:                        /* enter the word in the symbol table */
                    357:                        s = stab(q, ST_CLASS, ST_ENTER);
                    358:                        setbitn(class, s->s_class);
                    359:                }
                    360:        }
                    361: 
                    362:        (void) fclose(f);
                    363: }
                    364: /*
                    365: **  MAKEMAILER -- define a new mailer.
                    366: **
                    367: **     Parameters:
                    368: **             line -- description of mailer.  This is in labeled
                    369: **                     fields.  The fields are:
                    370: **                        P -- the path to the mailer
                    371: **                        F -- the flags associated with the mailer
                    372: **                        A -- the argv for this mailer
                    373: **                        S -- the sender rewriting set
                    374: **                        R -- the recipient rewriting set
                    375: **                        E -- the eol string
                    376: **                     The first word is the canonical name of the mailer.
                    377: **
                    378: **     Returns:
                    379: **             none.
                    380: **
                    381: **     Side Effects:
                    382: **             enters the mailer into the mailer table.
                    383: */
                    384: 
                    385: makemailer(line)
                    386:        char *line;
                    387: {
                    388:        register char *p;
                    389:        register struct mailer *m;
                    390:        register STAB *s;
                    391:        int i;
                    392:        char fcode;
                    393:        extern int NextMailer;
                    394:        extern char **makeargv();
                    395:        extern char *munchstring();
                    396:        extern char *DelimChar;
                    397:        extern long atol();
                    398: 
                    399:        /* allocate a mailer and set up defaults */
                    400:        m = (struct mailer *) xalloc(sizeof *m);
                    401:        bzero((char *) m, sizeof *m);
                    402:        m->m_mno = NextMailer;
                    403:        m->m_eol = "\n";
                    404: 
                    405:        /* collect the mailer name */
                    406:        for (p = line; *p != '\0' && *p != ',' && !isspace(*p); p++)
                    407:                continue;
                    408:        if (*p != '\0')
                    409:                *p++ = '\0';
                    410:        m->m_name = newstr(line);
                    411: 
                    412:        /* now scan through and assign info from the fields */
                    413:        while (*p != '\0')
                    414:        {
                    415:                while (*p != '\0' && (*p == ',' || isspace(*p)))
                    416:                        p++;
                    417: 
                    418:                /* p now points to field code */
                    419:                fcode = *p;
                    420:                while (*p != '\0' && *p != '=' && *p != ',')
                    421:                        p++;
                    422:                if (*p++ != '=')
                    423:                {
                    424:                        syserr("`=' expected");
                    425:                        return;
                    426:                }
                    427:                while (isspace(*p))
                    428:                        p++;
                    429: 
                    430:                /* p now points to the field body */
                    431:                p = munchstring(p);
                    432: 
                    433:                /* install the field into the mailer struct */
                    434:                switch (fcode)
                    435:                {
                    436:                  case 'P':             /* pathname */
                    437:                        m->m_mailer = newstr(p);
                    438:                        break;
                    439: 
                    440:                  case 'F':             /* flags */
                    441:                        for (; *p != '\0'; p++)
                    442:                                setbitn(*p, m->m_flags);
                    443:                        break;
                    444: 
                    445:                  case 'S':             /* sender rewriting ruleset */
                    446:                  case 'R':             /* recipient rewriting ruleset */
                    447:                        i = atoi(p);
                    448:                        if (i < 0 || i >= MAXRWSETS)
                    449:                        {
                    450:                                syserr("invalid rewrite set, %d max", MAXRWSETS);
                    451:                                return;
                    452:                        }
                    453:                        if (fcode == 'S')
                    454:                                m->m_s_rwset = i;
                    455:                        else
                    456:                                m->m_r_rwset = i;
                    457:                        break;
                    458: 
                    459:                  case 'E':             /* end of line string */
                    460:                        m->m_eol = newstr(p);
                    461:                        break;
                    462: 
                    463:                  case 'A':             /* argument vector */
                    464:                        m->m_argv = makeargv(p);
                    465:                        break;
                    466: 
                    467:                  case 'M':             /* maximum message size */
                    468:                        m->m_maxsize = atol(p);
                    469:                        break;
                    470:                }
                    471: 
                    472:                p = DelimChar;
                    473:        }
                    474: 
                    475:        /* now store the mailer away */
                    476:        if (NextMailer >= MAXMAILERS)
                    477:        {
                    478:                syserr("too many mailers defined (%d max)", MAXMAILERS);
                    479:                return;
                    480:        }
                    481:        Mailer[NextMailer++] = m;
                    482:        s = stab(m->m_name, ST_MAILER, ST_ENTER);
                    483:        s->s_mailer = m;
                    484: }
                    485: /*
                    486: **  MUNCHSTRING -- translate a string into internal form.
                    487: **
                    488: **     Parameters:
                    489: **             p -- the string to munch.
                    490: **
                    491: **     Returns:
                    492: **             the munched string.
                    493: **
                    494: **     Side Effects:
                    495: **             Sets "DelimChar" to point to the string that caused us
                    496: **             to stop.
                    497: */
                    498: 
                    499: char *
                    500: munchstring(p)
                    501:        register char *p;
                    502: {
                    503:        register char *q;
                    504:        bool backslash = FALSE;
                    505:        bool quotemode = FALSE;
                    506:        static char buf[MAXLINE];
                    507:        extern char *DelimChar;
                    508: 
                    509:        for (q = buf; *p != '\0'; p++)
                    510:        {
                    511:                if (backslash)
                    512:                {
                    513:                        /* everything is roughly literal */
                    514:                        backslash = FALSE;
                    515:                        switch (*p)
                    516:                        {
                    517:                          case 'r':             /* carriage return */
                    518:                                *q++ = '\r';
                    519:                                continue;
                    520: 
                    521:                          case 'n':             /* newline */
                    522:                                *q++ = '\n';
                    523:                                continue;
                    524: 
                    525:                          case 'f':             /* form feed */
                    526:                                *q++ = '\f';
                    527:                                continue;
                    528: 
                    529:                          case 'b':             /* backspace */
                    530:                                *q++ = '\b';
                    531:                                continue;
                    532:                        }
                    533:                        *q++ = *p;
                    534:                }
                    535:                else
                    536:                {
                    537:                        if (*p == '\\')
                    538:                                backslash = TRUE;
                    539:                        else if (*p == '"')
                    540:                                quotemode = !quotemode;
                    541:                        else if (quotemode || *p != ',')
                    542:                                *q++ = *p;
                    543:                        else
                    544:                                break;
                    545:                }
                    546:        }
                    547: 
                    548:        DelimChar = p;
                    549:        *q++ = '\0';
                    550:        return (buf);
                    551: }
                    552: /*
                    553: **  MAKEARGV -- break up a string into words
                    554: **
                    555: **     Parameters:
                    556: **             p -- the string to break up.
                    557: **
                    558: **     Returns:
                    559: **             a char **argv (dynamically allocated)
                    560: **
                    561: **     Side Effects:
                    562: **             munges p.
                    563: */
                    564: 
                    565: char **
                    566: makeargv(p)
                    567:        register char *p;
                    568: {
                    569:        char *q;
                    570:        int i;
                    571:        char **avp;
                    572:        char *argv[MAXPV + 1];
                    573: 
                    574:        /* take apart the words */
                    575:        i = 0;
                    576:        while (*p != '\0' && i < MAXPV)
                    577:        {
                    578:                q = p;
                    579:                while (*p != '\0' && !isspace(*p))
                    580:                        p++;
                    581:                while (isspace(*p))
                    582:                        *p++ = '\0';
                    583:                argv[i++] = newstr(q);
                    584:        }
                    585:        argv[i++] = NULL;
                    586: 
                    587:        /* now make a copy of the argv */
                    588:        avp = (char **) xalloc(sizeof *avp * i);
                    589:        bcopy((char *) argv, (char *) avp, sizeof *avp * i);
                    590: 
                    591:        return (avp);
                    592: }
                    593: /*
                    594: **  PRINTRULES -- print rewrite rules (for debugging)
                    595: **
                    596: **     Parameters:
                    597: **             none.
                    598: **
                    599: **     Returns:
                    600: **             none.
                    601: **
                    602: **     Side Effects:
                    603: **             prints rewrite rules.
                    604: */
                    605: 
                    606: # ifdef DEBUG
                    607: 
                    608: printrules()
                    609: {
                    610:        register struct rewrite *rwp;
                    611:        register int ruleset;
                    612: 
                    613:        for (ruleset = 0; ruleset < 10; ruleset++)
                    614:        {
                    615:                if (RewriteRules[ruleset] == NULL)
                    616:                        continue;
                    617:                printf("\n----Rule Set %d:", ruleset);
                    618: 
                    619:                for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next)
                    620:                {
                    621:                        printf("\nLHS:");
                    622:                        printav(rwp->r_lhs);
                    623:                        printf("RHS:");
                    624:                        printav(rwp->r_rhs);
                    625:                }
                    626:        }
                    627: }
                    628: 
                    629: # endif DEBUG
                    630: /*
                    631: **  SETOPTION -- set global processing option
                    632: **
                    633: **     Parameters:
                    634: **             opt -- option name.
                    635: **             val -- option value (as a text string).
                    636: **             safe -- set if this came from a configuration file.
                    637: **                     Some options (if set from the command line) will
                    638: **                     reset the user id to avoid security problems.
                    639: **             sticky -- if set, don't let other setoptions override
                    640: **                     this value.
                    641: **
                    642: **     Returns:
                    643: **             none.
                    644: **
                    645: **     Side Effects:
                    646: **             Sets options as implied by the arguments.
                    647: */
                    648: 
                    649: static BITMAP  StickyOpt;              /* set if option is stuck */
                    650: extern char    *NetName;               /* name of home (local) network */
                    651: # ifdef SMTP
                    652: # ifdef WIZ
                    653: extern char    *WizWord;               /* the stored wizard password */
                    654: # endif WIZ
                    655: # endif SMTP
                    656: 
                    657: setoption(opt, val, safe, sticky)
                    658:        char opt;
                    659:        char *val;
                    660:        bool safe;
                    661:        bool sticky;
                    662: {
                    663:        extern bool atobool();
                    664:        extern time_t convtime();
                    665:        extern int QueueLA;
                    666:        extern int RefuseLA;
                    667:        extern bool trusteduser();
                    668:        extern char *username();
                    669: 
                    670: # ifdef DEBUG
                    671:        if (tTd(37, 1))
                    672:                printf("setoption %c=%s", opt, val);
                    673: # endif DEBUG
                    674: 
                    675:        /*
                    676:        **  See if this option is preset for us.
                    677:        */
                    678: 
                    679:        if (bitnset(opt, StickyOpt))
                    680:        {
                    681: # ifdef DEBUG
                    682:                if (tTd(37, 1))
                    683:                        printf(" (ignored)\n");
                    684: # endif DEBUG
                    685:                return;
                    686:        }
                    687: 
                    688:        /*
                    689:        **  Check to see if this option can be specified by this user.
                    690:        */
                    691: 
                    692:        if (!safe && getruid() == 0)
                    693:                safe = TRUE;
                    694:        if (!safe && index("deiLmorsv", opt) == NULL)
                    695:        {
                    696: # ifdef DEBUG
                    697:                if (tTd(37, 1))
                    698:                        printf(" (unsafe)");
                    699: # endif DEBUG
                    700:                if (getruid() != geteuid())
                    701:                {
                    702:                        printf("(Resetting uid)\n");
                    703:                        (void) setgid(getgid());
                    704:                        (void) setuid(getuid());
                    705:                }
                    706:        }
                    707: #ifdef DEBUG
                    708:        else if (tTd(37, 1))
                    709:                printf("\n");
                    710: #endif DEBUG
                    711: 
                    712:        switch (opt)
                    713:        {
                    714:          case 'A':             /* set default alias file */
                    715:                if (val[0] == '\0')
                    716:                        AliasFile = "aliases";
                    717:                else
                    718:                        AliasFile = newstr(val);
                    719:                break;
                    720: 
                    721:          case 'a':             /* look N minutes for "@:@" in alias file */
                    722:                if (val[0] == '\0')
                    723:                        SafeAlias = 5;
                    724:                else
                    725:                        SafeAlias = atoi(val);
                    726:                break;
                    727: 
                    728:          case 'B':             /* substitution for blank character */
                    729:                SpaceSub = val[0];
                    730:                if (SpaceSub == '\0')
                    731:                        SpaceSub = ' ';
                    732:                break;
                    733: 
                    734:          case 'c':             /* don't connect to "expensive" mailers */
                    735:                NoConnect = atobool(val);
                    736:                break;
                    737: 
                    738:          case 'C':             /* checkpoint after N connections */
                    739:                CheckPointLimit = atoi(val);
                    740:                break;
                    741: 
                    742:          case 'd':             /* delivery mode */
                    743:                switch (*val)
                    744:                {
                    745:                  case '\0':
                    746:                        SendMode = SM_DELIVER;
                    747:                        break;
                    748: 
                    749:                  case SM_QUEUE:        /* queue only */
                    750: #ifndef QUEUE
                    751:                        syserr("need QUEUE to set -odqueue");
                    752: #endif QUEUE
                    753:                        /* fall through..... */
                    754: 
                    755:                  case SM_DELIVER:      /* do everything */
                    756:                  case SM_FORK:         /* fork after verification */
                    757:                        SendMode = *val;
                    758:                        break;
                    759: 
                    760:                  default:
                    761:                        syserr("Unknown delivery mode %c", *val);
                    762:                        exit(EX_USAGE);
                    763:                }
                    764:                break;
                    765: 
                    766:          case 'D':             /* rebuild alias database as needed */
                    767:                AutoRebuild = atobool(val);
                    768:                break;
                    769: 
                    770:          case 'e':             /* set error processing mode */
                    771:                switch (*val)
                    772:                {
                    773:                  case EM_QUIET:        /* be silent about it */
                    774:                  case EM_MAIL:         /* mail back */
                    775:                  case EM_BERKNET:      /* do berknet error processing */
                    776:                  case EM_WRITE:        /* write back (or mail) */
                    777:                        HoldErrs = TRUE;
                    778:                        /* fall through... */
                    779: 
                    780:                  case EM_PRINT:        /* print errors normally (default) */
                    781:                        ErrorMode = *val;
                    782:                        break;
                    783:                }
                    784:                break;
                    785: 
                    786:          case 'F':             /* file mode */
                    787:                FileMode = atooct(val) & 0777;
                    788:                break;
                    789: 
                    790:          case 'f':             /* save Unix-style From lines on front */
                    791:                SaveFrom = atobool(val);
                    792:                break;
                    793: 
                    794:          case 'g':             /* default gid */
                    795:                DefGid = atoi(val);
                    796:                break;
                    797: 
                    798:          case 'H':             /* help file */
                    799:                if (val[0] == '\0')
                    800:                        HelpFile = "sendmail.hf";
                    801:                else
                    802:                        HelpFile = newstr(val);
                    803:                break;
                    804: 
                    805:          case 'i':             /* ignore dot lines in message */
                    806:                IgnrDot = atobool(val);
                    807:                break;
                    808: 
                    809:          case 'L':             /* log level */
                    810:                LogLevel = atoi(val);
                    811:                break;
                    812: 
                    813:          case 'M':             /* define macro */
                    814:                define(val[0], newstr(&val[1]), CurEnv);
                    815:                sticky = FALSE;
                    816:                break;
                    817: 
                    818:          case 'm':             /* send to me too */
                    819:                MeToo = atobool(val);
                    820:                break;
                    821: 
                    822:          case 'n':             /* validate RHS in newaliases */
                    823:                CheckAliases = atobool(val);
                    824:                break;
                    825: 
                    826: # ifdef DAEMON
                    827:          case 'N':             /* home (local?) network name */
                    828:                NetName = newstr(val);
                    829:                break;
                    830: # endif DAEMON
                    831: 
                    832:          case 'o':             /* assume old style headers */
                    833:                if (atobool(val))
                    834:                        CurEnv->e_flags |= EF_OLDSTYLE;
                    835:                else
                    836:                        CurEnv->e_flags &= ~EF_OLDSTYLE;
                    837:                break;
                    838: 
                    839:          case 'P':             /* postmaster copy address for returned mail */
                    840:                PostMasterCopy = newstr(val);
                    841:                break;
                    842: 
                    843:          case 'q':             /* slope of queue only function */
                    844:                QueueFactor = atoi(val);
                    845:                break;
                    846: 
                    847:          case 'Q':             /* queue directory */
                    848:                if (val[0] == '\0')
                    849:                        QueueDir = "mqueue";
                    850:                else
                    851:                        QueueDir = newstr(val);
                    852:                break;
                    853: 
                    854:          case 'r':             /* read timeout */
                    855:                ReadTimeout = convtime(val);
                    856:                break;
                    857: 
                    858:          case 'S':             /* status file */
                    859:                if (val[0] == '\0')
                    860:                        StatFile = "sendmail.st";
                    861:                else
                    862:                        StatFile = newstr(val);
                    863:                break;
                    864: 
                    865:          case 's':             /* be super safe, even if expensive */
                    866:                SuperSafe = atobool(val);
                    867:                break;
                    868: 
                    869:          case 'T':             /* queue timeout */
                    870:                TimeOut = convtime(val);
                    871:                /*FALLTHROUGH*/
                    872: 
                    873:          case 't':             /* time zone name */
                    874:                break;
                    875: 
                    876:          case 'u':             /* set default uid */
                    877:                DefUid = atoi(val);
                    878:                break;
                    879: 
                    880:          case 'v':             /* run in verbose mode */
                    881:                Verbose = atobool(val);
                    882:                break;
                    883: 
                    884: # ifdef SMTP
                    885: # ifdef WIZ
                    886:          case 'W':             /* set the wizards password */
                    887:                WizWord = newstr(val);
                    888:                break;
                    889: # endif WIZ
                    890: # endif SMTP
                    891: 
                    892:          case 'x':             /* load avg at which to auto-queue msgs */
                    893:                QueueLA = atoi(val);
                    894:                break;
                    895: 
                    896:          case 'X':             /* load avg at which to auto-reject connections */
                    897:                RefuseLA = atoi(val);
                    898:                break;
                    899: 
                    900:          case 'y':             /* work recipient factor */
                    901:                WkRecipFact = atoi(val);
                    902:                break;
                    903: 
                    904:          case 'Y':             /* fork jobs during queue runs */
                    905:                ForkQueueRuns = atobool(val);
                    906:                break;
                    907: 
                    908:          case 'z':             /* work message class factor */
                    909:                WkClassFact = atoi(val);
                    910:                break;
                    911: 
                    912:          case 'Z':             /* work time factor */
                    913:                WkTimeFact = atoi(val);
                    914:                break;
                    915: 
                    916:          default:
                    917:                break;
                    918:        }
                    919:        if (sticky)
                    920:                setbitn(opt, StickyOpt);
                    921:        return;
                    922: }
                    923: /*
                    924: **  SETCLASS -- set a word into a class
                    925: **
                    926: **     Parameters:
                    927: **             class -- the class to put the word in.
                    928: **             word -- the word to enter
                    929: **
                    930: **     Returns:
                    931: **             none.
                    932: **
                    933: **     Side Effects:
                    934: **             puts the word into the symbol table.
                    935: */
                    936: 
                    937: setclass(class, word)
                    938:        int class;
                    939:        char *word;
                    940: {
                    941:        register STAB *s;
                    942: 
                    943:        s = stab(word, ST_CLASS, ST_ENTER);
                    944:        setbitn(class, s->s_class);
                    945: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.