fix the System 5 compatilibility to be compatible with the rest
[unix-history] / usr / src / usr.sbin / sendmail / src / main.c
index ca4325d..9ec75bf 100644 (file)
@@ -13,19 +13,21 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.58 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     6.13 (Berkeley) %G%";
 #endif /* not lint */
 
 #define        _DEFINE
 
 #endif /* not lint */
 
 #define        _DEFINE
 
-#include <sys/param.h>
-#include <sys/file.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 #include <signal.h>
 #include <sgtty.h>
 #include "sendmail.h"
 #include <sys/stat.h>
 #include <signal.h>
 #include <sgtty.h>
 #include "sendmail.h"
+#ifdef NAMED_BIND
 #include <arpa/nameser.h>
 #include <resolv.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
+#endif
 
 # ifdef lint
 char   edata, end;
 
 # ifdef lint
 char   edata, end;
@@ -70,6 +72,8 @@ ENVELOPE      BlankEnvelope;  /* a "blank" envelope */
 ENVELOPE       MainEnvelope;   /* the envelope around the basic letter */
 ADDRESS                NullAddress =   /* a null address */
                { "", "", NULL, "" };
 ENVELOPE       MainEnvelope;   /* the envelope around the basic letter */
 ADDRESS                NullAddress =   /* a null address */
                { "", "", NULL, "" };
+char           *UserEnviron[MAXUSERENVIRON + 1];
+                               /* saved user environment */
 
 /*
 **  Pointers for setproctitle.
 
 /*
 **  Pointers for setproctitle.
@@ -81,7 +85,7 @@ ADDRESS               NullAddress =   /* a null address */
 # ifdef SETPROCTITLE
 char           **Argv = NULL;          /* pointer to argument vector */
 char           *LastArgv = NULL;       /* end of argv */
 # ifdef SETPROCTITLE
 char           **Argv = NULL;          /* pointer to argument vector */
 char           *LastArgv = NULL;       /* end of argv */
-# endif SETPROCTITLE
+# endif /* SETPROCTITLE */
 
 /*
 **  The file in which to log raw recipient information.
 
 /*
 **  The file in which to log raw recipient information.
@@ -96,11 +100,13 @@ char               *LastArgv = NULL;       /* end of argv */
 
 char           *RcptLogFile = NULL;    /* file name */
 
 
 char           *RcptLogFile = NULL;    /* file name */
 
+static void    obsolete();
+
 #ifdef DAEMON
 #ifndef SMTP
 ERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR
 #ifdef DAEMON
 #ifndef SMTP
 ERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR
-#endif SMTP
-#endif DAEMON
+#endif /* SMTP */
+#endif /* DAEMON */
 
 #define MAXCONFIGLEVEL 3       /* highest config version level known */
 
 
 #define MAXCONFIGLEVEL 3       /* highest config version level known */
 
@@ -110,11 +116,12 @@ main(argc, argv, envp)
        char **envp;
 {
        register char *p;
        char **envp;
 {
        register char *p;
+       register char *q;
        char **av;
        char *locname;
        extern int finis();
        extern char Version[];
        char **av;
        char *locname;
        extern int finis();
        extern char Version[];
-       char *from;
+       char *ep, *from;
        typedef int (*fnptr)();
        STAB *st;
        register int i;
        typedef int (*fnptr)();
        STAB *st;
        register int i;
@@ -124,8 +131,10 @@ main(argc, argv, envp)
        bool nothaw;
        bool safecf = TRUE;
        static bool reenter = FALSE;
        bool nothaw;
        bool safecf = TRUE;
        static bool reenter = FALSE;
-       char jbuf[60];                  /* holds MyHostName */
+       char *argv0 = argv[0];
+       char jbuf[MAXHOSTNAMELEN];      /* holds MyHostName */
        extern int DtableSize;
        extern int DtableSize;
+       extern int optind;
        extern bool safefile();
        extern time_t convtime();
        extern putheader(), putbody();
        extern bool safefile();
        extern time_t convtime();
        extern putheader(), putbody();
@@ -133,6 +142,7 @@ main(argc, argv, envp)
        extern void intsig();
        extern char **myhostname();
        extern char *arpadate();
        extern void intsig();
        extern char **myhostname();
        extern char *arpadate();
+       extern char *optarg;
        extern char **environ;
 
        /*
        extern char **environ;
 
        /*
@@ -170,8 +180,11 @@ main(argc, argv, envp)
                i = dup(i);
 
        i = DtableSize;
                i = dup(i);
 
        i = DtableSize;
-       while (--i > 2)
-               (void) close(i);
+       while (--i > 0)
+       {
+               if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
+                       (void) close(i);
+       }
        errno = 0;
 
 #ifdef LOG_MAIL
        errno = 0;
 
 #ifdef LOG_MAIL
@@ -195,6 +208,9 @@ main(argc, argv, envp)
        STRUCTCOPY(BlankEnvelope, MainEnvelope);
        CurEnv = &MainEnvelope;
 
        STRUCTCOPY(BlankEnvelope, MainEnvelope);
        CurEnv = &MainEnvelope;
 
+       /* Handle any non-getoptable constructions. */
+       obsolete(argv);
+
        /*
        **  Do a quick prescan of the argument list.
        **      We do this to find out if we can potentially thaw the
        /*
        **  Do a quick prescan of the argument list.
        **      We do this to find out if we can potentially thaw the
@@ -202,30 +218,31 @@ main(argc, argv, envp)
        **      the argument processing applies to this run rather than
        **      to the run that froze the configuration.
        */
        **      the argument processing applies to this run rather than
        **      to the run that froze the configuration.
        */
-
-       argv[argc] = NULL;
-       av = argv;
        nothaw = FALSE;
        nothaw = FALSE;
-       while ((p = *++av) != NULL)
+#define OPTIONS                "b:C:cd:e:F:f:h:Iimno:p:q:R:r:sTtv"
+       while ((j = getopt(argc, argv, OPTIONS)) != EOF)
        {
        {
-               if (strncmp(p, "-C", 2) == 0)
+               switch (j)
                {
                {
-                       ConfFile = &p[2];
-                       if (ConfFile[0] == '\0')
-                               ConfFile = "sendmail.cf";
+                 case 'b':
+                       if (optarg[0] == 'z' && optarg[1] == '\0')
+                               nothaw = TRUE;
+                       break;
+
+                 case 'C':
+                       ConfFile = optarg;
                        (void) setgid(getrgid());
                        (void) setuid(getruid());
                        safecf = FALSE;
                        nothaw = TRUE;
                        (void) setgid(getrgid());
                        (void) setuid(getruid());
                        safecf = FALSE;
                        nothaw = TRUE;
-               }
-               else if (strncmp(p, "-bz", 3) == 0)
-                       nothaw = TRUE;
-               else if (strncmp(p, "-d", 2) == 0)
-               {
+                       break;
+
+                 case 'd':
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
-                       tTflag(&p[2]);
+                       tTflag(optarg);
                        setbuf(stdout, (char *) NULL);
                        printf("Version %s\n", Version);
                        setbuf(stdout, (char *) NULL);
                        printf("Version %s\n", Version);
+                       break;
                }
        }
 
                }
        }
 
@@ -233,13 +250,16 @@ main(argc, argv, envp)
        OutChannel = stdout;
 
        if (!nothaw)
        OutChannel = stdout;
 
        if (!nothaw)
-               readconfig = !thaw(FreezeFile);
+               readconfig = !thaw(FreezeFile, argv0);
 
 
-       /* reset the environment after the thaw */
-       i = j = 0;
-       while (j < MAXUSERENVIRON && (p = envp[i++]) != NULL)
+# ifdef SETPROCTITLE
+       /*
+       **  Move the environment so setproctitle can use the space at
+       **  the top of memory.
+       */
+
+       for (i = j = 0; j < MAXUSERENVIRON && (p = envp[i]) != NULL; i++)
        {
        {
-               /* strip out "dangerous" envariables */
                if (strncmp(p, "FS=", 3) == 0 || strncmp(p, "LD_", 3) == 0)
                        continue;
                UserEnviron[j++] = newstr(p);
                if (strncmp(p, "FS=", 3) == 0 || strncmp(p, "LD_", 3) == 0)
                        continue;
                UserEnviron[j++] = newstr(p);
@@ -247,17 +267,16 @@ main(argc, argv, envp)
        UserEnviron[j] = NULL;
        environ = UserEnviron;
 
        UserEnviron[j] = NULL;
        environ = UserEnviron;
 
-# ifdef SETPROCTITLE
        /*
        **  Save start and extent of argv for setproctitle.
        */
 
        Argv = argv;
        /*
        **  Save start and extent of argv for setproctitle.
        */
 
        Argv = argv;
-       if (--i > 0)
+       if (i > 0)
                LastArgv = envp[i - 1] + strlen(envp[i - 1]);
        else
                LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
                LastArgv = envp[i - 1] + strlen(envp[i - 1]);
        else
                LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
-# endif SETPROCTITLE
+# endif /* SETPROCTITLE */
 
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                (void) signal(SIGINT, intsig);
 
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                (void) signal(SIGINT, intsig);
@@ -282,7 +301,7 @@ main(argc, argv, envp)
                av = myhostname(jbuf, sizeof jbuf);
                if (jbuf[0] != '\0')
                {
                av = myhostname(jbuf, sizeof jbuf);
                if (jbuf[0] != '\0')
                {
-                       register char *q;
+                       struct  utsname utsname;
                        extern char *strchr();
 
                        if (tTd(0, 4))
                        extern char *strchr();
 
                        if (tTd(0, 4))
@@ -298,6 +317,19 @@ main(argc, argv, envp)
                                define('m', q, CurEnv);
                        }
                        setclass('w', p);
                                define('m', q, CurEnv);
                        }
                        setclass('w', p);
+
+                       if (uname(&utsname) >= 0)
+                               p = utsname.nodename;
+                       else
+                       {
+                               makelower(jbuf);
+                               p = jbuf;
+                       }
+                       if (tTd(0, 4))
+                               printf("UUCP nodename: %s\n", p);
+                       p = newstr(p);
+                       define('k', p, CurEnv);
+                       setclass('w', p);
                }
                while (av != NULL && *av != NULL)
                {
                }
                while (av != NULL && *av != NULL)
                {
@@ -318,7 +350,7 @@ main(argc, argv, envp)
        */
 
        av = argv;
        */
 
        av = argv;
-       p = rindex(*av, '/');
+       p = strrchr(*av, '/');
        if (p++ == NULL)
                p = *av;
        if (strcmp(p, "newaliases") == 0)
        if (p++ == NULL)
                p = *av;
        if (strcmp(p, "newaliases") == 0)
@@ -327,12 +359,14 @@ main(argc, argv, envp)
                OpMode = MD_PRINT;
        else if (strcmp(p, "smtpd") == 0)
                OpMode = MD_DAEMON;
                OpMode = MD_PRINT;
        else if (strcmp(p, "smtpd") == 0)
                OpMode = MD_DAEMON;
-       while ((p = *++av) != NULL && p[0] == '-')
+
+       optind = 1;
+       while ((j = getopt(argc, argv, OPTIONS)) != EOF)
        {
        {
-               switch (p[1])
+               switch (j)
                {
                  case 'b':     /* operations mode */
                {
                  case 'b':     /* operations mode */
-                       switch (p[2])
+                       switch (j = *optarg)
                        {
                          case MD_DAEMON:
 # ifdef DAEMON
                        {
                          case MD_DAEMON:
 # ifdef DAEMON
@@ -345,24 +379,24 @@ main(argc, argv, envp)
                                usrerr("Daemon mode not implemented");
                                ExitStat = EX_USAGE;
                                break;
                                usrerr("Daemon mode not implemented");
                                ExitStat = EX_USAGE;
                                break;
-# endif DAEMON
+# endif /* DAEMON */
                          case MD_SMTP:
 # ifndef SMTP
                                usrerr("I don't speak SMTP");
                                ExitStat = EX_USAGE;
                                break;
                          case MD_SMTP:
 # ifndef SMTP
                                usrerr("I don't speak SMTP");
                                ExitStat = EX_USAGE;
                                break;
-# endif SMTP
+# endif /* SMTP */
                          case MD_DELIVER:
                          case MD_VERIFY:
                          case MD_TEST:
                          case MD_INITALIAS:
                          case MD_PRINT:
                          case MD_FREEZE:
                          case MD_DELIVER:
                          case MD_VERIFY:
                          case MD_TEST:
                          case MD_INITALIAS:
                          case MD_PRINT:
                          case MD_FREEZE:
-                               OpMode = p[2];
+                               OpMode = j;
                                break;
 
                          default:
                                break;
 
                          default:
-                               usrerr("Invalid operation mode %c", p[2]);
+                               usrerr("Invalid operation mode %c", j);
                                ExitStat = EX_USAGE;
                                break;
                        }
                                ExitStat = EX_USAGE;
                                break;
                        }
@@ -373,55 +407,33 @@ main(argc, argv, envp)
 
                  case 'd':     /* debugging -- redo in case frozen */
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
 
                  case 'd':     /* debugging -- redo in case frozen */
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
-                       tTflag(&p[2]);
+                       tTflag(optarg);
                        setbuf(stdout, (char *) NULL);
                        break;
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
                        setbuf(stdout, (char *) NULL);
                        break;
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
-                       p += 2;
-                       if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
-                       {
-                               p = *++av;
-                               if (p == NULL || *p == '-')
-                               {
-                                       usrerr("No \"from\" person");
-                                       ExitStat = EX_USAGE;
-                                       av--;
-                                       break;
-                               }
-                       }
                        if (from != NULL)
                        {
                                usrerr("More than one \"from\" person");
                                ExitStat = EX_USAGE;
                                break;
                        }
                        if (from != NULL)
                        {
                                usrerr("More than one \"from\" person");
                                ExitStat = EX_USAGE;
                                break;
                        }
-                       from = newstr(p);
+                       from = newstr(optarg);
                        break;
 
                  case 'F':     /* set full name */
                        break;
 
                  case 'F':     /* set full name */
-                       p += 2;
-                       if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
-                       {
-                               usrerr("Bad -F flag");
-                               ExitStat = EX_USAGE;
-                               av--;
-                               break;
-                       }
-                       FullName = newstr(p);
+                       FullName = newstr(optarg);
                        break;
 
                  case 'h':     /* hop count */
                        break;
 
                  case 'h':     /* hop count */
-                       p += 2;
-                       if (*p == '\0' && ((p = *++av) == NULL || !isdigit(*p)))
+                       CurEnv->e_hopcount = strtol(optarg, &ep, 10);
+                       if (*ep)
                        {
                        {
-                               usrerr("Bad hop count (%s)", p);
+                               usrerr("Bad hop count (%s)", optarg);
                                ExitStat = EX_USAGE;
                                ExitStat = EX_USAGE;
-                               av--;
                                break;
                        }
                                break;
                        }
-                       CurEnv->e_hopcount = atoi(p);
                        break;
                
                  case 'n':     /* don't alias */
                        break;
                
                  case 'n':     /* don't alias */
@@ -429,7 +441,17 @@ main(argc, argv, envp)
                        break;
 
                  case 'o':     /* set option */
                        break;
 
                  case 'o':     /* set option */
-                       setoption(p[2], &p[3], FALSE, TRUE);
+                       setoption(*optarg, optarg + 1, FALSE, TRUE);
+                       break;
+
+                 case 'p':     /* set protocol */
+                       q = strchr(optarg, ':');
+                       if (q != NULL)
+                               *q++ = '\0';
+                       if (*optarg != '\0')
+                               define('r', newstr(optarg), CurEnv);
+                       if (*q != '\0')
+                               define('s', newstr(q), CurEnv);
                        break;
 
                  case 'q':     /* run queue files at intervals */
                        break;
 
                  case 'q':     /* run queue files at intervals */
@@ -451,11 +473,11 @@ main(argc, argv, envp)
                        (void) unsetenv("HOSTALIASES");
                        FullName = NULL;
                        queuemode = TRUE;
                        (void) unsetenv("HOSTALIASES");
                        FullName = NULL;
                        queuemode = TRUE;
-                       QueueIntvl = convtime(&p[2]);
-# else QUEUE
+                       QueueIntvl = convtime(optarg);
+# else /* QUEUE */
                        usrerr("I don't know about queues");
                        ExitStat = EX_USAGE;
                        usrerr("I don't know about queues");
                        ExitStat = EX_USAGE;
-# endif QUEUE
+# endif /* QUEUE */
                        break;
 
                  case 't':     /* read recipients from message */
                        break;
 
                  case 't':     /* read recipients from message */
@@ -464,16 +486,19 @@ main(argc, argv, envp)
 
                        /* compatibility flags */
                  case 'c':     /* connect to non-local mailers */
 
                        /* compatibility flags */
                  case 'c':     /* connect to non-local mailers */
-                 case 'e':     /* error message disposition */
                  case 'i':     /* don't let dot stop me */
                  case 'm':     /* send to me too */
                  case 'T':     /* set timeout interval */
                  case 'v':     /* give blow-by-blow description */
                  case 'i':     /* don't let dot stop me */
                  case 'm':     /* send to me too */
                  case 'T':     /* set timeout interval */
                  case 'v':     /* give blow-by-blow description */
-                       setoption(p[1], &p[2], FALSE, TRUE);
+                       setoption(j, "T", FALSE, TRUE);
+                       break;
+
+                 case 'e':     /* error message disposition */
+                       setoption(j, optarg, FALSE, TRUE);
                        break;
 
                  case 's':     /* save From lines in headers */
                        break;
 
                  case 's':     /* save From lines in headers */
-                       setoption('f', &p[2], FALSE, TRUE);
+                       setoption('f', "T", FALSE, TRUE);
                        break;
 
 # ifdef DBM
                        break;
 
 # ifdef DBM
@@ -483,18 +508,16 @@ main(argc, argv, envp)
 # endif /* DBM */
 
                  case 'R':     /* log raw recipient info */
 # endif /* DBM */
 
                  case 'R':     /* log raw recipient info */
-                       p += 2;
-                       if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
-                       {
-                               usrerr("Bad -R flag");
-                               ExitStat = EX_USAGE;
-                               av--;
-                               break;
-                       }
-                       RcptLogFile = newstr(p);
+                       RcptLogFile = newstr(optarg);
+                       break;
+
+                 default:
+                       ExitStat = EX_USAGE;
+                       finis();
                        break;
                }
        }
                        break;
                }
        }
+       av += optind;
 
 #ifdef NAMED_BIND
        if (tTd(8, 1))
 
 #ifdef NAMED_BIND
        if (tTd(8, 1))
@@ -563,18 +586,32 @@ main(argc, argv, envp)
        expand("\001j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
        MyHostName = jbuf;
 
        expand("\001j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
        MyHostName = jbuf;
 
-       /* the indices of local and program mailers */
+       /* the indices of built-in mailers */
        st = stab("local", ST_MAILER, ST_FIND);
        if (st == NULL)
                syserr("No local mailer defined");
        else
                LocalMailer = st->s_mailer;
        st = stab("local", ST_MAILER, ST_FIND);
        if (st == NULL)
                syserr("No local mailer defined");
        else
                LocalMailer = st->s_mailer;
+
        st = stab("prog", ST_MAILER, ST_FIND);
        if (st == NULL)
                syserr("No prog mailer defined");
        else
                ProgMailer = st->s_mailer;
 
        st = stab("prog", ST_MAILER, ST_FIND);
        if (st == NULL)
                syserr("No prog mailer defined");
        else
                ProgMailer = st->s_mailer;
 
+       st = stab("*file*", ST_MAILER, ST_FIND);
+       if (st == NULL)
+               syserr("No *file* mailer defined");
+       else
+               FileMailer = st->s_mailer;
+
+       st = stab("*include*", ST_MAILER, ST_FIND);
+       if (st == NULL)
+               syserr("No *include* mailer defined");
+       else
+               InclMailer = st->s_mailer;
+
+
        /* operate in queue directory */
        if (chdir(QueueDir) < 0)
        {
        /* operate in queue directory */
        if (chdir(QueueDir) < 0)
        {
@@ -594,10 +631,10 @@ main(argc, argv, envp)
                dropenvelope(CurEnv);
                printqueue();
                exit(EX_OK);
                dropenvelope(CurEnv);
                printqueue();
                exit(EX_OK);
-#else QUEUE
+#else /* QUEUE */
                usrerr("No queue to print");
                finis();
                usrerr("No queue to print");
                finis();
-#endif QUEUE
+#endif /* QUEUE */
 
          case MD_INITALIAS:
                /* initialize alias database */
 
          case MD_INITALIAS:
                /* initialize alias database */
@@ -675,6 +712,7 @@ main(argc, argv, envp)
                        register char **pvp;
                        char *q;
                        extern char *DelimChar;
                        register char **pvp;
                        char *q;
                        extern char *DelimChar;
+                       extern bool invalidaddr();
 
                        if (terminal)
                                printf("> ");
 
                        if (terminal)
                                printf("> ");
@@ -691,8 +729,13 @@ main(argc, argv, envp)
                        while (*p != '\0' && !isspace(*p))
                                p++;
                        if (*p == '\0')
                        while (*p != '\0' && !isspace(*p))
                                p++;
                        if (*p == '\0')
+                       {
+                               printf("No address!\n");
                                continue;
                                continue;
+                       }
                        *p = '\0';
                        *p = '\0';
+                       if (invalidaddr(p + 1))
+                               continue;
                        do
                        {
                                extern char **prescan();
                        do
                        {
                                extern char **prescan();
@@ -722,7 +765,7 @@ main(argc, argv, envp)
                runqueue(FALSE);
                finis();
        }
                runqueue(FALSE);
                finis();
        }
-# endif QUEUE
+# endif /* QUEUE */
 
        /*
        **  If a daemon, wait for a request.
 
        /*
        **  If a daemon, wait for a request.
@@ -759,7 +802,7 @@ main(argc, argv, envp)
                                for (;;)
                                        pause();
                }
                                for (;;)
                                        pause();
                }
-# endif QUEUE
+# endif /* QUEUE */
                dropenvelope(CurEnv);
 
 #ifdef DAEMON
                dropenvelope(CurEnv);
 
 #ifdef DAEMON
@@ -769,7 +812,7 @@ main(argc, argv, envp)
                OpMode = MD_SMTP;
                (void) newenvelope(CurEnv);
                openxscript(CurEnv);
                OpMode = MD_SMTP;
                (void) newenvelope(CurEnv);
                openxscript(CurEnv);
-#endif DAEMON
+#endif /* DAEMON */
        }
        
 # ifdef SMTP
        }
        
 # ifdef SMTP
@@ -780,7 +823,7 @@ main(argc, argv, envp)
 
        if (OpMode == MD_SMTP)
                smtp(CurEnv);
 
        if (OpMode == MD_SMTP)
                smtp(CurEnv);
-# endif SMTP
+# endif /* SMTP */
 
        /*
        **  Do basic system initialization and set the sender
 
        /*
        **  Do basic system initialization and set the sender
@@ -833,6 +876,11 @@ main(argc, argv, envp)
        */
 
        CurEnv->e_from.q_flags |= QDONTSEND;
        */
 
        CurEnv->e_from.q_flags |= QDONTSEND;
+       if (tTd(1, 5))
+       {
+               printf("main: QDONTSEND ");
+               printaddr(&CurEnv->e_from, FALSE);
+       }
        CurEnv->e_to = NULL;
        sendall(CurEnv, SM_DEFAULT);
 
        CurEnv->e_to = NULL;
        sendall(CurEnv, SM_DEFAULT);
 
@@ -874,7 +922,7 @@ finis()
 # ifdef LOG
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "finis, pid=%d", getpid());
 # ifdef LOG
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "finis, pid=%d", getpid());
-# endif LOG
+# endif /* LOG */
        if (ExitStat == EX_TEMPFAIL)
                ExitStat = EX_OK;
        exit(ExitStat);
        if (ExitStat == EX_TEMPFAIL)
                ExitStat = EX_OK;
        exit(ExitStat);
@@ -1031,6 +1079,7 @@ freeze(freezefile)
 **
 **     Parameters:
 **             freezefile -- the name of the file to thaw from.
 **
 **     Parameters:
 **             freezefile -- the name of the file to thaw from.
+**             binfile -- the name of the sendmail binary (ok to guess).
 **
 **     Returns:
 **             TRUE if it successfully read the freeze file.
 **
 **     Returns:
 **             TRUE if it successfully read the freeze file.
@@ -1040,13 +1089,15 @@ freeze(freezefile)
 **             reads freezefile in to BSS area.
 */
 
 **             reads freezefile in to BSS area.
 */
 
-thaw(freezefile)
+thaw(freezefile, binfile)
        char *freezefile;
        char *freezefile;
+       char *binfile;
 {
        int f;
        register char *p;
        union frz fhdr;
        char hbuf[60];
 {
        int f;
        register char *p;
        union frz fhdr;
        char hbuf[60];
+       struct stat fst, sst;
        extern char edata, end;
        extern char Version[];
        extern caddr_t brk();
        extern char edata, end;
        extern char Version[];
        extern caddr_t brk();
@@ -1064,6 +1115,22 @@ thaw(freezefile)
                return (FALSE);
        }
 
                return (FALSE);
        }
 
+       if (fstat(f, &fst) < 0 || stat(ConfFile, &sst) < 0 ||
+           fst.st_mtime < sst.st_mtime)
+       {
+               syslog(LOG_WARNING, "Freeze file older than config file");
+               (void) close(f);
+               return (FALSE);
+       }
+
+       if (strchr(binfile, '/') != NULL && stat(binfile, &sst) == 0 &&
+           fst.st_mtime < sst.st_mtime)
+       {
+               syslog(LOG_WARNING, "Freeze file older than binary file");
+               (void) close(f);
+               return (FALSE);
+       }
+
        /* read in the header */
        if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr)
        {
        /* read in the header */
        if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr)
        {
@@ -1178,9 +1245,11 @@ disconnect(fulldrop)
        /* drop our controlling TTY completely if possible */
        if (fulldrop)
        {
        /* drop our controlling TTY completely if possible */
        if (fulldrop)
        {
-#if BSD > 43
-               daemon(1, 1);
+#ifdef SYSTEM5
+               (void) setpgrp();
 #else
 #else
+               (void) setsid();
+#endif
 #ifdef TIOCNOTTY
                fd = open("/dev/tty", 2);
                if (fd >= 0)
 #ifdef TIOCNOTTY
                fd = open("/dev/tty", 2);
                if (fd >= 0)
@@ -1190,14 +1259,48 @@ disconnect(fulldrop)
                }
                (void) setpgrp(0, 0);
 #endif /* TIOCNOTTY */
                }
                (void) setpgrp(0, 0);
 #endif /* TIOCNOTTY */
-#endif /* BSD */
                errno = 0;
        }
 
 # ifdef LOG
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "in background, pid=%d", getpid());
                errno = 0;
        }
 
 # ifdef LOG
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "in background, pid=%d", getpid());
-# endif LOG
+# endif /* LOG */
 
        errno = 0;
 }
 
        errno = 0;
 }
+
+static void
+obsolete(argv)
+       char *argv[];
+{
+       char *ap;
+
+       while (ap = *++argv)
+       {
+               /* Return if "--" or not an option of any form. */
+               if (ap[0] != '-' || ap[1] == '-')
+                       return;
+
+               /* If -C doesn't have an argument, use sendmail.cf. */
+#define        __DEFPATH       "sendmail.cf"
+               if (ap[1] == 'C' && ap[2] == '\0' &&
+                   (argv[1] == NULL || argv[1][0] == '-'))
+               {
+                       *argv = xalloc(sizeof(__DEFPATH) + 2);
+                       argv[0][0] = '-';
+                       argv[0][1] = 'C';
+                       (void)strcpy(&argv[0][2], __DEFPATH);
+               }
+
+               /* If -q doesn't have an argument, run it once. */
+               if (ap[1] == 'q' && ap[2] == '\0' &&
+                   (argv[1] == NULL || argv[1][0] == '-'))
+                       *argv = "-q0";
+
+               /* if -d doesn't have an argument, use 0-99.1 */
+               if (ap[1] == 'd' && ap[2] == '\0' &&
+                   (argv[1] == NULL || argv[1][0] == '-'))
+                       *argv = "-d0-99.1";
+       }
+}