📄 readcf.c
字号:
if (ConfigLevel < 2)
setbitn(M_7BITS, m->m_flags);
}
if (strcmp(m->m_mailer, "[TCP]") == 0)
{
#if _FFR_REMOVE_TCP_MAILER_PATH
syserr("M%s: P=[TCP] is deprecated, use P=[IPC] instead\n",
m->m_name);
#else /* _FFR_REMOVE_TCP_MAILER_PATH */
printf("M%s: Warning: P=[TCP] is deprecated, use P=[IPC] instead\n",
m->m_name);
#endif /* _FFR_REMOVE_TCP_MAILER_PATH */
}
if (strcmp(m->m_mailer, "[IPC]") == 0
#if !_FFR_REMOVE_TCP_MAILER_PATH
|| strcmp(m->m_mailer, "[TCP]") == 0
#endif /* !_FFR_REMOVE_TCP_MAILER_PATH */
)
{
/* Use the second argument for host or path to socket */
if (m->m_argv[0] == NULL || m->m_argv[1] == NULL ||
m->m_argv[1][0] == '\0')
{
syserr("M%s: too few parameters for %s mailer",
m->m_name, m->m_mailer);
}
if (strcmp(m->m_argv[0], "TCP") != 0
#if NETUNIX
&& strcmp(m->m_argv[0], "FILE") != 0
#endif /* NETUNIX */
#if !_FFR_DEPRECATE_IPC_MAILER_ARG
&& strcmp(m->m_argv[0], "IPC") != 0
#endif /* !_FFR_DEPRECATE_IPC_MAILER_ARG */
)
{
printf("M%s: Warning: first argument in %s mailer must be %s\n",
m->m_name, m->m_mailer,
#if NETUNIX
"TCP or FILE"
#else /* NETUNIX */
"TCP"
#endif /* NETUNIX */
);
}
}
else if (strcmp(m->m_mailer, "[FILE]") == 0)
{
/* Use the second argument for filename */
if (m->m_argv[0] == NULL || m->m_argv[1] == NULL ||
m->m_argv[2] != NULL)
{
syserr("M%s: too %s parameters for [FILE] mailer",
m->m_name,
(m->m_argv[0] == NULL ||
m->m_argv[1] == NULL) ? "few" : "many");
}
else if (strcmp(m->m_argv[0], "FILE") != 0)
{
syserr("M%s: first argument in [FILE] mailer must be FILE",
m->m_name);
}
}
if (strcmp(m->m_mailer, "[IPC]") == 0 ||
strcmp(m->m_mailer, "[TCP]") == 0)
{
if (m->m_mtatype == NULL)
m->m_mtatype = "dns";
if (m->m_addrtype == NULL)
m->m_addrtype = "rfc822";
if (m->m_diagtype == NULL)
{
if (m->m_argv[0] != NULL &&
strcmp(m->m_argv[0], "FILE") == 0)
m->m_diagtype = "x-unix";
else
m->m_diagtype = "smtp";
}
}
if (m->m_eol == NULL)
{
char **pp;
/* default for SMTP is \r\n; use \n for local delivery */
for (pp = m->m_argv; *pp != NULL; pp++)
{
for (p = *pp; *p != '\0'; )
{
if ((*p++ & 0377) == MACROEXPAND && *p == 'u')
break;
}
if (*p != '\0')
break;
}
if (*pp == NULL)
m->m_eol = "\r\n";
else
m->m_eol = "\n";
}
/* enter the mailer into the symbol table */
s = stab(m->m_name, ST_MAILER, ST_ENTER);
if (s->s_mailer != NULL)
{
i = s->s_mailer->m_mno;
free(s->s_mailer);
}
else
{
i = NextMailer++;
}
Mailer[i] = s->s_mailer = m;
m->m_mno = i;
}
/*
** MUNCHSTRING -- translate a string into internal form.
**
** Parameters:
** p -- the string to munch.
** delimptr -- if non-NULL, set to the pointer of the
** field delimiter character.
** delim -- the delimiter for the field.
**
** Returns:
** the munched string.
**
** Side Effects:
** the munched string is a local static buffer.
** it must be copied before the function is called again.
*/
char *
munchstring(p, delimptr, delim)
register char *p;
char **delimptr;
int delim;
{
register char *q;
bool backslash = FALSE;
bool quotemode = FALSE;
static char buf[MAXLINE];
for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++)
{
if (backslash)
{
/* everything is roughly literal */
backslash = FALSE;
switch (*p)
{
case 'r': /* carriage return */
*q++ = '\r';
continue;
case 'n': /* newline */
*q++ = '\n';
continue;
case 'f': /* form feed */
*q++ = '\f';
continue;
case 'b': /* backspace */
*q++ = '\b';
continue;
}
*q++ = *p;
}
else
{
if (*p == '\\')
backslash = TRUE;
else if (*p == '"')
quotemode = !quotemode;
else if (quotemode || *p != delim)
*q++ = *p;
else
break;
}
}
if (delimptr != NULL)
*delimptr = p;
*q++ = '\0';
return buf;
}
/*
** MAKEARGV -- break up a string into words
**
** Parameters:
** p -- the string to break up.
**
** Returns:
** a char **argv (dynamically allocated)
**
** Side Effects:
** munges p.
*/
static char **
makeargv(p)
register char *p;
{
char *q;
int i;
char **avp;
char *argv[MAXPV + 1];
/* take apart the words */
i = 0;
while (*p != '\0' && i < MAXPV)
{
q = p;
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
p++;
while (isascii(*p) && isspace(*p))
*p++ = '\0';
argv[i++] = newstr(q);
}
argv[i++] = NULL;
/* now make a copy of the argv */
avp = (char **) xalloc(sizeof *avp * i);
memmove((char *) avp, (char *) argv, sizeof *avp * i);
return avp;
}
/*
** PRINTRULES -- print rewrite rules (for debugging)
**
** Parameters:
** none.
**
** Returns:
** none.
**
** Side Effects:
** prints rewrite rules.
*/
void
printrules()
{
register struct rewrite *rwp;
register int ruleset;
for (ruleset = 0; ruleset < 10; ruleset++)
{
if (RewriteRules[ruleset] == NULL)
continue;
printf("\n----Rule Set %d:", ruleset);
for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next)
{
printf("\nLHS:");
printav(rwp->r_lhs);
printf("RHS:");
printav(rwp->r_rhs);
}
}
}
/*
** PRINTMAILER -- print mailer structure (for debugging)
**
** Parameters:
** m -- the mailer to print
**
** Returns:
** none.
*/
void
printmailer(m)
register MAILER *m;
{
int j;
printf("mailer %d (%s): P=%s S=", m->m_mno, m->m_name, m->m_mailer);
if (RuleSetNames[m->m_se_rwset] == NULL)
printf("%d/", m->m_se_rwset);
else
printf("%s/", RuleSetNames[m->m_se_rwset]);
if (RuleSetNames[m->m_sh_rwset] == NULL)
printf("%d R=", m->m_sh_rwset);
else
printf("%s R=", RuleSetNames[m->m_sh_rwset]);
if (RuleSetNames[m->m_re_rwset] == NULL)
printf("%d/", m->m_re_rwset);
else
printf("%s/", RuleSetNames[m->m_re_rwset]);
if (RuleSetNames[m->m_rh_rwset] == NULL)
printf("%d ", m->m_rh_rwset);
else
printf("%s ", RuleSetNames[m->m_rh_rwset]);
printf("M=%ld U=%d:%d F=", m->m_maxsize,
(int) m->m_uid, (int) m->m_gid);
for (j = '\0'; j <= '\177'; j++)
if (bitnset(j, m->m_flags))
(void) putchar(j);
printf(" L=%d E=", m->m_linelimit);
xputs(m->m_eol);
if (m->m_defcharset != NULL)
printf(" C=%s", m->m_defcharset);
printf(" T=%s/%s/%s",
m->m_mtatype == NULL ? "<undefined>" : m->m_mtatype,
m->m_addrtype == NULL ? "<undefined>" : m->m_addrtype,
m->m_diagtype == NULL ? "<undefined>" : m->m_diagtype);
#if _FFR_DYNAMIC_TOBUF
printf(" r=%d", m->m_maxrcpt);
#endif /* _FFR_DYNAMIC_TOBUF */
if (m->m_argv != NULL)
{
char **a = m->m_argv;
printf(" A=");
while (*a != NULL)
{
if (a != m->m_argv)
printf(" ");
xputs(*a++);
}
}
printf("\n");
}
/*
** SETOPTION -- set global processing option
**
** Parameters:
** opt -- option name.
** val -- option value (as a text string).
** safe -- set if this came from a configuration file.
** Some options (if set from the command line) will
** reset the user id to avoid security problems.
** sticky -- if set, don't let other setoptions override
** this value.
** e -- the main envelope.
**
** Returns:
** none.
**
** Side Effects:
** Sets options as implied by the arguments.
*/
static BITMAP256 StickyOpt; /* set if option is stuck */
#if NAMED_BIND
static struct resolverflags
{
char *rf_name; /* name of the flag */
long rf_bits; /* bits to set/clear */
} ResolverFlags[] =
{
{ "debug", RES_DEBUG },
{ "aaonly", RES_AAONLY },
{ "usevc", RES_USEVC },
{ "primary", RES_PRIMARY },
{ "igntc", RES_IGNTC },
{ "recurse", RES_RECURSE },
{ "defnames", RES_DEFNAMES },
{ "stayopen", RES_STAYOPEN },
{ "dnsrch", RES_DNSRCH },
{ "true", 0 }, /* avoid error on old syntax */
{ NULL, 0 }
};
#endif /* NAMED_BIND */
#define OI_NONE 0 /* no special treatment */
#define OI_SAFE 0x0001 /* safe for random people to use */
#define OI_SUBOPT 0x0002 /* option has suboptions */
static struct optioninfo
{
char *o_name; /* long name of option */
u_char o_code; /* short name of option */
u_short o_flags; /* option flags */
} OptionTab[] =
{
#if defined(SUN_EXTENSIONS) && defined(REMOTE_MODE)
{ "RemoteMode", '>', OI_NONE },
#endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */
{ "SevenBitInput", '7', OI_SAFE },
#if MIME8TO7
{ "EightBitMode", '8', OI_SAFE },
#endif /* MIME8TO7 */
{ "AliasFile", 'A', OI_NONE },
{ "AliasWait", 'a', OI_NONE },
{ "BlankSub", 'B', OI_NONE },
{ "MinFreeBlocks", 'b', OI_SAFE },
{ "CheckpointInterval", 'C', OI_SAFE },
{ "HoldExpensive", 'c', OI_NONE },
#if !_FFR_REMOVE_AUTOREBUILD
{ "AutoRebuildAliases", 'D', OI_NONE },
#endif /* !_FFR_REMOVE_AUTOREBUILD */
{ "DeliveryMode", 'd', OI_SAFE },
{ "ErrorHeader", 'E', OI_NONE },
{ "ErrorMode", 'e', OI_SAFE },
{ "TempFileMode", 'F', OI_NONE },
{ "SaveFromLine", 'f', OI_NONE },
{ "MatchGECOS", 'G', OI_NONE },
{ "HelpFile", 'H', OI_NONE },
{ "MaxHopCount", 'h', OI_NONE },
{ "ResolverOptions", 'I', OI_NONE },
{ "IgnoreDots", 'i', OI_SAFE },
{ "ForwardPath", 'J', OI_NONE },
{ "SendMimeErrors", 'j', OI_SAFE },
{ "ConnectionCacheSize", 'k', OI_NONE },
{ "ConnectionCacheTimeout", 'K', OI_NONE },
{ "UseErrorsTo", 'l', OI_NONE },
{ "LogLevel", 'L', OI_SAFE },
{ "MeToo", 'm', OI_SAFE },
{ "CheckAliases", 'n', OI_NONE },
{ "OldStyleHeaders", 'o', OI_SAFE },
{ "DaemonPortOptions", 'O', OI_NONE },
{ "PrivacyOptions", 'p', OI_SAFE },
{ "PostmasterCopy", 'P', OI_NONE },
{ "QueueFactor", 'q', OI_NONE },
{ "QueueDirectory", 'Q', OI_NONE },
{ "DontPruneRoutes", 'R', OI_NONE },
{ "Timeout", 'r', OI_SUBOPT },
{ "StatusFile", 'S', OI_NONE },
{ "SuperSafe", 's', OI_SAFE },
{ "QueueTimeout", 'T', OI_NONE },
{ "TimeZoneSpec", 't', OI_NONE },
{ "UserDatabaseSpec", 'U', OI_NONE },
{ "DefaultUser", 'u', OI_NONE },
{ "FallbackMXhost", 'V', OI_NONE },
{ "Verbose", 'v', OI_SAFE },
{ "TryNullMXList", 'w', OI_NONE },
{ "QueueLA", 'x', OI_NONE },
{ "RefuseLA", 'X', OI_NONE },
{ "RecipientFactor", 'y', OI_NONE },
{ "ForkEachJob", 'Y', OI_NONE },
{ "ClassFactor", 'z', OI_NONE },
{ "RetryFactor", 'Z', OI_NONE },
#define O_QUEUESORTORD 0x81
{ "QueueSortOrder", O_QUEUESORTORD, OI_SAFE },
#define O_HOSTSFILE 0x82
{ "HostsFile", O_HOSTSFILE, OI_NONE },
#define O_MQA 0x83
{ "MinQueueAge", O_MQA, OI_SAFE },
#define O_DEFCHARSET 0x85
{ "DefaultCharSet", O_DEFCHARSET, OI_SAFE },
#define O_SSFILE 0x86
{ "ServiceSwitchFile", O_SSFILE, OI_NONE },
#define O_DIALDELAY 0x87
{ "DialDelay", O_DIALDELAY, OI_SAFE },
#define O_NORCPTACTION 0x88
{ "NoRecipientAction", O_NORCPTACTION, OI_SAFE },
#define O_SAFEFILEENV 0x89
{ "SafeFileEnvironment", O_SAFEFILEENV, OI_NONE },
#define O_MAXMSGSIZE 0x8a
{ "MaxMessageSize", O_MAXMSGSIZE, OI_NONE },
#define O_COLONOKINADDR 0x8b
{ "ColonOkInAddr", O_COLONOKINADDR, OI_SAFE },
#define O_MAXQUEUERUN 0x8c
{ "MaxQueueRunSize", O_MAXQUEUERUN, OI_SAFE },
#define O_MAXCHILDREN 0x8d
{ "MaxDaemonChildren", O_MAXCHILDREN, OI_NONE },
#define O_KEEPCNAMES 0x8e
{ "DontExpandCnames", O_KEEPCNAMES, OI_NONE },
#define O_MUSTQUOTE 0x8f
{ "MustQuoteChars", O_MUSTQUOTE, OI_NONE },
#define O_SMTPGREETING 0x90
{ "SmtpGreetingMessage", O_SMTPGREETING, OI_NONE },
#define O_UNIXFROM 0x91
{ "UnixFromLine", O_UNIXFROM, OI_NONE },
#define O_OPCHARS 0x92
{ "OperatorChars", O_OPCHARS, OI_NONE },
#define O_DONTINITGRPS 0x93
{ "DontInitGroups", O_DONTINITGRPS, OI_NONE },
#define O_SLFH 0x94
{ "SingleLineFromHeader", O_SLFH, OI_SAFE },
#define O_ABH 0x95
{ "AllowBogusHELO", O_ABH, OI_SAFE },
#define O_CONNTHROT 0x97
{ "ConnectionRateThrottle", O_CONNTHROT, OI_NONE },
#define O_UGW 0x99
{ "UnsafeGroupWrites", O_UGW, OI_NONE },
#define O_DBLBOUNCE 0x9a
{ "DoubleBounceAddress", O_DBLBOUNCE, OI_NONE },
#define O_HSDIR 0x9b
{ "HostStatusDirectory", O_HSDIR, OI_NONE },
#define O_SINGTHREAD 0x9c
{ "SingleThreadDelivery", O_SINGTHREAD, OI_NONE },
#define O_RUNASUSER 0x9d
{ "RunAsUser", O_RUNASUSER, OI_NONE },
#define O_DSN_RRT 0x9e
{ "RrtImpliesDsn", O_DSN_RRT, OI_NONE },
#define O_PIDFILE 0x9f
{ "PidFile", O_PIDFILE, OI_NONE },
#define O_DONTBLAMESENDMAIL 0xa0
{ "DontBlameSendmail", O_DONTBLAMESENDMAIL, OI_NONE },
#define O_DPI 0xa1
{ "DontProbeInterfaces", O_DPI, OI_NONE },
#define O_MAXRCPT 0xa2
{ "MaxRecipientsPerMessage", O_MAXRCPT, OI_SAFE },
#define O_DEADLETTER 0xa3
{ "DeadLetterDrop", O_DEADLETTER, OI_NONE },
#if _FFR_DONTLOCKFILESFORREAD_OPTION
# define O_DONTLOCK 0xa4
{ "DontLockFilesForRead", O_DONTLOCK, OI_NONE },
#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
#define O_MAXALIASRCSN 0xa5
{ "MaxAliasRecursion", O_MAXALIASRCSN, OI_NONE },
#define O_CNCTONLYTO 0xa6
{ "ConnectOnlyTo", O_CNCTONLYTO, OI_NONE },
#define O_TRUSTUSER 0xa7
{ "TrustedUser", O_TRUSTUSER, OI_NONE },
#define O_MAXMIMEHDRLEN 0xa8
{ "MaxMimeHeaderLength", O_MAXMIMEHDRLEN, OI_NONE },
#define O_CONTROLSOCKET 0xa9
{ "ControlSocketName", O_CONTROLSOCKET, OI_NONE },
#define O_MAXHDRSLEN 0xaa
{ "MaxHeadersLength", O_MAXHDRSLEN, OI_NONE },
#if _FFR_MAX_FORWARD_ENTRIES
# define O_MAXFORWARD 0xab
{ "MaxForwardEntries", O_MAXFORWARD, OI_NONE },
#endif /* _FFR_MAX_FORWARD_ENTRIES */
#define O_PROCTITLEPREFIX 0xac
{ "ProcessTitlePrefix", O_PROCTITLEPREFIX, OI_NONE },
#define O_SASLINFO 0xad
#if _FFR_ALLOW_SASLINFO
{ "DefaultAuthInfo", O_SASLINFO, OI_SAFE },
#else /* _FFR_ALLOW_SASLINFO */
{ "DefaultAuthInfo", O_SASLINFO, OI_NONE },
#endif /* _FFR_ALLOW_SASLINFO */
#define O_SASLMECH 0xae
{ "AuthMechanisms", O_SASLMECH, OI_NONE },
#define O_CLIENTPORT 0xaf
{ "ClientPortOptions", O_CLIENTPORT, OI_NONE },
#define O_DF_BUFSIZE 0xb0
{ "DataFileBufferSize", O_DF_BUFSIZE, OI_NONE },
#define O_XF_BUFSIZE 0xb1
{ "XscriptFileBufferSize", O_XF_BUFSIZE, OI_NONE },
# define O_LDAPDEFAULTSPEC 0xb2
{ "LDAPDefaultSpec", O_LDAPDEFAULTSPEC, OI_NONE },
#if _FFR_QUEUEDELAY
#define O_QUEUEDELAY 0xb3
{ "QueueDelay", O_QUEUEDELAY, OI_NONE },
#endif /* _FFR_QUEUEDELAY */
# define O_SRVCERTFILE 0xb4
{ "ServerCertFile", O_SRVCERTFILE, OI_NONE },
# define O_SRVKEYFILE 0xb5
{ "Serverkeyfile", O_SRVKEYFILE, OI_NONE },
# define O_CLTCERTFILE 0xb6
{ "ClientCertFile", O_CLTCERTFILE, OI_NONE },
# define O_CLTKEYFILE 0xb7
{ "Clientkeyfile", O_CLTKEYFILE, OI_NONE },
# define O_CACERTFILE 0xb8
{ "CACERTFile", O_CACERTFILE, OI_NONE },
# define O_CACERTPATH 0xb9
{ "CACERTPath", O_CACERTPATH, OI_NONE },
# define O_DHPARAMS 0xba
{ "DHParameters", O_DHPARAMS, OI_NONE },
#if _FFR_MILTER
#define O_INPUTMILTER 0xbb
{ "InputMailFilters", O_INPUTMILTER, OI_NONE },
#define O_MILTER 0xbc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -