add auto-rebuild on alias database; fix some aliasing bugs;
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Tue, 8 Sep 1981 03:33:55 +0000 (19:33 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Tue, 8 Sep 1981 03:33:55 +0000 (19:33 -0800)
add statistics to rebuild; slight code restructuring; change
version handling one last (?) time

SCCS-vsn: usr.sbin/sendmail/src/alias.c 3.20
SCCS-vsn: usr.sbin/sendmail/src/collect.c 3.21
SCCS-vsn: usr.sbin/sendmail/src/version.c 3.23
SCCS-vsn: usr.sbin/sendmail/src/main.c 3.33
SCCS-vsn: usr.sbin/sendmail/src/recipient.c 3.11

usr/src/usr.sbin/sendmail/src/alias.c
usr/src/usr.sbin/sendmail/src/collect.c
usr/src/usr.sbin/sendmail/src/main.c
usr/src/usr.sbin/sendmail/src/recipient.c
usr/src/usr.sbin/sendmail/src/version.c

index d9311a9..bdc80ff 100644 (file)
@@ -4,9 +4,9 @@
 # include "sendmail.h"
 
 # ifdef DBM
 # include "sendmail.h"
 
 # ifdef DBM
-static char SccsId[] = "@(#)alias.c    3.19    %G%     (with DBM)";
+static char SccsId[] = "@(#)alias.c    3.20    %G%     (with DBM)";
 # else DBM
 # else DBM
-static char SccsId[] = "@(#)alias.c    3.19    %G%     (without DBM)";
+static char SccsId[] = "@(#)alias.c    3.20    %G%     (without DBM)";
 # endif DBM
 
 /*
 # endif DBM
 
 /*
@@ -140,11 +140,52 @@ initaliases(aliasfile, init)
        char *aliasfile;
        bool init;
 {
        char *aliasfile;
        bool init;
 {
+       char buf[MAXNAME];
+       struct stat stb;
+       time_t modtime;
+
+       /*
+       **  See if the DBM version of the file is out of date with
+       **  the text version.  If so, go into 'init' mode automatically.
+       **      This only happens if our effective userid owns the DBM
+       **      version or if the mode of the database is 777 -- this
+       **      is an attempt to avoid protection problems.  Note the
+       **      unpalatable hack to see if the stat succeeded.
+       */
+
+       if (stat(aliasfile, &stb) < 0)
+               return;
 # ifdef DBM
 # ifdef DBM
-       if (init)
+       modtime = stb.st_mtime;
+       (void) strcpy(buf, aliasfile);
+       (void) strcat(buf, ".pag");
+       stb.st_ino = 0;
+       if ((stat(buf, &stb) < 0 || stb.st_mtime < modtime) && !init)
        {
        {
-               char buf[MAXNAME];
+               if (stb.st_ino != 0 &&
+                   ((stb.st_mode & 0777) == 0777 || stb.st_uid == geteuid()))
+               {
+                       init = TRUE;
+                       if (Verbose)
+                               message(Arpa_Info, "rebuilding alias database");
+               }
+               else
+               {
+                       message(Arpa_Info, "Warning: alias database out of date");
+               }
+       }
+# endif DBM
 
 
+       /*
+       **  If initializing, create the new files.
+       **      We should lock the alias file here to prevent other
+       **      instantiations of sendmail from reading an incomplete
+       **      file -- or worse yet, doing a concurrent initialize.
+       */
+
+# ifdef DBM
+       if (init)
+       {
                (void) strcpy(buf, aliasfile);
                (void) strcat(buf, ".dir");
                if (close(creat(buf, DBMMODE)) < 0)
                (void) strcpy(buf, aliasfile);
                (void) strcat(buf, ".dir");
                if (close(creat(buf, DBMMODE)) < 0)
@@ -160,6 +201,12 @@ initaliases(aliasfile, init)
                        return;
                }
        }
                        return;
                }
        }
+
+       /*
+       **  Open and, if necessary, load the DBM file.
+       **      If running without DBM, load the symbol table.
+       */
+
        dbminit(aliasfile);
        if (init)
                readaliases(aliasfile, TRUE);
        dbminit(aliasfile);
        if (init)
                readaliases(aliasfile, TRUE);
@@ -199,6 +246,7 @@ readaliases(aliasfile, init)
        FILE *af;
        int lineno;
        register STAB *s;
        FILE *af;
        int lineno;
        register STAB *s;
+       int naliases, bytes, longest;
 
        if ((af = fopen(aliasfile, "r")) == NULL)
        {
 
        if ((af = fopen(aliasfile, "r")) == NULL)
        {
@@ -216,9 +264,12 @@ readaliases(aliasfile, init)
        */
 
        lineno = 0;
        */
 
        lineno = 0;
+       naliases = bytes = longest = 0;
        skipping = FALSE;
        while (fgets(line, sizeof (line), af) != NULL)
        {
        skipping = FALSE;
        while (fgets(line, sizeof (line), af) != NULL)
        {
+               int lhssize, rhssize;
+
                lineno++;
                switch (line[0])
                {
                lineno++;
                switch (line[0])
                {
@@ -283,6 +334,8 @@ readaliases(aliasfile, init)
                                                p++;
                                        c = *p;
                                        *p++ = '\0';
                                                p++;
                                        c = *p;
                                        *p++ = '\0';
+                                       if (c == '\n')
+                                               c = '\0';
                                        if (*p2 == '\0')
                                        {
                                                p[-1] = c;
                                        if (*p2 == '\0')
                                        {
                                                p[-1] = c;
@@ -320,14 +373,17 @@ readaliases(aliasfile, init)
                **  Insert alias into symbol table or DBM file
                */
 
                **  Insert alias into symbol table or DBM file
                */
 
+               lhssize = strlen(al.q_user) + 1;
+               rhssize = strlen(rhs) + 1;
+
 # ifdef DBM
                if (init)
                {
                        DATUM key, content;
 
 # ifdef DBM
                if (init)
                {
                        DATUM key, content;
 
-                       key.dsize = strlen(al.q_user) + 1;
+                       key.dsize = lhssize;
                        key.dptr = al.q_user;
                        key.dptr = al.q_user;
-                       content.dsize = strlen(rhs) + 1;
+                       content.dsize = rhssize;
                        content.dptr = rhs;
                        store(key, content);
                }
                        content.dptr = rhs;
                        store(key, content);
                }
@@ -337,8 +393,18 @@ readaliases(aliasfile, init)
                        s = stab(al.q_user, ST_ALIAS, ST_ENTER);
                        s->s_alias = newstr(rhs);
                }
                        s = stab(al.q_user, ST_ALIAS, ST_ENTER);
                        s->s_alias = newstr(rhs);
                }
+
+               /* statistics */
+               naliases++;
+               bytes += lhssize + rhssize;
+               if (rhssize > longest)
+                       longest = rhssize;
        }
        (void) fclose(af);
        }
        (void) fclose(af);
+       To = NULL;
+       if (Verbose)
+               message(Arpa_Info, "%d aliases, longest %d bytes, %d bytes total",
+                       naliases, longest, bytes);
 }
 \f/*
 **  FORWARD -- Try to forward mail
 }
 \f/*
 **  FORWARD -- Try to forward mail
index 144b8b2..553a14e 100644 (file)
@@ -1,7 +1,7 @@
 # include <errno.h>
 # include "sendmail.h"
 
 # include <errno.h>
 # include "sendmail.h"
 
-static char    SccsId[] = "@(#)collect.c       3.20    %G%";
+static char    SccsId[] = "@(#)collect.c       3.21    %G%";
 
 /*
 **  COLLECT -- read & parse message header & make temp file.
 
 /*
 **  COLLECT -- read & parse message header & make temp file.
@@ -59,6 +59,17 @@ maketemp(from)
                return;
        }
 
                return;
        }
 
+       /*
+       **  Tell ARPANET to go ahead.
+       */
+
+       if (ArpaMode == ARPA_MAIL)
+       {
+               extern char Arpa_Enter[];
+
+               message(Arpa_Enter, "Enter mail, end with \".\" on a line by itself");
+       }
+
        /*
        **  Try to read a UNIX-style From line
        */
        /*
        **  Try to read a UNIX-style From line
        */
@@ -66,7 +77,7 @@ maketemp(from)
        if (fgets(buf, sizeof buf, stdin) == NULL)
                return;
 # ifndef NOTUNIX
        if (fgets(buf, sizeof buf, stdin) == NULL)
                return;
 # ifndef NOTUNIX
-       if (strncmp(buf, "From ", 5) == 0)
+       if (!SaveFrom && strncmp(buf, "From ", 5) == 0)
        {
                eatfrom(buf);
                (void) fgets(buf, sizeof buf, stdin);
        {
                eatfrom(buf);
                (void) fgets(buf, sizeof buf, stdin);
index 7172bb7..81c397c 100644 (file)
@@ -5,7 +5,7 @@
 # include <syslog.h>
 # endif LOG
 
 # include <syslog.h>
 # endif LOG
 
-static char    SccsId[] = "@(#)main.c  3.32    %G%";
+static char    SccsId[] = "@(#)main.c  3.33    %G%";
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
@@ -148,7 +148,6 @@ main(argc, argv)
        extern char Version[];
        char *from;
        typedef int (*fnptr)();
        extern char Version[];
        char *from;
        typedef int (*fnptr)();
-       char nbuf[MAXLINE];             /* holds full name */
        struct passwd *pw;
        extern char *arpadate();
        extern char *AliasFile;         /* location of alias file */
        struct passwd *pw;
        extern char *arpadate();
        extern char *AliasFile;         /* location of alias file */
@@ -166,6 +165,7 @@ main(argc, argv)
        extern char *ttyname();
        bool canrename;
 
        extern char *ttyname();
        bool canrename;
 
+       argv[argc] = NULL;
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                (void) signal(SIGINT, finis);
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                (void) signal(SIGINT, finis);
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
@@ -354,6 +354,7 @@ main(argc, argv)
 # ifdef DBM
                  case 'I':     /* initialize alias DBM file */
                        aliasinit = TRUE;
 # ifdef DBM
                  case 'I':     /* initialize alias DBM file */
                        aliasinit = TRUE;
+                       Verbose = TRUE;
                        break;
 # endif DBM
 
                        break;
 # endif DBM
 
@@ -482,6 +483,7 @@ main(argc, argv)
            pw != NULL && pw->pw_gecos != NULL)
        {
                register char *nb;
            pw != NULL && pw->pw_gecos != NULL)
        {
                register char *nb;
+               char nbuf[MAXNAME];
 
                nb = nbuf;
                p = pw->pw_gecos;
 
                nb = nbuf;
                p = pw->pw_gecos;
@@ -500,7 +502,7 @@ main(argc, argv)
                }
                *nb = '\0';
                if (ArpaMode == ARPA_NONE && from == NULL && nbuf[0] != '\0')
                }
                *nb = '\0';
                if (ArpaMode == ARPA_NONE && from == NULL && nbuf[0] != '\0')
-                       fullname = nbuf;
+                       fullname = newstr(nbuf);
        }
        if (fullname != NULL && fullname[0] != '\0')
                define('x', fullname);
        }
        if (fullname != NULL && fullname[0] != '\0')
                define('x', fullname);
@@ -522,69 +524,30 @@ main(argc, argv)
                syserr("Infinite forwarding loop (%s->%s)", From.q_paddr, *argv);
 
        /*
                syserr("Infinite forwarding loop (%s->%s)", From.q_paddr, *argv);
 
        /*
-       ** Scan argv and deliver the message to everyone.
+       **  Scan argv and deliver the message to everyone.
+       **      Actually, suppress delivery if we are taking To:
+       **      lines from the message.
        */
 
        if (GrabTo)
                DontSend = TRUE;
        */
 
        if (GrabTo)
                DontSend = TRUE;
-       for (; argc-- > 0; argv++)
-       {
-               p = argv[1];
-               if (argc >= 2 && p[2] == '\0' &&
-                   (p[0] == 'a' || p[0] == 'A') &&
-                   (p[1] == 't' || p[1] == 'T'))
-               {
-                       if (strlen(argv[0]) + strlen(argv[2]) + 2 > sizeof nbuf)
-                       {
-                               usrerr("address overflow");
-                               p = argv[0];
-                       }
-                       else
-                       {
-                               (void) strcpy(nbuf, argv[0]);
-                               (void) strcat(nbuf, "@");
-                               (void) strcat(nbuf, argv[2]);
-                               p = newstr(nbuf);
-                               argv += 2;
-                               argc -= 2;
-                       }
-               }
-               else
-                       p = argv[0];
-               sendto(p, 0);
-       }
+       sendtoargv(argv);
 
        /* if we have had errors sofar, drop out now */
        if (Errors > 0 && ExitStat == EX_OK)
                ExitStat = EX_USAGE;
 
        /* if we have had errors sofar, drop out now */
        if (Errors > 0 && ExitStat == EX_OK)
                ExitStat = EX_USAGE;
-       if ((ArpaMode > ARPA_OLD && ExitStat != EX_OK) ||
-           (verifyonly && !GrabTo))
+       if (ArpaMode > ARPA_OLD && ExitStat != EX_OK)
                finis();
 
                finis();
 
-       /* no errors, tell arpanet to go ahead */
-       To = NULL;
-       if (ArpaMode == ARPA_MAIL)
-       {
-               extern char Arpa_Enter[];
-
-               message(Arpa_Enter, "Enter mail, end with \".\" on a line by itself");
-       }
-       errno = 0;
-
        /*
        **  Read the input mail.
        */
 
        DontSend = FALSE;
        /*
        **  Read the input mail.
        */
 
        DontSend = FALSE;
-       collect();
-
-# ifdef DEBUG
-       if (Debug)
-               printf("From person = \"%s\"\n", From.q_paddr);
-# endif DEBUG
-
-       if (verifyonly && GrabTo)
-               finis();
+       To = NULL;
+       errno = 0;
+       if (!verifyonly || GrabTo)
+               collect();
 
        /* collect statistics */
        Stat.stat_nf[From.q_mailer]++;
 
        /* collect statistics */
        Stat.stat_nf[From.q_mailer]++;
@@ -595,6 +558,11 @@ main(argc, argv)
        **  will not be expanded (unless explicitly requested).
        */
 
        **  will not be expanded (unless explicitly requested).
        */
 
+# ifdef DEBUG
+       if (Debug)
+               printf("From person = \"%s\"\n", From.q_paddr);
+# endif DEBUG
+
        From.q_flags |= QDONTSEND;
        if (!MeToo)
                recipient(&From);
        From.q_flags |= QDONTSEND;
        if (!MeToo)
                recipient(&From);
@@ -602,6 +570,7 @@ main(argc, argv)
 
        /*
        **  Actually send everything.
 
        /*
        **  Actually send everything.
+       **      If verifying, just ack.
        */
 
        for (i = 0; Mailer[i] != NULL; i++)
        */
 
        for (i = 0; Mailer[i] != NULL; i++)
@@ -610,7 +579,19 @@ main(argc, argv)
 
                for (q = Mailer[i]->m_sendq; q != NULL; q = q->q_next)
                {
 
                for (q = Mailer[i]->m_sendq; q != NULL; q = q->q_next)
                {
-                       (void) deliver(q, (fnptr) NULL);
+                       if (verifyonly)
+                       {
+                               To = q->q_paddr;
+                               if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
+                               {
+                                       if (q->q_mailer == MN_LOCAL || q->q_mailer == MN_PROG)
+                                               message(Arpa_Info, "deliverable");
+                                       else
+                                               message(Arpa_Info, "queueable");
+                               }
+                       }
+                       else
+                               (void) deliver(q, (fnptr) NULL);
                }
        }
 
                }
        }
 
@@ -635,7 +616,8 @@ main(argc, argv)
                        break;
                }
        }
                        break;
                }
        }
-       poststats(StatFile);
+       if (!verifyonly)
+               poststats(StatFile);
        finis();
 }
 \f/*
        finis();
 }
 \f/*
index 540b5a8..c66db81 100644 (file)
@@ -1,7 +1,7 @@
 # include <pwd.h>
 # include "sendmail.h"
 
 # include <pwd.h>
 # include "sendmail.h"
 
-static char SccsId[] = "@(#)recipient.c        3.10    %G%";
+static char SccsId[] = "@(#)recipient.c        3.11    %G%";
 
 /*
 **  SENDTO -- Designate a send list.
 
 /*
 **  SENDTO -- Designate a send list.
@@ -28,8 +28,15 @@ sendto(list, copyf)
 {
        register char *p;
        bool more;              /* set if more addresses to send to */
 {
        register char *p;
        bool more;              /* set if more addresses to send to */
+       ADDRESS *al;            /* list of addresses to send to */
+
+# ifdef DEBUG
+       if (Debug > 1)
+               printf("sendto: %s\n", list);
+# endif DEBUG
 
        more = TRUE;
 
        more = TRUE;
+       al = NULL;
        for (p = list; more; )
        {
                register char *q;
        for (p = list; more; )
        {
                register char *q;
@@ -46,14 +53,27 @@ sendto(list, copyf)
                *--p = '\0';
                if (more)
                        p++;
                *--p = '\0';
                if (more)
                        p++;
+               if (*q == '\0')
+                       continue;
 
                /* parse the address */
                if ((a = parse(q, (ADDRESS *) NULL, copyf)) == NULL)
                        continue;
 
 
                /* parse the address */
                if ((a = parse(q, (ADDRESS *) NULL, copyf)) == NULL)
                        continue;
 
-               /* arrange to send to this person */
+               /* put it on the local send list */
+               a->q_next = al;
+               al = a;
+       }
+
+       /* arrange to send to everyone on the local send list */
+       while (al != NULL)
+       {
+               register ADDRESS *a = al;
+
+               al = a->q_next;
                recipient(a);
        }
                recipient(a);
        }
+
        To = NULL;
 }
 \f/*
        To = NULL;
 }
 \f/*
@@ -129,7 +149,7 @@ recipient(a)
                                printf("(%s in sendq)\n", a->q_paddr);
 # endif DEBUG
                        if (Verbose && !bitset(QDONTSEND, a->q_flags))
                                printf("(%s in sendq)\n", a->q_paddr);
 # endif DEBUG
                        if (Verbose && !bitset(QDONTSEND, a->q_flags))
-                               message(Arpa_Info, "duplicate supressed");
+                               message(Arpa_Info, "duplicate suppressed");
                        return;
                }
        }
                        return;
                }
        }
@@ -254,3 +274,43 @@ include(fname, msg)
 
        (void) fclose(fp);
 }
 
        (void) fclose(fp);
 }
+\f/*
+**  SENDTOARGV -- send to an argument vector.
+**
+**     Parameters:
+**             argv -- argument vector to send to.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             puts all addresses on the argument vector onto the
+**                     send queue.
+*/
+
+sendtoargv(argv)
+       register char **argv;
+{
+       register char *p;
+       extern bool sameword();
+
+       while ((p = *argv++) != NULL)
+       {
+               if (argv[0] != NULL && argv[1] != NULL && sameword(argv[0], "at"))
+               {
+                       char nbuf[MAXNAME];
+
+                       if (strlen(p) + strlen(argv[1]) + 2 > sizeof nbuf)
+                               usrerr("address overflow");
+                       else
+                       {
+                               (void) strcpy(nbuf, p);
+                               (void) strcat(nbuf, "@");
+                               (void) strcat(nbuf, argv[1]);
+                               p = newstr(nbuf);
+                               argv += 2;
+                       }
+               }
+               sendto(p, 0);
+       }
+}
index c189a6b..e6879ec 100644 (file)
@@ -1,3 +1,3 @@
-static char    SccsId[] = "@(#)SendMail version 3.22 of %G%";
+static char    SccsId[] = "@(#)SendMail version 3.23 of %G%";
 
 
-char   Version[] = "3.22 [%G%]";
+char   Version[] = "3.23 [%G%]";