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