add Berkeley specific header
[unix-history] / usr / src / usr.sbin / sendmail / src / main.c
index eb435ca..92b9a5d 100644 (file)
@@ -1,10 +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"
-# include <sys/file.h>
 
 
-SCCSID(@(#)main.c      3.155           %G%);
+# ifdef lint
+char   edata, end;
+# endif lint
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
 
 /*
 **  SENDMAIL -- Post mail to a set of destinations.
@@ -41,10 +68,24 @@ SCCSID(@(#)main.c   3.155           %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
@@ -57,9 +98,10 @@ 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;
        char **av;
 {
        register char *p;
        char **av;
@@ -70,17 +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 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.
@@ -97,14 +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.
        /*
        **  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);
+       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
@@ -115,14 +181,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
        */
@@ -142,30 +245,43 @@ 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();
-       av = myhostname(jbuf);
-       if (jbuf[0] != '\0')
+
+       if (readconfig)
        {
        {
-               p = newstr(jbuf);
-               define('w', p, CurEnv);
-               setclass('w', p);
+               /* 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);
        }
        }
-       while (av != NULL && *av != NULL)
-               setclass('w', *av++);
+
+       /* current time */
+       define('b', arpadate((char *) NULL), CurEnv);
 
        /*
        ** Crack argv.
 
        /*
        ** Crack argv.
@@ -179,6 +295,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])
@@ -212,19 +330,14 @@ 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
 
                        break;
 # endif DEBUG
 
@@ -246,7 +359,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 */
@@ -257,7 +370,7 @@ main(argc, argv)
                                av--;
                                break;
                        }
                                av--;
                                break;
                        }
-                       FullName = p;
+                       FullName = newstr(p);
                        break;
 
                  case 'h':     /* hop count */
                        break;
 
                  case 'h':     /* hop count */
@@ -320,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);
 
@@ -345,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);
@@ -368,11 +486,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();
@@ -381,16 +501,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))
        {
@@ -408,7 +534,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");
@@ -436,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++)
@@ -453,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);
@@ -547,7 +675,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)
@@ -588,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.
@@ -628,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/*
@@ -676,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'
 };
 
@@ -731,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;
 };
@@ -740,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[];
 
@@ -759,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");
        }
@@ -791,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);
@@ -807,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);
@@ -814,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);
@@ -822,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);
        }
 
@@ -868,9 +1013,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;
@@ -906,9 +1051,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