add Berkeley specific header
[unix-history] / usr / src / usr.sbin / sendmail / src / main.c
index 29a93fd..92b9a5d 100644 (file)
@@ -1,9 +1,37 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ *
+ *  Sendmail
+ *  Copyright (c) 1983  Eric P. Allman
+ *  Berkeley, California
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c     5.15 (Berkeley) %G%";
+#endif /* not lint */
+
 # define  _DEFINE
 # include <signal.h>
 # define  _DEFINE
 # include <signal.h>
-# include <sys/ioctl.h>
+# include <sgtty.h>
 # include "sendmail.h"
 
 # include "sendmail.h"
 
-SCCSID(@(#)main.c      3.146           %G%);
+# ifdef lint
+char   edata, end;
+# endif lint
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
@@ -40,10 +68,24 @@ SCCSID(@(#)main.c   3.146           %G%);
 
 
 
 
 
 
-int            NextMailer = 0; /* "free" index into Mailer struct */
+int            NextMailer;     /* "free" index into Mailer struct */
 char           *FullName;      /* sender's full name */
 ENVELOPE       BlankEnvelope;  /* a "blank" envelope */
 ENVELOPE       MainEnvelope;   /* the envelope around the basic letter */
 char           *FullName;      /* sender's full name */
 ENVELOPE       BlankEnvelope;  /* a "blank" envelope */
 ENVELOPE       MainEnvelope;   /* the envelope around the basic letter */
+ADDRESS                NullAddress =   /* a null address */
+               { "", "", "" };
+
+/*
+**  Pointers for setproctitle.
+**     This allows "ps" listings to give more useful information.
+**     These must be kept out of BSS for frozen configuration files
+**             to work.
+*/
+
+# ifdef SETPROCTITLE
+char           **Argv = NULL;          /* pointer to argument vector */
+char           *LastArgv = NULL;       /* end of argv */
+# endif SETPROCTITLE
 
 #ifdef DAEMON
 #ifndef SMTP
 
 #ifdef DAEMON
 #ifndef SMTP
@@ -56,12 +98,12 @@ ERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR
 
 
 
 
 
 
-main(argc, argv)
+main(argc, argv, envp)
        int argc;
        char **argv;
        int argc;
        char **argv;
+       char **envp;
 {
        register char *p;
 {
        register char *p;
-       int ac;
        char **av;
        char *locname;
        extern int finis();
        char **av;
        char *locname;
        extern int finis();
@@ -70,16 +112,19 @@ main(argc, argv)
        typedef int (*fnptr)();
        STAB *st;
        register int i;
        typedef int (*fnptr)();
        STAB *st;
        register int i;
-       bool readconfig = FALSE;
-       bool safecf = TRUE;             /* this conf file is sys default */
+       bool readconfig = TRUE;
        bool queuemode = FALSE;         /* process queue requests */
        bool queuemode = FALSE;         /* process queue requests */
+       bool nothaw;
        static bool reenter = FALSE;
        static bool reenter = FALSE;
-       char jbuf[30];                  /* holds HostName */
+       char jbuf[30];                  /* holds MyHostName */
        extern bool safefile();
        extern time_t convtime();
        extern putheader(), putbody();
        extern ENVELOPE *newenvelope();
        extern intsig();
        extern bool safefile();
        extern time_t convtime();
        extern putheader(), putbody();
        extern ENVELOPE *newenvelope();
        extern intsig();
+       extern char **myhostname();
+       extern char *arpadate();
+       extern char **environ;
 
        /*
        **  Check to see if we reentered.
 
        /*
        **  Check to see if we reentered.
@@ -96,6 +141,36 @@ main(argc, argv)
        extern ADDRESS *recipient();
        bool canrename;
 
        extern ADDRESS *recipient();
        bool canrename;
 
+       /* Enforce use of local time */
+       unsetenv("TZ");
+
+       /*
+       **  Be sure we have enough file descriptors.
+       **      But also be sure that 0, 1, & 2 are open.
+       */
+
+       i = open("/dev/null", 2);
+       while (i >= 0 && i < 2)
+               i = dup(i);
+       for (i = 3; i < 50; i++)
+               (void) close(i);
+       errno = 0;
+
+       /*
+       **  Set default values for variables.
+       **      These cannot be in initialized data space.
+       */
+
+       setdefaults();
+
+       /* set up the blank envelope */
+       BlankEnvelope.e_puthdr = putheader;
+       BlankEnvelope.e_putbody = putbody;
+       BlankEnvelope.e_xfp = NULL;
+       STRUCTCOPY(NullAddress, BlankEnvelope.e_from);
+       STRUCTCOPY(BlankEnvelope, MainEnvelope);
+       CurEnv = &MainEnvelope;
+
        /*
        **  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
@@ -105,16 +180,52 @@ main(argc, argv)
        */
 
        argv[argc] = NULL;
        */
 
        argv[argc] = NULL;
-       ac = argc;
        av = argv;
        av = argv;
-       while (--ac > 0)
+       nothaw = FALSE;
+       while ((p = *++av) != NULL)
        {
        {
-               if (strncmp(*++av, "-C", 2) == 0 || strncmp(*av, "-bz", 3) == 0)
-                       break;
+               if (strncmp(p, "-C", 2) == 0)
+               {
+                       ConfFile = &p[2];
+                       if (ConfFile[0] == '\0')
+                               ConfFile = "sendmail.cf";
+                       (void) setgid(getrgid());
+                       (void) setuid(getruid());
+                       nothaw = TRUE;
+               }
+               else if (strncmp(p, "-bz", 3) == 0)
+                       nothaw = TRUE;
+# ifdef DEBUG
+               else if (strncmp(p, "-d", 2) == 0)
+               {
+                       tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
+                       tTflag(&p[2]);
+                       setbuf(stdout, (char *) NULL);
+                       printf("Version %s\n", Version);
+               }
+# endif DEBUG
        }
        }
-       if (ac <= 0)
+       if (!nothaw)
                readconfig = !thaw(FreezeFile);
 
                readconfig = !thaw(FreezeFile);
 
+       /* reset the environment after the thaw */
+       for (i = 0; i < MAXUSERENVIRON && envp[i] != NULL; i++)
+               UserEnviron[i] = newstr(envp[i]);
+       UserEnviron[i] = NULL;
+       environ = UserEnviron;
+
+# ifdef SETPROCTITLE
+       /*
+       **  Save start and extent of argv for setproctitle.
+       */
+
+       Argv = argv;
+       if (i > 0)
+               LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+       else
+               LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+# endif SETPROCTITLE
+
        /*
        **  Now do basic initialization
        */
        /*
        **  Now do basic initialization
        */
@@ -126,6 +237,7 @@ main(argc, argv)
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                (void) signal(SIGHUP, intsig);
        (void) signal(SIGTERM, intsig);
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                (void) signal(SIGHUP, intsig);
        (void) signal(SIGTERM, intsig);
+       (void) signal(SIGPIPE, SIG_IGN);
        OldUmask = umask(0);
        OpMode = MD_DELIVER;
        MotherPid = getpid();
        OldUmask = umask(0);
        OpMode = MD_DELIVER;
        MotherPid = getpid();
@@ -133,27 +245,48 @@ main(argc, argv)
        FullName = getenv("NAME");
 # endif V6
 
        FullName = getenv("NAME");
 # endif V6
 
-       /* set up the blank envelope */
-       BlankEnvelope.e_puthdr = putheader;
-       BlankEnvelope.e_putbody = putbody;
-       BlankEnvelope.e_xfp = NULL;
-       CurEnv = &BlankEnvelope;
-
-       /* make sure we have a clean slate */
-       closeall();
-
 # ifdef LOG
 # ifdef LOG
-       openlog("sendmail", LOG_PID);
 # endif LOG
        errno = 0;
        from = NULL;
 # endif LOG
        errno = 0;
        from = NULL;
-       initmacros();
+
+       if (readconfig)
+       {
+               /* initialize some macros, etc. */
+               initmacros();
+
+               /* hostname */
+               av = myhostname(jbuf, sizeof jbuf);
+               if (jbuf[0] != '\0')
+               {
+#ifdef DEBUG
+                       if (tTd(0, 4))
+                               printf("canonical name: %s\n", jbuf);
+#endif DEBUG
+                       p = newstr(jbuf);
+                       define('w', p, CurEnv);
+                       setclass('w', p);
+               }
+               while (av != NULL && *av != NULL)
+               {
+#ifdef DEBUG
+                       if (tTd(0, 4))
+                               printf("\ta.k.a.: %s\n", *av);
+#endif DEBUG
+                       setclass('w', *av++);
+               }
+
+               /* version */
+               define('v', Version, CurEnv);
+       }
+
+       /* current time */
+       define('b', arpadate((char *) NULL), CurEnv);
 
        /*
        ** Crack argv.
        */
 
 
        /*
        ** Crack argv.
        */
 
-       ac = argc;
        av = argv;
        p = rindex(*av, '/');
        if (p++ == NULL)
        av = argv;
        p = rindex(*av, '/');
        if (p++ == NULL)
@@ -162,7 +295,9 @@ main(argc, argv)
                OpMode = MD_INITALIAS;
        else if (strcmp(p, "mailq") == 0)
                OpMode = MD_PRINT;
                OpMode = MD_INITALIAS;
        else if (strcmp(p, "mailq") == 0)
                OpMode = MD_PRINT;
-       while (--ac > 0 && (p = *++av)[0] == '-')
+       else if (strcmp(p, "smtpd") == 0)
+               OpMode = MD_DAEMON;
+       while ((p = *++av) != NULL && p[0] == '-')
        {
                switch (p[1])
                {
        {
                switch (p[1])
                {
@@ -195,32 +330,26 @@ main(argc, argv)
                        }
                        break;
 
                        }
                        break;
 
-                 case 'C':     /* select configuration file */
-                       ConfFile = &p[2];
-                       if (ConfFile[0] == '\0')
-                               ConfFile = "sendmail.cf";
-                       safecf = FALSE;
+                 case 'C':     /* select configuration file (already done) */
                        break;
 
 # ifdef DEBUG
                        break;
 
 # ifdef DEBUG
-                 case 'd':     /* debug */
+                 case 'd':     /* debugging -- redo in case frozen */
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
                        tTflag(&p[2]);
                        setbuf(stdout, (char *) NULL);
                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
                        tTflag(&p[2]);
                        setbuf(stdout, (char *) NULL);
-                       printf("Version %s\n", Version);
                        break;
 # endif DEBUG
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
                        p += 2;
                        break;
 # endif DEBUG
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
                        p += 2;
-                       if (*p == '\0')
+                       if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
                        {
                                p = *++av;
                        {
                                p = *++av;
-                               if (--ac <= 0 || *p == '-')
+                               if (p == NULL || *p == '-')
                                {
                                        syserr("No \"from\" person");
                                {
                                        syserr("No \"from\" person");
-                                       ac++;
                                        av--;
                                        break;
                                }
                                        av--;
                                        break;
                                }
@@ -230,37 +359,27 @@ main(argc, argv)
                                syserr("More than one \"from\" person");
                                break;
                        }
                                syserr("More than one \"from\" person");
                                break;
                        }
-                       from = p;
+                       from = newstr(p);
                        break;
 
                  case 'F':     /* set full name */
                        p += 2;
                        break;
 
                  case 'F':     /* set full name */
                        p += 2;
-                       if (*p == '\0')
+                       if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
                        {
                        {
-                               p = *++av;
-                               if (--ac <= 0 || *p == '-')
-                               {
-                                       syserr("Bad -F flag");
-                                       ac++;
-                                       av--;
-                                       break;
-                               }
+                               syserr("Bad -F flag");
+                               av--;
+                               break;
                        }
                        }
-                       FullName = p;
+                       FullName = newstr(p);
                        break;
 
                  case 'h':     /* hop count */
                        p += 2;
                        break;
 
                  case 'h':     /* hop count */
                        p += 2;
-                       if (*p == '\0')
+                       if (*p == '\0' && ((p = *++av) == NULL || !isdigit(*p)))
                        {
                        {
-                               p = *++av;
-                               if (--ac <= 0 || *p < '0' || *p > '9')
-                               {
-                                       syserr("Bad hop count (%s)", p);
-                                       ac++;
-                                       av--;
-                                       break;
-                               }
+                               syserr("Bad hop count (%s)", p);
+                               av--;
+                               break;
                        }
                        CurEnv->e_hopcount = atoi(p);
                        break;
                        }
                        CurEnv->e_hopcount = atoi(p);
                        break;
@@ -314,12 +433,17 @@ main(argc, argv)
        **      Extract special fields for local use.
        */
 
        **      Extract special fields for local use.
        */
 
-       if (!safecf || OpMode == MD_FREEZE || readconfig)
-               readcf(ConfFile, safecf);
+       if (OpMode == MD_FREEZE || readconfig)
+               readcf(ConfFile);
 
        switch (OpMode)
        {
          case MD_FREEZE:
 
        switch (OpMode)
        {
          case MD_FREEZE:
+               /* this is critical to avoid forgeries of the frozen config */
+               (void) setgid(getgid());
+               (void) setuid(getuid());
+
+               /* freeze the configuration */
                freeze(FreezeFile);
                exit(EX_OK);
 
                freeze(FreezeFile);
                exit(EX_OK);
 
@@ -339,8 +463,8 @@ main(argc, argv)
        }
 
        /* our name for SMTP codes */
        }
 
        /* our name for SMTP codes */
-       expand("$j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
-       HostName = jbuf;
+       expand("\001j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+       MyHostName = jbuf;
 
        /* the indices of local and program mailers */
        st = stab("local", ST_MAILER, ST_FIND);
 
        /* the indices of local and program mailers */
        st = stab("local", ST_MAILER, ST_FIND);
@@ -362,24 +486,37 @@ main(argc, argv)
        }
 
        /*
        }
 
        /*
-       **  If printing the queue, go off and do that.
+       **  Do operation-mode-dependent initialization.
        */
 
        */
 
-       if (OpMode == MD_PRINT)
+       switch (OpMode)
        {
        {
+         case MD_PRINT:
+               /* print the queue */
+#ifdef QUEUE
                dropenvelope(CurEnv);
                printqueue();
                exit(EX_OK);
                dropenvelope(CurEnv);
                printqueue();
                exit(EX_OK);
-       }
-
-       /*
-       **  Initialize aliases.
-       */
+#else QUEUE
+               usrerr("No queue to print");
+               finis();
+#endif QUEUE
 
 
-       initaliases(AliasFile, OpMode == MD_INITALIAS);
-       if (OpMode == MD_INITALIAS)
+         case MD_INITALIAS:
+               /* initialize alias database */
+               initaliases(AliasFile, TRUE);
                exit(EX_OK);
 
                exit(EX_OK);
 
+         case MD_DAEMON:
+               /* don't open alias database -- done in srvrsmtp */
+               break;
+
+         default:
+               /* open the alias database */
+               initaliases(AliasFile, FALSE);
+               break;
+       }
+
 # ifdef DEBUG
        if (tTd(0, 15))
        {
 # ifdef DEBUG
        if (tTd(0, 15))
        {
@@ -388,11 +525,19 @@ main(argc, argv)
                for (i = 0; i < MAXMAILERS; i++)
                {
                        register struct mailer *m = Mailer[i];
                for (i = 0; i < MAXMAILERS; i++)
                {
                        register struct mailer *m = Mailer[i];
+                       int j;
 
                        if (m == NULL)
                                continue;
 
                        if (m == NULL)
                                continue;
-                       printf("mailer %d: %s %s %lo %d %d\n", i, m->m_name,
-                              m->m_mailer, m->m_flags, m->m_s_rwset, m->m_r_rwset);
+                       printf("mailer %d (%s): P=%s S=%d R=%d M=%ld F=", i, m->m_name,
+                               m->m_mailer, m->m_s_rwset, m->m_r_rwset,
+                               m->m_maxsize);
+                       for (j = '\0'; j <= '\177'; j++)
+                               if (bitnset(j, m->m_flags))
+                                       (void) putchar(j);
+                       printf(" E=");
+                       xputs(m->m_eol);
+                       printf("\n");
                }
        }
 # endif DEBUG
                }
        }
 # endif DEBUG
@@ -417,11 +562,10 @@ main(argc, argv)
                {
                        register char **pvp;
                        char *q;
                {
                        register char **pvp;
                        char *q;
-                       extern char **prescan();
                        extern char *DelimChar;
 
                        printf("> ");
                        extern char *DelimChar;
 
                        printf("> ");
-                       fflush(stdout);
+                       (void) fflush(stdout);
                        if (fgets(buf, sizeof buf, stdin) == NULL)
                                finis();
                        for (p = buf; isspace(*p); *p++)
                        if (fgets(buf, sizeof buf, stdin) == NULL)
                                finis();
                        for (p = buf; isspace(*p); *p++)
@@ -434,7 +578,10 @@ main(argc, argv)
                        *p = '\0';
                        do
                        {
                        *p = '\0';
                        do
                        {
-                               pvp = prescan(++p, ',');
+                               extern char **prescan();
+                               char pvpbuf[PSBUFSIZE];
+
+                               pvp = prescan(++p, ',', pvpbuf);
                                if (pvp == NULL)
                                        continue;
                                rewrite(pvp, 3);
                                if (pvp == NULL)
                                        continue;
                                rewrite(pvp, 3);
@@ -485,7 +632,7 @@ main(argc, argv)
                        MotherPid = getpid();
 
                        /* disconnect from our controlling tty */
                        MotherPid = getpid();
 
                        /* disconnect from our controlling tty */
-                       disconnect();
+                       disconnect(TRUE);
                }
 
 # ifdef QUEUE
                }
 
 # ifdef QUEUE
@@ -526,9 +673,13 @@ main(argc, argv)
        initsys();
        setsender(from);
 
        initsys();
        setsender(from);
 
-       if (OpMode != MD_ARPAFTP && ac <= 0 && !GrabTo)
+       if (OpMode != MD_ARPAFTP && *av == NULL && !GrabTo)
        {
        {
-               usrerr("Usage: /etc/sendmail [flags] addr...");
+               usrerr("Recipient names must be specified");
+
+               /* collect body for UUCP return */
+               if (OpMode != MD_VERIFY)
+                       collect(FALSE);
                finis();
        }
        if (OpMode == MD_VERIFY)
                finis();
        }
        if (OpMode == MD_VERIFY)
@@ -569,7 +720,7 @@ main(argc, argv)
 
        CurEnv->e_from.q_flags |= QDONTSEND;
        CurEnv->e_to = NULL;
 
        CurEnv->e_from.q_flags |= QDONTSEND;
        CurEnv->e_to = NULL;
-       sendall(CurEnv, SendMode);
+       sendall(CurEnv, SM_DEFAULT);
 
        /*
        ** All done.
 
        /*
        ** All done.
@@ -609,6 +760,8 @@ finis()
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "finis, pid=%d", getpid());
 # endif LOG
        if (LogLevel > 11)
                syslog(LOG_DEBUG, "finis, pid=%d", getpid());
 # endif LOG
+       if (ExitStat == EX_TEMPFAIL)
+               ExitStat = EX_OK;
        exit(ExitStat);
 }
 \f/*
        exit(ExitStat);
 }
 \f/*
@@ -657,16 +810,20 @@ struct metamac
 
 struct metamac MetaMacros[] =
 {
 
 struct metamac MetaMacros[] =
 {
-       /* these are important on the LHS */
+       /* LHS pattern matching characters */
        '*', MATCHZANY, '+', MATCHANY,  '-', MATCHONE,  '=', MATCHCLASS,
        '~', MATCHNCLASS,
 
        /* these are RHS metasymbols */
        '#', CANONNET,  '@', CANONHOST, ':', CANONUSER, '>', CALLSUBR,
        '*', MATCHZANY, '+', MATCHANY,  '-', MATCHONE,  '=', MATCHCLASS,
        '~', MATCHNCLASS,
 
        /* these are RHS metasymbols */
        '#', CANONNET,  '@', CANONHOST, ':', CANONUSER, '>', CALLSUBR,
+       '{', MATCHLOOKUP,               '}', MATCHELOOKUP,
 
 
-       /* and finally the conditional operations */
+       /* the conditional operations */
        '?', CONDIF,    '|', CONDELSE,  '.', CONDFI,
 
        '?', CONDIF,    '|', CONDELSE,  '.', CONDFI,
 
+       /* and finally the hostname lookup characters */
+       '[', HOSTBEGIN, ']', HOSTEND,
+
        '\0'
 };
 
        '\0'
 };
 
@@ -712,6 +869,8 @@ union frz
        {
                time_t  frzstamp;       /* timestamp on this freeze */
                char    *frzbrk;        /* the current break */
        {
                time_t  frzstamp;       /* timestamp on this freeze */
                char    *frzbrk;        /* the current break */
+               char    *frzedata;      /* address of edata */
+               char    *frzend;        /* address of end */
                char    frzver[252];    /* sendmail version */
        } frzinfo;
 };
                char    frzver[252];    /* sendmail version */
        } frzinfo;
 };
@@ -721,7 +880,7 @@ freeze(freezefile)
 {
        int f;
        union frz fhdr;
 {
        int f;
        union frz fhdr;
-       extern char edata;
+       extern char edata, end;
        extern char *sbrk();
        extern char Version[];
 
        extern char *sbrk();
        extern char Version[];
 
@@ -740,12 +899,14 @@ freeze(freezefile)
        /* build the freeze header */
        fhdr.frzinfo.frzstamp = curtime();
        fhdr.frzinfo.frzbrk = sbrk(0);
        /* build the freeze header */
        fhdr.frzinfo.frzstamp = curtime();
        fhdr.frzinfo.frzbrk = sbrk(0);
-       strcpy(fhdr.frzinfo.frzver, Version);
+       fhdr.frzinfo.frzedata = &edata;
+       fhdr.frzinfo.frzend = &end;
+       (void) strcpy(fhdr.frzinfo.frzver, Version);
 
        /* write out the freeze header */
        if (write(f, (char *) &fhdr, sizeof fhdr) != sizeof fhdr ||
 
        /* write out the freeze header */
        if (write(f, (char *) &fhdr, sizeof fhdr) != sizeof fhdr ||
-           write(f, (char *) &edata, fhdr.frzinfo.frzbrk - &edata) !=
-                                       (fhdr.frzinfo.frzbrk - &edata))
+           write(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - &edata)) !=
+                                       (int) (fhdr.frzinfo.frzbrk - &edata))
        {
                syserr("Cannot freeze");
        }
        {
                syserr("Cannot freeze");
        }
@@ -772,8 +933,9 @@ thaw(freezefile)
 {
        int f;
        union frz fhdr;
 {
        int f;
        union frz fhdr;
-       extern char edata;
+       extern char edata, end;
        extern char Version[];
        extern char Version[];
+       extern caddr_t brk();
 
        if (freezefile == NULL)
                return (FALSE);
 
        if (freezefile == NULL)
                return (FALSE);
@@ -788,6 +950,8 @@ thaw(freezefile)
 
        /* 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 ||
+           fhdr.frzinfo.frzedata != &edata ||
+           fhdr.frzinfo.frzend != &end ||
            strcmp(fhdr.frzinfo.frzver, Version) != 0)
        {
                (void) close(f);
            strcmp(fhdr.frzinfo.frzver, Version) != 0)
        {
                (void) close(f);
@@ -795,7 +959,7 @@ thaw(freezefile)
        }
 
        /* arrange to have enough space */
        }
 
        /* arrange to have enough space */
-       if (brk(fhdr.frzinfo.frzbrk) < 0)
+       if (brk(fhdr.frzinfo.frzbrk) == (caddr_t) -1)
        {
                syserr("Cannot break to %x", fhdr.frzinfo.frzbrk);
                (void) close(f);
        {
                syserr("Cannot break to %x", fhdr.frzinfo.frzbrk);
                (void) close(f);
@@ -803,11 +967,11 @@ thaw(freezefile)
        }
 
        /* now read in the freeze file */
        }
 
        /* now read in the freeze file */
-       if (read(f, (char *) &edata, fhdr.frzinfo.frzbrk - &edata) !=
-                                       (fhdr.frzinfo.frzbrk - &edata))
+       if (read(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - &edata)) !=
+                                       (int) (fhdr.frzinfo.frzbrk - &edata))
        {
                /* oops!  we have trashed memory..... */
        {
                /* oops!  we have trashed memory..... */
-               write(2, "Cannot read freeze file\n", 24);
+               (void) write(2, "Cannot read freeze file\n", 24);
                _exit(EX_SOFTWARE);
        }
 
                _exit(EX_SOFTWARE);
        }
 
@@ -818,7 +982,11 @@ thaw(freezefile)
 **  DISCONNECT -- remove our connection with any foreground process
 **
 **     Parameters:
 **  DISCONNECT -- remove our connection with any foreground process
 **
 **     Parameters:
-**             none.
+**             fulldrop -- if set, we should also drop the controlling
+**                     TTY if possible -- this should only be done when
+**                     setting up the daemon since otherwise UUCP can
+**                     leave us trying to open a dialin, and we will
+**                     wait for the carrier.
 **
 **     Returns:
 **             none
 **
 **     Returns:
 **             none
@@ -828,7 +996,8 @@ thaw(freezefile)
 **             the controlling tty.
 */
 
 **             the controlling tty.
 */
 
-disconnect()
+disconnect(fulldrop)
+       bool fulldrop;
 {
        int fd;
 
 {
        int fd;
 
@@ -844,9 +1013,9 @@ disconnect()
 #endif DEBUG
 
        /* be sure we don't get nasty signals */
 #endif DEBUG
 
        /* be sure we don't get nasty signals */
-       signal(SIGHUP, SIG_IGN);
-       signal(SIGINT, SIG_IGN);
-       signal(SIGQUIT, SIG_IGN);
+       (void) signal(SIGHUP, SIG_IGN);
+       (void) signal(SIGINT, SIG_IGN);
+       (void) signal(SIGQUIT, SIG_IGN);
 
        /* we can't communicate with our caller, so.... */
        HoldErrs = TRUE;
 
        /* we can't communicate with our caller, so.... */
        HoldErrs = TRUE;
@@ -877,11 +1046,16 @@ disconnect()
 
 #ifdef TIOCNOTTY
        /* drop our controlling TTY completely if possible */
 
 #ifdef TIOCNOTTY
        /* drop our controlling TTY completely if possible */
-       fd = open("/dev/tty", 2);
-       if (fd >= 0)
+       if (fulldrop)
        {
        {
-               (void) ioctl(fd, TIOCNOTTY, 0);
-               (void) close(fd);
+               fd = open("/dev/tty", 2);
+               if (fd >= 0)
+               {
+                       (void) ioctl(fd, (int) TIOCNOTTY, (char *) 0);
+                       (void) close(fd);
+               }
+               (void) setpgrp(0, 0);
+               errno = 0;
        }
 #endif TIOCNOTTY
 
        }
 #endif TIOCNOTTY