# 2.11BSD#431 - /usr/src/usr.sbin/sendmail/src/readcf.c

##### Functions

    fileclass         X
    makeargv          X
    makemailer        X
    munchstring       X
    printrules        X
    readcf            X
    setclass          X
    setoption         X
    toomany           X

       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: #if !defined(lint) && !defined(NOSCCS)
      12: static char SccsId[] = "@(#)readcf.c	5.10.1 (2.11BSD GTE) 3/07/95";
      13: #endif
      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:     register 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:     register char   *p;
     662:
     663: # ifdef DEBUG
     664:     if (tTd(37, 1))
     665:         printf("setoption %c=%s", opt, val);
     666: # endif DEBUG
     667:
     668:     /*
     669: 	**  See if this option is preset for us.
     670: 	*/
     671:
     672:     if (bitnset(opt, StickyOpt))
     673:     {
     674: # ifdef DEBUG
     675:         if (tTd(37, 1))
     676:             printf(" (ignored)\n");
     677: # endif DEBUG
     678:         return;
     679:     }
     680:
     681:     /*
     682: 	**  Check to see if this option can be specified by this user.
     683: 	*/
     684:
     685:     if (!safe && getruid() == 0)
     686:         safe = TRUE;
     687:     if (!safe && index("deiLmorsv", opt) == NULL)
     688:     {
     689: # ifdef DEBUG
     690:         if (tTd(37, 1))
     691:             printf(" (unsafe)");
     692: # endif DEBUG
     693:         if (getruid() != geteuid())
     694:         {
     695:             printf("(Resetting uid)\n");
     696:             (void) setgid(getgid());
     697:             (void) setuid(getuid());
     698:         }
     699:     }
     700: #ifdef DEBUG
     701:     else if (tTd(37, 1))
     702:         printf("\n");
     703: #endif DEBUG
     704:
     705:     switch (opt)
     706:     {
     707:       case 'A':     /* set default alias file */
     708:         if (val[0] == '\0')
     709:             AliasFile = "aliases";
     710:         else
     711:             AliasFile = newstr(val);
     712:         break;
     713:
     714:       case 'a':     /* look N minutes for "@:@" in alias file */
     715:         if (val[0] == '\0')
     716:             SafeAlias = 5;
     717:         else
     718:             SafeAlias = atoi(val);
     719:         break;
     720:
     721:       case 'B':     /* substitution for blank character */
     722:         SpaceSub = val[0];
     723:         if (SpaceSub == '\0')
     724:             SpaceSub = ' ';
     725:         break;
     726:
     727:       case 'c':     /* don't connect to "expensive" mailers */
     728:         NoConnect = atobool(val);
     729:         break;
     730:
     731:       case 'C':     /* checkpoint after N connections */
     732:         CheckPointLimit = atoi(val);
     733:         break;
     734:
     735:       case 'd':     /* delivery mode */
     736:         switch (*val)
     737:         {
     738:           case '\0':
     739:             SendMode = SM_DELIVER;
     740:             break;
     741:
     742:           case SM_QUEUE:    /* queue only */
     743: #ifndef QUEUE
     744:             syserr("need QUEUE to set -odqueue");
     745: #endif QUEUE
     746:             /* fall through..... */
     747:
     748:           case SM_DELIVER:  /* do everything */
     749:           case SM_FORK:     /* fork after verification */
     750:             SendMode = *val;
     751:             break;
     752:
     753:           default:
     754:             syserr("Unknown delivery mode %c", *val);
     755:             exit(EX_USAGE);
     756:         }
     757:         break;
     758:
     759:       case 'D':     /* rebuild alias database as needed */
     760:         AutoRebuild = atobool(val);
     761:         break;
     762:
     763:       case 'e':     /* set error processing mode */
     764:         switch (*val)
     765:         {
     766:           case EM_QUIET:    /* be silent about it */
     767:           case EM_MAIL:     /* mail back */
     768:           case EM_BERKNET:  /* do berknet error processing */
     769:           case EM_WRITE:    /* write back (or mail) */
     770:             HoldErrs = TRUE;
     771:             /* fall through... */
     772:
     773:           case EM_PRINT:    /* print errors normally (default) */
     774:             ErrorMode = *val;
     775:             break;
     776:         }
     777:         break;
     778:
     779:       case 'F':     /* file mode */
     780:         FileMode = atooct(val) & 0777;
     781:         break;
     782:
     783:       case 'f':     /* save Unix-style From lines on front */
     784:         SaveFrom = atobool(val);
     785:         break;
     786:
     787:       case 'g':     /* default gid */
     788:         DefGid = atoi(val);
     789:         break;
     790:
     791:       case 'H':     /* help file */
     792:         if (val[0] == '\0')
     793:             HelpFile = "sendmail.hf";
     794:         else
     795:             HelpFile = newstr(val);
     796:         break;
     797:
     798:       case 'i':     /* ignore dot lines in message */
     799:         IgnrDot = atobool(val);
     800:         break;
     801:
     802:       case 'L':     /* log level */
     803:         LogLevel = atoi(val);
     804:         break;
     805:
     806:       case 'M':     /* define macro */
     807:         p = newstr(&val[1]);
     808:         if (!safe)
     809:             cleanstrcpy(p, p, MAXNAME);
     810:         define(val[0], p, CurEnv);
     811:         sticky = FALSE;
     812:         break;
     813:
     814:       case 'm':     /* send to me too */
     815:         MeToo = atobool(val);
     816:         break;
     817:
     818:       case 'n':     /* validate RHS in newaliases */
     819:         CheckAliases = atobool(val);
     820:         break;
     821:
     822: # ifdef DAEMON
     823:       case 'N':     /* home (local?) network name */
     824:         NetName = newstr(val);
     825:         break;
     826: # endif DAEMON
     827:
     828:       case 'o':     /* assume old style headers */
     829:         if (atobool(val))
     830:             CurEnv->e_flags |= EF_OLDSTYLE;
     831:         else
     832:             CurEnv->e_flags &= ~EF_OLDSTYLE;
     833:         break;
     834:
     835:       case 'P':     /* postmaster copy address for returned mail */
     836:         PostMasterCopy = newstr(val);
     837:         break;
     838:
     839:       case 'q':     /* slope of queue only function */
     840:         QueueFactor = atoi(val);
     841:         break;
     842:
     843:       case 'Q':     /* queue directory */
     844:         if (val[0] == '\0')
     845:             QueueDir = "mqueue";
     846:         else
     847:             QueueDir = newstr(val);
     848:         break;
     849:
     850:       case 'r':     /* read timeout */
     851:         ReadTimeout = convtime(val);
     852:         break;
     853:
     854:       case 'S':     /* status file */
     855:         if (val[0] == '\0')
     856:             StatFile = "sendmail.st";
     857:         else
     858:             StatFile = newstr(val);
     859:         break;
     860:
     861:       case 's':     /* be super safe, even if expensive */
     862:         SuperSafe = atobool(val);
     863:         break;
     864:
     865:       case 'T':     /* queue timeout */
     866:         TimeOut = convtime(val);
     867:         break;
     868:
     869:       case 't':     /* time zone name */
     870:         break;
     871:
     872:       case 'u':     /* set default uid */
     873:         DefUid = atoi(val);
     874:         break;
     875:
     876:       case 'v':     /* run in verbose mode */
     877:         Verbose = atobool(val);
     878:         break;
     879:
     880: # ifdef SMTP
     881: # ifdef WIZ
     882:       case 'W':     /* set the wizards password */
     883:         WizWord = newstr(val);
     884:         break;
     885: # endif WIZ
     886: # endif SMTP
     887:
     888:       case 'x':     /* load avg at which to auto-queue msgs */
     889:         QueueLA = atoi(val);
     890:         break;
     891:
     892:       case 'X':     /* load avg at which to auto-reject connections */
     893:         RefuseLA = atoi(val);
     894:         break;
     895:
     896:       case 'y':     /* work recipient factor */
     897:         WkRecipFact = atoi(val);
     898:         break;
     899:
     900:       case 'Y':     /* fork jobs during queue runs */
     901:         ForkQueueRuns = atobool(val);
     902:         break;
     903:
     904:       case 'z':     /* work message class factor */
     905:         WkClassFact = atoi(val);
     906:         break;
     907:
     908:       case 'Z':     /* work time factor */
     909:         WkTimeFact = atoi(val);
     910:         break;
     911:
     912:       default:
     913:         break;
     914:     }
     915:     if (sticky)
     916:         setbitn(opt, StickyOpt);
     917:     return;
     918: }
     919: /*
     920: **  SETCLASS -- set a word into a class
     921: **
     922: **	Parameters:
     923: **		class -- the class to put the word in.
     924: **		word -- the word to enter
     925: **
     926: **	Returns:
     927: **		none.
     928: **
     929: **	Side Effects:
     930: **		puts the word into the symbol table.
     931: */
     932:
     933: setclass(class, word)
     934:     int class;
     935:     char *word;
     936: {
     937:     register STAB *s;
     938:
     939:     s = stab(word, ST_CLASS, ST_ENTER);
     940:     setbitn(class, s->s_class);
     941: }

#### Defined functions

fileclass defined in line 298; used 1 times

- in line 183

makeargv defined in line 557; used 2 times

- in line 386, 456

makemailer defined in line 377; used 1 times

- in line 207

munchstring defined in line 491; used 4 times

- in line 69, 160, 387, 423

printrules defined in line 600; used 1 times

- in /usr/src/usr.sbin/sendmail/src/main.c line 517

readcf defined in line 54; used 1 times

- in /usr/src/usr.sbin/sendmail/src/main.c line 421

setclass defined in line 933; used 3 times

- in line 201
- in /usr/src/usr.sbin/sendmail/src/main.c line 251, 259

setoption defined in line 649; used 6 times

- in line 211
- in /usr/src/usr.sbin/sendmail/src/main.c line 375, 399-403(2), 452-455(2)

toomany defined in line 275; used 2 times

- in line 217, 247

#### Defined variables

SccsId defined in line 12; never used
StickyOpt defined in line 641; used 2 times

- in line 672, 916

Last modified: 1995-03-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2574 |