propagate alias owner information back to envelope sender
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Wed, 24 Feb 1993 21:37:00 +0000 (13:37 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Wed, 24 Feb 1993 21:37:00 +0000 (13:37 -0800)
SCCS-vsn: usr.sbin/sendmail/src/headers.c 6.12
SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 6.22
SCCS-vsn: usr.sbin/sendmail/src/util.c 6.7
SCCS-vsn: usr.sbin/sendmail/src/deliver.c 6.25
SCCS-vsn: usr.sbin/sendmail/src/alias.c 6.18

usr/src/usr.sbin/sendmail/src/alias.c
usr/src/usr.sbin/sendmail/src/deliver.c
usr/src/usr.sbin/sendmail/src/headers.c
usr/src/usr.sbin/sendmail/src/sendmail.h
usr/src/usr.sbin/sendmail/src/util.c

index 7e11747..b18616c 100644 (file)
@@ -29,15 +29,15 @@ ERROR: DBM is no longer supported -- use NDBM instead.
 #ifndef lint
 #ifdef NEWDB
 #ifdef NDBM
 #ifndef lint
 #ifdef NEWDB
 #ifdef NDBM
-static char sccsid[] = "@(#)alias.c    6.17 (Berkeley) %G% (with NEWDB and NDBM)";
+static char sccsid[] = "@(#)alias.c    6.18 (Berkeley) %G% (with NEWDB and NDBM)";
 #else
 #else
-static char sccsid[] = "@(#)alias.c    6.17 (Berkeley) %G% (with NEWDB)";
+static char sccsid[] = "@(#)alias.c    6.18 (Berkeley) %G% (with NEWDB)";
 #endif
 #else
 #ifdef NDBM
 #endif
 #else
 #ifdef NDBM
-static char sccsid[] = "@(#)alias.c    6.17 (Berkeley) %G% (with NDBM)";
+static char sccsid[] = "@(#)alias.c    6.18 (Berkeley) %G% (with NDBM)";
 #else
 #else
-static char sccsid[] = "@(#)alias.c    6.17 (Berkeley) %G% (without NEWDB or NDBM)";
+static char sccsid[] = "@(#)alias.c    6.18 (Berkeley) %G% (without NEWDB or NDBM)";
 #endif
 #endif
 #endif /* not lint */
 #endif
 #endif
 #endif /* not lint */
@@ -114,6 +114,8 @@ alias(a, sendq, e)
 {
        register char *p;
        int naliases;
 {
        register char *p;
        int naliases;
+       char *owner;
+       char obuf[MAXNAME + 6];
        extern ADDRESS *sendto();
        extern char *aliaslookup();
 
        extern ADDRESS *sendto();
        extern char *aliaslookup();
 
@@ -168,6 +170,25 @@ alias(a, sendq, e)
                }
                a->q_flags |= QDONTSEND;
        }
                }
                a->q_flags |= QDONTSEND;
        }
+
+       /*
+       **  Look for owner of alias
+       */
+
+       (void) strcpy(obuf, "owner-");
+       if (strncmp(a->q_user, "owner-", 6) == 0)
+               (void) strcat(obuf, "owner");
+       else
+               (void) strcat(obuf, a->q_user);
+       if (!bitnset(M_USR_UPPER, a->q_mailer->m_flags))
+               makelower(obuf);
+       owner = aliaslookup(obuf);
+       if (owner != NULL)
+       {
+               if (strchr(owner, ',') != NULL)
+                       owner = obuf;
+               a->q_owner = newstr(owner);
+       }
 }
 \f/*
 **  ALIASLOOKUP -- look up a name in the alias file.
 }
 \f/*
 **  ALIASLOOKUP -- look up a name in the alias file.
index 319430c..3fec485 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)deliver.c  6.24 (Berkeley) %G%";
+static char sccsid[] = "@(#)deliver.c  6.25 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -1287,6 +1287,28 @@ putbody(fp, m, e)
        errno = 0;
 }
 \f/*
        errno = 0;
 }
 \f/*
+**  PARENTBODY -- put the body of the parent of a message.
+**
+**     Parameters:
+**             fp -- file to output onto.
+**             m -- a mailer descriptor to control output format.
+**             e -- the envelope whose parent to put out.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             The message is written onto fp.
+*/
+
+parentbody(fp, m, e)
+       FILE *fp;
+       MAILER *m;
+       register ENVELOPE *e;
+{
+       putbody(fp, m, e->e_parent);
+}
+\f/*
 **  MAILFILE -- Send a message to a file.
 **
 **     If the file has the setuid/setgid bits set, but NO execute
 **  MAILFILE -- Send a message to a file.
 **
 **     If the file has the setuid/setgid bits set, but NO execute
@@ -1457,6 +1479,9 @@ sendall(e, mode)
        register ADDRESS *q;
        bool oldverbose;
        int pid;
        register ADDRESS *q;
        bool oldverbose;
        int pid;
+       char *owner;
+       int otherowners;
+       ENVELOPE *splitenv = NULL;
 # ifdef LOCKF
        struct flock lfd;
 # endif
 # ifdef LOCKF
        struct flock lfd;
 # endif
@@ -1508,6 +1533,106 @@ sendall(e, mode)
                (void) recipient(&e->e_from, &e->e_sendqueue, e);
        }
 
                (void) recipient(&e->e_from, &e->e_sendqueue, e);
        }
 
+       /*
+       **  Handle alias owners.
+       **
+       **      We scan up the q_alias chain looking for owners.
+       **      We discard owners that are the same as the return path.
+       */
+
+       for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+       {
+               register struct address *a;
+
+               for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
+                       continue;
+               if (a != NULL)
+                       q->q_owner = a->q_owner;
+                               
+               if (q->q_owner != NULL && !bitset(QDONTSEND, q->q_flags) &&
+                   strcmp(q->q_owner, e->e_returnpath) == 0)
+                       q->q_owner = NULL;
+       }
+               
+       owner = "";
+       otherowners = 1;
+       while (owner != NULL && otherowners > 0)
+       {
+               owner = NULL;
+               otherowners = 0;
+
+               for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+               {
+                       if (bitset(QDONTSEND, q->q_flags))
+                               continue;
+
+                       if (q->q_owner != NULL)
+                       {
+                               if (owner == NULL)
+                                       owner = q->q_owner;
+                               else if (owner != q->q_owner)
+                               {
+                                       if (strcmp(owner, q->q_owner) == 0)
+                                       {
+                                               /* make future comparisons cheap */
+                                               q->q_owner = owner;
+                                       }
+                                       else
+                                       {
+                                               otherowners++;
+                                       }
+                                       owner = q->q_owner;
+                               }
+                       }
+                       else
+                       {
+                               otherowners++;
+                       }
+               }
+
+               if (owner != NULL && otherowners > 0)
+               {
+                       register ENVELOPE *ee;
+                       extern ENVELOPE *newenvelope();
+                       extern HDR *copyheader();
+                       extern ADDRESS *copyqueue();
+
+                       ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE));
+                       STRUCTCOPY(*e, *ee);
+                       ee->e_id = NULL;
+                       ee->e_parent = e;
+                       ee->e_header = copyheader(e->e_header);
+                       ee->e_sendqueue = copyqueue(e->e_sendqueue);
+                       ee->e_errorqueue = copyqueue(e->e_errorqueue);
+                       ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE);
+                       ee->e_returnpath = owner;
+                       ee->e_putbody = parentbody;
+                       ee->e_sibling = splitenv;
+                       splitenv = ee;
+                       
+                       for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+                               if (q->q_owner == owner)
+                                       q->q_flags |= QDONTSEND;
+                       for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
+                               if (q->q_owner != owner)
+                                       q->q_flags |= QDONTSEND;
+
+                       if (e->e_df != NULL && mode != SM_VERIFY)
+                       {
+                               ee->e_dfp = NULL;
+                               ee->e_df = queuename(ee, 'd');
+                               if (link(e->e_df, ee->e_df) < 0)
+                               {
+                                       syserr("sendall: link(%s, %s)",
+                                               e->e_df, ee->e_df);
+                               }
+                       }
+               }
+       }
+
+       if (owner != NULL)
+               e->e_returnpath = owner;
+
 # ifdef QUEUE
        if ((mode == SM_QUEUE || mode == SM_FORK ||
             (mode != SM_VERIFY && SuperSafe)) &&
 # ifdef QUEUE
        if ((mode == SM_QUEUE || mode == SM_FORK ||
             (mode != SM_VERIFY && SuperSafe)) &&
@@ -1515,6 +1640,23 @@ sendall(e, mode)
                queueup(e, TRUE, mode == SM_QUEUE);
 #endif /* QUEUE */
 
                queueup(e, TRUE, mode == SM_QUEUE);
 #endif /* QUEUE */
 
+       if (splitenv != NULL)
+       {
+               if (tTd(13, 1))
+               {
+                       printf("\nsendall: Split queue; remaining queue:\n");
+                       printaddr(e->e_sendqueue, TRUE);
+               }
+
+               while (splitenv != NULL)
+               {
+                       sendall(splitenv, mode);
+                       splitenv = splitenv->e_sibling;
+               }
+
+               CurEnv = e;
+       }
+
        oldverbose = Verbose;
        switch (mode)
        {
        oldverbose = Verbose;
        switch (mode)
        {
@@ -1660,8 +1802,6 @@ sendall(e, mode)
 
        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
        {
 
        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
        {
-               register ADDRESS *qq;
-
                if (tTd(13, 3))
                {
                        printf("Checking ");
                if (tTd(13, 3))
                {
                        printf("Checking ");
@@ -1672,44 +1812,8 @@ sendall(e, mode)
                if (!bitset(QBADADDR, q->q_flags))
                        continue;
 
                if (!bitset(QBADADDR, q->q_flags))
                        continue;
 
-               /* we have an address that failed -- find the parent */
-               for (qq = q; qq != NULL; qq = qq->q_alias)
-               {
-                       char obuf[MAXNAME + 6];
-                       extern char *aliaslookup();
-
-                       /* we can only have owners for local addresses */
-                       if (!bitnset(M_LOCALMAILER, qq->q_mailer->m_flags))
-                               continue;
-
-                       /* see if the owner list exists */
-                       (void) strcpy(obuf, "owner-");
-                       if (strncmp(qq->q_user, "owner-", 6) == 0)
-                               (void) strcat(obuf, "owner");
-                       else
-                               (void) strcat(obuf, qq->q_user);
-                       if (!bitnset(M_USR_UPPER, qq->q_mailer->m_flags))
-                               makelower(obuf);
-                       if (aliaslookup(obuf) == NULL)
-                               continue;
-
-                       if (tTd(13, 4))
-                               printf("Errors to %s\n", obuf);
-
-                       /* owner list exists -- add it to the error queue */
-                       (void) sendtolist(obuf, (ADDRESS *) NULL,
-                                         &e->e_errorqueue, e);
-
-                       /* and set the return path to point to it */
-                       e->e_returnpath = newstr(obuf);
-
-                       ErrorMode = EM_MAIL;
-                       break;
-               }
-
-               /* if we did not find an owner, send to the sender */
-               if (qq == NULL && bitset(QBADADDR, q->q_flags))
-                       (void) sendtolist(e->e_from.q_paddr, qq,
+               if (q->q_owner == NULL)
+                       (void) sendtolist(e->e_from.q_paddr, NULL,
                                          &e->e_errorqueue, e);
        }
 
                                          &e->e_errorqueue, e);
        }
 
index 1877329..31424b7 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)headers.c  6.11 (Berkeley) %G%";
+static char sccsid[] = "@(#)headers.c  6.12 (Berkeley) %G%";
 #endif /* not lint */
 
 # include <errno.h>
 #endif /* not lint */
 
 # include <errno.h>
@@ -839,7 +839,6 @@ commaize(h, p, fp, oldstyle, m, e)
                {
                        char *oldp;
                        char pvpbuf[PSBUFSIZE];
                {
                        char *oldp;
                        char pvpbuf[PSBUFSIZE];
-                       extern bool isatword();
                        extern char **prescan();
 
                        (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf);
                        extern char **prescan();
 
                        (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf);
@@ -850,7 +849,7 @@ commaize(h, p, fp, oldstyle, m, e)
                        while (*p != '\0' && isascii(*p) && isspace(*p))
                                p++;
 
                        while (*p != '\0' && isascii(*p) && isspace(*p))
                                p++;
 
-                       if (*p != '@' && !isatword(p))
+                       if (*p != '@')
                        {
                                p = oldp;
                                break;
                        {
                                p = oldp;
                                break;
@@ -913,27 +912,37 @@ commaize(h, p, fp, oldstyle, m, e)
        putline(obuf, fp, m);
 }
 \f/*
        putline(obuf, fp, m);
 }
 \f/*
-**  ISATWORD -- tell if the word we are pointing to is "at".
+**  COPYHEADER -- copy header list
+**
+**     This routine is the equivalent of newstr for header lists
 **
 **     Parameters:
 **
 **     Parameters:
-**             p -- word to check.
+**             header -- list of header structures to copy.
 **
 **     Returns:
 **
 **     Returns:
-**             TRUE -- if p is the word at.
-**             FALSE -- otherwise.
+**             a copy of 'header'.
 **
 **     Side Effects:
 **             none.
 */
 
 **
 **     Side Effects:
 **             none.
 */
 
-bool
-isatword(p)
-       register char *p;
+HDR *
+copyheader(header)
+       register HDR *header;
 {
 {
-       extern char lower();
+       register HDR *newhdr;
+       HDR *ret;
+       register HDR **tail = &ret;
 
 
-       if (lower(p[0]) == 'a' && lower(p[1]) == 't' &&
-           p[2] != '\0' && isascii(p[2]) && isspace(p[2]))
-               return (TRUE);
-       return (FALSE);
+       while (header != NULL)
+       {
+               newhdr = (HDR *) xalloc(sizeof(HDR));
+               STRUCTCOPY(*header, *newhdr);
+               *tail = newhdr;
+               tail = &newhdr->h_link;
+               header = header->h_link;
+       }
+       *tail = NULL;
+       
+       return ret;
 }
 }
index e2f3756..e399995 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sendmail.h  6.21 (Berkeley) %G%
+ *     @(#)sendmail.h  6.22 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,7 +15,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 6.21            %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 6.22            %G%";
 # endif lint
 # else /*  _DEFINE */
 # define EXTERN extern
 # endif lint
 # else /*  _DEFINE */
 # define EXTERN extern
index 0f96505..6711b3a 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)util.c     6.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)util.c     6.7 (Berkeley) %G%";
 #endif /* not lint */
 
 # include <stdio.h>
 #endif /* not lint */
 
 # include <stdio.h>
@@ -170,6 +170,45 @@ copyplist(list, copycont)
        return (newvp);
 }
 \f/*
        return (newvp);
 }
 \f/*
+**  COPYQUEUE -- copy address queue.
+**
+**     This routine is the equivalent of newstr for address queues
+**     addresses marked with QDONTSEND aren't copied
+**
+**     Parameters:
+**             addr -- list of address structures to copy.
+**
+**     Returns:
+**             a copy of 'addr'.
+**
+**     Side Effects:
+**             none.
+*/
+
+ADDRESS *
+copyqueue(addr)
+       ADDRESS *addr;
+{
+       register ADDRESS *newaddr;
+       ADDRESS *ret;
+       register ADDRESS **tail = &ret;
+
+       while (addr != NULL)
+       {
+               if (!bitset(QDONTSEND, addr->q_flags))
+               {
+                       newaddr = (ADDRESS *) xalloc(sizeof(ADDRESS));
+                       STRUCTCOPY(*addr, *newaddr);
+                       *tail = newaddr;
+                       tail = &newaddr->q_next;
+               }
+               addr = addr->q_next;
+       }
+       *tail = NULL;
+       
+       return ret;
+}
+\f/*
 **  PRINTAV -- print argument vector.
 **
 **     Parameters:
 **  PRINTAV -- print argument vector.
 **
 **     Parameters: