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

##### Functions

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

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

#### Defined functions

fileclass defined in line 304; used 1 times

- in line 189

makeargv defined in line 563; used 2 times

- in line 392, 462

makemailer defined in line 383; used 1 times

- in line 213

munchstring defined in line 497; used 4 times

- in line 75, 166, 393, 429

printrules defined in line 606; used 1 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 513

readcf defined in line 60; used 1 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 426

setclass defined in line 935; used 3 times

- in line 207
- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 256, 264

setoption defined in line 655; used 6 times

- in line 217
- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 381, 404-408(2), 448-451(2)

toomany defined in line 281; used 2 times

- in line 223, 253

#### Defined variables

StickyOpt defined in line 647; used 2 times

- in line 677, 918

sccsid defined in line 18; never used

Last modified: 1988-09-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2114 |