diff options
Diffstat (limited to 'contrib/sendmail/src/savemail.c')
-rw-r--r-- | contrib/sendmail/src/savemail.c | 263 |
1 files changed, 165 insertions, 98 deletions
diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c index 857d81f..66141df 100644 --- a/contrib/sendmail/src/savemail.c +++ b/contrib/sendmail/src/savemail.c @@ -9,13 +9,15 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * + * $FreeBSD$ + * */ #include <sendmail.h> -SM_RCSID("@(#)$Id: savemail.c,v 8.304 2004/10/06 21:36:06 ca Exp $") +SM_RCSID("@(#)$Id: savemail.c,v 8.306 2006/02/25 02:16:53 ca Exp $") -static void errbody __P((MCI *, ENVELOPE *, char *)); +static bool errbody __P((MCI *, ENVELOPE *, char *)); static bool pruneroute __P((char *)); /* @@ -432,12 +434,13 @@ savemail(e, sendbody) p = macvalue('g', e); macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); - putfromline(&mcibuf, e); - (*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER); - (*e->e_putbody)(&mcibuf, e, NULL); - putline("\n", &mcibuf); /* XXX EOL from FileMailer? */ - (void) sm_io_flush(fp, SM_TIME_DEFAULT); - if (sm_io_error(fp) || + if (!putfromline(&mcibuf, e) || + !(*e->e_puthdr)(&mcibuf, e->e_header, e, + M87F_OUTER) || + !(*e->e_putbody)(&mcibuf, e, NULL) || + !putline("\n", &mcibuf) || + sm_io_flush(fp, SM_TIME_DEFAULT) == SM_IO_EOF || + sm_io_error(fp) || sm_io_close(fp, SM_TIME_DEFAULT) < 0) state = ESM_PANIC; else @@ -732,14 +735,14 @@ returntosender(msg, returnq, flags, e) ** separator -- any possible MIME separator (unused). ** ** Returns: -** none +** success ** ** Side Effects: ** Outputs the body of an error message. */ /* ARGSUSED2 */ -static void +static bool errbody(mci, e, separator) register MCI *mci; register ENVELOPE *e; @@ -757,14 +760,16 @@ errbody(mci, e, separator) if (bitset(MCIF_INHEADER, mci->mci_flags)) { - putline("", mci); + if (!putline("", mci)) + goto writeerr; mci->mci_flags &= ~MCIF_INHEADER; } if (e->e_parent == NULL) { syserr("errbody: null parent"); - putline(" ----- Original message lost -----\n", mci); - return; + if (!putline(" ----- Original message lost -----\n", mci)) + goto writeerr; + return true; } /* @@ -773,11 +778,12 @@ errbody(mci, e, separator) if (e->e_msgboundary != NULL) { - putline("This is a MIME-encapsulated message", mci); - putline("", mci); (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); - putline(buf, mci); - putline("", mci); + if (!putline("This is a MIME-encapsulated message", mci) || + !putline("", mci) || + !putline(buf, mci) || + !putline("", mci)) + goto writeerr; } /* @@ -799,31 +805,36 @@ errbody(mci, e, separator) if (!pm_notify && q == NULL && !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags)) { - putline(" **********************************************", - mci); - putline(" ** THIS IS A WARNING MESSAGE ONLY **", - mci); - putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **", - mci); - putline(" **********************************************", - mci); - putline("", mci); + if (!putline(" **********************************************", + mci) || + !putline(" ** THIS IS A WARNING MESSAGE ONLY **", + mci) || + !putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **", + mci) || + !putline(" **********************************************", + mci) || + !putline("", mci)) + goto writeerr; } (void) sm_snprintf(buf, sizeof buf, "The original message was received at %s", arpadate(ctime(&e->e_parent->e_ctime))); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; expand("from \201_", buf, sizeof buf, e->e_parent); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* include id in postmaster copies */ if (pm_notify && e->e_parent->e_id != NULL) { (void) sm_strlcpyn(buf, sizeof buf, 2, "with id ", e->e_parent->e_id); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } - putline("", mci); + if (!putline("", mci)) + goto writeerr; /* ** Output error message header (if specified and available). @@ -849,17 +860,19 @@ errbody(mci, e, separator) { translate_dollars(buf); expand(buf, buf, sizeof buf, e); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } (void) sm_io_close(xfile, SM_TIME_DEFAULT); - putline("\n", mci); + if (!putline("\n", mci)) + goto writeerr; } } else { expand(ErrMsgFile, buf, sizeof buf, e); - putline(buf, mci); - putline("", mci); + if (!putline(buf, mci) || !putline("", mci)) + goto writeerr; } } @@ -877,21 +890,24 @@ errbody(mci, e, separator) if (printheader) { - putline(" ----- The following addresses had permanent fatal errors -----", - mci); + if (!putline(" ----- The following addresses had permanent fatal errors -----", + mci)) + goto writeerr; printheader = false; } (void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR), sizeof buf); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; if (q->q_rstatus != NULL) { (void) sm_snprintf(buf, sizeof buf, " (reason: %s)", shortenstring(exitstat(q->q_rstatus), MAXSHORTSTR)); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } if (q->q_alias != NULL) { @@ -899,11 +915,12 @@ errbody(mci, e, separator) " (expanded from: %s)", shortenstring(q->q_alias->q_paddr, MAXSHORTSTR)); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } - if (!printheader) - putline("", mci); + if (!printheader && !putline("", mci)) + goto writeerr; /* transient non-fatal errors */ printheader = true; @@ -917,25 +934,28 @@ errbody(mci, e, separator) if (printheader) { - putline(" ----- The following addresses had transient non-fatal errors -----", - mci); + if (!putline(" ----- The following addresses had transient non-fatal errors -----", + mci)) + goto writeerr; printheader = false; } (void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR), sizeof buf); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; if (q->q_alias != NULL) { (void) sm_snprintf(buf, sizeof buf, " (expanded from: %s)", shortenstring(q->q_alias->q_paddr, MAXSHORTSTR)); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } - if (!printheader) - putline("", mci); + if (!printheader && !putline("", mci)) + goto writeerr; /* successful delivery notifications */ printheader = true; @@ -968,25 +988,28 @@ errbody(mci, e, separator) if (printheader) { - putline(" ----- The following addresses had successful delivery notifications -----", - mci); + if (!putline(" ----- The following addresses had successful delivery notifications -----", + mci)) + goto writeerr; printheader = false; } (void) sm_snprintf(buf, sizeof buf, "%s (%s)", shortenstring(q->q_paddr, MAXSHORTSTR), p); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; if (q->q_alias != NULL) { (void) sm_snprintf(buf, sizeof buf, " (expanded from: %s)", shortenstring(q->q_alias->q_paddr, MAXSHORTSTR)); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } - if (!printheader) - putline("", mci); + if (!printheader && !putline("", mci)) + goto writeerr; /* ** Output transcript of errors @@ -995,8 +1018,9 @@ errbody(mci, e, separator) (void) sm_io_flush(smioout, SM_TIME_DEFAULT); if (e->e_parent->e_xfp == NULL) { - putline(" ----- Transcript of session is unavailable -----\n", - mci); + if (!putline(" ----- Transcript of session is unavailable -----\n", + mci)) + goto writeerr; } else { @@ -1007,11 +1031,12 @@ errbody(mci, e, separator) while (sm_io_fgets(e->e_parent->e_xfp, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) { - if (printheader) - putline(" ----- Transcript of session follows -----\n", - mci); + if (printheader && !putline(" ----- Transcript of session follows -----\n", + mci)) + goto writeerr; printheader = false; - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } errno = 0; @@ -1023,11 +1048,12 @@ errbody(mci, e, separator) if (e->e_msgboundary != NULL) { - putline("", mci); (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); - putline(buf, mci); - putline("Content-Type: message/delivery-status", mci); - putline("", mci); + if (!putline("", mci) || + !putline(buf, mci) || + !putline("Content-Type: message/delivery-status", mci) || + !putline("", mci)) + goto writeerr; /* ** Output per-message information. @@ -1039,13 +1065,15 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Original-Envelope-Id: %.800s", xuntextify(e->e_parent->e_envid)); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Reporting-MTA: is us (required) */ (void) sm_snprintf(buf, sizeof buf, "Reporting-MTA: dns; %.800s", MyHostName); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* DSN-Gateway: not relevant since we are not translating */ @@ -1059,13 +1087,15 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Received-From-MTA: %s; %.800s", p, RealHostName); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Arrival-Date: -- when it arrived here */ (void) sm_strlcpyn(buf, sizeof buf, 2, "Arrival-Date: ", arpadate(ctime(&e->e_parent->e_ctime))); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* Deliver-By-Date: -- when it should have been delivered */ if (IS_DLVR_BY(e->e_parent)) @@ -1076,7 +1106,8 @@ errbody(mci, e, separator) (void) sm_strlcpyn(buf, sizeof buf, 2, "Deliver-By-Date: ", arpadate(ctime(&dbyd))); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* @@ -1119,7 +1150,8 @@ errbody(mci, e, separator) else continue; - putline("", mci); + if (!putline("", mci)) + goto writeerr; /* Original-Recipient: -- passed from on high */ if (q->q_orcpt != NULL) @@ -1127,7 +1159,8 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Original-Recipient: %.800s", q->q_orcpt); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Figure out actual recipient */ @@ -1176,7 +1209,8 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Final-Recipient: %s", q->q_finalrcpt); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* X-Actual-Recipient: -- the real problem address */ @@ -1190,13 +1224,15 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "X-Actual-Recipient: %s", actual); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Action: -- what happened? */ (void) sm_strlcpyn(buf, sizeof buf, 2, "Action: ", action); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* Status: -- what _really_ happened? */ if (q->q_status != NULL) @@ -1208,7 +1244,8 @@ errbody(mci, e, separator) else p = "2.0.0"; (void) sm_strlcpyn(buf, sizeof buf, 2, "Status: ", p); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* Remote-MTA: -- who was I talking to? */ if (q->q_statmta != NULL) @@ -1222,7 +1259,8 @@ errbody(mci, e, separator) p = &buf[strlen(buf) - 1]; if (*p == '.') *p = '\0'; - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Diagnostic-Code: -- actual result from other end */ @@ -1234,7 +1272,8 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Diagnostic-Code: %s; %.800s", p, q->q_rstatus); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } /* Last-Attempt-Date: -- fine granularity */ @@ -1243,7 +1282,8 @@ errbody(mci, e, separator) (void) sm_strlcpyn(buf, sizeof buf, 2, "Last-Attempt-Date: ", arpadate(ctime(&q->q_statdate))); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; /* Will-Retry-Until: -- for delayed messages only */ if (QS_IS_QUEUEUP(q->q_state)) @@ -1255,7 +1295,8 @@ errbody(mci, e, separator) (void) sm_strlcpyn(buf, sizeof buf, 2, "Will-Retry-Until: ", arpadate(ctime(&xdate))); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } } @@ -1265,7 +1306,8 @@ errbody(mci, e, separator) ** Output text of original message */ - putline("", mci); + if (!putline("", mci)) + goto writeerr; if (bitset(EF_HAS_DF, e->e_parent->e_flags)) { sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) && @@ -1273,21 +1315,27 @@ errbody(mci, e, separator) if (e->e_msgboundary == NULL) { - if (sendbody) - putline(" ----- Original message follows -----\n", mci); - else - putline(" ----- Message header follows -----\n", mci); + if (!putline( + sendbody + ? " ----- Original message follows -----\n" + : " ----- Message header follows -----\n", + mci)) + { + goto writeerr; + } } else { (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; (void) sm_strlcpyn(buf, sizeof buf, 2, "Content-Type: ", sendbody ? "message/rfc822" : "text/rfc822-headers"); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; p = hvalue("Content-Transfer-Encoding", e->e_parent->e_header); @@ -1301,43 +1349,62 @@ errbody(mci, e, separator) (void) sm_snprintf(buf, sizeof buf, "Content-Transfer-Encoding: %s", p); - putline(buf, mci); + if (!putline(buf, mci)) + goto writeerr; } } - putline("", mci); + if (!putline("", mci)) + goto writeerr; save_errno = errno; - putheader(mci, e->e_parent->e_header, e->e_parent, M87F_OUTER); + if (!putheader(mci, e->e_parent->e_header, e->e_parent, + M87F_OUTER)) + goto writeerr; errno = save_errno; if (sendbody) - putbody(mci, e->e_parent, e->e_msgboundary); + { + if (!putbody(mci, e->e_parent, e->e_msgboundary)) + goto writeerr; + } else if (e->e_msgboundary == NULL) { - putline("", mci); - putline(" ----- Message body suppressed -----", mci); + if (!putline("", mci) || + !putline(" ----- Message body suppressed -----", + mci)) + { + goto writeerr; + } } } else if (e->e_msgboundary == NULL) { - putline(" ----- No message was collected -----\n", mci); + if (!putline(" ----- No message was collected -----\n", mci)) + goto writeerr; } if (e->e_msgboundary != NULL) { - putline("", mci); (void) sm_strlcpyn(buf, sizeof buf, 3, "--", e->e_msgboundary, "--"); - putline(buf, mci); + if (!putline("", mci) || !putline(buf, mci)) + goto writeerr; } - putline("", mci); - (void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT); + if (!putline("", mci) || + sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF) + goto writeerr; /* ** Cleanup and exit */ if (errno != 0) + { + writeerr: syserr("errbody: I/O error"); + return false; + } + return true; } + /* ** SMTPTODSN -- convert SMTP to DSN status code ** @@ -1402,9 +1469,9 @@ smtptodsn(smtpstat) return "5.0.0"; } - if ((smtpstat / 100) == 2) + if (REPLYTYPE(smtpstat) == 2) return "2.0.0"; - if ((smtpstat / 100) == 4) + if (REPLYTYPE(smtpstat) == 4) return "4.0.0"; return "5.0.0"; } |