13313Seric # include "sendmail.h" 23308Seric 3*8547Seric SCCSID(@(#)readcf.c 3.38 10/16/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 48*8547Seric # define MAXTRUST 10 /* maximum number of trusted users */ 49*8547Seric 50*8547Seric char *TrustedUsers[MAXTRUST+1]; /* list of trusted users */ 51*8547Seric 524217Seric readcf(cfname, safe) 533308Seric char *cfname; 544217Seric bool safe; 553308Seric { 563308Seric FILE *cf; 57*8547Seric int class; 58*8547Seric int ruleset = 0; 59*8547Seric char *q; 60*8547Seric char **pv; 613308Seric char buf[MAXLINE]; 623308Seric register char *p; 633308Seric struct rewrite *rwp = NULL; 643308Seric extern char **prescan(); 653308Seric extern char **copyplist(); 665909Seric char exbuf[MAXLINE]; 673308Seric 683308Seric cf = fopen(cfname, "r"); 693308Seric if (cf == NULL) 703308Seric { 713308Seric syserr("cannot open %s", cfname); 723308Seric exit(EX_OSFILE); 733308Seric } 743308Seric 758056Seric LineNumber = 0; 767854Seric while (fgetfolded(buf, sizeof buf, cf) != NULL) 773308Seric { 783308Seric switch (buf[0]) 793308Seric { 803308Seric case '\0': 813308Seric case '#': /* comment */ 823308Seric break; 833308Seric 843308Seric case 'R': /* rewriting rule */ 853308Seric for (p = &buf[1]; *p != '\0' && *p != '\t'; p++) 863308Seric continue; 873308Seric 883308Seric if (*p == '\0') 895909Seric { 908056Seric syserr("line %d: invalid rewrite line \"%s\"", 918056Seric LineNumber, buf); 925909Seric break; 935909Seric } 945909Seric 955909Seric /* allocate space for the rule header */ 965909Seric if (rwp == NULL) 975909Seric { 985909Seric RewriteRules[ruleset] = rwp = 995909Seric (struct rewrite *) xalloc(sizeof *rwp); 1005909Seric } 1013308Seric else 1023308Seric { 1035909Seric rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 1045909Seric rwp = rwp->r_next; 1055909Seric } 1065909Seric rwp->r_next = NULL; 1073308Seric 1085909Seric /* expand and save the LHS */ 1095909Seric *p = '\0'; 1106991Seric expand(&buf[1], exbuf, &exbuf[sizeof exbuf], CurEnv); 1115909Seric rwp->r_lhs = prescan(exbuf, '\t'); 1125909Seric if (rwp->r_lhs != NULL) 1135909Seric rwp->r_lhs = copyplist(rwp->r_lhs, TRUE); 1145909Seric 1155909Seric /* expand and save the RHS */ 1165909Seric while (*++p == '\t') 1175909Seric continue; 1187231Seric q = p; 1197231Seric while (*p != '\0' && *p != '\t') 1207231Seric p++; 1217231Seric *p = '\0'; 1227231Seric expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv); 1235909Seric rwp->r_rhs = prescan(exbuf, '\t'); 1245909Seric if (rwp->r_rhs != NULL) 1255909Seric rwp->r_rhs = copyplist(rwp->r_rhs, TRUE); 1263308Seric break; 1273308Seric 1284072Seric case 'S': /* select rewriting set */ 1294072Seric ruleset = atoi(&buf[1]); 1308056Seric if (ruleset >= MAXRWSETS || ruleset < 0) 1318056Seric { 1328056Seric syserr("readcf: line %d: bad ruleset %d (%d max)", 1338056Seric LineNumber, ruleset, MAXRWSETS); 1348056Seric ruleset = 0; 1358056Seric } 1364072Seric rwp = NULL; 1374072Seric break; 1384072Seric 1393308Seric case 'D': /* macro definition */ 1403308Seric define(buf[1], newstr(&buf[2])); 1413308Seric break; 1423308Seric 1433387Seric case 'H': /* required header line */ 1444088Seric (void) chompheader(&buf[1], TRUE); 1453387Seric break; 1463387Seric 1474061Seric case 'C': /* word class */ 1484432Seric case 'F': /* word class from file */ 1494061Seric class = buf[1]; 1504061Seric if (!isalpha(class)) 1514061Seric goto badline; 1524061Seric if (isupper(class)) 1534061Seric class -= 'A'; 1544061Seric else 1554061Seric class -= 'a'; 1564432Seric 1574432Seric /* read list of words from argument or file */ 1584432Seric if (buf[0] == 'F') 1594432Seric { 1604432Seric /* read from file */ 1614432Seric for (p = &buf[2]; *p != '\0' && !isspace(*p); p++) 1624432Seric continue; 1634432Seric if (*p == '\0') 1644432Seric p = "%s"; 1654432Seric else 1664432Seric { 1674432Seric *p = '\0'; 1684432Seric while (isspace(*++p)) 1694432Seric continue; 1704432Seric } 1714432Seric fileclass(class, &buf[2], p); 1724432Seric break; 1734432Seric } 1744061Seric 1754432Seric /* scan the list of words and set class for all */ 1764061Seric for (p = &buf[2]; *p != '\0'; ) 1774061Seric { 1784061Seric register char *wd; 1794061Seric char delim; 1804061Seric register STAB *s; 1814061Seric 1824061Seric while (*p != '\0' && isspace(*p)) 1834061Seric p++; 1844061Seric wd = p; 1854061Seric while (*p != '\0' && !isspace(*p)) 1864061Seric p++; 1874061Seric delim = *p; 1884061Seric *p = '\0'; 1894061Seric if (wd[0] != '\0') 1904061Seric { 1914103Seric s = stab(wd, ST_CLASS, ST_ENTER); 1926275Seric s->s_class |= 1L << class; 1934061Seric } 1944061Seric *p = delim; 1954061Seric } 1964061Seric break; 1974061Seric 1984096Seric case 'M': /* define mailer */ 1994217Seric makemailer(&buf[1], safe); 2004096Seric break; 2014096Seric 2028252Seric case 'O': /* set option */ 2038269Seric setoption(buf[1], &buf[2], safe, FALSE); 2048252Seric break; 2058252Seric 2068252Seric case 'P': /* set precedence */ 2078252Seric if (NumPriorities >= MAXPRIORITIES) 2088252Seric { 209*8547Seric toomany('P', MAXPRIORITIES); 2108252Seric break; 2118252Seric } 2128252Seric for (p = &buf[1]; *p != '\0' && *p != '='; p++) 2138252Seric continue; 2148252Seric if (*p == '\0') 2158252Seric goto badline; 2168252Seric *p = '\0'; 2178252Seric Priorities[NumPriorities].pri_name = newstr(&buf[1]); 2188252Seric Priorities[NumPriorities].pri_val = atoi(++p); 2198252Seric NumPriorities++; 2208252Seric break; 2218252Seric 222*8547Seric case 'T': /* trusted user(s) */ 223*8547Seric p = &buf[1]; 224*8547Seric while (*p != '\0') 225*8547Seric { 226*8547Seric while (isspace(*p)) 227*8547Seric p++; 228*8547Seric q = p; 229*8547Seric while (*p != '\0' && !isspace(*p)) 230*8547Seric p++; 231*8547Seric if (*p != '\0') 232*8547Seric *p++ = '\0'; 233*8547Seric if (*q == '\0') 234*8547Seric continue; 235*8547Seric for (pv = TrustedUsers; *pv != NULL; pv++) 236*8547Seric continue; 237*8547Seric if (pv >= &TrustedUsers[MAXTRUST]) 238*8547Seric { 239*8547Seric toomany('T', MAXTRUST); 240*8547Seric break; 241*8547Seric } 242*8547Seric *pv = newstr(q); 243*8547Seric } 244*8547Seric break; 245*8547Seric 2463308Seric default: 2474061Seric badline: 2488056Seric syserr("readcf: line %d: unknown control line \"%s\"", 2498056Seric LineNumber, buf); 2503308Seric } 2513308Seric } 2524096Seric } 2534096Seric /* 254*8547Seric ** TOOMANY -- signal too many of some option 255*8547Seric ** 256*8547Seric ** Parameters: 257*8547Seric ** id -- the id of the error line 258*8547Seric ** maxcnt -- the maximum possible values 259*8547Seric ** 260*8547Seric ** Returns: 261*8547Seric ** none. 262*8547Seric ** 263*8547Seric ** Side Effects: 264*8547Seric ** gives a syserr. 265*8547Seric */ 266*8547Seric 267*8547Seric toomany(id, maxcnt) 268*8547Seric char id; 269*8547Seric int maxcnt; 270*8547Seric { 271*8547Seric syserr("readcf: line %d: too many %c lines, %d max", 272*8547Seric LineNumber, id, maxcnt); 273*8547Seric } 274*8547Seric /* 2754432Seric ** FILECLASS -- read members of a class from a file 2764432Seric ** 2774432Seric ** Parameters: 2784432Seric ** class -- class to define. 2794432Seric ** filename -- name of file to read. 2804432Seric ** fmt -- scanf string to use for match. 2814432Seric ** 2824432Seric ** Returns: 2834432Seric ** none 2844432Seric ** 2854432Seric ** Side Effects: 2864432Seric ** 2874432Seric ** puts all lines in filename that match a scanf into 2884432Seric ** the named class. 2894432Seric */ 2904432Seric 2914432Seric fileclass(class, filename, fmt) 2924432Seric int class; 2934432Seric char *filename; 2944432Seric char *fmt; 2954432Seric { 2964432Seric register FILE *f; 2974432Seric char buf[MAXLINE]; 2984432Seric 2994432Seric f = fopen(filename, "r"); 3004432Seric if (f == NULL) 3014432Seric { 3024432Seric syserr("cannot open %s", filename); 3034432Seric return; 3044432Seric } 3054432Seric 3064432Seric while (fgets(buf, sizeof buf, f) != NULL) 3074432Seric { 3084432Seric register STAB *s; 3094432Seric char wordbuf[MAXNAME+1]; 3104432Seric 3114432Seric if (sscanf(buf, fmt, wordbuf) != 1) 3124432Seric continue; 3134432Seric s = stab(wordbuf, ST_CLASS, ST_ENTER); 3146275Seric s->s_class |= 1L << class; 3154432Seric } 3164432Seric 3174627Seric (void) fclose(f); 3184432Seric } 3194432Seric /* 3204096Seric ** MAKEMAILER -- define a new mailer. 3214096Seric ** 3224096Seric ** Parameters: 3234096Seric ** line -- description of mailer. This is in tokens 3244096Seric ** separated by white space. The fields are: 3254096Seric ** * the name of the mailer, as refered to 3264096Seric ** in the rewriting rules. 3274096Seric ** * the pathname of the program to fork to 3284096Seric ** execute it. 3294096Seric ** * the options needed by this program. 3304096Seric ** * the macro string needed to translate 3314096Seric ** a local "from" name to one that can be 3324096Seric ** returned to this machine. 3334096Seric ** * the argument vector (a series of parameters). 3344217Seric ** safe -- set if this is a safe configuration file. 3354096Seric ** 3364096Seric ** Returns: 3374096Seric ** none. 3384096Seric ** 3394096Seric ** Side Effects: 3404096Seric ** enters the mailer into the mailer table. 3414096Seric */ 3423308Seric 3434096Seric # define SETWORD \ 3444096Seric { \ 3454096Seric while (*p != '\0' && isspace(*p)) \ 3464096Seric p++; \ 3474096Seric q = p; \ 3484096Seric while (*p != '\0' && !isspace(*p)) \ 3494096Seric p++; \ 3504096Seric if (*p != '\0') \ 3514096Seric *p++ = '\0'; \ 3524096Seric } 3534096Seric 3544217Seric makemailer(line, safe) 3554096Seric char *line; 3564217Seric bool safe; 3574096Seric { 3584096Seric register char *p; 3594096Seric register char *q; 3608067Seric register struct mailer *m; 3618067Seric register STAB *s; 3628067Seric int i; 3634096Seric char *mname; 3644096Seric char *mpath; 3654627Seric u_long mopts; 3668067Seric short mrset, msset; 3678067Seric char *margv[MAXPV + 1]; 3684627Seric extern u_long mfencode(); 3694096Seric extern int NextMailer; 3704096Seric 3714096Seric if (NextMailer >= MAXMAILERS) 3724096Seric { 3738056Seric syserr("readcf: line %d: too many mailers defined (%d max)", 3748056Seric LineNumber, MAXMAILERS); 3754096Seric return; 3764096Seric } 3774096Seric 3784096Seric /* collect initial information */ 3794096Seric p = line; 3804096Seric SETWORD; 3814096Seric mname = q; 3824096Seric SETWORD; 3834096Seric mpath = q; 3844096Seric SETWORD; 3854627Seric mopts = mfencode(q); 3864217Seric if (!safe) 3874217Seric mopts &= ~M_RESTR; 3884096Seric SETWORD; 3898067Seric msset = atoi(q); 3908067Seric SETWORD; 3918067Seric mrset = atoi(q); 3924096Seric 3934096Seric if (*p == '\0') 3944096Seric { 3958056Seric syserr("readcf: line %d: invalid M line in configuration file", 3968056Seric LineNumber); 3974096Seric return; 3984096Seric } 3998067Seric if (msset >= MAXRWSETS || mrset >= MAXRWSETS) 4008067Seric { 4018067Seric syserr("readcf: line %d: invalid rewrite set, %d max", 4028067Seric LineNumber, MAXRWSETS); 4038067Seric return; 4048067Seric } 4054096Seric 4064096Seric /* allocate a mailer */ 4074096Seric m = (struct mailer *) xalloc(sizeof *m); 4084096Seric m->m_name = newstr(mname); 4094096Seric m->m_mailer = newstr(mpath); 4104096Seric m->m_flags = mopts; 4118067Seric m->m_r_rwset = mrset; 4128067Seric m->m_s_rwset = msset; 4134096Seric m->m_badstat = EX_UNAVAILABLE; 4144439Seric m->m_mno = NextMailer; 4154096Seric Mailer[NextMailer++] = m; 4164096Seric 4174096Seric /* collect the argument vector */ 4184096Seric for (i = 0; i < MAXPV - 1 && *p != '\0'; i++) 4194096Seric { 4204096Seric SETWORD; 4214096Seric margv[i] = newstr(q); 4224096Seric } 4234096Seric margv[i++] = NULL; 4244096Seric 4254096Seric /* save the argv */ 4267009Seric m->m_argv = (char **) xalloc(sizeof margv[0] * i); 4274096Seric bmove((char *) margv, (char *) m->m_argv, sizeof margv[0] * i); 4284439Seric s = stab(m->m_name, ST_MAILER, ST_ENTER); 4294439Seric s->s_mailer = m; 4303308Seric } 4313308Seric /* 4323308Seric ** PRINTRULES -- print rewrite rules (for debugging) 4333308Seric ** 4343308Seric ** Parameters: 4353308Seric ** none. 4363308Seric ** 4373308Seric ** Returns: 4383308Seric ** none. 4393308Seric ** 4403308Seric ** Side Effects: 4413308Seric ** prints rewrite rules. 4423308Seric */ 4433308Seric 4444319Seric # ifdef DEBUG 4454319Seric 4463308Seric printrules() 4473308Seric { 4483308Seric register struct rewrite *rwp; 4494072Seric register int ruleset; 4503308Seric 4514072Seric for (ruleset = 0; ruleset < 10; ruleset++) 4523308Seric { 4534072Seric if (RewriteRules[ruleset] == NULL) 4544072Seric continue; 4558067Seric printf("\n----Rule Set %d:", ruleset); 4563308Seric 4574072Seric for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 4583308Seric { 4598067Seric printf("\nLHS:"); 4608067Seric printav(rwp->r_lhs); 4618067Seric printf("RHS:"); 4628067Seric printav(rwp->r_rhs); 4633308Seric } 4643308Seric } 4653308Seric } 4664319Seric 4674319Seric # endif DEBUG 4684096Seric /* 4694627Seric ** MFENCODE -- crack mailer options 4704096Seric ** 4714096Seric ** These options modify the functioning of the mailer 4724096Seric ** from the configuration table. 4734096Seric ** 4744096Seric ** Parameters: 4754096Seric ** p -- pointer to vector of options. 4764096Seric ** 4774096Seric ** Returns: 4784096Seric ** option list in binary. 4794096Seric ** 4804096Seric ** Side Effects: 4814096Seric ** none. 4824096Seric */ 4834096Seric 4844096Seric struct optlist 4854096Seric { 4864096Seric char opt_name; /* external name of option */ 4876275Seric u_long opt_value; /* internal name of option */ 4884096Seric }; 4894096Seric struct optlist OptList[] = 4904096Seric { 4914096Seric 'f', M_FOPT, 4924096Seric 'r', M_ROPT, 4934096Seric 'q', M_QUIET, 4944096Seric 'S', M_RESTR, 4954096Seric 'n', M_NHDR, 4964197Seric 'l', M_LOCAL, 4974096Seric 's', M_STRIPQ, 4984096Seric 'm', M_MUSER, 4994096Seric 'F', M_NEEDFROM, 5004096Seric 'D', M_NEEDDATE, 5014096Seric 'M', M_MSGID, 5024096Seric 'u', M_USR_UPPER, 5034096Seric 'h', M_HST_UPPER, 5044096Seric 'x', M_FULLNAME, 5054096Seric 'A', M_ARPAFMT, 5065601Seric 'U', M_UGLYUUCP, 5075906Seric 'e', M_EXPENSIVE, 5086983Seric 'X', M_FULLSMTP, 5098182Seric 'C', M_CANONICAL, 5104319Seric '\0', 0 5114096Seric }; 5124096Seric 5134627Seric u_long 5144627Seric mfencode(p) 5154096Seric register char *p; 5164096Seric { 5174096Seric register struct optlist *o; 5184627Seric register u_long opts = 0; 5194096Seric 5204096Seric while (*p != '\0') 5214096Seric { 5224096Seric for (o = OptList; o->opt_name != '\0' && o->opt_name != *p; o++) 5234096Seric continue; 5244096Seric if (o->opt_name == '\0') 5254096Seric syserr("bad mailer option %c", *p); 5264096Seric opts |= o->opt_value; 5274096Seric p++; 5284096Seric } 5294096Seric return (opts); 5304096Seric } 5314627Seric /* 5324627Seric ** MFDECODE -- decode mailer flags into external form. 5334627Seric ** 5344627Seric ** Parameters: 5354627Seric ** flags -- value of flags to decode. 5364627Seric ** f -- file to write them onto. 5374627Seric ** 5384627Seric ** Returns: 5394627Seric ** none. 5404627Seric ** 5414627Seric ** Side Effects: 5424627Seric ** none. 5434627Seric */ 5444627Seric 5454627Seric mfdecode(flags, f) 5464627Seric u_long flags; 5474627Seric FILE *f; 5484627Seric { 5494627Seric register struct optlist *o; 5504627Seric 5514627Seric putc('?', f); 5524627Seric for (o = OptList; o->opt_name != '\0'; o++) 5534627Seric { 5544627Seric if ((o->opt_value & flags) == o->opt_value) 5554627Seric { 5564627Seric flags &= ~o->opt_value; 5574627Seric putc(o->opt_name, f); 5584627Seric } 5594627Seric } 5604627Seric putc('?', f); 5614627Seric } 5628256Seric /* 5638256Seric ** SETOPTION -- set global processing option 5648256Seric ** 5658256Seric ** Parameters: 5668256Seric ** opt -- option name. 5678256Seric ** val -- option value (as a text string). 5688269Seric ** safe -- if set, this came from a system configuration file. 5698269Seric ** sticky -- if set, don't let other setoptions override 5708269Seric ** this value. 5718256Seric ** 5728256Seric ** Returns: 5738256Seric ** none. 5748256Seric ** 5758256Seric ** Side Effects: 5768256Seric ** Sets options as implied by the arguments. 5778256Seric */ 5788256Seric 5798544Seric static int StickyOpt[128 / sizeof (int)]; /* set if option is stuck */ 5808544Seric extern char *WizWord; /* the stored wizard password */ 5818269Seric 5828269Seric setoption(opt, val, safe, sticky) 5838256Seric char opt; 5848256Seric char *val; 5858269Seric bool safe; 5868269Seric bool sticky; 5878256Seric { 5888256Seric time_t tval; 5898256Seric int ival; 5908265Seric bool bval; 5918269Seric int smask; 5928269Seric int sindex; 5938265Seric extern bool atobool(); 5948256Seric 5958256Seric # ifdef DEBUG 5968256Seric if (tTd(37, 1)) 5978256Seric printf("setoption %c=%s\n", opt, val); 5988256Seric # endif DEBUG 5998256Seric 6008256Seric /* 6018269Seric ** See if this option is preset for us. 6028256Seric */ 6038256Seric 6048269Seric sindex = opt; 6058269Seric smask = 1 << (sindex % sizeof (int)); 6068269Seric sindex /= sizeof (int); 6078269Seric if (bitset(smask, StickyOpt[sindex])) 6088269Seric { 6098269Seric # ifdef DEBUG 6108269Seric if (tTd(37, 2)) 6118269Seric printf("(ignored)\n"); 6128269Seric # endif DEBUG 6138269Seric return; 6148269Seric } 6158269Seric if (sticky) 6168269Seric StickyOpt[sindex] |= smask; 6178269Seric 6188269Seric if (getruid() == 0) 6198269Seric safe = TRUE; 6208269Seric 6218269Seric /* 6228269Seric ** Encode this option as appropriate. 6238269Seric */ 6248269Seric 6258256Seric if (index("rT", opt) != NULL) 6268256Seric tval = convtime(val); 6278256Seric else if (index("gLu", opt) != NULL) 6288256Seric ival = atoi(val); 6298269Seric else if (index("cfimosv", opt) != NULL) 6308265Seric bval = atobool(val); 6318269Seric else if (index("be", opt) != NULL) 6328269Seric /* do nothing */ ; 6338256Seric else if (val[0] == '\0') 6348256Seric val = ""; 6358256Seric else 6368256Seric val = newstr(val); 6378256Seric 6388256Seric /* 6398256Seric ** Now do the actual assignment. 6408256Seric */ 6418256Seric 6428256Seric switch (opt) 6438256Seric { 6448256Seric case 'A': /* set default alias file */ 6458256Seric AliasFile = val; 6468269Seric if (AliasFile[0] == '\0') 6478269Seric AliasFile = "aliases"; 6488256Seric break; 6498256Seric 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