From 82e3dc750dc6263f5af47bb973b9ee1fa8b059b0 Mon Sep 17 00:00:00 2001 From: Eric Allman Date: Tue, 22 Nov 1994 05:07:42 -0800 Subject: [PATCH] convert to new DSN draft SCCS-vsn: usr.sbin/sendmail/src/usersmtp.c 8.28 SCCS-vsn: usr.sbin/sendmail/src/recipient.c 8.54 SCCS-vsn: usr.sbin/sendmail/src/envelope.c 8.44 SCCS-vsn: usr.sbin/sendmail/src/parseaddr.c 8.41 SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 8.74 SCCS-vsn: usr.sbin/sendmail/src/savemail.c 8.40 SCCS-vsn: usr.sbin/sendmail/src/srvrsmtp.c 8.47 SCCS-vsn: usr.sbin/sendmail/src/queue.c 8.54 --- usr/src/usr.sbin/sendmail/src/envelope.c | 31 +++++--- usr/src/usr.sbin/sendmail/src/parseaddr.c | 4 +- usr/src/usr.sbin/sendmail/src/queue.c | 8 +- usr/src/usr.sbin/sendmail/src/recipient.c | 4 +- usr/src/usr.sbin/sendmail/src/savemail.c | 39 ++++++++-- usr/src/usr.sbin/sendmail/src/sendmail.h | 9 ++- usr/src/usr.sbin/sendmail/src/srvrsmtp.c | 94 ++++++++++++++++++++++- usr/src/usr.sbin/sendmail/src/usersmtp.c | 56 +++++++++----- 8 files changed, 197 insertions(+), 48 deletions(-) diff --git a/usr/src/usr.sbin/sendmail/src/envelope.c b/usr/src/usr.sbin/sendmail/src/envelope.c index f8e09e7ecb..226440659b 100644 --- a/usr/src/usr.sbin/sendmail/src/envelope.c +++ b/usr/src/usr.sbin/sendmail/src/envelope.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.43 (Berkeley) %G%"; +static char sccsid[] = "@(#)envelope.c 8.44 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -135,18 +135,22 @@ dropenvelope(e) { success_return = TRUE; } + else if (bitset(QRELAYED, q->q_flags)) + { + success_return = TRUE; + } else continue; /* common code for error returns and return receipts */ /* test for returning the body */ - if (!bitset(QHASRETPARAM, q->q_flags)) + if (!bitset(QHAS_RET_PARAM, q->q_flags)) { if (!bitset(EF_NORETURN, e->e_flags)) return_yes = TRUE; } - else if (bitset(QNOBODYRETURN, q->q_flags)) + else if (bitset(QRET_HDRS, q->q_flags)) return_no = TRUE; else return_yes = TRUE; @@ -182,7 +186,19 @@ dropenvelope(e) else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) { - if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && + bool delay_return = FALSE; + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags) && + bitset(QPINGONDELAY, q->q_flags)) + { + q->q_flags |= QREPORT; + delay_return = TRUE; + } + } + if (delay_return && + !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && e->e_class >= 0 && strcmp(e->e_from.q_paddr, "<>") != 0 && strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && @@ -204,11 +220,6 @@ dropenvelope(e) pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); fprintf(e->e_xfp, "Will keep trying until message is %s old\n", pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); - for (q = e->e_sendqueue; q != NULL; q = q->q_next) - { - if (bitset(QQUEUEUP, q->q_flags)) - q->q_flags |= QREPORT; - } } if (tTd(50, 2)) @@ -231,7 +242,7 @@ dropenvelope(e) e->e_flags |= EF_SENDRECEIPT; (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e); - (void) returntosender("Return receipt", rlist, FALSE, e); + (void) returntosender("Return receipt", rlist, return_yes, e); } e->e_flags &= ~EF_SENDRECEIPT; diff --git a/usr/src/usr.sbin/sendmail/src/parseaddr.c b/usr/src/usr.sbin/sendmail/src/parseaddr.c index aa32d1aa73..1cf246d564 100644 --- a/usr/src/usr.sbin/sendmail/src/parseaddr.c +++ b/usr/src/usr.sbin/sendmail/src/parseaddr.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)parseaddr.c 8.40 (Berkeley) %G%"; +static char sccsid[] = "@(#)parseaddr.c 8.41 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -1591,7 +1591,7 @@ buildaddr(tv, a, flags, e) clear((char *) a, sizeof *a); /* set up default error return flags */ - a->q_flags |= QPINGONFAILURE; + a->q_flags |= QPINGONFAILURE|QPINGONDELAY; /* figure out what net/mailer to use */ if (*tv == NULL || **tv != CANONNET) diff --git a/usr/src/usr.sbin/sendmail/src/queue.c b/usr/src/usr.sbin/sendmail/src/queue.c index 33d212077b..d23b40f854 100644 --- a/usr/src/usr.sbin/sendmail/src/queue.c +++ b/usr/src/usr.sbin/sendmail/src/queue.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 8.53 (Berkeley) %G% (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.54 (Berkeley) %G% (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.53 (Berkeley) %G% (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.54 (Berkeley) %G% (without queueing)"; #endif #endif /* not lint */ @@ -272,9 +272,9 @@ queueup(e, queueall, announce) putc('F', tfp); if (bitset(QPINGONDELAY, q->q_flags)) putc('D', tfp); - if (bitset(QHASRETPARAM, q->q_flags)) + if (bitset(QHAS_RET_PARAM, q->q_flags)) { - if (bitset(QNOBODYRETURN, q->q_flags)) + if (bitset(QRET_HDRS, q->q_flags)) putc('N', tfp); else putc('B', tfp); diff --git a/usr/src/usr.sbin/sendmail/src/recipient.c b/usr/src/usr.sbin/sendmail/src/recipient.c index bf3344d52a..4a8393a7dd 100644 --- a/usr/src/usr.sbin/sendmail/src/recipient.c +++ b/usr/src/usr.sbin/sendmail/src/recipient.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)recipient.c 8.53 (Berkeley) %G%"; +static char sccsid[] = "@(#)recipient.c 8.54 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -46,7 +46,7 @@ static char sccsid[] = "@(#)recipient.c 8.53 (Berkeley) %G%"; #define MAXRCRSN 10 /* maximum levels of alias recursion */ /* q_flags bits inherited from ctladdr */ -#define QINHERITEDBITS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHASRETPARAM|QNOBODYRETURN) +#define QINHERITEDBITS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHAS_RET_PARAM|QRET_HDRS) ADDRESS * sendto(list, copyf, ctladdr, qflags) diff --git a/usr/src/usr.sbin/sendmail/src/savemail.c b/usr/src/usr.sbin/sendmail/src/savemail.c index c4b0a47b9c..3866bfa5a2 100644 --- a/usr/src/usr.sbin/sendmail/src/savemail.c +++ b/usr/src/usr.sbin/sendmail/src/savemail.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)savemail.c 8.39 (Berkeley) %G%"; +static char sccsid[] = "@(#)savemail.c 8.40 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -728,7 +728,13 @@ errbody(mci, e, separator, flags) ** Output per-message information. */ - /* Original-MTS-Type: is optional */ + /* OMTS from MAIL FROM: line */ + if (e->e_parent->e_omts != NULL) + { + (void) sprintf(buf, "Original-MTS-Type: %s", + e->e_parent->e_omts); + putline(buf, mci); + } /* original envelope id from MAIL FROM: line */ if (e->e_parent->e_envid != NULL) @@ -738,12 +744,23 @@ errbody(mci, e, separator, flags) putline(buf, mci); } - /* Final-MTS-Type: is optional (always INET?) */ + /* Final-MTS-Type: is required -- our type */ + putline("Final-MTS-Type: Internet", mci); /* Final-MTA: seems silly -- this is in the From: line */ (void) sprintf(buf, "Final-MTA: %s", MyHostName); putline(buf, mci); + /* Received-From: shows where we got this message from */ + expand("Received-From: \201_", buf, &buf[sizeof buf - 1], + e->e_parent); + 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. */ @@ -756,10 +773,10 @@ errbody(mci, e, separator, flags) continue; putline("", mci); - /* Rcpt: -- the name from the RCPT command */ + /* Recipient: -- the name from the RCPT command */ for (r = q; r->q_alias != NULL; r = r->q_alias) continue; - (void) sprintf(buf, "Rcpt: %s", r->q_paddr); + (void) sprintf(buf, "Recipient: %s", r->q_paddr); putline(buf, mci); /* Action: -- what happened? */ @@ -797,6 +814,18 @@ errbody(mci, e, separator, flags) (void) sprintf(buf, "Final-Log-Id: %s", e->e_id); putline(buf, mci); + /* Expiry-Date: -- for delayed messages only */ + if (bitset(QQUEUEUP, q->q_flags) && + !bitset(QBADADDR, q->q_flags)) + { + time_t xdate; + + xdate = e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]; + sprintf(buf, "Expiry-Date: %s", + arpadate(ctime(&xdate))); + putline(buf, mci); + } + /* Original-Rcpt: -- passed from on high */ if (q->q_orcpt != NULL) { diff --git a/usr/src/usr.sbin/sendmail/src/sendmail.h b/usr/src/usr.sbin/sendmail/src/sendmail.h index 1b04d363be..b81f0a006b 100644 --- a/usr/src/usr.sbin/sendmail/src/sendmail.h +++ b/usr/src/usr.sbin/sendmail/src/sendmail.h @@ -5,7 +5,7 @@ * * %sccs.include.redist.c% * - * @(#)sendmail.h 8.73 (Berkeley) %G% + * @(#)sendmail.h 8.74 (Berkeley) %G% */ /* @@ -15,7 +15,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 8.73 %G%"; +static char SmailSccsId[] = "@(#)sendmail.h 8.74 %G%"; # endif # else /* _DEFINE */ # define EXTERN extern @@ -141,8 +141,8 @@ typedef struct address ADDRESS; # define QPINGONSUCCESS 0x00001000 /* give return on successful delivery */ # define QPINGONFAILURE 0x00002000 /* give return on failure */ # define QPINGONDELAY 0x00004000 /* give return on message delay */ -# define QHASRETPARAM 0x00008000 /* RCPT command had RET argument */ -# define QNOBODYRETURN 0x00010000 /* don't return message body */ +# define QHAS_RET_PARAM 0x00008000 /* RCPT command had RET argument */ +# define QRET_HDRS 0x00010000 /* don't return message body */ # define QRELAYED 0x00020000 /* relayed to non-DSN aware mailer */ # define NULLADDR ((ADDRESS *) NULL) @@ -375,6 +375,7 @@ ENVELOPE char *e_msgboundary; /* MIME-style message part boundary */ char *e_origrcpt; /* original recipient (one only) */ char *e_envid; /* envelope id from MAIL FROM: line */ + char *e_omts; /* OMTS parameter from MAIL FROM: */ time_t e_dtime; /* time of last delivery attempt */ int e_ntries; /* number of delivery attempts */ dev_t e_dfdev; /* df file's device, for crash recov */ diff --git a/usr/src/usr.sbin/sendmail/src/srvrsmtp.c b/usr/src/usr.sbin/sendmail/src/srvrsmtp.c index 46b80f24fc..092081dde3 100644 --- a/usr/src/usr.sbin/sendmail/src/srvrsmtp.c +++ b/usr/src/usr.sbin/sendmail/src/srvrsmtp.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)srvrsmtp.c 8.46 (Berkeley) %G% (with SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.47 (Berkeley) %G% (with SMTP)"; #else -static char sccsid[] = "@(#)srvrsmtp.c 8.46 (Berkeley) %G% (without SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.47 (Berkeley) %G% (without SMTP)"; #endif #endif /* not lint */ @@ -452,6 +452,15 @@ smtp(e) } e->e_envid = newstr(vp); } + else if (strcasecmp(kp, "omts") == 0) + { + if (vp == NULL) + { + usrerr("501 OMTS requires a value"); + /* NOTREACHED */ + } + e->e_omts = newstr(vp); + } else { usrerr("501 %s parameter unrecognized", kp); @@ -805,6 +814,87 @@ skipword(p, w) return (p); } /* +** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line +** +** Parameters: +** a -- the address corresponding to the To: parameter. +** kp -- the parameter key. +** vp -- the value of that parameter. +** e -- the envelope. +** +** Returns: +** none. +*/ + +rcpt_esmtp_args(a, kp, vp, e) + ADDRESS *a; + char *kp; + char *vp; + ENVELOPE *e; +{ + if (strcasecmp(kp, "notify") == 0) + { + char *p; + + if (vp == NULL) + { + usrerr("501 NOTIFY requires a value"); + /* NOTREACHED */ + } + a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY); + if (strcasecmp(vp, "never") == 0) + return; + for (p = vp; p != NULL; vp = p) + { + p = strchr(p, ','); + if (p != NULL) + *p++ = '\0'; + if (strcasecmp(vp, "success") == 0) + a->q_flags |= QPINGONSUCCESS; + else if (strcasecmp(vp, "failure") == 0) + a->q_flags |= QPINGONFAILURE; + else if (strcasecmp(vp, "delay") == 0) + a->q_flags |= QPINGONDELAY; + else + { + usrerr("501 Bad argument \"%s\" to NOTIFY", + vp); + /* NOTREACHED */ + } + } + } + else if (strcasecmp(kp, "ret") == 0) + { + if (vp == NULL) + { + usrerr("501 RET requires a value"); + /* NOTREACHED */ + } + a->q_flags |= QHAS_RET_PARAM; + if (strcasecmp(vp, "hdrs") == 0) + a->q_flags |= QRET_HDRS; + else if (strcasecmp(vp, "full") != 0) + { + usrerr("501 Bad argument \"%s\" to RET", vp); + /* NOTREACHED */ + } + } + else if (strcasecmp(kp, "orcpt") == 0) + { + if (vp == NULL) + { + usrerr("501 ORCPT requires a value"); + /* NOTREACHED */ + } + a->q_orcpt = newstr(vp); + } + else + { + usrerr("501 %s parameter unrecognized", kp); + /* NOTREACHED */ + } +} + /* ** PRINTVRFYADDR -- print an entry in the verify queue ** ** Parameters: diff --git a/usr/src/usr.sbin/sendmail/src/usersmtp.c b/usr/src/usr.sbin/sendmail/src/usersmtp.c index a08999d7ac..1e133e3f8c 100644 --- a/usr/src/usr.sbin/sendmail/src/usersmtp.c +++ b/usr/src/usr.sbin/sendmail/src/usersmtp.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 8.27 (Berkeley) %G% (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.28 (Berkeley) %G% (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 8.27 (Berkeley) %G% (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.28 (Berkeley) %G% (without SMTP)"; #endif #endif /* not lint */ @@ -291,7 +291,7 @@ helo_options(line, firstline, m, mci, e) } else if (strcasecmp(line, "expn") == 0) mci->mci_flags |= MCIF_EXPN; - else if (strcasecmp(line, "x-dsn-0") == 0) + else if (strcasecmp(line, "x-dsn-1") == 0) mci->mci_flags |= MCIF_DSN; } /* @@ -355,10 +355,18 @@ smtpmailfrom(m, mci, e) return EX_DATAERR; } - if (e->e_envid != NULL && bitset(MCIF_DSN, mci->mci_flags)) + if (bitset(MCIF_DSN, mci->mci_flags)) { - strcat(optbuf, " ENVID="); - strcat(optbuf, e->e_envid); + if (e->e_envid != NULL) + { + strcat(optbuf, " ENVID="); + strcat(optbuf, e->e_envid); + } + if (e->e_omts != NULL) + { + strcat(optbuf, " OMTS="); + strcat(optbuf, e->e_omts); + } } /* @@ -465,28 +473,38 @@ smtprcpt(to, m, mci, e) strcpy(optbuf, ""); if (bitset(MCIF_DSN, mci->mci_flags)) { + bool firstone = TRUE; + strcat(optbuf, " NOTIFY="); if (bitset(QPINGONFAILURE, to->q_flags)) { - if (bitset(QPINGONSUCCESS, to->q_flags)) - strcat(optbuf, "ALWAYS"); - else - strcat(optbuf, "FAILURE"); + strcat(optbuf, "FAILURE"); + firstone = FALSE; } - else + if (bitset(QPINGONSUCCESS, to->q_flags)) { - if (bitset(QPINGONSUCCESS, to->q_flags)) - strcat(optbuf, "SUCCESS"); - else - strcat(optbuf, "NEVER"); + if (firstone) + strcat(optbuf, ","); + strcat(optbuf, "SUCCESS"); + firstone = FALSE; } - if (bitset(QHASRETPARAM, to->q_flags)) + if (bitset(QPINGONDELAY, to->q_flags)) + { + if (firstone) + strcat(optbuf, ","); + strcat(optbuf, "DELAY"); + firstone = FALSE; + } + if (firstone) + strcat(optbuf, "NEVER"); + + if (bitset(QHAS_RET_PARAM, to->q_flags)) { strcat(optbuf, " RET="); - if (bitset(QNOBODYRETURN, to->q_flags)) - strcat(optbuf, "NO"); + if (bitset(QRET_HDRS, to->q_flags)) + strcat(optbuf, "HDRS"); else - strcat(optbuf, "YES"); + strcat(optbuf, "FULL"); } } else if (bitset(QPINGONSUCCESS, to->q_flags)) -- 2.20.1