*/
#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"
{
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;
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 &&
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))
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;
*/
#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"
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)
#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 */
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);
*/
#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"
#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)
*/
#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"
** 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)
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.
*/
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? */
(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)
{
*
* %sccs.include.redist.c%
*
- * @(#)sendmail.h 8.73 (Berkeley) %G%
+ * @(#)sendmail.h 8.74 (Berkeley) %G%
*/
/*
# 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
# 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)
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 */
#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 */
}
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);
return (p);
}
\f/*
+** 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 */
+ }
+}
+\f/*
** PRINTVRFYADDR -- print an entry in the verify queue
**
** Parameters:
#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 */
}
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;
}
\f/*
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);
+ }
}
/*
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))