13313Seric # include "sendmail.h" 23308Seric 3*8931Seric SCCSID(@(#)readcf.c 3.39 10/28/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, 5064319Seric '\0', 0 5074096Seric }; 5084096Seric 5094627Seric u_long 5104627Seric mfencode(p) 5114096Seric register char *p; 5124096Seric { 5134096Seric register struct optlist *o; 5144627Seric register u_long opts = 0; 5154096Seric 5164096Seric while (*p != '\0') 5174096Seric { 5184096Seric for (o = OptList; o->opt_name != '\0' && o->opt_name != *p; o++) 5194096Seric continue; 5204096Seric if (o->opt_name == '\0') 5214096Seric syserr("bad mailer option %c", *p); 5224096Seric opts |= o->opt_value; 5234096Seric p++; 5244096Seric } 5254096Seric return (opts); 5264096Seric } 5274627Seric /* 5284627Seric ** MFDECODE -- decode mailer flags into external form. 5294627Seric ** 5304627Seric ** Parameters: 5314627Seric ** flags -- value of flags to decode. 5324627Seric ** f -- file to write them onto. 5334627Seric ** 5344627Seric ** Returns: 5354627Seric ** none. 5364627Seric ** 5374627Seric ** Side Effects: 5384627Seric ** none. 5394627Seric */ 5404627Seric 5414627Seric mfdecode(flags, f) 5424627Seric u_long flags; 5434627Seric FILE *f; 5444627Seric { 5454627Seric register struct optlist *o; 5464627Seric 5474627Seric putc('?', f); 5484627Seric for (o = OptList; o->opt_name != '\0'; o++) 5494627Seric { 5504627Seric if ((o->opt_value & flags) == o->opt_value) 5514627Seric { 5524627Seric flags &= ~o->opt_value; 5534627Seric putc(o->opt_name, f); 5544627Seric } 5554627Seric } 5564627Seric putc('?', f); 5574627Seric } 5588256Seric /* 5598256Seric ** SETOPTION -- set global processing option 5608256Seric ** 5618256Seric ** Parameters: 5628256Seric ** opt -- option name. 5638256Seric ** val -- option value (as a text string). 5648269Seric ** safe -- if set, this came from a system configuration file. 5658269Seric ** sticky -- if set, don't let other setoptions override 5668269Seric ** this value. 5678256Seric ** 5688256Seric ** Returns: 5698256Seric ** none. 5708256Seric ** 5718256Seric ** Side Effects: 5728256Seric ** Sets options as implied by the arguments. 5738256Seric */ 5748256Seric 5758544Seric static int StickyOpt[128 / sizeof (int)]; /* set if option is stuck */ 5768544Seric extern char *WizWord; /* the stored wizard password */ 5778269Seric 5788269Seric setoption(opt, val, safe, sticky) 5798256Seric char opt; 5808256Seric char *val; 5818269Seric bool safe; 5828269Seric bool sticky; 5838256Seric { 5848256Seric time_t tval; 5858256Seric int ival; 5868265Seric bool bval; 5878269Seric int smask; 5888269Seric int sindex; 5898265Seric extern bool atobool(); 5908256Seric 5918256Seric # ifdef DEBUG 5928256Seric if (tTd(37, 1)) 5938256Seric printf("setoption %c=%s\n", opt, val); 5948256Seric # endif DEBUG 5958256Seric 5968256Seric /* 5978269Seric ** See if this option is preset for us. 5988256Seric */ 5998256Seric 6008269Seric sindex = opt; 6018269Seric smask = 1 << (sindex % sizeof (int)); 6028269Seric sindex /= sizeof (int); 6038269Seric if (bitset(smask, StickyOpt[sindex])) 6048269Seric { 6058269Seric # ifdef DEBUG 6068269Seric if (tTd(37, 2)) 6078269Seric printf("(ignored)\n"); 6088269Seric # endif DEBUG 6098269Seric return; 6108269Seric } 6118269Seric if (sticky) 6128269Seric StickyOpt[sindex] |= smask; 6138269Seric 6148269Seric if (getruid() == 0) 6158269Seric safe = TRUE; 6168269Seric 6178269Seric /* 6188269Seric ** Encode this option as appropriate. 6198269Seric */ 6208269Seric 6218256Seric if (index("rT", opt) != NULL) 6228256Seric tval = convtime(val); 6238256Seric else if (index("gLu", opt) != NULL) 6248256Seric ival = atoi(val); 625*8931Seric else if (index("acfimosv", opt) != NULL) 6268265Seric bval = atobool(val); 6278269Seric else if (index("be", opt) != NULL) 6288269Seric /* do nothing */ ; 6298256Seric else if (val[0] == '\0') 6308256Seric val = ""; 6318256Seric else 6328256Seric val = newstr(val); 6338256Seric 6348256Seric /* 6358256Seric ** Now do the actual assignment. 6368256Seric */ 6378256Seric 6388256Seric switch (opt) 6398256Seric { 6408256Seric case 'A': /* set default alias file */ 6418256Seric AliasFile = val; 6428269Seric if (AliasFile[0] == '\0') 6438269Seric AliasFile = "aliases"; 6448256Seric break; 6458256Seric 646*8931Seric case 'a': /* look for "@:@" in alias file */ 647*8931Seric SafeAlias = bval; 648*8931Seric break; 649*8931Seric 6508269Seric case 'b': /* operations mode */ 6518269Seric Mode = *val; 6528269Seric switch (Mode) 6538269Seric { 6548269Seric case MD_DAEMON: /* run as a daemon */ 6558269Seric #ifdef DAEMON 6568269Seric ArpaMode = Smtp = TRUE; 6578269Seric #else DAEMON 6588269Seric syserr("Daemon mode not implemented"); 6598269Seric #endif DAEMON 6608269Seric break; 6618269Seric 6628269Seric case '\0': /* default: do full delivery */ 6638269Seric Mode = MD_DEFAULT; 6648269Seric /* fall through....... */ 6658269Seric 6668269Seric case MD_DELIVER: /* do everything (default) */ 6678269Seric case MD_FORK: /* fork after verification */ 6688269Seric case MD_QUEUE: /* queue only */ 6698269Seric case MD_VERIFY: /* verify only */ 6708337Seric case MD_TEST: /* test addresses */ 6718269Seric break; 6728269Seric 6738269Seric default: 6748269Seric syserr("Unknown operation mode -b%c", Mode); 6758269Seric exit(EX_USAGE); 6768269Seric } 6778269Seric break; 6788269Seric 6798269Seric case 'c': /* don't connect to "expensive" mailers */ 6808269Seric NoConnect = bval; 6818269Seric break; 6828269Seric 6838269Seric case 'e': /* set error processing mode */ 6848269Seric switch (*val) 6858269Seric { 6868269Seric case 'p': /* print errors normally */ 6878269Seric break; /* (default) */ 6888269Seric 6898269Seric case 'q': /* be silent about it */ 6908269Seric (void) freopen("/dev/null", "w", stdout); 6918269Seric break; 6928269Seric 6938269Seric case 'm': /* mail back */ 6948269Seric MailBack = TRUE; 6958269Seric HoldErrs = TRUE; 6968269Seric break; 6978269Seric 6988269Seric case 'e': /* do berknet error processing */ 6998269Seric BerkNet = TRUE; 7008269Seric HoldErrs = TRUE; 7018269Seric break; 7028269Seric 7038269Seric case 'w': /* write back (or mail) */ 7048269Seric WriteBack = TRUE; 7058269Seric HoldErrs = TRUE; 7068269Seric break; 7078269Seric } 7088269Seric break; 7098269Seric 7108269Seric case 'f': /* save Unix-style From lines on front */ 7118269Seric SaveFrom = bval; 7128269Seric break; 7138269Seric 7148256Seric case 'g': /* default gid */ 7158269Seric if (!safe) 7168269Seric goto syntax; 7178256Seric DefGid = ival; 7188256Seric break; 7198256Seric 7208256Seric case 'H': /* help file */ 7218256Seric HelpFile = val; 7228269Seric if (HelpFile[0] == '\0') 7238269Seric HelpFile = "sendmail.hf"; 7248256Seric break; 7258256Seric 7268269Seric case 'i': /* ignore dot lines in message */ 7278269Seric IgnrDot = bval; 7288269Seric break; 7298269Seric 7308256Seric case 'L': /* log level */ 7318256Seric LogLevel = ival; 7328256Seric break; 7338256Seric 7348269Seric case 'M': /* define macro */ 7358269Seric define(val[0], &val[1]); 7368269Seric break; 7378269Seric 7388269Seric case 'm': /* send to me too */ 7398269Seric MeToo = bval; 7408269Seric break; 7418269Seric 7428269Seric case 'o': /* assume old style headers */ 7438269Seric CurEnv->e_oldstyle = bval; 7448269Seric break; 7458269Seric 7468256Seric case 'Q': /* queue directory */ 7478256Seric QueueDir = val; 7488269Seric if (QueueDir[0] == '\0') 7498269Seric QueueDir = "mqueue"; 7508256Seric break; 7518256Seric 7528256Seric case 'r': /* read timeout */ 7538256Seric ReadTimeout = tval; 7548256Seric break; 7558256Seric 7568256Seric case 'S': /* status file */ 7578256Seric StatFile = val; 7588269Seric if (StatFile[0] == '\0') 7598269Seric StatFile = "sendmail.st"; 7608256Seric break; 7618256Seric 7628265Seric case 's': /* be super safe, even if expensive */ 7638265Seric SuperSafe = bval; 7648256Seric break; 7658256Seric 7668256Seric case 'T': /* queue timeout */ 7678256Seric TimeOut = tval; 7688256Seric break; 7698256Seric 7708265Seric case 't': /* time zone name */ 7718265Seric # ifdef V6 7728265Seric StdTimezone = val; 7738265Seric DstTimezone = index(val, ','); 7748265Seric if (DstTimezone == NULL) 7758265Seric goto syntax; 7768265Seric *DstTimezone++ = '\0'; 7778265Seric # endif V6 7788265Seric break; 7798265Seric 7808256Seric case 'u': /* set default uid */ 7818269Seric if (!safe) 7828269Seric goto syntax; 7838256Seric DefUid = ival; 7848256Seric break; 7858256Seric 7868269Seric case 'v': /* run in verbose mode */ 7878269Seric Verbose = bval; 7888269Seric if (Verbose) 7898269Seric NoConnect = FALSE; 7908256Seric break; 7918256Seric 7928544Seric # ifdef DEBUG 7938544Seric case 'W': /* set the wizards password */ 7948544Seric if (!safe) 7958544Seric goto syntax; 7968544Seric WizWord = val; 7978544Seric break; 7988544Seric # endif DEBUG 7998544Seric 8008256Seric default: 8018265Seric syntax: 8028265Seric syserr("setoption: line %d: syntax error on \"%c%s\"", 8038265Seric LineNumber, opt, val); 8048256Seric break; 8058256Seric } 8068256Seric } 807