*/
#ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.1 (Berkeley) 6/7/93";
+static char sccsid[] = "@(#)savemail.c 8.17 (Berkeley) 10/31/93";
#endif /* not lint */
-# include <pwd.h>
# include "sendmail.h"
+# include <pwd.h>
/*
** SAVEMAIL -- Save mail on error
return;
}
- e->e_flags &= ~EF_FATALERRS;
-
/*
** In the unhappy event we don't know who to return the mail
** to, make someone up.
if (e->e_from.q_paddr == NULL)
{
e->e_sender = "Postmaster";
- if (parseaddr(e->e_sender, &e->e_from, 0, '\0', NULL, e) == NULL)
+ if (parseaddr(e->e_sender, &e->e_from,
+ RF_COPYPARSE|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
syserr("553 Cannot parse Postmaster!");
ExitStat = EX_SOFTWARE;
** joe@x, which gives a response, etc. Also force
** the mail to be delivered even if a version of
** it has already been sent to the sender.
+ **
+ ** If this is a configuration or local software
+ ** error, send to the local postmaster as well,
+ ** since the originator can't do anything
+ ** about it anyway. Note that this is a full
+ ** copy of the message (intentionally) so that
+ ** the Postmaster can forward things along.
*/
+ if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE)
+ {
+ (void) sendtolist("postmaster",
+ NULLADDR, &e->e_errorqueue, e);
+ }
if (strcmp(e->e_from.q_paddr, "<>") != 0)
+ {
(void) sendtolist(e->e_from.q_paddr,
- (ADDRESS *) NULL,
- &e->e_errorqueue, e);
+ NULLADDR, &e->e_errorqueue, e);
+ }
- /* deliver a cc: to the postmaster if desired */
- if (PostMasterCopy != NULL)
- {
- auto ADDRESS *rlist = NULL;
+ /*
+ ** Deliver a non-delivery report to the
+ ** Postmaster-designate (not necessarily
+ ** Postmaster). This does not include the
+ ** body of the message, for privacy reasons.
+ ** You really shouldn't need this.
+ */
- (void) sendtolist(PostMasterCopy,
- (ADDRESS *) NULL,
- &rlist, e);
- (void) returntosender(e->e_message,
- rlist, FALSE, e);
- }
- q = e->e_errorqueue;
+ e->e_flags |= EF_PM_NOTIFY;
+
+ /* 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))
+ break;
if (q == NULL)
{
/* this is an error-error */
e->e_to = buf;
q = NULL;
(void) sendtolist(buf, &e->e_from, &q, e);
- if (deliver(e, q) == 0)
+ if (q != NULL &&
+ !bitset(QBADADDR, q->q_flags) &&
+ deliver(e, q) == 0)
state = ESM_DONE;
else
state = ESM_MAIL;
define('_', "localhost", ee);
ee->e_puthdr = putheader;
ee->e_putbody = errbody;
- ee->e_flags |= EF_RESPONSE;
+ ee->e_flags |= EF_RESPONSE|EF_METOO;
if (!bitset(EF_OLDSTYLE, e->e_flags))
ee->e_flags &= ~EF_OLDSTYLE;
ee->e_sendqueue = returnq;
- ee->e_msgsize = e->e_msgsize + ERRORFUDGE;
- openxscript(ee);
+ ee->e_msgsize = ERRORFUDGE;
+ if (!NoReturn)
+ ee->e_msgsize += e->e_msgsize;
+ initsys(ee);
for (q = returnq; q != NULL; q = q->q_next)
{
if (bitset(QBADADDR, q->q_flags))
ee->e_nrcpts++;
if (!DontPruneRoutes && pruneroute(q->q_paddr))
- parseaddr(q->q_paddr, q, 0, '\0', NULL, e);
+ parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e);
if (q->q_alias == NULL)
addheader("To", q->q_paddr, ee);
/* fake up an address header for the from person */
expand("\201n", buf, &buf[sizeof buf - 1], e);
- if (parseaddr(buf, &ee->e_from, 1, '\0', NULL, e) == NULL)
+ if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
syserr("553 Can't parse myself!");
ExitStat = EX_SOFTWARE;
define('x', "Mail Delivery Subsystem", ee);
eatheader(ee, TRUE);
+ /* mark statistics */
+ markstats(ee, NULLADDR);
+
/* actually deliver the error message */
sendall(ee, SM_DEFAULT);
putline("", fp, m);
}
+ /*
+ ** Output introductory information.
+ */
+
+ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
+ if (bitset(QBADADDR, q->q_flags))
+ break;
+ if (q == NULL && !bitset(EF_FATALERRS, e->e_parent->e_flags))
+ {
+ putline(" **********************************************",
+ fp, m);
+ putline(" ** THIS IS A WARNING MESSAGE ONLY **",
+ fp, m);
+ putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **",
+ fp, m);
+ putline(" **********************************************",
+ fp, m);
+ putline("", fp, m);
+ }
+ sprintf(buf, "The original message was received at %s",
+ arpadate(ctime(&e->e_parent->e_ctime)));
+ putline(buf, fp, m);
+ expand("from \201_", buf, &buf[sizeof buf - 1], e->e_parent);
+ putline(buf, fp, m);
+ putline("", fp, m);
+
/*
** Output error message header (if specified and available).
*/
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR, q->q_flags))
+ if (bitset(QBADADDR|QREPORT, q->q_flags))
{
if (printheader)
{
- putline(" ----- The following addresses failed -----",
+ putline(" ----- The following addresses had delivery problems -----",
fp, m);
printheader = FALSE;
}
- if (q->q_alias != NULL)
- putline(q->q_alias->q_paddr, fp, m);
+ strcpy(buf, q->q_paddr);
+ if (bitset(QBADADDR, q->q_flags))
+ strcat(buf, " (unrecoverable error)");
else
- putline(q->q_paddr, fp, m);
+ strcat(buf, " (transient failure)");
+ putline(buf, fp, m);
+ if (q->q_alias != NULL)
+ {
+ strcpy(buf, " (expanded from: ");
+ strcat(buf, q->q_alias->q_paddr);
+ strcat(buf, ")");
+ putline(buf, fp, m);
+ }
}
}
if (!printheader)
if (e->e_parent->e_df != NULL)
{
if (SendBody)
- putline(" ----- Unsent message follows -----\n", fp, m);
+ putline(" ----- Original message follows -----\n", fp, m);
else
putline(" ----- Message header follows -----\n", fp, m);
(void) fflush(fp);