BSD 4_3_Tahoe release
[unix-history] / usr / src / usr.lib / sendmail / src / main.c
index d5895c1..bc98bbb 100644 (file)
@@ -1,10 +1,42 @@
-# define  _DEFINE
-# include <signal.h>
-# include <sys/ioctl.h>
-# include "sendmail.h"
-# include <sys/file.h>
-
-SCCSID(@(#)main.c      3.157           3/7/83);
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#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.18 (Berkeley) 6/30/88";
+#endif /* not lint */
+
+#define        _DEFINE
+
+#include <signal.h>
+#include <sgtty.h>
+#include "sendmail.h"
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+# ifdef lint
+char   edata, end;
+# endif lint
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
@@ -38,13 +70,24 @@ SCCSID(@(#)main.c   3.157           3/7/83);
 */
 
 
 */
 
 
-
-
-
-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
@@ -52,14 +95,10 @@ ERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR
 #endif SMTP
 #endif DAEMON
 
 #endif SMTP
 #endif DAEMON
 
-
-
-
-
-
-main(argc, argv)
+main(argc, argv, envp)
        int argc;
        char **argv;
        int argc;
        char **argv;
+       char **envp;
 {
        register char *p;
        char **av;
 {
        register char *p;
        char **av;
@@ -69,17 +108,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 char **myhostname();
        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.
@@ -94,14 +135,36 @@ main(argc, argv)
        }
        reenter = TRUE;
 
        }
        reenter = TRUE;
 
+       /* Enforce use of local time */
+       unsetenv("TZ");
+
        /*
        **  Be sure we have enough file descriptors.
        /*
        **  Be sure we have enough file descriptors.
+       **      But also be sure that 0, 1, & 2 are open.
        */
 
        */
 
-       for (i = 3; i < 20; i++)
+       i = open("/dev/null", 2);
+       while (i >= 0 && i < 2)
+               i = dup(i);
+       for (i = 3; i < 50; i++)
                (void) close(i);
        errno = 0;
 
                (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);
+       CurEnv = &BlankEnvelope;
+       STRUCTCOPY(NullAddress, MainEnvelope.e_from);
+
        /*
        **  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
@@ -112,14 +175,51 @@ main(argc, argv)
 
        argv[argc] = NULL;
        av = argv;
 
        argv[argc] = NULL;
        av = argv;
-       while (*++av != NULL)
+       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 (*av == NULL)
+       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
        */
@@ -135,44 +235,46 @@ main(argc, argv)
        OldUmask = umask(0);
        OpMode = MD_DELIVER;
        MotherPid = getpid();
        OldUmask = umask(0);
        OpMode = MD_DELIVER;
        MotherPid = getpid();
-# ifndef V6
        FullName = getenv("NAME");
        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);
+       openlog("sendmail", LOG_PID, LOG_MAIL);
 # endif LOG
        errno = 0;
        from = NULL;
 
 # endif LOG
        errno = 0;
        from = NULL;
 
-       /* initialize some macros, etc. */
-       initmacros();
-
-       /* hostname */
-       av = myhostname(jbuf);
-       if (jbuf[0] != '\0')
+       if (readconfig)
        {
        {
-               p = newstr(jbuf);
-               define('w', p, CurEnv);
-               setclass('w', p);
-       }
-       while (av != NULL && *av != NULL)
-               setclass('w', *av++);
+               /* 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);
+               /* version */
+               define('v', Version, CurEnv);
+       }
 
        /* current time */
 
        /* current time */
-       define('b', arpadate(NULL), CurEnv);
+       define('b', arpadate((char *) NULL), CurEnv);
 
        /*
        ** Crack argv.
 
        /*
        ** Crack argv.
@@ -186,6 +288,8 @@ 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;
+       else if (strcmp(p, "smtpd") == 0)
+               OpMode = MD_DAEMON;
        while ((p = *++av) != NULL && p[0] == '-')
        {
                switch (p[1])
        while ((p = *++av) != NULL && p[0] == '-')
        {
                switch (p[1])
@@ -219,21 +323,17 @@ 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;
 
                        break;
 
-# ifdef DEBUG
-                 case 'd':     /* debug */
+#ifdef 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);
+                       _res.options |= RES_DEBUG;
                        break;
                        break;
-# endif DEBUG
+#endif
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
 
                  case 'f':     /* from address */
                  case 'r':     /* obsolete -f flag */
@@ -253,7 +353,7 @@ 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 */
                        break;
 
                  case 'F':     /* set full name */
@@ -264,7 +364,7 @@ main(argc, argv)
                                av--;
                                break;
                        }
                                av--;
                                break;
                        }
-                       FullName = p;
+                       FullName = newstr(p);
                        break;
 
                  case 'h':     /* hop count */
                        break;
 
                  case 'h':     /* hop count */
@@ -327,12 +427,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);
 
@@ -352,8 +457,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);
@@ -375,11 +480,13 @@ 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();
 #ifdef QUEUE
                dropenvelope(CurEnv);
                printqueue();
@@ -388,16 +495,22 @@ main(argc, argv)
                usrerr("No queue to print");
                finis();
 #endif QUEUE
                usrerr("No queue to print");
                finis();
 #endif QUEUE
-       }
-
-       /*
-       **  Initialize aliases.
-       */
 
 
-       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))
        {
@@ -415,7 +528,7 @@ main(argc, argv)
                                m->m_maxsize);
                        for (j = '\0'; j <= '\177'; j++)
                                if (bitnset(j, m->m_flags))
                                m->m_maxsize);
                        for (j = '\0'; j <= '\177'; j++)
                                if (bitnset(j, m->m_flags))
-                                       putchar(j);
+                                       (void) putchar(j);
                        printf(" E=");
                        xputs(m->m_eol);
                        printf("\n");
                        printf(" E=");
                        xputs(m->m_eol);
                        printf("\n");
@@ -443,11 +556,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++)
@@ -460,7 +572,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);
@@ -554,7 +669,11 @@ main(argc, argv)
 
        if (OpMode != MD_ARPAFTP && *av == NULL && !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)
@@ -595,7 +714,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.
@@ -685,16 +804,19 @@ 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,
 
-       /* and finally the conditional operations */
+       /* the conditional operations */
        '?', CONDIF,    '|', CONDELSE,  '.', CONDFI,
 
        '?', CONDIF,    '|', CONDELSE,  '.', CONDFI,
 
+       /* and finally the hostname lookup characters */
+       '[', HOSTBEGIN, ']', HOSTEND,
+
        '\0'
 };
 
        '\0'
 };
 
@@ -740,6 +862,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;
 };
@@ -749,7 +873,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[];
 
@@ -768,12 +892,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");
        }
@@ -800,8 +926,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);
@@ -816,6 +943,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);
@@ -823,7 +952,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);
@@ -831,11 +960,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);
        }
 
@@ -877,9 +1006,9 @@ disconnect(fulldrop)
 #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;
@@ -915,9 +1044,11 @@ disconnect(fulldrop)
                fd = open("/dev/tty", 2);
                if (fd >= 0)
                {
                fd = open("/dev/tty", 2);
                if (fd >= 0)
                {
-                       (void) ioctl(fd, TIOCNOTTY, 0);
+                       (void) ioctl(fd, (int) TIOCNOTTY, (char *) 0);
                        (void) close(fd);
                }
                        (void) close(fd);
                }
+               (void) setpgrp(0, 0);
+               errno = 0;
        }
 #endif TIOCNOTTY
 
        }
 #endif TIOCNOTTY