1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. 3*7c478bd9Sstevel@tonic-gate * All rights reserved. 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5*7c478bd9Sstevel@tonic-gate * Copyright (c) 1988, 1993 6*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 7*7c478bd9Sstevel@tonic-gate * 8*7c478bd9Sstevel@tonic-gate * By using this file, you agree to the terms and conditions set 9*7c478bd9Sstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of 10*7c478bd9Sstevel@tonic-gate * the sendmail distribution. 11*7c478bd9Sstevel@tonic-gate * 12*7c478bd9Sstevel@tonic-gate */ 13*7c478bd9Sstevel@tonic-gate 14*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 15*7c478bd9Sstevel@tonic-gate 16*7c478bd9Sstevel@tonic-gate #include <sendmail.h> 17*7c478bd9Sstevel@tonic-gate 18*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: readcf.c,v 8.642 2004/08/04 21:17:57 ca Exp $") 19*7c478bd9Sstevel@tonic-gate 20*7c478bd9Sstevel@tonic-gate #if NETINET || NETINET6 21*7c478bd9Sstevel@tonic-gate # include <arpa/inet.h> 22*7c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */ 23*7c478bd9Sstevel@tonic-gate 24*7c478bd9Sstevel@tonic-gate #define SECONDS 25*7c478bd9Sstevel@tonic-gate #define MINUTES * 60 26*7c478bd9Sstevel@tonic-gate #define HOUR * 3600 27*7c478bd9Sstevel@tonic-gate #define HOURS HOUR 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate static void fileclass __P((int, char *, char *, bool, bool, bool)); 30*7c478bd9Sstevel@tonic-gate static char **makeargv __P((char *)); 31*7c478bd9Sstevel@tonic-gate static void settimeout __P((char *, char *, bool)); 32*7c478bd9Sstevel@tonic-gate static void toomany __P((int, int)); 33*7c478bd9Sstevel@tonic-gate static char *extrquotstr __P((char *, char **, char *, bool *)); 34*7c478bd9Sstevel@tonic-gate static void parse_class_words __P((int, char *)); 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate /* 37*7c478bd9Sstevel@tonic-gate ** READCF -- read configuration file. 38*7c478bd9Sstevel@tonic-gate ** 39*7c478bd9Sstevel@tonic-gate ** This routine reads the configuration file and builds the internal 40*7c478bd9Sstevel@tonic-gate ** form. 41*7c478bd9Sstevel@tonic-gate ** 42*7c478bd9Sstevel@tonic-gate ** The file is formatted as a sequence of lines, each taken 43*7c478bd9Sstevel@tonic-gate ** atomically. The first character of each line describes how 44*7c478bd9Sstevel@tonic-gate ** the line is to be interpreted. The lines are: 45*7c478bd9Sstevel@tonic-gate ** Dxval Define macro x to have value val. 46*7c478bd9Sstevel@tonic-gate ** Cxword Put word into class x. 47*7c478bd9Sstevel@tonic-gate ** Fxfile [fmt] Read file for lines to put into 48*7c478bd9Sstevel@tonic-gate ** class x. Use scanf string 'fmt' 49*7c478bd9Sstevel@tonic-gate ** or "%s" if not present. Fmt should 50*7c478bd9Sstevel@tonic-gate ** only produce one string-valued result. 51*7c478bd9Sstevel@tonic-gate ** Hname: value Define header with field-name 'name' 52*7c478bd9Sstevel@tonic-gate ** and value as specified; this will be 53*7c478bd9Sstevel@tonic-gate ** macro expanded immediately before 54*7c478bd9Sstevel@tonic-gate ** use. 55*7c478bd9Sstevel@tonic-gate ** Sn Use rewriting set n. 56*7c478bd9Sstevel@tonic-gate ** Rlhs rhs Rewrite addresses that match lhs to 57*7c478bd9Sstevel@tonic-gate ** be rhs. 58*7c478bd9Sstevel@tonic-gate ** Mn arg=val... Define mailer. n is the internal name. 59*7c478bd9Sstevel@tonic-gate ** Args specify mailer parameters. 60*7c478bd9Sstevel@tonic-gate ** Oxvalue Set option x to value. 61*7c478bd9Sstevel@tonic-gate ** O option value Set option (long name) to value. 62*7c478bd9Sstevel@tonic-gate ** Pname=value Set precedence name to value. 63*7c478bd9Sstevel@tonic-gate ** Qn arg=val... Define queue groups. n is the internal name. 64*7c478bd9Sstevel@tonic-gate ** Args specify queue parameters. 65*7c478bd9Sstevel@tonic-gate ** Vversioncode[/vendorcode] 66*7c478bd9Sstevel@tonic-gate ** Version level/vendor name of 67*7c478bd9Sstevel@tonic-gate ** configuration syntax. 68*7c478bd9Sstevel@tonic-gate ** Kmapname mapclass arguments.... 69*7c478bd9Sstevel@tonic-gate ** Define keyed lookup of a given class. 70*7c478bd9Sstevel@tonic-gate ** Arguments are class dependent. 71*7c478bd9Sstevel@tonic-gate ** Eenvar=value Set the environment value to the given value. 72*7c478bd9Sstevel@tonic-gate ** 73*7c478bd9Sstevel@tonic-gate ** Parameters: 74*7c478bd9Sstevel@tonic-gate ** cfname -- configuration file name. 75*7c478bd9Sstevel@tonic-gate ** safe -- true if this is the system config file; 76*7c478bd9Sstevel@tonic-gate ** false otherwise. 77*7c478bd9Sstevel@tonic-gate ** e -- the main envelope. 78*7c478bd9Sstevel@tonic-gate ** 79*7c478bd9Sstevel@tonic-gate ** Returns: 80*7c478bd9Sstevel@tonic-gate ** none. 81*7c478bd9Sstevel@tonic-gate ** 82*7c478bd9Sstevel@tonic-gate ** Side Effects: 83*7c478bd9Sstevel@tonic-gate ** Builds several internal tables. 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate void 87*7c478bd9Sstevel@tonic-gate readcf(cfname, safe, e) 88*7c478bd9Sstevel@tonic-gate char *cfname; 89*7c478bd9Sstevel@tonic-gate bool safe; 90*7c478bd9Sstevel@tonic-gate register ENVELOPE *e; 91*7c478bd9Sstevel@tonic-gate { 92*7c478bd9Sstevel@tonic-gate SM_FILE_T *cf; 93*7c478bd9Sstevel@tonic-gate int ruleset = -1; 94*7c478bd9Sstevel@tonic-gate char *q; 95*7c478bd9Sstevel@tonic-gate struct rewrite *rwp = NULL; 96*7c478bd9Sstevel@tonic-gate char *bp; 97*7c478bd9Sstevel@tonic-gate auto char *ep; 98*7c478bd9Sstevel@tonic-gate int nfuzzy; 99*7c478bd9Sstevel@tonic-gate char *file; 100*7c478bd9Sstevel@tonic-gate bool optional; 101*7c478bd9Sstevel@tonic-gate bool ok; 102*7c478bd9Sstevel@tonic-gate bool ismap; 103*7c478bd9Sstevel@tonic-gate int mid; 104*7c478bd9Sstevel@tonic-gate register char *p; 105*7c478bd9Sstevel@tonic-gate long sff = SFF_OPENASROOT; 106*7c478bd9Sstevel@tonic-gate struct stat statb; 107*7c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 108*7c478bd9Sstevel@tonic-gate char exbuf[MAXLINE]; 109*7c478bd9Sstevel@tonic-gate char pvpbuf[MAXLINE + MAXATOM]; 110*7c478bd9Sstevel@tonic-gate static char *null_list[1] = { NULL }; 111*7c478bd9Sstevel@tonic-gate extern unsigned char TokTypeNoC[]; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate FileName = cfname; 114*7c478bd9Sstevel@tonic-gate LineNumber = 0; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate if (DontLockReadFiles) 117*7c478bd9Sstevel@tonic-gate sff |= SFF_NOLOCK; 118*7c478bd9Sstevel@tonic-gate cf = safefopen(cfname, O_RDONLY, 0444, sff); 119*7c478bd9Sstevel@tonic-gate if (cf == NULL) 120*7c478bd9Sstevel@tonic-gate { 121*7c478bd9Sstevel@tonic-gate syserr("cannot open"); 122*7c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate if (fstat(sm_io_getinfo(cf, SM_IO_WHAT_FD, NULL), &statb) < 0) 126*7c478bd9Sstevel@tonic-gate { 127*7c478bd9Sstevel@tonic-gate syserr("cannot fstat"); 128*7c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (!S_ISREG(statb.st_mode)) 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate syserr("not a plain file"); 134*7c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) 138*7c478bd9Sstevel@tonic-gate { 139*7c478bd9Sstevel@tonic-gate if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS) 140*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 141*7c478bd9Sstevel@tonic-gate "%s: WARNING: dangerous write permissions\n", 142*7c478bd9Sstevel@tonic-gate FileName); 143*7c478bd9Sstevel@tonic-gate if (LogLevel > 0) 144*7c478bd9Sstevel@tonic-gate sm_syslog(LOG_CRIT, NOQID, 145*7c478bd9Sstevel@tonic-gate "%s: WARNING: dangerous write permissions", 146*7c478bd9Sstevel@tonic-gate FileName); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate #if XLA 150*7c478bd9Sstevel@tonic-gate xla_zero(); 151*7c478bd9Sstevel@tonic-gate #endif /* XLA */ 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate while ((bp = fgetfolded(buf, sizeof buf, cf)) != NULL) 154*7c478bd9Sstevel@tonic-gate { 155*7c478bd9Sstevel@tonic-gate if (bp[0] == '#') 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate if (bp != buf) 158*7c478bd9Sstevel@tonic-gate sm_free(bp); /* XXX */ 159*7c478bd9Sstevel@tonic-gate continue; 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* do macro expansion mappings */ 163*7c478bd9Sstevel@tonic-gate translate_dollars(bp); 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate /* interpret this line */ 166*7c478bd9Sstevel@tonic-gate errno = 0; 167*7c478bd9Sstevel@tonic-gate switch (bp[0]) 168*7c478bd9Sstevel@tonic-gate { 169*7c478bd9Sstevel@tonic-gate case '\0': 170*7c478bd9Sstevel@tonic-gate case '#': /* comment */ 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate case 'R': /* rewriting rule */ 174*7c478bd9Sstevel@tonic-gate if (ruleset < 0) 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate syserr("missing valid ruleset for \"%s\"", bp); 177*7c478bd9Sstevel@tonic-gate break; 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate for (p = &bp[1]; *p != '\0' && *p != '\t'; p++) 180*7c478bd9Sstevel@tonic-gate continue; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate if (*p == '\0') 183*7c478bd9Sstevel@tonic-gate { 184*7c478bd9Sstevel@tonic-gate syserr("invalid rewrite line \"%s\" (tab expected)", bp); 185*7c478bd9Sstevel@tonic-gate break; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate /* allocate space for the rule header */ 189*7c478bd9Sstevel@tonic-gate if (rwp == NULL) 190*7c478bd9Sstevel@tonic-gate { 191*7c478bd9Sstevel@tonic-gate RewriteRules[ruleset] = rwp = 192*7c478bd9Sstevel@tonic-gate (struct rewrite *) xalloc(sizeof *rwp); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate else 195*7c478bd9Sstevel@tonic-gate { 196*7c478bd9Sstevel@tonic-gate rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 197*7c478bd9Sstevel@tonic-gate rwp = rwp->r_next; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate rwp->r_next = NULL; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* expand and save the LHS */ 202*7c478bd9Sstevel@tonic-gate *p = '\0'; 203*7c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 204*7c478bd9Sstevel@tonic-gate rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, 205*7c478bd9Sstevel@tonic-gate sizeof pvpbuf, NULL, 206*7c478bd9Sstevel@tonic-gate ConfigLevel >= 9 ? TokTypeNoC : NULL, 207*7c478bd9Sstevel@tonic-gate true); 208*7c478bd9Sstevel@tonic-gate nfuzzy = 0; 209*7c478bd9Sstevel@tonic-gate if (rwp->r_lhs != NULL) 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate register char **ap; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate rwp->r_lhs = copyplist(rwp->r_lhs, true, NULL); 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate /* count the number of fuzzy matches in LHS */ 216*7c478bd9Sstevel@tonic-gate for (ap = rwp->r_lhs; *ap != NULL; ap++) 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate char *botch; 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate botch = NULL; 221*7c478bd9Sstevel@tonic-gate switch (**ap & 0377) 222*7c478bd9Sstevel@tonic-gate { 223*7c478bd9Sstevel@tonic-gate case MATCHZANY: 224*7c478bd9Sstevel@tonic-gate case MATCHANY: 225*7c478bd9Sstevel@tonic-gate case MATCHONE: 226*7c478bd9Sstevel@tonic-gate case MATCHCLASS: 227*7c478bd9Sstevel@tonic-gate case MATCHNCLASS: 228*7c478bd9Sstevel@tonic-gate nfuzzy++; 229*7c478bd9Sstevel@tonic-gate break; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate case MATCHREPL: 232*7c478bd9Sstevel@tonic-gate botch = "$0-$9"; 233*7c478bd9Sstevel@tonic-gate break; 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate case CANONUSER: 236*7c478bd9Sstevel@tonic-gate botch = "$:"; 237*7c478bd9Sstevel@tonic-gate break; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate case CALLSUBR: 240*7c478bd9Sstevel@tonic-gate botch = "$>"; 241*7c478bd9Sstevel@tonic-gate break; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate case CONDIF: 244*7c478bd9Sstevel@tonic-gate botch = "$?"; 245*7c478bd9Sstevel@tonic-gate break; 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate case CONDFI: 248*7c478bd9Sstevel@tonic-gate botch = "$."; 249*7c478bd9Sstevel@tonic-gate break; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate case HOSTBEGIN: 252*7c478bd9Sstevel@tonic-gate botch = "$["; 253*7c478bd9Sstevel@tonic-gate break; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate case HOSTEND: 256*7c478bd9Sstevel@tonic-gate botch = "$]"; 257*7c478bd9Sstevel@tonic-gate break; 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 260*7c478bd9Sstevel@tonic-gate botch = "$("; 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate case LOOKUPEND: 264*7c478bd9Sstevel@tonic-gate botch = "$)"; 265*7c478bd9Sstevel@tonic-gate break; 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate if (botch != NULL) 268*7c478bd9Sstevel@tonic-gate syserr("Inappropriate use of %s on LHS", 269*7c478bd9Sstevel@tonic-gate botch); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate rwp->r_line = LineNumber; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate else 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate syserr("R line: null LHS"); 276*7c478bd9Sstevel@tonic-gate rwp->r_lhs = null_list; 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate if (nfuzzy > MAXMATCH) 279*7c478bd9Sstevel@tonic-gate { 280*7c478bd9Sstevel@tonic-gate syserr("R line: too many wildcards"); 281*7c478bd9Sstevel@tonic-gate rwp->r_lhs = null_list; 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* expand and save the RHS */ 285*7c478bd9Sstevel@tonic-gate while (*++p == '\t') 286*7c478bd9Sstevel@tonic-gate continue; 287*7c478bd9Sstevel@tonic-gate q = p; 288*7c478bd9Sstevel@tonic-gate while (*p != '\0' && *p != '\t') 289*7c478bd9Sstevel@tonic-gate p++; 290*7c478bd9Sstevel@tonic-gate *p = '\0'; 291*7c478bd9Sstevel@tonic-gate expand(q, exbuf, sizeof exbuf, e); 292*7c478bd9Sstevel@tonic-gate rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, 293*7c478bd9Sstevel@tonic-gate sizeof pvpbuf, NULL, 294*7c478bd9Sstevel@tonic-gate ConfigLevel >= 9 ? TokTypeNoC : NULL, 295*7c478bd9Sstevel@tonic-gate true); 296*7c478bd9Sstevel@tonic-gate if (rwp->r_rhs != NULL) 297*7c478bd9Sstevel@tonic-gate { 298*7c478bd9Sstevel@tonic-gate register char **ap; 299*7c478bd9Sstevel@tonic-gate int args, endtoken; 300*7c478bd9Sstevel@tonic-gate #if _FFR_EXTRA_MAP_CHECK 301*7c478bd9Sstevel@tonic-gate int nexttoken; 302*7c478bd9Sstevel@tonic-gate #endif /* _FFR_EXTRA_MAP_CHECK */ 303*7c478bd9Sstevel@tonic-gate bool inmap; 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate rwp->r_rhs = copyplist(rwp->r_rhs, true, NULL); 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* check no out-of-bounds replacements */ 308*7c478bd9Sstevel@tonic-gate nfuzzy += '0'; 309*7c478bd9Sstevel@tonic-gate inmap = false; 310*7c478bd9Sstevel@tonic-gate args = 0; 311*7c478bd9Sstevel@tonic-gate endtoken = 0; 312*7c478bd9Sstevel@tonic-gate for (ap = rwp->r_rhs; *ap != NULL; ap++) 313*7c478bd9Sstevel@tonic-gate { 314*7c478bd9Sstevel@tonic-gate char *botch; 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate botch = NULL; 317*7c478bd9Sstevel@tonic-gate switch (**ap & 0377) 318*7c478bd9Sstevel@tonic-gate { 319*7c478bd9Sstevel@tonic-gate case MATCHREPL: 320*7c478bd9Sstevel@tonic-gate if ((*ap)[1] <= '0' || (*ap)[1] > nfuzzy) 321*7c478bd9Sstevel@tonic-gate { 322*7c478bd9Sstevel@tonic-gate syserr("replacement $%c out of bounds", 323*7c478bd9Sstevel@tonic-gate (*ap)[1]); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate break; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate case MATCHZANY: 328*7c478bd9Sstevel@tonic-gate botch = "$*"; 329*7c478bd9Sstevel@tonic-gate break; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate case MATCHANY: 332*7c478bd9Sstevel@tonic-gate botch = "$+"; 333*7c478bd9Sstevel@tonic-gate break; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate case MATCHONE: 336*7c478bd9Sstevel@tonic-gate botch = "$-"; 337*7c478bd9Sstevel@tonic-gate break; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate case MATCHCLASS: 340*7c478bd9Sstevel@tonic-gate botch = "$="; 341*7c478bd9Sstevel@tonic-gate break; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate case MATCHNCLASS: 344*7c478bd9Sstevel@tonic-gate botch = "$~"; 345*7c478bd9Sstevel@tonic-gate break; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate case CANONHOST: 348*7c478bd9Sstevel@tonic-gate if (!inmap) 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate if (++args >= MAX_MAP_ARGS) 351*7c478bd9Sstevel@tonic-gate syserr("too many arguments for map lookup"); 352*7c478bd9Sstevel@tonic-gate break; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate case HOSTBEGIN: 355*7c478bd9Sstevel@tonic-gate endtoken = HOSTEND; 356*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 357*7c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 358*7c478bd9Sstevel@tonic-gate /* see above... */ 359*7c478bd9Sstevel@tonic-gate if ((**ap & 0377) == LOOKUPBEGIN) 360*7c478bd9Sstevel@tonic-gate endtoken = LOOKUPEND; 361*7c478bd9Sstevel@tonic-gate if (inmap) 362*7c478bd9Sstevel@tonic-gate syserr("cannot nest map lookups"); 363*7c478bd9Sstevel@tonic-gate inmap = true; 364*7c478bd9Sstevel@tonic-gate args = 0; 365*7c478bd9Sstevel@tonic-gate #if _FFR_EXTRA_MAP_CHECK 366*7c478bd9Sstevel@tonic-gate if (*(ap + 1) == NULL) 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 369*7c478bd9Sstevel@tonic-gate break; 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate nexttoken = **(ap + 1) & 0377; 372*7c478bd9Sstevel@tonic-gate if (nexttoken == CANONHOST || 373*7c478bd9Sstevel@tonic-gate nexttoken == CANONUSER || 374*7c478bd9Sstevel@tonic-gate nexttoken == endtoken) 375*7c478bd9Sstevel@tonic-gate { 376*7c478bd9Sstevel@tonic-gate syserr("missing map name for lookup"); 377*7c478bd9Sstevel@tonic-gate break; 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate if (*(ap + 2) == NULL) 380*7c478bd9Sstevel@tonic-gate { 381*7c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 382*7c478bd9Sstevel@tonic-gate break; 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate if ((**ap & 0377) == HOSTBEGIN) 385*7c478bd9Sstevel@tonic-gate break; 386*7c478bd9Sstevel@tonic-gate nexttoken = **(ap + 2) & 0377; 387*7c478bd9Sstevel@tonic-gate if (nexttoken == CANONHOST || 388*7c478bd9Sstevel@tonic-gate nexttoken == CANONUSER || 389*7c478bd9Sstevel@tonic-gate nexttoken == endtoken) 390*7c478bd9Sstevel@tonic-gate { 391*7c478bd9Sstevel@tonic-gate syserr("missing key name for lookup"); 392*7c478bd9Sstevel@tonic-gate break; 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate #endif /* _FFR_EXTRA_MAP_CHECK */ 395*7c478bd9Sstevel@tonic-gate break; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate case HOSTEND: 398*7c478bd9Sstevel@tonic-gate case LOOKUPEND: 399*7c478bd9Sstevel@tonic-gate if ((**ap & 0377) != endtoken) 400*7c478bd9Sstevel@tonic-gate break; 401*7c478bd9Sstevel@tonic-gate inmap = false; 402*7c478bd9Sstevel@tonic-gate endtoken = 0; 403*7c478bd9Sstevel@tonic-gate break; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate #if 0 407*7c478bd9Sstevel@tonic-gate /* 408*7c478bd9Sstevel@tonic-gate ** This doesn't work yet as there are maps defined *after* the cf 409*7c478bd9Sstevel@tonic-gate ** is read such as host, user, and alias. So for now, it's removed. 410*7c478bd9Sstevel@tonic-gate ** When it comes back, the RELEASE_NOTES entry will be: 411*7c478bd9Sstevel@tonic-gate ** Emit warnings for unknown maps when reading the .cf file. Based on 412*7c478bd9Sstevel@tonic-gate ** patch from Robert Harker of Harker Systems. 413*7c478bd9Sstevel@tonic-gate */ 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 416*7c478bd9Sstevel@tonic-gate /* 417*7c478bd9Sstevel@tonic-gate ** Got a database lookup, 418*7c478bd9Sstevel@tonic-gate ** check if map is defined. 419*7c478bd9Sstevel@tonic-gate */ 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate ep = *(ap + 1); 422*7c478bd9Sstevel@tonic-gate if ((*ep & 0377) != MACRODEXPAND && 423*7c478bd9Sstevel@tonic-gate stab(ep, ST_MAP, 424*7c478bd9Sstevel@tonic-gate ST_FIND) == NULL) 425*7c478bd9Sstevel@tonic-gate { 426*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 427*7c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 428*7c478bd9Sstevel@tonic-gate "Warning: %s: line %d: map %s not found\n", 429*7c478bd9Sstevel@tonic-gate FileName, 430*7c478bd9Sstevel@tonic-gate LineNumber, 431*7c478bd9Sstevel@tonic-gate ep); 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate break; 434*7c478bd9Sstevel@tonic-gate #endif /* 0 */ 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate if (botch != NULL) 437*7c478bd9Sstevel@tonic-gate syserr("Inappropriate use of %s on RHS", 438*7c478bd9Sstevel@tonic-gate botch); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate if (inmap) 441*7c478bd9Sstevel@tonic-gate syserr("missing map closing token"); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate else 444*7c478bd9Sstevel@tonic-gate { 445*7c478bd9Sstevel@tonic-gate syserr("R line: null RHS"); 446*7c478bd9Sstevel@tonic-gate rwp->r_rhs = null_list; 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate break; 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate case 'S': /* select rewriting set */ 451*7c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 452*7c478bd9Sstevel@tonic-gate ruleset = strtorwset(exbuf, NULL, ST_ENTER); 453*7c478bd9Sstevel@tonic-gate if (ruleset < 0) 454*7c478bd9Sstevel@tonic-gate break; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate rwp = RewriteRules[ruleset]; 457*7c478bd9Sstevel@tonic-gate if (rwp != NULL) 458*7c478bd9Sstevel@tonic-gate { 459*7c478bd9Sstevel@tonic-gate if (OpMode == MD_TEST) 460*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 461*7c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 462*7c478bd9Sstevel@tonic-gate "WARNING: Ruleset %s has multiple definitions\n", 463*7c478bd9Sstevel@tonic-gate &bp[1]); 464*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 465*7c478bd9Sstevel@tonic-gate sm_dprintf("WARNING: Ruleset %s has multiple definitions\n", 466*7c478bd9Sstevel@tonic-gate &bp[1]); 467*7c478bd9Sstevel@tonic-gate while (rwp->r_next != NULL) 468*7c478bd9Sstevel@tonic-gate rwp = rwp->r_next; 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate break; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate case 'D': /* macro definition */ 473*7c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 474*7c478bd9Sstevel@tonic-gate if (mid == 0) 475*7c478bd9Sstevel@tonic-gate break; 476*7c478bd9Sstevel@tonic-gate p = munchstring(ep, NULL, '\0'); 477*7c478bd9Sstevel@tonic-gate macdefine(&e->e_macro, A_TEMP, mid, p); 478*7c478bd9Sstevel@tonic-gate break; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate case 'H': /* required header line */ 481*7c478bd9Sstevel@tonic-gate (void) chompheader(&bp[1], CHHDR_DEF, NULL, e); 482*7c478bd9Sstevel@tonic-gate break; 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate case 'C': /* word class */ 485*7c478bd9Sstevel@tonic-gate case 'T': /* trusted user (set class `t') */ 486*7c478bd9Sstevel@tonic-gate if (bp[0] == 'C') 487*7c478bd9Sstevel@tonic-gate { 488*7c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 489*7c478bd9Sstevel@tonic-gate if (mid == 0) 490*7c478bd9Sstevel@tonic-gate break; 491*7c478bd9Sstevel@tonic-gate expand(ep, exbuf, sizeof exbuf, e); 492*7c478bd9Sstevel@tonic-gate p = exbuf; 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate else 495*7c478bd9Sstevel@tonic-gate { 496*7c478bd9Sstevel@tonic-gate mid = 't'; 497*7c478bd9Sstevel@tonic-gate p = &bp[1]; 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate while (*p != '\0') 500*7c478bd9Sstevel@tonic-gate { 501*7c478bd9Sstevel@tonic-gate register char *wd; 502*7c478bd9Sstevel@tonic-gate char delim; 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && isspace(*p)) 505*7c478bd9Sstevel@tonic-gate p++; 506*7c478bd9Sstevel@tonic-gate wd = p; 507*7c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 508*7c478bd9Sstevel@tonic-gate p++; 509*7c478bd9Sstevel@tonic-gate delim = *p; 510*7c478bd9Sstevel@tonic-gate *p = '\0'; 511*7c478bd9Sstevel@tonic-gate if (wd[0] != '\0') 512*7c478bd9Sstevel@tonic-gate setclass(mid, wd); 513*7c478bd9Sstevel@tonic-gate *p = delim; 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate break; 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate case 'F': /* word class from file */ 518*7c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 519*7c478bd9Sstevel@tonic-gate if (mid == 0) 520*7c478bd9Sstevel@tonic-gate break; 521*7c478bd9Sstevel@tonic-gate for (p = ep; isascii(*p) && isspace(*p); ) 522*7c478bd9Sstevel@tonic-gate p++; 523*7c478bd9Sstevel@tonic-gate if (p[0] == '-' && p[1] == 'o') 524*7c478bd9Sstevel@tonic-gate { 525*7c478bd9Sstevel@tonic-gate optional = true; 526*7c478bd9Sstevel@tonic-gate while (*p != '\0' && 527*7c478bd9Sstevel@tonic-gate !(isascii(*p) && isspace(*p))) 528*7c478bd9Sstevel@tonic-gate p++; 529*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 530*7c478bd9Sstevel@tonic-gate p++; 531*7c478bd9Sstevel@tonic-gate file = p; 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate else 534*7c478bd9Sstevel@tonic-gate optional = false; 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate /* check if [key]@map:spec */ 537*7c478bd9Sstevel@tonic-gate ismap = false; 538*7c478bd9Sstevel@tonic-gate if (!SM_IS_DIR_DELIM(*p) && 539*7c478bd9Sstevel@tonic-gate *p != '|' && 540*7c478bd9Sstevel@tonic-gate (q = strchr(p, '@')) != NULL) 541*7c478bd9Sstevel@tonic-gate { 542*7c478bd9Sstevel@tonic-gate q++; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* look for @LDAP or @map: in string */ 545*7c478bd9Sstevel@tonic-gate if (strcmp(q, "LDAP") == 0 || 546*7c478bd9Sstevel@tonic-gate (*q != ':' && 547*7c478bd9Sstevel@tonic-gate strchr(q, ':') != NULL)) 548*7c478bd9Sstevel@tonic-gate ismap = true; 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate if (ismap) 552*7c478bd9Sstevel@tonic-gate { 553*7c478bd9Sstevel@tonic-gate /* use entire spec */ 554*7c478bd9Sstevel@tonic-gate file = p; 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate else 557*7c478bd9Sstevel@tonic-gate { 558*7c478bd9Sstevel@tonic-gate file = extrquotstr(p, &q, " ", &ok); 559*7c478bd9Sstevel@tonic-gate if (!ok) 560*7c478bd9Sstevel@tonic-gate { 561*7c478bd9Sstevel@tonic-gate syserr("illegal filename '%s'", p); 562*7c478bd9Sstevel@tonic-gate break; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate if (*file == '|' || ismap) 567*7c478bd9Sstevel@tonic-gate p = "%s"; 568*7c478bd9Sstevel@tonic-gate else 569*7c478bd9Sstevel@tonic-gate { 570*7c478bd9Sstevel@tonic-gate p = q; 571*7c478bd9Sstevel@tonic-gate if (*p == '\0') 572*7c478bd9Sstevel@tonic-gate p = "%s"; 573*7c478bd9Sstevel@tonic-gate else 574*7c478bd9Sstevel@tonic-gate { 575*7c478bd9Sstevel@tonic-gate *p = '\0'; 576*7c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 577*7c478bd9Sstevel@tonic-gate continue; 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate fileclass(mid, file, p, ismap, safe, optional); 581*7c478bd9Sstevel@tonic-gate break; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate #if XLA 584*7c478bd9Sstevel@tonic-gate case 'L': /* extended load average description */ 585*7c478bd9Sstevel@tonic-gate xla_init(&bp[1]); 586*7c478bd9Sstevel@tonic-gate break; 587*7c478bd9Sstevel@tonic-gate #endif /* XLA */ 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) 590*7c478bd9Sstevel@tonic-gate case 'L': /* lookup macro */ 591*7c478bd9Sstevel@tonic-gate case 'G': /* lookup class */ 592*7c478bd9Sstevel@tonic-gate /* reserved for Sun -- NIS+ database lookup */ 593*7c478bd9Sstevel@tonic-gate if (VendorCode != VENDOR_SUN) 594*7c478bd9Sstevel@tonic-gate goto badline; 595*7c478bd9Sstevel@tonic-gate sun_lg_config_line(bp, e); 596*7c478bd9Sstevel@tonic-gate break; 597*7c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) */ 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate case 'M': /* define mailer */ 600*7c478bd9Sstevel@tonic-gate makemailer(&bp[1]); 601*7c478bd9Sstevel@tonic-gate break; 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate case 'O': /* set option */ 604*7c478bd9Sstevel@tonic-gate setoption(bp[1], &bp[2], safe, false, e); 605*7c478bd9Sstevel@tonic-gate break; 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate case 'P': /* set precedence */ 608*7c478bd9Sstevel@tonic-gate if (NumPriorities >= MAXPRIORITIES) 609*7c478bd9Sstevel@tonic-gate { 610*7c478bd9Sstevel@tonic-gate toomany('P', MAXPRIORITIES); 611*7c478bd9Sstevel@tonic-gate break; 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate for (p = &bp[1]; *p != '\0' && *p != '='; p++) 614*7c478bd9Sstevel@tonic-gate continue; 615*7c478bd9Sstevel@tonic-gate if (*p == '\0') 616*7c478bd9Sstevel@tonic-gate goto badline; 617*7c478bd9Sstevel@tonic-gate *p = '\0'; 618*7c478bd9Sstevel@tonic-gate Priorities[NumPriorities].pri_name = newstr(&bp[1]); 619*7c478bd9Sstevel@tonic-gate Priorities[NumPriorities].pri_val = atoi(++p); 620*7c478bd9Sstevel@tonic-gate NumPriorities++; 621*7c478bd9Sstevel@tonic-gate break; 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate case 'Q': /* define queue */ 624*7c478bd9Sstevel@tonic-gate makequeue(&bp[1], true); 625*7c478bd9Sstevel@tonic-gate break; 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate case 'V': /* configuration syntax version */ 628*7c478bd9Sstevel@tonic-gate for (p = &bp[1]; isascii(*p) && isspace(*p); p++) 629*7c478bd9Sstevel@tonic-gate continue; 630*7c478bd9Sstevel@tonic-gate if (!isascii(*p) || !isdigit(*p)) 631*7c478bd9Sstevel@tonic-gate { 632*7c478bd9Sstevel@tonic-gate syserr("invalid argument to V line: \"%.20s\"", 633*7c478bd9Sstevel@tonic-gate &bp[1]); 634*7c478bd9Sstevel@tonic-gate break; 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate ConfigLevel = strtol(p, &ep, 10); 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate /* 639*7c478bd9Sstevel@tonic-gate ** Do heuristic tweaking for back compatibility. 640*7c478bd9Sstevel@tonic-gate */ 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate if (ConfigLevel >= 5) 643*7c478bd9Sstevel@tonic-gate { 644*7c478bd9Sstevel@tonic-gate /* level 5 configs have short name in $w */ 645*7c478bd9Sstevel@tonic-gate p = macvalue('w', e); 646*7c478bd9Sstevel@tonic-gate if (p != NULL && (p = strchr(p, '.')) != NULL) 647*7c478bd9Sstevel@tonic-gate { 648*7c478bd9Sstevel@tonic-gate *p = '\0'; 649*7c478bd9Sstevel@tonic-gate macdefine(&e->e_macro, A_TEMP, 'w', 650*7c478bd9Sstevel@tonic-gate macvalue('w', e)); 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate if (ConfigLevel >= 6) 654*7c478bd9Sstevel@tonic-gate { 655*7c478bd9Sstevel@tonic-gate ColonOkInAddr = false; 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate /* 659*7c478bd9Sstevel@tonic-gate ** Look for vendor code. 660*7c478bd9Sstevel@tonic-gate */ 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate if (*ep++ == '/') 663*7c478bd9Sstevel@tonic-gate { 664*7c478bd9Sstevel@tonic-gate /* extract vendor code */ 665*7c478bd9Sstevel@tonic-gate for (p = ep; isascii(*p) && isalpha(*p); ) 666*7c478bd9Sstevel@tonic-gate p++; 667*7c478bd9Sstevel@tonic-gate *p = '\0'; 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate if (!setvendor(ep)) 670*7c478bd9Sstevel@tonic-gate syserr("invalid V line vendor code: \"%s\"", 671*7c478bd9Sstevel@tonic-gate ep); 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate break; 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate case 'K': 676*7c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 677*7c478bd9Sstevel@tonic-gate (void) makemapentry(exbuf); 678*7c478bd9Sstevel@tonic-gate break; 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate case 'E': 681*7c478bd9Sstevel@tonic-gate p = strchr(bp, '='); 682*7c478bd9Sstevel@tonic-gate if (p != NULL) 683*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 684*7c478bd9Sstevel@tonic-gate setuserenv(&bp[1], p); 685*7c478bd9Sstevel@tonic-gate break; 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate case 'X': /* mail filter */ 688*7c478bd9Sstevel@tonic-gate #if MILTER 689*7c478bd9Sstevel@tonic-gate milter_setup(&bp[1]); 690*7c478bd9Sstevel@tonic-gate #else /* MILTER */ 691*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 692*7c478bd9Sstevel@tonic-gate "Warning: Filter usage ('X') requires Milter support (-DMILTER)\n"); 693*7c478bd9Sstevel@tonic-gate #endif /* MILTER */ 694*7c478bd9Sstevel@tonic-gate break; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate default: 697*7c478bd9Sstevel@tonic-gate badline: 698*7c478bd9Sstevel@tonic-gate syserr("unknown configuration line \"%s\"", bp); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate if (bp != buf) 701*7c478bd9Sstevel@tonic-gate sm_free(bp); /* XXX */ 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate if (sm_io_error(cf)) 704*7c478bd9Sstevel@tonic-gate { 705*7c478bd9Sstevel@tonic-gate syserr("I/O read error"); 706*7c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 707*7c478bd9Sstevel@tonic-gate } 708*7c478bd9Sstevel@tonic-gate (void) sm_io_close(cf, SM_TIME_DEFAULT); 709*7c478bd9Sstevel@tonic-gate FileName = NULL; 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate /* initialize host maps from local service tables */ 712*7c478bd9Sstevel@tonic-gate inithostmaps(); 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate /* initialize daemon (if not defined yet) */ 715*7c478bd9Sstevel@tonic-gate initdaemon(); 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate /* determine if we need to do special name-server frotz */ 718*7c478bd9Sstevel@tonic-gate { 719*7c478bd9Sstevel@tonic-gate int nmaps; 720*7c478bd9Sstevel@tonic-gate char *maptype[MAXMAPSTACK]; 721*7c478bd9Sstevel@tonic-gate short mapreturn[MAXMAPACTIONS]; 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate nmaps = switch_map_find("hosts", maptype, mapreturn); 724*7c478bd9Sstevel@tonic-gate UseNameServer = false; 725*7c478bd9Sstevel@tonic-gate if (nmaps > 0 && nmaps <= MAXMAPSTACK) 726*7c478bd9Sstevel@tonic-gate { 727*7c478bd9Sstevel@tonic-gate register int mapno; 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < nmaps && !UseNameServer; 730*7c478bd9Sstevel@tonic-gate mapno++) 731*7c478bd9Sstevel@tonic-gate { 732*7c478bd9Sstevel@tonic-gate if (strcmp(maptype[mapno], "dns") == 0) 733*7c478bd9Sstevel@tonic-gate UseNameServer = true; 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate /* 739*7c478bd9Sstevel@tonic-gate ** TRANSLATE_DOLLARS -- convert $x into internal form 740*7c478bd9Sstevel@tonic-gate ** 741*7c478bd9Sstevel@tonic-gate ** Actually does all appropriate pre-processing of a config line 742*7c478bd9Sstevel@tonic-gate ** to turn it into internal form. 743*7c478bd9Sstevel@tonic-gate ** 744*7c478bd9Sstevel@tonic-gate ** Parameters: 745*7c478bd9Sstevel@tonic-gate ** bp -- the buffer to translate. 746*7c478bd9Sstevel@tonic-gate ** 747*7c478bd9Sstevel@tonic-gate ** Returns: 748*7c478bd9Sstevel@tonic-gate ** None. The buffer is translated in place. Since the 749*7c478bd9Sstevel@tonic-gate ** translations always make the buffer shorter, this is 750*7c478bd9Sstevel@tonic-gate ** safe without a size parameter. 751*7c478bd9Sstevel@tonic-gate */ 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate void 754*7c478bd9Sstevel@tonic-gate translate_dollars(bp) 755*7c478bd9Sstevel@tonic-gate char *bp; 756*7c478bd9Sstevel@tonic-gate { 757*7c478bd9Sstevel@tonic-gate register char *p; 758*7c478bd9Sstevel@tonic-gate auto char *ep; 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate for (p = bp; *p != '\0'; p++) 761*7c478bd9Sstevel@tonic-gate { 762*7c478bd9Sstevel@tonic-gate if (*p == '#' && p > bp && ConfigLevel >= 3) 763*7c478bd9Sstevel@tonic-gate { 764*7c478bd9Sstevel@tonic-gate register char *e; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate switch (*--p & 0377) 767*7c478bd9Sstevel@tonic-gate { 768*7c478bd9Sstevel@tonic-gate case MACROEXPAND: 769*7c478bd9Sstevel@tonic-gate /* it's from $# -- let it go through */ 770*7c478bd9Sstevel@tonic-gate p++; 771*7c478bd9Sstevel@tonic-gate break; 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate case '\\': 774*7c478bd9Sstevel@tonic-gate /* it's backslash escaped */ 775*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, p + 1, strlen(p)); 776*7c478bd9Sstevel@tonic-gate break; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate default: 779*7c478bd9Sstevel@tonic-gate /* delete leading white space */ 780*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p) && 781*7c478bd9Sstevel@tonic-gate *p != '\n' && p > bp) 782*7c478bd9Sstevel@tonic-gate p--; 783*7c478bd9Sstevel@tonic-gate if ((e = strchr(++p, '\n')) != NULL) 784*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, e, strlen(p)); 785*7c478bd9Sstevel@tonic-gate else 786*7c478bd9Sstevel@tonic-gate *p-- = '\0'; 787*7c478bd9Sstevel@tonic-gate break; 788*7c478bd9Sstevel@tonic-gate } 789*7c478bd9Sstevel@tonic-gate continue; 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate if (*p != '$' || p[1] == '\0') 793*7c478bd9Sstevel@tonic-gate continue; 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate if (p[1] == '$') 796*7c478bd9Sstevel@tonic-gate { 797*7c478bd9Sstevel@tonic-gate /* actual dollar sign.... */ 798*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, p + 1, strlen(p)); 799*7c478bd9Sstevel@tonic-gate continue; 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate /* convert to macro expansion character */ 803*7c478bd9Sstevel@tonic-gate *p++ = MACROEXPAND; 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate /* special handling for $=, $~, $&, and $? */ 806*7c478bd9Sstevel@tonic-gate if (*p == '=' || *p == '~' || *p == '&' || *p == '?') 807*7c478bd9Sstevel@tonic-gate p++; 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate /* convert macro name to code */ 810*7c478bd9Sstevel@tonic-gate *p = macid_parse(p, &ep); 811*7c478bd9Sstevel@tonic-gate if (ep != p + 1) 812*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p + 1, ep, strlen(p + 1)); 813*7c478bd9Sstevel@tonic-gate } 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate /* strip trailing white space from the line */ 816*7c478bd9Sstevel@tonic-gate while (--p > bp && isascii(*p) && isspace(*p)) 817*7c478bd9Sstevel@tonic-gate *p = '\0'; 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate /* 820*7c478bd9Sstevel@tonic-gate ** TOOMANY -- signal too many of some option 821*7c478bd9Sstevel@tonic-gate ** 822*7c478bd9Sstevel@tonic-gate ** Parameters: 823*7c478bd9Sstevel@tonic-gate ** id -- the id of the error line 824*7c478bd9Sstevel@tonic-gate ** maxcnt -- the maximum possible values 825*7c478bd9Sstevel@tonic-gate ** 826*7c478bd9Sstevel@tonic-gate ** Returns: 827*7c478bd9Sstevel@tonic-gate ** none. 828*7c478bd9Sstevel@tonic-gate ** 829*7c478bd9Sstevel@tonic-gate ** Side Effects: 830*7c478bd9Sstevel@tonic-gate ** gives a syserr. 831*7c478bd9Sstevel@tonic-gate */ 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate static void 834*7c478bd9Sstevel@tonic-gate toomany(id, maxcnt) 835*7c478bd9Sstevel@tonic-gate int id; 836*7c478bd9Sstevel@tonic-gate int maxcnt; 837*7c478bd9Sstevel@tonic-gate { 838*7c478bd9Sstevel@tonic-gate syserr("too many %c lines, %d max", id, maxcnt); 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate /* 841*7c478bd9Sstevel@tonic-gate ** FILECLASS -- read members of a class from a file 842*7c478bd9Sstevel@tonic-gate ** 843*7c478bd9Sstevel@tonic-gate ** Parameters: 844*7c478bd9Sstevel@tonic-gate ** class -- class to define. 845*7c478bd9Sstevel@tonic-gate ** filename -- name of file to read. 846*7c478bd9Sstevel@tonic-gate ** fmt -- scanf string to use for match. 847*7c478bd9Sstevel@tonic-gate ** ismap -- if set, this is a map lookup. 848*7c478bd9Sstevel@tonic-gate ** safe -- if set, this is a safe read. 849*7c478bd9Sstevel@tonic-gate ** optional -- if set, it is not an error for the file to 850*7c478bd9Sstevel@tonic-gate ** not exist. 851*7c478bd9Sstevel@tonic-gate ** 852*7c478bd9Sstevel@tonic-gate ** Returns: 853*7c478bd9Sstevel@tonic-gate ** none 854*7c478bd9Sstevel@tonic-gate ** 855*7c478bd9Sstevel@tonic-gate ** Side Effects: 856*7c478bd9Sstevel@tonic-gate ** puts all lines in filename that match a scanf into 857*7c478bd9Sstevel@tonic-gate ** the named class. 858*7c478bd9Sstevel@tonic-gate */ 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate /* 861*7c478bd9Sstevel@tonic-gate ** Break up the match into words and add to class. 862*7c478bd9Sstevel@tonic-gate */ 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate static void 865*7c478bd9Sstevel@tonic-gate parse_class_words(class, line) 866*7c478bd9Sstevel@tonic-gate int class; 867*7c478bd9Sstevel@tonic-gate char *line; 868*7c478bd9Sstevel@tonic-gate { 869*7c478bd9Sstevel@tonic-gate while (line != NULL && *line != '\0') 870*7c478bd9Sstevel@tonic-gate { 871*7c478bd9Sstevel@tonic-gate register char *q; 872*7c478bd9Sstevel@tonic-gate 873*7c478bd9Sstevel@tonic-gate /* strip leading spaces */ 874*7c478bd9Sstevel@tonic-gate while (isascii(*line) && isspace(*line)) 875*7c478bd9Sstevel@tonic-gate line++; 876*7c478bd9Sstevel@tonic-gate if (*line == '\0') 877*7c478bd9Sstevel@tonic-gate break; 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate /* find the end of the word */ 880*7c478bd9Sstevel@tonic-gate q = line; 881*7c478bd9Sstevel@tonic-gate while (*line != '\0' && !(isascii(*line) && isspace(*line))) 882*7c478bd9Sstevel@tonic-gate line++; 883*7c478bd9Sstevel@tonic-gate if (*line != '\0') 884*7c478bd9Sstevel@tonic-gate *line++ = '\0'; 885*7c478bd9Sstevel@tonic-gate 886*7c478bd9Sstevel@tonic-gate /* enter the word in the symbol table */ 887*7c478bd9Sstevel@tonic-gate setclass(class, q); 888*7c478bd9Sstevel@tonic-gate } 889*7c478bd9Sstevel@tonic-gate } 890*7c478bd9Sstevel@tonic-gate 891*7c478bd9Sstevel@tonic-gate static void 892*7c478bd9Sstevel@tonic-gate fileclass(class, filename, fmt, ismap, safe, optional) 893*7c478bd9Sstevel@tonic-gate int class; 894*7c478bd9Sstevel@tonic-gate char *filename; 895*7c478bd9Sstevel@tonic-gate char *fmt; 896*7c478bd9Sstevel@tonic-gate bool ismap; 897*7c478bd9Sstevel@tonic-gate bool safe; 898*7c478bd9Sstevel@tonic-gate bool optional; 899*7c478bd9Sstevel@tonic-gate { 900*7c478bd9Sstevel@tonic-gate SM_FILE_T *f; 901*7c478bd9Sstevel@tonic-gate long sff; 902*7c478bd9Sstevel@tonic-gate pid_t pid; 903*7c478bd9Sstevel@tonic-gate register char *p; 904*7c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 907*7c478bd9Sstevel@tonic-gate sm_dprintf("fileclass(%s, fmt=%s)\n", filename, fmt); 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate if (*filename == '\0') 910*7c478bd9Sstevel@tonic-gate { 911*7c478bd9Sstevel@tonic-gate syserr("fileclass: missing file name"); 912*7c478bd9Sstevel@tonic-gate return; 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate else if (ismap) 915*7c478bd9Sstevel@tonic-gate { 916*7c478bd9Sstevel@tonic-gate int status = 0; 917*7c478bd9Sstevel@tonic-gate char *key; 918*7c478bd9Sstevel@tonic-gate char *mn; 919*7c478bd9Sstevel@tonic-gate char *cl, *spec; 920*7c478bd9Sstevel@tonic-gate STAB *mapclass; 921*7c478bd9Sstevel@tonic-gate MAP map; 922*7c478bd9Sstevel@tonic-gate 923*7c478bd9Sstevel@tonic-gate mn = newstr(macname(class)); 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate key = filename; 926*7c478bd9Sstevel@tonic-gate 927*7c478bd9Sstevel@tonic-gate /* skip past key */ 928*7c478bd9Sstevel@tonic-gate if ((p = strchr(filename, '@')) == NULL) 929*7c478bd9Sstevel@tonic-gate { 930*7c478bd9Sstevel@tonic-gate /* should not happen */ 931*7c478bd9Sstevel@tonic-gate syserr("fileclass: bogus map specification"); 932*7c478bd9Sstevel@tonic-gate sm_free(mn); 933*7c478bd9Sstevel@tonic-gate return; 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate 936*7c478bd9Sstevel@tonic-gate /* skip past '@' */ 937*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 938*7c478bd9Sstevel@tonic-gate cl = p; 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate #if LDAPMAP 941*7c478bd9Sstevel@tonic-gate if (strcmp(cl, "LDAP") == 0) 942*7c478bd9Sstevel@tonic-gate { 943*7c478bd9Sstevel@tonic-gate int n; 944*7c478bd9Sstevel@tonic-gate char *lc; 945*7c478bd9Sstevel@tonic-gate char jbuf[MAXHOSTNAMELEN]; 946*7c478bd9Sstevel@tonic-gate char lcbuf[MAXLINE]; 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate /* Get $j */ 949*7c478bd9Sstevel@tonic-gate expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope); 950*7c478bd9Sstevel@tonic-gate if (jbuf[0] == '\0') 951*7c478bd9Sstevel@tonic-gate { 952*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(jbuf, "localhost", 953*7c478bd9Sstevel@tonic-gate sizeof jbuf); 954*7c478bd9Sstevel@tonic-gate } 955*7c478bd9Sstevel@tonic-gate 956*7c478bd9Sstevel@tonic-gate /* impose the default schema */ 957*7c478bd9Sstevel@tonic-gate lc = macvalue(macid("{sendmailMTACluster}"), CurEnv); 958*7c478bd9Sstevel@tonic-gate if (lc == NULL) 959*7c478bd9Sstevel@tonic-gate lc = ""; 960*7c478bd9Sstevel@tonic-gate else 961*7c478bd9Sstevel@tonic-gate { 962*7c478bd9Sstevel@tonic-gate expand(lc, lcbuf, sizeof lcbuf, CurEnv); 963*7c478bd9Sstevel@tonic-gate lc = lcbuf; 964*7c478bd9Sstevel@tonic-gate } 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate cl = "ldap"; 967*7c478bd9Sstevel@tonic-gate n = sm_snprintf(buf, sizeof buf, 968*7c478bd9Sstevel@tonic-gate "-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass", 969*7c478bd9Sstevel@tonic-gate mn, lc, jbuf); 970*7c478bd9Sstevel@tonic-gate if (n >= sizeof buf) 971*7c478bd9Sstevel@tonic-gate { 972*7c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: Default LDAP string too long", 973*7c478bd9Sstevel@tonic-gate mn); 974*7c478bd9Sstevel@tonic-gate sm_free(mn); 975*7c478bd9Sstevel@tonic-gate return; 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate spec = buf; 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate else 980*7c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 981*7c478bd9Sstevel@tonic-gate { 982*7c478bd9Sstevel@tonic-gate if ((spec = strchr(cl, ':')) == NULL) 983*7c478bd9Sstevel@tonic-gate { 984*7c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: missing map class", 985*7c478bd9Sstevel@tonic-gate mn); 986*7c478bd9Sstevel@tonic-gate sm_free(mn); 987*7c478bd9Sstevel@tonic-gate return; 988*7c478bd9Sstevel@tonic-gate } 989*7c478bd9Sstevel@tonic-gate *spec++ ='\0'; 990*7c478bd9Sstevel@tonic-gate } 991*7c478bd9Sstevel@tonic-gate 992*7c478bd9Sstevel@tonic-gate /* set up map structure */ 993*7c478bd9Sstevel@tonic-gate mapclass = stab(cl, ST_MAPCLASS, ST_FIND); 994*7c478bd9Sstevel@tonic-gate if (mapclass == NULL) 995*7c478bd9Sstevel@tonic-gate { 996*7c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: class %s not available", 997*7c478bd9Sstevel@tonic-gate mn, cl); 998*7c478bd9Sstevel@tonic-gate sm_free(mn); 999*7c478bd9Sstevel@tonic-gate return; 1000*7c478bd9Sstevel@tonic-gate } 1001*7c478bd9Sstevel@tonic-gate memset(&map, '\0', sizeof map); 1002*7c478bd9Sstevel@tonic-gate map.map_class = &mapclass->s_mapclass; 1003*7c478bd9Sstevel@tonic-gate map.map_mname = mn; 1004*7c478bd9Sstevel@tonic-gate map.map_mflags |= MF_FILECLASS; 1005*7c478bd9Sstevel@tonic-gate 1006*7c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 1007*7c478bd9Sstevel@tonic-gate sm_dprintf("fileclass: F{%s}: map class %s, key %s, spec %s\n", 1008*7c478bd9Sstevel@tonic-gate mn, cl, key, spec); 1009*7c478bd9Sstevel@tonic-gate 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate /* parse map spec */ 1012*7c478bd9Sstevel@tonic-gate if (!map.map_class->map_parse(&map, spec)) 1013*7c478bd9Sstevel@tonic-gate { 1014*7c478bd9Sstevel@tonic-gate /* map_parse() showed the error already */ 1015*7c478bd9Sstevel@tonic-gate sm_free(mn); 1016*7c478bd9Sstevel@tonic-gate return; 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate map.map_mflags |= MF_VALID; 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate /* open map */ 1021*7c478bd9Sstevel@tonic-gate if (map.map_class->map_open(&map, O_RDONLY)) 1022*7c478bd9Sstevel@tonic-gate { 1023*7c478bd9Sstevel@tonic-gate map.map_mflags |= MF_OPEN; 1024*7c478bd9Sstevel@tonic-gate map.map_pid = getpid(); 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate else 1027*7c478bd9Sstevel@tonic-gate { 1028*7c478bd9Sstevel@tonic-gate if (!optional && 1029*7c478bd9Sstevel@tonic-gate !bitset(MF_OPTIONAL, map.map_mflags)) 1030*7c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: map open failed", 1031*7c478bd9Sstevel@tonic-gate mn); 1032*7c478bd9Sstevel@tonic-gate sm_free(mn); 1033*7c478bd9Sstevel@tonic-gate return; 1034*7c478bd9Sstevel@tonic-gate } 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate /* lookup */ 1037*7c478bd9Sstevel@tonic-gate p = (*map.map_class->map_lookup)(&map, key, NULL, &status); 1038*7c478bd9Sstevel@tonic-gate if (status != EX_OK && status != EX_NOTFOUND) 1039*7c478bd9Sstevel@tonic-gate { 1040*7c478bd9Sstevel@tonic-gate if (!optional) 1041*7c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: map lookup failed", 1042*7c478bd9Sstevel@tonic-gate mn); 1043*7c478bd9Sstevel@tonic-gate p = NULL; 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate /* use the results */ 1047*7c478bd9Sstevel@tonic-gate if (p != NULL) 1048*7c478bd9Sstevel@tonic-gate parse_class_words(class, p); 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate /* close map */ 1051*7c478bd9Sstevel@tonic-gate map.map_mflags |= MF_CLOSING; 1052*7c478bd9Sstevel@tonic-gate map.map_class->map_close(&map); 1053*7c478bd9Sstevel@tonic-gate map.map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 1054*7c478bd9Sstevel@tonic-gate sm_free(mn); 1055*7c478bd9Sstevel@tonic-gate return; 1056*7c478bd9Sstevel@tonic-gate } 1057*7c478bd9Sstevel@tonic-gate else if (filename[0] == '|') 1058*7c478bd9Sstevel@tonic-gate { 1059*7c478bd9Sstevel@tonic-gate auto int fd; 1060*7c478bd9Sstevel@tonic-gate int i; 1061*7c478bd9Sstevel@tonic-gate char *argv[MAXPV + 1]; 1062*7c478bd9Sstevel@tonic-gate 1063*7c478bd9Sstevel@tonic-gate i = 0; 1064*7c478bd9Sstevel@tonic-gate for (p = strtok(&filename[1], " \t"); 1065*7c478bd9Sstevel@tonic-gate p != NULL && i < MAXPV; 1066*7c478bd9Sstevel@tonic-gate p = strtok(NULL, " \t")) 1067*7c478bd9Sstevel@tonic-gate argv[i++] = p; 1068*7c478bd9Sstevel@tonic-gate argv[i] = NULL; 1069*7c478bd9Sstevel@tonic-gate pid = prog_open(argv, &fd, CurEnv); 1070*7c478bd9Sstevel@tonic-gate if (pid < 0) 1071*7c478bd9Sstevel@tonic-gate f = NULL; 1072*7c478bd9Sstevel@tonic-gate else 1073*7c478bd9Sstevel@tonic-gate f = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 1074*7c478bd9Sstevel@tonic-gate (void *) &fd, SM_IO_RDONLY, NULL); 1075*7c478bd9Sstevel@tonic-gate } 1076*7c478bd9Sstevel@tonic-gate else 1077*7c478bd9Sstevel@tonic-gate { 1078*7c478bd9Sstevel@tonic-gate pid = -1; 1079*7c478bd9Sstevel@tonic-gate sff = SFF_REGONLY; 1080*7c478bd9Sstevel@tonic-gate if (!bitnset(DBS_CLASSFILEINUNSAFEDIRPATH, DontBlameSendmail)) 1081*7c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 1082*7c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDCLASSFILEINWRITABLEDIR, 1083*7c478bd9Sstevel@tonic-gate DontBlameSendmail)) 1084*7c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 1085*7c478bd9Sstevel@tonic-gate if (safe) 1086*7c478bd9Sstevel@tonic-gate sff |= SFF_OPENASROOT; 1087*7c478bd9Sstevel@tonic-gate else if (RealUid == 0) 1088*7c478bd9Sstevel@tonic-gate sff |= SFF_ROOTOK; 1089*7c478bd9Sstevel@tonic-gate if (DontLockReadFiles) 1090*7c478bd9Sstevel@tonic-gate sff |= SFF_NOLOCK; 1091*7c478bd9Sstevel@tonic-gate f = safefopen(filename, O_RDONLY, 0, sff); 1092*7c478bd9Sstevel@tonic-gate } 1093*7c478bd9Sstevel@tonic-gate if (f == NULL) 1094*7c478bd9Sstevel@tonic-gate { 1095*7c478bd9Sstevel@tonic-gate if (!optional) 1096*7c478bd9Sstevel@tonic-gate syserr("fileclass: cannot open '%s'", filename); 1097*7c478bd9Sstevel@tonic-gate return; 1098*7c478bd9Sstevel@tonic-gate } 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) 1101*7c478bd9Sstevel@tonic-gate { 1102*7c478bd9Sstevel@tonic-gate #if SCANF 1103*7c478bd9Sstevel@tonic-gate char wordbuf[MAXLINE + 1]; 1104*7c478bd9Sstevel@tonic-gate #endif /* SCANF */ 1105*7c478bd9Sstevel@tonic-gate 1106*7c478bd9Sstevel@tonic-gate if (buf[0] == '#') 1107*7c478bd9Sstevel@tonic-gate continue; 1108*7c478bd9Sstevel@tonic-gate #if SCANF 1109*7c478bd9Sstevel@tonic-gate if (sm_io_sscanf(buf, fmt, wordbuf) != 1) 1110*7c478bd9Sstevel@tonic-gate continue; 1111*7c478bd9Sstevel@tonic-gate p = wordbuf; 1112*7c478bd9Sstevel@tonic-gate #else /* SCANF */ 1113*7c478bd9Sstevel@tonic-gate p = buf; 1114*7c478bd9Sstevel@tonic-gate #endif /* SCANF */ 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate parse_class_words(class, p); 1117*7c478bd9Sstevel@tonic-gate 1118*7c478bd9Sstevel@tonic-gate /* 1119*7c478bd9Sstevel@tonic-gate ** If anything else is added here, 1120*7c478bd9Sstevel@tonic-gate ** check if the '@' map case above 1121*7c478bd9Sstevel@tonic-gate ** needs the code as well. 1122*7c478bd9Sstevel@tonic-gate */ 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate 1125*7c478bd9Sstevel@tonic-gate (void) sm_io_close(f, SM_TIME_DEFAULT); 1126*7c478bd9Sstevel@tonic-gate if (pid > 0) 1127*7c478bd9Sstevel@tonic-gate (void) waitfor(pid); 1128*7c478bd9Sstevel@tonic-gate } 1129*7c478bd9Sstevel@tonic-gate /* 1130*7c478bd9Sstevel@tonic-gate ** MAKEMAILER -- define a new mailer. 1131*7c478bd9Sstevel@tonic-gate ** 1132*7c478bd9Sstevel@tonic-gate ** Parameters: 1133*7c478bd9Sstevel@tonic-gate ** line -- description of mailer. This is in labeled 1134*7c478bd9Sstevel@tonic-gate ** fields. The fields are: 1135*7c478bd9Sstevel@tonic-gate ** A -- the argv for this mailer 1136*7c478bd9Sstevel@tonic-gate ** C -- the character set for MIME conversions 1137*7c478bd9Sstevel@tonic-gate ** D -- the directory to run in 1138*7c478bd9Sstevel@tonic-gate ** E -- the eol string 1139*7c478bd9Sstevel@tonic-gate ** F -- the flags associated with the mailer 1140*7c478bd9Sstevel@tonic-gate ** L -- the maximum line length 1141*7c478bd9Sstevel@tonic-gate ** M -- the maximum message size 1142*7c478bd9Sstevel@tonic-gate ** N -- the niceness at which to run 1143*7c478bd9Sstevel@tonic-gate ** P -- the path to the mailer 1144*7c478bd9Sstevel@tonic-gate ** Q -- the queue group for the mailer 1145*7c478bd9Sstevel@tonic-gate ** R -- the recipient rewriting set 1146*7c478bd9Sstevel@tonic-gate ** S -- the sender rewriting set 1147*7c478bd9Sstevel@tonic-gate ** T -- the mailer type (for DSNs) 1148*7c478bd9Sstevel@tonic-gate ** U -- the uid to run as 1149*7c478bd9Sstevel@tonic-gate ** W -- the time to wait at the end 1150*7c478bd9Sstevel@tonic-gate ** m -- maximum messages per connection 1151*7c478bd9Sstevel@tonic-gate ** r -- maximum number of recipients per message 1152*7c478bd9Sstevel@tonic-gate ** / -- new root directory 1153*7c478bd9Sstevel@tonic-gate ** The first word is the canonical name of the mailer. 1154*7c478bd9Sstevel@tonic-gate ** 1155*7c478bd9Sstevel@tonic-gate ** Returns: 1156*7c478bd9Sstevel@tonic-gate ** none. 1157*7c478bd9Sstevel@tonic-gate ** 1158*7c478bd9Sstevel@tonic-gate ** Side Effects: 1159*7c478bd9Sstevel@tonic-gate ** enters the mailer into the mailer table. 1160*7c478bd9Sstevel@tonic-gate */ 1161*7c478bd9Sstevel@tonic-gate 1162*7c478bd9Sstevel@tonic-gate void 1163*7c478bd9Sstevel@tonic-gate makemailer(line) 1164*7c478bd9Sstevel@tonic-gate char *line; 1165*7c478bd9Sstevel@tonic-gate { 1166*7c478bd9Sstevel@tonic-gate register char *p; 1167*7c478bd9Sstevel@tonic-gate register struct mailer *m; 1168*7c478bd9Sstevel@tonic-gate register STAB *s; 1169*7c478bd9Sstevel@tonic-gate int i; 1170*7c478bd9Sstevel@tonic-gate char fcode; 1171*7c478bd9Sstevel@tonic-gate auto char *endp; 1172*7c478bd9Sstevel@tonic-gate static int nextmailer = 0; /* "free" index into Mailer struct */ 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate /* allocate a mailer and set up defaults */ 1175*7c478bd9Sstevel@tonic-gate m = (struct mailer *) xalloc(sizeof *m); 1176*7c478bd9Sstevel@tonic-gate memset((char *) m, '\0', sizeof *m); 1177*7c478bd9Sstevel@tonic-gate errno = 0; /* avoid bogus error text */ 1178*7c478bd9Sstevel@tonic-gate 1179*7c478bd9Sstevel@tonic-gate /* collect the mailer name */ 1180*7c478bd9Sstevel@tonic-gate for (p = line; 1181*7c478bd9Sstevel@tonic-gate *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); 1182*7c478bd9Sstevel@tonic-gate p++) 1183*7c478bd9Sstevel@tonic-gate continue; 1184*7c478bd9Sstevel@tonic-gate if (*p != '\0') 1185*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1186*7c478bd9Sstevel@tonic-gate if (line[0] == '\0') 1187*7c478bd9Sstevel@tonic-gate { 1188*7c478bd9Sstevel@tonic-gate syserr("name required for mailer"); 1189*7c478bd9Sstevel@tonic-gate return; 1190*7c478bd9Sstevel@tonic-gate } 1191*7c478bd9Sstevel@tonic-gate m->m_name = newstr(line); 1192*7c478bd9Sstevel@tonic-gate m->m_qgrp = NOQGRP; 1193*7c478bd9Sstevel@tonic-gate m->m_uid = NO_UID; 1194*7c478bd9Sstevel@tonic-gate m->m_gid = NO_GID; 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate /* now scan through and assign info from the fields */ 1197*7c478bd9Sstevel@tonic-gate while (*p != '\0') 1198*7c478bd9Sstevel@tonic-gate { 1199*7c478bd9Sstevel@tonic-gate auto char *delimptr; 1200*7c478bd9Sstevel@tonic-gate 1201*7c478bd9Sstevel@tonic-gate while (*p != '\0' && 1202*7c478bd9Sstevel@tonic-gate (*p == ',' || (isascii(*p) && isspace(*p)))) 1203*7c478bd9Sstevel@tonic-gate p++; 1204*7c478bd9Sstevel@tonic-gate 1205*7c478bd9Sstevel@tonic-gate /* p now points to field code */ 1206*7c478bd9Sstevel@tonic-gate fcode = *p; 1207*7c478bd9Sstevel@tonic-gate while (*p != '\0' && *p != '=' && *p != ',') 1208*7c478bd9Sstevel@tonic-gate p++; 1209*7c478bd9Sstevel@tonic-gate if (*p++ != '=') 1210*7c478bd9Sstevel@tonic-gate { 1211*7c478bd9Sstevel@tonic-gate syserr("mailer %s: `=' expected", m->m_name); 1212*7c478bd9Sstevel@tonic-gate return; 1213*7c478bd9Sstevel@tonic-gate } 1214*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1215*7c478bd9Sstevel@tonic-gate p++; 1216*7c478bd9Sstevel@tonic-gate 1217*7c478bd9Sstevel@tonic-gate /* p now points to the field body */ 1218*7c478bd9Sstevel@tonic-gate p = munchstring(p, &delimptr, ','); 1219*7c478bd9Sstevel@tonic-gate 1220*7c478bd9Sstevel@tonic-gate /* install the field into the mailer struct */ 1221*7c478bd9Sstevel@tonic-gate switch (fcode) 1222*7c478bd9Sstevel@tonic-gate { 1223*7c478bd9Sstevel@tonic-gate case 'P': /* pathname */ 1224*7c478bd9Sstevel@tonic-gate if (*p != '\0') /* error is issued below */ 1225*7c478bd9Sstevel@tonic-gate m->m_mailer = newstr(p); 1226*7c478bd9Sstevel@tonic-gate break; 1227*7c478bd9Sstevel@tonic-gate 1228*7c478bd9Sstevel@tonic-gate case 'F': /* flags */ 1229*7c478bd9Sstevel@tonic-gate for (; *p != '\0'; p++) 1230*7c478bd9Sstevel@tonic-gate { 1231*7c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isspace(*p))) 1232*7c478bd9Sstevel@tonic-gate { 1233*7c478bd9Sstevel@tonic-gate #if _FFR_DEPRECATE_MAILER_FLAG_I 1234*7c478bd9Sstevel@tonic-gate if (*p == M_INTERNAL) 1235*7c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, NOQID, 1236*7c478bd9Sstevel@tonic-gate "WARNING: mailer=%s, flag=%c deprecated", 1237*7c478bd9Sstevel@tonic-gate m->m_name, *p); 1238*7c478bd9Sstevel@tonic-gate #endif /* _FFR_DEPRECATE_MAILER_FLAG_I */ 1239*7c478bd9Sstevel@tonic-gate setbitn(bitidx(*p), m->m_flags); 1240*7c478bd9Sstevel@tonic-gate } 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate break; 1243*7c478bd9Sstevel@tonic-gate 1244*7c478bd9Sstevel@tonic-gate case 'S': /* sender rewriting ruleset */ 1245*7c478bd9Sstevel@tonic-gate case 'R': /* recipient rewriting ruleset */ 1246*7c478bd9Sstevel@tonic-gate i = strtorwset(p, &endp, ST_ENTER); 1247*7c478bd9Sstevel@tonic-gate if (i < 0) 1248*7c478bd9Sstevel@tonic-gate return; 1249*7c478bd9Sstevel@tonic-gate if (fcode == 'S') 1250*7c478bd9Sstevel@tonic-gate m->m_sh_rwset = m->m_se_rwset = i; 1251*7c478bd9Sstevel@tonic-gate else 1252*7c478bd9Sstevel@tonic-gate m->m_rh_rwset = m->m_re_rwset = i; 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate p = endp; 1255*7c478bd9Sstevel@tonic-gate if (*p++ == '/') 1256*7c478bd9Sstevel@tonic-gate { 1257*7c478bd9Sstevel@tonic-gate i = strtorwset(p, NULL, ST_ENTER); 1258*7c478bd9Sstevel@tonic-gate if (i < 0) 1259*7c478bd9Sstevel@tonic-gate return; 1260*7c478bd9Sstevel@tonic-gate if (fcode == 'S') 1261*7c478bd9Sstevel@tonic-gate m->m_sh_rwset = i; 1262*7c478bd9Sstevel@tonic-gate else 1263*7c478bd9Sstevel@tonic-gate m->m_rh_rwset = i; 1264*7c478bd9Sstevel@tonic-gate } 1265*7c478bd9Sstevel@tonic-gate break; 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate case 'E': /* end of line string */ 1268*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1269*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null end-of-line string", 1270*7c478bd9Sstevel@tonic-gate m->m_name); 1271*7c478bd9Sstevel@tonic-gate else 1272*7c478bd9Sstevel@tonic-gate m->m_eol = newstr(p); 1273*7c478bd9Sstevel@tonic-gate break; 1274*7c478bd9Sstevel@tonic-gate 1275*7c478bd9Sstevel@tonic-gate case 'A': /* argument vector */ 1276*7c478bd9Sstevel@tonic-gate if (*p != '\0') /* error is issued below */ 1277*7c478bd9Sstevel@tonic-gate m->m_argv = makeargv(p); 1278*7c478bd9Sstevel@tonic-gate break; 1279*7c478bd9Sstevel@tonic-gate 1280*7c478bd9Sstevel@tonic-gate case 'M': /* maximum message size */ 1281*7c478bd9Sstevel@tonic-gate m->m_maxsize = atol(p); 1282*7c478bd9Sstevel@tonic-gate break; 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate case 'm': /* maximum messages per connection */ 1285*7c478bd9Sstevel@tonic-gate m->m_maxdeliveries = atoi(p); 1286*7c478bd9Sstevel@tonic-gate break; 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate case 'r': /* max recipient per envelope */ 1289*7c478bd9Sstevel@tonic-gate m->m_maxrcpt = atoi(p); 1290*7c478bd9Sstevel@tonic-gate break; 1291*7c478bd9Sstevel@tonic-gate 1292*7c478bd9Sstevel@tonic-gate case 'L': /* maximum line length */ 1293*7c478bd9Sstevel@tonic-gate m->m_linelimit = atoi(p); 1294*7c478bd9Sstevel@tonic-gate if (m->m_linelimit < 0) 1295*7c478bd9Sstevel@tonic-gate m->m_linelimit = 0; 1296*7c478bd9Sstevel@tonic-gate break; 1297*7c478bd9Sstevel@tonic-gate 1298*7c478bd9Sstevel@tonic-gate case 'N': /* run niceness */ 1299*7c478bd9Sstevel@tonic-gate m->m_nice = atoi(p); 1300*7c478bd9Sstevel@tonic-gate break; 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate case 'D': /* working directory */ 1303*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1304*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null working directory", 1305*7c478bd9Sstevel@tonic-gate m->m_name); 1306*7c478bd9Sstevel@tonic-gate else 1307*7c478bd9Sstevel@tonic-gate m->m_execdir = newstr(p); 1308*7c478bd9Sstevel@tonic-gate break; 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate case 'C': /* default charset */ 1311*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1312*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null charset", m->m_name); 1313*7c478bd9Sstevel@tonic-gate else 1314*7c478bd9Sstevel@tonic-gate m->m_defcharset = newstr(p); 1315*7c478bd9Sstevel@tonic-gate break; 1316*7c478bd9Sstevel@tonic-gate 1317*7c478bd9Sstevel@tonic-gate case 'Q': /* queue for this mailer */ 1318*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1319*7c478bd9Sstevel@tonic-gate { 1320*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null queue", m->m_name); 1321*7c478bd9Sstevel@tonic-gate break; 1322*7c478bd9Sstevel@tonic-gate } 1323*7c478bd9Sstevel@tonic-gate s = stab(p, ST_QUEUE, ST_FIND); 1324*7c478bd9Sstevel@tonic-gate if (s == NULL) 1325*7c478bd9Sstevel@tonic-gate syserr("mailer %s: unknown queue %s", 1326*7c478bd9Sstevel@tonic-gate m->m_name, p); 1327*7c478bd9Sstevel@tonic-gate else 1328*7c478bd9Sstevel@tonic-gate m->m_qgrp = s->s_quegrp->qg_index; 1329*7c478bd9Sstevel@tonic-gate break; 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate case 'T': /* MTA-Name/Address/Diagnostic types */ 1332*7c478bd9Sstevel@tonic-gate /* extract MTA name type; default to "dns" */ 1333*7c478bd9Sstevel@tonic-gate m->m_mtatype = newstr(p); 1334*7c478bd9Sstevel@tonic-gate p = strchr(m->m_mtatype, '/'); 1335*7c478bd9Sstevel@tonic-gate if (p != NULL) 1336*7c478bd9Sstevel@tonic-gate { 1337*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1338*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1339*7c478bd9Sstevel@tonic-gate p = NULL; 1340*7c478bd9Sstevel@tonic-gate } 1341*7c478bd9Sstevel@tonic-gate if (*m->m_mtatype == '\0') 1342*7c478bd9Sstevel@tonic-gate m->m_mtatype = "dns"; 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate /* extract address type; default to "rfc822" */ 1345*7c478bd9Sstevel@tonic-gate m->m_addrtype = p; 1346*7c478bd9Sstevel@tonic-gate if (p != NULL) 1347*7c478bd9Sstevel@tonic-gate p = strchr(p, '/'); 1348*7c478bd9Sstevel@tonic-gate if (p != NULL) 1349*7c478bd9Sstevel@tonic-gate { 1350*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1351*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1352*7c478bd9Sstevel@tonic-gate p = NULL; 1353*7c478bd9Sstevel@tonic-gate } 1354*7c478bd9Sstevel@tonic-gate if (m->m_addrtype == NULL || *m->m_addrtype == '\0') 1355*7c478bd9Sstevel@tonic-gate m->m_addrtype = "rfc822"; 1356*7c478bd9Sstevel@tonic-gate 1357*7c478bd9Sstevel@tonic-gate /* extract diagnostic type; default to "smtp" */ 1358*7c478bd9Sstevel@tonic-gate m->m_diagtype = p; 1359*7c478bd9Sstevel@tonic-gate if (m->m_diagtype == NULL || *m->m_diagtype == '\0') 1360*7c478bd9Sstevel@tonic-gate m->m_diagtype = "smtp"; 1361*7c478bd9Sstevel@tonic-gate break; 1362*7c478bd9Sstevel@tonic-gate 1363*7c478bd9Sstevel@tonic-gate case 'U': /* user id */ 1364*7c478bd9Sstevel@tonic-gate if (isascii(*p) && !isdigit(*p)) 1365*7c478bd9Sstevel@tonic-gate { 1366*7c478bd9Sstevel@tonic-gate char *q = p; 1367*7c478bd9Sstevel@tonic-gate struct passwd *pw; 1368*7c478bd9Sstevel@tonic-gate 1369*7c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && 1370*7c478bd9Sstevel@tonic-gate (isalnum(*p) || strchr("-_", *p) != NULL)) 1371*7c478bd9Sstevel@tonic-gate p++; 1372*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1373*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1374*7c478bd9Sstevel@tonic-gate if (*p != '\0') 1375*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1376*7c478bd9Sstevel@tonic-gate if (*q == '\0') 1377*7c478bd9Sstevel@tonic-gate { 1378*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null user name", 1379*7c478bd9Sstevel@tonic-gate m->m_name); 1380*7c478bd9Sstevel@tonic-gate break; 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate pw = sm_getpwnam(q); 1383*7c478bd9Sstevel@tonic-gate if (pw == NULL) 1384*7c478bd9Sstevel@tonic-gate { 1385*7c478bd9Sstevel@tonic-gate syserr("readcf: mailer U= flag: unknown user %s", q); 1386*7c478bd9Sstevel@tonic-gate break; 1387*7c478bd9Sstevel@tonic-gate } 1388*7c478bd9Sstevel@tonic-gate else 1389*7c478bd9Sstevel@tonic-gate { 1390*7c478bd9Sstevel@tonic-gate m->m_uid = pw->pw_uid; 1391*7c478bd9Sstevel@tonic-gate m->m_gid = pw->pw_gid; 1392*7c478bd9Sstevel@tonic-gate } 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate else 1395*7c478bd9Sstevel@tonic-gate { 1396*7c478bd9Sstevel@tonic-gate auto char *q; 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate m->m_uid = strtol(p, &q, 0); 1399*7c478bd9Sstevel@tonic-gate p = q; 1400*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1401*7c478bd9Sstevel@tonic-gate p++; 1402*7c478bd9Sstevel@tonic-gate if (*p != '\0') 1403*7c478bd9Sstevel@tonic-gate p++; 1404*7c478bd9Sstevel@tonic-gate } 1405*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1406*7c478bd9Sstevel@tonic-gate p++; 1407*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1408*7c478bd9Sstevel@tonic-gate break; 1409*7c478bd9Sstevel@tonic-gate if (isascii(*p) && !isdigit(*p)) 1410*7c478bd9Sstevel@tonic-gate { 1411*7c478bd9Sstevel@tonic-gate char *q = p; 1412*7c478bd9Sstevel@tonic-gate struct group *gr; 1413*7c478bd9Sstevel@tonic-gate 1414*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 1415*7c478bd9Sstevel@tonic-gate p++; 1416*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1417*7c478bd9Sstevel@tonic-gate if (*q == '\0') 1418*7c478bd9Sstevel@tonic-gate { 1419*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null group name", 1420*7c478bd9Sstevel@tonic-gate m->m_name); 1421*7c478bd9Sstevel@tonic-gate break; 1422*7c478bd9Sstevel@tonic-gate } 1423*7c478bd9Sstevel@tonic-gate gr = getgrnam(q); 1424*7c478bd9Sstevel@tonic-gate if (gr == NULL) 1425*7c478bd9Sstevel@tonic-gate { 1426*7c478bd9Sstevel@tonic-gate syserr("readcf: mailer U= flag: unknown group %s", q); 1427*7c478bd9Sstevel@tonic-gate break; 1428*7c478bd9Sstevel@tonic-gate } 1429*7c478bd9Sstevel@tonic-gate else 1430*7c478bd9Sstevel@tonic-gate m->m_gid = gr->gr_gid; 1431*7c478bd9Sstevel@tonic-gate } 1432*7c478bd9Sstevel@tonic-gate else 1433*7c478bd9Sstevel@tonic-gate { 1434*7c478bd9Sstevel@tonic-gate m->m_gid = strtol(p, NULL, 0); 1435*7c478bd9Sstevel@tonic-gate } 1436*7c478bd9Sstevel@tonic-gate break; 1437*7c478bd9Sstevel@tonic-gate 1438*7c478bd9Sstevel@tonic-gate case 'W': /* wait timeout */ 1439*7c478bd9Sstevel@tonic-gate m->m_wait = convtime(p, 's'); 1440*7c478bd9Sstevel@tonic-gate break; 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate case '/': /* new root directory */ 1443*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1444*7c478bd9Sstevel@tonic-gate syserr("mailer %s: null root directory", 1445*7c478bd9Sstevel@tonic-gate m->m_name); 1446*7c478bd9Sstevel@tonic-gate else 1447*7c478bd9Sstevel@tonic-gate m->m_rootdir = newstr(p); 1448*7c478bd9Sstevel@tonic-gate break; 1449*7c478bd9Sstevel@tonic-gate 1450*7c478bd9Sstevel@tonic-gate default: 1451*7c478bd9Sstevel@tonic-gate syserr("M%s: unknown mailer equate %c=", 1452*7c478bd9Sstevel@tonic-gate m->m_name, fcode); 1453*7c478bd9Sstevel@tonic-gate break; 1454*7c478bd9Sstevel@tonic-gate } 1455*7c478bd9Sstevel@tonic-gate 1456*7c478bd9Sstevel@tonic-gate p = delimptr; 1457*7c478bd9Sstevel@tonic-gate } 1458*7c478bd9Sstevel@tonic-gate 1459*7c478bd9Sstevel@tonic-gate #if !HASRRESVPORT 1460*7c478bd9Sstevel@tonic-gate if (bitnset(M_SECURE_PORT, m->m_flags)) 1461*7c478bd9Sstevel@tonic-gate { 1462*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 1463*7c478bd9Sstevel@tonic-gate "M%s: Warning: F=%c set on system that doesn't support rresvport()\n", 1464*7c478bd9Sstevel@tonic-gate m->m_name, M_SECURE_PORT); 1465*7c478bd9Sstevel@tonic-gate } 1466*7c478bd9Sstevel@tonic-gate #endif /* !HASRRESVPORT */ 1467*7c478bd9Sstevel@tonic-gate 1468*7c478bd9Sstevel@tonic-gate #if !HASNICE 1469*7c478bd9Sstevel@tonic-gate if (m->m_nice != 0) 1470*7c478bd9Sstevel@tonic-gate { 1471*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 1472*7c478bd9Sstevel@tonic-gate "M%s: Warning: N= set on system that doesn't support nice()\n", 1473*7c478bd9Sstevel@tonic-gate m->m_name); 1474*7c478bd9Sstevel@tonic-gate } 1475*7c478bd9Sstevel@tonic-gate #endif /* !HASNICE */ 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate /* do some rationality checking */ 1478*7c478bd9Sstevel@tonic-gate if (m->m_argv == NULL) 1479*7c478bd9Sstevel@tonic-gate { 1480*7c478bd9Sstevel@tonic-gate syserr("M%s: A= argument required", m->m_name); 1481*7c478bd9Sstevel@tonic-gate return; 1482*7c478bd9Sstevel@tonic-gate } 1483*7c478bd9Sstevel@tonic-gate if (m->m_mailer == NULL) 1484*7c478bd9Sstevel@tonic-gate { 1485*7c478bd9Sstevel@tonic-gate syserr("M%s: P= argument required", m->m_name); 1486*7c478bd9Sstevel@tonic-gate return; 1487*7c478bd9Sstevel@tonic-gate } 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate if (nextmailer >= MAXMAILERS) 1490*7c478bd9Sstevel@tonic-gate { 1491*7c478bd9Sstevel@tonic-gate syserr("too many mailers defined (%d max)", MAXMAILERS); 1492*7c478bd9Sstevel@tonic-gate return; 1493*7c478bd9Sstevel@tonic-gate } 1494*7c478bd9Sstevel@tonic-gate 1495*7c478bd9Sstevel@tonic-gate if (m->m_maxrcpt <= 0) 1496*7c478bd9Sstevel@tonic-gate m->m_maxrcpt = DEFAULT_MAX_RCPT; 1497*7c478bd9Sstevel@tonic-gate 1498*7c478bd9Sstevel@tonic-gate /* do some heuristic cleanup for back compatibility */ 1499*7c478bd9Sstevel@tonic-gate if (bitnset(M_LIMITS, m->m_flags)) 1500*7c478bd9Sstevel@tonic-gate { 1501*7c478bd9Sstevel@tonic-gate if (m->m_linelimit == 0) 1502*7c478bd9Sstevel@tonic-gate m->m_linelimit = SMTPLINELIM; 1503*7c478bd9Sstevel@tonic-gate if (ConfigLevel < 2) 1504*7c478bd9Sstevel@tonic-gate setbitn(M_7BITS, m->m_flags); 1505*7c478bd9Sstevel@tonic-gate } 1506*7c478bd9Sstevel@tonic-gate 1507*7c478bd9Sstevel@tonic-gate if (strcmp(m->m_mailer, "[TCP]") == 0) 1508*7c478bd9Sstevel@tonic-gate { 1509*7c478bd9Sstevel@tonic-gate syserr("M%s: P=[TCP] must be replaced by P=[IPC]", m->m_name); 1510*7c478bd9Sstevel@tonic-gate return; 1511*7c478bd9Sstevel@tonic-gate } 1512*7c478bd9Sstevel@tonic-gate 1513*7c478bd9Sstevel@tonic-gate if (strcmp(m->m_mailer, "[IPC]") == 0) 1514*7c478bd9Sstevel@tonic-gate { 1515*7c478bd9Sstevel@tonic-gate /* Use the second argument for host or path to socket */ 1516*7c478bd9Sstevel@tonic-gate if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 1517*7c478bd9Sstevel@tonic-gate m->m_argv[1][0] == '\0') 1518*7c478bd9Sstevel@tonic-gate { 1519*7c478bd9Sstevel@tonic-gate syserr("M%s: too few parameters for %s mailer", 1520*7c478bd9Sstevel@tonic-gate m->m_name, m->m_mailer); 1521*7c478bd9Sstevel@tonic-gate return; 1522*7c478bd9Sstevel@tonic-gate } 1523*7c478bd9Sstevel@tonic-gate if (strcmp(m->m_argv[0], "TCP") != 0 1524*7c478bd9Sstevel@tonic-gate #if NETUNIX 1525*7c478bd9Sstevel@tonic-gate && strcmp(m->m_argv[0], "FILE") != 0 1526*7c478bd9Sstevel@tonic-gate #endif /* NETUNIX */ 1527*7c478bd9Sstevel@tonic-gate ) 1528*7c478bd9Sstevel@tonic-gate { 1529*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 1530*7c478bd9Sstevel@tonic-gate "M%s: Warning: first argument in %s mailer must be %s\n", 1531*7c478bd9Sstevel@tonic-gate m->m_name, m->m_mailer, 1532*7c478bd9Sstevel@tonic-gate #if NETUNIX 1533*7c478bd9Sstevel@tonic-gate "TCP or FILE" 1534*7c478bd9Sstevel@tonic-gate #else /* NETUNIX */ 1535*7c478bd9Sstevel@tonic-gate "TCP" 1536*7c478bd9Sstevel@tonic-gate #endif /* NETUNIX */ 1537*7c478bd9Sstevel@tonic-gate ); 1538*7c478bd9Sstevel@tonic-gate } 1539*7c478bd9Sstevel@tonic-gate if (m->m_mtatype == NULL) 1540*7c478bd9Sstevel@tonic-gate m->m_mtatype = "dns"; 1541*7c478bd9Sstevel@tonic-gate if (m->m_addrtype == NULL) 1542*7c478bd9Sstevel@tonic-gate m->m_addrtype = "rfc822"; 1543*7c478bd9Sstevel@tonic-gate if (m->m_diagtype == NULL) 1544*7c478bd9Sstevel@tonic-gate { 1545*7c478bd9Sstevel@tonic-gate if (m->m_argv[0] != NULL && 1546*7c478bd9Sstevel@tonic-gate strcmp(m->m_argv[0], "FILE") == 0) 1547*7c478bd9Sstevel@tonic-gate m->m_diagtype = "x-unix"; 1548*7c478bd9Sstevel@tonic-gate else 1549*7c478bd9Sstevel@tonic-gate m->m_diagtype = "smtp"; 1550*7c478bd9Sstevel@tonic-gate } 1551*7c478bd9Sstevel@tonic-gate } 1552*7c478bd9Sstevel@tonic-gate else if (strcmp(m->m_mailer, "[FILE]") == 0) 1553*7c478bd9Sstevel@tonic-gate { 1554*7c478bd9Sstevel@tonic-gate /* Use the second argument for filename */ 1555*7c478bd9Sstevel@tonic-gate if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 1556*7c478bd9Sstevel@tonic-gate m->m_argv[2] != NULL) 1557*7c478bd9Sstevel@tonic-gate { 1558*7c478bd9Sstevel@tonic-gate syserr("M%s: too %s parameters for [FILE] mailer", 1559*7c478bd9Sstevel@tonic-gate m->m_name, 1560*7c478bd9Sstevel@tonic-gate (m->m_argv[0] == NULL || 1561*7c478bd9Sstevel@tonic-gate m->m_argv[1] == NULL) ? "few" : "many"); 1562*7c478bd9Sstevel@tonic-gate return; 1563*7c478bd9Sstevel@tonic-gate } 1564*7c478bd9Sstevel@tonic-gate else if (strcmp(m->m_argv[0], "FILE") != 0) 1565*7c478bd9Sstevel@tonic-gate { 1566*7c478bd9Sstevel@tonic-gate syserr("M%s: first argument in [FILE] mailer must be FILE", 1567*7c478bd9Sstevel@tonic-gate m->m_name); 1568*7c478bd9Sstevel@tonic-gate return; 1569*7c478bd9Sstevel@tonic-gate } 1570*7c478bd9Sstevel@tonic-gate } 1571*7c478bd9Sstevel@tonic-gate 1572*7c478bd9Sstevel@tonic-gate if (m->m_eol == NULL) 1573*7c478bd9Sstevel@tonic-gate { 1574*7c478bd9Sstevel@tonic-gate char **pp; 1575*7c478bd9Sstevel@tonic-gate 1576*7c478bd9Sstevel@tonic-gate /* default for SMTP is \r\n; use \n for local delivery */ 1577*7c478bd9Sstevel@tonic-gate for (pp = m->m_argv; *pp != NULL; pp++) 1578*7c478bd9Sstevel@tonic-gate { 1579*7c478bd9Sstevel@tonic-gate for (p = *pp; *p != '\0'; ) 1580*7c478bd9Sstevel@tonic-gate { 1581*7c478bd9Sstevel@tonic-gate if ((*p++ & 0377) == MACROEXPAND && *p == 'u') 1582*7c478bd9Sstevel@tonic-gate break; 1583*7c478bd9Sstevel@tonic-gate } 1584*7c478bd9Sstevel@tonic-gate if (*p != '\0') 1585*7c478bd9Sstevel@tonic-gate break; 1586*7c478bd9Sstevel@tonic-gate } 1587*7c478bd9Sstevel@tonic-gate if (*pp == NULL) 1588*7c478bd9Sstevel@tonic-gate m->m_eol = "\r\n"; 1589*7c478bd9Sstevel@tonic-gate else 1590*7c478bd9Sstevel@tonic-gate m->m_eol = "\n"; 1591*7c478bd9Sstevel@tonic-gate } 1592*7c478bd9Sstevel@tonic-gate 1593*7c478bd9Sstevel@tonic-gate /* enter the mailer into the symbol table */ 1594*7c478bd9Sstevel@tonic-gate s = stab(m->m_name, ST_MAILER, ST_ENTER); 1595*7c478bd9Sstevel@tonic-gate if (s->s_mailer != NULL) 1596*7c478bd9Sstevel@tonic-gate { 1597*7c478bd9Sstevel@tonic-gate i = s->s_mailer->m_mno; 1598*7c478bd9Sstevel@tonic-gate sm_free(s->s_mailer); /* XXX */ 1599*7c478bd9Sstevel@tonic-gate } 1600*7c478bd9Sstevel@tonic-gate else 1601*7c478bd9Sstevel@tonic-gate { 1602*7c478bd9Sstevel@tonic-gate i = nextmailer++; 1603*7c478bd9Sstevel@tonic-gate } 1604*7c478bd9Sstevel@tonic-gate Mailer[i] = s->s_mailer = m; 1605*7c478bd9Sstevel@tonic-gate m->m_mno = i; 1606*7c478bd9Sstevel@tonic-gate } 1607*7c478bd9Sstevel@tonic-gate /* 1608*7c478bd9Sstevel@tonic-gate ** MUNCHSTRING -- translate a string into internal form. 1609*7c478bd9Sstevel@tonic-gate ** 1610*7c478bd9Sstevel@tonic-gate ** Parameters: 1611*7c478bd9Sstevel@tonic-gate ** p -- the string to munch. 1612*7c478bd9Sstevel@tonic-gate ** delimptr -- if non-NULL, set to the pointer of the 1613*7c478bd9Sstevel@tonic-gate ** field delimiter character. 1614*7c478bd9Sstevel@tonic-gate ** delim -- the delimiter for the field. 1615*7c478bd9Sstevel@tonic-gate ** 1616*7c478bd9Sstevel@tonic-gate ** Returns: 1617*7c478bd9Sstevel@tonic-gate ** the munched string. 1618*7c478bd9Sstevel@tonic-gate ** 1619*7c478bd9Sstevel@tonic-gate ** Side Effects: 1620*7c478bd9Sstevel@tonic-gate ** the munched string is a local static buffer. 1621*7c478bd9Sstevel@tonic-gate ** it must be copied before the function is called again. 1622*7c478bd9Sstevel@tonic-gate */ 1623*7c478bd9Sstevel@tonic-gate 1624*7c478bd9Sstevel@tonic-gate char * 1625*7c478bd9Sstevel@tonic-gate munchstring(p, delimptr, delim) 1626*7c478bd9Sstevel@tonic-gate register char *p; 1627*7c478bd9Sstevel@tonic-gate char **delimptr; 1628*7c478bd9Sstevel@tonic-gate int delim; 1629*7c478bd9Sstevel@tonic-gate { 1630*7c478bd9Sstevel@tonic-gate register char *q; 1631*7c478bd9Sstevel@tonic-gate bool backslash = false; 1632*7c478bd9Sstevel@tonic-gate bool quotemode = false; 1633*7c478bd9Sstevel@tonic-gate static char buf[MAXLINE]; 1634*7c478bd9Sstevel@tonic-gate 1635*7c478bd9Sstevel@tonic-gate for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++) 1636*7c478bd9Sstevel@tonic-gate { 1637*7c478bd9Sstevel@tonic-gate if (backslash) 1638*7c478bd9Sstevel@tonic-gate { 1639*7c478bd9Sstevel@tonic-gate /* everything is roughly literal */ 1640*7c478bd9Sstevel@tonic-gate backslash = false; 1641*7c478bd9Sstevel@tonic-gate switch (*p) 1642*7c478bd9Sstevel@tonic-gate { 1643*7c478bd9Sstevel@tonic-gate case 'r': /* carriage return */ 1644*7c478bd9Sstevel@tonic-gate *q++ = '\r'; 1645*7c478bd9Sstevel@tonic-gate continue; 1646*7c478bd9Sstevel@tonic-gate 1647*7c478bd9Sstevel@tonic-gate case 'n': /* newline */ 1648*7c478bd9Sstevel@tonic-gate *q++ = '\n'; 1649*7c478bd9Sstevel@tonic-gate continue; 1650*7c478bd9Sstevel@tonic-gate 1651*7c478bd9Sstevel@tonic-gate case 'f': /* form feed */ 1652*7c478bd9Sstevel@tonic-gate *q++ = '\f'; 1653*7c478bd9Sstevel@tonic-gate continue; 1654*7c478bd9Sstevel@tonic-gate 1655*7c478bd9Sstevel@tonic-gate case 'b': /* backspace */ 1656*7c478bd9Sstevel@tonic-gate *q++ = '\b'; 1657*7c478bd9Sstevel@tonic-gate continue; 1658*7c478bd9Sstevel@tonic-gate } 1659*7c478bd9Sstevel@tonic-gate *q++ = *p; 1660*7c478bd9Sstevel@tonic-gate } 1661*7c478bd9Sstevel@tonic-gate else 1662*7c478bd9Sstevel@tonic-gate { 1663*7c478bd9Sstevel@tonic-gate if (*p == '\\') 1664*7c478bd9Sstevel@tonic-gate backslash = true; 1665*7c478bd9Sstevel@tonic-gate else if (*p == '"') 1666*7c478bd9Sstevel@tonic-gate quotemode = !quotemode; 1667*7c478bd9Sstevel@tonic-gate else if (quotemode || *p != delim) 1668*7c478bd9Sstevel@tonic-gate *q++ = *p; 1669*7c478bd9Sstevel@tonic-gate else 1670*7c478bd9Sstevel@tonic-gate break; 1671*7c478bd9Sstevel@tonic-gate } 1672*7c478bd9Sstevel@tonic-gate } 1673*7c478bd9Sstevel@tonic-gate 1674*7c478bd9Sstevel@tonic-gate if (delimptr != NULL) 1675*7c478bd9Sstevel@tonic-gate *delimptr = p; 1676*7c478bd9Sstevel@tonic-gate *q++ = '\0'; 1677*7c478bd9Sstevel@tonic-gate return buf; 1678*7c478bd9Sstevel@tonic-gate } 1679*7c478bd9Sstevel@tonic-gate /* 1680*7c478bd9Sstevel@tonic-gate ** EXTRQUOTSTR -- extract a (quoted) string. 1681*7c478bd9Sstevel@tonic-gate ** 1682*7c478bd9Sstevel@tonic-gate ** This routine deals with quoted (") strings and escaped 1683*7c478bd9Sstevel@tonic-gate ** spaces (\\ ). 1684*7c478bd9Sstevel@tonic-gate ** 1685*7c478bd9Sstevel@tonic-gate ** Parameters: 1686*7c478bd9Sstevel@tonic-gate ** p -- source string. 1687*7c478bd9Sstevel@tonic-gate ** delimptr -- if non-NULL, set to the pointer of the 1688*7c478bd9Sstevel@tonic-gate ** field delimiter character. 1689*7c478bd9Sstevel@tonic-gate ** delimbuf -- delimiters for the field. 1690*7c478bd9Sstevel@tonic-gate ** st -- if non-NULL, store the return value (whether the 1691*7c478bd9Sstevel@tonic-gate ** string was correctly quoted) here. 1692*7c478bd9Sstevel@tonic-gate ** 1693*7c478bd9Sstevel@tonic-gate ** Returns: 1694*7c478bd9Sstevel@tonic-gate ** the extracted string. 1695*7c478bd9Sstevel@tonic-gate ** 1696*7c478bd9Sstevel@tonic-gate ** Side Effects: 1697*7c478bd9Sstevel@tonic-gate ** the returned string is a local static buffer. 1698*7c478bd9Sstevel@tonic-gate ** it must be copied before the function is called again. 1699*7c478bd9Sstevel@tonic-gate */ 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate static char * 1702*7c478bd9Sstevel@tonic-gate extrquotstr(p, delimptr, delimbuf, st) 1703*7c478bd9Sstevel@tonic-gate register char *p; 1704*7c478bd9Sstevel@tonic-gate char **delimptr; 1705*7c478bd9Sstevel@tonic-gate char *delimbuf; 1706*7c478bd9Sstevel@tonic-gate bool *st; 1707*7c478bd9Sstevel@tonic-gate { 1708*7c478bd9Sstevel@tonic-gate register char *q; 1709*7c478bd9Sstevel@tonic-gate bool backslash = false; 1710*7c478bd9Sstevel@tonic-gate bool quotemode = false; 1711*7c478bd9Sstevel@tonic-gate static char buf[MAXLINE]; 1712*7c478bd9Sstevel@tonic-gate 1713*7c478bd9Sstevel@tonic-gate for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++) 1714*7c478bd9Sstevel@tonic-gate { 1715*7c478bd9Sstevel@tonic-gate if (backslash) 1716*7c478bd9Sstevel@tonic-gate { 1717*7c478bd9Sstevel@tonic-gate backslash = false; 1718*7c478bd9Sstevel@tonic-gate if (*p != ' ') 1719*7c478bd9Sstevel@tonic-gate *q++ = '\\'; 1720*7c478bd9Sstevel@tonic-gate } 1721*7c478bd9Sstevel@tonic-gate if (*p == '\\') 1722*7c478bd9Sstevel@tonic-gate backslash = true; 1723*7c478bd9Sstevel@tonic-gate else if (*p == '"') 1724*7c478bd9Sstevel@tonic-gate quotemode = !quotemode; 1725*7c478bd9Sstevel@tonic-gate else if (quotemode || 1726*7c478bd9Sstevel@tonic-gate strchr(delimbuf, (int) *p) == NULL) 1727*7c478bd9Sstevel@tonic-gate *q++ = *p; 1728*7c478bd9Sstevel@tonic-gate else 1729*7c478bd9Sstevel@tonic-gate break; 1730*7c478bd9Sstevel@tonic-gate } 1731*7c478bd9Sstevel@tonic-gate 1732*7c478bd9Sstevel@tonic-gate if (delimptr != NULL) 1733*7c478bd9Sstevel@tonic-gate *delimptr = p; 1734*7c478bd9Sstevel@tonic-gate *q++ = '\0'; 1735*7c478bd9Sstevel@tonic-gate if (st != NULL) 1736*7c478bd9Sstevel@tonic-gate *st = !(quotemode || backslash); 1737*7c478bd9Sstevel@tonic-gate return buf; 1738*7c478bd9Sstevel@tonic-gate } 1739*7c478bd9Sstevel@tonic-gate /* 1740*7c478bd9Sstevel@tonic-gate ** MAKEARGV -- break up a string into words 1741*7c478bd9Sstevel@tonic-gate ** 1742*7c478bd9Sstevel@tonic-gate ** Parameters: 1743*7c478bd9Sstevel@tonic-gate ** p -- the string to break up. 1744*7c478bd9Sstevel@tonic-gate ** 1745*7c478bd9Sstevel@tonic-gate ** Returns: 1746*7c478bd9Sstevel@tonic-gate ** a char **argv (dynamically allocated) 1747*7c478bd9Sstevel@tonic-gate ** 1748*7c478bd9Sstevel@tonic-gate ** Side Effects: 1749*7c478bd9Sstevel@tonic-gate ** munges p. 1750*7c478bd9Sstevel@tonic-gate */ 1751*7c478bd9Sstevel@tonic-gate 1752*7c478bd9Sstevel@tonic-gate static char ** 1753*7c478bd9Sstevel@tonic-gate makeargv(p) 1754*7c478bd9Sstevel@tonic-gate register char *p; 1755*7c478bd9Sstevel@tonic-gate { 1756*7c478bd9Sstevel@tonic-gate char *q; 1757*7c478bd9Sstevel@tonic-gate int i; 1758*7c478bd9Sstevel@tonic-gate char **avp; 1759*7c478bd9Sstevel@tonic-gate char *argv[MAXPV + 1]; 1760*7c478bd9Sstevel@tonic-gate 1761*7c478bd9Sstevel@tonic-gate /* take apart the words */ 1762*7c478bd9Sstevel@tonic-gate i = 0; 1763*7c478bd9Sstevel@tonic-gate while (*p != '\0' && i < MAXPV) 1764*7c478bd9Sstevel@tonic-gate { 1765*7c478bd9Sstevel@tonic-gate q = p; 1766*7c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 1767*7c478bd9Sstevel@tonic-gate p++; 1768*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1769*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1770*7c478bd9Sstevel@tonic-gate argv[i++] = newstr(q); 1771*7c478bd9Sstevel@tonic-gate } 1772*7c478bd9Sstevel@tonic-gate argv[i++] = NULL; 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate /* now make a copy of the argv */ 1775*7c478bd9Sstevel@tonic-gate avp = (char **) xalloc(sizeof *avp * i); 1776*7c478bd9Sstevel@tonic-gate memmove((char *) avp, (char *) argv, sizeof *avp * i); 1777*7c478bd9Sstevel@tonic-gate 1778*7c478bd9Sstevel@tonic-gate return avp; 1779*7c478bd9Sstevel@tonic-gate } 1780*7c478bd9Sstevel@tonic-gate /* 1781*7c478bd9Sstevel@tonic-gate ** PRINTRULES -- print rewrite rules (for debugging) 1782*7c478bd9Sstevel@tonic-gate ** 1783*7c478bd9Sstevel@tonic-gate ** Parameters: 1784*7c478bd9Sstevel@tonic-gate ** none. 1785*7c478bd9Sstevel@tonic-gate ** 1786*7c478bd9Sstevel@tonic-gate ** Returns: 1787*7c478bd9Sstevel@tonic-gate ** none. 1788*7c478bd9Sstevel@tonic-gate ** 1789*7c478bd9Sstevel@tonic-gate ** Side Effects: 1790*7c478bd9Sstevel@tonic-gate ** prints rewrite rules. 1791*7c478bd9Sstevel@tonic-gate */ 1792*7c478bd9Sstevel@tonic-gate 1793*7c478bd9Sstevel@tonic-gate void 1794*7c478bd9Sstevel@tonic-gate printrules() 1795*7c478bd9Sstevel@tonic-gate { 1796*7c478bd9Sstevel@tonic-gate register struct rewrite *rwp; 1797*7c478bd9Sstevel@tonic-gate register int ruleset; 1798*7c478bd9Sstevel@tonic-gate 1799*7c478bd9Sstevel@tonic-gate for (ruleset = 0; ruleset < 10; ruleset++) 1800*7c478bd9Sstevel@tonic-gate { 1801*7c478bd9Sstevel@tonic-gate if (RewriteRules[ruleset] == NULL) 1802*7c478bd9Sstevel@tonic-gate continue; 1803*7c478bd9Sstevel@tonic-gate sm_dprintf("\n----Rule Set %d:", ruleset); 1804*7c478bd9Sstevel@tonic-gate 1805*7c478bd9Sstevel@tonic-gate for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 1806*7c478bd9Sstevel@tonic-gate { 1807*7c478bd9Sstevel@tonic-gate sm_dprintf("\nLHS:"); 1808*7c478bd9Sstevel@tonic-gate printav(sm_debug_file(), rwp->r_lhs); 1809*7c478bd9Sstevel@tonic-gate sm_dprintf("RHS:"); 1810*7c478bd9Sstevel@tonic-gate printav(sm_debug_file(), rwp->r_rhs); 1811*7c478bd9Sstevel@tonic-gate } 1812*7c478bd9Sstevel@tonic-gate } 1813*7c478bd9Sstevel@tonic-gate } 1814*7c478bd9Sstevel@tonic-gate /* 1815*7c478bd9Sstevel@tonic-gate ** PRINTMAILER -- print mailer structure (for debugging) 1816*7c478bd9Sstevel@tonic-gate ** 1817*7c478bd9Sstevel@tonic-gate ** Parameters: 1818*7c478bd9Sstevel@tonic-gate ** fp -- output file 1819*7c478bd9Sstevel@tonic-gate ** m -- the mailer to print 1820*7c478bd9Sstevel@tonic-gate ** 1821*7c478bd9Sstevel@tonic-gate ** Returns: 1822*7c478bd9Sstevel@tonic-gate ** none. 1823*7c478bd9Sstevel@tonic-gate */ 1824*7c478bd9Sstevel@tonic-gate 1825*7c478bd9Sstevel@tonic-gate void 1826*7c478bd9Sstevel@tonic-gate printmailer(fp, m) 1827*7c478bd9Sstevel@tonic-gate SM_FILE_T *fp; 1828*7c478bd9Sstevel@tonic-gate register MAILER *m; 1829*7c478bd9Sstevel@tonic-gate { 1830*7c478bd9Sstevel@tonic-gate int j; 1831*7c478bd9Sstevel@tonic-gate 1832*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 1833*7c478bd9Sstevel@tonic-gate "mailer %d (%s): P=%s S=", m->m_mno, m->m_name, 1834*7c478bd9Sstevel@tonic-gate m->m_mailer); 1835*7c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_se_rwset] == NULL) 1836*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 1837*7c478bd9Sstevel@tonic-gate m->m_se_rwset); 1838*7c478bd9Sstevel@tonic-gate else 1839*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 1840*7c478bd9Sstevel@tonic-gate RuleSetNames[m->m_se_rwset]); 1841*7c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_sh_rwset] == NULL) 1842*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d R=", 1843*7c478bd9Sstevel@tonic-gate m->m_sh_rwset); 1844*7c478bd9Sstevel@tonic-gate else 1845*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s R=", 1846*7c478bd9Sstevel@tonic-gate RuleSetNames[m->m_sh_rwset]); 1847*7c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_re_rwset] == NULL) 1848*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 1849*7c478bd9Sstevel@tonic-gate m->m_re_rwset); 1850*7c478bd9Sstevel@tonic-gate else 1851*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 1852*7c478bd9Sstevel@tonic-gate RuleSetNames[m->m_re_rwset]); 1853*7c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_rh_rwset] == NULL) 1854*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d ", 1855*7c478bd9Sstevel@tonic-gate m->m_rh_rwset); 1856*7c478bd9Sstevel@tonic-gate else 1857*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s ", 1858*7c478bd9Sstevel@tonic-gate RuleSetNames[m->m_rh_rwset]); 1859*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "M=%ld U=%d:%d F=", 1860*7c478bd9Sstevel@tonic-gate m->m_maxsize, (int) m->m_uid, (int) m->m_gid); 1861*7c478bd9Sstevel@tonic-gate for (j = '\0'; j <= '\177'; j++) 1862*7c478bd9Sstevel@tonic-gate if (bitnset(j, m->m_flags)) 1863*7c478bd9Sstevel@tonic-gate (void) sm_io_putc(fp, SM_TIME_DEFAULT, j); 1864*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " L=%d E=", 1865*7c478bd9Sstevel@tonic-gate m->m_linelimit); 1866*7c478bd9Sstevel@tonic-gate xputs(fp, m->m_eol); 1867*7c478bd9Sstevel@tonic-gate if (m->m_defcharset != NULL) 1868*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " C=%s", 1869*7c478bd9Sstevel@tonic-gate m->m_defcharset); 1870*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " T=%s/%s/%s", 1871*7c478bd9Sstevel@tonic-gate m->m_mtatype == NULL 1872*7c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_mtatype, 1873*7c478bd9Sstevel@tonic-gate m->m_addrtype == NULL 1874*7c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_addrtype, 1875*7c478bd9Sstevel@tonic-gate m->m_diagtype == NULL 1876*7c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_diagtype); 1877*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " r=%d", m->m_maxrcpt); 1878*7c478bd9Sstevel@tonic-gate if (m->m_argv != NULL) 1879*7c478bd9Sstevel@tonic-gate { 1880*7c478bd9Sstevel@tonic-gate char **a = m->m_argv; 1881*7c478bd9Sstevel@tonic-gate 1882*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " A="); 1883*7c478bd9Sstevel@tonic-gate while (*a != NULL) 1884*7c478bd9Sstevel@tonic-gate { 1885*7c478bd9Sstevel@tonic-gate if (a != m->m_argv) 1886*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 1887*7c478bd9Sstevel@tonic-gate " "); 1888*7c478bd9Sstevel@tonic-gate xputs(fp, *a++); 1889*7c478bd9Sstevel@tonic-gate } 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n"); 1892*7c478bd9Sstevel@tonic-gate } 1893*7c478bd9Sstevel@tonic-gate /* 1894*7c478bd9Sstevel@tonic-gate ** SETOPTION -- set global processing option 1895*7c478bd9Sstevel@tonic-gate ** 1896*7c478bd9Sstevel@tonic-gate ** Parameters: 1897*7c478bd9Sstevel@tonic-gate ** opt -- option name. 1898*7c478bd9Sstevel@tonic-gate ** val -- option value (as a text string). 1899*7c478bd9Sstevel@tonic-gate ** safe -- set if this came from a configuration file. 1900*7c478bd9Sstevel@tonic-gate ** Some options (if set from the command line) will 1901*7c478bd9Sstevel@tonic-gate ** reset the user id to avoid security problems. 1902*7c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 1903*7c478bd9Sstevel@tonic-gate ** this value. 1904*7c478bd9Sstevel@tonic-gate ** e -- the main envelope. 1905*7c478bd9Sstevel@tonic-gate ** 1906*7c478bd9Sstevel@tonic-gate ** Returns: 1907*7c478bd9Sstevel@tonic-gate ** none. 1908*7c478bd9Sstevel@tonic-gate ** 1909*7c478bd9Sstevel@tonic-gate ** Side Effects: 1910*7c478bd9Sstevel@tonic-gate ** Sets options as implied by the arguments. 1911*7c478bd9Sstevel@tonic-gate */ 1912*7c478bd9Sstevel@tonic-gate 1913*7c478bd9Sstevel@tonic-gate static BITMAP256 StickyOpt; /* set if option is stuck */ 1914*7c478bd9Sstevel@tonic-gate 1915*7c478bd9Sstevel@tonic-gate #if NAMED_BIND 1916*7c478bd9Sstevel@tonic-gate 1917*7c478bd9Sstevel@tonic-gate static struct resolverflags 1918*7c478bd9Sstevel@tonic-gate { 1919*7c478bd9Sstevel@tonic-gate char *rf_name; /* name of the flag */ 1920*7c478bd9Sstevel@tonic-gate long rf_bits; /* bits to set/clear */ 1921*7c478bd9Sstevel@tonic-gate } ResolverFlags[] = 1922*7c478bd9Sstevel@tonic-gate { 1923*7c478bd9Sstevel@tonic-gate { "debug", RES_DEBUG }, 1924*7c478bd9Sstevel@tonic-gate { "aaonly", RES_AAONLY }, 1925*7c478bd9Sstevel@tonic-gate { "usevc", RES_USEVC }, 1926*7c478bd9Sstevel@tonic-gate { "primary", RES_PRIMARY }, 1927*7c478bd9Sstevel@tonic-gate { "igntc", RES_IGNTC }, 1928*7c478bd9Sstevel@tonic-gate { "recurse", RES_RECURSE }, 1929*7c478bd9Sstevel@tonic-gate { "defnames", RES_DEFNAMES }, 1930*7c478bd9Sstevel@tonic-gate { "stayopen", RES_STAYOPEN }, 1931*7c478bd9Sstevel@tonic-gate { "dnsrch", RES_DNSRCH }, 1932*7c478bd9Sstevel@tonic-gate # ifdef RES_USE_INET6 1933*7c478bd9Sstevel@tonic-gate { "use_inet6", RES_USE_INET6 }, 1934*7c478bd9Sstevel@tonic-gate # endif /* RES_USE_INET6 */ 1935*7c478bd9Sstevel@tonic-gate { "true", 0 }, /* avoid error on old syntax */ 1936*7c478bd9Sstevel@tonic-gate { NULL, 0 } 1937*7c478bd9Sstevel@tonic-gate }; 1938*7c478bd9Sstevel@tonic-gate 1939*7c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 1940*7c478bd9Sstevel@tonic-gate 1941*7c478bd9Sstevel@tonic-gate #define OI_NONE 0 /* no special treatment */ 1942*7c478bd9Sstevel@tonic-gate #define OI_SAFE 0x0001 /* safe for random people to use */ 1943*7c478bd9Sstevel@tonic-gate #define OI_SUBOPT 0x0002 /* option has suboptions */ 1944*7c478bd9Sstevel@tonic-gate 1945*7c478bd9Sstevel@tonic-gate static struct optioninfo 1946*7c478bd9Sstevel@tonic-gate { 1947*7c478bd9Sstevel@tonic-gate char *o_name; /* long name of option */ 1948*7c478bd9Sstevel@tonic-gate unsigned char o_code; /* short name of option */ 1949*7c478bd9Sstevel@tonic-gate unsigned short o_flags; /* option flags */ 1950*7c478bd9Sstevel@tonic-gate } OptionTab[] = 1951*7c478bd9Sstevel@tonic-gate { 1952*7c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) 1953*7c478bd9Sstevel@tonic-gate { "RemoteMode", '>', OI_NONE }, 1954*7c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */ 1955*7c478bd9Sstevel@tonic-gate { "SevenBitInput", '7', OI_SAFE }, 1956*7c478bd9Sstevel@tonic-gate { "EightBitMode", '8', OI_SAFE }, 1957*7c478bd9Sstevel@tonic-gate { "AliasFile", 'A', OI_NONE }, 1958*7c478bd9Sstevel@tonic-gate { "AliasWait", 'a', OI_NONE }, 1959*7c478bd9Sstevel@tonic-gate { "BlankSub", 'B', OI_NONE }, 1960*7c478bd9Sstevel@tonic-gate { "MinFreeBlocks", 'b', OI_SAFE }, 1961*7c478bd9Sstevel@tonic-gate { "CheckpointInterval", 'C', OI_SAFE }, 1962*7c478bd9Sstevel@tonic-gate { "HoldExpensive", 'c', OI_NONE }, 1963*7c478bd9Sstevel@tonic-gate { "DeliveryMode", 'd', OI_SAFE }, 1964*7c478bd9Sstevel@tonic-gate { "ErrorHeader", 'E', OI_NONE }, 1965*7c478bd9Sstevel@tonic-gate { "ErrorMode", 'e', OI_SAFE }, 1966*7c478bd9Sstevel@tonic-gate { "TempFileMode", 'F', OI_NONE }, 1967*7c478bd9Sstevel@tonic-gate { "SaveFromLine", 'f', OI_NONE }, 1968*7c478bd9Sstevel@tonic-gate { "MatchGECOS", 'G', OI_NONE }, 1969*7c478bd9Sstevel@tonic-gate 1970*7c478bd9Sstevel@tonic-gate /* no long name, just here to avoid problems in setoption */ 1971*7c478bd9Sstevel@tonic-gate { "", 'g', OI_NONE }, 1972*7c478bd9Sstevel@tonic-gate { "HelpFile", 'H', OI_NONE }, 1973*7c478bd9Sstevel@tonic-gate { "MaxHopCount", 'h', OI_NONE }, 1974*7c478bd9Sstevel@tonic-gate { "ResolverOptions", 'I', OI_NONE }, 1975*7c478bd9Sstevel@tonic-gate { "IgnoreDots", 'i', OI_SAFE }, 1976*7c478bd9Sstevel@tonic-gate { "ForwardPath", 'J', OI_NONE }, 1977*7c478bd9Sstevel@tonic-gate { "SendMimeErrors", 'j', OI_SAFE }, 1978*7c478bd9Sstevel@tonic-gate { "ConnectionCacheSize", 'k', OI_NONE }, 1979*7c478bd9Sstevel@tonic-gate { "ConnectionCacheTimeout", 'K', OI_NONE }, 1980*7c478bd9Sstevel@tonic-gate { "UseErrorsTo", 'l', OI_NONE }, 1981*7c478bd9Sstevel@tonic-gate { "LogLevel", 'L', OI_SAFE }, 1982*7c478bd9Sstevel@tonic-gate { "MeToo", 'm', OI_SAFE }, 1983*7c478bd9Sstevel@tonic-gate 1984*7c478bd9Sstevel@tonic-gate /* no long name, just here to avoid problems in setoption */ 1985*7c478bd9Sstevel@tonic-gate { "", 'M', OI_NONE }, 1986*7c478bd9Sstevel@tonic-gate { "CheckAliases", 'n', OI_NONE }, 1987*7c478bd9Sstevel@tonic-gate { "OldStyleHeaders", 'o', OI_SAFE }, 1988*7c478bd9Sstevel@tonic-gate { "DaemonPortOptions", 'O', OI_NONE }, 1989*7c478bd9Sstevel@tonic-gate { "PrivacyOptions", 'p', OI_SAFE }, 1990*7c478bd9Sstevel@tonic-gate { "PostmasterCopy", 'P', OI_NONE }, 1991*7c478bd9Sstevel@tonic-gate { "QueueFactor", 'q', OI_NONE }, 1992*7c478bd9Sstevel@tonic-gate { "QueueDirectory", 'Q', OI_NONE }, 1993*7c478bd9Sstevel@tonic-gate { "DontPruneRoutes", 'R', OI_NONE }, 1994*7c478bd9Sstevel@tonic-gate { "Timeout", 'r', OI_SUBOPT }, 1995*7c478bd9Sstevel@tonic-gate { "StatusFile", 'S', OI_NONE }, 1996*7c478bd9Sstevel@tonic-gate { "SuperSafe", 's', OI_SAFE }, 1997*7c478bd9Sstevel@tonic-gate { "QueueTimeout", 'T', OI_NONE }, 1998*7c478bd9Sstevel@tonic-gate { "TimeZoneSpec", 't', OI_NONE }, 1999*7c478bd9Sstevel@tonic-gate { "UserDatabaseSpec", 'U', OI_NONE }, 2000*7c478bd9Sstevel@tonic-gate { "DefaultUser", 'u', OI_NONE }, 2001*7c478bd9Sstevel@tonic-gate { "FallbackMXhost", 'V', OI_NONE }, 2002*7c478bd9Sstevel@tonic-gate { "Verbose", 'v', OI_SAFE }, 2003*7c478bd9Sstevel@tonic-gate { "TryNullMXList", 'w', OI_NONE }, 2004*7c478bd9Sstevel@tonic-gate { "QueueLA", 'x', OI_NONE }, 2005*7c478bd9Sstevel@tonic-gate { "RefuseLA", 'X', OI_NONE }, 2006*7c478bd9Sstevel@tonic-gate { "RecipientFactor", 'y', OI_NONE }, 2007*7c478bd9Sstevel@tonic-gate { "ForkEachJob", 'Y', OI_NONE }, 2008*7c478bd9Sstevel@tonic-gate { "ClassFactor", 'z', OI_NONE }, 2009*7c478bd9Sstevel@tonic-gate { "RetryFactor", 'Z', OI_NONE }, 2010*7c478bd9Sstevel@tonic-gate #define O_QUEUESORTORD 0x81 2011*7c478bd9Sstevel@tonic-gate { "QueueSortOrder", O_QUEUESORTORD, OI_SAFE }, 2012*7c478bd9Sstevel@tonic-gate #define O_HOSTSFILE 0x82 2013*7c478bd9Sstevel@tonic-gate { "HostsFile", O_HOSTSFILE, OI_NONE }, 2014*7c478bd9Sstevel@tonic-gate #define O_MQA 0x83 2015*7c478bd9Sstevel@tonic-gate { "MinQueueAge", O_MQA, OI_SAFE }, 2016*7c478bd9Sstevel@tonic-gate #define O_DEFCHARSET 0x85 2017*7c478bd9Sstevel@tonic-gate { "DefaultCharSet", O_DEFCHARSET, OI_SAFE }, 2018*7c478bd9Sstevel@tonic-gate #define O_SSFILE 0x86 2019*7c478bd9Sstevel@tonic-gate { "ServiceSwitchFile", O_SSFILE, OI_NONE }, 2020*7c478bd9Sstevel@tonic-gate #define O_DIALDELAY 0x87 2021*7c478bd9Sstevel@tonic-gate { "DialDelay", O_DIALDELAY, OI_SAFE }, 2022*7c478bd9Sstevel@tonic-gate #define O_NORCPTACTION 0x88 2023*7c478bd9Sstevel@tonic-gate { "NoRecipientAction", O_NORCPTACTION, OI_SAFE }, 2024*7c478bd9Sstevel@tonic-gate #define O_SAFEFILEENV 0x89 2025*7c478bd9Sstevel@tonic-gate { "SafeFileEnvironment", O_SAFEFILEENV, OI_NONE }, 2026*7c478bd9Sstevel@tonic-gate #define O_MAXMSGSIZE 0x8a 2027*7c478bd9Sstevel@tonic-gate { "MaxMessageSize", O_MAXMSGSIZE, OI_NONE }, 2028*7c478bd9Sstevel@tonic-gate #define O_COLONOKINADDR 0x8b 2029*7c478bd9Sstevel@tonic-gate { "ColonOkInAddr", O_COLONOKINADDR, OI_SAFE }, 2030*7c478bd9Sstevel@tonic-gate #define O_MAXQUEUERUN 0x8c 2031*7c478bd9Sstevel@tonic-gate { "MaxQueueRunSize", O_MAXQUEUERUN, OI_SAFE }, 2032*7c478bd9Sstevel@tonic-gate #define O_MAXCHILDREN 0x8d 2033*7c478bd9Sstevel@tonic-gate { "MaxDaemonChildren", O_MAXCHILDREN, OI_NONE }, 2034*7c478bd9Sstevel@tonic-gate #define O_KEEPCNAMES 0x8e 2035*7c478bd9Sstevel@tonic-gate { "DontExpandCnames", O_KEEPCNAMES, OI_NONE }, 2036*7c478bd9Sstevel@tonic-gate #define O_MUSTQUOTE 0x8f 2037*7c478bd9Sstevel@tonic-gate { "MustQuoteChars", O_MUSTQUOTE, OI_NONE }, 2038*7c478bd9Sstevel@tonic-gate #define O_SMTPGREETING 0x90 2039*7c478bd9Sstevel@tonic-gate { "SmtpGreetingMessage", O_SMTPGREETING, OI_NONE }, 2040*7c478bd9Sstevel@tonic-gate #define O_UNIXFROM 0x91 2041*7c478bd9Sstevel@tonic-gate { "UnixFromLine", O_UNIXFROM, OI_NONE }, 2042*7c478bd9Sstevel@tonic-gate #define O_OPCHARS 0x92 2043*7c478bd9Sstevel@tonic-gate { "OperatorChars", O_OPCHARS, OI_NONE }, 2044*7c478bd9Sstevel@tonic-gate #define O_DONTINITGRPS 0x93 2045*7c478bd9Sstevel@tonic-gate { "DontInitGroups", O_DONTINITGRPS, OI_NONE }, 2046*7c478bd9Sstevel@tonic-gate #define O_SLFH 0x94 2047*7c478bd9Sstevel@tonic-gate { "SingleLineFromHeader", O_SLFH, OI_SAFE }, 2048*7c478bd9Sstevel@tonic-gate #define O_ABH 0x95 2049*7c478bd9Sstevel@tonic-gate { "AllowBogusHELO", O_ABH, OI_SAFE }, 2050*7c478bd9Sstevel@tonic-gate #define O_CONNTHROT 0x97 2051*7c478bd9Sstevel@tonic-gate { "ConnectionRateThrottle", O_CONNTHROT, OI_NONE }, 2052*7c478bd9Sstevel@tonic-gate #define O_UGW 0x99 2053*7c478bd9Sstevel@tonic-gate { "UnsafeGroupWrites", O_UGW, OI_NONE }, 2054*7c478bd9Sstevel@tonic-gate #define O_DBLBOUNCE 0x9a 2055*7c478bd9Sstevel@tonic-gate { "DoubleBounceAddress", O_DBLBOUNCE, OI_NONE }, 2056*7c478bd9Sstevel@tonic-gate #define O_HSDIR 0x9b 2057*7c478bd9Sstevel@tonic-gate { "HostStatusDirectory", O_HSDIR, OI_NONE }, 2058*7c478bd9Sstevel@tonic-gate #define O_SINGTHREAD 0x9c 2059*7c478bd9Sstevel@tonic-gate { "SingleThreadDelivery", O_SINGTHREAD, OI_NONE }, 2060*7c478bd9Sstevel@tonic-gate #define O_RUNASUSER 0x9d 2061*7c478bd9Sstevel@tonic-gate { "RunAsUser", O_RUNASUSER, OI_NONE }, 2062*7c478bd9Sstevel@tonic-gate #define O_DSN_RRT 0x9e 2063*7c478bd9Sstevel@tonic-gate { "RrtImpliesDsn", O_DSN_RRT, OI_NONE }, 2064*7c478bd9Sstevel@tonic-gate #define O_PIDFILE 0x9f 2065*7c478bd9Sstevel@tonic-gate { "PidFile", O_PIDFILE, OI_NONE }, 2066*7c478bd9Sstevel@tonic-gate #define O_DONTBLAMESENDMAIL 0xa0 2067*7c478bd9Sstevel@tonic-gate { "DontBlameSendmail", O_DONTBLAMESENDMAIL, OI_NONE }, 2068*7c478bd9Sstevel@tonic-gate #define O_DPI 0xa1 2069*7c478bd9Sstevel@tonic-gate { "DontProbeInterfaces", O_DPI, OI_NONE }, 2070*7c478bd9Sstevel@tonic-gate #define O_MAXRCPT 0xa2 2071*7c478bd9Sstevel@tonic-gate { "MaxRecipientsPerMessage", O_MAXRCPT, OI_SAFE }, 2072*7c478bd9Sstevel@tonic-gate #define O_DEADLETTER 0xa3 2073*7c478bd9Sstevel@tonic-gate { "DeadLetterDrop", O_DEADLETTER, OI_NONE }, 2074*7c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION 2075*7c478bd9Sstevel@tonic-gate # define O_DONTLOCK 0xa4 2076*7c478bd9Sstevel@tonic-gate { "DontLockFilesForRead", O_DONTLOCK, OI_NONE }, 2077*7c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ 2078*7c478bd9Sstevel@tonic-gate #define O_MAXALIASRCSN 0xa5 2079*7c478bd9Sstevel@tonic-gate { "MaxAliasRecursion", O_MAXALIASRCSN, OI_NONE }, 2080*7c478bd9Sstevel@tonic-gate #define O_CNCTONLYTO 0xa6 2081*7c478bd9Sstevel@tonic-gate { "ConnectOnlyTo", O_CNCTONLYTO, OI_NONE }, 2082*7c478bd9Sstevel@tonic-gate #define O_TRUSTUSER 0xa7 2083*7c478bd9Sstevel@tonic-gate { "TrustedUser", O_TRUSTUSER, OI_NONE }, 2084*7c478bd9Sstevel@tonic-gate #define O_MAXMIMEHDRLEN 0xa8 2085*7c478bd9Sstevel@tonic-gate { "MaxMimeHeaderLength", O_MAXMIMEHDRLEN, OI_NONE }, 2086*7c478bd9Sstevel@tonic-gate #define O_CONTROLSOCKET 0xa9 2087*7c478bd9Sstevel@tonic-gate { "ControlSocketName", O_CONTROLSOCKET, OI_NONE }, 2088*7c478bd9Sstevel@tonic-gate #define O_MAXHDRSLEN 0xaa 2089*7c478bd9Sstevel@tonic-gate { "MaxHeadersLength", O_MAXHDRSLEN, OI_NONE }, 2090*7c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES 2091*7c478bd9Sstevel@tonic-gate # define O_MAXFORWARD 0xab 2092*7c478bd9Sstevel@tonic-gate { "MaxForwardEntries", O_MAXFORWARD, OI_NONE }, 2093*7c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */ 2094*7c478bd9Sstevel@tonic-gate #define O_PROCTITLEPREFIX 0xac 2095*7c478bd9Sstevel@tonic-gate { "ProcessTitlePrefix", O_PROCTITLEPREFIX, OI_NONE }, 2096*7c478bd9Sstevel@tonic-gate #define O_SASLINFO 0xad 2097*7c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO 2098*7c478bd9Sstevel@tonic-gate { "DefaultAuthInfo", O_SASLINFO, OI_SAFE }, 2099*7c478bd9Sstevel@tonic-gate #else /* _FFR_ALLOW_SASLINFO */ 2100*7c478bd9Sstevel@tonic-gate { "DefaultAuthInfo", O_SASLINFO, OI_NONE }, 2101*7c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */ 2102*7c478bd9Sstevel@tonic-gate #define O_SASLMECH 0xae 2103*7c478bd9Sstevel@tonic-gate { "AuthMechanisms", O_SASLMECH, OI_NONE }, 2104*7c478bd9Sstevel@tonic-gate #define O_CLIENTPORT 0xaf 2105*7c478bd9Sstevel@tonic-gate { "ClientPortOptions", O_CLIENTPORT, OI_NONE }, 2106*7c478bd9Sstevel@tonic-gate #define O_DF_BUFSIZE 0xb0 2107*7c478bd9Sstevel@tonic-gate { "DataFileBufferSize", O_DF_BUFSIZE, OI_NONE }, 2108*7c478bd9Sstevel@tonic-gate #define O_XF_BUFSIZE 0xb1 2109*7c478bd9Sstevel@tonic-gate { "XscriptFileBufferSize", O_XF_BUFSIZE, OI_NONE }, 2110*7c478bd9Sstevel@tonic-gate #define O_LDAPDEFAULTSPEC 0xb2 2111*7c478bd9Sstevel@tonic-gate { "LDAPDefaultSpec", O_LDAPDEFAULTSPEC, OI_NONE }, 2112*7c478bd9Sstevel@tonic-gate #define O_SRVCERTFILE 0xb4 2113*7c478bd9Sstevel@tonic-gate { "ServerCertFile", O_SRVCERTFILE, OI_NONE }, 2114*7c478bd9Sstevel@tonic-gate #define O_SRVKEYFILE 0xb5 2115*7c478bd9Sstevel@tonic-gate { "ServerKeyFile", O_SRVKEYFILE, OI_NONE }, 2116*7c478bd9Sstevel@tonic-gate #define O_CLTCERTFILE 0xb6 2117*7c478bd9Sstevel@tonic-gate { "ClientCertFile", O_CLTCERTFILE, OI_NONE }, 2118*7c478bd9Sstevel@tonic-gate #define O_CLTKEYFILE 0xb7 2119*7c478bd9Sstevel@tonic-gate { "ClientKeyFile", O_CLTKEYFILE, OI_NONE }, 2120*7c478bd9Sstevel@tonic-gate #define O_CACERTFILE 0xb8 2121*7c478bd9Sstevel@tonic-gate { "CACertFile", O_CACERTFILE, OI_NONE }, 2122*7c478bd9Sstevel@tonic-gate #define O_CACERTPATH 0xb9 2123*7c478bd9Sstevel@tonic-gate { "CACertPath", O_CACERTPATH, OI_NONE }, 2124*7c478bd9Sstevel@tonic-gate #define O_DHPARAMS 0xba 2125*7c478bd9Sstevel@tonic-gate { "DHParameters", O_DHPARAMS, OI_NONE }, 2126*7c478bd9Sstevel@tonic-gate #define O_INPUTMILTER 0xbb 2127*7c478bd9Sstevel@tonic-gate { "InputMailFilters", O_INPUTMILTER, OI_NONE }, 2128*7c478bd9Sstevel@tonic-gate #define O_MILTER 0xbc 2129*7c478bd9Sstevel@tonic-gate { "Milter", O_MILTER, OI_SUBOPT }, 2130*7c478bd9Sstevel@tonic-gate #define O_SASLOPTS 0xbd 2131*7c478bd9Sstevel@tonic-gate { "AuthOptions", O_SASLOPTS, OI_NONE }, 2132*7c478bd9Sstevel@tonic-gate #define O_QUEUE_FILE_MODE 0xbe 2133*7c478bd9Sstevel@tonic-gate { "QueueFileMode", O_QUEUE_FILE_MODE, OI_NONE }, 2134*7c478bd9Sstevel@tonic-gate #if _FFR_TLS_1 2135*7c478bd9Sstevel@tonic-gate # define O_DHPARAMS5 0xbf 2136*7c478bd9Sstevel@tonic-gate { "DHParameters512", O_DHPARAMS5, OI_NONE }, 2137*7c478bd9Sstevel@tonic-gate # define O_CIPHERLIST 0xc0 2138*7c478bd9Sstevel@tonic-gate { "CipherList", O_CIPHERLIST, OI_NONE }, 2139*7c478bd9Sstevel@tonic-gate #endif /* _FFR_TLS_1 */ 2140*7c478bd9Sstevel@tonic-gate #define O_RANDFILE 0xc1 2141*7c478bd9Sstevel@tonic-gate { "RandFile", O_RANDFILE, OI_NONE }, 2142*7c478bd9Sstevel@tonic-gate #define O_TLS_SRV_OPTS 0xc2 2143*7c478bd9Sstevel@tonic-gate { "TLSSrvOptions", O_TLS_SRV_OPTS, OI_NONE }, 2144*7c478bd9Sstevel@tonic-gate #define O_RCPTTHROT 0xc3 2145*7c478bd9Sstevel@tonic-gate { "BadRcptThrottle", O_RCPTTHROT, OI_SAFE }, 2146*7c478bd9Sstevel@tonic-gate #define O_DLVR_MIN 0xc4 2147*7c478bd9Sstevel@tonic-gate { "DeliverByMin", O_DLVR_MIN, OI_NONE }, 2148*7c478bd9Sstevel@tonic-gate #define O_MAXQUEUECHILDREN 0xc5 2149*7c478bd9Sstevel@tonic-gate { "MaxQueueChildren", O_MAXQUEUECHILDREN, OI_NONE }, 2150*7c478bd9Sstevel@tonic-gate #define O_MAXRUNNERSPERQUEUE 0xc6 2151*7c478bd9Sstevel@tonic-gate { "MaxRunnersPerQueue", O_MAXRUNNERSPERQUEUE, OI_NONE }, 2152*7c478bd9Sstevel@tonic-gate #define O_DIRECTSUBMODIFIERS 0xc7 2153*7c478bd9Sstevel@tonic-gate { "DirectSubmissionModifiers", O_DIRECTSUBMODIFIERS, OI_NONE }, 2154*7c478bd9Sstevel@tonic-gate #define O_NICEQUEUERUN 0xc8 2155*7c478bd9Sstevel@tonic-gate { "NiceQueueRun", O_NICEQUEUERUN, OI_NONE }, 2156*7c478bd9Sstevel@tonic-gate #define O_SHMKEY 0xc9 2157*7c478bd9Sstevel@tonic-gate { "SharedMemoryKey", O_SHMKEY, OI_NONE }, 2158*7c478bd9Sstevel@tonic-gate #define O_SASLBITS 0xca 2159*7c478bd9Sstevel@tonic-gate { "AuthMaxBits", O_SASLBITS, OI_NONE }, 2160*7c478bd9Sstevel@tonic-gate #define O_MBDB 0xcb 2161*7c478bd9Sstevel@tonic-gate { "MailboxDatabase", O_MBDB, OI_NONE }, 2162*7c478bd9Sstevel@tonic-gate #define O_MSQ 0xcc 2163*7c478bd9Sstevel@tonic-gate { "UseMSP", O_MSQ, OI_NONE }, 2164*7c478bd9Sstevel@tonic-gate #define O_DELAY_LA 0xcd 2165*7c478bd9Sstevel@tonic-gate { "DelayLA", O_DELAY_LA, OI_NONE }, 2166*7c478bd9Sstevel@tonic-gate #define O_FASTSPLIT 0xce 2167*7c478bd9Sstevel@tonic-gate { "FastSplit", O_FASTSPLIT, OI_NONE }, 2168*7c478bd9Sstevel@tonic-gate #if _FFR_SOFT_BOUNCE 2169*7c478bd9Sstevel@tonic-gate # define O_SOFTBOUNCE 0xcf 2170*7c478bd9Sstevel@tonic-gate { "SoftBounce", O_SOFTBOUNCE, OI_NONE }, 2171*7c478bd9Sstevel@tonic-gate #endif /* _FFR_SOFT_BOUNCE */ 2172*7c478bd9Sstevel@tonic-gate #if _FFR_SELECT_SHM 2173*7c478bd9Sstevel@tonic-gate # define O_SHMKEYFILE 0xd0 2174*7c478bd9Sstevel@tonic-gate { "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE }, 2175*7c478bd9Sstevel@tonic-gate #endif /* _FFR_SELECT_SHM */ 2176*7c478bd9Sstevel@tonic-gate #define O_REJECTLOGINTERVAL 0xd1 2177*7c478bd9Sstevel@tonic-gate { "RejectLogInterval", O_REJECTLOGINTERVAL, OI_NONE }, 2178*7c478bd9Sstevel@tonic-gate #define O_REQUIRES_DIR_FSYNC 0xd2 2179*7c478bd9Sstevel@tonic-gate { "RequiresDirfsync", O_REQUIRES_DIR_FSYNC, OI_NONE }, 2180*7c478bd9Sstevel@tonic-gate #define O_CONNECTION_RATE_WINDOW_SIZE 0xd3 2181*7c478bd9Sstevel@tonic-gate { "ConnectionRateWindowSize", O_CONNECTION_RATE_WINDOW_SIZE, OI_NONE }, 2182*7c478bd9Sstevel@tonic-gate #define O_CRLFILE 0xd4 2183*7c478bd9Sstevel@tonic-gate { "CRLFile", O_CRLFILE, OI_NONE }, 2184*7c478bd9Sstevel@tonic-gate #define O_FALLBACKSMARTHOST 0xd5 2185*7c478bd9Sstevel@tonic-gate { "FallbackSmartHost", O_FALLBACKSMARTHOST, OI_NONE }, 2186*7c478bd9Sstevel@tonic-gate #define O_SASLREALM 0xd6 2187*7c478bd9Sstevel@tonic-gate { "AuthRealm", O_SASLREALM, OI_NONE }, 2188*7c478bd9Sstevel@tonic-gate #if _FFR_CRLPATH 2189*7c478bd9Sstevel@tonic-gate # define O_CRLPATH 0xd7 2190*7c478bd9Sstevel@tonic-gate { "CRLPath", O_CRLPATH, OI_NONE }, 2191*7c478bd9Sstevel@tonic-gate #endif /* _FFR_CRLPATH */ 2192*7c478bd9Sstevel@tonic-gate #if _FFR_HELONAME 2193*7c478bd9Sstevel@tonic-gate # define O_HELONAME 0xd8 2194*7c478bd9Sstevel@tonic-gate { "HeloName", O_HELONAME, OI_NONE }, 2195*7c478bd9Sstevel@tonic-gate #endif /* _FFR_HELONAME */ 2196*7c478bd9Sstevel@tonic-gate 2197*7c478bd9Sstevel@tonic-gate { NULL, '\0', OI_NONE } 2198*7c478bd9Sstevel@tonic-gate }; 2199*7c478bd9Sstevel@tonic-gate 2200*7c478bd9Sstevel@tonic-gate # define CANONIFY(val) 2201*7c478bd9Sstevel@tonic-gate 2202*7c478bd9Sstevel@tonic-gate # define SET_OPT_DEFAULT(opt, val) opt = val 2203*7c478bd9Sstevel@tonic-gate 2204*7c478bd9Sstevel@tonic-gate /* set a string option by expanding the value and assigning it */ 2205*7c478bd9Sstevel@tonic-gate /* WARNING this belongs ONLY into a case statement! */ 2206*7c478bd9Sstevel@tonic-gate #define SET_STRING_EXP(str) \ 2207*7c478bd9Sstevel@tonic-gate expand(val, exbuf, sizeof exbuf, e); \ 2208*7c478bd9Sstevel@tonic-gate newval = sm_pstrdup_x(exbuf); \ 2209*7c478bd9Sstevel@tonic-gate if (str != NULL) \ 2210*7c478bd9Sstevel@tonic-gate sm_free(str); \ 2211*7c478bd9Sstevel@tonic-gate CANONIFY(newval); \ 2212*7c478bd9Sstevel@tonic-gate str = newval; \ 2213*7c478bd9Sstevel@tonic-gate break 2214*7c478bd9Sstevel@tonic-gate 2215*7c478bd9Sstevel@tonic-gate #define OPTNAME o->o_name == NULL ? "<unknown>" : o->o_name 2216*7c478bd9Sstevel@tonic-gate 2217*7c478bd9Sstevel@tonic-gate void 2218*7c478bd9Sstevel@tonic-gate setoption(opt, val, safe, sticky, e) 2219*7c478bd9Sstevel@tonic-gate int opt; 2220*7c478bd9Sstevel@tonic-gate char *val; 2221*7c478bd9Sstevel@tonic-gate bool safe; 2222*7c478bd9Sstevel@tonic-gate bool sticky; 2223*7c478bd9Sstevel@tonic-gate register ENVELOPE *e; 2224*7c478bd9Sstevel@tonic-gate { 2225*7c478bd9Sstevel@tonic-gate register char *p; 2226*7c478bd9Sstevel@tonic-gate register struct optioninfo *o; 2227*7c478bd9Sstevel@tonic-gate char *subopt; 2228*7c478bd9Sstevel@tonic-gate int mid; 2229*7c478bd9Sstevel@tonic-gate bool can_setuid = RunAsUid == 0; 2230*7c478bd9Sstevel@tonic-gate auto char *ep; 2231*7c478bd9Sstevel@tonic-gate char buf[50]; 2232*7c478bd9Sstevel@tonic-gate extern bool Warn_Q_option; 2233*7c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO 2234*7c478bd9Sstevel@tonic-gate extern unsigned int SubmitMode; 2235*7c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */ 2236*7c478bd9Sstevel@tonic-gate #if STARTTLS 2237*7c478bd9Sstevel@tonic-gate char *newval; 2238*7c478bd9Sstevel@tonic-gate char exbuf[MAXLINE]; 2239*7c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 2240*7c478bd9Sstevel@tonic-gate 2241*7c478bd9Sstevel@tonic-gate errno = 0; 2242*7c478bd9Sstevel@tonic-gate if (opt == ' ') 2243*7c478bd9Sstevel@tonic-gate { 2244*7c478bd9Sstevel@tonic-gate /* full word options */ 2245*7c478bd9Sstevel@tonic-gate struct optioninfo *sel; 2246*7c478bd9Sstevel@tonic-gate 2247*7c478bd9Sstevel@tonic-gate p = strchr(val, '='); 2248*7c478bd9Sstevel@tonic-gate if (p == NULL) 2249*7c478bd9Sstevel@tonic-gate p = &val[strlen(val)]; 2250*7c478bd9Sstevel@tonic-gate while (*--p == ' ') 2251*7c478bd9Sstevel@tonic-gate continue; 2252*7c478bd9Sstevel@tonic-gate while (*++p == ' ') 2253*7c478bd9Sstevel@tonic-gate *p = '\0'; 2254*7c478bd9Sstevel@tonic-gate if (p == val) 2255*7c478bd9Sstevel@tonic-gate { 2256*7c478bd9Sstevel@tonic-gate syserr("readcf: null option name"); 2257*7c478bd9Sstevel@tonic-gate return; 2258*7c478bd9Sstevel@tonic-gate } 2259*7c478bd9Sstevel@tonic-gate if (*p == '=') 2260*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2261*7c478bd9Sstevel@tonic-gate while (*p == ' ') 2262*7c478bd9Sstevel@tonic-gate p++; 2263*7c478bd9Sstevel@tonic-gate subopt = strchr(val, '.'); 2264*7c478bd9Sstevel@tonic-gate if (subopt != NULL) 2265*7c478bd9Sstevel@tonic-gate *subopt++ = '\0'; 2266*7c478bd9Sstevel@tonic-gate sel = NULL; 2267*7c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 2268*7c478bd9Sstevel@tonic-gate { 2269*7c478bd9Sstevel@tonic-gate if (sm_strncasecmp(o->o_name, val, strlen(val)) != 0) 2270*7c478bd9Sstevel@tonic-gate continue; 2271*7c478bd9Sstevel@tonic-gate if (strlen(o->o_name) == strlen(val)) 2272*7c478bd9Sstevel@tonic-gate { 2273*7c478bd9Sstevel@tonic-gate /* completely specified -- this must be it */ 2274*7c478bd9Sstevel@tonic-gate sel = NULL; 2275*7c478bd9Sstevel@tonic-gate break; 2276*7c478bd9Sstevel@tonic-gate } 2277*7c478bd9Sstevel@tonic-gate if (sel != NULL) 2278*7c478bd9Sstevel@tonic-gate break; 2279*7c478bd9Sstevel@tonic-gate sel = o; 2280*7c478bd9Sstevel@tonic-gate } 2281*7c478bd9Sstevel@tonic-gate if (sel != NULL && o->o_name == NULL) 2282*7c478bd9Sstevel@tonic-gate o = sel; 2283*7c478bd9Sstevel@tonic-gate else if (o->o_name == NULL) 2284*7c478bd9Sstevel@tonic-gate { 2285*7c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name %s", val); 2286*7c478bd9Sstevel@tonic-gate return; 2287*7c478bd9Sstevel@tonic-gate } 2288*7c478bd9Sstevel@tonic-gate else if (sel != NULL) 2289*7c478bd9Sstevel@tonic-gate { 2290*7c478bd9Sstevel@tonic-gate syserr("readcf: ambiguous option name %s (matches %s and %s)", 2291*7c478bd9Sstevel@tonic-gate val, sel->o_name, o->o_name); 2292*7c478bd9Sstevel@tonic-gate return; 2293*7c478bd9Sstevel@tonic-gate } 2294*7c478bd9Sstevel@tonic-gate if (strlen(val) != strlen(o->o_name)) 2295*7c478bd9Sstevel@tonic-gate { 2296*7c478bd9Sstevel@tonic-gate int oldVerbose = Verbose; 2297*7c478bd9Sstevel@tonic-gate 2298*7c478bd9Sstevel@tonic-gate Verbose = 1; 2299*7c478bd9Sstevel@tonic-gate message("Option %s used as abbreviation for %s", 2300*7c478bd9Sstevel@tonic-gate val, o->o_name); 2301*7c478bd9Sstevel@tonic-gate Verbose = oldVerbose; 2302*7c478bd9Sstevel@tonic-gate } 2303*7c478bd9Sstevel@tonic-gate opt = o->o_code; 2304*7c478bd9Sstevel@tonic-gate val = p; 2305*7c478bd9Sstevel@tonic-gate } 2306*7c478bd9Sstevel@tonic-gate else 2307*7c478bd9Sstevel@tonic-gate { 2308*7c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 2309*7c478bd9Sstevel@tonic-gate { 2310*7c478bd9Sstevel@tonic-gate if (o->o_code == opt) 2311*7c478bd9Sstevel@tonic-gate break; 2312*7c478bd9Sstevel@tonic-gate } 2313*7c478bd9Sstevel@tonic-gate if (o->o_name == NULL) 2314*7c478bd9Sstevel@tonic-gate { 2315*7c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name 0x%x", opt & 0xff); 2316*7c478bd9Sstevel@tonic-gate return; 2317*7c478bd9Sstevel@tonic-gate } 2318*7c478bd9Sstevel@tonic-gate subopt = NULL; 2319*7c478bd9Sstevel@tonic-gate } 2320*7c478bd9Sstevel@tonic-gate 2321*7c478bd9Sstevel@tonic-gate if (subopt != NULL && !bitset(OI_SUBOPT, o->o_flags)) 2322*7c478bd9Sstevel@tonic-gate { 2323*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 2324*7c478bd9Sstevel@tonic-gate sm_dprintf("setoption: %s does not support suboptions, ignoring .%s\n", 2325*7c478bd9Sstevel@tonic-gate OPTNAME, subopt); 2326*7c478bd9Sstevel@tonic-gate subopt = NULL; 2327*7c478bd9Sstevel@tonic-gate } 2328*7c478bd9Sstevel@tonic-gate 2329*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 2330*7c478bd9Sstevel@tonic-gate { 2331*7c478bd9Sstevel@tonic-gate sm_dprintf(isascii(opt) && isprint(opt) ? 2332*7c478bd9Sstevel@tonic-gate "setoption %s (%c)%s%s=" : 2333*7c478bd9Sstevel@tonic-gate "setoption %s (0x%x)%s%s=", 2334*7c478bd9Sstevel@tonic-gate OPTNAME, opt, subopt == NULL ? "" : ".", 2335*7c478bd9Sstevel@tonic-gate subopt == NULL ? "" : subopt); 2336*7c478bd9Sstevel@tonic-gate xputs(sm_debug_file(), val); 2337*7c478bd9Sstevel@tonic-gate } 2338*7c478bd9Sstevel@tonic-gate 2339*7c478bd9Sstevel@tonic-gate /* 2340*7c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 2341*7c478bd9Sstevel@tonic-gate */ 2342*7c478bd9Sstevel@tonic-gate 2343*7c478bd9Sstevel@tonic-gate if (!sticky && bitnset(opt, StickyOpt)) 2344*7c478bd9Sstevel@tonic-gate { 2345*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 2346*7c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 2347*7c478bd9Sstevel@tonic-gate return; 2348*7c478bd9Sstevel@tonic-gate } 2349*7c478bd9Sstevel@tonic-gate 2350*7c478bd9Sstevel@tonic-gate /* 2351*7c478bd9Sstevel@tonic-gate ** Check to see if this option can be specified by this user. 2352*7c478bd9Sstevel@tonic-gate */ 2353*7c478bd9Sstevel@tonic-gate 2354*7c478bd9Sstevel@tonic-gate if (!safe && RealUid == 0) 2355*7c478bd9Sstevel@tonic-gate safe = true; 2356*7c478bd9Sstevel@tonic-gate if (!safe && !bitset(OI_SAFE, o->o_flags)) 2357*7c478bd9Sstevel@tonic-gate { 2358*7c478bd9Sstevel@tonic-gate if (opt != 'M' || (val[0] != 'r' && val[0] != 's')) 2359*7c478bd9Sstevel@tonic-gate { 2360*7c478bd9Sstevel@tonic-gate int dp; 2361*7c478bd9Sstevel@tonic-gate 2362*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 2363*7c478bd9Sstevel@tonic-gate sm_dprintf(" (unsafe)"); 2364*7c478bd9Sstevel@tonic-gate dp = drop_privileges(true); 2365*7c478bd9Sstevel@tonic-gate setstat(dp); 2366*7c478bd9Sstevel@tonic-gate } 2367*7c478bd9Sstevel@tonic-gate } 2368*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 2369*7c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 2370*7c478bd9Sstevel@tonic-gate 2371*7c478bd9Sstevel@tonic-gate switch (opt & 0xff) 2372*7c478bd9Sstevel@tonic-gate { 2373*7c478bd9Sstevel@tonic-gate case '7': /* force seven-bit input */ 2374*7c478bd9Sstevel@tonic-gate SevenBitInput = atobool(val); 2375*7c478bd9Sstevel@tonic-gate break; 2376*7c478bd9Sstevel@tonic-gate 2377*7c478bd9Sstevel@tonic-gate case '8': /* handling of 8-bit input */ 2378*7c478bd9Sstevel@tonic-gate #if MIME8TO7 2379*7c478bd9Sstevel@tonic-gate switch (*val) 2380*7c478bd9Sstevel@tonic-gate { 2381*7c478bd9Sstevel@tonic-gate case 'p': /* pass 8 bit, convert MIME */ 2382*7c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_PASS8BIT; 2383*7c478bd9Sstevel@tonic-gate break; 2384*7c478bd9Sstevel@tonic-gate 2385*7c478bd9Sstevel@tonic-gate case 'm': /* convert 8-bit, convert MIME */ 2386*7c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_MIME8BIT; 2387*7c478bd9Sstevel@tonic-gate break; 2388*7c478bd9Sstevel@tonic-gate 2389*7c478bd9Sstevel@tonic-gate case 's': /* strict adherence */ 2390*7c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME; 2391*7c478bd9Sstevel@tonic-gate break; 2392*7c478bd9Sstevel@tonic-gate 2393*7c478bd9Sstevel@tonic-gate # if 0 2394*7c478bd9Sstevel@tonic-gate case 'r': /* reject 8-bit, don't convert MIME */ 2395*7c478bd9Sstevel@tonic-gate MimeMode = 0; 2396*7c478bd9Sstevel@tonic-gate break; 2397*7c478bd9Sstevel@tonic-gate 2398*7c478bd9Sstevel@tonic-gate case 'j': /* "just send 8" */ 2399*7c478bd9Sstevel@tonic-gate MimeMode = MM_PASS8BIT; 2400*7c478bd9Sstevel@tonic-gate break; 2401*7c478bd9Sstevel@tonic-gate 2402*7c478bd9Sstevel@tonic-gate case 'a': /* encode 8 bit if available */ 2403*7c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME; 2404*7c478bd9Sstevel@tonic-gate break; 2405*7c478bd9Sstevel@tonic-gate 2406*7c478bd9Sstevel@tonic-gate case 'c': /* convert 8 bit to MIME, never 7 bit */ 2407*7c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT; 2408*7c478bd9Sstevel@tonic-gate break; 2409*7c478bd9Sstevel@tonic-gate # endif /* 0 */ 2410*7c478bd9Sstevel@tonic-gate 2411*7c478bd9Sstevel@tonic-gate default: 2412*7c478bd9Sstevel@tonic-gate syserr("Unknown 8-bit mode %c", *val); 2413*7c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 2414*7c478bd9Sstevel@tonic-gate } 2415*7c478bd9Sstevel@tonic-gate #else /* MIME8TO7 */ 2416*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 2417*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires MIME8TO7 support\n", 2418*7c478bd9Sstevel@tonic-gate OPTNAME); 2419*7c478bd9Sstevel@tonic-gate #endif /* MIME8TO7 */ 2420*7c478bd9Sstevel@tonic-gate break; 2421*7c478bd9Sstevel@tonic-gate 2422*7c478bd9Sstevel@tonic-gate case 'A': /* set default alias file */ 2423*7c478bd9Sstevel@tonic-gate if (val[0] == '\0') 2424*7c478bd9Sstevel@tonic-gate { 2425*7c478bd9Sstevel@tonic-gate char *al; 2426*7c478bd9Sstevel@tonic-gate 2427*7c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(al, "aliases"); 2428*7c478bd9Sstevel@tonic-gate setalias(al); 2429*7c478bd9Sstevel@tonic-gate } 2430*7c478bd9Sstevel@tonic-gate else 2431*7c478bd9Sstevel@tonic-gate setalias(val); 2432*7c478bd9Sstevel@tonic-gate break; 2433*7c478bd9Sstevel@tonic-gate 2434*7c478bd9Sstevel@tonic-gate case 'a': /* look N minutes for "@:@" in alias file */ 2435*7c478bd9Sstevel@tonic-gate if (val[0] == '\0') 2436*7c478bd9Sstevel@tonic-gate SafeAlias = 5 MINUTES; 2437*7c478bd9Sstevel@tonic-gate else 2438*7c478bd9Sstevel@tonic-gate SafeAlias = convtime(val, 'm'); 2439*7c478bd9Sstevel@tonic-gate break; 2440*7c478bd9Sstevel@tonic-gate 2441*7c478bd9Sstevel@tonic-gate case 'B': /* substitution for blank character */ 2442*7c478bd9Sstevel@tonic-gate SpaceSub = val[0]; 2443*7c478bd9Sstevel@tonic-gate if (SpaceSub == '\0') 2444*7c478bd9Sstevel@tonic-gate SpaceSub = ' '; 2445*7c478bd9Sstevel@tonic-gate break; 2446*7c478bd9Sstevel@tonic-gate 2447*7c478bd9Sstevel@tonic-gate case 'b': /* min blocks free on queue fs/max msg size */ 2448*7c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 2449*7c478bd9Sstevel@tonic-gate if (p != NULL) 2450*7c478bd9Sstevel@tonic-gate { 2451*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2452*7c478bd9Sstevel@tonic-gate MaxMessageSize = atol(p); 2453*7c478bd9Sstevel@tonic-gate } 2454*7c478bd9Sstevel@tonic-gate MinBlocksFree = atol(val); 2455*7c478bd9Sstevel@tonic-gate break; 2456*7c478bd9Sstevel@tonic-gate 2457*7c478bd9Sstevel@tonic-gate case 'c': /* don't connect to "expensive" mailers */ 2458*7c478bd9Sstevel@tonic-gate NoConnect = atobool(val); 2459*7c478bd9Sstevel@tonic-gate break; 2460*7c478bd9Sstevel@tonic-gate 2461*7c478bd9Sstevel@tonic-gate case 'C': /* checkpoint every N addresses */ 2462*7c478bd9Sstevel@tonic-gate if (safe || CheckpointInterval > atoi(val)) 2463*7c478bd9Sstevel@tonic-gate CheckpointInterval = atoi(val); 2464*7c478bd9Sstevel@tonic-gate break; 2465*7c478bd9Sstevel@tonic-gate 2466*7c478bd9Sstevel@tonic-gate case 'd': /* delivery mode */ 2467*7c478bd9Sstevel@tonic-gate switch (*val) 2468*7c478bd9Sstevel@tonic-gate { 2469*7c478bd9Sstevel@tonic-gate case '\0': 2470*7c478bd9Sstevel@tonic-gate set_delivery_mode(SM_DELIVER, e); 2471*7c478bd9Sstevel@tonic-gate break; 2472*7c478bd9Sstevel@tonic-gate 2473*7c478bd9Sstevel@tonic-gate case SM_QUEUE: /* queue only */ 2474*7c478bd9Sstevel@tonic-gate case SM_DEFER: /* queue only and defer map lookups */ 2475*7c478bd9Sstevel@tonic-gate case SM_DELIVER: /* do everything */ 2476*7c478bd9Sstevel@tonic-gate case SM_FORK: /* fork after verification */ 2477*7c478bd9Sstevel@tonic-gate set_delivery_mode(*val, e); 2478*7c478bd9Sstevel@tonic-gate break; 2479*7c478bd9Sstevel@tonic-gate 2480*7c478bd9Sstevel@tonic-gate default: 2481*7c478bd9Sstevel@tonic-gate syserr("Unknown delivery mode %c", *val); 2482*7c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 2483*7c478bd9Sstevel@tonic-gate } 2484*7c478bd9Sstevel@tonic-gate break; 2485*7c478bd9Sstevel@tonic-gate 2486*7c478bd9Sstevel@tonic-gate case 'E': /* error message header/header file */ 2487*7c478bd9Sstevel@tonic-gate if (*val != '\0') 2488*7c478bd9Sstevel@tonic-gate ErrMsgFile = newstr(val); 2489*7c478bd9Sstevel@tonic-gate break; 2490*7c478bd9Sstevel@tonic-gate 2491*7c478bd9Sstevel@tonic-gate case 'e': /* set error processing mode */ 2492*7c478bd9Sstevel@tonic-gate switch (*val) 2493*7c478bd9Sstevel@tonic-gate { 2494*7c478bd9Sstevel@tonic-gate case EM_QUIET: /* be silent about it */ 2495*7c478bd9Sstevel@tonic-gate case EM_MAIL: /* mail back */ 2496*7c478bd9Sstevel@tonic-gate case EM_BERKNET: /* do berknet error processing */ 2497*7c478bd9Sstevel@tonic-gate case EM_WRITE: /* write back (or mail) */ 2498*7c478bd9Sstevel@tonic-gate case EM_PRINT: /* print errors normally (default) */ 2499*7c478bd9Sstevel@tonic-gate e->e_errormode = *val; 2500*7c478bd9Sstevel@tonic-gate break; 2501*7c478bd9Sstevel@tonic-gate } 2502*7c478bd9Sstevel@tonic-gate break; 2503*7c478bd9Sstevel@tonic-gate 2504*7c478bd9Sstevel@tonic-gate case 'F': /* file mode */ 2505*7c478bd9Sstevel@tonic-gate FileMode = atooct(val) & 0777; 2506*7c478bd9Sstevel@tonic-gate break; 2507*7c478bd9Sstevel@tonic-gate 2508*7c478bd9Sstevel@tonic-gate case 'f': /* save Unix-style From lines on front */ 2509*7c478bd9Sstevel@tonic-gate SaveFrom = atobool(val); 2510*7c478bd9Sstevel@tonic-gate break; 2511*7c478bd9Sstevel@tonic-gate 2512*7c478bd9Sstevel@tonic-gate case 'G': /* match recipients against GECOS field */ 2513*7c478bd9Sstevel@tonic-gate MatchGecos = atobool(val); 2514*7c478bd9Sstevel@tonic-gate break; 2515*7c478bd9Sstevel@tonic-gate 2516*7c478bd9Sstevel@tonic-gate case 'g': /* default gid */ 2517*7c478bd9Sstevel@tonic-gate g_opt: 2518*7c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 2519*7c478bd9Sstevel@tonic-gate DefGid = atoi(val); 2520*7c478bd9Sstevel@tonic-gate else 2521*7c478bd9Sstevel@tonic-gate { 2522*7c478bd9Sstevel@tonic-gate register struct group *gr; 2523*7c478bd9Sstevel@tonic-gate 2524*7c478bd9Sstevel@tonic-gate DefGid = -1; 2525*7c478bd9Sstevel@tonic-gate gr = getgrnam(val); 2526*7c478bd9Sstevel@tonic-gate if (gr == NULL) 2527*7c478bd9Sstevel@tonic-gate syserr("readcf: option %c: unknown group %s", 2528*7c478bd9Sstevel@tonic-gate opt, val); 2529*7c478bd9Sstevel@tonic-gate else 2530*7c478bd9Sstevel@tonic-gate DefGid = gr->gr_gid; 2531*7c478bd9Sstevel@tonic-gate } 2532*7c478bd9Sstevel@tonic-gate break; 2533*7c478bd9Sstevel@tonic-gate 2534*7c478bd9Sstevel@tonic-gate case 'H': /* help file */ 2535*7c478bd9Sstevel@tonic-gate if (val[0] == '\0') 2536*7c478bd9Sstevel@tonic-gate { 2537*7c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(HelpFile, "helpfile"); 2538*7c478bd9Sstevel@tonic-gate } 2539*7c478bd9Sstevel@tonic-gate else 2540*7c478bd9Sstevel@tonic-gate { 2541*7c478bd9Sstevel@tonic-gate CANONIFY(val); 2542*7c478bd9Sstevel@tonic-gate HelpFile = newstr(val); 2543*7c478bd9Sstevel@tonic-gate } 2544*7c478bd9Sstevel@tonic-gate break; 2545*7c478bd9Sstevel@tonic-gate 2546*7c478bd9Sstevel@tonic-gate case 'h': /* maximum hop count */ 2547*7c478bd9Sstevel@tonic-gate MaxHopCount = atoi(val); 2548*7c478bd9Sstevel@tonic-gate break; 2549*7c478bd9Sstevel@tonic-gate 2550*7c478bd9Sstevel@tonic-gate case 'I': /* use internet domain name server */ 2551*7c478bd9Sstevel@tonic-gate #if NAMED_BIND 2552*7c478bd9Sstevel@tonic-gate for (p = val; *p != 0; ) 2553*7c478bd9Sstevel@tonic-gate { 2554*7c478bd9Sstevel@tonic-gate bool clearmode; 2555*7c478bd9Sstevel@tonic-gate char *q; 2556*7c478bd9Sstevel@tonic-gate struct resolverflags *rfp; 2557*7c478bd9Sstevel@tonic-gate 2558*7c478bd9Sstevel@tonic-gate while (*p == ' ') 2559*7c478bd9Sstevel@tonic-gate p++; 2560*7c478bd9Sstevel@tonic-gate if (*p == '\0') 2561*7c478bd9Sstevel@tonic-gate break; 2562*7c478bd9Sstevel@tonic-gate clearmode = false; 2563*7c478bd9Sstevel@tonic-gate if (*p == '-') 2564*7c478bd9Sstevel@tonic-gate clearmode = true; 2565*7c478bd9Sstevel@tonic-gate else if (*p != '+') 2566*7c478bd9Sstevel@tonic-gate p--; 2567*7c478bd9Sstevel@tonic-gate p++; 2568*7c478bd9Sstevel@tonic-gate q = p; 2569*7c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 2570*7c478bd9Sstevel@tonic-gate p++; 2571*7c478bd9Sstevel@tonic-gate if (*p != '\0') 2572*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2573*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "HasWildcardMX") == 0) 2574*7c478bd9Sstevel@tonic-gate { 2575*7c478bd9Sstevel@tonic-gate HasWildcardMX = !clearmode; 2576*7c478bd9Sstevel@tonic-gate continue; 2577*7c478bd9Sstevel@tonic-gate } 2578*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "WorkAroundBrokenAAAA") == 0) 2579*7c478bd9Sstevel@tonic-gate { 2580*7c478bd9Sstevel@tonic-gate WorkAroundBrokenAAAA = !clearmode; 2581*7c478bd9Sstevel@tonic-gate continue; 2582*7c478bd9Sstevel@tonic-gate } 2583*7c478bd9Sstevel@tonic-gate for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++) 2584*7c478bd9Sstevel@tonic-gate { 2585*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, rfp->rf_name) == 0) 2586*7c478bd9Sstevel@tonic-gate break; 2587*7c478bd9Sstevel@tonic-gate } 2588*7c478bd9Sstevel@tonic-gate if (rfp->rf_name == NULL) 2589*7c478bd9Sstevel@tonic-gate syserr("readcf: I option value %s unrecognized", q); 2590*7c478bd9Sstevel@tonic-gate else if (clearmode) 2591*7c478bd9Sstevel@tonic-gate _res.options &= ~rfp->rf_bits; 2592*7c478bd9Sstevel@tonic-gate else 2593*7c478bd9Sstevel@tonic-gate _res.options |= rfp->rf_bits; 2594*7c478bd9Sstevel@tonic-gate } 2595*7c478bd9Sstevel@tonic-gate if (tTd(8, 2)) 2596*7c478bd9Sstevel@tonic-gate sm_dprintf("_res.options = %x, HasWildcardMX = %d\n", 2597*7c478bd9Sstevel@tonic-gate (unsigned int) _res.options, HasWildcardMX); 2598*7c478bd9Sstevel@tonic-gate #else /* NAMED_BIND */ 2599*7c478bd9Sstevel@tonic-gate usrerr("name server (I option) specified but BIND not compiled in"); 2600*7c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 2601*7c478bd9Sstevel@tonic-gate break; 2602*7c478bd9Sstevel@tonic-gate 2603*7c478bd9Sstevel@tonic-gate case 'i': /* ignore dot lines in message */ 2604*7c478bd9Sstevel@tonic-gate IgnrDot = atobool(val); 2605*7c478bd9Sstevel@tonic-gate break; 2606*7c478bd9Sstevel@tonic-gate 2607*7c478bd9Sstevel@tonic-gate case 'j': /* send errors in MIME (RFC 1341) format */ 2608*7c478bd9Sstevel@tonic-gate SendMIMEErrors = atobool(val); 2609*7c478bd9Sstevel@tonic-gate break; 2610*7c478bd9Sstevel@tonic-gate 2611*7c478bd9Sstevel@tonic-gate case 'J': /* .forward search path */ 2612*7c478bd9Sstevel@tonic-gate CANONIFY(val); 2613*7c478bd9Sstevel@tonic-gate ForwardPath = newstr(val); 2614*7c478bd9Sstevel@tonic-gate break; 2615*7c478bd9Sstevel@tonic-gate 2616*7c478bd9Sstevel@tonic-gate case 'k': /* connection cache size */ 2617*7c478bd9Sstevel@tonic-gate MaxMciCache = atoi(val); 2618*7c478bd9Sstevel@tonic-gate if (MaxMciCache < 0) 2619*7c478bd9Sstevel@tonic-gate MaxMciCache = 0; 2620*7c478bd9Sstevel@tonic-gate break; 2621*7c478bd9Sstevel@tonic-gate 2622*7c478bd9Sstevel@tonic-gate case 'K': /* connection cache timeout */ 2623*7c478bd9Sstevel@tonic-gate MciCacheTimeout = convtime(val, 'm'); 2624*7c478bd9Sstevel@tonic-gate break; 2625*7c478bd9Sstevel@tonic-gate 2626*7c478bd9Sstevel@tonic-gate case 'l': /* use Errors-To: header */ 2627*7c478bd9Sstevel@tonic-gate UseErrorsTo = atobool(val); 2628*7c478bd9Sstevel@tonic-gate break; 2629*7c478bd9Sstevel@tonic-gate 2630*7c478bd9Sstevel@tonic-gate case 'L': /* log level */ 2631*7c478bd9Sstevel@tonic-gate if (safe || LogLevel < atoi(val)) 2632*7c478bd9Sstevel@tonic-gate LogLevel = atoi(val); 2633*7c478bd9Sstevel@tonic-gate break; 2634*7c478bd9Sstevel@tonic-gate 2635*7c478bd9Sstevel@tonic-gate case 'M': /* define macro */ 2636*7c478bd9Sstevel@tonic-gate sticky = false; 2637*7c478bd9Sstevel@tonic-gate mid = macid_parse(val, &ep); 2638*7c478bd9Sstevel@tonic-gate if (mid == 0) 2639*7c478bd9Sstevel@tonic-gate break; 2640*7c478bd9Sstevel@tonic-gate p = newstr(ep); 2641*7c478bd9Sstevel@tonic-gate if (!safe) 2642*7c478bd9Sstevel@tonic-gate cleanstrcpy(p, p, strlen(p) + 1); 2643*7c478bd9Sstevel@tonic-gate macdefine(&CurEnv->e_macro, A_TEMP, mid, p); 2644*7c478bd9Sstevel@tonic-gate break; 2645*7c478bd9Sstevel@tonic-gate 2646*7c478bd9Sstevel@tonic-gate case 'm': /* send to me too */ 2647*7c478bd9Sstevel@tonic-gate MeToo = atobool(val); 2648*7c478bd9Sstevel@tonic-gate break; 2649*7c478bd9Sstevel@tonic-gate 2650*7c478bd9Sstevel@tonic-gate case 'n': /* validate RHS in newaliases */ 2651*7c478bd9Sstevel@tonic-gate CheckAliases = atobool(val); 2652*7c478bd9Sstevel@tonic-gate break; 2653*7c478bd9Sstevel@tonic-gate 2654*7c478bd9Sstevel@tonic-gate /* 'N' available -- was "net name" */ 2655*7c478bd9Sstevel@tonic-gate 2656*7c478bd9Sstevel@tonic-gate case 'O': /* daemon options */ 2657*7c478bd9Sstevel@tonic-gate if (!setdaemonoptions(val)) 2658*7c478bd9Sstevel@tonic-gate syserr("too many daemons defined (%d max)", MAXDAEMONS); 2659*7c478bd9Sstevel@tonic-gate break; 2660*7c478bd9Sstevel@tonic-gate 2661*7c478bd9Sstevel@tonic-gate case 'o': /* assume old style headers */ 2662*7c478bd9Sstevel@tonic-gate if (atobool(val)) 2663*7c478bd9Sstevel@tonic-gate CurEnv->e_flags |= EF_OLDSTYLE; 2664*7c478bd9Sstevel@tonic-gate else 2665*7c478bd9Sstevel@tonic-gate CurEnv->e_flags &= ~EF_OLDSTYLE; 2666*7c478bd9Sstevel@tonic-gate break; 2667*7c478bd9Sstevel@tonic-gate 2668*7c478bd9Sstevel@tonic-gate case 'p': /* select privacy level */ 2669*7c478bd9Sstevel@tonic-gate p = val; 2670*7c478bd9Sstevel@tonic-gate for (;;) 2671*7c478bd9Sstevel@tonic-gate { 2672*7c478bd9Sstevel@tonic-gate register struct prival *pv; 2673*7c478bd9Sstevel@tonic-gate extern struct prival PrivacyValues[]; 2674*7c478bd9Sstevel@tonic-gate 2675*7c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 2676*7c478bd9Sstevel@tonic-gate p++; 2677*7c478bd9Sstevel@tonic-gate if (*p == '\0') 2678*7c478bd9Sstevel@tonic-gate break; 2679*7c478bd9Sstevel@tonic-gate val = p; 2680*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 2681*7c478bd9Sstevel@tonic-gate p++; 2682*7c478bd9Sstevel@tonic-gate if (*p != '\0') 2683*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2684*7c478bd9Sstevel@tonic-gate 2685*7c478bd9Sstevel@tonic-gate for (pv = PrivacyValues; pv->pv_name != NULL; pv++) 2686*7c478bd9Sstevel@tonic-gate { 2687*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, pv->pv_name) == 0) 2688*7c478bd9Sstevel@tonic-gate break; 2689*7c478bd9Sstevel@tonic-gate } 2690*7c478bd9Sstevel@tonic-gate if (pv->pv_name == NULL) 2691*7c478bd9Sstevel@tonic-gate syserr("readcf: Op line: %s unrecognized", val); 2692*7c478bd9Sstevel@tonic-gate else 2693*7c478bd9Sstevel@tonic-gate PrivacyFlags |= pv->pv_flag; 2694*7c478bd9Sstevel@tonic-gate } 2695*7c478bd9Sstevel@tonic-gate sticky = false; 2696*7c478bd9Sstevel@tonic-gate break; 2697*7c478bd9Sstevel@tonic-gate 2698*7c478bd9Sstevel@tonic-gate case 'P': /* postmaster copy address for returned mail */ 2699*7c478bd9Sstevel@tonic-gate PostMasterCopy = newstr(val); 2700*7c478bd9Sstevel@tonic-gate break; 2701*7c478bd9Sstevel@tonic-gate 2702*7c478bd9Sstevel@tonic-gate case 'q': /* slope of queue only function */ 2703*7c478bd9Sstevel@tonic-gate QueueFactor = atoi(val); 2704*7c478bd9Sstevel@tonic-gate break; 2705*7c478bd9Sstevel@tonic-gate 2706*7c478bd9Sstevel@tonic-gate case 'Q': /* queue directory */ 2707*7c478bd9Sstevel@tonic-gate if (val[0] == '\0') 2708*7c478bd9Sstevel@tonic-gate { 2709*7c478bd9Sstevel@tonic-gate QueueDir = "mqueue"; 2710*7c478bd9Sstevel@tonic-gate } 2711*7c478bd9Sstevel@tonic-gate else 2712*7c478bd9Sstevel@tonic-gate { 2713*7c478bd9Sstevel@tonic-gate QueueDir = newstr(val); 2714*7c478bd9Sstevel@tonic-gate } 2715*7c478bd9Sstevel@tonic-gate if (RealUid != 0 && !safe) 2716*7c478bd9Sstevel@tonic-gate Warn_Q_option = true; 2717*7c478bd9Sstevel@tonic-gate break; 2718*7c478bd9Sstevel@tonic-gate 2719*7c478bd9Sstevel@tonic-gate case 'R': /* don't prune routes */ 2720*7c478bd9Sstevel@tonic-gate DontPruneRoutes = atobool(val); 2721*7c478bd9Sstevel@tonic-gate break; 2722*7c478bd9Sstevel@tonic-gate 2723*7c478bd9Sstevel@tonic-gate case 'r': /* read timeout */ 2724*7c478bd9Sstevel@tonic-gate if (subopt == NULL) 2725*7c478bd9Sstevel@tonic-gate inittimeouts(val, sticky); 2726*7c478bd9Sstevel@tonic-gate else 2727*7c478bd9Sstevel@tonic-gate settimeout(subopt, val, sticky); 2728*7c478bd9Sstevel@tonic-gate break; 2729*7c478bd9Sstevel@tonic-gate 2730*7c478bd9Sstevel@tonic-gate case 'S': /* status file */ 2731*7c478bd9Sstevel@tonic-gate if (val[0] == '\0') 2732*7c478bd9Sstevel@tonic-gate { 2733*7c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(StatFile, "statistics"); 2734*7c478bd9Sstevel@tonic-gate } 2735*7c478bd9Sstevel@tonic-gate else 2736*7c478bd9Sstevel@tonic-gate { 2737*7c478bd9Sstevel@tonic-gate CANONIFY(val); 2738*7c478bd9Sstevel@tonic-gate StatFile = newstr(val); 2739*7c478bd9Sstevel@tonic-gate } 2740*7c478bd9Sstevel@tonic-gate break; 2741*7c478bd9Sstevel@tonic-gate 2742*7c478bd9Sstevel@tonic-gate case 's': /* be super safe, even if expensive */ 2743*7c478bd9Sstevel@tonic-gate if (tolower(*val) == 'i') 2744*7c478bd9Sstevel@tonic-gate SuperSafe = SAFE_INTERACTIVE; 2745*7c478bd9Sstevel@tonic-gate else if (tolower(*val) == 'p') 2746*7c478bd9Sstevel@tonic-gate #if MILTER 2747*7c478bd9Sstevel@tonic-gate SuperSafe = SAFE_REALLY_POSTMILTER; 2748*7c478bd9Sstevel@tonic-gate #else /* MILTER */ 2749*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 2750*7c478bd9Sstevel@tonic-gate "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n"); 2751*7c478bd9Sstevel@tonic-gate #endif /* MILTER */ 2752*7c478bd9Sstevel@tonic-gate else 2753*7c478bd9Sstevel@tonic-gate SuperSafe = atobool(val) ? SAFE_REALLY : SAFE_NO; 2754*7c478bd9Sstevel@tonic-gate break; 2755*7c478bd9Sstevel@tonic-gate 2756*7c478bd9Sstevel@tonic-gate case 'T': /* queue timeout */ 2757*7c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 2758*7c478bd9Sstevel@tonic-gate if (p != NULL) 2759*7c478bd9Sstevel@tonic-gate { 2760*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2761*7c478bd9Sstevel@tonic-gate settimeout("queuewarn", p, sticky); 2762*7c478bd9Sstevel@tonic-gate } 2763*7c478bd9Sstevel@tonic-gate settimeout("queuereturn", val, sticky); 2764*7c478bd9Sstevel@tonic-gate break; 2765*7c478bd9Sstevel@tonic-gate 2766*7c478bd9Sstevel@tonic-gate case 't': /* time zone name */ 2767*7c478bd9Sstevel@tonic-gate TimeZoneSpec = newstr(val); 2768*7c478bd9Sstevel@tonic-gate break; 2769*7c478bd9Sstevel@tonic-gate 2770*7c478bd9Sstevel@tonic-gate case 'U': /* location of user database */ 2771*7c478bd9Sstevel@tonic-gate UdbSpec = newstr(val); 2772*7c478bd9Sstevel@tonic-gate break; 2773*7c478bd9Sstevel@tonic-gate 2774*7c478bd9Sstevel@tonic-gate case 'u': /* set default uid */ 2775*7c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 2776*7c478bd9Sstevel@tonic-gate { 2777*7c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 2778*7c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 2779*7c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 2780*7c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 2781*7c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 2782*7c478bd9Sstevel@tonic-gate { 2783*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 2784*7c478bd9Sstevel@tonic-gate break; 2785*7c478bd9Sstevel@tonic-gate } 2786*7c478bd9Sstevel@tonic-gate } 2787*7c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 2788*7c478bd9Sstevel@tonic-gate { 2789*7c478bd9Sstevel@tonic-gate DefUid = atoi(val); 2790*7c478bd9Sstevel@tonic-gate setdefuser(); 2791*7c478bd9Sstevel@tonic-gate } 2792*7c478bd9Sstevel@tonic-gate else 2793*7c478bd9Sstevel@tonic-gate { 2794*7c478bd9Sstevel@tonic-gate register struct passwd *pw; 2795*7c478bd9Sstevel@tonic-gate 2796*7c478bd9Sstevel@tonic-gate DefUid = -1; 2797*7c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 2798*7c478bd9Sstevel@tonic-gate if (pw == NULL) 2799*7c478bd9Sstevel@tonic-gate { 2800*7c478bd9Sstevel@tonic-gate syserr("readcf: option u: unknown user %s", val); 2801*7c478bd9Sstevel@tonic-gate break; 2802*7c478bd9Sstevel@tonic-gate } 2803*7c478bd9Sstevel@tonic-gate else 2804*7c478bd9Sstevel@tonic-gate { 2805*7c478bd9Sstevel@tonic-gate DefUid = pw->pw_uid; 2806*7c478bd9Sstevel@tonic-gate DefGid = pw->pw_gid; 2807*7c478bd9Sstevel@tonic-gate DefUser = newstr(pw->pw_name); 2808*7c478bd9Sstevel@tonic-gate } 2809*7c478bd9Sstevel@tonic-gate } 2810*7c478bd9Sstevel@tonic-gate 2811*7c478bd9Sstevel@tonic-gate # ifdef UID_MAX 2812*7c478bd9Sstevel@tonic-gate if (DefUid > UID_MAX) 2813*7c478bd9Sstevel@tonic-gate { 2814*7c478bd9Sstevel@tonic-gate syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored", 2815*7c478bd9Sstevel@tonic-gate (long)DefUid, (long)UID_MAX); 2816*7c478bd9Sstevel@tonic-gate break; 2817*7c478bd9Sstevel@tonic-gate } 2818*7c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 2819*7c478bd9Sstevel@tonic-gate 2820*7c478bd9Sstevel@tonic-gate /* handle the group if it is there */ 2821*7c478bd9Sstevel@tonic-gate if (*p == '\0') 2822*7c478bd9Sstevel@tonic-gate break; 2823*7c478bd9Sstevel@tonic-gate val = p; 2824*7c478bd9Sstevel@tonic-gate goto g_opt; 2825*7c478bd9Sstevel@tonic-gate 2826*7c478bd9Sstevel@tonic-gate case 'V': /* fallback MX host */ 2827*7c478bd9Sstevel@tonic-gate if (val[0] != '\0') 2828*7c478bd9Sstevel@tonic-gate FallbackMX = newstr(val); 2829*7c478bd9Sstevel@tonic-gate break; 2830*7c478bd9Sstevel@tonic-gate 2831*7c478bd9Sstevel@tonic-gate case 'v': /* run in verbose mode */ 2832*7c478bd9Sstevel@tonic-gate Verbose = atobool(val) ? 1 : 0; 2833*7c478bd9Sstevel@tonic-gate break; 2834*7c478bd9Sstevel@tonic-gate 2835*7c478bd9Sstevel@tonic-gate case 'w': /* if we are best MX, try host directly */ 2836*7c478bd9Sstevel@tonic-gate TryNullMXList = atobool(val); 2837*7c478bd9Sstevel@tonic-gate break; 2838*7c478bd9Sstevel@tonic-gate 2839*7c478bd9Sstevel@tonic-gate /* 'W' available -- was wizard password */ 2840*7c478bd9Sstevel@tonic-gate 2841*7c478bd9Sstevel@tonic-gate case 'x': /* load avg at which to auto-queue msgs */ 2842*7c478bd9Sstevel@tonic-gate QueueLA = atoi(val); 2843*7c478bd9Sstevel@tonic-gate break; 2844*7c478bd9Sstevel@tonic-gate 2845*7c478bd9Sstevel@tonic-gate case 'X': /* load avg at which to auto-reject connections */ 2846*7c478bd9Sstevel@tonic-gate RefuseLA = atoi(val); 2847*7c478bd9Sstevel@tonic-gate break; 2848*7c478bd9Sstevel@tonic-gate 2849*7c478bd9Sstevel@tonic-gate case O_DELAY_LA: /* load avg at which to delay connections */ 2850*7c478bd9Sstevel@tonic-gate DelayLA = atoi(val); 2851*7c478bd9Sstevel@tonic-gate break; 2852*7c478bd9Sstevel@tonic-gate 2853*7c478bd9Sstevel@tonic-gate case 'y': /* work recipient factor */ 2854*7c478bd9Sstevel@tonic-gate WkRecipFact = atoi(val); 2855*7c478bd9Sstevel@tonic-gate break; 2856*7c478bd9Sstevel@tonic-gate 2857*7c478bd9Sstevel@tonic-gate case 'Y': /* fork jobs during queue runs */ 2858*7c478bd9Sstevel@tonic-gate ForkQueueRuns = atobool(val); 2859*7c478bd9Sstevel@tonic-gate break; 2860*7c478bd9Sstevel@tonic-gate 2861*7c478bd9Sstevel@tonic-gate case 'z': /* work message class factor */ 2862*7c478bd9Sstevel@tonic-gate WkClassFact = atoi(val); 2863*7c478bd9Sstevel@tonic-gate break; 2864*7c478bd9Sstevel@tonic-gate 2865*7c478bd9Sstevel@tonic-gate case 'Z': /* work time factor */ 2866*7c478bd9Sstevel@tonic-gate WkTimeFact = atoi(val); 2867*7c478bd9Sstevel@tonic-gate break; 2868*7c478bd9Sstevel@tonic-gate 2869*7c478bd9Sstevel@tonic-gate 2870*7c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_GROUP_SORTORDER 2871*7c478bd9Sstevel@tonic-gate /* coordinate this with makequeue() */ 2872*7c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_GROUP_SORTORDER */ 2873*7c478bd9Sstevel@tonic-gate case O_QUEUESORTORD: /* queue sorting order */ 2874*7c478bd9Sstevel@tonic-gate switch (*val) 2875*7c478bd9Sstevel@tonic-gate { 2876*7c478bd9Sstevel@tonic-gate case 'f': /* File Name */ 2877*7c478bd9Sstevel@tonic-gate case 'F': 2878*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYFILENAME; 2879*7c478bd9Sstevel@tonic-gate break; 2880*7c478bd9Sstevel@tonic-gate 2881*7c478bd9Sstevel@tonic-gate case 'h': /* Host first */ 2882*7c478bd9Sstevel@tonic-gate case 'H': 2883*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYHOST; 2884*7c478bd9Sstevel@tonic-gate break; 2885*7c478bd9Sstevel@tonic-gate 2886*7c478bd9Sstevel@tonic-gate case 'm': /* Modification time */ 2887*7c478bd9Sstevel@tonic-gate case 'M': 2888*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYMODTIME; 2889*7c478bd9Sstevel@tonic-gate break; 2890*7c478bd9Sstevel@tonic-gate 2891*7c478bd9Sstevel@tonic-gate case 'p': /* Priority order */ 2892*7c478bd9Sstevel@tonic-gate case 'P': 2893*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYPRIORITY; 2894*7c478bd9Sstevel@tonic-gate break; 2895*7c478bd9Sstevel@tonic-gate 2896*7c478bd9Sstevel@tonic-gate case 't': /* Submission time */ 2897*7c478bd9Sstevel@tonic-gate case 'T': 2898*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYTIME; 2899*7c478bd9Sstevel@tonic-gate break; 2900*7c478bd9Sstevel@tonic-gate 2901*7c478bd9Sstevel@tonic-gate case 'r': /* Random */ 2902*7c478bd9Sstevel@tonic-gate case 'R': 2903*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_RANDOM; 2904*7c478bd9Sstevel@tonic-gate break; 2905*7c478bd9Sstevel@tonic-gate 2906*7c478bd9Sstevel@tonic-gate #if _FFR_RHS 2907*7c478bd9Sstevel@tonic-gate case 's': /* Shuffled host name */ 2908*7c478bd9Sstevel@tonic-gate case 'S': 2909*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYSHUFFLE; 2910*7c478bd9Sstevel@tonic-gate break; 2911*7c478bd9Sstevel@tonic-gate #endif /* _FFR_RHS */ 2912*7c478bd9Sstevel@tonic-gate 2913*7c478bd9Sstevel@tonic-gate case 'n': /* none */ 2914*7c478bd9Sstevel@tonic-gate case 'N': 2915*7c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_NONE; 2916*7c478bd9Sstevel@tonic-gate break; 2917*7c478bd9Sstevel@tonic-gate 2918*7c478bd9Sstevel@tonic-gate default: 2919*7c478bd9Sstevel@tonic-gate syserr("Invalid queue sort order \"%s\"", val); 2920*7c478bd9Sstevel@tonic-gate } 2921*7c478bd9Sstevel@tonic-gate break; 2922*7c478bd9Sstevel@tonic-gate 2923*7c478bd9Sstevel@tonic-gate case O_HOSTSFILE: /* pathname of /etc/hosts file */ 2924*7c478bd9Sstevel@tonic-gate CANONIFY(val); 2925*7c478bd9Sstevel@tonic-gate HostsFile = newstr(val); 2926*7c478bd9Sstevel@tonic-gate break; 2927*7c478bd9Sstevel@tonic-gate 2928*7c478bd9Sstevel@tonic-gate case O_MQA: /* minimum queue age between deliveries */ 2929*7c478bd9Sstevel@tonic-gate MinQueueAge = convtime(val, 'm'); 2930*7c478bd9Sstevel@tonic-gate break; 2931*7c478bd9Sstevel@tonic-gate 2932*7c478bd9Sstevel@tonic-gate case O_DEFCHARSET: /* default character set for mimefying */ 2933*7c478bd9Sstevel@tonic-gate DefaultCharSet = newstr(denlstring(val, true, true)); 2934*7c478bd9Sstevel@tonic-gate break; 2935*7c478bd9Sstevel@tonic-gate 2936*7c478bd9Sstevel@tonic-gate case O_SSFILE: /* service switch file */ 2937*7c478bd9Sstevel@tonic-gate CANONIFY(val); 2938*7c478bd9Sstevel@tonic-gate ServiceSwitchFile = newstr(val); 2939*7c478bd9Sstevel@tonic-gate break; 2940*7c478bd9Sstevel@tonic-gate 2941*7c478bd9Sstevel@tonic-gate case O_DIALDELAY: /* delay for dial-on-demand operation */ 2942*7c478bd9Sstevel@tonic-gate DialDelay = convtime(val, 's'); 2943*7c478bd9Sstevel@tonic-gate break; 2944*7c478bd9Sstevel@tonic-gate 2945*7c478bd9Sstevel@tonic-gate case O_NORCPTACTION: /* what to do if no recipient */ 2946*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "none") == 0) 2947*7c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_NO_ACTION; 2948*7c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to") == 0) 2949*7c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO; 2950*7c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-apparently-to") == 0) 2951*7c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_APPARENTLY_TO; 2952*7c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-bcc") == 0) 2953*7c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_BCC; 2954*7c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to-undisclosed") == 0) 2955*7c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO_UNDISCLOSED; 2956*7c478bd9Sstevel@tonic-gate else 2957*7c478bd9Sstevel@tonic-gate syserr("Invalid NoRecipientAction: %s", val); 2958*7c478bd9Sstevel@tonic-gate break; 2959*7c478bd9Sstevel@tonic-gate 2960*7c478bd9Sstevel@tonic-gate case O_SAFEFILEENV: /* chroot() environ for writing to files */ 2961*7c478bd9Sstevel@tonic-gate if (*val == '\0') 2962*7c478bd9Sstevel@tonic-gate break; 2963*7c478bd9Sstevel@tonic-gate 2964*7c478bd9Sstevel@tonic-gate /* strip trailing slashes */ 2965*7c478bd9Sstevel@tonic-gate p = val + strlen(val) - 1; 2966*7c478bd9Sstevel@tonic-gate while (p >= val && *p == '/') 2967*7c478bd9Sstevel@tonic-gate *p-- = '\0'; 2968*7c478bd9Sstevel@tonic-gate 2969*7c478bd9Sstevel@tonic-gate if (*val == '\0') 2970*7c478bd9Sstevel@tonic-gate break; 2971*7c478bd9Sstevel@tonic-gate 2972*7c478bd9Sstevel@tonic-gate SafeFileEnv = newstr(val); 2973*7c478bd9Sstevel@tonic-gate break; 2974*7c478bd9Sstevel@tonic-gate 2975*7c478bd9Sstevel@tonic-gate case O_MAXMSGSIZE: /* maximum message size */ 2976*7c478bd9Sstevel@tonic-gate MaxMessageSize = atol(val); 2977*7c478bd9Sstevel@tonic-gate break; 2978*7c478bd9Sstevel@tonic-gate 2979*7c478bd9Sstevel@tonic-gate case O_COLONOKINADDR: /* old style handling of colon addresses */ 2980*7c478bd9Sstevel@tonic-gate ColonOkInAddr = atobool(val); 2981*7c478bd9Sstevel@tonic-gate break; 2982*7c478bd9Sstevel@tonic-gate 2983*7c478bd9Sstevel@tonic-gate case O_MAXQUEUERUN: /* max # of jobs in a single queue run */ 2984*7c478bd9Sstevel@tonic-gate MaxQueueRun = atoi(val); 2985*7c478bd9Sstevel@tonic-gate break; 2986*7c478bd9Sstevel@tonic-gate 2987*7c478bd9Sstevel@tonic-gate case O_MAXCHILDREN: /* max # of children of daemon */ 2988*7c478bd9Sstevel@tonic-gate MaxChildren = atoi(val); 2989*7c478bd9Sstevel@tonic-gate break; 2990*7c478bd9Sstevel@tonic-gate 2991*7c478bd9Sstevel@tonic-gate case O_MAXQUEUECHILDREN: /* max # of children of daemon */ 2992*7c478bd9Sstevel@tonic-gate MaxQueueChildren = atoi(val); 2993*7c478bd9Sstevel@tonic-gate break; 2994*7c478bd9Sstevel@tonic-gate 2995*7c478bd9Sstevel@tonic-gate case O_MAXRUNNERSPERQUEUE: /* max # runners in a queue group */ 2996*7c478bd9Sstevel@tonic-gate MaxRunnersPerQueue = atoi(val); 2997*7c478bd9Sstevel@tonic-gate break; 2998*7c478bd9Sstevel@tonic-gate 2999*7c478bd9Sstevel@tonic-gate case O_NICEQUEUERUN: /* nice queue runs */ 3000*7c478bd9Sstevel@tonic-gate #if !HASNICE 3001*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3002*7c478bd9Sstevel@tonic-gate "Warning: NiceQueueRun set on system that doesn't support nice()\n"); 3003*7c478bd9Sstevel@tonic-gate #endif /* !HASNICE */ 3004*7c478bd9Sstevel@tonic-gate 3005*7c478bd9Sstevel@tonic-gate /* XXX do we want to check the range? > 0 ? */ 3006*7c478bd9Sstevel@tonic-gate NiceQueueRun = atoi(val); 3007*7c478bd9Sstevel@tonic-gate break; 3008*7c478bd9Sstevel@tonic-gate 3009*7c478bd9Sstevel@tonic-gate case O_SHMKEY: /* shared memory key */ 3010*7c478bd9Sstevel@tonic-gate #if SM_CONF_SHM 3011*7c478bd9Sstevel@tonic-gate ShmKey = atol(val); 3012*7c478bd9Sstevel@tonic-gate #else /* SM_CONF_SHM */ 3013*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3014*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 3015*7c478bd9Sstevel@tonic-gate OPTNAME); 3016*7c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SHM */ 3017*7c478bd9Sstevel@tonic-gate break; 3018*7c478bd9Sstevel@tonic-gate 3019*7c478bd9Sstevel@tonic-gate #if _FFR_SELECT_SHM 3020*7c478bd9Sstevel@tonic-gate case O_SHMKEYFILE: /* shared memory key file */ 3021*7c478bd9Sstevel@tonic-gate # if SM_CONF_SHM 3022*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(ShmKeyFile); 3023*7c478bd9Sstevel@tonic-gate # else /* SM_CONF_SHM */ 3024*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3025*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 3026*7c478bd9Sstevel@tonic-gate OPTNAME); 3027*7c478bd9Sstevel@tonic-gate break; 3028*7c478bd9Sstevel@tonic-gate # endif /* SM_CONF_SHM */ 3029*7c478bd9Sstevel@tonic-gate #endif /* _FFR_SELECT_SHM */ 3030*7c478bd9Sstevel@tonic-gate 3031*7c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES 3032*7c478bd9Sstevel@tonic-gate case O_MAXFORWARD: /* max # of forward entries */ 3033*7c478bd9Sstevel@tonic-gate MaxForwardEntries = atoi(val); 3034*7c478bd9Sstevel@tonic-gate break; 3035*7c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */ 3036*7c478bd9Sstevel@tonic-gate 3037*7c478bd9Sstevel@tonic-gate case O_KEEPCNAMES: /* don't expand CNAME records */ 3038*7c478bd9Sstevel@tonic-gate DontExpandCnames = atobool(val); 3039*7c478bd9Sstevel@tonic-gate break; 3040*7c478bd9Sstevel@tonic-gate 3041*7c478bd9Sstevel@tonic-gate case O_MUSTQUOTE: /* must quote these characters in phrases */ 3042*7c478bd9Sstevel@tonic-gate (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof buf); 3043*7c478bd9Sstevel@tonic-gate if (strlen(val) < sizeof buf - 10) 3044*7c478bd9Sstevel@tonic-gate (void) sm_strlcat(buf, val, sizeof buf); 3045*7c478bd9Sstevel@tonic-gate else 3046*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3047*7c478bd9Sstevel@tonic-gate "Warning: MustQuoteChars too long, ignored.\n"); 3048*7c478bd9Sstevel@tonic-gate MustQuoteChars = newstr(buf); 3049*7c478bd9Sstevel@tonic-gate break; 3050*7c478bd9Sstevel@tonic-gate 3051*7c478bd9Sstevel@tonic-gate case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */ 3052*7c478bd9Sstevel@tonic-gate SmtpGreeting = newstr(munchstring(val, NULL, '\0')); 3053*7c478bd9Sstevel@tonic-gate break; 3054*7c478bd9Sstevel@tonic-gate 3055*7c478bd9Sstevel@tonic-gate case O_UNIXFROM: /* UNIX From_ line (old $l macro) */ 3056*7c478bd9Sstevel@tonic-gate UnixFromLine = newstr(munchstring(val, NULL, '\0')); 3057*7c478bd9Sstevel@tonic-gate break; 3058*7c478bd9Sstevel@tonic-gate 3059*7c478bd9Sstevel@tonic-gate case O_OPCHARS: /* operator characters (old $o macro) */ 3060*7c478bd9Sstevel@tonic-gate if (OperatorChars != NULL) 3061*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3062*7c478bd9Sstevel@tonic-gate "Warning: OperatorChars is being redefined.\n It should only be set before ruleset definitions.\n"); 3063*7c478bd9Sstevel@tonic-gate OperatorChars = newstr(munchstring(val, NULL, '\0')); 3064*7c478bd9Sstevel@tonic-gate break; 3065*7c478bd9Sstevel@tonic-gate 3066*7c478bd9Sstevel@tonic-gate case O_DONTINITGRPS: /* don't call initgroups(3) */ 3067*7c478bd9Sstevel@tonic-gate DontInitGroups = atobool(val); 3068*7c478bd9Sstevel@tonic-gate break; 3069*7c478bd9Sstevel@tonic-gate 3070*7c478bd9Sstevel@tonic-gate case O_SLFH: /* make sure from fits on one line */ 3071*7c478bd9Sstevel@tonic-gate SingleLineFromHeader = atobool(val); 3072*7c478bd9Sstevel@tonic-gate break; 3073*7c478bd9Sstevel@tonic-gate 3074*7c478bd9Sstevel@tonic-gate case O_ABH: /* allow HELO commands with syntax errors */ 3075*7c478bd9Sstevel@tonic-gate AllowBogusHELO = atobool(val); 3076*7c478bd9Sstevel@tonic-gate break; 3077*7c478bd9Sstevel@tonic-gate 3078*7c478bd9Sstevel@tonic-gate case O_CONNTHROT: /* connection rate throttle */ 3079*7c478bd9Sstevel@tonic-gate ConnRateThrottle = atoi(val); 3080*7c478bd9Sstevel@tonic-gate break; 3081*7c478bd9Sstevel@tonic-gate 3082*7c478bd9Sstevel@tonic-gate case O_UGW: /* group writable files are unsafe */ 3083*7c478bd9Sstevel@tonic-gate if (!atobool(val)) 3084*7c478bd9Sstevel@tonic-gate { 3085*7c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEFORWARDFILESAFE, 3086*7c478bd9Sstevel@tonic-gate DontBlameSendmail); 3087*7c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEINCLUDEFILESAFE, 3088*7c478bd9Sstevel@tonic-gate DontBlameSendmail); 3089*7c478bd9Sstevel@tonic-gate } 3090*7c478bd9Sstevel@tonic-gate break; 3091*7c478bd9Sstevel@tonic-gate 3092*7c478bd9Sstevel@tonic-gate case O_DBLBOUNCE: /* address to which to send double bounces */ 3093*7c478bd9Sstevel@tonic-gate DoubleBounceAddr = newstr(val); 3094*7c478bd9Sstevel@tonic-gate break; 3095*7c478bd9Sstevel@tonic-gate 3096*7c478bd9Sstevel@tonic-gate case O_HSDIR: /* persistent host status directory */ 3097*7c478bd9Sstevel@tonic-gate if (val[0] != '\0') 3098*7c478bd9Sstevel@tonic-gate { 3099*7c478bd9Sstevel@tonic-gate CANONIFY(val); 3100*7c478bd9Sstevel@tonic-gate HostStatDir = newstr(val); 3101*7c478bd9Sstevel@tonic-gate } 3102*7c478bd9Sstevel@tonic-gate break; 3103*7c478bd9Sstevel@tonic-gate 3104*7c478bd9Sstevel@tonic-gate case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */ 3105*7c478bd9Sstevel@tonic-gate SingleThreadDelivery = atobool(val); 3106*7c478bd9Sstevel@tonic-gate break; 3107*7c478bd9Sstevel@tonic-gate 3108*7c478bd9Sstevel@tonic-gate case O_RUNASUSER: /* run bulk of code as this user */ 3109*7c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 3110*7c478bd9Sstevel@tonic-gate { 3111*7c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 3112*7c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 3113*7c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 3114*7c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 3115*7c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 3116*7c478bd9Sstevel@tonic-gate { 3117*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3118*7c478bd9Sstevel@tonic-gate break; 3119*7c478bd9Sstevel@tonic-gate } 3120*7c478bd9Sstevel@tonic-gate } 3121*7c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 3122*7c478bd9Sstevel@tonic-gate { 3123*7c478bd9Sstevel@tonic-gate if (can_setuid) 3124*7c478bd9Sstevel@tonic-gate RunAsUid = atoi(val); 3125*7c478bd9Sstevel@tonic-gate } 3126*7c478bd9Sstevel@tonic-gate else 3127*7c478bd9Sstevel@tonic-gate { 3128*7c478bd9Sstevel@tonic-gate register struct passwd *pw; 3129*7c478bd9Sstevel@tonic-gate 3130*7c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 3131*7c478bd9Sstevel@tonic-gate if (pw == NULL) 3132*7c478bd9Sstevel@tonic-gate { 3133*7c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown user %s", val); 3134*7c478bd9Sstevel@tonic-gate break; 3135*7c478bd9Sstevel@tonic-gate } 3136*7c478bd9Sstevel@tonic-gate else if (can_setuid) 3137*7c478bd9Sstevel@tonic-gate { 3138*7c478bd9Sstevel@tonic-gate if (*p == '\0') 3139*7c478bd9Sstevel@tonic-gate RunAsUserName = newstr(val); 3140*7c478bd9Sstevel@tonic-gate RunAsUid = pw->pw_uid; 3141*7c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 3142*7c478bd9Sstevel@tonic-gate } 3143*7c478bd9Sstevel@tonic-gate else if (EffGid == pw->pw_gid) 3144*7c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 3145*7c478bd9Sstevel@tonic-gate else if (UseMSP && *p == '\0') 3146*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3147*7c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 3148*7c478bd9Sstevel@tonic-gate (int) EffGid, 3149*7c478bd9Sstevel@tonic-gate (int) pw->pw_gid); 3150*7c478bd9Sstevel@tonic-gate } 3151*7c478bd9Sstevel@tonic-gate # ifdef UID_MAX 3152*7c478bd9Sstevel@tonic-gate if (RunAsUid > UID_MAX) 3153*7c478bd9Sstevel@tonic-gate { 3154*7c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored", 3155*7c478bd9Sstevel@tonic-gate (long) RunAsUid, (long) UID_MAX); 3156*7c478bd9Sstevel@tonic-gate break; 3157*7c478bd9Sstevel@tonic-gate } 3158*7c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 3159*7c478bd9Sstevel@tonic-gate if (*p != '\0') 3160*7c478bd9Sstevel@tonic-gate { 3161*7c478bd9Sstevel@tonic-gate if (isascii(*p) && isdigit(*p)) 3162*7c478bd9Sstevel@tonic-gate { 3163*7c478bd9Sstevel@tonic-gate gid_t runasgid; 3164*7c478bd9Sstevel@tonic-gate 3165*7c478bd9Sstevel@tonic-gate runasgid = (gid_t) atoi(p); 3166*7c478bd9Sstevel@tonic-gate if (can_setuid || EffGid == runasgid) 3167*7c478bd9Sstevel@tonic-gate RunAsGid = runasgid; 3168*7c478bd9Sstevel@tonic-gate else if (UseMSP) 3169*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 3170*7c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 3171*7c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 3172*7c478bd9Sstevel@tonic-gate (int) EffGid, 3173*7c478bd9Sstevel@tonic-gate (int) runasgid); 3174*7c478bd9Sstevel@tonic-gate } 3175*7c478bd9Sstevel@tonic-gate else 3176*7c478bd9Sstevel@tonic-gate { 3177*7c478bd9Sstevel@tonic-gate register struct group *gr; 3178*7c478bd9Sstevel@tonic-gate 3179*7c478bd9Sstevel@tonic-gate gr = getgrnam(p); 3180*7c478bd9Sstevel@tonic-gate if (gr == NULL) 3181*7c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown group %s", 3182*7c478bd9Sstevel@tonic-gate p); 3183*7c478bd9Sstevel@tonic-gate else if (can_setuid || EffGid == gr->gr_gid) 3184*7c478bd9Sstevel@tonic-gate RunAsGid = gr->gr_gid; 3185*7c478bd9Sstevel@tonic-gate else if (UseMSP) 3186*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 3187*7c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 3188*7c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 3189*7c478bd9Sstevel@tonic-gate (int) EffGid, 3190*7c478bd9Sstevel@tonic-gate (int) gr->gr_gid); 3191*7c478bd9Sstevel@tonic-gate } 3192*7c478bd9Sstevel@tonic-gate } 3193*7c478bd9Sstevel@tonic-gate if (tTd(47, 5)) 3194*7c478bd9Sstevel@tonic-gate sm_dprintf("readcf: RunAsUser = %d:%d\n", 3195*7c478bd9Sstevel@tonic-gate (int) RunAsUid, (int) RunAsGid); 3196*7c478bd9Sstevel@tonic-gate break; 3197*7c478bd9Sstevel@tonic-gate 3198*7c478bd9Sstevel@tonic-gate case O_DSN_RRT: 3199*7c478bd9Sstevel@tonic-gate RrtImpliesDsn = atobool(val); 3200*7c478bd9Sstevel@tonic-gate break; 3201*7c478bd9Sstevel@tonic-gate 3202*7c478bd9Sstevel@tonic-gate case O_PIDFILE: 3203*7c478bd9Sstevel@tonic-gate PSTRSET(PidFile, val); 3204*7c478bd9Sstevel@tonic-gate break; 3205*7c478bd9Sstevel@tonic-gate 3206*7c478bd9Sstevel@tonic-gate case O_DONTBLAMESENDMAIL: 3207*7c478bd9Sstevel@tonic-gate p = val; 3208*7c478bd9Sstevel@tonic-gate for (;;) 3209*7c478bd9Sstevel@tonic-gate { 3210*7c478bd9Sstevel@tonic-gate register struct dbsval *dbs; 3211*7c478bd9Sstevel@tonic-gate extern struct dbsval DontBlameSendmailValues[]; 3212*7c478bd9Sstevel@tonic-gate 3213*7c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 3214*7c478bd9Sstevel@tonic-gate p++; 3215*7c478bd9Sstevel@tonic-gate if (*p == '\0') 3216*7c478bd9Sstevel@tonic-gate break; 3217*7c478bd9Sstevel@tonic-gate val = p; 3218*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 3219*7c478bd9Sstevel@tonic-gate p++; 3220*7c478bd9Sstevel@tonic-gate if (*p != '\0') 3221*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3222*7c478bd9Sstevel@tonic-gate 3223*7c478bd9Sstevel@tonic-gate for (dbs = DontBlameSendmailValues; 3224*7c478bd9Sstevel@tonic-gate dbs->dbs_name != NULL; dbs++) 3225*7c478bd9Sstevel@tonic-gate { 3226*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, dbs->dbs_name) == 0) 3227*7c478bd9Sstevel@tonic-gate break; 3228*7c478bd9Sstevel@tonic-gate } 3229*7c478bd9Sstevel@tonic-gate if (dbs->dbs_name == NULL) 3230*7c478bd9Sstevel@tonic-gate syserr("readcf: DontBlameSendmail option: %s unrecognized", val); 3231*7c478bd9Sstevel@tonic-gate else if (dbs->dbs_flag == DBS_SAFE) 3232*7c478bd9Sstevel@tonic-gate clrbitmap(DontBlameSendmail); 3233*7c478bd9Sstevel@tonic-gate else 3234*7c478bd9Sstevel@tonic-gate setbitn(dbs->dbs_flag, DontBlameSendmail); 3235*7c478bd9Sstevel@tonic-gate } 3236*7c478bd9Sstevel@tonic-gate sticky = false; 3237*7c478bd9Sstevel@tonic-gate break; 3238*7c478bd9Sstevel@tonic-gate 3239*7c478bd9Sstevel@tonic-gate case O_DPI: 3240*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "loopback") == 0) 3241*7c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_SKIPLOOPBACK; 3242*7c478bd9Sstevel@tonic-gate else if (atobool(val)) 3243*7c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBENONE; 3244*7c478bd9Sstevel@tonic-gate else 3245*7c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBEALL; 3246*7c478bd9Sstevel@tonic-gate break; 3247*7c478bd9Sstevel@tonic-gate 3248*7c478bd9Sstevel@tonic-gate case O_MAXRCPT: 3249*7c478bd9Sstevel@tonic-gate MaxRcptPerMsg = atoi(val); 3250*7c478bd9Sstevel@tonic-gate break; 3251*7c478bd9Sstevel@tonic-gate 3252*7c478bd9Sstevel@tonic-gate case O_RCPTTHROT: 3253*7c478bd9Sstevel@tonic-gate BadRcptThrottle = atoi(val); 3254*7c478bd9Sstevel@tonic-gate break; 3255*7c478bd9Sstevel@tonic-gate 3256*7c478bd9Sstevel@tonic-gate case O_DEADLETTER: 3257*7c478bd9Sstevel@tonic-gate CANONIFY(val); 3258*7c478bd9Sstevel@tonic-gate PSTRSET(DeadLetterDrop, val); 3259*7c478bd9Sstevel@tonic-gate break; 3260*7c478bd9Sstevel@tonic-gate 3261*7c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION 3262*7c478bd9Sstevel@tonic-gate case O_DONTLOCK: 3263*7c478bd9Sstevel@tonic-gate DontLockReadFiles = atobool(val); 3264*7c478bd9Sstevel@tonic-gate break; 3265*7c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ 3266*7c478bd9Sstevel@tonic-gate 3267*7c478bd9Sstevel@tonic-gate case O_MAXALIASRCSN: 3268*7c478bd9Sstevel@tonic-gate MaxAliasRecursion = atoi(val); 3269*7c478bd9Sstevel@tonic-gate break; 3270*7c478bd9Sstevel@tonic-gate 3271*7c478bd9Sstevel@tonic-gate case O_CNCTONLYTO: 3272*7c478bd9Sstevel@tonic-gate /* XXX should probably use gethostbyname */ 3273*7c478bd9Sstevel@tonic-gate #if NETINET || NETINET6 3274*7c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_UNSPEC; 3275*7c478bd9Sstevel@tonic-gate # if NETINET6 3276*7c478bd9Sstevel@tonic-gate if (anynet_pton(AF_INET6, val, 3277*7c478bd9Sstevel@tonic-gate &ConnectOnlyTo.sin6.sin6_addr) != 1) 3278*7c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET6; 3279*7c478bd9Sstevel@tonic-gate else 3280*7c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 3281*7c478bd9Sstevel@tonic-gate # if NETINET 3282*7c478bd9Sstevel@tonic-gate { 3283*7c478bd9Sstevel@tonic-gate ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val); 3284*7c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sin.sin_addr.s_addr != INADDR_NONE) 3285*7c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET; 3286*7c478bd9Sstevel@tonic-gate } 3287*7c478bd9Sstevel@tonic-gate 3288*7c478bd9Sstevel@tonic-gate # endif /* NETINET */ 3289*7c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sa.sa_family == AF_UNSPEC) 3290*7c478bd9Sstevel@tonic-gate { 3291*7c478bd9Sstevel@tonic-gate syserr("readcf: option ConnectOnlyTo: invalid IP address %s", 3292*7c478bd9Sstevel@tonic-gate val); 3293*7c478bd9Sstevel@tonic-gate break; 3294*7c478bd9Sstevel@tonic-gate } 3295*7c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */ 3296*7c478bd9Sstevel@tonic-gate break; 3297*7c478bd9Sstevel@tonic-gate 3298*7c478bd9Sstevel@tonic-gate case O_TRUSTUSER: 3299*7c478bd9Sstevel@tonic-gate # if !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) 3300*7c478bd9Sstevel@tonic-gate if (!UseMSP) 3301*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3302*7c478bd9Sstevel@tonic-gate "readcf: option TrustedUser may cause problems on systems\n which do not support fchown() if UseMSP is not set.\n"); 3303*7c478bd9Sstevel@tonic-gate # endif /* !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) */ 3304*7c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 3305*7c478bd9Sstevel@tonic-gate TrustedUid = atoi(val); 3306*7c478bd9Sstevel@tonic-gate else 3307*7c478bd9Sstevel@tonic-gate { 3308*7c478bd9Sstevel@tonic-gate register struct passwd *pw; 3309*7c478bd9Sstevel@tonic-gate 3310*7c478bd9Sstevel@tonic-gate TrustedUid = 0; 3311*7c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 3312*7c478bd9Sstevel@tonic-gate if (pw == NULL) 3313*7c478bd9Sstevel@tonic-gate { 3314*7c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: unknown user %s", val); 3315*7c478bd9Sstevel@tonic-gate break; 3316*7c478bd9Sstevel@tonic-gate } 3317*7c478bd9Sstevel@tonic-gate else 3318*7c478bd9Sstevel@tonic-gate TrustedUid = pw->pw_uid; 3319*7c478bd9Sstevel@tonic-gate } 3320*7c478bd9Sstevel@tonic-gate 3321*7c478bd9Sstevel@tonic-gate # ifdef UID_MAX 3322*7c478bd9Sstevel@tonic-gate if (TrustedUid > UID_MAX) 3323*7c478bd9Sstevel@tonic-gate { 3324*7c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)", 3325*7c478bd9Sstevel@tonic-gate (long) TrustedUid, (long) UID_MAX); 3326*7c478bd9Sstevel@tonic-gate TrustedUid = 0; 3327*7c478bd9Sstevel@tonic-gate } 3328*7c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 3329*7c478bd9Sstevel@tonic-gate break; 3330*7c478bd9Sstevel@tonic-gate 3331*7c478bd9Sstevel@tonic-gate case O_MAXMIMEHDRLEN: 3332*7c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 3333*7c478bd9Sstevel@tonic-gate if (p != NULL) 3334*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3335*7c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = atoi(val); 3336*7c478bd9Sstevel@tonic-gate if (p != NULL && *p != '\0') 3337*7c478bd9Sstevel@tonic-gate MaxMimeFieldLength = atoi(p); 3338*7c478bd9Sstevel@tonic-gate else 3339*7c478bd9Sstevel@tonic-gate MaxMimeFieldLength = MaxMimeHeaderLength / 2; 3340*7c478bd9Sstevel@tonic-gate 3341*7c478bd9Sstevel@tonic-gate if (MaxMimeHeaderLength <= 0) 3342*7c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = 0; 3343*7c478bd9Sstevel@tonic-gate else if (MaxMimeHeaderLength < 128) 3344*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3345*7c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: header length limit set lower than 128\n"); 3346*7c478bd9Sstevel@tonic-gate 3347*7c478bd9Sstevel@tonic-gate if (MaxMimeFieldLength <= 0) 3348*7c478bd9Sstevel@tonic-gate MaxMimeFieldLength = 0; 3349*7c478bd9Sstevel@tonic-gate else if (MaxMimeFieldLength < 40) 3350*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3351*7c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: field length limit set lower than 40\n"); 3352*7c478bd9Sstevel@tonic-gate break; 3353*7c478bd9Sstevel@tonic-gate 3354*7c478bd9Sstevel@tonic-gate case O_CONTROLSOCKET: 3355*7c478bd9Sstevel@tonic-gate PSTRSET(ControlSocketName, val); 3356*7c478bd9Sstevel@tonic-gate break; 3357*7c478bd9Sstevel@tonic-gate 3358*7c478bd9Sstevel@tonic-gate case O_MAXHDRSLEN: 3359*7c478bd9Sstevel@tonic-gate MaxHeadersLength = atoi(val); 3360*7c478bd9Sstevel@tonic-gate 3361*7c478bd9Sstevel@tonic-gate if (MaxHeadersLength > 0 && 3362*7c478bd9Sstevel@tonic-gate MaxHeadersLength < (MAXHDRSLEN / 2)) 3363*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3364*7c478bd9Sstevel@tonic-gate "Warning: MaxHeadersLength: headers length limit set lower than %d\n", 3365*7c478bd9Sstevel@tonic-gate (MAXHDRSLEN / 2)); 3366*7c478bd9Sstevel@tonic-gate break; 3367*7c478bd9Sstevel@tonic-gate 3368*7c478bd9Sstevel@tonic-gate case O_PROCTITLEPREFIX: 3369*7c478bd9Sstevel@tonic-gate PSTRSET(ProcTitlePrefix, val); 3370*7c478bd9Sstevel@tonic-gate break; 3371*7c478bd9Sstevel@tonic-gate 3372*7c478bd9Sstevel@tonic-gate #if SASL 3373*7c478bd9Sstevel@tonic-gate case O_SASLINFO: 3374*7c478bd9Sstevel@tonic-gate # if _FFR_ALLOW_SASLINFO 3375*7c478bd9Sstevel@tonic-gate /* 3376*7c478bd9Sstevel@tonic-gate ** Allow users to select their own authinfo file 3377*7c478bd9Sstevel@tonic-gate ** under certain circumstances, otherwise just ignore 3378*7c478bd9Sstevel@tonic-gate ** the option. If the option isn't ignored, several 3379*7c478bd9Sstevel@tonic-gate ** commands don't work very well, e.g., mailq. 3380*7c478bd9Sstevel@tonic-gate ** However, this is not a "perfect" solution. 3381*7c478bd9Sstevel@tonic-gate ** If mail is queued, the authentication info 3382*7c478bd9Sstevel@tonic-gate ** will not be used in subsequent delivery attempts. 3383*7c478bd9Sstevel@tonic-gate ** If we really want to support this, then it has 3384*7c478bd9Sstevel@tonic-gate ** to be stored in the queue file. 3385*7c478bd9Sstevel@tonic-gate */ 3386*7c478bd9Sstevel@tonic-gate if (!bitset(SUBMIT_MSA, SubmitMode) && RealUid != 0 && 3387*7c478bd9Sstevel@tonic-gate RunAsUid != RealUid) 3388*7c478bd9Sstevel@tonic-gate break; 3389*7c478bd9Sstevel@tonic-gate # endif /* _FFR_ALLOW_SASLINFO */ 3390*7c478bd9Sstevel@tonic-gate PSTRSET(SASLInfo, val); 3391*7c478bd9Sstevel@tonic-gate break; 3392*7c478bd9Sstevel@tonic-gate 3393*7c478bd9Sstevel@tonic-gate case O_SASLMECH: 3394*7c478bd9Sstevel@tonic-gate if (AuthMechanisms != NULL) 3395*7c478bd9Sstevel@tonic-gate sm_free(AuthMechanisms); /* XXX */ 3396*7c478bd9Sstevel@tonic-gate if (*val != '\0') 3397*7c478bd9Sstevel@tonic-gate AuthMechanisms = newstr(val); 3398*7c478bd9Sstevel@tonic-gate else 3399*7c478bd9Sstevel@tonic-gate AuthMechanisms = NULL; 3400*7c478bd9Sstevel@tonic-gate break; 3401*7c478bd9Sstevel@tonic-gate 3402*7c478bd9Sstevel@tonic-gate case O_SASLREALM: 3403*7c478bd9Sstevel@tonic-gate if (AuthRealm != NULL) 3404*7c478bd9Sstevel@tonic-gate sm_free(AuthRealm); 3405*7c478bd9Sstevel@tonic-gate if (*val != '\0') 3406*7c478bd9Sstevel@tonic-gate AuthRealm = newstr(val); 3407*7c478bd9Sstevel@tonic-gate else 3408*7c478bd9Sstevel@tonic-gate AuthRealm = NULL; 3409*7c478bd9Sstevel@tonic-gate break; 3410*7c478bd9Sstevel@tonic-gate 3411*7c478bd9Sstevel@tonic-gate case O_SASLOPTS: 3412*7c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 3413*7c478bd9Sstevel@tonic-gate { 3414*7c478bd9Sstevel@tonic-gate switch (*val) 3415*7c478bd9Sstevel@tonic-gate { 3416*7c478bd9Sstevel@tonic-gate case 'A': 3417*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_AUTH_AUTH; 3418*7c478bd9Sstevel@tonic-gate break; 3419*7c478bd9Sstevel@tonic-gate 3420*7c478bd9Sstevel@tonic-gate case 'a': 3421*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOACTIVE; 3422*7c478bd9Sstevel@tonic-gate break; 3423*7c478bd9Sstevel@tonic-gate 3424*7c478bd9Sstevel@tonic-gate case 'c': 3425*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_PASS_CREDENTIALS; 3426*7c478bd9Sstevel@tonic-gate break; 3427*7c478bd9Sstevel@tonic-gate 3428*7c478bd9Sstevel@tonic-gate case 'd': 3429*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NODICTIONARY; 3430*7c478bd9Sstevel@tonic-gate break; 3431*7c478bd9Sstevel@tonic-gate 3432*7c478bd9Sstevel@tonic-gate case 'f': 3433*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_FORWARD_SECRECY; 3434*7c478bd9Sstevel@tonic-gate break; 3435*7c478bd9Sstevel@tonic-gate 3436*7c478bd9Sstevel@tonic-gate # if SASL >= 20101 3437*7c478bd9Sstevel@tonic-gate case 'm': 3438*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_MUTUAL_AUTH; 3439*7c478bd9Sstevel@tonic-gate break; 3440*7c478bd9Sstevel@tonic-gate # endif /* SASL >= 20101 */ 3441*7c478bd9Sstevel@tonic-gate 3442*7c478bd9Sstevel@tonic-gate case 'p': 3443*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOPLAINTEXT; 3444*7c478bd9Sstevel@tonic-gate break; 3445*7c478bd9Sstevel@tonic-gate 3446*7c478bd9Sstevel@tonic-gate case 'y': 3447*7c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOANONYMOUS; 3448*7c478bd9Sstevel@tonic-gate break; 3449*7c478bd9Sstevel@tonic-gate 3450*7c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 3451*7c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 3452*7c478bd9Sstevel@tonic-gate case ',': /* ignore */ 3453*7c478bd9Sstevel@tonic-gate break; 3454*7c478bd9Sstevel@tonic-gate 3455*7c478bd9Sstevel@tonic-gate default: 3456*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3457*7c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 3458*7c478bd9Sstevel@tonic-gate OPTNAME, 3459*7c478bd9Sstevel@tonic-gate (isascii(*val) && 3460*7c478bd9Sstevel@tonic-gate isprint(*val)) 3461*7c478bd9Sstevel@tonic-gate ? *val : '?'); 3462*7c478bd9Sstevel@tonic-gate break; 3463*7c478bd9Sstevel@tonic-gate } 3464*7c478bd9Sstevel@tonic-gate ++val; 3465*7c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 3466*7c478bd9Sstevel@tonic-gate if (val != NULL) 3467*7c478bd9Sstevel@tonic-gate ++val; 3468*7c478bd9Sstevel@tonic-gate } 3469*7c478bd9Sstevel@tonic-gate break; 3470*7c478bd9Sstevel@tonic-gate 3471*7c478bd9Sstevel@tonic-gate case O_SASLBITS: 3472*7c478bd9Sstevel@tonic-gate MaxSLBits = atoi(val); 3473*7c478bd9Sstevel@tonic-gate break; 3474*7c478bd9Sstevel@tonic-gate 3475*7c478bd9Sstevel@tonic-gate #else /* SASL */ 3476*7c478bd9Sstevel@tonic-gate case O_SASLINFO: 3477*7c478bd9Sstevel@tonic-gate case O_SASLMECH: 3478*7c478bd9Sstevel@tonic-gate case O_SASLREALM: 3479*7c478bd9Sstevel@tonic-gate case O_SASLOPTS: 3480*7c478bd9Sstevel@tonic-gate case O_SASLBITS: 3481*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3482*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires SASL support (-DSASL)\n", 3483*7c478bd9Sstevel@tonic-gate OPTNAME); 3484*7c478bd9Sstevel@tonic-gate break; 3485*7c478bd9Sstevel@tonic-gate #endif /* SASL */ 3486*7c478bd9Sstevel@tonic-gate 3487*7c478bd9Sstevel@tonic-gate #if STARTTLS 3488*7c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 3489*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvCertFile); 3490*7c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 3491*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvKeyFile); 3492*7c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 3493*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltCertFile); 3494*7c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 3495*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltKeyFile); 3496*7c478bd9Sstevel@tonic-gate case O_CACERTFILE: 3497*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertFile); 3498*7c478bd9Sstevel@tonic-gate case O_CACERTPATH: 3499*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertPath); 3500*7c478bd9Sstevel@tonic-gate case O_DHPARAMS: 3501*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams); 3502*7c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 3503*7c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 3504*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams5); 3505*7c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 3506*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CipherList); 3507*7c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 3508*7c478bd9Sstevel@tonic-gate case O_CRLFILE: 3509*7c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 3510*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLFile); 3511*7c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 3512*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3513*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 3514*7c478bd9Sstevel@tonic-gate OPTNAME); 3515*7c478bd9Sstevel@tonic-gate break; 3516*7c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 3517*7c478bd9Sstevel@tonic-gate 3518*7c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 3519*7c478bd9Sstevel@tonic-gate case O_CRLPATH: 3520*7c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 3521*7c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLPath); 3522*7c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 3523*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3524*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 3525*7c478bd9Sstevel@tonic-gate OPTNAME); 3526*7c478bd9Sstevel@tonic-gate break; 3527*7c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 3528*7c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 3529*7c478bd9Sstevel@tonic-gate 3530*7c478bd9Sstevel@tonic-gate /* 3531*7c478bd9Sstevel@tonic-gate ** XXX How about options per daemon/client instead of globally? 3532*7c478bd9Sstevel@tonic-gate ** This doesn't work well for some options, e.g., no server cert, 3533*7c478bd9Sstevel@tonic-gate ** but fine for others. 3534*7c478bd9Sstevel@tonic-gate ** 3535*7c478bd9Sstevel@tonic-gate ** XXX Some people may want different certs per server. 3536*7c478bd9Sstevel@tonic-gate ** 3537*7c478bd9Sstevel@tonic-gate ** See also srvfeatures() 3538*7c478bd9Sstevel@tonic-gate */ 3539*7c478bd9Sstevel@tonic-gate 3540*7c478bd9Sstevel@tonic-gate case O_TLS_SRV_OPTS: 3541*7c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 3542*7c478bd9Sstevel@tonic-gate { 3543*7c478bd9Sstevel@tonic-gate switch (*val) 3544*7c478bd9Sstevel@tonic-gate { 3545*7c478bd9Sstevel@tonic-gate case 'V': 3546*7c478bd9Sstevel@tonic-gate TLS_Srv_Opts |= TLS_I_NO_VRFY; 3547*7c478bd9Sstevel@tonic-gate break; 3548*7c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 3549*7c478bd9Sstevel@tonic-gate /* 3550*7c478bd9Sstevel@tonic-gate ** Server without a cert? That works only if 3551*7c478bd9Sstevel@tonic-gate ** AnonDH is enabled as cipher, which is not in the 3552*7c478bd9Sstevel@tonic-gate ** default list. Hence the CipherList option must 3553*7c478bd9Sstevel@tonic-gate ** be available. Moreover: which clients support this 3554*7c478bd9Sstevel@tonic-gate ** besides sendmail with this setting? 3555*7c478bd9Sstevel@tonic-gate */ 3556*7c478bd9Sstevel@tonic-gate 3557*7c478bd9Sstevel@tonic-gate case 'C': 3558*7c478bd9Sstevel@tonic-gate TLS_Srv_Opts &= ~TLS_I_SRV_CERT; 3559*7c478bd9Sstevel@tonic-gate break; 3560*7c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 3561*7c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 3562*7c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 3563*7c478bd9Sstevel@tonic-gate case ',': /* ignore */ 3564*7c478bd9Sstevel@tonic-gate break; 3565*7c478bd9Sstevel@tonic-gate default: 3566*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3567*7c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 3568*7c478bd9Sstevel@tonic-gate OPTNAME, 3569*7c478bd9Sstevel@tonic-gate (isascii(*val) && 3570*7c478bd9Sstevel@tonic-gate isprint(*val)) 3571*7c478bd9Sstevel@tonic-gate ? *val : '?'); 3572*7c478bd9Sstevel@tonic-gate break; 3573*7c478bd9Sstevel@tonic-gate } 3574*7c478bd9Sstevel@tonic-gate ++val; 3575*7c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 3576*7c478bd9Sstevel@tonic-gate if (val != NULL) 3577*7c478bd9Sstevel@tonic-gate ++val; 3578*7c478bd9Sstevel@tonic-gate } 3579*7c478bd9Sstevel@tonic-gate break; 3580*7c478bd9Sstevel@tonic-gate 3581*7c478bd9Sstevel@tonic-gate case O_RANDFILE: 3582*7c478bd9Sstevel@tonic-gate PSTRSET(RandFile, val); 3583*7c478bd9Sstevel@tonic-gate break; 3584*7c478bd9Sstevel@tonic-gate 3585*7c478bd9Sstevel@tonic-gate #else /* STARTTLS */ 3586*7c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 3587*7c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 3588*7c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 3589*7c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 3590*7c478bd9Sstevel@tonic-gate case O_CACERTFILE: 3591*7c478bd9Sstevel@tonic-gate case O_CACERTPATH: 3592*7c478bd9Sstevel@tonic-gate case O_DHPARAMS: 3593*7c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 3594*7c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 3595*7c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 3596*7c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 3597*7c478bd9Sstevel@tonic-gate case O_CRLFILE: 3598*7c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 3599*7c478bd9Sstevel@tonic-gate case O_CRLPATH: 3600*7c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 3601*7c478bd9Sstevel@tonic-gate case O_RANDFILE: 3602*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3603*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires TLS support\n", 3604*7c478bd9Sstevel@tonic-gate OPTNAME); 3605*7c478bd9Sstevel@tonic-gate break; 3606*7c478bd9Sstevel@tonic-gate 3607*7c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 3608*7c478bd9Sstevel@tonic-gate 3609*7c478bd9Sstevel@tonic-gate case O_CLIENTPORT: 3610*7c478bd9Sstevel@tonic-gate setclientoptions(val); 3611*7c478bd9Sstevel@tonic-gate break; 3612*7c478bd9Sstevel@tonic-gate 3613*7c478bd9Sstevel@tonic-gate case O_DF_BUFSIZE: 3614*7c478bd9Sstevel@tonic-gate DataFileBufferSize = atoi(val); 3615*7c478bd9Sstevel@tonic-gate break; 3616*7c478bd9Sstevel@tonic-gate 3617*7c478bd9Sstevel@tonic-gate case O_XF_BUFSIZE: 3618*7c478bd9Sstevel@tonic-gate XscriptFileBufferSize = atoi(val); 3619*7c478bd9Sstevel@tonic-gate break; 3620*7c478bd9Sstevel@tonic-gate 3621*7c478bd9Sstevel@tonic-gate case O_LDAPDEFAULTSPEC: 3622*7c478bd9Sstevel@tonic-gate #if LDAPMAP 3623*7c478bd9Sstevel@tonic-gate ldapmap_set_defaults(val); 3624*7c478bd9Sstevel@tonic-gate #else /* LDAPMAP */ 3625*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3626*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires LDAP support (-DLDAPMAP)\n", 3627*7c478bd9Sstevel@tonic-gate OPTNAME); 3628*7c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 3629*7c478bd9Sstevel@tonic-gate break; 3630*7c478bd9Sstevel@tonic-gate 3631*7c478bd9Sstevel@tonic-gate case O_INPUTMILTER: 3632*7c478bd9Sstevel@tonic-gate #if MILTER 3633*7c478bd9Sstevel@tonic-gate InputFilterList = newstr(val); 3634*7c478bd9Sstevel@tonic-gate #else /* MILTER */ 3635*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3636*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 3637*7c478bd9Sstevel@tonic-gate OPTNAME); 3638*7c478bd9Sstevel@tonic-gate #endif /* MILTER */ 3639*7c478bd9Sstevel@tonic-gate break; 3640*7c478bd9Sstevel@tonic-gate 3641*7c478bd9Sstevel@tonic-gate case O_MILTER: 3642*7c478bd9Sstevel@tonic-gate #if MILTER 3643*7c478bd9Sstevel@tonic-gate milter_set_option(subopt, val, sticky); 3644*7c478bd9Sstevel@tonic-gate #else /* MILTER */ 3645*7c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3646*7c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 3647*7c478bd9Sstevel@tonic-gate OPTNAME); 3648*7c478bd9Sstevel@tonic-gate #endif /* MILTER */ 3649*7c478bd9Sstevel@tonic-gate break; 3650*7c478bd9Sstevel@tonic-gate 3651*7c478bd9Sstevel@tonic-gate case O_QUEUE_FILE_MODE: /* queue file mode */ 3652*7c478bd9Sstevel@tonic-gate QueueFileMode = atooct(val) & 0777; 3653*7c478bd9Sstevel@tonic-gate break; 3654*7c478bd9Sstevel@tonic-gate 3655*7c478bd9Sstevel@tonic-gate case O_DLVR_MIN: /* deliver by minimum time */ 3656*7c478bd9Sstevel@tonic-gate DeliverByMin = convtime(val, 's'); 3657*7c478bd9Sstevel@tonic-gate break; 3658*7c478bd9Sstevel@tonic-gate 3659*7c478bd9Sstevel@tonic-gate /* modifiers {daemon_flags} for direct submissions */ 3660*7c478bd9Sstevel@tonic-gate case O_DIRECTSUBMODIFIERS: 3661*7c478bd9Sstevel@tonic-gate { 3662*7c478bd9Sstevel@tonic-gate BITMAP256 m; /* ignored */ 3663*7c478bd9Sstevel@tonic-gate extern ENVELOPE BlankEnvelope; 3664*7c478bd9Sstevel@tonic-gate 3665*7c478bd9Sstevel@tonic-gate macdefine(&BlankEnvelope.e_macro, A_PERM, 3666*7c478bd9Sstevel@tonic-gate macid("{daemon_flags}"), 3667*7c478bd9Sstevel@tonic-gate getmodifiers(val, m)); 3668*7c478bd9Sstevel@tonic-gate } 3669*7c478bd9Sstevel@tonic-gate break; 3670*7c478bd9Sstevel@tonic-gate 3671*7c478bd9Sstevel@tonic-gate case O_FASTSPLIT: 3672*7c478bd9Sstevel@tonic-gate FastSplit = atoi(val); 3673*7c478bd9Sstevel@tonic-gate break; 3674*7c478bd9Sstevel@tonic-gate 3675*7c478bd9Sstevel@tonic-gate case O_MBDB: 3676*7c478bd9Sstevel@tonic-gate Mbdb = newstr(val); 3677*7c478bd9Sstevel@tonic-gate break; 3678*7c478bd9Sstevel@tonic-gate 3679*7c478bd9Sstevel@tonic-gate case O_MSQ: 3680*7c478bd9Sstevel@tonic-gate UseMSP = atobool(val); 3681*7c478bd9Sstevel@tonic-gate break; 3682*7c478bd9Sstevel@tonic-gate 3683*7c478bd9Sstevel@tonic-gate #if _FFR_SOFT_BOUNCE 3684*7c478bd9Sstevel@tonic-gate case O_SOFTBOUNCE: 3685*7c478bd9Sstevel@tonic-gate SoftBounce = atobool(val); 3686*7c478bd9Sstevel@tonic-gate break; 3687*7c478bd9Sstevel@tonic-gate #endif /* _FFR_SOFT_BOUNCE */ 3688*7c478bd9Sstevel@tonic-gate 3689*7c478bd9Sstevel@tonic-gate case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */ 3690*7c478bd9Sstevel@tonic-gate RejectLogInterval = convtime(val, 'h'); 3691*7c478bd9Sstevel@tonic-gate break; 3692*7c478bd9Sstevel@tonic-gate 3693*7c478bd9Sstevel@tonic-gate case O_REQUIRES_DIR_FSYNC: 3694*7c478bd9Sstevel@tonic-gate #if REQUIRES_DIR_FSYNC 3695*7c478bd9Sstevel@tonic-gate RequiresDirfsync = atobool(val); 3696*7c478bd9Sstevel@tonic-gate #else /* REQUIRES_DIR_FSYNC */ 3697*7c478bd9Sstevel@tonic-gate /* silently ignored... required for cf file option */ 3698*7c478bd9Sstevel@tonic-gate #endif /* REQUIRES_DIR_FSYNC */ 3699*7c478bd9Sstevel@tonic-gate break; 3700*7c478bd9Sstevel@tonic-gate 3701*7c478bd9Sstevel@tonic-gate case O_CONNECTION_RATE_WINDOW_SIZE: 3702*7c478bd9Sstevel@tonic-gate ConnectionRateWindowSize = convtime(val, 's'); 3703*7c478bd9Sstevel@tonic-gate break; 3704*7c478bd9Sstevel@tonic-gate 3705*7c478bd9Sstevel@tonic-gate case O_FALLBACKSMARTHOST: /* fallback smart host */ 3706*7c478bd9Sstevel@tonic-gate if (val[0] != '\0') 3707*7c478bd9Sstevel@tonic-gate FallbackSmartHost = newstr(val); 3708*7c478bd9Sstevel@tonic-gate break; 3709*7c478bd9Sstevel@tonic-gate 3710*7c478bd9Sstevel@tonic-gate #if _FFR_HELONAME 3711*7c478bd9Sstevel@tonic-gate case O_HELONAME: 3712*7c478bd9Sstevel@tonic-gate HeloName = newstr(val); 3713*7c478bd9Sstevel@tonic-gate break; 3714*7c478bd9Sstevel@tonic-gate #endif /* _FFR_HELONAME */ 3715*7c478bd9Sstevel@tonic-gate 3716*7c478bd9Sstevel@tonic-gate default: 3717*7c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 3718*7c478bd9Sstevel@tonic-gate { 3719*7c478bd9Sstevel@tonic-gate if (isascii(opt) && isprint(opt)) 3720*7c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option %c unknown\n", opt); 3721*7c478bd9Sstevel@tonic-gate else 3722*7c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option 0x%x unknown\n", opt); 3723*7c478bd9Sstevel@tonic-gate } 3724*7c478bd9Sstevel@tonic-gate break; 3725*7c478bd9Sstevel@tonic-gate } 3726*7c478bd9Sstevel@tonic-gate 3727*7c478bd9Sstevel@tonic-gate /* 3728*7c478bd9Sstevel@tonic-gate ** Options with suboptions are responsible for taking care 3729*7c478bd9Sstevel@tonic-gate ** of sticky-ness (e.g., that a command line setting is kept 3730*7c478bd9Sstevel@tonic-gate ** when reading in the sendmail.cf file). This has to be done 3731*7c478bd9Sstevel@tonic-gate ** when the suboptions are parsed since each suboption must be 3732*7c478bd9Sstevel@tonic-gate ** sticky, not the root option. 3733*7c478bd9Sstevel@tonic-gate */ 3734*7c478bd9Sstevel@tonic-gate 3735*7c478bd9Sstevel@tonic-gate if (sticky && !bitset(OI_SUBOPT, o->o_flags)) 3736*7c478bd9Sstevel@tonic-gate setbitn(opt, StickyOpt); 3737*7c478bd9Sstevel@tonic-gate } 3738*7c478bd9Sstevel@tonic-gate /* 3739*7c478bd9Sstevel@tonic-gate ** SETCLASS -- set a string into a class 3740*7c478bd9Sstevel@tonic-gate ** 3741*7c478bd9Sstevel@tonic-gate ** Parameters: 3742*7c478bd9Sstevel@tonic-gate ** class -- the class to put the string in. 3743*7c478bd9Sstevel@tonic-gate ** str -- the string to enter 3744*7c478bd9Sstevel@tonic-gate ** 3745*7c478bd9Sstevel@tonic-gate ** Returns: 3746*7c478bd9Sstevel@tonic-gate ** none. 3747*7c478bd9Sstevel@tonic-gate ** 3748*7c478bd9Sstevel@tonic-gate ** Side Effects: 3749*7c478bd9Sstevel@tonic-gate ** puts the word into the symbol table. 3750*7c478bd9Sstevel@tonic-gate */ 3751*7c478bd9Sstevel@tonic-gate 3752*7c478bd9Sstevel@tonic-gate void 3753*7c478bd9Sstevel@tonic-gate setclass(class, str) 3754*7c478bd9Sstevel@tonic-gate int class; 3755*7c478bd9Sstevel@tonic-gate char *str; 3756*7c478bd9Sstevel@tonic-gate { 3757*7c478bd9Sstevel@tonic-gate register STAB *s; 3758*7c478bd9Sstevel@tonic-gate 3759*7c478bd9Sstevel@tonic-gate if ((*str & 0377) == MATCHCLASS) 3760*7c478bd9Sstevel@tonic-gate { 3761*7c478bd9Sstevel@tonic-gate int mid; 3762*7c478bd9Sstevel@tonic-gate 3763*7c478bd9Sstevel@tonic-gate str++; 3764*7c478bd9Sstevel@tonic-gate mid = macid(str); 3765*7c478bd9Sstevel@tonic-gate if (mid == 0) 3766*7c478bd9Sstevel@tonic-gate return; 3767*7c478bd9Sstevel@tonic-gate 3768*7c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 3769*7c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, $=%s)\n", 3770*7c478bd9Sstevel@tonic-gate macname(class), macname(mid)); 3771*7c478bd9Sstevel@tonic-gate copy_class(mid, class); 3772*7c478bd9Sstevel@tonic-gate } 3773*7c478bd9Sstevel@tonic-gate else 3774*7c478bd9Sstevel@tonic-gate { 3775*7c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 3776*7c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, %s)\n", macname(class), str); 3777*7c478bd9Sstevel@tonic-gate 3778*7c478bd9Sstevel@tonic-gate s = stab(str, ST_CLASS, ST_ENTER); 3779*7c478bd9Sstevel@tonic-gate setbitn(bitidx(class), s->s_class); 3780*7c478bd9Sstevel@tonic-gate } 3781*7c478bd9Sstevel@tonic-gate } 3782*7c478bd9Sstevel@tonic-gate /* 3783*7c478bd9Sstevel@tonic-gate ** MAKEMAPENTRY -- create a map entry 3784*7c478bd9Sstevel@tonic-gate ** 3785*7c478bd9Sstevel@tonic-gate ** Parameters: 3786*7c478bd9Sstevel@tonic-gate ** line -- the config file line 3787*7c478bd9Sstevel@tonic-gate ** 3788*7c478bd9Sstevel@tonic-gate ** Returns: 3789*7c478bd9Sstevel@tonic-gate ** A pointer to the map that has been created. 3790*7c478bd9Sstevel@tonic-gate ** NULL if there was a syntax error. 3791*7c478bd9Sstevel@tonic-gate ** 3792*7c478bd9Sstevel@tonic-gate ** Side Effects: 3793*7c478bd9Sstevel@tonic-gate ** Enters the map into the dictionary. 3794*7c478bd9Sstevel@tonic-gate */ 3795*7c478bd9Sstevel@tonic-gate 3796*7c478bd9Sstevel@tonic-gate MAP * 3797*7c478bd9Sstevel@tonic-gate makemapentry(line) 3798*7c478bd9Sstevel@tonic-gate char *line; 3799*7c478bd9Sstevel@tonic-gate { 3800*7c478bd9Sstevel@tonic-gate register char *p; 3801*7c478bd9Sstevel@tonic-gate char *mapname; 3802*7c478bd9Sstevel@tonic-gate char *classname; 3803*7c478bd9Sstevel@tonic-gate register STAB *s; 3804*7c478bd9Sstevel@tonic-gate STAB *class; 3805*7c478bd9Sstevel@tonic-gate 3806*7c478bd9Sstevel@tonic-gate for (p = line; isascii(*p) && isspace(*p); p++) 3807*7c478bd9Sstevel@tonic-gate continue; 3808*7c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 3809*7c478bd9Sstevel@tonic-gate { 3810*7c478bd9Sstevel@tonic-gate syserr("readcf: config K line: no map name"); 3811*7c478bd9Sstevel@tonic-gate return NULL; 3812*7c478bd9Sstevel@tonic-gate } 3813*7c478bd9Sstevel@tonic-gate 3814*7c478bd9Sstevel@tonic-gate mapname = p; 3815*7c478bd9Sstevel@tonic-gate while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.') 3816*7c478bd9Sstevel@tonic-gate continue; 3817*7c478bd9Sstevel@tonic-gate if (*p != '\0') 3818*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3819*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 3820*7c478bd9Sstevel@tonic-gate p++; 3821*7c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 3822*7c478bd9Sstevel@tonic-gate { 3823*7c478bd9Sstevel@tonic-gate syserr("readcf: config K line, map %s: no map class", mapname); 3824*7c478bd9Sstevel@tonic-gate return NULL; 3825*7c478bd9Sstevel@tonic-gate } 3826*7c478bd9Sstevel@tonic-gate classname = p; 3827*7c478bd9Sstevel@tonic-gate while (isascii(*++p) && isalnum(*p)) 3828*7c478bd9Sstevel@tonic-gate continue; 3829*7c478bd9Sstevel@tonic-gate if (*p != '\0') 3830*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3831*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 3832*7c478bd9Sstevel@tonic-gate p++; 3833*7c478bd9Sstevel@tonic-gate 3834*7c478bd9Sstevel@tonic-gate /* look up the class */ 3835*7c478bd9Sstevel@tonic-gate class = stab(classname, ST_MAPCLASS, ST_FIND); 3836*7c478bd9Sstevel@tonic-gate if (class == NULL) 3837*7c478bd9Sstevel@tonic-gate { 3838*7c478bd9Sstevel@tonic-gate syserr("readcf: map %s: class %s not available", mapname, 3839*7c478bd9Sstevel@tonic-gate classname); 3840*7c478bd9Sstevel@tonic-gate return NULL; 3841*7c478bd9Sstevel@tonic-gate } 3842*7c478bd9Sstevel@tonic-gate 3843*7c478bd9Sstevel@tonic-gate /* enter the map */ 3844*7c478bd9Sstevel@tonic-gate s = stab(mapname, ST_MAP, ST_ENTER); 3845*7c478bd9Sstevel@tonic-gate s->s_map.map_class = &class->s_mapclass; 3846*7c478bd9Sstevel@tonic-gate s->s_map.map_mname = newstr(mapname); 3847*7c478bd9Sstevel@tonic-gate 3848*7c478bd9Sstevel@tonic-gate if (class->s_mapclass.map_parse(&s->s_map, p)) 3849*7c478bd9Sstevel@tonic-gate s->s_map.map_mflags |= MF_VALID; 3850*7c478bd9Sstevel@tonic-gate 3851*7c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 3852*7c478bd9Sstevel@tonic-gate { 3853*7c478bd9Sstevel@tonic-gate sm_dprintf("map %s, class %s, flags %lx, file %s,\n", 3854*7c478bd9Sstevel@tonic-gate s->s_map.map_mname, s->s_map.map_class->map_cname, 3855*7c478bd9Sstevel@tonic-gate s->s_map.map_mflags, s->s_map.map_file); 3856*7c478bd9Sstevel@tonic-gate sm_dprintf("\tapp %s, domain %s, rebuild %s\n", 3857*7c478bd9Sstevel@tonic-gate s->s_map.map_app, s->s_map.map_domain, 3858*7c478bd9Sstevel@tonic-gate s->s_map.map_rebuild); 3859*7c478bd9Sstevel@tonic-gate } 3860*7c478bd9Sstevel@tonic-gate return &s->s_map; 3861*7c478bd9Sstevel@tonic-gate } 3862*7c478bd9Sstevel@tonic-gate /* 3863*7c478bd9Sstevel@tonic-gate ** STRTORWSET -- convert string to rewriting set number 3864*7c478bd9Sstevel@tonic-gate ** 3865*7c478bd9Sstevel@tonic-gate ** Parameters: 3866*7c478bd9Sstevel@tonic-gate ** p -- the pointer to the string to decode. 3867*7c478bd9Sstevel@tonic-gate ** endp -- if set, store the trailing delimiter here. 3868*7c478bd9Sstevel@tonic-gate ** stabmode -- ST_ENTER to create this entry, ST_FIND if 3869*7c478bd9Sstevel@tonic-gate ** it must already exist. 3870*7c478bd9Sstevel@tonic-gate ** 3871*7c478bd9Sstevel@tonic-gate ** Returns: 3872*7c478bd9Sstevel@tonic-gate ** The appropriate ruleset number. 3873*7c478bd9Sstevel@tonic-gate ** -1 if it is not valid (error already printed) 3874*7c478bd9Sstevel@tonic-gate */ 3875*7c478bd9Sstevel@tonic-gate 3876*7c478bd9Sstevel@tonic-gate int 3877*7c478bd9Sstevel@tonic-gate strtorwset(p, endp, stabmode) 3878*7c478bd9Sstevel@tonic-gate char *p; 3879*7c478bd9Sstevel@tonic-gate char **endp; 3880*7c478bd9Sstevel@tonic-gate int stabmode; 3881*7c478bd9Sstevel@tonic-gate { 3882*7c478bd9Sstevel@tonic-gate int ruleset; 3883*7c478bd9Sstevel@tonic-gate static int nextruleset = MAXRWSETS; 3884*7c478bd9Sstevel@tonic-gate 3885*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 3886*7c478bd9Sstevel@tonic-gate p++; 3887*7c478bd9Sstevel@tonic-gate if (!isascii(*p)) 3888*7c478bd9Sstevel@tonic-gate { 3889*7c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", p); 3890*7c478bd9Sstevel@tonic-gate return -1; 3891*7c478bd9Sstevel@tonic-gate } 3892*7c478bd9Sstevel@tonic-gate if (isdigit(*p)) 3893*7c478bd9Sstevel@tonic-gate { 3894*7c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 3895*7c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 3896*7c478bd9Sstevel@tonic-gate { 3897*7c478bd9Sstevel@tonic-gate syserr("bad ruleset %d (%d max)", 3898*7c478bd9Sstevel@tonic-gate ruleset, MAXRWSETS / 2); 3899*7c478bd9Sstevel@tonic-gate ruleset = -1; 3900*7c478bd9Sstevel@tonic-gate } 3901*7c478bd9Sstevel@tonic-gate } 3902*7c478bd9Sstevel@tonic-gate else 3903*7c478bd9Sstevel@tonic-gate { 3904*7c478bd9Sstevel@tonic-gate STAB *s; 3905*7c478bd9Sstevel@tonic-gate char delim; 3906*7c478bd9Sstevel@tonic-gate char *q = NULL; 3907*7c478bd9Sstevel@tonic-gate 3908*7c478bd9Sstevel@tonic-gate q = p; 3909*7c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && 3910*7c478bd9Sstevel@tonic-gate (isalnum(*p) || *p == '_')) 3911*7c478bd9Sstevel@tonic-gate p++; 3912*7c478bd9Sstevel@tonic-gate if (q == p || !(isascii(*q) && isalpha(*q))) 3913*7c478bd9Sstevel@tonic-gate { 3914*7c478bd9Sstevel@tonic-gate /* no valid characters */ 3915*7c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", q); 3916*7c478bd9Sstevel@tonic-gate return -1; 3917*7c478bd9Sstevel@tonic-gate } 3918*7c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 3919*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 3920*7c478bd9Sstevel@tonic-gate delim = *p; 3921*7c478bd9Sstevel@tonic-gate if (delim != '\0') 3922*7c478bd9Sstevel@tonic-gate *p = '\0'; 3923*7c478bd9Sstevel@tonic-gate s = stab(q, ST_RULESET, stabmode); 3924*7c478bd9Sstevel@tonic-gate if (delim != '\0') 3925*7c478bd9Sstevel@tonic-gate *p = delim; 3926*7c478bd9Sstevel@tonic-gate 3927*7c478bd9Sstevel@tonic-gate if (s == NULL) 3928*7c478bd9Sstevel@tonic-gate return -1; 3929*7c478bd9Sstevel@tonic-gate 3930*7c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && delim == '=') 3931*7c478bd9Sstevel@tonic-gate { 3932*7c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 3933*7c478bd9Sstevel@tonic-gate continue; 3934*7c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isdigit(*p))) 3935*7c478bd9Sstevel@tonic-gate { 3936*7c478bd9Sstevel@tonic-gate syserr("bad ruleset definition \"%s\" (number required after `=')", q); 3937*7c478bd9Sstevel@tonic-gate ruleset = -1; 3938*7c478bd9Sstevel@tonic-gate } 3939*7c478bd9Sstevel@tonic-gate else 3940*7c478bd9Sstevel@tonic-gate { 3941*7c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 3942*7c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 3943*7c478bd9Sstevel@tonic-gate { 3944*7c478bd9Sstevel@tonic-gate syserr("bad ruleset number %d in \"%s\" (%d max)", 3945*7c478bd9Sstevel@tonic-gate ruleset, q, MAXRWSETS / 2); 3946*7c478bd9Sstevel@tonic-gate ruleset = -1; 3947*7c478bd9Sstevel@tonic-gate } 3948*7c478bd9Sstevel@tonic-gate } 3949*7c478bd9Sstevel@tonic-gate } 3950*7c478bd9Sstevel@tonic-gate else 3951*7c478bd9Sstevel@tonic-gate { 3952*7c478bd9Sstevel@tonic-gate if (endp != NULL) 3953*7c478bd9Sstevel@tonic-gate *endp = p; 3954*7c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0) 3955*7c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 3956*7c478bd9Sstevel@tonic-gate else if ((ruleset = --nextruleset) < MAXRWSETS / 2) 3957*7c478bd9Sstevel@tonic-gate { 3958*7c478bd9Sstevel@tonic-gate syserr("%s: too many named rulesets (%d max)", 3959*7c478bd9Sstevel@tonic-gate q, MAXRWSETS / 2); 3960*7c478bd9Sstevel@tonic-gate ruleset = -1; 3961*7c478bd9Sstevel@tonic-gate } 3962*7c478bd9Sstevel@tonic-gate } 3963*7c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0 && 3964*7c478bd9Sstevel@tonic-gate ruleset >= 0 && 3965*7c478bd9Sstevel@tonic-gate ruleset != s->s_ruleset) 3966*7c478bd9Sstevel@tonic-gate { 3967*7c478bd9Sstevel@tonic-gate syserr("%s: ruleset changed value (old %d, new %d)", 3968*7c478bd9Sstevel@tonic-gate q, s->s_ruleset, ruleset); 3969*7c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 3970*7c478bd9Sstevel@tonic-gate } 3971*7c478bd9Sstevel@tonic-gate else if (ruleset >= 0) 3972*7c478bd9Sstevel@tonic-gate { 3973*7c478bd9Sstevel@tonic-gate s->s_ruleset = ruleset; 3974*7c478bd9Sstevel@tonic-gate } 3975*7c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && ruleset >= 0) 3976*7c478bd9Sstevel@tonic-gate { 3977*7c478bd9Sstevel@tonic-gate char *h = NULL; 3978*7c478bd9Sstevel@tonic-gate 3979*7c478bd9Sstevel@tonic-gate if (RuleSetNames[ruleset] != NULL) 3980*7c478bd9Sstevel@tonic-gate sm_free(RuleSetNames[ruleset]); /* XXX */ 3981*7c478bd9Sstevel@tonic-gate if (delim != '\0' && (h = strchr(q, delim)) != NULL) 3982*7c478bd9Sstevel@tonic-gate *h = '\0'; 3983*7c478bd9Sstevel@tonic-gate RuleSetNames[ruleset] = newstr(q); 3984*7c478bd9Sstevel@tonic-gate if (delim == '/' && h != NULL) 3985*7c478bd9Sstevel@tonic-gate *h = delim; /* put back delim */ 3986*7c478bd9Sstevel@tonic-gate } 3987*7c478bd9Sstevel@tonic-gate } 3988*7c478bd9Sstevel@tonic-gate return ruleset; 3989*7c478bd9Sstevel@tonic-gate } 3990*7c478bd9Sstevel@tonic-gate /* 3991*7c478bd9Sstevel@tonic-gate ** SETTIMEOUT -- set an individual timeout 3992*7c478bd9Sstevel@tonic-gate ** 3993*7c478bd9Sstevel@tonic-gate ** Parameters: 3994*7c478bd9Sstevel@tonic-gate ** name -- the name of the timeout. 3995*7c478bd9Sstevel@tonic-gate ** val -- the value of the timeout. 3996*7c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 3997*7c478bd9Sstevel@tonic-gate ** this value. 3998*7c478bd9Sstevel@tonic-gate ** 3999*7c478bd9Sstevel@tonic-gate ** Returns: 4000*7c478bd9Sstevel@tonic-gate ** none. 4001*7c478bd9Sstevel@tonic-gate */ 4002*7c478bd9Sstevel@tonic-gate 4003*7c478bd9Sstevel@tonic-gate /* set if Timeout sub-option is stuck */ 4004*7c478bd9Sstevel@tonic-gate static BITMAP256 StickyTimeoutOpt; 4005*7c478bd9Sstevel@tonic-gate 4006*7c478bd9Sstevel@tonic-gate static struct timeoutinfo 4007*7c478bd9Sstevel@tonic-gate { 4008*7c478bd9Sstevel@tonic-gate char *to_name; /* long name of timeout */ 4009*7c478bd9Sstevel@tonic-gate unsigned char to_code; /* code for option */ 4010*7c478bd9Sstevel@tonic-gate } TimeOutTab[] = 4011*7c478bd9Sstevel@tonic-gate { 4012*7c478bd9Sstevel@tonic-gate #define TO_INITIAL 0x01 4013*7c478bd9Sstevel@tonic-gate { "initial", TO_INITIAL }, 4014*7c478bd9Sstevel@tonic-gate #define TO_MAIL 0x02 4015*7c478bd9Sstevel@tonic-gate { "mail", TO_MAIL }, 4016*7c478bd9Sstevel@tonic-gate #define TO_RCPT 0x03 4017*7c478bd9Sstevel@tonic-gate { "rcpt", TO_RCPT }, 4018*7c478bd9Sstevel@tonic-gate #define TO_DATAINIT 0x04 4019*7c478bd9Sstevel@tonic-gate { "datainit", TO_DATAINIT }, 4020*7c478bd9Sstevel@tonic-gate #define TO_DATABLOCK 0x05 4021*7c478bd9Sstevel@tonic-gate { "datablock", TO_DATABLOCK }, 4022*7c478bd9Sstevel@tonic-gate #define TO_DATAFINAL 0x06 4023*7c478bd9Sstevel@tonic-gate { "datafinal", TO_DATAFINAL }, 4024*7c478bd9Sstevel@tonic-gate #define TO_COMMAND 0x07 4025*7c478bd9Sstevel@tonic-gate { "command", TO_COMMAND }, 4026*7c478bd9Sstevel@tonic-gate #define TO_RSET 0x08 4027*7c478bd9Sstevel@tonic-gate { "rset", TO_RSET }, 4028*7c478bd9Sstevel@tonic-gate #define TO_HELO 0x09 4029*7c478bd9Sstevel@tonic-gate { "helo", TO_HELO }, 4030*7c478bd9Sstevel@tonic-gate #define TO_QUIT 0x0A 4031*7c478bd9Sstevel@tonic-gate { "quit", TO_QUIT }, 4032*7c478bd9Sstevel@tonic-gate #define TO_MISC 0x0B 4033*7c478bd9Sstevel@tonic-gate { "misc", TO_MISC }, 4034*7c478bd9Sstevel@tonic-gate #define TO_IDENT 0x0C 4035*7c478bd9Sstevel@tonic-gate { "ident", TO_IDENT }, 4036*7c478bd9Sstevel@tonic-gate #define TO_FILEOPEN 0x0D 4037*7c478bd9Sstevel@tonic-gate { "fileopen", TO_FILEOPEN }, 4038*7c478bd9Sstevel@tonic-gate #define TO_CONNECT 0x0E 4039*7c478bd9Sstevel@tonic-gate { "connect", TO_CONNECT }, 4040*7c478bd9Sstevel@tonic-gate #define TO_ICONNECT 0x0F 4041*7c478bd9Sstevel@tonic-gate { "iconnect", TO_ICONNECT }, 4042*7c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN 0x10 4043*7c478bd9Sstevel@tonic-gate { "queuewarn", TO_QUEUEWARN }, 4044*7c478bd9Sstevel@tonic-gate { "queuewarn.*", TO_QUEUEWARN }, 4045*7c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NORMAL 0x11 4046*7c478bd9Sstevel@tonic-gate { "queuewarn.normal", TO_QUEUEWARN_NORMAL }, 4047*7c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_URGENT 0x12 4048*7c478bd9Sstevel@tonic-gate { "queuewarn.urgent", TO_QUEUEWARN_URGENT }, 4049*7c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NON_URGENT 0x13 4050*7c478bd9Sstevel@tonic-gate { "queuewarn.non-urgent", TO_QUEUEWARN_NON_URGENT }, 4051*7c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN 0x14 4052*7c478bd9Sstevel@tonic-gate { "queuereturn", TO_QUEUERETURN }, 4053*7c478bd9Sstevel@tonic-gate { "queuereturn.*", TO_QUEUERETURN }, 4054*7c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NORMAL 0x15 4055*7c478bd9Sstevel@tonic-gate { "queuereturn.normal", TO_QUEUERETURN_NORMAL }, 4056*7c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_URGENT 0x16 4057*7c478bd9Sstevel@tonic-gate { "queuereturn.urgent", TO_QUEUERETURN_URGENT }, 4058*7c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NON_URGENT 0x17 4059*7c478bd9Sstevel@tonic-gate { "queuereturn.non-urgent", TO_QUEUERETURN_NON_URGENT }, 4060*7c478bd9Sstevel@tonic-gate #define TO_HOSTSTATUS 0x18 4061*7c478bd9Sstevel@tonic-gate { "hoststatus", TO_HOSTSTATUS }, 4062*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS 0x19 4063*7c478bd9Sstevel@tonic-gate { "resolver.retrans", TO_RESOLVER_RETRANS }, 4064*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_NORMAL 0x1A 4065*7c478bd9Sstevel@tonic-gate { "resolver.retrans.normal", TO_RESOLVER_RETRANS_NORMAL }, 4066*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_FIRST 0x1B 4067*7c478bd9Sstevel@tonic-gate { "resolver.retrans.first", TO_RESOLVER_RETRANS_FIRST }, 4068*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY 0x1C 4069*7c478bd9Sstevel@tonic-gate { "resolver.retry", TO_RESOLVER_RETRY }, 4070*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_NORMAL 0x1D 4071*7c478bd9Sstevel@tonic-gate { "resolver.retry.normal", TO_RESOLVER_RETRY_NORMAL }, 4072*7c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_FIRST 0x1E 4073*7c478bd9Sstevel@tonic-gate { "resolver.retry.first", TO_RESOLVER_RETRY_FIRST }, 4074*7c478bd9Sstevel@tonic-gate #define TO_CONTROL 0x1F 4075*7c478bd9Sstevel@tonic-gate { "control", TO_CONTROL }, 4076*7c478bd9Sstevel@tonic-gate #define TO_LHLO 0x20 4077*7c478bd9Sstevel@tonic-gate { "lhlo", TO_LHLO }, 4078*7c478bd9Sstevel@tonic-gate #define TO_AUTH 0x21 4079*7c478bd9Sstevel@tonic-gate { "auth", TO_AUTH }, 4080*7c478bd9Sstevel@tonic-gate #define TO_STARTTLS 0x22 4081*7c478bd9Sstevel@tonic-gate { "starttls", TO_STARTTLS }, 4082*7c478bd9Sstevel@tonic-gate #define TO_ACONNECT 0x23 4083*7c478bd9Sstevel@tonic-gate { "aconnect", TO_ACONNECT }, 4084*7c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_DSN 0x24 4085*7c478bd9Sstevel@tonic-gate { "queuewarn.dsn", TO_QUEUEWARN_DSN }, 4086*7c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_DSN 0x25 4087*7c478bd9Sstevel@tonic-gate { "queuereturn.dsn", TO_QUEUERETURN_DSN }, 4088*7c478bd9Sstevel@tonic-gate { NULL, 0 }, 4089*7c478bd9Sstevel@tonic-gate }; 4090*7c478bd9Sstevel@tonic-gate 4091*7c478bd9Sstevel@tonic-gate 4092*7c478bd9Sstevel@tonic-gate static void 4093*7c478bd9Sstevel@tonic-gate settimeout(name, val, sticky) 4094*7c478bd9Sstevel@tonic-gate char *name; 4095*7c478bd9Sstevel@tonic-gate char *val; 4096*7c478bd9Sstevel@tonic-gate bool sticky; 4097*7c478bd9Sstevel@tonic-gate { 4098*7c478bd9Sstevel@tonic-gate register struct timeoutinfo *to; 4099*7c478bd9Sstevel@tonic-gate int i, addopts; 4100*7c478bd9Sstevel@tonic-gate time_t toval; 4101*7c478bd9Sstevel@tonic-gate 4102*7c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 4103*7c478bd9Sstevel@tonic-gate sm_dprintf("settimeout(%s = %s)", name, val); 4104*7c478bd9Sstevel@tonic-gate 4105*7c478bd9Sstevel@tonic-gate for (to = TimeOutTab; to->to_name != NULL; to++) 4106*7c478bd9Sstevel@tonic-gate { 4107*7c478bd9Sstevel@tonic-gate if (sm_strcasecmp(to->to_name, name) == 0) 4108*7c478bd9Sstevel@tonic-gate break; 4109*7c478bd9Sstevel@tonic-gate } 4110*7c478bd9Sstevel@tonic-gate 4111*7c478bd9Sstevel@tonic-gate if (to->to_name == NULL) 4112*7c478bd9Sstevel@tonic-gate { 4113*7c478bd9Sstevel@tonic-gate errno = 0; /* avoid bogus error text */ 4114*7c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 4115*7c478bd9Sstevel@tonic-gate return; 4116*7c478bd9Sstevel@tonic-gate } 4117*7c478bd9Sstevel@tonic-gate 4118*7c478bd9Sstevel@tonic-gate /* 4119*7c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 4120*7c478bd9Sstevel@tonic-gate */ 4121*7c478bd9Sstevel@tonic-gate 4122*7c478bd9Sstevel@tonic-gate if (!sticky && bitnset(to->to_code, StickyTimeoutOpt)) 4123*7c478bd9Sstevel@tonic-gate { 4124*7c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 4125*7c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 4126*7c478bd9Sstevel@tonic-gate return; 4127*7c478bd9Sstevel@tonic-gate } 4128*7c478bd9Sstevel@tonic-gate 4129*7c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 4130*7c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 4131*7c478bd9Sstevel@tonic-gate 4132*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'm'); 4133*7c478bd9Sstevel@tonic-gate addopts = 0; 4134*7c478bd9Sstevel@tonic-gate 4135*7c478bd9Sstevel@tonic-gate switch (to->to_code) 4136*7c478bd9Sstevel@tonic-gate { 4137*7c478bd9Sstevel@tonic-gate case TO_INITIAL: 4138*7c478bd9Sstevel@tonic-gate TimeOuts.to_initial = toval; 4139*7c478bd9Sstevel@tonic-gate break; 4140*7c478bd9Sstevel@tonic-gate 4141*7c478bd9Sstevel@tonic-gate case TO_MAIL: 4142*7c478bd9Sstevel@tonic-gate TimeOuts.to_mail = toval; 4143*7c478bd9Sstevel@tonic-gate break; 4144*7c478bd9Sstevel@tonic-gate 4145*7c478bd9Sstevel@tonic-gate case TO_RCPT: 4146*7c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = toval; 4147*7c478bd9Sstevel@tonic-gate break; 4148*7c478bd9Sstevel@tonic-gate 4149*7c478bd9Sstevel@tonic-gate case TO_DATAINIT: 4150*7c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = toval; 4151*7c478bd9Sstevel@tonic-gate break; 4152*7c478bd9Sstevel@tonic-gate 4153*7c478bd9Sstevel@tonic-gate case TO_DATABLOCK: 4154*7c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = toval; 4155*7c478bd9Sstevel@tonic-gate break; 4156*7c478bd9Sstevel@tonic-gate 4157*7c478bd9Sstevel@tonic-gate case TO_DATAFINAL: 4158*7c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = toval; 4159*7c478bd9Sstevel@tonic-gate break; 4160*7c478bd9Sstevel@tonic-gate 4161*7c478bd9Sstevel@tonic-gate case TO_COMMAND: 4162*7c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = toval; 4163*7c478bd9Sstevel@tonic-gate break; 4164*7c478bd9Sstevel@tonic-gate 4165*7c478bd9Sstevel@tonic-gate case TO_RSET: 4166*7c478bd9Sstevel@tonic-gate TimeOuts.to_rset = toval; 4167*7c478bd9Sstevel@tonic-gate break; 4168*7c478bd9Sstevel@tonic-gate 4169*7c478bd9Sstevel@tonic-gate case TO_HELO: 4170*7c478bd9Sstevel@tonic-gate TimeOuts.to_helo = toval; 4171*7c478bd9Sstevel@tonic-gate break; 4172*7c478bd9Sstevel@tonic-gate 4173*7c478bd9Sstevel@tonic-gate case TO_QUIT: 4174*7c478bd9Sstevel@tonic-gate TimeOuts.to_quit = toval; 4175*7c478bd9Sstevel@tonic-gate break; 4176*7c478bd9Sstevel@tonic-gate 4177*7c478bd9Sstevel@tonic-gate case TO_MISC: 4178*7c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = toval; 4179*7c478bd9Sstevel@tonic-gate break; 4180*7c478bd9Sstevel@tonic-gate 4181*7c478bd9Sstevel@tonic-gate case TO_IDENT: 4182*7c478bd9Sstevel@tonic-gate TimeOuts.to_ident = toval; 4183*7c478bd9Sstevel@tonic-gate break; 4184*7c478bd9Sstevel@tonic-gate 4185*7c478bd9Sstevel@tonic-gate case TO_FILEOPEN: 4186*7c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = toval; 4187*7c478bd9Sstevel@tonic-gate break; 4188*7c478bd9Sstevel@tonic-gate 4189*7c478bd9Sstevel@tonic-gate case TO_CONNECT: 4190*7c478bd9Sstevel@tonic-gate TimeOuts.to_connect = toval; 4191*7c478bd9Sstevel@tonic-gate break; 4192*7c478bd9Sstevel@tonic-gate 4193*7c478bd9Sstevel@tonic-gate case TO_ICONNECT: 4194*7c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = toval; 4195*7c478bd9Sstevel@tonic-gate break; 4196*7c478bd9Sstevel@tonic-gate 4197*7c478bd9Sstevel@tonic-gate case TO_ACONNECT: 4198*7c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = toval; 4199*7c478bd9Sstevel@tonic-gate break; 4200*7c478bd9Sstevel@tonic-gate 4201*7c478bd9Sstevel@tonic-gate case TO_QUEUEWARN: 4202*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 4203*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 4204*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 4205*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 4206*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 4207*7c478bd9Sstevel@tonic-gate addopts = 2; 4208*7c478bd9Sstevel@tonic-gate break; 4209*7c478bd9Sstevel@tonic-gate 4210*7c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NORMAL: 4211*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 4212*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 4213*7c478bd9Sstevel@tonic-gate break; 4214*7c478bd9Sstevel@tonic-gate 4215*7c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_URGENT: 4216*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 4217*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 4218*7c478bd9Sstevel@tonic-gate break; 4219*7c478bd9Sstevel@tonic-gate 4220*7c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NON_URGENT: 4221*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 4222*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 4223*7c478bd9Sstevel@tonic-gate break; 4224*7c478bd9Sstevel@tonic-gate 4225*7c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_DSN: 4226*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 4227*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 4228*7c478bd9Sstevel@tonic-gate break; 4229*7c478bd9Sstevel@tonic-gate 4230*7c478bd9Sstevel@tonic-gate case TO_QUEUERETURN: 4231*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 4232*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 4233*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 4234*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 4235*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 4236*7c478bd9Sstevel@tonic-gate addopts = 2; 4237*7c478bd9Sstevel@tonic-gate break; 4238*7c478bd9Sstevel@tonic-gate 4239*7c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NORMAL: 4240*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 4241*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 4242*7c478bd9Sstevel@tonic-gate break; 4243*7c478bd9Sstevel@tonic-gate 4244*7c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_URGENT: 4245*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 4246*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 4247*7c478bd9Sstevel@tonic-gate break; 4248*7c478bd9Sstevel@tonic-gate 4249*7c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NON_URGENT: 4250*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 4251*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 4252*7c478bd9Sstevel@tonic-gate break; 4253*7c478bd9Sstevel@tonic-gate 4254*7c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_DSN: 4255*7c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 4256*7c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 4257*7c478bd9Sstevel@tonic-gate break; 4258*7c478bd9Sstevel@tonic-gate 4259*7c478bd9Sstevel@tonic-gate case TO_HOSTSTATUS: 4260*7c478bd9Sstevel@tonic-gate MciInfoTimeout = toval; 4261*7c478bd9Sstevel@tonic-gate break; 4262*7c478bd9Sstevel@tonic-gate 4263*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS: 4264*7c478bd9Sstevel@tonic-gate toval = convtime(val, 's'); 4265*7c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_DEFAULT] = toval; 4266*7c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = toval; 4267*7c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = toval; 4268*7c478bd9Sstevel@tonic-gate addopts = 2; 4269*7c478bd9Sstevel@tonic-gate break; 4270*7c478bd9Sstevel@tonic-gate 4271*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY: 4272*7c478bd9Sstevel@tonic-gate i = atoi(val); 4273*7c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_DEFAULT] = i; 4274*7c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = i; 4275*7c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = i; 4276*7c478bd9Sstevel@tonic-gate addopts = 2; 4277*7c478bd9Sstevel@tonic-gate break; 4278*7c478bd9Sstevel@tonic-gate 4279*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_NORMAL: 4280*7c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = convtime(val, 's'); 4281*7c478bd9Sstevel@tonic-gate break; 4282*7c478bd9Sstevel@tonic-gate 4283*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_NORMAL: 4284*7c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = atoi(val); 4285*7c478bd9Sstevel@tonic-gate break; 4286*7c478bd9Sstevel@tonic-gate 4287*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_FIRST: 4288*7c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = convtime(val, 's'); 4289*7c478bd9Sstevel@tonic-gate break; 4290*7c478bd9Sstevel@tonic-gate 4291*7c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_FIRST: 4292*7c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = atoi(val); 4293*7c478bd9Sstevel@tonic-gate break; 4294*7c478bd9Sstevel@tonic-gate 4295*7c478bd9Sstevel@tonic-gate case TO_CONTROL: 4296*7c478bd9Sstevel@tonic-gate TimeOuts.to_control = toval; 4297*7c478bd9Sstevel@tonic-gate break; 4298*7c478bd9Sstevel@tonic-gate 4299*7c478bd9Sstevel@tonic-gate case TO_LHLO: 4300*7c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = toval; 4301*7c478bd9Sstevel@tonic-gate break; 4302*7c478bd9Sstevel@tonic-gate 4303*7c478bd9Sstevel@tonic-gate #if SASL 4304*7c478bd9Sstevel@tonic-gate case TO_AUTH: 4305*7c478bd9Sstevel@tonic-gate TimeOuts.to_auth = toval; 4306*7c478bd9Sstevel@tonic-gate break; 4307*7c478bd9Sstevel@tonic-gate #endif /* SASL */ 4308*7c478bd9Sstevel@tonic-gate 4309*7c478bd9Sstevel@tonic-gate #if STARTTLS 4310*7c478bd9Sstevel@tonic-gate case TO_STARTTLS: 4311*7c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = toval; 4312*7c478bd9Sstevel@tonic-gate break; 4313*7c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 4314*7c478bd9Sstevel@tonic-gate 4315*7c478bd9Sstevel@tonic-gate default: 4316*7c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 4317*7c478bd9Sstevel@tonic-gate break; 4318*7c478bd9Sstevel@tonic-gate } 4319*7c478bd9Sstevel@tonic-gate 4320*7c478bd9Sstevel@tonic-gate if (sticky) 4321*7c478bd9Sstevel@tonic-gate { 4322*7c478bd9Sstevel@tonic-gate for (i = 0; i <= addopts; i++) 4323*7c478bd9Sstevel@tonic-gate setbitn(to->to_code + i, StickyTimeoutOpt); 4324*7c478bd9Sstevel@tonic-gate } 4325*7c478bd9Sstevel@tonic-gate } 4326*7c478bd9Sstevel@tonic-gate /* 4327*7c478bd9Sstevel@tonic-gate ** INITTIMEOUTS -- parse and set timeout values 4328*7c478bd9Sstevel@tonic-gate ** 4329*7c478bd9Sstevel@tonic-gate ** Parameters: 4330*7c478bd9Sstevel@tonic-gate ** val -- a pointer to the values. If NULL, do initial 4331*7c478bd9Sstevel@tonic-gate ** settings. 4332*7c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 4333*7c478bd9Sstevel@tonic-gate ** this suboption value. 4334*7c478bd9Sstevel@tonic-gate ** 4335*7c478bd9Sstevel@tonic-gate ** Returns: 4336*7c478bd9Sstevel@tonic-gate ** none. 4337*7c478bd9Sstevel@tonic-gate ** 4338*7c478bd9Sstevel@tonic-gate ** Side Effects: 4339*7c478bd9Sstevel@tonic-gate ** Initializes the TimeOuts structure 4340*7c478bd9Sstevel@tonic-gate */ 4341*7c478bd9Sstevel@tonic-gate 4342*7c478bd9Sstevel@tonic-gate void 4343*7c478bd9Sstevel@tonic-gate inittimeouts(val, sticky) 4344*7c478bd9Sstevel@tonic-gate register char *val; 4345*7c478bd9Sstevel@tonic-gate bool sticky; 4346*7c478bd9Sstevel@tonic-gate { 4347*7c478bd9Sstevel@tonic-gate register char *p; 4348*7c478bd9Sstevel@tonic-gate 4349*7c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 4350*7c478bd9Sstevel@tonic-gate sm_dprintf("inittimeouts(%s)\n", val == NULL ? "<NULL>" : val); 4351*7c478bd9Sstevel@tonic-gate if (val == NULL) 4352*7c478bd9Sstevel@tonic-gate { 4353*7c478bd9Sstevel@tonic-gate TimeOuts.to_connect = (time_t) 0 SECONDS; 4354*7c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = (time_t) 0 SECONDS; 4355*7c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = (time_t) 0 SECONDS; 4356*7c478bd9Sstevel@tonic-gate TimeOuts.to_initial = (time_t) 5 MINUTES; 4357*7c478bd9Sstevel@tonic-gate TimeOuts.to_helo = (time_t) 5 MINUTES; 4358*7c478bd9Sstevel@tonic-gate TimeOuts.to_mail = (time_t) 10 MINUTES; 4359*7c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = (time_t) 1 HOUR; 4360*7c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = (time_t) 5 MINUTES; 4361*7c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = (time_t) 1 HOUR; 4362*7c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = (time_t) 1 HOUR; 4363*7c478bd9Sstevel@tonic-gate TimeOuts.to_rset = (time_t) 5 MINUTES; 4364*7c478bd9Sstevel@tonic-gate TimeOuts.to_quit = (time_t) 2 MINUTES; 4365*7c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = (time_t) 1 HOUR; 4366*7c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = (time_t) 2 MINUTES; 4367*7c478bd9Sstevel@tonic-gate #if IDENTPROTO 4368*7c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 5 SECONDS; 4369*7c478bd9Sstevel@tonic-gate #else /* IDENTPROTO */ 4370*7c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 0 SECONDS; 4371*7c478bd9Sstevel@tonic-gate #endif /* IDENTPROTO */ 4372*7c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = (time_t) 60 SECONDS; 4373*7c478bd9Sstevel@tonic-gate TimeOuts.to_control = (time_t) 2 MINUTES; 4374*7c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = (time_t) 2 MINUTES; 4375*7c478bd9Sstevel@tonic-gate #if SASL 4376*7c478bd9Sstevel@tonic-gate TimeOuts.to_auth = (time_t) 10 MINUTES; 4377*7c478bd9Sstevel@tonic-gate #endif /* SASL */ 4378*7c478bd9Sstevel@tonic-gate #if STARTTLS 4379*7c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = (time_t) 1 HOUR; 4380*7c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 4381*7c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 4382*7c478bd9Sstevel@tonic-gate { 4383*7c478bd9Sstevel@tonic-gate sm_dprintf("Timeouts:\n"); 4384*7c478bd9Sstevel@tonic-gate sm_dprintf(" connect = %ld\n", 4385*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_connect); 4386*7c478bd9Sstevel@tonic-gate sm_dprintf(" aconnect = %ld\n", 4387*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_aconnect); 4388*7c478bd9Sstevel@tonic-gate sm_dprintf(" initial = %ld\n", 4389*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_initial); 4390*7c478bd9Sstevel@tonic-gate sm_dprintf(" helo = %ld\n", (long) TimeOuts.to_helo); 4391*7c478bd9Sstevel@tonic-gate sm_dprintf(" mail = %ld\n", (long) TimeOuts.to_mail); 4392*7c478bd9Sstevel@tonic-gate sm_dprintf(" rcpt = %ld\n", (long) TimeOuts.to_rcpt); 4393*7c478bd9Sstevel@tonic-gate sm_dprintf(" datainit = %ld\n", 4394*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datainit); 4395*7c478bd9Sstevel@tonic-gate sm_dprintf(" datablock = %ld\n", 4396*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datablock); 4397*7c478bd9Sstevel@tonic-gate sm_dprintf(" datafinal = %ld\n", 4398*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datafinal); 4399*7c478bd9Sstevel@tonic-gate sm_dprintf(" rset = %ld\n", (long) TimeOuts.to_rset); 4400*7c478bd9Sstevel@tonic-gate sm_dprintf(" quit = %ld\n", (long) TimeOuts.to_quit); 4401*7c478bd9Sstevel@tonic-gate sm_dprintf(" nextcommand = %ld\n", 4402*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_nextcommand); 4403*7c478bd9Sstevel@tonic-gate sm_dprintf(" miscshort = %ld\n", 4404*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_miscshort); 4405*7c478bd9Sstevel@tonic-gate sm_dprintf(" ident = %ld\n", (long) TimeOuts.to_ident); 4406*7c478bd9Sstevel@tonic-gate sm_dprintf(" fileopen = %ld\n", 4407*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_fileopen); 4408*7c478bd9Sstevel@tonic-gate sm_dprintf(" lhlo = %ld\n", 4409*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_lhlo); 4410*7c478bd9Sstevel@tonic-gate sm_dprintf(" control = %ld\n", 4411*7c478bd9Sstevel@tonic-gate (long) TimeOuts.to_control); 4412*7c478bd9Sstevel@tonic-gate } 4413*7c478bd9Sstevel@tonic-gate return; 4414*7c478bd9Sstevel@tonic-gate } 4415*7c478bd9Sstevel@tonic-gate 4416*7c478bd9Sstevel@tonic-gate for (;; val = p) 4417*7c478bd9Sstevel@tonic-gate { 4418*7c478bd9Sstevel@tonic-gate while (isascii(*val) && isspace(*val)) 4419*7c478bd9Sstevel@tonic-gate val++; 4420*7c478bd9Sstevel@tonic-gate if (*val == '\0') 4421*7c478bd9Sstevel@tonic-gate break; 4422*7c478bd9Sstevel@tonic-gate for (p = val; *p != '\0' && *p != ','; p++) 4423*7c478bd9Sstevel@tonic-gate continue; 4424*7c478bd9Sstevel@tonic-gate if (*p != '\0') 4425*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 4426*7c478bd9Sstevel@tonic-gate 4427*7c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 4428*7c478bd9Sstevel@tonic-gate { 4429*7c478bd9Sstevel@tonic-gate /* old syntax -- set everything */ 4430*7c478bd9Sstevel@tonic-gate TimeOuts.to_mail = convtime(val, 'm'); 4431*7c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = TimeOuts.to_mail; 4432*7c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = TimeOuts.to_mail; 4433*7c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = TimeOuts.to_mail; 4434*7c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = TimeOuts.to_mail; 4435*7c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = TimeOuts.to_mail; 4436*7c478bd9Sstevel@tonic-gate if (sticky) 4437*7c478bd9Sstevel@tonic-gate { 4438*7c478bd9Sstevel@tonic-gate setbitn(TO_MAIL, StickyTimeoutOpt); 4439*7c478bd9Sstevel@tonic-gate setbitn(TO_RCPT, StickyTimeoutOpt); 4440*7c478bd9Sstevel@tonic-gate setbitn(TO_DATAINIT, StickyTimeoutOpt); 4441*7c478bd9Sstevel@tonic-gate setbitn(TO_DATABLOCK, StickyTimeoutOpt); 4442*7c478bd9Sstevel@tonic-gate setbitn(TO_DATAFINAL, StickyTimeoutOpt); 4443*7c478bd9Sstevel@tonic-gate setbitn(TO_COMMAND, StickyTimeoutOpt); 4444*7c478bd9Sstevel@tonic-gate } 4445*7c478bd9Sstevel@tonic-gate continue; 4446*7c478bd9Sstevel@tonic-gate } 4447*7c478bd9Sstevel@tonic-gate else 4448*7c478bd9Sstevel@tonic-gate { 4449*7c478bd9Sstevel@tonic-gate register char *q = strchr(val, ':'); 4450*7c478bd9Sstevel@tonic-gate 4451*7c478bd9Sstevel@tonic-gate if (q == NULL && (q = strchr(val, '=')) == NULL) 4452*7c478bd9Sstevel@tonic-gate { 4453*7c478bd9Sstevel@tonic-gate /* syntax error */ 4454*7c478bd9Sstevel@tonic-gate continue; 4455*7c478bd9Sstevel@tonic-gate } 4456*7c478bd9Sstevel@tonic-gate *q++ = '\0'; 4457*7c478bd9Sstevel@tonic-gate settimeout(val, q, sticky); 4458*7c478bd9Sstevel@tonic-gate } 4459*7c478bd9Sstevel@tonic-gate } 4460*7c478bd9Sstevel@tonic-gate } 4461