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