This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / sendmail / src / savemail.c
index 5a35734..99e33c5 100644 (file)
  */
 
 #ifndef lint
  */
 
 #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 */
 
 #endif /* not lint */
 
-# include <pwd.h>
 # include "sendmail.h"
 # include "sendmail.h"
+# include <pwd.h>
 
 /*
 **  SAVEMAIL -- Save mail on error
 
 /*
 **  SAVEMAIL -- Save mail on error
@@ -96,8 +96,6 @@ savemail(e)
                return;
        }
 
                return;
        }
 
-       e->e_flags &= ~EF_FATALERRS;
-
        /*
        **  In the unhappy event we don't know who to return the mail
        **  to, make someone up.
        /*
        **  In the unhappy event we don't know who to return the mail
        **  to, make someone up.
@@ -106,7 +104,8 @@ savemail(e)
        if (e->e_from.q_paddr == NULL)
        {
                e->e_sender = "Postmaster";
        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;
                {
                        syserr("553 Cannot parse Postmaster!");
                        ExitStat = EX_SOFTWARE;
@@ -238,25 +237,40 @@ savemail(e)
                        **      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.
                        **      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)
                        if (strcmp(e->e_from.q_paddr, "<>") != 0)
+                       {
                                (void) sendtolist(e->e_from.q_paddr,
                                (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 */
                        if (q == NULL)
                        {
                                /* this is an error-error */
@@ -335,7 +349,9 @@ savemail(e)
                                e->e_to = buf;
                                q = NULL;
                                (void) sendtolist(buf, &e->e_from, &q, e);
                                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;
                                        state = ESM_DONE;
                                else
                                        state = ESM_MAIL;
@@ -457,12 +473,14 @@ returntosender(msg, returnq, sendbody, e)
        define('_', "localhost", ee);
        ee->e_puthdr = putheader;
        ee->e_putbody = errbody;
        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;
        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))
        for (q = returnq; q != NULL; q = q->q_next)
        {
                if (bitset(QBADADDR, q->q_flags))
@@ -472,7 +490,7 @@ returntosender(msg, returnq, sendbody, e)
                        ee->e_nrcpts++;
 
                if (!DontPruneRoutes && pruneroute(q->q_paddr))
                        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);
 
                if (q->q_alias == NULL)
                        addheader("To", q->q_paddr, ee);
@@ -499,7 +517,7 @@ returntosender(msg, returnq, sendbody, e)
 
        /* fake up an address header for the from person */
        expand("\201n", buf, &buf[sizeof buf - 1], e);
 
        /* 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;
        {
                syserr("553 Can't parse myself!");
                ExitStat = EX_SOFTWARE;
@@ -514,6 +532,9 @@ returntosender(msg, returnq, sendbody, e)
        define('x', "Mail Delivery Subsystem", ee);
        eatheader(ee, TRUE);
 
        define('x', "Mail Delivery Subsystem", ee);
        eatheader(ee, TRUE);
 
+       /* mark statistics */
+       markstats(ee, NULLADDR);
+
        /* actually deliver the error message */
        sendall(ee, SM_DEFAULT);
 
        /* actually deliver the error message */
        sendall(ee, SM_DEFAULT);
 
@@ -574,6 +595,32 @@ errbody(fp, m, e)
                putline("", fp, m);
        }
 
                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).
        */
        /*
        **  Output error message header (if specified and available).
        */
@@ -609,18 +656,27 @@ errbody(fp, m, e)
        printheader = TRUE;
        for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
        {
        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)
                        {
                {
                        if (printheader)
                        {
-                               putline("   ----- The following addresses failed -----",
+                               putline("   ----- The following addresses had delivery problems -----",
                                        fp, m);
                                printheader = FALSE;
                        }
                                        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
                        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 (!printheader)
@@ -658,7 +714,7 @@ errbody(fp, m, e)
        if (e->e_parent->e_df != NULL)
        {
                if (SendBody)
        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);
                else
                        putline("   ----- Message header follows -----\n", fp, m);
                (void) fflush(fp);