Annotation of 43BSDReno/usr.sbin/sendmail/src/readcf.c, revision 1.1

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

unix.superglobalmegacorp.com

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