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

unix.superglobalmegacorp.com

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