# include <pwd.h>
#ifndef lint
-static char sccsid[] = "@(#)alias.c 8.39 (Berkeley) %G%";
+static char sccsid[] = "@(#)alias.c 8.40 (Berkeley) %G%";
#endif /* not lint */
fprintf(e->e_xfp, "Message delivered to mailing list %s\n",
a->q_paddr);
e->e_flags |= EF_SENDRECEIPT;
- a->q_flags |= QREPORT;
+ a->q_flags |= QREPORT|QEXPLODED;
}
\f/*
** ALIASLOOKUP -- look up a name in the alias file.
*/
#ifndef lint
-static char sccsid[] = "@(#)deliver.c 8.136 (Berkeley) %G%";
+static char sccsid[] = "@(#)deliver.c 8.137 (Berkeley) %G%";
#endif /* not lint */
#include "sendmail.h"
to->q_paddr);
}
else if (bitset(QPINGONSUCCESS, to->q_flags) &&
+ bitset(QPRIMARY, to->q_flags) &&
!bitset(MCIF_DSN, mci->mci_flags))
{
to->q_flags |= QRELAYED;
*/
#ifndef lint
-static char sccsid[] = "@(#)envelope.c 8.55 (Berkeley) %G%";
+static char sccsid[] = "@(#)envelope.c 8.56 (Berkeley) %G%";
#endif /* not lint */
#include "sendmail.h"
(void) sendtolist(e->e_from.q_paddr, NULL,
&e->e_errorqueue, 0, e);
}
- else if (bitset(QSENT, q->q_flags) &&
- bitnset(M_LOCALMAILER, q->q_mailer->m_flags) &&
- bitset(QPINGONSUCCESS, q->q_flags))
+ else if (bitset(QPINGONSUCCESS, q->q_flags) &&
+ ((bitset(QSENT, q->q_flags) &&
+ bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) ||
+ bitset(QRELAYED|QEXPLODED, q->q_flags)))
{
success_return = TRUE;
}
- else if (bitset(QRELAYED, q->q_flags))
- {
- success_return = TRUE;
- }
- else
- {
- continue;
- }
}
if (e->e_class < 0)
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.92 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c 8.93 (Berkeley) %G%";
#endif /* not lint */
#define _DEFINE
if (tTd(0, 15))
{
/* print configuration table (or at least part of it) */
- printrules();
+ if (tTd(0, 90))
+ printrules();
for (i = 0; i < MAXMAILERS; i++)
{
- register struct mailer *m = Mailer[i];
- int j;
-
- if (m == NULL)
- continue;
- printmailer(m);
+ if (Mailer[i] != NULL)
+ printmailer(Mailer[i]);
}
}
*/
#ifndef lint
-static char sccsid[] = "@(#)parseaddr.c 8.60 (Berkeley) %G%";
+static char sccsid[] = "@(#)parseaddr.c 8.61 (Berkeley) %G%";
#endif /* not lint */
#include "sendmail.h"
"QPINGONDELAY", QPINGONDELAY,
"QHASNOTIFY", QHASNOTIFY,
"QRELAYED", QRELAYED,
+ "QEXPLODED", QEXPLODED,
+ "QTHISPASS", QTHISPASS,
NULL
};
#ifndef lint
#ifdef QUEUE
-static char sccsid[] = "@(#)queue.c 8.73 (Berkeley) %G% (with queueing)";
+static char sccsid[] = "@(#)queue.c 8.74 (Berkeley) %G% (with queueing)";
#else
-static char sccsid[] = "@(#)queue.c 8.73 (Berkeley) %G% (without queueing)";
+static char sccsid[] = "@(#)queue.c 8.74 (Berkeley) %G% (without queueing)";
#endif
#endif /* not lint */
if (tTd(40, 1))
printf("\n>>>>> queueing %s%s queueall=%d >>>>>\n", e->e_id,
newid ? " (new id)" : "", queueall);
+ if (tTd(40, 3))
+ {
+ extern void printenvflags();
+
+ printf(" e_flags=");
+ printenvflags(e);
+ }
if (tTd(40, 32))
{
printf(" sendq=");
{
syserr("readqf: cannot open %s", p);
}
- else if (fstat(fileno(e->e_dfp), &st) >= 0)
+ else
{
- e->e_msgsize = st.st_size;
- e->e_dfdev = st.st_dev;
- e->e_dfino = st.st_ino;
+ e->e_flags |= EF_HAS_DF;
+ if (fstat(fileno(e->e_dfp), &st) >= 0)
+ {
+ e->e_msgsize = st.st_size;
+ e->e_dfdev = st.st_dev;
+ e->e_dfino = st.st_ino;
+ }
}
}
a->q_home = newstr(pw->pw_dir);
a->q_uid = pw->pw_uid;
a->q_gid = pw->pw_gid;
- a->q_user = newstr(user);
a->q_flags |= QGOODUID;
}
+
+ if (*user != '\0')
+ a->q_user = newstr(user);
+ else if (p != NULL)
+ a->q_user = newstr(p);
else
- {
a->q_user = newstr(DefUser);
- }
a->q_flags |= QPRIMARY; /* flag as a "ctladdr" */
a->q_mailer = LocalMailer;
*/
#ifndef lint
-static char sccsid[] = "@(#)recipient.c 8.74 (Berkeley) %G%";
+static char sccsid[] = "@(#)recipient.c 8.75 (Berkeley) %G%";
#endif /* not lint */
# include "sendmail.h"
a->q_flags |= ctladdr->q_flags & ~QPRIMARY;
a->q_flags |= qflags;
- /* see if this should be marked as a primary address */
- if (ctladdr == NULL ||
- (firstone && *p == '\0' && bitset(QPRIMARY, ctladdr->q_flags)))
- a->q_flags |= QPRIMARY;
-
sibl = recipient(a);
if (sibl != NULL)
{
register char *p;
bool quoted = FALSE; /* set if the addr has a quote bit */
int findusercount = 0;
+ bool initialdontsend = bitset(QDONTSEND, a->q_flags);
int i;
char *buf;
char buf0[MAXNAME + 1]; /* unquoted image of the user name */
e->e_to = a->q_paddr;
m = a->q_mailer;
errno = 0;
+ if (aliaslevel == 0)
+ a->q_flags |= QPRIMARY;
if (tTd(26, 1))
{
- printf("\nrecipient: ");
+ printf("\nrecipient (%d): ", aliaslevel);
printaddr(a, FALSE);
}
ConfigLevel >= 2 && RewriteRules[5] != NULL &&
bitnset(M_TRYRULESET5, m->m_flags))
{
- maplocaluser(a, sendq, aliaslevel, e);
+ maplocaluser(a, sendq, aliaslevel + 1, e);
}
/*
e->e_nrcpts++;
testselfdestruct:
+ a->q_flags |= QTHISPASS;
if (tTd(26, 8))
{
printf("testselfdestruct: ");
- printaddr(a, TRUE);
+ printaddr(a, FALSE);
+ if (tTd(26, 10))
+ {
+ printf("SENDQ:\n");
+ printaddr(*sendq, TRUE);
+ printf("----\n");
+ }
}
if (a->q_alias == NULL && a != &e->e_from &&
bitset(QDONTSEND, a->q_flags))
{
- q = *sendq;
- while (q != NULL && bitset(QDONTSEND, q->q_flags))
- q = q->q_next;
+ for (q = *sendq; q != NULL; q = q->q_next)
+ {
+ if (!bitset(QDONTSEND|QBADADDR, q->q_flags) &&
+ bitset(QTHISPASS, q->q_flags))
+ break;
+ }
if (q == NULL)
{
a->q_flags |= QBADADDR;
}
done:
+ a->q_flags |= QTHISPASS;
if (buf != buf0)
free(buf);
+
+ /*
+ ** If we are at the top level, check to see if this has
+ ** expanded to exactly one address. If so, it can inherit
+ ** the primaryness of the address.
+ **
+ ** While we're at it, clear the QTHISPASS bits.
+ */
+
+ if (aliaslevel == 0)
+ {
+ int nrcpts = 0;
+ ADDRESS *only;
+
+ for (q = *sendq; q != NULL; q = q->q_next)
+ {
+ if (bitset(QTHISPASS, q->q_flags) &&
+ !bitset(QDONTSEND|QBADADDR, q->q_flags))
+ {
+ nrcpts++;
+ only = q;
+ }
+ q->q_flags &= ~QTHISPASS;
+ }
+ if (nrcpts == 1)
+ only->q_flags |= QPRIMARY;
+ else if (!initialdontsend)
+ {
+ /* arrange for return receipt */
+ e->e_flags |= EF_SENDRECEIPT;
+ a->q_flags |= QEXPLODED;
+ if (e->e_xfp != NULL)
+ fprintf(e->e_xfp,
+ "%s... expanded to multiple addresses\n",
+ a->q_paddr);
+ }
+ }
+
return (a);
return (a);
*/
#ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.59 (Berkeley) %G%";
+static char sccsid[] = "@(#)savemail.c 8.60 (Berkeley) %G%";
#endif /* not lint */
# include "sendmail.h"
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR|QREPORT|QRELAYED, q->q_flags))
+ if (bitset(QBADADDR|QREPORT|QRELAYED|QEXPLODED, q->q_flags))
{
- if (printheader)
- {
- putline(" ----- The following addresses have delivery notifications -----",
- mci);
- printheader = FALSE;
- }
strcpy(buf, q->q_paddr);
if (bitset(QBADADDR, q->q_flags))
strcat(buf, " (unrecoverable error)");
+ else if (!bitset(QPRIMARY, q->q_flags))
+ continue;
else if (bitset(QRELAYED, q->q_flags))
strcat(buf, " (relayed to non-DSN-aware mailer)");
else if (bitset(QSENT, q->q_flags))
strcat(buf, " (successfully delivered)");
+ else if (bitset(QEXPLODED, q->q_flags))
+ strcat(buf, " (expanded by mailing list)");
else
strcat(buf, " (transient failure)");
+ if (printheader)
+ {
+ putline(" ----- The following addresses have delivery notifications -----",
+ mci);
+ printheader = FALSE;
+ }
putline(buf, mci);
if (q->q_alias != NULL)
{
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
register ADDRESS *r;
+ char *action;
- if (!bitset(QBADADDR|QREPORT|QRELAYED, q->q_flags))
+ if (bitset(QBADADDR, q->q_flags))
+ action = "failure";
+ else if (!bitset(QPRIMARY, q->q_flags))
+ continue;
+ else if (bitset(QRELAYED, q->q_flags))
+ action = "relayed";
+ else if (bitset(QEXPLODED, q->q_flags))
+ action = "delivered (to mailing list)";
+ else if (bitset(QSENT, q->q_flags) &&
+ bitnset(M_LOCALMAILER, q->q_mailer->m_flags))
+ action = "delivered (final delivery)";
+ else if (bitset(QREPORT, q->q_flags))
+ action = "delayed";
+ else
continue;
+
putline("", mci);
/* Original-Recipient: -- passed from on high */
}
putline(buf, mci);
+ /* X-Actual-Recipient: -- the real problem address */
+ if (r != q)
+ {
+ if (strchr(q->q_user, '@') == NULL)
+ {
+ (void) sprintf(buf, "X-Actual-Recipient: %s; %s@",
+ p, xtextify(q->q_user));
+ strcat(buf, xtextify(MyHostName));
+ }
+ else
+ {
+ (void) sprintf(buf, "X-Actual-Recipient: %s; %s",
+ p, xtextify(q->q_user));
+ }
+ putline(buf, mci);
+ }
+
/* Action: -- what happened? */
- if (bitset(QBADADDR, q->q_flags))
- putline("Action: failure", mci);
- else if (bitset(QQUEUEUP, q->q_flags))
- putline("Action: delayed", mci);
- else if (bitset(QRELAYED, q->q_flags))
- putline("Action: relayed", mci);
- else
- putline("Action: delivered", mci);
+ sprintf(buf, "Action: %s", action);
+ putline(buf, mci);
/* Status: -- what _really_ happened? */
strcpy(buf, "Status: ");
strcat(buf, "5.0.0");
else if (bitset(QQUEUEUP, q->q_flags))
strcat(buf, "4.0.0");
- else if (bitset(QRELAYED, q->q_flags))
- strcat(buf, "6.0.1");
else
strcat(buf, "2.0.0");
putline(buf, mci);
(void) sprintf(buf, "Remote-MTA: %s; ", p);
if (q->q_statmta != NULL)
p = q->q_statmta;
- else if (q->q_host != NULL)
+ else if (q->q_host != NULL && q->q_host[0] != '\0')
p = q->q_host;
else
p = NULL;
if (p == NULL)
p = "smtp";
(void) sprintf(buf, "Diagnostic-Code: %s; %s",
- p, xtextify(q->q_rstatus));
+ p, q->q_rstatus);
putline(buf, mci);
}
register int c = (*p & 0xff);
/* ASCII dependence here -- this is the way the spec words it */
- if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
+ if ((c < ' ' || c > '~' || c == '+' || c == '\\' || c == '(') &&
+ c != '\t')
nbogus++;
l++;
}
*
* %sccs.include.redist.c%
*
- * @(#)sendmail.h 8.106 (Berkeley) %G%
+ * @(#)sendmail.h 8.107 (Berkeley) %G%
*/
/*
# ifdef _DEFINE
# define EXTERN
# ifndef lint
-static char SmailSccsId[] = "@(#)sendmail.h 8.106 %G%";
+static char SmailSccsId[] = "@(#)sendmail.h 8.107 %G%";
# endif
# else /* _DEFINE */
# define EXTERN extern
# define QDONTSEND 0x00000001 /* don't send to this address */
# define QBADADDR 0x00000002 /* this address is verified bad */
# define QGOODUID 0x00000004 /* the q_uid q_gid fields are good */
-# define QPRIMARY 0x00000008 /* set from argv */
+# define QPRIMARY 0x00000008 /* set from RCPT or argv */
# define QQUEUEUP 0x00000010 /* queue for later transmission */
# define QSENT 0x00000020 /* has been successfully delivered */
# define QNOTREMOTE 0x00000040 /* address not for remote forwarding */
# define QPINGONFAILURE 0x00002000 /* give return on failure */
# define QPINGONDELAY 0x00004000 /* give return on message delay */
# define QHASNOTIFY 0x00008000 /* propogate notify parameter */
-# define QRELAYED 0x00020000 /* relayed to non-DSN aware mailer */
+# define QRELAYED 0x00010000 /* relayed to non-DSN aware mailer */
+# define QEXPLODED 0x00020000 /* undergone mailing list explosion */
+# define QTHISPASS 0x80000000 /* temp: address set this pass */
# define NULLADDR ((ADDRESS *) NULL)
# define QPSEUDO 000040 /* only on the list for verification */
char *map_domain; /* the (nominal) NIS domain */
char *map_rebuild; /* program to run to do auto-rebuild */
time_t map_mtime; /* last database modification time */
+ short map_specificity; /* specificity of alaases */
MAP *map_stack[MAXMAPSTACK]; /* list for stacked maps */
short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */
};
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)srvrsmtp.c 8.61 (Berkeley) %G% (with SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.62 (Berkeley) %G% (with SMTP)";
#else
-static char sccsid[] = "@(#)srvrsmtp.c 8.61 (Berkeley) %G% (without SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.62 (Berkeley) %G% (without SMTP)";
#endif
#endif /* not lint */
case CMDRSET: /* rset -- reset state */
message("250 Reset state");
+
+ /* arrange to ignore any current send list */
+ e->e_sendqueue = NULL;
e->e_flags |= EF_CLRQUEUE;
if (InChild)
finis();
message("221 %s closing connection", MyHostName);
doquit:
+ /* arrange to ignore any current send list */
+ e->e_sendqueue = NULL;
+
/* avoid future 050 messages */
disconnect(1, e);
#ifndef lint
#ifdef USERDB
-static char sccsid [] = "@(#)udb.c 8.15 (Berkeley) %G% (with USERDB)";
+static char sccsid [] = "@(#)udb.c 8.16 (Berkeley) %G% (with USERDB)";
#else
-static char sccsid [] = "@(#)udb.c 8.15 (Berkeley) %G% (without USERDB)";
+static char sccsid [] = "@(#)udb.c 8.16 (Berkeley) %G% (without USERDB)";
#endif
#endif
fprintf(e->e_xfp,
"Message delivered to mailing list %s\n",
a->q_paddr);
- e->e_flags |= EF_SENDRECEIPT;
}
+ e->e_flags |= EF_SENDRECEIPT;
+ a->q_flags |= QREPORT|QEXPLODED;
break;
#ifdef HESIOD
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)usersmtp.c 8.40 (Berkeley) %G% (with SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.41 (Berkeley) %G% (with SMTP)";
#else
-static char sccsid[] = "@(#)usersmtp.c 8.40 (Berkeley) %G% (without SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.41 (Berkeley) %G% (without SMTP)";
#endif
#endif /* not lint */
if (bitset(MCIF_DSN, mci->mci_flags))
{
/* NOTIFY= parameter */
- if (bitset(QHASNOTIFY, to->q_flags))
+ if (bitset(QHASNOTIFY, to->q_flags) &&
+ bitset(QPRIMARY, to->q_flags))
{
bool firstone = TRUE;