13313Seric # include "sendmail.h" 23308Seric 3*9341Seric SCCSID(@(#)readcf.c 3.46 11/24/82); 43308Seric 53308Seric /* 63308Seric ** READCF -- read control file. 73308Seric ** 83308Seric ** This routine reads the control file and builds the internal 93308Seric ** form. 103308Seric ** 114432Seric ** The file is formatted as a sequence of lines, each taken 124432Seric ** atomically. The first character of each line describes how 134432Seric ** the line is to be interpreted. The lines are: 144432Seric ** Dxval Define macro x to have value val. 154432Seric ** Cxword Put word into class x. 164432Seric ** Fxfile [fmt] Read file for lines to put into 174432Seric ** class x. Use scanf string 'fmt' 184432Seric ** or "%s" if not present. Fmt should 194432Seric ** only produce one string-valued result. 204432Seric ** Hname: value Define header with field-name 'name' 214432Seric ** and value as specified; this will be 224432Seric ** macro expanded immediately before 234432Seric ** use. 244432Seric ** Sn Use rewriting set n. 254432Seric ** Rlhs rhs Rewrite addresses that match lhs to 264432Seric ** be rhs. 278252Seric ** Mn p f s r a Define mailer. n - internal name, 288252Seric ** p - pathname, f - flags, s - rewriting 298252Seric ** ruleset for sender, s - rewriting ruleset 308252Seric ** for recipients, a - argument vector. 318252Seric ** Oxvalue Set option x to value. 328252Seric ** Pname=value Set precedence name to value. 334432Seric ** 343308Seric ** Parameters: 353308Seric ** cfname -- control file name. 364217Seric ** safe -- set if this is a system configuration file. 374217Seric ** Non-system configuration files can not do 384217Seric ** certain things (e.g., leave the SUID bit on 394217Seric ** when executing mailers). 403308Seric ** 413308Seric ** Returns: 423308Seric ** none. 433308Seric ** 443308Seric ** Side Effects: 453308Seric ** Builds several internal tables. 463308Seric */ 473308Seric 484217Seric readcf(cfname, safe) 493308Seric char *cfname; 504217Seric bool safe; 513308Seric { 523308Seric FILE *cf; 538547Seric int class; 548547Seric int ruleset = 0; 558547Seric char *q; 568547Seric char **pv; 573308Seric char buf[MAXLINE]; 583308Seric register char *p; 593308Seric struct rewrite *rwp = NULL; 603308Seric extern char **prescan(); 613308Seric extern char **copyplist(); 625909Seric char exbuf[MAXLINE]; 633308Seric 643308Seric cf = fopen(cfname, "r"); 653308Seric if (cf == NULL) 663308Seric { 673308Seric syserr("cannot open %s", cfname); 683308Seric exit(EX_OSFILE); 693308Seric } 703308Seric 718056Seric LineNumber = 0; 727854Seric while (fgetfolded(buf, sizeof buf, cf) != NULL) 733308Seric { 743308Seric switch (buf[0]) 753308Seric { 763308Seric case '\0': 773308Seric case '#': /* comment */ 783308Seric break; 793308Seric 803308Seric case 'R': /* rewriting rule */ 813308Seric for (p = &buf[1]; *p != '\0' && *p != '\t'; p++) 823308Seric continue; 833308Seric 843308Seric if (*p == '\0') 855909Seric { 868056Seric syserr("line %d: invalid rewrite line \"%s\"", 878056Seric LineNumber, buf); 885909Seric break; 895909Seric } 905909Seric 915909Seric /* allocate space for the rule header */ 925909Seric if (rwp == NULL) 935909Seric { 945909Seric RewriteRules[ruleset] = rwp = 955909Seric (struct rewrite *) xalloc(sizeof *rwp); 965909Seric } 973308Seric else 983308Seric { 995909Seric rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 1005909Seric rwp = rwp->r_next; 1015909Seric } 1025909Seric rwp->r_next = NULL; 1033308Seric 1045909Seric /* expand and save the LHS */ 1055909Seric *p = '\0'; 1066991Seric expand(&buf[1], exbuf, &exbuf[sizeof exbuf], CurEnv); 1075909Seric rwp->r_lhs = prescan(exbuf, '\t'); 1085909Seric if (rwp->r_lhs != NULL) 1095909Seric rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); 1105909Seric 1115909Seric /* expand and save the RHS */ 1125909Seric while (*++p == '\t') 1135909Seric continue; 1147231Seric q = p; 1157231Seric while (*p != '\0' && *p != '\t') 1167231Seric p++; 1177231Seric *p = '\0'; 1187231Seric expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv); 1195909Seric rwp->r_rhs = prescan(exbuf, '\t'); 1205909Seric if (rwp->r_rhs != NULL) 1215909Seric rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); 1223308Seric break; 1233308Seric 1244072Seric case 'S': /* select rewriting set */ 1254072Seric ruleset = atoi(&buf[1]); 1268056Seric if (ruleset >= MAXRWSETS || ruleset < 0) 1278056Seric { 1288056Seric syserr("readcf: line %d: bad ruleset %d (%d max)", 1298056Seric LineNumber, ruleset, MAXRWSETS); 1308056Seric ruleset = 0; 1318056Seric } 1324072Seric rwp = NULL; 1334072Seric break; 1344072Seric 1353308Seric case 'D': /* macro definition */ 1363308Seric define(buf[1], newstr(&buf[2])); 1373308Seric break; 1383308Seric 1393387Seric case 'H': /* required header line */ 1404088Seric (void) chompheader(&buf[1], TRUE); 1413387Seric break; 1423387Seric 1434061Seric case 'C': /* word class */ 1444432Seric case 'F': /* word class from file */ 1454061Seric class = buf[1]; 1464061Seric if (!isalpha(class)) 1474061Seric goto badline; 1484061Seric if (isupper(class)) 1494061Seric class -= 'A'; 1504061Seric else 1514061Seric class -= 'a'; 1524432Seric 1534432Seric /* read list of words from argument or file */ 1544432Seric if (buf[0] == 'F') 1554432Seric { 1564432Seric /* read from file */ 1574432Seric for (p = &buf[2]; *p != '\0' && !isspace(*p); p++) 1584432Seric continue; 1594432Seric if (*p == '\0') 1604432Seric p = "%s"; 1614432Seric else 1624432Seric { 1634432Seric *p = '\0'; 1644432Seric while (isspace(*++p)) 1654432Seric continue; 1664432Seric } 1674432Seric fileclass(class, &buf[2], p); 1684432Seric break; 1694432Seric } 1704061Seric 1714432Seric /* scan the list of words and set class for all */ 1724061Seric for (p = &buf[2]; *p != '\0'; ) 1734061Seric { 1744061Seric register char *wd; 1754061Seric char delim; 1764061Seric register STAB *s; 1774061Seric 1784061Seric while (*p != '\0' && isspace(*p)) 1794061Seric p++; 1804061Seric wd = p; 1814061Seric while (*p != '\0' && !isspace(*p)) 1824061Seric p++; 1834061Seric delim = *p; 1844061Seric *p = '\0'; 1854061Seric if (wd[0] != '\0') 1864061Seric { 1874103Seric s = stab(wd, ST_CLASS, ST_ENTER); 1886275Seric s->s_class |= 1L << class; 1894061Seric } 1904061Seric *p = delim; 1914061Seric } 1924061Seric break; 1934061Seric 1944096Seric case 'M': /* define mailer */ 1954217Seric makemailer(&buf[1], safe); 1964096Seric break; 1974096Seric 1988252Seric case 'O': /* set option */ 1998269Seric setoption(buf[1], &buf[2], safe, FALSE); 2008252Seric break; 2018252Seric 2028252Seric case 'P': /* set precedence */ 2038252Seric if (NumPriorities >= MAXPRIORITIES) 2048252Seric { 2058547Seric toomany('P', MAXPRIORITIES); 2068252Seric break; 2078252Seric } 2088252Seric for (p = &buf[1]; *p != '\0' && *p != '='; p++) 2098252Seric continue; 2108252Seric if (*p == '\0') 2118252Seric goto badline; 2128252Seric *p = '\0'; 2138252Seric Priorities[NumPriorities].pri_name = newstr(&buf[1]); 2148252Seric Priorities[NumPriorities].pri_val = atoi(++p); 2158252Seric NumPriorities++; 2168252Seric break; 2178252Seric 2188547Seric case 'T': /* trusted user(s) */ 2198547Seric p = &buf[1]; 2208547Seric while (*p != '\0') 2218547Seric { 2228547Seric while (isspace(*p)) 2238547Seric p++; 2248547Seric q = p; 2258547Seric while (*p != '\0' && !isspace(*p)) 2268547Seric p++; 2278547Seric if (*p != '\0') 2288547Seric *p++ = '\0'; 2298547Seric if (*q == '\0') 2308547Seric continue; 2318547Seric for (pv = TrustedUsers; *pv != NULL; pv++) 2328547Seric continue; 2338547Seric if (pv >= &TrustedUsers[MAXTRUST]) 2348547Seric { 2358547Seric toomany('T', MAXTRUST); 2368547Seric break; 2378547Seric } 2388547Seric *pv = newstr(q); 2398547Seric } 2408547Seric break; 2418547Seric 2423308Seric default: 2434061Seric badline: 2448056Seric syserr("readcf: line %d: unknown control line \"%s\"", 2458056Seric LineNumber, buf); 2463308Seric } 2473308Seric } 2484096Seric } 2494096Seric /* 2508547Seric ** TOOMANY -- signal too many of some option 2518547Seric ** 2528547Seric ** Parameters: 2538547Seric ** id -- the id of the error line 2548547Seric ** maxcnt -- the maximum possible values 2558547Seric ** 2568547Seric ** Returns: 2578547Seric ** none. 2588547Seric ** 2598547Seric ** Side Effects: 2608547Seric ** gives a syserr. 2618547Seric */ 2628547Seric 2638547Seric toomany(id, maxcnt) 2648547Seric char id; 2658547Seric int maxcnt; 2668547Seric { 2678547Seric syserr("readcf: line %d: too many %c lines, %d max", 2688547Seric LineNumber, id, maxcnt); 2698547Seric } 2708547Seric /* 2714432Seric ** FILECLASS -- read members of a class from a file 2724432Seric ** 2734432Seric ** Parameters: 2744432Seric ** class -- class to define. 2754432Seric ** filename -- name of file to read. 2764432Seric ** fmt -- scanf string to use for match. 2774432Seric ** 2784432Seric ** Returns: 2794432Seric ** none 2804432Seric ** 2814432Seric ** Side Effects: 2824432Seric ** 2834432Seric ** puts all lines in filename that match a scanf into 2844432Seric ** the named class. 2854432Seric */ 2864432Seric 2874432Seric fileclass(class, filename, fmt) 2884432Seric int class; 2894432Seric char *filename; 2904432Seric char *fmt; 2914432Seric { 2924432Seric register FILE *f; 2934432Seric char buf[MAXLINE]; 2944432Seric 2954432Seric f = fopen(filename, "r"); 2964432Seric if (f == NULL) 2974432Seric { 2984432Seric syserr("cannot open %s", filename); 2994432Seric return; 3004432Seric } 3014432Seric 3024432Seric while (fgets(buf, sizeof buf, f) != NULL) 3034432Seric { 3044432Seric register STAB *s; 3054432Seric char wordbuf[MAXNAME+1]; 3064432Seric 3074432Seric if (sscanf(buf, fmt, wordbuf) != 1) 3084432Seric continue; 3094432Seric s = stab(wordbuf, ST_CLASS, ST_ENTER); 3106275Seric s->s_class |= 1L << class; 3114432Seric } 3124432Seric 3134627Seric (void) fclose(f); 3144432Seric } 3154432Seric /* 3164096Seric ** MAKEMAILER -- define a new mailer. 3174096Seric ** 3184096Seric ** Parameters: 3194096Seric ** line -- description of mailer. This is in tokens 3204096Seric ** separated by white space. The fields are: 3214096Seric ** * the name of the mailer, as refered to 3224096Seric ** in the rewriting rules. 3234096Seric ** * the pathname of the program to fork to 3244096Seric ** execute it. 3254096Seric ** * the options needed by this program. 3264096Seric ** * the macro string needed to translate 3274096Seric ** a local "from" name to one that can be 3284096Seric ** returned to this machine. 3294096Seric ** * the argument vector (a series of parameters). 3304217Seric ** safe -- set if this is a safe configuration file. 3314096Seric ** 3324096Seric ** Returns: 3334096Seric ** none. 3344096Seric ** 3354096Seric ** Side Effects: 3364096Seric ** enters the mailer into the mailer table. 3374096Seric */ 3383308Seric 3394096Seric # define SETWORD \ 3404096Seric { \ 3414096Seric while (*p != '\0' && isspace(*p)) \ 3424096Seric p++; \ 3434096Seric q = p; \ 3444096Seric while (*p != '\0' && !isspace(*p)) \ 3454096Seric p++; \ 3464096Seric if (*p != '\0') \ 3474096Seric *p++ = '\0'; \ 3484096Seric } 3494096Seric 3504217Seric makemailer(line, safe) 3514096Seric char *line; 3524217Seric bool safe; 3534096Seric { 3544096Seric register char *p; 3554096Seric register char *q; 3568067Seric register struct mailer *m; 3578067Seric register STAB *s; 3588067Seric int i; 3594096Seric char *mname; 3604096Seric char *mpath; 3614627Seric u_long mopts; 3628067Seric short mrset, msset; 3638067Seric char *margv[MAXPV + 1]; 3644627Seric extern u_long mfencode(); 3654096Seric extern int NextMailer; 3664096Seric 3674096Seric if (NextMailer >= MAXMAILERS) 3684096Seric { 3698056Seric syserr("readcf: line %d: too many mailers defined (%d max)", 3708056Seric LineNumber, MAXMAILERS); 3714096Seric return; 3724096Seric } 3734096Seric 3744096Seric /* collect initial information */ 3754096Seric p = line; 3764096Seric SETWORD; 3774096Seric mname = q; 3784096Seric SETWORD; 3794096Seric mpath = q; 3804096Seric SETWORD; 3814627Seric mopts = mfencode(q); 3824217Seric if (!safe) 3834217Seric mopts &= ~M_RESTR; 3844096Seric SETWORD; 3858067Seric msset = atoi(q); 3868067Seric SETWORD; 3878067Seric mrset = atoi(q); 3884096Seric 3894096Seric if (*p == '\0') 3904096Seric { 3918056Seric syserr("readcf: line %d: invalid M line in configuration file", 3928056Seric LineNumber); 3934096Seric return; 3944096Seric } 3958067Seric if (msset >= MAXRWSETS || mrset >= MAXRWSETS) 3968067Seric { 3978067Seric syserr("readcf: line %d: invalid rewrite set, %d max", 3988067Seric LineNumber, MAXRWSETS); 3998067Seric return; 4008067Seric } 4014096Seric 4024096Seric /* allocate a mailer */ 4034096Seric m = (struct mailer *) xalloc(sizeof *m); 4044096Seric m->m_name = newstr(mname); 4054096Seric m->m_mailer = newstr(mpath); 4064096Seric m->m_flags = mopts; 4078067Seric m->m_r_rwset = mrset; 4088067Seric m->m_s_rwset = msset; 4094096Seric m->m_badstat = EX_UNAVAILABLE; 4104439Seric m->m_mno = NextMailer; 4114096Seric Mailer[NextMailer++] = m; 4124096Seric 4134096Seric /* collect the argument vector */ 4144096Seric for (i = 0; i < MAXPV - 1 && *p != '\0'; i++) 4154096Seric { 4164096Seric SETWORD; 4174096Seric margv[i] = newstr(q); 4184096Seric } 4194096Seric margv[i++] = NULL; 4204096Seric 4214096Seric /* save the argv */ 4227009Seric m->m_argv = (char **) xalloc(sizeof margv[0] * i); 4234096Seric bmove((char *) margv, (char *) m->m_argv, sizeof margv[0] * i); 4244439Seric s = stab(m->m_name, ST_MAILER, ST_ENTER); 4254439Seric s->s_mailer = m; 4263308Seric } 4273308Seric /* 4283308Seric ** PRINTRULES -- print rewrite rules (for debugging) 4293308Seric ** 4303308Seric ** Parameters: 4313308Seric ** none. 4323308Seric ** 4333308Seric ** Returns: 4343308Seric ** none. 4353308Seric ** 4363308Seric ** Side Effects: 4373308Seric ** prints rewrite rules. 4383308Seric */ 4393308Seric 4404319Seric # ifdef DEBUG 4414319Seric 4423308Seric printrules() 4433308Seric { 4443308Seric register struct rewrite *rwp; 4454072Seric register int ruleset; 4463308Seric 4474072Seric for (ruleset = 0; ruleset < 10; ruleset++) 4483308Seric { 4494072Seric if (RewriteRules[ruleset] == NULL) 4504072Seric continue; 4518067Seric printf("\n----Rule Set %d:", ruleset); 4523308Seric 4534072Seric for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 4543308Seric { 4558067Seric printf("\nLHS:"); 4568067Seric printav(rwp->r_lhs); 4578067Seric printf("RHS:"); 4588067Seric printav(rwp->r_rhs); 4593308Seric } 4603308Seric } 4613308Seric } 4624319Seric 4634319Seric # endif DEBUG 4644096Seric /* 4654627Seric ** MFENCODE -- crack mailer options 4664096Seric ** 4674096Seric ** These options modify the functioning of the mailer 4684096Seric ** from the configuration table. 4694096Seric ** 4704096Seric ** Parameters: 4714096Seric ** p -- pointer to vector of options. 4724096Seric ** 4734096Seric ** Returns: 4744096Seric ** option list in binary. 4754096Seric ** 4764096Seric ** Side Effects: 4774096Seric ** none. 4784096Seric */ 4794096Seric 4804096Seric struct optlist 4814096Seric { 4824096Seric char opt_name; /* external name of option */ 4836275Seric u_long opt_value; /* internal name of option */ 4844096Seric }; 4854096Seric struct optlist OptList[] = 4864096Seric { 4874096Seric 'f', M_FOPT, 4884096Seric 'r', M_ROPT, 4894096Seric 'q', M_QUIET, 4904096Seric 'S', M_RESTR, 4914096Seric 'n', M_NHDR, 4924197Seric 'l', M_LOCAL, 4934096Seric 's', M_STRIPQ, 4944096Seric 'm', M_MUSER, 4954096Seric 'F', M_NEEDFROM, 4964096Seric 'D', M_NEEDDATE, 4974096Seric 'M', M_MSGID, 4984096Seric 'u', M_USR_UPPER, 4994096Seric 'h', M_HST_UPPER, 5004096Seric 'x', M_FULLNAME, 5014096Seric 'A', M_ARPAFMT, 5025601Seric 'U', M_UGLYUUCP, 5035906Seric 'e', M_EXPENSIVE, 5046983Seric 'X', M_FULLSMTP, 5058182Seric 'C', M_CANONICAL, 5069315Seric 'I', M_INTERNAL, 5074319Seric '\0', 0 5084096Seric }; 5094096Seric 5104627Seric u_long 5114627Seric mfencode(p) 5124096Seric register char *p; 5134096Seric { 5144096Seric register struct optlist *o; 5154627Seric register u_long opts = 0; 5164096Seric 5174096Seric while (*p != '\0') 5184096Seric { 5194096Seric for (o = OptList; o->opt_name != '\0' && o->opt_name != *p; o++) 5204096Seric continue; 5214096Seric if (o->opt_name == '\0') 5224096Seric syserr("bad mailer option %c", *p); 5234096Seric opts |= o->opt_value; 5244096Seric p++; 5254096Seric } 5264096Seric return (opts); 5274096Seric } 5284627Seric /* 5294627Seric ** MFDECODE -- decode mailer flags into external form. 5304627Seric ** 5314627Seric ** Parameters: 5324627Seric ** flags -- value of flags to decode. 5334627Seric ** f -- file to write them onto. 5344627Seric ** 5354627Seric ** Returns: 5364627Seric ** none. 5374627Seric ** 5384627Seric ** Side Effects: 5394627Seric ** none. 5404627Seric */ 5414627Seric 5424627Seric mfdecode(flags, f) 5434627Seric u_long flags; 5444627Seric FILE *f; 5454627Seric { 5464627Seric register struct optlist *o; 5474627Seric 5484627Seric putc('?', f); 5494627Seric for (o = OptList; o->opt_name != '\0'; o++) 5504627Seric { 5514627Seric if ((o->opt_value & flags) == o->opt_value) 5524627Seric { 5534627Seric flags &= ~o->opt_value; 5544627Seric putc(o->opt_name, f); 5554627Seric } 5564627Seric } 5574627Seric putc('?', f); 5584627Seric } 5598256Seric /* 5608256Seric ** SETOPTION -- set global processing option 5618256Seric ** 5628256Seric ** Parameters: 5638256Seric ** opt -- option name. 5648256Seric ** val -- option value (as a text string). 5658269Seric ** safe -- if set, this came from a system configuration file. 5668269Seric ** sticky -- if set, don't let other setoptions override 5678269Seric ** this value. 5688256Seric ** 5698256Seric ** Returns: 5708256Seric ** none. 5718256Seric ** 5728256Seric ** Side Effects: 5738256Seric ** Sets options as implied by the arguments. 5748256Seric */ 5758256Seric 5768544Seric static int StickyOpt[128 / sizeof (int)]; /* set if option is stuck */ 5778544Seric extern char *WizWord; /* the stored wizard password */ 5788269Seric 5798269Seric setoption(opt, val, safe, sticky) 5808256Seric char opt; 5818256Seric char *val; 5828269Seric bool safe; 5838269Seric bool sticky; 5848256Seric { 5858256Seric time_t tval; 5868256Seric int ival; 5878265Seric bool bval; 5888269Seric int smask; 5898269Seric int sindex; 5908265Seric extern bool atobool(); 5918256Seric 5928256Seric # ifdef DEBUG 5938256Seric if (tTd(37, 1)) 594*9341Seric printf("setoption %c=%s", opt, val); 5958256Seric # endif DEBUG 5968256Seric 5978256Seric /* 5988269Seric ** See if this option is preset for us. 5998256Seric */ 6008256Seric 6018269Seric sindex = opt; 6028269Seric smask = 1 << (sindex % sizeof (int)); 6038269Seric sindex /= sizeof (int); 6048269Seric if (bitset(smask, StickyOpt[sindex])) 6058269Seric { 6068269Seric # ifdef DEBUG 607*9341Seric if (tTd(37, 1)) 608*9341Seric printf(" (ignored)\n"); 6098269Seric # endif DEBUG 6108269Seric return; 6118269Seric } 612*9341Seric #ifdef DEBUG 613*9341Seric else if (tTd(37, 1)) 614*9341Seric printf("\n"); 615*9341Seric #endif DEBUG 6168269Seric if (sticky) 6178269Seric StickyOpt[sindex] |= smask; 6188269Seric 6198269Seric if (getruid() == 0) 6208269Seric safe = TRUE; 6218269Seric 6228269Seric /* 6238269Seric ** Encode this option as appropriate. 6248269Seric */ 6258269Seric 6268256Seric if (index("rT", opt) != NULL) 6278256Seric tval = convtime(val); 6288256Seric else if (index("gLu", opt) != NULL) 6298256Seric ival = atoi(val); 6309049Seric else if (index("F", opt) != NULL) 6319049Seric ival = atooct(val); 6329146Seric else if (index("acDfimosv", opt) != NULL) 6338265Seric bval = atobool(val); 6348269Seric else if (index("be", opt) != NULL) 6358269Seric /* do nothing */ ; 6368256Seric else if (val[0] == '\0') 6378256Seric val = ""; 6388256Seric else 6398256Seric val = newstr(val); 6408256Seric 6418256Seric /* 6428256Seric ** Now do the actual assignment. 6438256Seric */ 6448256Seric 6458256Seric switch (opt) 6468256Seric { 6478256Seric case 'A': /* set default alias file */ 6488256Seric AliasFile = val; 6498269Seric if (AliasFile[0] == '\0') 6508269Seric AliasFile = "aliases"; 6518256Seric break; 6528256Seric 6538931Seric case 'a': /* look for "@:@" in alias file */ 6548931Seric SafeAlias = bval; 6558931Seric break; 6568931Seric 6579284Seric case 'c': /* don't connect to "expensive" mailers */ 6589284Seric NoConnect = bval; 6599284Seric break; 6609284Seric 6619284Seric case 'd': /* delivery mode */ 6629284Seric switch (*val) 6638269Seric { 6649284Seric case '\0': 6659284Seric SendMode = SM_DELIVER; 6668269Seric break; 6678269Seric 6689284Seric case SM_DELIVER: /* do everything */ 6699284Seric case SM_FORK: /* fork after verification */ 6709284Seric case SM_QUEUE: /* queue only */ 6719284Seric SendMode = *val; 6728269Seric break; 6738269Seric 6748269Seric default: 6759284Seric syserr("Unknown delivery mode %c", *val); 6768269Seric exit(EX_USAGE); 6778269Seric } 6788269Seric break; 6798269Seric 6809146Seric case 'D': /* rebuild alias database as needed */ 6819146Seric AutoRebuild = bval; 6829146Seric break; 6839146Seric 6848269Seric case 'e': /* set error processing mode */ 6858269Seric switch (*val) 6868269Seric { 6878269Seric case 'p': /* print errors normally */ 6888269Seric break; /* (default) */ 6898269Seric 6908269Seric case 'q': /* be silent about it */ 6918269Seric (void) freopen("/dev/null", "w", stdout); 6928269Seric break; 6938269Seric 6948269Seric case 'm': /* mail back */ 6958269Seric MailBack = TRUE; 6968269Seric HoldErrs = TRUE; 6978269Seric break; 6988269Seric 6998269Seric case 'e': /* do berknet error processing */ 7008269Seric BerkNet = TRUE; 7018269Seric HoldErrs = TRUE; 7028269Seric break; 7038269Seric 7048269Seric case 'w': /* write back (or mail) */ 7058269Seric WriteBack = TRUE; 7068269Seric HoldErrs = TRUE; 7078269Seric break; 7088269Seric } 7098269Seric break; 7108269Seric 7119049Seric case 'F': /* file mode */ 7129049Seric FileMode = ival; 7139049Seric break; 7149049Seric 7158269Seric case 'f': /* save Unix-style From lines on front */ 7168269Seric SaveFrom = bval; 7178269Seric break; 7188269Seric 7198256Seric case 'g': /* default gid */ 7209105Seric if (safe) 7219105Seric DefGid = ival; 7228256Seric break; 7238256Seric 7248256Seric case 'H': /* help file */ 7258256Seric HelpFile = val; 7268269Seric if (HelpFile[0] == '\0') 7278269Seric HelpFile = "sendmail.hf"; 7288256Seric break; 7298256Seric 7308269Seric case 'i': /* ignore dot lines in message */ 7318269Seric IgnrDot = bval; 7328269Seric break; 7338269Seric 7348256Seric case 'L': /* log level */ 7358256Seric LogLevel = ival; 7368256Seric break; 7378256Seric 7388269Seric case 'M': /* define macro */ 7398269Seric define(val[0], &val[1]); 7408269Seric break; 7418269Seric 7428269Seric case 'm': /* send to me too */ 7438269Seric MeToo = bval; 7448269Seric break; 7458269Seric 7468269Seric case 'o': /* assume old style headers */ 747*9341Seric if (bval) 748*9341Seric CurEnv->e_flags |= EF_OLDSTYLE; 749*9341Seric else 750*9341Seric CurEnv->e_flags &= ~EF_OLDSTYLE; 7518269Seric break; 7528269Seric 7538256Seric case 'Q': /* queue directory */ 7548256Seric QueueDir = val; 7558269Seric if (QueueDir[0] == '\0') 7568269Seric QueueDir = "mqueue"; 7578256Seric break; 7588256Seric 7598256Seric case 'r': /* read timeout */ 7608256Seric ReadTimeout = tval; 7618256Seric break; 7628256Seric 7638256Seric case 'S': /* status file */ 7648256Seric StatFile = val; 7658269Seric if (StatFile[0] == '\0') 7668269Seric StatFile = "sendmail.st"; 7678256Seric break; 7688256Seric 7698265Seric case 's': /* be super safe, even if expensive */ 7708265Seric SuperSafe = bval; 7718256Seric break; 7728256Seric 7738256Seric case 'T': /* queue timeout */ 7748256Seric TimeOut = tval; 7758256Seric break; 7768256Seric 7778265Seric case 't': /* time zone name */ 7788265Seric # ifdef V6 7798265Seric StdTimezone = val; 7808265Seric DstTimezone = index(val, ','); 7818265Seric if (DstTimezone == NULL) 7828265Seric goto syntax; 7838265Seric *DstTimezone++ = '\0'; 7848265Seric # endif V6 7858265Seric break; 7868265Seric 7878256Seric case 'u': /* set default uid */ 7889105Seric if (safe) 7899105Seric DefUid = ival; 7908256Seric break; 7918256Seric 7928269Seric case 'v': /* run in verbose mode */ 7938269Seric Verbose = bval; 7948256Seric break; 7958256Seric 7968544Seric # ifdef DEBUG 7978544Seric case 'W': /* set the wizards password */ 7989105Seric if (safe) 7999105Seric WizWord = val; 8008544Seric break; 8018544Seric # endif DEBUG 8028544Seric 8038256Seric default: 8048256Seric break; 8058256Seric } 8069188Seric return; 8079188Seric 8089188Seric syntax: 8099188Seric syserr("setoption: line %d: syntax error on \"%c%s\"", 8109188Seric LineNumber, opt, val); 8118256Seric } 812