📄 envelope.c
字号:
/* time as integer, unix time, arpa time */
settime(e);
/* Load average */
(void)sm_getla(e);
#ifdef TTYNAME
/* tty name */
if (macvalue('y', e) == NULL)
{
p = ttyname(2);
if (p != NULL)
{
if (strrchr(p, '/') != NULL)
p = strrchr(p, '/') + 1;
snprintf(ybuf, sizeof ybuf, "%s", p);
define('y', ybuf, e);
}
}
#endif /* TTYNAME */
}
/*
** SETTIME -- set the current time.
**
** Parameters:
** e -- the envelope in which the macros should be set.
**
** Returns:
** none.
**
** Side Effects:
** Sets the various time macros -- $a, $b, $d, $t.
*/
void
settime(e)
register ENVELOPE *e;
{
register char *p;
auto time_t now;
char tbuf[20]; /* holds "current" time */
char dbuf[30]; /* holds ctime(tbuf) */
register struct tm *tm;
now = curtime();
tm = gmtime(&now);
(void) snprintf(tbuf, sizeof tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
define('t', newstr(tbuf), e);
(void) strlcpy(dbuf, ctime(&now), sizeof dbuf);
p = strchr(dbuf, '\n');
if (p != NULL)
*p = '\0';
define('d', newstr(dbuf), e);
p = arpadate(dbuf);
p = newstr(p);
if (macvalue('a', e) == NULL)
define('a', p, e);
define('b', p, e);
}
/*
** OPENXSCRIPT -- Open transcript file
**
** Creates a transcript file for possible eventual mailing or
** sending back.
**
** Parameters:
** e -- the envelope to create the transcript in/for.
**
** Returns:
** none
**
** Side Effects:
** Creates the transcript file.
*/
#ifndef O_APPEND
# define O_APPEND 0
#endif /* ! O_APPEND */
void
openxscript(e)
register ENVELOPE *e;
{
register char *p;
if (e->e_xfp != NULL)
return;
#if 0
if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags))
syserr("openxscript: job not locked");
#endif /* 0 */
p = queuename(e, 'x');
e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize,
SFF_NOTEXCL|SFF_OPENASROOT);
if (e->e_xfp == NULL)
{
syserr("Can't create transcript file %s", p);
e->e_xfp = fopen("/dev/null", "r+");
if (e->e_xfp == NULL)
syserr("!Can't open /dev/null");
}
#if HASSETVBUF
(void) setvbuf(e->e_xfp, NULL, _IOLBF, 0);
#else /* HASSETVBUF */
(void) setlinebuf(e->e_xfp);
#endif /* HASSETVBUF */
if (tTd(46, 9))
{
dprintf("openxscript(%s):\n ", p);
dumpfd(fileno(e->e_xfp), TRUE, FALSE);
}
}
/*
** CLOSEXSCRIPT -- close the transcript file.
**
** Parameters:
** e -- the envelope containing the transcript to close.
**
** Returns:
** none.
**
** Side Effects:
** none.
*/
void
closexscript(e)
register ENVELOPE *e;
{
if (e->e_xfp == NULL)
return;
#if 0
if (e->e_lockfp == NULL)
syserr("closexscript: job not locked");
#endif /* 0 */
(void) bfclose(e->e_xfp);
e->e_xfp = NULL;
}
/*
** SETSENDER -- set the person who this message is from
**
** Under certain circumstances allow the user to say who
** s/he is (using -f or -r). These are:
** 1. The user's uid is zero (root).
** 2. The user's login name is in an approved list (typically
** from a network server).
** 3. The address the user is trying to claim has a
** "!" character in it (since #2 doesn't do it for
** us if we are dialing out for UUCP).
** A better check to replace #3 would be if the
** effective uid is "UUCP" -- this would require me
** to rewrite getpwent to "grab" uucp as it went by,
** make getname more nasty, do another passwd file
** scan, or compile the UID of "UUCP" into the code,
** all of which are reprehensible.
**
** Assuming all of these fail, we figure out something
** ourselves.
**
** Parameters:
** from -- the person we would like to believe this message
** is from, as specified on the command line.
** e -- the envelope in which we would like the sender set.
** delimptr -- if non-NULL, set to the location of the
** trailing delimiter.
** delimchar -- the character that will delimit the sender
** address.
** internal -- set if this address is coming from an internal
** source such as an owner alias.
**
** Returns:
** none.
**
** Side Effects:
** sets sendmail's notion of who the from person is.
*/
void
setsender(from, e, delimptr, delimchar, internal)
char *from;
register ENVELOPE *e;
char **delimptr;
int delimchar;
bool internal;
{
register char **pvp;
char *realname = NULL;
register struct passwd *pw;
char *bp;
char buf[MAXNAME + 2];
char pvpbuf[PSBUFSIZE];
extern char *FullName;
if (tTd(45, 1))
dprintf("setsender(%s)\n", from == NULL ? "" : from);
/*
** Figure out the real user executing us.
** Username can return errno != 0 on non-errors.
*/
if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
realname = from;
if (realname == NULL || realname[0] == '\0')
realname = username();
if (ConfigLevel < 2)
SuprErrs = TRUE;
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), "e s", e);
#endif /* _FFR_ADDR_TYPE */
/* preset state for then clause in case from == NULL */
e->e_from.q_state = QS_BADADDR;
e->e_from.q_flags = 0;
if (from == NULL ||
parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
delimchar, delimptr, e) == NULL ||
QS_IS_BADADDR(e->e_from.q_state) ||
e->e_from.q_mailer == ProgMailer ||
e->e_from.q_mailer == FileMailer ||
e->e_from.q_mailer == InclMailer)
{
/* log garbage addresses for traceback */
if (from != NULL && LogLevel > 2)
{
char *p;
char ebuf[MAXNAME * 2 + 2];
p = macvalue('_', e);
if (p == NULL)
{
char *host = RealHostName;
if (host == NULL)
host = MyHostName;
(void) snprintf(ebuf, sizeof ebuf, "%.*s@%.*s",
MAXNAME, realname,
MAXNAME, host);
p = ebuf;
}
sm_syslog(LOG_NOTICE, e->e_id,
"setsender: %s: invalid or unparsable, received from %s",
shortenstring(from, 83), p);
}
if (from != NULL)
{
if (!QS_IS_BADADDR(e->e_from.q_state))
{
/* it was a bogus mailer in the from addr */
e->e_status = "5.1.7";
usrerrenh(e->e_status,
"553 Invalid sender address");
}
SuprErrs = TRUE;
}
if (from == realname ||
parseaddr(from = newstr(realname), &e->e_from,
RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
{
char nbuf[100];
SuprErrs = TRUE;
expand("\201n", nbuf, sizeof nbuf, e);
if (parseaddr(from = newstr(nbuf), &e->e_from,
RF_COPYALL, ' ', NULL, e) == NULL &&
parseaddr(from = "postmaster", &e->e_from,
RF_COPYALL, ' ', NULL, e) == NULL)
syserr("553 5.3.0 setsender: can't even parse postmaster!");
}
}
else
FromFlag = TRUE;
e->e_from.q_state = QS_SENDER;
if (tTd(45, 5))
{
dprintf("setsender: QS_SENDER ");
printaddr(&e->e_from, FALSE);
}
SuprErrs = FALSE;
#if USERDB
if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
{
register char *p;
p = udbsender(e->e_from.q_user);
if (p != NULL)
from = p;
}
#endif /* USERDB */
if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
{
if (!internal)
{
/* if the user already given fullname don't redefine */
if (FullName == NULL)
FullName = macvalue('x', e);
if (FullName != NULL && FullName[0] == '\0')
FullName = NULL;
}
if (e->e_from.q_user[0] != '\0' &&
(pw = sm_getpwnam(e->e_from.q_user)) != NULL)
{
/*
** Process passwd file entry.
*/
/* extract home directory */
if (*pw->pw_dir == '\0')
e->e_from.q_home = NULL;
else if (strcmp(pw->pw_dir, "/") == 0)
e->e_from.q_home = newstr("");
else
e->e_from.q_home = newstr(pw->pw_dir);
define('z', e->e_from.q_home, e);
/* extract user and group id */
e->e_from.q_uid = pw->pw_uid;
e->e_from.q_gid = pw->pw_gid;
e->e_from.q_flags |= QGOODUID;
/* extract full name from passwd file */
if (FullName == NULL && pw->pw_gecos != NULL &&
strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
!internal)
{
buildfname(pw->pw_gecos, e->e_from.q_user, buf, sizeof buf);
if (buf[0] != '\0')
FullName = newstr(buf);
}
}
else
{
e->e_from.q_home = NULL;
}
if (FullName != NULL && !internal)
define('x', FullName, e);
}
else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP)
{
if (e->e_from.q_home == NULL)
{
e->e_from.q_home = getenv("HOME");
if (e->e_from.q_home != NULL)
{
if (*e->e_from.q_home == '\0')
e->e_from.q_home = NULL;
else if (strcmp(e->e_from.q_home, "/") == 0)
e->e_from.q_home++;
}
}
e->e_from.q_uid = RealUid;
e->e_from.q_gid = RealGid;
e->e_from.q_flags |= QGOODUID;
}
/*
** Rewrite the from person to dispose of possible implicit
** links in the net.
*/
pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL);
if (pvp == NULL)
{
/* don't need to give error -- prescan did that already */
if (LogLevel > 2)
sm_syslog(LOG_NOTICE, e->e_id,
"cannot prescan from (%s)",
shortenstring(from, MAXSHORTSTR));
finis(TRUE, ExitStat);
}
(void) rewrite(pvp, 3, 0, e);
(void) rewrite(pvp, 1, 0, e);
(void) rewrite(pvp, 4, 0, e);
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), NULL, e);
#endif /* _FFR_ADDR_TYPE */
bp = buf + 1;
cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
{
/* heuristic: route-addr: add angle brackets */
(void) strlcat(bp, ">", sizeof buf - 1);
*--bp = '<';
}
e->e_sender = newstr(bp);
define('f', e->e_sender, e);
/* save the domain spec if this mailer wants it */
if (e->e_from.q_mailer != NULL &&
bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
{
char **lastat;
/* get rid of any pesky angle brackets */
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), "e s", e);
#endif /* _FFR_ADDR_TYPE */
(void) rewrite(pvp, 3, 0, e);
(void) rewrite(pvp, 1, 0, e);
(void) rewrite(pvp, 4, 0, e);
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), NULL, e);
#endif /* _FFR_ADDR_TYPE */
/* strip off to the last "@" sign */
for (lastat = NULL; *pvp != NULL; pvp++)
if (strcmp(*pvp, "@") == 0)
lastat = pvp;
if (lastat != NULL)
{
e->e_fromdomain = copyplist(lastat, TRUE);
if (tTd(45, 3))
{
dprintf("Saving from domain: ");
printav(e->e_fromdomain);
}
}
}
}
/*
** PRINTENVFLAGS -- print envelope flags for debugging
**
** Parameters:
** e -- the envelope with the flags to be printed.
**
** Returns:
** none.
*/
struct eflags
{
char *ef_name;
u_long ef_bit;
};
static struct eflags EnvelopeFlags[] =
{
{ "OLDSTYLE", EF_OLDSTYLE },
{ "INQUEUE", EF_INQUEUE },
{ "NO_BODY_RETN", EF_NO_BODY_RETN },
{ "CLRQUEUE", EF_CLRQUEUE },
{ "SENDRECEIPT", EF_SENDRECEIPT },
{ "FATALERRS", EF_FATALERRS },
{ "DELETE_BCC", EF_DELETE_BCC },
{ "RESPONSE", EF_RESPONSE },
{ "RESENT", EF_RESENT },
{ "VRFYONLY", EF_VRFYONLY },
{ "WARNING", EF_WARNING },
{ "QUEUERUN", EF_QUEUERUN },
{ "GLOBALERRS", EF_GLOBALERRS },
{ "PM_NOTIFY", EF_PM_NOTIFY },
{ "METOO", EF_METOO },
{ "LOGSENDER", EF_LOGSENDER },
{ "NORECEIPT", EF_NORECEIPT },
{ "HAS8BIT", EF_HAS8BIT },
{ "NL_NOT_EOL", EF_NL_NOT_EOL },
{ "CRLF_NOT_EOL", EF_CRLF_NOT_EOL },
{ "RET_PARAM", EF_RET_PARAM },
{ "HAS_DF", EF_HAS_DF },
{ "IS_MIME", EF_IS_MIME },
{ "DONT_MIME", EF_DONT_MIME },
{ NULL }
};
void
printenvflags(e)
register ENVELOPE *e;
{
register struct eflags *ef;
bool first = TRUE;
printf("%lx", e->e_flags);
for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++)
{
if (!bitset(ef->ef_bit, e->e_flags))
continue;
if (first)
printf("<%s", ef->ef_name);
else
printf(",%s", ef->ef_name);
first = FALSE;
}
if (!first)
printf(">\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -