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

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

unix.superglobalmegacorp.com

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