📄 readcf.c
字号:
if (nmaps > 0 && nmaps <= MAXMAPSTACK)
{
register int mapno;
for (mapno = 0; mapno < nmaps && !UseNameServer; mapno++)
{
if (strcmp(maptype[mapno], "dns") == 0)
UseNameServer = TRUE;
}
}
#ifdef HESIOD
nmaps = switch_map_find("passwd", maptype, mapreturn);
UseHesiod = FALSE;
if (nmaps > 0 && nmaps <= MAXMAPSTACK)
{
register int mapno;
for (mapno = 0; mapno < nmaps && !UseHesiod; mapno++)
{
if (strcmp(maptype[mapno], "hesiod") == 0)
UseHesiod = TRUE;
}
}
#endif /* HESIOD */
}
}
/*
** TRANSLATE_DOLLARS -- convert $x into internal form
**
** Actually does all appropriate pre-processing of a config line
** to turn it into internal form.
**
** Parameters:
** bp -- the buffer to translate.
**
** Returns:
** None. The buffer is translated in place. Since the
** translations always make the buffer shorter, this is
** safe without a size parameter.
*/
void
translate_dollars(bp)
char *bp;
{
register char *p;
auto char *ep;
for (p = bp; *p != '\0'; p++)
{
if (*p == '#' && p > bp && ConfigLevel >= 3)
{
/* this is an on-line comment */
register char *e;
switch (*--p & 0377)
{
case MACROEXPAND:
/* it's from $# -- let it go through */
p++;
break;
case '\\':
/* it's backslash escaped */
(void) strlcpy(p, p + 1, strlen(p));
break;
default:
/* delete leading white space */
while (isascii(*p) && isspace(*p) &&
*p != '\n' && p > bp)
p--;
if ((e = strchr(++p, '\n')) != NULL)
(void) strlcpy(p, e, strlen(p));
else
*p-- = '\0';
break;
}
continue;
}
if (*p != '$' || p[1] == '\0')
continue;
if (p[1] == '$')
{
/* actual dollar sign.... */
(void) strlcpy(p, p + 1, strlen(p));
continue;
}
/* convert to macro expansion character */
*p++ = MACROEXPAND;
/* special handling for $=, $~, $&, and $? */
if (*p == '=' || *p == '~' || *p == '&' || *p == '?')
p++;
/* convert macro name to code */
*p = macid(p, &ep);
if (ep != p + 1)
(void) strlcpy(p + 1, ep, strlen(p + 1));
}
/* strip trailing white space from the line */
while (--p > bp && isascii(*p) && isspace(*p))
*p = '\0';
}
/*
** TOOMANY -- signal too many of some option
**
** Parameters:
** id -- the id of the error line
** maxcnt -- the maximum possible values
**
** Returns:
** none.
**
** Side Effects:
** gives a syserr.
*/
static void
toomany(id, maxcnt)
int id;
int maxcnt;
{
syserr("too many %c lines, %d max", id, maxcnt);
}
/*
** FILECLASS -- read members of a class from a file
**
** Parameters:
** class -- class to define.
** filename -- name of file to read.
** fmt -- scanf string to use for match.
** safe -- if set, this is a safe read.
** optional -- if set, it is not an error for the file to
** not exist.
**
** Returns:
** none
**
** Side Effects:
**
** puts all lines in filename that match a scanf into
** the named class.
*/
static void
fileclass(class, filename, fmt, safe, optional)
int class;
char *filename;
char *fmt;
bool safe;
bool optional;
{
FILE *f;
long sff;
pid_t pid;
register char *p;
char buf[MAXLINE];
if (tTd(37, 2))
dprintf("fileclass(%s, fmt=%s)\n", filename, fmt);
if (filename[0] == '|')
{
auto int fd;
int i;
char *argv[MAXPV + 1];
i = 0;
for (p = strtok(&filename[1], " \t"); p != NULL; p = strtok(NULL, " \t"))
{
if (i >= MAXPV)
break;
argv[i++] = p;
}
argv[i] = NULL;
pid = prog_open(argv, &fd, CurEnv);
if (pid < 0)
f = NULL;
else
f = fdopen(fd, "r");
}
else
{
pid = -1;
sff = SFF_REGONLY;
if (!bitnset(DBS_CLASSFILEINUNSAFEDIRPATH, DontBlameSendmail))
sff |= SFF_SAFEDIRPATH;
if (!bitnset(DBS_LINKEDCLASSFILEINWRITABLEDIR,
DontBlameSendmail))
sff |= SFF_NOWLINK;
if (safe)
sff |= SFF_OPENASROOT;
if (DontLockReadFiles)
sff |= SFF_NOLOCK;
f = safefopen(filename, O_RDONLY, 0, sff);
}
if (f == NULL)
{
if (!optional)
syserr("fileclass: cannot open '%s'", filename);
return;
}
while (fgets(buf, sizeof buf, f) != NULL)
{
#if SCANF
char wordbuf[MAXLINE + 1];
#endif /* SCANF */
if (buf[0] == '#')
continue;
#if SCANF
if (sscanf(buf, fmt, wordbuf) != 1)
continue;
p = wordbuf;
#else /* SCANF */
p = buf;
#endif /* SCANF */
/*
** Break up the match into words.
*/
while (*p != '\0')
{
register char *q;
/* strip leading spaces */
while (isascii(*p) && isspace(*p))
p++;
if (*p == '\0')
break;
/* find the end of the word */
q = p;
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
/* enter the word in the symbol table */
setclass(class, q);
}
}
(void) fclose(f);
if (pid > 0)
(void) waitfor(pid);
}
/*
** MAKEMAILER -- define a new mailer.
**
** Parameters:
** line -- description of mailer. This is in labeled
** fields. The fields are:
** A -- the argv for this mailer
** C -- the character set for MIME conversions
** D -- the directory to run in
** E -- the eol string
** F -- the flags associated with the mailer
** L -- the maximum line length
** M -- the maximum message size
** N -- the niceness at which to run
** P -- the path to the mailer
** R -- the recipient rewriting set
** S -- the sender rewriting set
** T -- the mailer type (for DSNs)
** U -- the uid to run as
** W -- the time to wait at the end
** The first word is the canonical name of the mailer.
**
** Returns:
** none.
**
** Side Effects:
** enters the mailer into the mailer table.
*/
void
makemailer(line)
char *line;
{
register char *p;
register struct mailer *m;
register STAB *s;
int i;
char fcode;
auto char *endp;
extern int NextMailer;
/* allocate a mailer and set up defaults */
m = (struct mailer *) xalloc(sizeof *m);
memset((char *) m, '\0', sizeof *m);
/* collect the mailer name */
for (p = line; *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); p++)
continue;
if (*p != '\0')
*p++ = '\0';
if (line[0] == '\0')
syserr("name required for mailer");
m->m_name = newstr(line);
/* now scan through and assign info from the fields */
while (*p != '\0')
{
auto char *delimptr;
while (*p != '\0' && (*p == ',' || (isascii(*p) && isspace(*p))))
p++;
/* p now points to field code */
fcode = *p;
while (*p != '\0' && *p != '=' && *p != ',')
p++;
if (*p++ != '=')
{
syserr("mailer %s: `=' expected", m->m_name);
return;
}
while (isascii(*p) && isspace(*p))
p++;
/* p now points to the field body */
p = munchstring(p, &delimptr, ',');
/* install the field into the mailer struct */
switch (fcode)
{
case 'P': /* pathname */
if (*p == '\0')
syserr("mailer %s: empty path name", m->m_name);
m->m_mailer = newstr(p);
break;
case 'F': /* flags */
for (; *p != '\0'; p++)
if (!(isascii(*p) && isspace(*p)))
setbitn(*p, m->m_flags);
break;
case 'S': /* sender rewriting ruleset */
case 'R': /* recipient rewriting ruleset */
i = strtorwset(p, &endp, ST_ENTER);
if (i < 0)
return;
if (fcode == 'S')
m->m_sh_rwset = m->m_se_rwset = i;
else
m->m_rh_rwset = m->m_re_rwset = i;
p = endp;
if (*p++ == '/')
{
i = strtorwset(p, NULL, ST_ENTER);
if (i < 0)
return;
if (fcode == 'S')
m->m_sh_rwset = i;
else
m->m_rh_rwset = i;
}
break;
case 'E': /* end of line string */
if (*p == '\0')
syserr("mailer %s: null end-of-line string",
m->m_name);
m->m_eol = newstr(p);
break;
case 'A': /* argument vector */
if (*p == '\0')
syserr("mailer %s: null argument vector",
m->m_name);
m->m_argv = makeargv(p);
break;
case 'M': /* maximum message size */
m->m_maxsize = atol(p);
break;
case 'm': /* maximum messages per connection */
m->m_maxdeliveries = atoi(p);
break;
#if _FFR_DYNAMIC_TOBUF
case 'r': /* max recipient per envelope */
m->m_maxrcpt = atoi(p);
break;
#endif /* _FFR_DYNAMIC_TOBUF */
case 'L': /* maximum line length */
m->m_linelimit = atoi(p);
if (m->m_linelimit < 0)
m->m_linelimit = 0;
break;
case 'N': /* run niceness */
m->m_nice = atoi(p);
break;
case 'D': /* working directory */
if (*p == '\0')
syserr("mailer %s: null working directory",
m->m_name);
m->m_execdir = newstr(p);
break;
case 'C': /* default charset */
if (*p == '\0')
syserr("mailer %s: null charset", m->m_name);
m->m_defcharset = newstr(p);
break;
case 'T': /* MTA-Name/Address/Diagnostic types */
/* extract MTA name type; default to "dns" */
m->m_mtatype = newstr(p);
p = strchr(m->m_mtatype, '/');
if (p != NULL)
{
*p++ = '\0';
if (*p == '\0')
p = NULL;
}
if (*m->m_mtatype == '\0')
m->m_mtatype = "dns";
/* extract address type; default to "rfc822" */
m->m_addrtype = p;
if (p != NULL)
p = strchr(p, '/');
if (p != NULL)
{
*p++ = '\0';
if (*p == '\0')
p = NULL;
}
if (m->m_addrtype == NULL || *m->m_addrtype == '\0')
m->m_addrtype = "rfc822";
/* extract diagnostic type; default to "smtp" */
m->m_diagtype = p;
if (m->m_diagtype == NULL || *m->m_diagtype == '\0')
m->m_diagtype = "smtp";
break;
case 'U': /* user id */
if (isascii(*p) && !isdigit(*p))
{
char *q = p;
struct passwd *pw;
while (*p != '\0' && isascii(*p) &&
(isalnum(*p) || strchr("-_", *p) != NULL))
p++;
while (isascii(*p) && isspace(*p))
*p++ = '\0';
if (*p != '\0')
*p++ = '\0';
if (*q == '\0')
syserr("mailer %s: null user name",
m->m_name);
pw = sm_getpwnam(q);
if (pw == NULL)
syserr("readcf: mailer U= flag: unknown user %s", q);
else
{
m->m_uid = pw->pw_uid;
m->m_gid = pw->pw_gid;
}
}
else
{
auto char *q;
m->m_uid = strtol(p, &q, 0);
p = q;
while (isascii(*p) && isspace(*p))
p++;
if (*p != '\0')
p++;
}
while (isascii(*p) && isspace(*p))
p++;
if (*p == '\0')
break;
if (isascii(*p) && !isdigit(*p))
{
char *q = p;
struct group *gr;
while (isascii(*p) && isalnum(*p))
p++;
*p++ = '\0';
if (*q == '\0')
syserr("mailer %s: null group name",
m->m_name);
gr = getgrnam(q);
if (gr == NULL)
syserr("readcf: mailer U= flag: unknown group %s", q);
else
m->m_gid = gr->gr_gid;
}
else
{
m->m_gid = strtol(p, NULL, 0);
}
break;
case 'W': /* wait timeout */
m->m_wait = convtime(p, 's');
break;
case '/': /* new root directory */
if (*p == '\0')
syserr("mailer %s: null root directory",
m->m_name);
else
m->m_rootdir = newstr(p);
break;
default:
syserr("M%s: unknown mailer equate %c=",
m->m_name, fcode);
break;
}
p = delimptr;
}
/* do some rationality checking */
if (m->m_argv == NULL)
{
syserr("M%s: A= argument required", m->m_name);
return;
}
if (m->m_mailer == NULL)
{
syserr("M%s: P= argument required", m->m_name);
return;
}
if (NextMailer >= MAXMAILERS)
{
syserr("too many mailers defined (%d max)", MAXMAILERS);
return;
}
#if _FFR_DYNAMIC_TOBUF
if (m->m_maxrcpt <= 0)
m->m_maxrcpt = DEFAULT_MAX_RCPT;
#endif /* _FFR_DYNAMIC_TOBUF */
/* do some heuristic cleanup for back compatibility */
if (bitnset(M_LIMITS, m->m_flags))
{
if (m->m_linelimit == 0)
m->m_linelimit = SMTPLINELIM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -