📄 readcf.c
字号:
DefUid = -1;
pw = sm_getpwnam(val);
if (pw == NULL)
syserr("readcf: option u: unknown user %s", val);
else
{
DefUid = pw->pw_uid;
DefGid = pw->pw_gid;
DefUser = newstr(pw->pw_name);
}
}
#ifdef UID_MAX
if (DefUid > UID_MAX)
{
syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored",
DefUid, UID_MAX);
}
#endif /* UID_MAX */
/* handle the group if it is there */
if (*p == '\0')
break;
val = p;
goto g_opt;
case 'V': /* fallback MX host */
if (val[0] != '\0')
FallBackMX = newstr(val);
break;
case 'v': /* run in verbose mode */
Verbose = atobool(val) ? 1 : 0;
break;
case 'w': /* if we are best MX, try host directly */
TryNullMXList = atobool(val);
break;
/* 'W' available -- was wizard password */
case 'x': /* load avg at which to auto-queue msgs */
QueueLA = atoi(val);
break;
case 'X': /* load avg at which to auto-reject connections */
RefuseLA = atoi(val);
break;
case 'y': /* work recipient factor */
WkRecipFact = atoi(val);
break;
case 'Y': /* fork jobs during queue runs */
ForkQueueRuns = atobool(val);
break;
case 'z': /* work message class factor */
WkClassFact = atoi(val);
break;
case 'Z': /* work time factor */
WkTimeFact = atoi(val);
break;
case O_QUEUESORTORD: /* queue sorting order */
switch (*val)
{
case 'h': /* Host first */
case 'H':
QueueSortOrder = QSO_BYHOST;
break;
case 'p': /* Priority order */
case 'P':
QueueSortOrder = QSO_BYPRIORITY;
break;
case 't': /* Submission time */
case 'T':
QueueSortOrder = QSO_BYTIME;
break;
case 'f': /* File Name */
case 'F':
QueueSortOrder = QSO_BYFILENAME;
break;
default:
syserr("Invalid queue sort order \"%s\"", val);
}
break;
#if _FFR_QUEUEDELAY
case O_QUEUEDELAY: /* queue delay algorithm */
switch (*val)
{
case 'e': /* exponential */
case 'E':
QueueAlg = QD_EXP;
QueueInitDelay = 10 MINUTES;
QueueMaxDelay = 2 HOURS;
p = strchr(val, '/');
if (p != NULL)
{
char *q;
*p++ = '\0';
q = strchr(p, '/');
if (q != NULL)
*q++ = '\0';
QueueInitDelay = convtime(p, 's');
if (q != NULL)
{
QueueMaxDelay = convtime(q, 's');
}
}
break;
case 'l': /* linear */
case 'L':
QueueAlg = QD_LINEAR;
break;
default:
syserr("Invalid queue delay algorithm \"%s\"", val);
}
break;
#endif /* _FFR_QUEUEDELAY */
case O_HOSTSFILE: /* pathname of /etc/hosts file */
HostsFile = newstr(val);
break;
case O_MQA: /* minimum queue age between deliveries */
MinQueueAge = convtime(val, 'm');
break;
case O_DEFCHARSET: /* default character set for mimefying */
DefaultCharSet = newstr(denlstring(val, TRUE, TRUE));
break;
case O_SSFILE: /* service switch file */
ServiceSwitchFile = newstr(val);
break;
case O_DIALDELAY: /* delay for dial-on-demand operation */
DialDelay = convtime(val, 's');
break;
case O_NORCPTACTION: /* what to do if no recipient */
if (strcasecmp(val, "none") == 0)
NoRecipientAction = NRA_NO_ACTION;
else if (strcasecmp(val, "add-to") == 0)
NoRecipientAction = NRA_ADD_TO;
else if (strcasecmp(val, "add-apparently-to") == 0)
NoRecipientAction = NRA_ADD_APPARENTLY_TO;
else if (strcasecmp(val, "add-bcc") == 0)
NoRecipientAction = NRA_ADD_BCC;
else if (strcasecmp(val, "add-to-undisclosed") == 0)
NoRecipientAction = NRA_ADD_TO_UNDISCLOSED;
else
syserr("Invalid NoRecipientAction: %s", val);
break;
case O_SAFEFILEENV: /* chroot() environ for writing to files */
SafeFileEnv = newstr(val);
break;
case O_MAXMSGSIZE: /* maximum message size */
MaxMessageSize = atol(val);
break;
case O_COLONOKINADDR: /* old style handling of colon addresses */
ColonOkInAddr = atobool(val);
break;
case O_MAXQUEUERUN: /* max # of jobs in a single queue run */
MaxQueueRun = atol(val);
break;
case O_MAXCHILDREN: /* max # of children of daemon */
MaxChildren = atoi(val);
break;
#if _FFR_MAX_FORWARD_ENTRIES
case O_MAXFORWARD: /* max # of forward entries */
MaxForwardEntries = atoi(val);
break;
#endif /* _FFR_MAX_FORWARD_ENTRIES */
case O_KEEPCNAMES: /* don't expand CNAME records */
DontExpandCnames = atobool(val);
break;
case O_MUSTQUOTE: /* must quote these characters in phrases */
(void) strlcpy(buf, "@,;:\\()[]", sizeof buf);
if (strlen(val) < (SIZE_T) sizeof buf - 10)
(void) strlcat(buf, val, sizeof buf);
else
printf("Warning: MustQuoteChars too long, ignored.\n");
MustQuoteChars = newstr(buf);
break;
case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */
SmtpGreeting = newstr(munchstring(val, NULL, '\0'));
break;
case O_UNIXFROM: /* UNIX From_ line (old $l macro) */
UnixFromLine = newstr(munchstring(val, NULL, '\0'));
break;
case O_OPCHARS: /* operator characters (old $o macro) */
if (OperatorChars != NULL)
printf("Warning: OperatorChars is being redefined.\n It should only be set before ruleset definitions.\n");
OperatorChars = newstr(munchstring(val, NULL, '\0'));
break;
case O_DONTINITGRPS: /* don't call initgroups(3) */
DontInitGroups = atobool(val);
break;
case O_SLFH: /* make sure from fits on one line */
SingleLineFromHeader = atobool(val);
break;
case O_ABH: /* allow HELO commands with syntax errors */
AllowBogusHELO = atobool(val);
break;
case O_CONNTHROT: /* connection rate throttle */
ConnRateThrottle = atoi(val);
break;
case O_UGW: /* group writable files are unsafe */
if (!atobool(val))
{
setbitn(DBS_GROUPWRITABLEFORWARDFILESAFE,
DontBlameSendmail);
setbitn(DBS_GROUPWRITABLEINCLUDEFILESAFE,
DontBlameSendmail);
}
break;
case O_DBLBOUNCE: /* address to which to send double bounces */
if (val[0] != '\0')
DoubleBounceAddr = newstr(val);
else
syserr("readcf: option DoubleBounceAddress: value required");
break;
case O_HSDIR: /* persistent host status directory */
if (val[0] != '\0')
HostStatDir = newstr(val);
break;
case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */
SingleThreadDelivery = atobool(val);
break;
case O_RUNASUSER: /* run bulk of code as this user */
for (p = val; *p != '\0'; p++)
{
if (*p == '.' || *p == '/' || *p == ':')
{
*p++ = '\0';
break;
}
}
if (isascii(*val) && isdigit(*val))
{
if (can_setuid)
RunAsUid = atoi(val);
}
else
{
register struct passwd *pw;
pw = sm_getpwnam(val);
if (pw == NULL)
syserr("readcf: option RunAsUser: unknown user %s", val);
else if (can_setuid)
{
if (*p == '\0')
RunAsUserName = newstr(val);
RunAsUid = pw->pw_uid;
RunAsGid = pw->pw_gid;
}
}
#ifdef UID_MAX
if (RunAsUid > UID_MAX)
{
syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored",
RunAsUid, UID_MAX);
}
#endif /* UID_MAX */
if (*p != '\0')
{
if (isascii(*p) && isdigit(*p))
{
if (can_setuid)
RunAsGid = atoi(p);
}
else
{
register struct group *gr;
gr = getgrnam(p);
if (gr == NULL)
syserr("readcf: option RunAsUser: unknown group %s",
p);
else if (can_setuid)
RunAsGid = gr->gr_gid;
}
}
if (tTd(47, 5))
dprintf("readcf: RunAsUser = %d:%d\n",
(int)RunAsUid, (int)RunAsGid);
break;
case O_DSN_RRT:
RrtImpliesDsn = atobool(val);
break;
case O_PIDFILE:
if (PidFile != NULL)
free(PidFile);
PidFile = newstr(val);
break;
case O_DONTBLAMESENDMAIL:
p = val;
for (;;)
{
register struct dbsval *dbs;
extern struct dbsval DontBlameSendmailValues[];
while (isascii(*p) && (isspace(*p) || ispunct(*p)))
p++;
if (*p == '\0')
break;
val = p;
while (isascii(*p) && isalnum(*p))
p++;
if (*p != '\0')
*p++ = '\0';
for (dbs = DontBlameSendmailValues;
dbs->dbs_name != NULL; dbs++)
{
if (strcasecmp(val, dbs->dbs_name) == 0)
break;
}
if (dbs->dbs_name == NULL)
syserr("readcf: DontBlameSendmail option: %s unrecognized", val);
else if (dbs->dbs_flag == DBS_SAFE)
clrbitmap(DontBlameSendmail);
else
setbitn(dbs->dbs_flag, DontBlameSendmail);
}
sticky = FALSE;
break;
case O_DPI:
DontProbeInterfaces = atobool(val);
break;
case O_MAXRCPT:
MaxRcptPerMsg = atoi(val);
break;
case O_DEADLETTER:
if (DeadLetterDrop != NULL)
free(DeadLetterDrop);
DeadLetterDrop = newstr(val);
break;
#if _FFR_DONTLOCKFILESFORREAD_OPTION
case O_DONTLOCK:
DontLockReadFiles = atobool(val);
break;
#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
case O_MAXALIASRCSN:
MaxAliasRecursion = atoi(val);
break;
case O_CNCTONLYTO:
/* XXX should probably use gethostbyname */
#if NETINET || NETINET6
# if NETINET6
if (inet_addr(val) == INADDR_NONE)
{
ConnectOnlyTo.sa.sa_family = AF_INET6;
if (inet_pton(AF_INET6, val,
&ConnectOnlyTo.sin6.sin6_addr) != 1)
syserr("readcf: option ConnectOnlyTo: invalid IP address %s",
val);
}
else
# endif /* NETINET6 */
{
ConnectOnlyTo.sa.sa_family = AF_INET;
ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val);
}
#endif /* NETINET || NETINET6 */
break;
case O_TRUSTUSER:
#if HASFCHOWN
if (isascii(*val) && isdigit(*val))
TrustedUid = atoi(val);
else
{
register struct passwd *pw;
TrustedUid = 0;
pw = sm_getpwnam(val);
if (pw == NULL)
syserr("readcf: option TrustedUser: unknown user %s", val);
else
TrustedUid = pw->pw_uid;
}
# ifdef UID_MAX
if (TrustedUid > UID_MAX)
{
syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)",
TrustedUid, UID_MAX);
TrustedUid = 0;
}
# endif /* UID_MAX */
#else /* HASFCHOWN */
syserr("readcf: option TrustedUser: can not be used on systems which do not support fchown()");
#endif /* HASFCHOWN */
break;
case O_MAXMIMEHDRLEN:
p = strchr(val, '/');
if (p != NULL)
*p++ = '\0';
MaxMimeHeaderLength = atoi(val);
if (p != NULL && *p != '\0')
MaxMimeFieldLength = atoi(p);
else
MaxMimeFieldLength = MaxMimeHeaderLength / 2;
if (MaxMimeHeaderLength < 0)
MaxMimeHeaderLength = 0;
else if (MaxMimeHeaderLength < 128)
printf("Warning: MaxMimeHeaderLength: header length limit set lower than 128\n");
if (MaxMimeFieldLength < 0)
MaxMimeFieldLength = 0;
else if (MaxMimeFieldLength < 40)
printf("Warning: MaxMimeHeaderLength: field length limit set lower than 40\n");
break;
case O_CONTROLSOCKET:
if (ControlSocketName != NULL)
free(ControlSocketName);
ControlSocketName = newstr(val);
break;
case O_MAXHDRSLEN:
MaxHeadersLength = atoi(val);
if (MaxHeadersLength > 0 &&
MaxHeadersLength < (MAXHDRSLEN / 2))
printf("Warning: MaxHeadersLength: headers length limit set lower than %d\n", (MAXHDRSLEN / 2));
break;
case O_PROCTITLEPREFIX:
if (ProcTitlePrefix != NULL)
free(ProcTitlePrefix);
ProcTitlePrefix = newstr(val);
break;
#if SASL
case O_SASLINFO:
#if _FFR_ALLOW_SASLINFO
/*
** Allow users to select their own authinfo file.
** However, this is not a "perfect" solution.
** If mail is queued, the authentication info
** will not be used in subsequent delivery attempts.
** If we really want to support this, then it has
** to be stored in the queue file.
*/
if (!bitset(SUBMIT_MSA, SubmitMode) && RealUid != 0 &&
RunAsUid != RealUid)
{
errno = 0;
syserr("Error: %s only allowed with -U\n",
o->o_name == NULL ? "<unknown>" : o->o_name);
ExitStat = EX_USAGE;
break;
}
#endif /* _FFR_ALLOW_SASLINFO */
if (SASLInfo != NULL)
free(SASLInfo);
SASLInfo = newstr(val);
break;
case O_SASLMECH:
if (AuthMechanisms != NULL)
free(AuthMechanisms);
if (*val != '\0')
AuthMechanisms = newstr(val);
else
AuthMechanisms = NULL;
break;
case O_SASLOPTS:
while (val != NULL && *val != '\0')
{
switch(*val)
{
case 'A':
SASLOpts |= SASL_AUTH_AUTH;
break;
# if _FFR_SASL_OPTS
case 'a':
SASLOpts |= SASL_SEC_NOACTIVE;
break;
case 'c':
SASLOpts |= SASL_SEC_PASS_CREDENTIALS;
break;
case 'd':
SASLOpts |= SASL_SEC_NODICTIONARY;
break;
case 'f':
SASLOpts |= SASL_SEC_FORWARD_SECRECY;
break;
case 'p':
SASLOpts |= SASL_SEC_NOPLAINTEXT;
break;
case 'y':
SASLOpts |= SASL_SEC_NOANONYMOUS;
break;
# endif /* _FFR_SASL_OPTS */
default:
printf("Warning: Option: %s unknown parameter '%c'\n",
o->o_name == NULL ? "<unknown>"
: o->o_name,
(isascii(*val) && isprint(*val)) ? *val
: '?');
break;
}
++val;
val = strpbrk(val, ", \t");
if (val != NULL)
++val;
}
break;
#else /* SASL */
case O_SASLINFO:
ca
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -