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

unix.superglobalmegacorp.com

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