summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/savemail.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/savemail.c')
-rw-r--r--usr.sbin/sendmail/src/savemail.c791
1 files changed, 118 insertions, 673 deletions
diff --git a/usr.sbin/sendmail/src/savemail.c b/usr.sbin/sendmail/src/savemail.c
index 78c9149..65c915d 100644
--- a/usr.sbin/sendmail/src/savemail.c
+++ b/usr.sbin/sendmail/src/savemail.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983, 1995 Eric P. Allman
+ * Copyright (c) 1983 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,10 +33,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.87 (Berkeley) 10/28/95";
+static char sccsid[] = "@(#)savemail.c 8.29 (Berkeley) 5/10/94";
#endif /* not lint */
# include "sendmail.h"
+# include <pwd.h>
/*
** SAVEMAIL -- Save mail on error
@@ -48,8 +49,6 @@ static char sccsid[] = "@(#)savemail.c 8.87 (Berkeley) 10/28/95";
**
** Parameters:
** e -- the envelope containing the message in error.
-** sendbody -- if TRUE, also send back the body of the
-** message; otherwise just send the header.
**
** Returns:
** none
@@ -75,10 +74,8 @@ static char sccsid[] = "@(#)savemail.c 8.87 (Berkeley) 10/28/95";
# endif
-void
-savemail(e, sendbody)
+savemail(e)
register ENVELOPE *e;
- bool sendbody;
{
register struct passwd *pw;
register FILE *fp;
@@ -86,8 +83,8 @@ savemail(e, sendbody)
auto ADDRESS *q = NULL;
register char *p;
MCI mcibuf;
- int sfflags;
char buf[MAXLINE+1];
+ extern struct passwd *getpwnam();
extern char *ttypath();
typedef int (*fnptr)();
extern bool writable();
@@ -146,6 +143,11 @@ savemail(e, sendbody)
break;
case EM_BERKNET:
+ /* mail back, but return o.k. exit status */
+ ExitStat = EX_OK;
+
+ /* fall through.... */
+
case EM_MAIL:
state = ESM_MAIL;
break;
@@ -185,7 +187,7 @@ savemail(e, sendbody)
switch (state)
{
case ESM_QUIET:
- if (bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags))
+ if (e->e_from.q_mailer == LocalMailer)
state = ESM_DEADLETTER;
else
state = ESM_MAIL;
@@ -205,7 +207,7 @@ savemail(e, sendbody)
break;
}
- expand("\201n", buf, sizeof buf, e);
+ expand("\201n", buf, &buf[sizeof buf - 1], e);
printf("\r\nMessage from %s...\r\n", buf);
printf("Errors occurred while sending mail.\r\n");
if (e->e_xfp != NULL)
@@ -254,12 +256,12 @@ savemail(e, sendbody)
if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE)
{
(void) sendtolist("postmaster",
- NULLADDR, &e->e_errorqueue, 0, e);
+ NULLADDR, &e->e_errorqueue, e);
}
- if (!emptyaddr(&e->e_from))
+ if (strcmp(e->e_from.q_paddr, "<>") != 0)
{
(void) sendtolist(e->e_from.q_paddr,
- NULLADDR, &e->e_errorqueue, 0, e);
+ NULLADDR, &e->e_errorqueue, e);
}
/*
@@ -283,7 +285,7 @@ savemail(e, sendbody)
break;
}
if (returntosender(e->e_message, e->e_errorqueue,
- sendbody, e) == 0)
+ (e->e_class >= 0), e) == 0)
{
state = ESM_DONE;
break;
@@ -299,14 +301,15 @@ savemail(e, sendbody)
*/
q = NULL;
- if (sendtolist("postmaster", NULL, &q, 0, e) <= 0)
+ if (sendtolist("postmaster", NULL, &q, e) <= 0)
{
syserr("553 cannot parse postmaster!");
ExitStat = EX_SOFTWARE;
state = ESM_USRTMP;
break;
}
- if (returntosender(e->e_message, q, sendbody, e) == 0)
+ if (returntosender(e->e_message,
+ q, (e->e_class >= 0), e) == 0)
{
state = ESM_DONE;
break;
@@ -327,36 +330,44 @@ savemail(e, sendbody)
*/
p = NULL;
- if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
+ if (e->e_from.q_mailer == LocalMailer)
{
if (e->e_from.q_home != NULL)
p = e->e_from.q_home;
- else if ((pw = sm_getpwnam(e->e_from.q_user)) != NULL)
+ else if ((pw = getpwnam(e->e_from.q_user)) != NULL)
p = pw->pw_dir;
}
- if (p == NULL || e->e_dfp == NULL)
+ if (p == NULL)
{
- /* no local directory or no data file */
+ /* no local directory */
state = ESM_MAIL;
break;
}
-
- /* we have a home directory; write dead.letter */
- define('z', p, e);
- expand("\201z/dead.letter", buf, sizeof buf, e);
- sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
- e->e_to = buf;
- if (mailfile(buf, NULL, sfflags, e) == EX_OK)
+ if (e->e_dfp != NULL)
{
bool oldverb = Verbose;
+ /* we have a home directory; open dead.letter */
+ define('z', p, e);
+ expand("\201z/dead.letter", buf, &buf[sizeof buf - 1], e);
Verbose = TRUE;
- message("Saved message in %s", buf);
+ message("Saving message in %s", buf);
Verbose = oldverb;
- state = ESM_DONE;
- break;
+ e->e_to = buf;
+ q = NULL;
+ (void) sendtolist(buf, &e->e_from, &q, e);
+ if (q != NULL &&
+ !bitset(QBADADDR, q->q_flags) &&
+ deliver(e, q) == 0)
+ state = ESM_DONE;
+ else
+ state = ESM_MAIL;
+ }
+ else
+ {
+ /* no data file -- try mailing back */
+ state = ESM_MAIL;
}
- state = ESM_MAIL;
break;
case ESM_USRTMP:
@@ -370,19 +381,15 @@ savemail(e, sendbody)
break;
}
- if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
+ strcpy(buf, _PATH_VARTMP);
+ strcat(buf, "dead.letter");
+ if (!writable(buf, NULLADDR, SFF_NOSLINK))
{
state = ESM_PANIC;
break;
}
-
- strcpy(buf, _PATH_VARTMP);
- strcat(buf, "dead.letter");
-
- sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT;
- if (!writable(buf, NULL, sfflags) ||
- (fp = safefopen(buf, O_WRONLY|O_CREAT|O_APPEND,
- FileMode, sfflags)) == NULL)
+ fp = dfopen(buf, O_WRONLY|O_CREAT|O_APPEND, FileMode);
+ if (fp == NULL)
{
state = ESM_PANIC;
break;
@@ -395,26 +402,13 @@ savemail(e, sendbody)
mcibuf.mci_flags |= MCIF_7BIT;
putfromline(&mcibuf, e);
- (*e->e_puthdr)(&mcibuf, e->e_header, e);
+ (*e->e_puthdr)(&mcibuf, e);
+ putline("\n", &mcibuf);
(*e->e_putbody)(&mcibuf, e, NULL);
putline("\n", &mcibuf);
(void) fflush(fp);
- if (!ferror(fp))
- {
- bool oldverb = Verbose;
-
- Verbose = TRUE;
- message("Saved message in %s", buf);
- Verbose = oldverb;
-#ifdef LOG
- if (LogLevel > 3)
- syslog(LOG_NOTICE, "Saved message in %s", buf);
-#endif
- state = ESM_DONE;
- break;
- }
- state = ESM_PANIC;
- (void) xfclose(fp, "savemail", buf);
+ state = ferror(fp) ? ESM_PANIC : ESM_DONE;
+ (void) xfclose(fp, "savemail", "/usr/tmp/dead.letter");
break;
default:
@@ -424,7 +418,6 @@ savemail(e, sendbody)
case ESM_PANIC:
/* leave the locked queue & transcript files around */
- loseqfile(e, "savemail panic");
syserr("!554 savemail: cannot save rejected email anywhere");
}
}
@@ -448,24 +441,24 @@ savemail(e, sendbody)
** mail.
*/
+static bool SendBody;
+
#define MAXRETURNS 6 /* max depth of returning messages */
#define ERRORFUDGE 100 /* nominal size of error message text */
-int
returntosender(msg, returnq, sendbody, e)
char *msg;
ADDRESS *returnq;
bool sendbody;
register ENVELOPE *e;
{
+ char buf[MAXNAME];
+ extern putheader(), errbody();
register ENVELOPE *ee;
ENVELOPE *oldcur = CurEnv;
ENVELOPE errenvelope;
static int returndepth;
register ADDRESS *q;
- char *p;
- char buf[MAXNAME + 1];
- extern void errbody __P((MCI *, ENVELOPE *, char *));
if (returnq == NULL)
return (-1);
@@ -475,14 +468,9 @@ returntosender(msg, returnq, sendbody, e)
if (tTd(6, 1))
{
- printf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=",
+ printf("Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=",
msg, returndepth, e);
printaddr(returnq, TRUE);
- if (tTd(6, 20))
- {
- printf("Sendq=");
- printaddr(e->e_sendqueue, TRUE);
- }
}
if (++returndepth >= MAXRETURNS)
@@ -494,10 +482,9 @@ returntosender(msg, returnq, sendbody, e)
return (0);
}
+ SendBody = sendbody;
define('g', e->e_from.q_paddr, e);
define('u', NULL, e);
-
- /* initialize error envelope */
ee = newenvelope(&errenvelope, e);
define('a', "\201b", ee);
define('r', "internal", ee);
@@ -510,97 +497,45 @@ returntosender(msg, returnq, sendbody, e)
ee->e_flags &= ~EF_OLDSTYLE;
ee->e_sendqueue = returnq;
ee->e_msgsize = ERRORFUDGE;
- if (sendbody)
+ if (!NoReturn)
ee->e_msgsize += e->e_msgsize;
- else
- ee->e_flags |= EF_NO_BODY_RETN;
initsys(ee);
for (q = returnq; q != NULL; q = q->q_next)
{
if (bitset(QBADADDR, q->q_flags))
continue;
- if (!DontPruneRoutes && pruneroute(q->q_paddr))
- {
- register ADDRESS *p;
-
- parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e);
- for (p = returnq; p != NULL; p = p->q_next)
- {
- if (p != q && sameaddr(p, q))
- q->q_flags |= QDONTSEND;
- }
- }
-
if (!bitset(QDONTSEND, q->q_flags))
ee->e_nrcpts++;
+ if (!DontPruneRoutes && pruneroute(q->q_paddr))
+ parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e);
+
if (q->q_alias == NULL)
- addheader("To", q->q_paddr, &ee->e_header);
+ addheader("To", q->q_paddr, ee);
}
# ifdef LOG
if (LogLevel > 5)
- {
- if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags))
- p = "return to sender";
- else
- p = "postmaster notify";
- syslog(LOG_INFO, "%s: %s: %s: %s",
- e->e_id, ee->e_id, p, shortenstring(msg, 203));
- }
+ syslog(LOG_INFO, "%s: %s: return to sender: %s",
+ e->e_id, ee->e_id, msg);
# endif
+ (void) sprintf(buf, "Returned mail: %.*s", sizeof buf - 20, msg);
+ addheader("Subject", buf, ee);
if (SendMIMEErrors)
{
- addheader("MIME-Version", "1.0", &ee->e_header);
-
- (void) sprintf(buf, "%s.%ld/%.100s",
+ addheader("MIME-Version", "1.0", ee);
+ (void) sprintf(buf, "%s.%ld/%s",
ee->e_id, curtime(), MyHostName);
ee->e_msgboundary = newstr(buf);
- (void) sprintf(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);
-
- p = hvalue("Content-Transfer-Encoding", e->e_header);
- if (p != NULL && strcasecmp(p, "binary") != 0)
- p = NULL;
- if (p == NULL && bitset(EF_HAS8BIT, e->e_flags))
- p = "8bit";
- if (p != NULL)
- addheader("Content-Transfer-Encoding", p, &ee->e_header);
+ (void) sprintf(buf, "multipart/mixed; boundary=\"%s\"",
+ ee->e_msgboundary);
+ addheader("Content-Type", buf, ee);
}
- if (strncmp(msg, "Warning:", 8) == 0)
- {
- addheader("Subject", msg, &ee->e_header);
- p = "warning-timeout";
- }
- else if (strncmp(msg, "Postmaster warning:", 19) == 0)
- {
- addheader("Subject", msg, &ee->e_header);
- p = "postmaster-warning";
- }
- else if (strcmp(msg, "Return receipt") == 0)
- {
- addheader("Subject", msg, &ee->e_header);
- p = "return-receipt";
- }
- else
- {
- sprintf(buf, "Returned mail: %.*s", sizeof buf - 20, msg);
- addheader("Subject", buf, &ee->e_header);
- p = "failure";
- }
- (void) sprintf(buf, "auto-generated (%s)", p);
- addheader("Auto-Submitted", buf, &ee->e_header);
/* fake up an address header for the from person */
- expand("\201n", buf, sizeof buf, e);
+ expand("\201n", buf, &buf[sizeof buf - 1], e);
if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
syserr("553 Can't parse myself!");
@@ -627,15 +562,8 @@ returntosender(msg, returnq, sendbody, e)
CurEnv = oldcur;
returndepth--;
- /* check for delivery errors */
- 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(QSENT, q->q_flags))
- return 0;
- }
- return -1;
+ /* should check for delivery errors here */
+ return (0);
}
/*
** ERRBODY -- output the body of an error message.
@@ -646,8 +574,6 @@ returntosender(msg, returnq, sendbody, e)
** Parameters:
** mci -- the mailer connection information.
** e -- the envelope we are working in.
-** separator -- any possible MIME separator.
-** flags -- to modify the behaviour.
**
** Returns:
** none
@@ -656,25 +582,16 @@ returntosender(msg, returnq, sendbody, e)
** Outputs the body of an error message.
*/
-void
-errbody(mci, e, separator)
+errbody(mci, e)
register MCI *mci;
register ENVELOPE *e;
- char *separator;
{
register FILE *xfile;
char *p;
register ADDRESS *q;
bool printheader;
- bool sendbody;
char buf[MAXLINE];
- extern char *xuntextify();
- if (bitset(MCIF_INHEADER, mci->mci_flags))
- {
- putline("", mci);
- mci->mci_flags &= ~MCIF_INHEADER;
- }
if (e->e_parent == NULL)
{
syserr("errbody: null parent");
@@ -718,7 +635,7 @@ errbody(mci, e, separator)
sprintf(buf, "The original message was received at %s",
arpadate(ctime(&e->e_parent->e_ctime)));
putline(buf, mci);
- expand("from \201_", buf, sizeof buf, e->e_parent);
+ expand("from \201_", buf, &buf[sizeof buf - 1], e->e_parent);
putline(buf, mci);
putline("", mci);
@@ -726,7 +643,7 @@ errbody(mci, e, separator)
** Output error message header (if specified and available).
*/
- if (ErrMsgFile != NULL && !bitset(EF_SENDRECEIPT, e->e_parent->e_flags))
+ if (ErrMsgFile != NULL)
{
if (*ErrMsgFile == '/')
{
@@ -735,7 +652,7 @@ errbody(mci, e, separator)
{
while (fgets(buf, sizeof buf, xfile) != NULL)
{
- expand(buf, buf, sizeof buf, e);
+ expand(buf, buf, &buf[sizeof buf - 1], e);
putline(buf, mci);
}
(void) fclose(xfile);
@@ -744,7 +661,7 @@ errbody(mci, e, separator)
}
else
{
- expand(ErrMsgFile, buf, sizeof buf, e);
+ expand(ErrMsgFile, buf, &buf[sizeof buf - 1], e);
putline(buf, mci);
putline("", mci);
}
@@ -757,46 +674,27 @@ 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 (bitset(QBADADDR|QREPORT, q->q_flags))
{
- if (!bitset(QPINGONFAILURE, q->q_flags))
- continue;
- p = "unrecoverable error";
- }
- else if (!bitset(QPRIMARY, q->q_flags))
- continue;
- else if (bitset(QDELAYED, q->q_flags))
- p = "transient failure";
- else if (!bitset(QPINGONSUCCESS, q->q_flags))
- continue;
- else if (bitset(QRELAYED, q->q_flags))
- p = "relayed to non-DSN-aware mailer";
- else if (bitset(QDELIVERED, q->q_flags))
- {
- if (bitset(QEXPANDED, q->q_flags))
- p = "successfully delivered to mailing list";
+ if (printheader)
+ {
+ putline(" ----- The following addresses had delivery problems -----",
+ mci);
+ printheader = FALSE;
+ }
+ strcpy(buf, q->q_paddr);
+ if (bitset(QBADADDR, q->q_flags))
+ strcat(buf, " (unrecoverable error)");
else
- p = "successfully delivered to mailbox";
- }
- else if (bitset(QEXPANDED, q->q_flags))
- p = "expanded by alias";
- else
- continue;
-
- if (printheader)
- {
- putline(" ----- The following addresses have delivery notifications -----",
- mci);
- printheader = FALSE;
- }
-
- sprintf(buf, "%s (%s)", shortenstring(q->q_paddr, 203), p);
- putline(buf, mci);
- if (q->q_alias != NULL)
- {
- sprintf(buf, " (expanded from: %s)",
- shortenstring(q->q_alias->q_paddr, 203));
+ strcat(buf, " (transient failure)");
putline(buf, mci);
+ if (q->q_alias != NULL)
+ {
+ strcpy(buf, " (expanded from: ");
+ strcat(buf, q->q_alias->q_paddr);
+ strcat(buf, ")");
+ putline(buf, mci);
+ }
}
}
if (!printheader)
@@ -815,256 +713,46 @@ errbody(mci, e, separator)
}
else
{
- printheader = TRUE;
+ putline(" ----- Transcript of session follows -----\n", mci);
if (e->e_xfp != NULL)
(void) fflush(e->e_xfp);
while (fgets(buf, sizeof buf, xfile) != NULL)
- {
- if (printheader)
- putline(" ----- Transcript of session follows -----\n", mci);
- printheader = FALSE;
putline(buf, mci);
- }
(void) xfclose(xfile, "errbody xscript", p);
}
errno = 0;
-#if DSN
- /*
- ** Output machine-readable version.
- */
-
- if (e->e_msgboundary != NULL)
- {
- putline("", mci);
- (void) sprintf(buf, "--%s", e->e_msgboundary);
- putline(buf, mci);
- putline("Content-Type: message/delivery-status", mci);
- putline("", mci);
-
- /*
- ** Output per-message information.
- */
-
- /* original envelope id from MAIL FROM: line */
- if (e->e_parent->e_envid != NULL)
- {
- (void) sprintf(buf, "Original-Envelope-Id: %.800s",
- xuntextify(e->e_parent->e_envid));
- putline(buf, mci);
- }
-
- /* Reporting-MTA: is us (required) */
- (void) sprintf(buf, "Reporting-MTA: dns; %.800s", MyHostName);
- putline(buf, mci);
-
- /* DSN-Gateway: not relevant since we are not translating */
-
- /* Received-From-MTA: shows where we got this message from */
- if (RealHostName != NULL)
- {
- /* XXX use $s for type? */
- if (e->e_parent->e_from.q_mailer == NULL ||
- (p = e->e_parent->e_from.q_mailer->m_mtatype) == NULL)
- p = "dns";
- (void) sprintf(buf, "Received-From-MTA: %s; %.800s",
- p, RealHostName);
- putline(buf, mci);
- }
-
- /* Arrival-Date: -- when it arrived here */
- (void) sprintf(buf, "Arrival-Date: %s",
- arpadate(ctime(&e->e_parent->e_ctime)));
- putline(buf, mci);
-
- /*
- ** Output per-address information.
- */
-
- for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
- {
- register ADDRESS *r;
- char *action;
-
- if (bitset(QBADADDR, q->q_flags))
- action = "failed";
- else if (!bitset(QPRIMARY, q->q_flags))
- continue;
- else if (bitset(QDELIVERED, q->q_flags))
- {
- if (bitset(QEXPANDED, q->q_flags))
- action = "delivered (to mailing list)";
- else
- action = "delivered (to mailbox)";
- }
- else if (bitset(QRELAYED, q->q_flags))
- action = "relayed (to non-DSN-aware mailer)";
- else if (bitset(QEXPANDED, q->q_flags))
- action = "expanded (to multi-recipient alias)";
- else if (bitset(QDELAYED, q->q_flags))
- action = "delayed";
- else
- continue;
-
- putline("", mci);
-
- /* Original-Recipient: -- passed from on high */
- if (q->q_orcpt != NULL)
- {
- (void) sprintf(buf, "Original-Recipient: %.800s",
- q->q_orcpt);
- putline(buf, mci);
- }
-
- /* Final-Recipient: -- the name from the RCPT command */
- p = e->e_parent->e_from.q_mailer->m_addrtype;
- if (p == NULL)
- p = "rfc822";
- for (r = q; r->q_alias != NULL; r = r->q_alias)
- continue;
- if (strchr(r->q_user, '@') == NULL)
- {
- (void) sprintf(buf, "Final-Recipient: %s; %.700s@%.100s",
- p, r->q_user, MyHostName);
- }
- else
- {
- (void) sprintf(buf, "Final-Recipient: %s; %.800s",
- p, r->q_user);
- }
- putline(buf, mci);
-
- /* X-Actual-Recipient: -- the real problem address */
- if (r != q && q->q_user[0] != '\0')
- {
- if (strchr(q->q_user, '@') == NULL)
- {
- (void) sprintf(buf, "X-Actual-Recipient: %s; %.700s@%.100s",
- p, q->q_user, MyHostName);
- }
- else
- {
- (void) sprintf(buf, "X-Actual-Recipient: %s; %.800s",
- p, q->q_user);
- }
- putline(buf, mci);
- }
-
- /* Action: -- what happened? */
- sprintf(buf, "Action: %s", action);
- putline(buf, mci);
-
- /* Status: -- what _really_ happened? */
- strcpy(buf, "Status: ");
- if (q->q_status != NULL)
- strcat(buf, q->q_status);
- else if (bitset(QBADADDR, q->q_flags))
- strcat(buf, "5.0.0");
- else if (bitset(QQUEUEUP, q->q_flags))
- strcat(buf, "4.0.0");
- else
- strcat(buf, "2.0.0");
- putline(buf, mci);
-
- /* Remote-MTA: -- who was I talking to? */
- if (q->q_statmta != NULL)
- {
- if (q->q_mailer == NULL ||
- (p = q->q_mailer->m_mtatype) == NULL)
- p = "dns";
- (void) sprintf(buf, "Remote-MTA: %s; %.800s",
- p, q->q_statmta);
- p = &buf[strlen(buf) - 1];
- if (*p == '.')
- *p = '\0';
- putline(buf, mci);
- }
-
- /* Diagnostic-Code: -- actual result from other end */
- if (q->q_rstatus != NULL)
- {
- p = q->q_mailer->m_diagtype;
- if (p == NULL)
- p = "smtp";
- (void) sprintf(buf, "Diagnostic-Code: %s; %.800s",
- p, q->q_rstatus);
- putline(buf, mci);
- }
-
- /* Last-Attempt-Date: -- fine granularity */
- if (q->q_statdate == (time_t) 0L)
- q->q_statdate = curtime();
- (void) sprintf(buf, "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))
- {
- time_t xdate;
-
- xdate = e->e_parent->e_ctime +
- TimeOuts.to_q_return[e->e_parent->e_timeoutclass];
- sprintf(buf, "Will-Retry-Until: %s",
- arpadate(ctime(&xdate)));
- putline(buf, mci);
- }
- }
- }
-#endif
-
/*
** Output text of original message
*/
+ if (NoReturn)
+ SendBody = FALSE;
putline("", mci);
- if (bitset(EF_HAS_DF, e->e_parent->e_flags))
+ if (e->e_parent->e_df != NULL)
{
- sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) &&
- !bitset(EF_NO_BODY_RETN, e->e_flags);
-
- if (e->e_msgboundary == NULL)
- {
- if (sendbody)
- putline(" ----- Original message follows -----\n", mci);
- else
- putline(" ----- Message header follows -----\n", mci);
- (void) fflush(mci->mci_out);
- }
+ if (SendBody)
+ putline(" ----- Original message follows -----\n", mci);
else
+ putline(" ----- Message header follows -----\n", mci);
+ (void) fflush(mci->mci_out);
+
+ if (e->e_msgboundary != NULL)
{
+ putline("", mci);
(void) sprintf(buf, "--%s", e->e_msgboundary);
-
- putline(buf, mci);
- (void) sprintf(buf, "Content-Type: %s",
- sendbody ? "message/rfc822"
- : "text/rfc822-headers");
putline(buf, mci);
-
- 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))
- p = "8bit";
- if (p != NULL)
- {
- (void) sprintf(buf, "Content-Transfer-Encoding: %s",
- p);
- putline(buf, mci);
- }
+ putline("Content-Type: message/rfc822", mci);
+ putline("", mci);
}
+ putheader(mci, e->e_parent);
putline("", mci);
- putheader(mci, e->e_parent->e_header, e->e_parent);
- if (sendbody)
+ if (SendBody)
putbody(mci, e->e_parent, e->e_msgboundary);
- else if (e->e_msgboundary == NULL)
- {
- putline("", mci);
+ else
putline(" ----- Message body suppressed -----", mci);
- }
}
- else if (e->e_msgboundary == NULL)
+ else
{
putline(" ----- No message was collected -----\n", mci);
}
@@ -1085,265 +773,22 @@ errbody(mci, e, separator)
syserr("errbody: I/O error");
}
/*
-** SMTPTODSN -- convert SMTP to DSN status code
-**
-** Parameters:
-** smtpstat -- the smtp status code (e.g., 550).
-**
-** Returns:
-** The DSN version of the status code.
-*/
-
-char *
-smtptodsn(smtpstat)
- int smtpstat;
-{
- if (smtpstat < 0)
- return "4.4.2";
-
- switch (smtpstat)
- {
- case 450: /* Req mail action not taken: mailbox unavailable */
- return "4.2.0";
-
- case 451: /* Req action aborted: local error in processing */
- return "4.3.0";
-
- case 452: /* Req action not taken: insufficient sys storage */
- return "4.3.1";
-
- case 500: /* Syntax error, command unrecognized */
- return "5.5.2";
-
- case 501: /* Syntax error in parameters or arguments */
- return "5.5.4";
-
- case 502: /* Command not implemented */
- return "5.5.1";
-
- case 503: /* Bad sequence of commands */
- return "5.5.1";
-
- case 504: /* Command parameter not implemented */
- return "5.5.4";
-
- case 550: /* Req mail action not taken: mailbox unavailable */
- return "5.2.0";
-
- case 551: /* User not local; please try <...> */
- return "5.1.6";
-
- case 552: /* Req mail action aborted: exceeded storage alloc */
- return "5.2.2";
-
- case 553: /* Req action not taken: mailbox name not allowed */
- return "5.1.3";
-
- case 554: /* Transaction failed */
- return "5.0.0";
- }
-
- if ((smtpstat / 100) == 2)
- return "2.0.0";
- if ((smtpstat / 100) == 4)
- return "4.0.0";
- return "5.0.0";
-}
- /*
-** XTEXTIFY -- take regular text and turn it into DSN-style xtext
-**
-** Parameters:
-** t -- the text to convert.
-**
-** Returns:
-** The xtext-ified version of the same string.
-*/
-
-char *
-xtextify(t)
- register char *t;
-{
- register char *p;
- int l;
- int nbogus;
- static char *bp = NULL;
- static int bplen = 0;
-
- /* figure out how long this xtext will have to be */
- nbogus = l = 0;
- for (p = t; *p != '\0'; p++)
- {
- register int c = (*p & 0xff);
-
- /* ASCII dependence here -- this is the way the spec words it */
- if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
- nbogus++;
- l++;
- }
- if (nbogus == 0)
- return t;
- l += nbogus * 2 + 1;
-
- /* now allocate space if necessary for the new string */
- if (l > bplen)
- {
- if (bp != NULL)
- free(bp);
- bp = xalloc(l);
- bplen = l;
- }
-
- /* ok, copy the text with byte expansion */
- for (p = bp; *t != '\0'; )
- {
- register int c = (*t++ & 0xff);
-
- /* ASCII dependence here -- this is the way the spec words it */
- if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
- {
- *p++ = '+';
- *p++ = "0123456789abcdef"[c >> 4];
- *p++ = "0123456789abcdef"[c & 0xf];
- }
- else
- *p++ = c;
- }
- *p = '\0';
- return bp;
-}
- /*
-** XUNTEXTIFY -- take xtext and turn it into plain text
-**
-** Parameters:
-** t -- the xtextified text.
-**
-** Returns:
-** The decoded text. No attempt is made to deal with
-** null strings in the resulting text.
-*/
-
-char *
-xuntextify(t)
- register char *t;
-{
- register char *p;
- int l;
- static char *bp = NULL;
- static int bplen = 0;
-
- /* heuristic -- if no plus sign, just return the input */
- if (strchr(t, '+') == NULL)
- return t;
-
- /* xtext is always longer than decoded text */
- l = strlen(t);
- if (l > bplen)
- {
- if (bp != NULL)
- free(bp);
- bp = xalloc(l);
- bplen = l;
- }
-
- /* ok, copy the text with byte compression */
- for (p = bp; *t != '\0'; t++)
- {
- register int c = *t & 0xff;
-
- if (c != '+')
- {
- *p++ = c;
- continue;
- }
-
- c = *++t & 0xff;
- if (!isascii(c) || !isxdigit(c))
- {
- /* error -- first digit is not hex */
- usrerr("bogus xtext: +%c", c);
- t--;
- continue;
- }
- if (isdigit(c))
- c -= '0';
- else if (isupper(c))
- c -= 'A' - 10;
- else
- c -= 'a' - 10;
- *p = c << 4;
-
- c = *++t & 0xff;
- if (!isascii(c) || !isxdigit(c))
- {
- /* error -- second digit is not hex */
- usrerr("bogus xtext: +%x%c", *p >> 4, c);
- t--;
- continue;
- }
- if (isdigit(c))
- c -= '0';
- else if (isupper(c))
- c -= 'A' - 10;
- else
- c -= 'a' - 10;
- *p++ |= c;
- }
- return bp;
-}
- /*
-** XTEXTOK -- check if a string is legal xtext
-**
-** Xtext is used in Delivery Status Notifications. The spec was
-** taken from draft-ietf-notary-mime-delivery-04.txt.
-**
-** Parameters:
-** s -- the string to check.
-**
-** Returns:
-** TRUE -- if 's' is legal xtext.
-** FALSE -- if it has any illegal characters in it.
-*/
-
-bool
-xtextok(s)
- char *s;
-{
- int c;
-
- while ((c = *s++) != '\0')
- {
- if (c == '+')
- {
- c = *s++;
- if (!isascii(c) || !isxdigit(c))
- return FALSE;
- c = *s++;
- if (!isascii(c) || !isxdigit(c))
- return FALSE;
- }
- else if (c < '!' || c > '~' || c == '=')
- return FALSE;
- }
- return TRUE;
-}
- /*
** 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
pruneroute(addr)
char *addr;
{
OpenPOWER on IntegriCloud