summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/savemail.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/savemail.c')
-rw-r--r--contrib/sendmail/src/savemail.c484
1 files changed, 304 insertions, 180 deletions
diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c
index 6a18ee6..0478e359 100644
--- a/contrib/sendmail/src/savemail.c
+++ b/contrib/sendmail/src/savemail.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+ * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
@@ -11,10 +12,14 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.140 (Berkeley) 1/18/1999";
-#endif /* not lint */
+static char id[] = "@(#)$Id: savemail.c,v 8.212.4.3 2000/06/13 07:16:26 gshapiro Exp $";
+#endif /* ! lint */
-# include "sendmail.h"
+#include <sendmail.h>
+
+
+static void errbody __P((MCI *, ENVELOPE *, char *));
+static bool pruneroute __P((char *));
/*
** SAVEMAIL -- Save mail on error
@@ -39,14 +44,14 @@ static char sccsid[] = "@(#)savemail.c 8.140 (Berkeley) 1/18/1999";
*/
/* defines for state machine */
-# define ESM_REPORT 0 /* report to sender's terminal */
-# define ESM_MAIL 1 /* mail back to sender */
-# define ESM_QUIET 2 /* messages have already been returned */
-# define ESM_DEADLETTER 3 /* save in ~/dead.letter */
-# define ESM_POSTMASTER 4 /* return to postmaster */
-# define ESM_USRTMP 5 /* save in /usr/tmp/dead.letter */
-# define ESM_PANIC 6 /* leave the locked queue/transcript files */
-# define ESM_DONE 7 /* the message is successfully delivered */
+#define ESM_REPORT 0 /* report to sender's terminal */
+#define ESM_MAIL 1 /* mail back to sender */
+#define ESM_QUIET 2 /* mail has already been returned */
+#define ESM_DEADLETTER 3 /* save in ~/dead.letter */
+#define ESM_POSTMASTER 4 /* return to postmaster */
+#define ESM_DEADLETTERDROP 5 /* save in DeadLetterDrop */
+#define ESM_PANIC 6 /* call loseqfile() */
+#define ESM_DONE 7 /* message is successfully delivered */
void
@@ -61,13 +66,12 @@ savemail(e, sendbody)
register char *p;
MCI mcibuf;
int flags;
- char buf[MAXLINE+1];
- extern char *ttypath __P((void));
- extern bool writable __P((char *, ADDRESS *, int));
+ long sff;
+ char buf[MAXLINE + 1];
if (tTd(6, 1))
{
- printf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=",
+ dprintf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=",
e->e_errormode, e->e_id == NULL ? "NONE" : e->e_id,
ExitStat);
printaddr(&e->e_from, FALSE);
@@ -90,7 +94,7 @@ savemail(e, sendbody)
if (parseaddr(e->e_sender, &e->e_from,
RF_COPYPARSE|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
- syserr("553 Cannot parse Postmaster!");
+ syserr("553 5.3.5 Cannot parse Postmaster!");
finis(TRUE, EX_SOFTWARE);
}
}
@@ -107,6 +111,8 @@ savemail(e, sendbody)
** ESM_MAIL Mail response to the sender.
** ESM_DEADLETTER Save response in ~/dead.letter.
** ESM_POSTMASTER Mail response to the postmaster.
+ ** ESM_DEADLETTERDROP
+ ** If DeadLetterDrop set, save it there.
** ESM_PANIC Save response anywhere possible.
*/
@@ -132,7 +138,8 @@ savemail(e, sendbody)
return;
default:
- syserr("554 savemail: bogus errormode x%x\n", e->e_errormode);
+ syserr("554 5.3.0 savemail: bogus errormode x%x\n",
+ e->e_errormode);
state = ESM_MAIL;
break;
}
@@ -152,7 +159,7 @@ savemail(e, sendbody)
while (state != ESM_DONE)
{
if (tTd(6, 5))
- printf(" state %d\n", state);
+ dprintf(" state %d\n", state);
switch (state)
{
@@ -182,24 +189,17 @@ savemail(e, sendbody)
printf("Errors occurred while sending mail.\r\n");
if (e->e_xfp != NULL)
{
- (void) fflush(e->e_xfp);
- fp = fopen(queuename(e, 'x'), "r");
+ (void) bfrewind(e->e_xfp);
+ printf("Transcript follows:\r\n");
+ while (fgets(buf, sizeof buf, e->e_xfp) != NULL &&
+ !ferror(stdout))
+ (void) fputs(buf, stdout);
}
else
- fp = NULL;
- if (fp == NULL)
{
syserr("Cannot open %s", queuename(e, 'x'));
printf("Transcript of session is unavailable.\r\n");
}
- else
- {
- printf("Transcript follows:\r\n");
- while (fgets(buf, sizeof buf, fp) != NULL &&
- !ferror(stdout))
- fputs(buf, stdout);
- (void) xfclose(fp, "savemail transcript", e->e_id);
- }
printf("Original message will be saved in dead.letter.\r\n");
state = ESM_DEADLETTER;
break;
@@ -231,14 +231,14 @@ savemail(e, sendbody)
if (!emptyaddr(&e->e_from))
{
char from[TOBUFSIZE];
- extern bool pruneroute __P((char *));
- if (strlen(e->e_from.q_paddr) + 1 > sizeof from)
+ if (strlen(e->e_from.q_paddr) >= sizeof from)
{
state = ESM_POSTMASTER;
break;
}
- strcpy(from, e->e_from.q_paddr);
+ (void) strlcpy(from, e->e_from.q_paddr,
+ sizeof from);
if (!DontPruneRoutes && pruneroute(from))
{
@@ -248,7 +248,7 @@ savemail(e, sendbody)
a = a->q_next)
{
if (sameaddr(a, &e->e_from))
- a->q_flags |= QDONTSEND;
+ a->q_state = QS_DUPLICATE;
}
}
(void) sendtolist(from, NULLADDR,
@@ -267,8 +267,10 @@ savemail(e, sendbody)
/* check to see if there are any good addresses */
for (q = e->e_errorqueue; q != NULL; q = q->q_next)
- if (!bitset(QBADADDR|QDONTSEND, q->q_flags))
+ {
+ if (QS_IS_SENDABLE(q->q_state))
break;
+ }
if (q == NULL)
{
/* this is an error-error */
@@ -294,12 +296,12 @@ savemail(e, sendbody)
*/
q = NULL;
- if (sendtolist(DoubleBounceAddr,
- NULLADDR, &q, 0, e) <= 0)
+ expand(DoubleBounceAddr, buf, sizeof buf, e);
+ if (sendtolist(buf, NULLADDR, &q, 0, e) <= 0)
{
- syserr("553 cannot parse %s!", DoubleBounceAddr);
+ syserr("553 5.3.0 cannot parse %s!", buf);
ExitStat = EX_SOFTWARE;
- state = ESM_USRTMP;
+ state = ESM_DEADLETTERDROP;
break;
}
flags = RTSF_PM_BOUNCE;
@@ -312,7 +314,7 @@ savemail(e, sendbody)
}
/* didn't work -- last resort */
- state = ESM_USRTMP;
+ state = ESM_DEADLETTERDROP;
break;
case ESM_DEADLETTER:
@@ -342,27 +344,37 @@ savemail(e, sendbody)
/* we have a home directory; write dead.letter */
define('z', p, e);
+
+ /* get the sender for the UnixFromLine */
+ p = macvalue('g', e);
+ define('g', e->e_sender, e);
+
expand("\201z/dead.letter", buf, sizeof buf, e);
- flags = SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
+ sff = SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
if (RealUid == 0)
- flags |= SFF_ROOTOK;
+ sff |= SFF_ROOTOK;
e->e_to = buf;
- if (mailfile(buf, FileMailer, NULL, flags, e) == EX_OK)
+ if (writable(buf, NULL, sff) &&
+ mailfile(buf, FileMailer, NULL, sff, e) == EX_OK)
{
int oldverb = Verbose;
- Verbose = 1;
- message("Saved message in %s", buf);
+ if (OpMode != MD_DAEMON && OpMode != MD_SMTP)
+ Verbose = 1;
+ if (Verbose > 0)
+ message("Saved message in %s", buf);
Verbose = oldverb;
+ define('g', p, e);
state = ESM_DONE;
break;
}
+ define('g', p, e);
state = ESM_MAIL;
break;
- case ESM_USRTMP:
+ case ESM_DEADLETTERDROP:
/*
- ** Log the mail in /usr/tmp/dead.letter.
+ ** Log the mail in DeadLetterDrop file.
*/
if (e->e_class < 0)
@@ -372,55 +384,63 @@ savemail(e, sendbody)
}
if ((SafeFileEnv != NULL && SafeFileEnv[0] != '\0') ||
- DeadLetterDrop == NULL || DeadLetterDrop[0] == '\0')
+ DeadLetterDrop == NULL ||
+ DeadLetterDrop[0] == '\0')
{
state = ESM_PANIC;
break;
}
- flags = SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT|SFF_MUSTOWN;
- if (!writable(DeadLetterDrop, NULL, flags) ||
+ sff = SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT|SFF_MUSTOWN;
+ if (!writable(DeadLetterDrop, NULL, sff) ||
(fp = safefopen(DeadLetterDrop, O_WRONLY|O_APPEND,
- FileMode, flags)) == NULL)
+ FileMode, sff)) == NULL)
{
state = ESM_PANIC;
break;
}
- bzero(&mcibuf, sizeof mcibuf);
+ memset(&mcibuf, '\0', sizeof mcibuf);
mcibuf.mci_out = fp;
mcibuf.mci_mailer = FileMailer;
if (bitnset(M_7BITS, FileMailer->m_flags))
mcibuf.mci_flags |= MCIF_7BIT;
- mcibuf.mci_contentlen = 0;
+
+ /* get the sender for the UnixFromLine */
+ p = macvalue('g', e);
+ define('g', e->e_sender, e);
putfromline(&mcibuf, e);
(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
(*e->e_putbody)(&mcibuf, e, NULL);
putline("\n", &mcibuf);
(void) fflush(fp);
- if (ferror(fp))
+ if (ferror(fp) ||
+ fclose(fp) < 0)
state = ESM_PANIC;
else
{
int oldverb = Verbose;
- Verbose = 1;
- message("Saved message in %s", DeadLetterDrop);
+ if (OpMode != MD_DAEMON && OpMode != MD_SMTP)
+ Verbose = 1;
+ if (Verbose > 0)
+ message("Saved message in %s",
+ DeadLetterDrop);
Verbose = oldverb;
if (LogLevel > 3)
sm_syslog(LOG_NOTICE, e->e_id,
- "Saved message in %s",
- DeadLetterDrop);
+ "Saved message in %s",
+ DeadLetterDrop);
state = ESM_DONE;
}
- (void) xfclose(fp, "savemail", DeadLetterDrop);
+ define('g', p, e);
break;
default:
- syserr("554 savemail: unknown state %d", state);
+ syserr("554 5.3.5 savemail: unknown state %d", state);
- /* fall through ... */
+ /* FALLTHROUGH */
case ESM_PANIC:
/* leave the locked queue & transcript files around */
@@ -467,22 +487,21 @@ returntosender(msg, returnq, flags, e)
register ADDRESS *q;
char *p;
char buf[MAXNAME + 1];
- extern void errbody __P((MCI *, ENVELOPE *, char *));
if (returnq == NULL)
- return (-1);
+ return -1;
if (msg == NULL)
msg = "Unable to deliver mail";
if (tTd(6, 1))
{
- printf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%lx, returnq=",
- msg, returndepth, (u_long) e);
+ dprintf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%lx, returnq=",
+ msg, returndepth, (u_long) e);
printaddr(returnq, TRUE);
if (tTd(6, 20))
{
- printf("Sendq=");
+ dprintf("Sendq=");
printaddr(e->e_sendqueue, TRUE);
}
}
@@ -490,76 +509,119 @@ returntosender(msg, returnq, flags, e)
if (++returndepth >= MAXRETURNS)
{
if (returndepth != MAXRETURNS)
- syserr("554 returntosender: infinite recursion on %s", returnq->q_paddr);
+ syserr("554 5.3.0 returntosender: infinite recursion on %s",
+ returnq->q_paddr);
/* don't "unrecurse" and fake a clean exit */
/* returndepth--; */
- return (0);
+ return 0;
}
- define('g', e->e_from.q_paddr, e);
+ define('g', e->e_sender, e);
define('u', NULL, e);
/* initialize error envelope */
ee = newenvelope(&errenvelope, e);
define('a', "\201b", ee);
- define('r', "internal", ee);
+ define('r', "", ee);
define('s', "localhost", ee);
define('_', "localhost", ee);
+#if SASL
+ define(macid("{auth_type}", NULL), "", ee);
+ define(macid("{auth_authen}", NULL), "", ee);
+ define(macid("{auth_author}", NULL), "", ee);
+ define(macid("{auth_ssf}", NULL), "", ee);
+#endif /* SASL */
+#if STARTTLS
+ define(macid("{cert_issuer}", NULL), "", ee);
+ define(macid("{cert_subject}", NULL), "", ee);
+ define(macid("{cipher_bits}", NULL), "", ee);
+ define(macid("{cipher}", NULL), "", ee);
+ define(macid("{tls_version}", NULL), "", ee);
+ define(macid("{verify}", NULL), "", ee);
+# if _FFR_TLS_1
+ define(macid("{alg_bits}", NULL), "", ee);
+ define(macid("{cn_issuer}", NULL), "", ee);
+ define(macid("{cn_subject}", NULL), "", ee);
+# endif /* _FFR_TLS_1 */
+#endif /* STARTTLS */
+
ee->e_puthdr = putheader;
ee->e_putbody = errbody;
ee->e_flags |= EF_RESPONSE|EF_METOO;
if (!bitset(EF_OLDSTYLE, e->e_flags))
ee->e_flags &= ~EF_OLDSTYLE;
+ if (bitset(EF_DONT_MIME, e->e_flags))
+ {
+ ee->e_flags |= EF_DONT_MIME;
+
+ /*
+ ** If we can't convert to MIME and we don't pass
+ ** 8-bit, we can't send the body.
+ */
+
+ if (bitset(EF_HAS8BIT, e->e_flags) &&
+ !bitset(MM_PASS8BIT, MimeMode))
+ flags &= ~RTSF_SEND_BODY;
+ }
+
ee->e_sendqueue = returnq;
ee->e_msgsize = ERRORFUDGE;
- if (bitset(RTSF_SEND_BODY, flags))
+ if (bitset(RTSF_SEND_BODY, flags) &&
+ !bitset(PRIV_NOBODYRETN, PrivacyFlags))
ee->e_msgsize += e->e_msgsize;
else
ee->e_flags |= EF_NO_BODY_RETN;
initsys(ee);
+
+#if NAMED_BIND
+ _res.retry = TimeOuts.res_retry[RES_TO_FIRST];
+ _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
+#endif /* NAMED_BIND */
for (q = returnq; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR, q->q_flags))
+ if (QS_IS_BADADDR(q->q_state))
continue;
q->q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
q->q_flags |= QPINGONFAILURE;
- if (!bitset(QDONTSEND, q->q_flags))
+ if (!QS_IS_DEAD(q->q_state))
ee->e_nrcpts++;
if (q->q_alias == NULL)
- addheader("To", q->q_paddr, &ee->e_header);
+ addheader("To", q->q_paddr, 0, &ee->e_header);
}
if (LogLevel > 5)
{
- if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags))
+ if (bitset(EF_RESPONSE, e->e_flags))
p = "return to sender";
+ else if (bitset(EF_WARNING, e->e_flags))
+ p = "sender notify";
else if (bitset(RTSF_PM_BOUNCE, flags))
p = "postmaster notify";
else
p = "DSN";
sm_syslog(LOG_INFO, e->e_id,
- "%s: %s: %s",
- ee->e_id, p, shortenstring(msg, MAXSHORTSTR));
+ "%s: %s: %s",
+ ee->e_id, p, shortenstring(msg, MAXSHORTSTR));
}
if (SendMIMEErrors)
{
- addheader("MIME-Version", "1.0", &ee->e_header);
+ addheader("MIME-Version", "1.0", 0, &ee->e_header);
(void) snprintf(buf, sizeof buf, "%s.%ld/%.100s",
- ee->e_id, curtime(), MyHostName);
+ ee->e_id, curtime(), MyHostName);
ee->e_msgboundary = newstr(buf);
(void) snprintf(buf, sizeof buf,
#if DSN
- "multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"",
-#else
- "multipart/mixed; boundary=\"%s\"",
-#endif
- ee->e_msgboundary);
- addheader("Content-Type", buf, &ee->e_header);
+ "multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"",
+#else /* DSN */
+ "multipart/mixed; boundary=\"%s\"",
+#endif /* DSN */
+ ee->e_msgboundary);
+ addheader("Content-Type", buf, 0, &ee->e_header);
p = hvalue("Content-Transfer-Encoding", e->e_header);
if (p != NULL && strcasecmp(p, "binary") != 0)
@@ -567,48 +629,50 @@ returntosender(msg, returnq, flags, e)
if (p == NULL && bitset(EF_HAS8BIT, e->e_flags))
p = "8bit";
if (p != NULL)
- addheader("Content-Transfer-Encoding", p, &ee->e_header);
+ addheader("Content-Transfer-Encoding",
+ p, 0, &ee->e_header);
}
if (strncmp(msg, "Warning:", 8) == 0)
{
- addheader("Subject", msg, &ee->e_header);
+ addheader("Subject", msg, 0, &ee->e_header);
p = "warning-timeout";
}
else if (strncmp(msg, "Postmaster warning:", 19) == 0)
{
- addheader("Subject", msg, &ee->e_header);
+ addheader("Subject", msg, 0, &ee->e_header);
p = "postmaster-warning";
}
else if (strcmp(msg, "Return receipt") == 0)
{
- addheader("Subject", msg, &ee->e_header);
+ addheader("Subject", msg, 0, &ee->e_header);
p = "return-receipt";
}
else if (bitset(RTSF_PM_BOUNCE, flags))
{
- snprintf(buf, sizeof buf, "Postmaster notify: %.*s",
- sizeof buf - 20, msg);
- addheader("Subject", buf, &ee->e_header);
+ snprintf(buf, sizeof buf,
+ "Postmaster notify: see transcript for details");
+ addheader("Subject", buf, 0, &ee->e_header);
p = "postmaster-notification";
}
else
{
- snprintf(buf, sizeof buf, "Returned mail: %.*s",
- sizeof buf - 20, msg);
- addheader("Subject", buf, &ee->e_header);
+ snprintf(buf, sizeof buf,
+ "Returned mail: see transcript for details");
+ addheader("Subject", buf, 0, &ee->e_header);
p = "failure";
}
(void) snprintf(buf, sizeof buf, "auto-generated (%s)", p);
- addheader("Auto-Submitted", buf, &ee->e_header);
+ addheader("Auto-Submitted", buf, 0, &ee->e_header);
/* fake up an address header for the from person */
expand("\201n", buf, sizeof buf, e);
- if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
+ if (parseaddr(buf, &ee->e_from,
+ RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
- syserr("553 Can't parse myself!");
+ syserr("553 5.3.5 Can't parse myself!");
ExitStat = EX_SOFTWARE;
returndepth--;
- return (-1);
+ return -1;
}
ee->e_from.q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
ee->e_from.q_flags |= QPINGONFAILURE;
@@ -632,11 +696,12 @@ returntosender(msg, returnq, flags, e)
returndepth--;
/* check for delivery errors */
- if (ee->e_parent == NULL || !bitset(EF_RESPONSE, ee->e_parent->e_flags))
+ if (ee->e_parent == NULL ||
+ !bitset(EF_RESPONSE, ee->e_parent->e_flags))
return 0;
for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QQUEUEUP|QSENT, q->q_flags))
+ if (QS_IS_ATTEMPTED(q->q_state))
return 0;
}
return -1;
@@ -659,18 +724,20 @@ returntosender(msg, returnq, flags, e)
** Outputs the body of an error message.
*/
-void
+/* ARGSUSED2 */
+static void
errbody(mci, e, separator)
register MCI *mci;
register ENVELOPE *e;
char *separator;
{
- register FILE *xfile;
- char *p;
- register ADDRESS *q = NULL;
bool printheader;
bool sendbody;
bool pm_notify;
+ int save_errno;
+ register FILE *xfile;
+ char *p;
+ register ADDRESS *q = NULL;
char buf[MAXLINE];
if (bitset(MCIF_INHEADER, mci->mci_flags))
@@ -709,8 +776,10 @@ errbody(mci, e, separator)
else
{
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
- if (bitset(QBADADDR, q->q_flags))
+ {
+ if (QS_IS_BADADDR(q->q_state))
break;
+ }
}
if (!pm_notify && q == NULL &&
!bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
@@ -726,33 +795,40 @@ errbody(mci, e, separator)
putline("", mci);
}
snprintf(buf, sizeof buf, "The original message was received at %s",
- arpadate(ctime(&e->e_parent->e_ctime)));
+ arpadate(ctime(&e->e_parent->e_ctime)));
putline(buf, mci);
expand("from \201_", buf, sizeof buf, e->e_parent);
putline(buf, mci);
+
+ /* include id in postmaster copies */
+ if (pm_notify && e->e_parent->e_id != NULL)
+ {
+ snprintf(buf, sizeof buf, "with id %s", e->e_parent->e_id);
+ putline(buf, mci);
+ }
putline("", mci);
/*
** Output error message header (if specified and available).
*/
- if (ErrMsgFile != NULL && !bitset(EF_SENDRECEIPT, e->e_parent->e_flags))
+ if (ErrMsgFile != NULL &&
+ !bitset(EF_SENDRECEIPT, e->e_parent->e_flags))
{
if (*ErrMsgFile == '/')
{
- int sff = SFF_ROOTOK|SFF_REGONLY;
+ long sff = SFF_ROOTOK|SFF_REGONLY;
if (DontLockReadFiles)
sff |= SFF_NOLOCK;
- if (!bitset(DBS_ERRORHEADERINUNSAFEDIRPATH, DontBlameSendmail))
+ if (!bitnset(DBS_ERRORHEADERINUNSAFEDIRPATH,
+ DontBlameSendmail))
sff |= SFF_SAFEDIRPATH;
xfile = safefopen(ErrMsgFile, O_RDONLY, 0444, sff);
if (xfile != NULL)
{
while (fgets(buf, sizeof buf, xfile) != NULL)
{
- extern void translate_dollars __P((char *));
-
translate_dollars(buf);
expand(buf, buf, sizeof buf, e);
putline(buf, mci);
@@ -776,7 +852,7 @@ errbody(mci, e, separator)
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (!bitset(QBADADDR, q->q_flags) ||
+ if (!QS_IS_BADADDR(q->q_state) ||
!bitset(QPINGONFAILURE, q->q_flags))
continue;
@@ -790,10 +866,18 @@ errbody(mci, e, separator)
snprintf(buf, sizeof buf, "%s",
shortenstring(q->q_paddr, MAXSHORTSTR));
putline(buf, mci);
+ if (q->q_rstatus != NULL)
+ {
+ snprintf(buf, sizeof buf, " (reason: %s)",
+ shortenstring(exitstat(q->q_rstatus),
+ MAXSHORTSTR));
+ putline(buf, mci);
+ }
if (q->q_alias != NULL)
{
snprintf(buf, sizeof buf, " (expanded from: %s)",
- shortenstring(q->q_alias->q_paddr, MAXSHORTSTR));
+ shortenstring(q->q_alias->q_paddr,
+ MAXSHORTSTR));
putline(buf, mci);
}
}
@@ -803,7 +887,7 @@ errbody(mci, e, separator)
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR, q->q_flags) ||
+ if (QS_IS_BADADDR(q->q_state) ||
!bitset(QPRIMARY, q->q_flags) ||
!bitset(QDELAYED, q->q_flags))
continue;
@@ -821,7 +905,8 @@ errbody(mci, e, separator)
if (q->q_alias != NULL)
{
snprintf(buf, sizeof buf, " (expanded from: %s)",
- shortenstring(q->q_alias->q_paddr, MAXSHORTSTR));
+ shortenstring(q->q_alias->q_paddr,
+ MAXSHORTSTR));
putline(buf, mci);
}
}
@@ -831,7 +916,7 @@ errbody(mci, e, separator)
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR, q->q_flags) ||
+ if (QS_IS_BADADDR(q->q_state) ||
!bitset(QPRIMARY, q->q_flags) ||
bitset(QDELAYED, q->q_flags))
continue;
@@ -859,12 +944,13 @@ errbody(mci, e, separator)
}
snprintf(buf, sizeof buf, "%s (%s)",
- shortenstring(q->q_paddr, MAXSHORTSTR), p);
+ shortenstring(q->q_paddr, MAXSHORTSTR), p);
putline(buf, mci);
if (q->q_alias != NULL)
{
snprintf(buf, sizeof buf, " (expanded from: %s)",
- shortenstring(q->q_alias->q_paddr, MAXSHORTSTR));
+ shortenstring(q->q_alias->q_paddr,
+ MAXSHORTSTR));
putline(buf, mci);
}
}
@@ -876,25 +962,25 @@ errbody(mci, e, separator)
*/
(void) fflush(stdout);
- p = queuename(e->e_parent, 'x');
- if ((xfile = fopen(p, "r")) == NULL)
+ if (e->e_parent->e_xfp == NULL)
{
- syserr("Cannot open %s", p);
- putline(" ----- Transcript of session is unavailable -----\n", mci);
+ putline(" ----- Transcript of session is unavailable -----\n",
+ mci);
}
else
{
printheader = TRUE;
+ (void) bfrewind(e->e_parent->e_xfp);
if (e->e_xfp != NULL)
(void) fflush(e->e_xfp);
- while (fgets(buf, sizeof buf, xfile) != NULL)
+ while (fgets(buf, sizeof buf, e->e_parent->e_xfp) != NULL)
{
if (printheader)
- putline(" ----- Transcript of session follows -----\n", mci);
+ putline(" ----- Transcript of session follows -----\n",
+ mci);
printheader = FALSE;
putline(buf, mci);
}
- (void) xfclose(xfile, "errbody xscript", p);
}
errno = 0;
@@ -918,8 +1004,9 @@ errbody(mci, e, separator)
/* original envelope id from MAIL FROM: line */
if (e->e_parent->e_envid != NULL)
{
- (void) snprintf(buf, sizeof buf, "Original-Envelope-Id: %.800s",
- xuntextify(e->e_parent->e_envid));
+ (void) snprintf(buf, sizeof buf,
+ "Original-Envelope-Id: %.800s",
+ xuntextify(e->e_parent->e_envid));
putline(buf, mci);
}
@@ -936,14 +1023,15 @@ errbody(mci, e, separator)
if (e->e_parent->e_from.q_mailer == NULL ||
(p = e->e_parent->e_from.q_mailer->m_mtatype) == NULL)
p = "dns";
- (void) snprintf(buf, sizeof buf, "Received-From-MTA: %s; %.800s",
- p, RealHostName);
+ (void) snprintf(buf, sizeof buf,
+ "Received-From-MTA: %s; %.800s",
+ p, RealHostName);
putline(buf, mci);
}
/* Arrival-Date: -- when it arrived here */
(void) snprintf(buf, sizeof buf, "Arrival-Date: %s",
- arpadate(ctime(&e->e_parent->e_ctime)));
+ arpadate(ctime(&e->e_parent->e_ctime)));
putline(buf, mci);
/*
@@ -955,7 +1043,7 @@ errbody(mci, e, separator)
register ADDRESS *r;
char *action;
- if (bitset(QBADADDR, q->q_flags))
+ if (QS_IS_BADADDR(q->q_state))
action = "failed";
else if (!bitset(QPRIMARY, q->q_flags))
continue;
@@ -980,8 +1068,9 @@ errbody(mci, e, separator)
/* Original-Recipient: -- passed from on high */
if (q->q_orcpt != NULL)
{
- (void) snprintf(buf, sizeof buf, "Original-Recipient: %.800s",
- q->q_orcpt);
+ (void) snprintf(buf, sizeof buf,
+ "Original-Recipient: %.800s",
+ q->q_orcpt);
putline(buf, mci);
}
@@ -991,40 +1080,71 @@ errbody(mci, e, separator)
p = "rfc822";
for (r = q; r->q_alias != NULL; r = r->q_alias)
continue;
- if (strchr(r->q_user, '@') != NULL)
+ if (strcasecmp(p, "rfc822") != 0)
+ {
+ (void) snprintf(buf, sizeof buf,
+ "Final-Recipient: %s; %.800s",
+ r->q_mailer->m_addrtype,
+ r->q_user);
+ }
+ else if (strchr(r->q_user, '@') != NULL)
{
(void) snprintf(buf, sizeof buf,
- "Final-Recipient: %s; %.800s",
- p, r->q_user);
+ "Final-Recipient: %s; %.800s",
+ p, r->q_user);
}
else if (strchr(r->q_paddr, '@') != NULL)
{
+ char *qp;
+ bool b;
+
+ qp = r->q_paddr;
+ /* strip brackets from address */
+ b = FALSE;
+ if (*qp == '<')
+ {
+ b = qp[strlen(qp) - 1] == '>';
+ if (b)
+ qp[strlen(qp) - 1] = '\0';
+ qp++;
+ }
(void) snprintf(buf, sizeof buf,
- "Final-Recipient: %s; %.800s",
- p, r->q_paddr);
+ "Final-Recipient: %s; %.800s",
+ p, qp);
+ /* undo damage */
+ if (b)
+ qp[strlen(qp)] = '>';
}
else
{
(void) snprintf(buf, sizeof buf,
- "Final-Recipient: %s; %.700s@%.100s",
- p, r->q_user, MyHostName);
+ "Final-Recipient: %s; %.700s@%.100s",
+ p, r->q_user, MyHostName);
}
putline(buf, mci);
/* X-Actual-Recipient: -- the real problem address */
if (r != q && q->q_user[0] != '\0')
{
- if (strchr(q->q_user, '@') == NULL)
+ if (q->q_mailer != NULL &&
+ q->q_mailer->m_addrtype != NULL)
+ p = q->q_mailer->m_addrtype;
+ else
+ p = "rfc822";
+
+ if (strcasecmp(p, "rfc822") == 0 &&
+ strchr(q->q_user, '@') == NULL)
{
(void) snprintf(buf, sizeof buf,
- "X-Actual-Recipient: %s; %.700s@%.100s",
- p, q->q_user, MyHostName);
+ "X-Actual-Recipient: %s; %.700s@%.100s",
+ p, q->q_user,
+ MyHostName);
}
else
{
(void) snprintf(buf, sizeof buf,
- "X-Actual-Recipient: %s; %.800s",
- p, q->q_user);
+ "X-Actual-Recipient: %s; %.800s",
+ p, q->q_user);
}
putline(buf, mci);
}
@@ -1036,9 +1156,9 @@ errbody(mci, e, separator)
/* Status: -- what _really_ happened? */
if (q->q_status != NULL)
p = q->q_status;
- else if (bitset(QBADADDR, q->q_flags))
+ else if (QS_IS_BADADDR(q->q_state))
p = "5.0.0";
- else if (bitset(QQUEUEUP, q->q_flags))
+ else if (QS_IS_QUEUEUP(q->q_state))
p = "4.0.0";
else
p = "2.0.0";
@@ -1052,8 +1172,8 @@ errbody(mci, e, separator)
(p = q->q_mailer->m_mtatype) == NULL)
p = "dns";
(void) snprintf(buf, sizeof buf,
- "Remote-MTA: %s; %.800s",
- p, q->q_statmta);
+ "Remote-MTA: %s; %.800s",
+ p, q->q_statmta);
p = &buf[strlen(buf) - 1];
if (*p == '.')
*p = '\0';
@@ -1067,8 +1187,8 @@ errbody(mci, e, separator)
if (p == NULL)
p = "smtp";
(void) snprintf(buf, sizeof buf,
- "Diagnostic-Code: %s; %.800s",
- p, q->q_rstatus);
+ "Diagnostic-Code: %s; %.800s",
+ p, q->q_rstatus);
putline(buf, mci);
}
@@ -1076,26 +1196,25 @@ errbody(mci, e, separator)
if (q->q_statdate == (time_t) 0L)
q->q_statdate = curtime();
(void) snprintf(buf, sizeof buf,
- "Last-Attempt-Date: %s",
- arpadate(ctime(&q->q_statdate)));
+ "Last-Attempt-Date: %s",
+ arpadate(ctime(&q->q_statdate)));
putline(buf, mci);
/* Will-Retry-Until: -- for delayed messages only */
- if (bitset(QQUEUEUP, q->q_flags) &&
- !bitset(QBADADDR, q->q_flags))
+ if (QS_IS_QUEUEUP(q->q_state))
{
time_t xdate;
xdate = e->e_parent->e_ctime +
TimeOuts.to_q_return[e->e_parent->e_timeoutclass];
snprintf(buf, sizeof buf,
- "Will-Retry-Until: %s",
- arpadate(ctime(&xdate)));
+ "Will-Retry-Until: %s",
+ arpadate(ctime(&xdate)));
putline(buf, mci);
}
}
}
-#endif
+#endif /* DSN */
/*
** Output text of original message
@@ -1113,33 +1232,37 @@ errbody(mci, e, separator)
putline(" ----- Original message follows -----\n", mci);
else
putline(" ----- Message header follows -----\n", mci);
- (void) fflush(mci->mci_out);
}
else
{
(void) snprintf(buf, sizeof buf, "--%s",
- e->e_msgboundary);
+ e->e_msgboundary);
putline(buf, mci);
(void) snprintf(buf, sizeof buf, "Content-Type: %s",
- sendbody ? "message/rfc822"
- : "text/rfc822-headers");
+ sendbody ? "message/rfc822"
+ : "text/rfc822-headers");
putline(buf, mci);
- p = hvalue("Content-Transfer-Encoding", e->e_parent->e_header);
+ p = hvalue("Content-Transfer-Encoding",
+ e->e_parent->e_header);
if (p != NULL && strcasecmp(p, "binary") != 0)
p = NULL;
- if (p == NULL && bitset(EF_HAS8BIT, e->e_parent->e_flags))
+ if (p == NULL &&
+ bitset(EF_HAS8BIT, e->e_parent->e_flags))
p = "8bit";
if (p != NULL)
{
- (void) snprintf(buf, sizeof buf, "Content-Transfer-Encoding: %s",
- p);
+ (void) snprintf(buf, sizeof buf,
+ "Content-Transfer-Encoding: %s",
+ p);
putline(buf, mci);
}
}
putline("", mci);
+ save_errno = errno;
putheader(mci, e->e_parent->e_header, e->e_parent, M87F_OUTER);
+ errno = save_errno;
if (sendbody)
putbody(mci, e->e_parent, e->e_msgboundary);
else if (e->e_msgboundary == NULL)
@@ -1160,6 +1283,7 @@ errbody(mci, e, separator)
putline(buf, mci);
}
putline("", mci);
+ (void) fflush(mci->mci_out);
/*
** Cleanup and exit
@@ -1293,8 +1417,8 @@ xtextify(t, taboo)
strchr(taboo, c) != NULL)
{
*p++ = '+';
- *p++ = "0123456789abcdef"[c >> 4];
- *p++ = "0123456789abcdef"[c & 0xf];
+ *p++ = "0123456789ABCDEF"[c >> 4];
+ *p++ = "0123456789ABCDEF"[c & 0xf];
}
else
*p++ = c;
@@ -1421,22 +1545,22 @@ xtextok(s)
}
/*
** PRUNEROUTE -- prune an RFC-822 source route
-**
+**
** Trims down a source route to the last internet-registered hop.
** This is encouraged by RFC 1123 section 5.3.3.
-**
+**
** Parameters:
** addr -- the address
-**
+**
** Returns:
** TRUE -- address was modified
** FALSE -- address could not be pruned
-**
+**
** Side Effects:
** modifies addr in-place
*/
-bool
+static bool
pruneroute(addr)
char *addr;
{
@@ -1460,14 +1584,14 @@ pruneroute(addr)
i = strlen(at + 1);
if (i >= (SIZE_T) sizeof hostbuf)
return FALSE;
- strcpy(hostbuf, at + 1);
+ (void) strlcpy(hostbuf, at + 1, sizeof hostbuf);
hostbuf[i - 1] = '\0';
while (start)
{
- if (getmxrr(hostbuf, mxhosts, FALSE, &rcode) > 0)
+ if (getmxrr(hostbuf, mxhosts, NULL, FALSE, &rcode) > 0)
{
- strcpy(addr + 1, start + 1);
+ (void) strlcpy(addr + 1, start + 1, strlen(addr) - 1);
return TRUE;
}
c = *start;
@@ -1475,12 +1599,12 @@ pruneroute(addr)
comma = strrchr(addr, ',');
if (comma != NULL && comma[1] == '@' &&
strlen(comma + 2) < (SIZE_T) sizeof hostbuf)
- strcpy(hostbuf, comma + 2);
+ (void) strlcpy(hostbuf, comma + 2, sizeof hostbuf);
else
comma = NULL;
*start = c;
start = comma;
}
-#endif
+#endif /* NAMED_BIND */
return FALSE;
}
OpenPOWER on IntegriCloud