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

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