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