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

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

unix.superglobalmegacorp.com

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