BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / conf.c
index 5780fea..8467caa 100644 (file)
@@ -1,21 +1,45 @@
 /*
 /*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)conf.c     8.135 (Berkeley) %G%";
+static char sccsid[] = "@(#)conf.c     8.203 (Berkeley) 6/20/95";
 #endif /* not lint */
 
 # include "sendmail.h"
 # include "pathnames.h"
 # include <sys/ioctl.h>
 # include <sys/param.h>
 #endif /* not lint */
 
 # include "sendmail.h"
 # include "pathnames.h"
 # include <sys/ioctl.h>
 # include <sys/param.h>
-# include <netdb.h>
-# include <pwd.h>
 
 /*
 **  CONF.C -- Sendmail Configuration Tables.
 
 /*
 **  CONF.C -- Sendmail Configuration Tables.
@@ -41,7 +65,7 @@ static char sccsid[] = "@(#)conf.c    8.135 (Berkeley) %G%";
 
 
 
 
 
 
-\f/*
+/*
 **  Header info table
 **     Final (null) entry contains the flags used for any other field.
 **
 **  Header info table
 **     Final (null) entry contains the flags used for any other field.
 **
@@ -94,6 +118,7 @@ struct hdrinfo       HdrInfo[] =
        "return-path",                  H_FORCE|H_ACHECK,
        "content-transfer-encoding",    H_CTE,
        "content-type",                 H_CTYPE,
        "return-path",                  H_FORCE|H_ACHECK,
        "content-transfer-encoding",    H_CTE,
        "content-type",                 H_CTYPE,
+       "content-length",               H_ACHECK,
 
        NULL,                   0,
 };
 
        NULL,                   0,
 };
@@ -185,13 +210,18 @@ setdefaults(e)
        LogLevel = 9;                           /* option L */
        inittimeouts(NULL);                     /* option r */
        PrivacyFlags = 0;                       /* option p */
        LogLevel = 9;                           /* option L */
        inittimeouts(NULL);                     /* option r */
        PrivacyFlags = 0;                       /* option p */
+#if MIME8TO7
        MimeMode = MM_CVTMIME|MM_PASS8BIT;      /* option 8 */
        MimeMode = MM_CVTMIME|MM_PASS8BIT;      /* option 8 */
+#else
+       MimeMode = MM_PASS8BIT;
+#endif
        for (i = 0; i < MAXTOCLASS; i++)
        {
                TimeOuts.to_q_return[i] = 5 DAYS;       /* option T */
                TimeOuts.to_q_warning[i] = 0;           /* option T */
        }
        ServiceSwitchFile = "/etc/service.switch";
        for (i = 0; i < MAXTOCLASS; i++)
        {
                TimeOuts.to_q_return[i] = 5 DAYS;       /* option T */
                TimeOuts.to_q_warning[i] = 0;           /* option T */
        }
        ServiceSwitchFile = "/etc/service.switch";
+       HostsFile = _PATH_HOSTS;
        setdefuser();
        setupmaps();
        setupmailers();
        setdefuser();
        setupmaps();
        setupmailers();
@@ -209,7 +239,7 @@ setdefuser()
        static char defuserbuf[40];
 
        DefUser = defuserbuf;
        static char defuserbuf[40];
 
        DefUser = defuserbuf;
-       if ((defpwent = getpwuid(DefUid)) != NULL)
+       if ((defpwent = sm_getpwuid(DefUid)) != NULL)
                strcpy(defuserbuf, defpwent->pw_name);
        else
                strcpy(defuserbuf, "nobody");
                strcpy(defuserbuf, defpwent->pw_name);
        else
                strcpy(defuserbuf, "nobody");
@@ -258,10 +288,10 @@ setupmailers()
        char buf[100];
        extern void makemailer();
 
        char buf[100];
        extern void makemailer();
 
-       strcpy(buf, "prog, P=/bin/sh, F=lsoD, A=sh -c $u");
+       strcpy(buf, "prog, P=/bin/sh, F=lsoD, T=DNS/RFC822/X-Unix, A=sh -c \201u");
        makemailer(buf);
 
        makemailer(buf);
 
-       strcpy(buf, "*file*, P=/dev/null, F=lsDFMPEou, A=FILE");
+       strcpy(buf, "*file*, P=[FILE], F=lsDFMPEou, T=DNS/RFC822/X-Unix, A=FILE");
        makemailer(buf);
 
        strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE");
        makemailer(buf);
 
        strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE");
@@ -328,7 +358,7 @@ setupmaps()
                hes_map_lookup, null_map_store);
 #endif
 
                hes_map_lookup, null_map_store);
 #endif
 
-#ifdef NETINFO
+#if NETINFO
        MAPDEF("netinfo", NULL, MCF_ALIASOK,
                map_parseargs, ni_map_open, null_map_close,
                ni_map_lookup, null_map_store);
        MAPDEF("netinfo", NULL, MCF_ALIASOK,
                map_parseargs, ni_map_open, null_map_close,
                ni_map_lookup, null_map_store);
@@ -373,15 +403,18 @@ setupmaps()
                dequote_init, null_map_open, null_map_close,
                dequote_map, null_map_store);
 
                dequote_init, null_map_open, null_map_close,
                dequote_map, null_map_store);
 
-#if 0
-# ifdef USERDB
+#if USERDB
        /* user database */
        /* user database */
-       MAPDEF("udb", ".db", 0,
-               udb_map_parse, null_map_open, null_map_close,
+       MAPDEF("userdb", ".db", 0,
+               map_parseargs, null_map_open, null_map_close,
                udb_map_lookup, null_map_store);
                udb_map_lookup, null_map_store);
-# endif
 #endif
 
 #endif
 
+       /* arbitrary programs */
+       MAPDEF("program", NULL, MCF_ALIASOK,
+               map_parseargs, null_map_open, null_map_close,
+               prog_map_lookup, null_map_store);
+
        /* sequenced maps */
        MAPDEF("sequence", NULL, MCF_ALIASOK,
                seq_map_parse, null_map_open, null_map_close,
        /* sequenced maps */
        MAPDEF("sequence", NULL, MCF_ALIASOK,
                seq_map_parse, null_map_open, null_map_close,
@@ -435,14 +468,14 @@ inithostmaps()
                    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts");
                    stab("hosts.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #if NAMED_BIND
                else if (strcmp(maptype[i], "dns") == 0 &&
                    stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.dns dns A");
                }
 #if NAMED_BIND
                else if (strcmp(maptype[i], "dns") == 0 &&
                    stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.dns dns A");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
 #ifdef NISPLUS
                }
 #endif
 #ifdef NISPLUS
@@ -450,7 +483,7 @@ inithostmaps()
                    stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.nisplus nisplus -k name -v address -d hosts.org_dir");
                    stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.nisplus nisplus -k name -v address -d hosts.org_dir");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
 #ifdef NIS
                }
 #endif
 #ifdef NIS
@@ -458,7 +491,7 @@ inithostmaps()
                    stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.nis nis -d -k 0 -v 1 hosts.byname");
                    stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "hosts.nis nis -d -k 0 -v 1 hosts.byname");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
        }
                }
 #endif
        }
@@ -476,7 +509,7 @@ inithostmaps()
                if (ConfigLevel >= 2)
                        strcat(buf, " -a.");
 #endif
                if (ConfigLevel >= 2)
                        strcat(buf, " -a.");
 #endif
-               makemapentry(buf);
+               (void) makemapentry(buf);
        }
 
        /*
        }
 
        /*
@@ -490,14 +523,14 @@ inithostmaps()
                    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.files implicit /etc/aliases");
                    stab("aliases.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.files implicit /etc/aliases");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #ifdef NISPLUS
                else if (strcmp(maptype[i], "nisplus") == 0 &&
                    stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion -d mail_aliases.org_dir");
                }
 #ifdef NISPLUS
                else if (strcmp(maptype[i], "nisplus") == 0 &&
                    stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion -d mail_aliases.org_dir");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
 #ifdef NIS
                }
 #endif
 #ifdef NIS
@@ -505,17 +538,23 @@ inithostmaps()
                    stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.nis nis -d mail.aliases");
                    stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "aliases.nis nis -d mail.aliases");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
+               }
+#endif
+#ifdef HESIOD
+               else if (strcmp(maptype[i], "hesiod") == 0 &&
+                   stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
+               {
+                       strcpy(buf, "aliases.hesiod hesiod aliases");
+                       (void) makemapentry(buf);
                }
 #endif
        }
        if (stab("aliases", ST_MAP, ST_FIND) == NULL)
        {
                strcpy(buf, "aliases switch aliases");
                }
 #endif
        }
        if (stab("aliases", ST_MAP, ST_FIND) == NULL)
        {
                strcpy(buf, "aliases switch aliases");
-               makemapentry(buf);
+               (void) makemapentry(buf);
        }
        }
-       strcpy(buf, "switch:aliases");
-       setalias(buf);
 
 #if 0          /* "user" map class is a better choice */
        /*
 
 #if 0          /* "user" map class is a better choice */
        /*
@@ -529,14 +568,14 @@ inithostmaps()
                    stab("users.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd");
                    stab("users.files", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #ifdef NISPLUS
                else if (strcmp(maptype[i], "nisplus") == 0 &&
                    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.nisplus nisplus -m -kname -vhome -d passwd.org_dir");
                }
 #ifdef NISPLUS
                else if (strcmp(maptype[i], "nisplus") == 0 &&
                    stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.nisplus nisplus -m -kname -vhome -d passwd.org_dir");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
 #ifdef NIS
                }
 #endif
 #ifdef NIS
@@ -544,7 +583,7 @@ inithostmaps()
                    stab("users.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.nis nis -m -d passwd.byname");
                    stab("users.nis", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.nis nis -m -d passwd.byname");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
 #ifdef HESIOD
                }
 #endif
 #ifdef HESIOD
@@ -552,14 +591,14 @@ inithostmaps()
                    stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.hesiod hesiod");
                    stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
                {
                        strcpy(buf, "users.hesiod hesiod");
-                       makemapentry(buf);
+                       (void) makemapentry(buf);
                }
 #endif
        }
        if (stab("users", ST_MAP, ST_FIND) == NULL)
        {
                strcpy(buf, "users switch -m passwd");
                }
 #endif
        }
        if (stab("users", ST_MAP, ST_FIND) == NULL)
        {
                strcpy(buf, "users switch -m passwd");
-               makemapentry(buf);
+               (void) makemapentry(buf);
        }
 #endif
 }
        }
 #endif
 }
@@ -584,7 +623,11 @@ inithostmaps()
 # include <nsswitch.h>
 #endif
 
 # include <nsswitch.h>
 #endif
 
-#if defined(ultrix) || defined(__osf__)
+#if defined(ultrix) || (defined(__osf__) && defined(__alpha))
+# define _USE_DEC_SVC_CONF_
+#endif
+
+#ifdef _USE_DEC_SVC_CONF_
 # include <sys/svcinfo.h>
 #endif
 
 # include <sys/svcinfo.h>
 #endif
 
@@ -628,10 +671,13 @@ switch_map_find(service, maptype, mapreturn)
        return svcno;
 #endif
 
        return svcno;
 #endif
 
-#if defined(ultrix) || defined(__osf__)
+#ifdef _USE_DEC_SVC_CONF_
        struct svcinfo *svcinfo;
        int svc;
 
        struct svcinfo *svcinfo;
        int svc;
 
+       for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+               mapreturn[svcno] = 0;
+
        svcinfo = getsvc();
        if (svcinfo == NULL)
                goto punt;
        svcinfo = getsvc();
        if (svcinfo == NULL)
                goto punt;
@@ -672,11 +718,14 @@ switch_map_find(service, maptype, mapreturn)
        return svcno;
 #endif
 
        return svcno;
 #endif
 
-#if !defined(SOLARIS) && !defined(ultrix) && !defined(__osf__)
+#if !defined(SOLARIS) && !defined(_USE_DEC_SVC_CONF_)
        /*
        **  Fall-back mechanism.
        */
 
        /*
        **  Fall-back mechanism.
        */
 
+       for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+               mapreturn[svcno] = 0;
+
        svcno = 0;
        fp = fopen(ServiceSwitchFile, "r");
        if (fp != NULL)
        svcno = 0;
        fp = fopen(ServiceSwitchFile, "r");
        if (fp != NULL)
@@ -706,19 +755,32 @@ switch_map_find(service, maptype, mapreturn)
                                if (p != NULL)
                                        *p++ = '\0';
                        } while (p != NULL);
                                if (p != NULL)
                                        *p++ = '\0';
                        } while (p != NULL);
-                       break;
+                       fclose(fp);
+                       return svcno;
                }
                }
+
+               /* service was not found -- use compiled in default */
                fclose(fp);
                fclose(fp);
-               return svcno;
        }
 #endif
 
        /* if the service file doesn't work, use an absolute fallback */
   punt:
        }
 #endif
 
        /* if the service file doesn't work, use an absolute fallback */
   punt:
+       for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+               mapreturn[svcno] = 0;
+       svcno = 0;
        if (strcmp(service, "aliases") == 0)
        {
        if (strcmp(service, "aliases") == 0)
        {
-               maptype[0] = "files";
-               return 1;
+               maptype[svcno++] = "files";
+#ifdef AUTO_NIS_ALIASES
+# ifdef NISPLUS
+               maptype[svcno++] = "nisplus";
+# endif
+# ifdef NIS
+               maptype[svcno++] = "nis";
+# endif
+#endif
+               return svcno;
        }
        if (strcmp(service, "hosts") == 0)
        {
        }
        if (strcmp(service, "hosts") == 0)
        {
@@ -764,7 +826,7 @@ username()
                myname = getlogin();
                if (myname == NULL || myname[0] == '\0')
                {
                myname = getlogin();
                if (myname == NULL || myname[0] == '\0')
                {
-                       pw = getpwuid(RealUid);
+                       pw = sm_getpwuid(RealUid);
                        if (pw != NULL)
                                myname = newstr(pw->pw_name);
                }
                        if (pw != NULL)
                                myname = newstr(pw->pw_name);
                }
@@ -773,10 +835,10 @@ username()
                        uid_t uid = RealUid;
 
                        myname = newstr(myname);
                        uid_t uid = RealUid;
 
                        myname = newstr(myname);
-                       if ((pw = getpwnam(myname)) == NULL ||
+                       if ((pw = sm_getpwnam(myname)) == NULL ||
                              (uid != 0 && uid != pw->pw_uid))
                        {
                              (uid != 0 && uid != pw->pw_uid))
                        {
-                               pw = getpwuid(uid);
+                               pw = sm_getpwuid(uid);
                                if (pw != NULL)
                                        myname = newstr(pw->pw_name);
                        }
                                if (pw != NULL)
                                        myname = newstr(pw->pw_name);
                        }
@@ -853,11 +915,14 @@ ttypath()
 **     forwarding or registration of users.
 **
 **     If the hosts are found to be incompatible, an error
 **     forwarding or registration of users.
 **
 **     If the hosts are found to be incompatible, an error
-**     message should be given using "usrerr" and 0 should
-**     be returned.
+**     message should be given using "usrerr" and an EX_ code
+**     should be returned.  You can also set to->q_status to
+**     a DSN-style status code.
 **
 **
-**     EF_NORETURN can be set in e->e_flags to suppress the return-to-sender
-**     function; this should be done on huge messages.
+**     EF_NO_BODY_RETN can be set in e->e_flags to suppress the
+**     body during the return-to-sender function; this should be done
+**     on huge messages.  This bit may already be set by the ESMTP
+**     protocol.
 **
 **     Parameters:
 **             to -- the person being sent to.
 **
 **     Parameters:
 **             to -- the person being sent to.
@@ -892,7 +957,8 @@ checkcompat(to, e)
            to->q_mailer == s->s_mailer)
        {
                usrerr("553 No ARPA mail through this machine: see your system administration");
            to->q_mailer == s->s_mailer)
        {
                usrerr("553 No ARPA mail through this machine: see your system administration");
-               /* e->e_flags |= EF_NORETURN; to supress return copy */
+               /* e->e_flags |= EF_NO_BODY_RETN; to supress body on return */
+               to->q_status = "5.7.1";
                return (EX_UNAVAILABLE);
        }
 # endif /* EXAMPLE_CODE */
                return (EX_UNAVAILABLE);
        }
 # endif /* EXAMPLE_CODE */
@@ -909,7 +975,7 @@ setsignal(sig, handler)
        int sig;
        sigfunc_t handler;
 {
        int sig;
        sigfunc_t handler;
 {
-#if defined(SYS5SIGNALS) || defined(BSD4_3) || defined(_AUX_SOURCE)
+#if defined(SYS5SIGNALS) || defined(BSD4_3)
        return signal(sig, handler);
 #else
        struct sigaction n, o;
        return signal(sig, handler);
 #else
        struct sigaction n, o;
@@ -925,6 +991,31 @@ setsignal(sig, handler)
 #endif
 }
 \f/*
 #endif
 }
 \f/*
+**  RELEASESIGNAL -- release a held signal
+**
+**     Parameters:
+**             sig -- the signal to release.
+**
+**     Returns:
+**             0 on success.
+**             -1 on failure.
+*/
+
+int
+releasesignal(sig)
+       int sig;
+{
+#ifdef BSD4_3
+       return sigsetmask(sigblock(0) & ~(1 << sig));
+#else
+       sigset_t sset;
+
+       sigemptyset(&sset);
+       sigaddset(&sset, sig);
+       return sigprocmask(SIG_UNBLOCK, &sset, NULL);
+#endif
+}
+\f/*
 **  HOLDSIGS -- arrange to hold all signals
 **
 **     Parameters:
 **  HOLDSIGS -- arrange to hold all signals
 **
 **     Parameters:
@@ -987,6 +1078,26 @@ init_md(argc, argv)
 #endif
 }
 \f/*
 #endif
 }
 \f/*
+**  INIT_VENDOR_MACROS -- vendor-dependent macro initializations
+**
+**     Called once, on startup.
+**
+**     Parameters:
+**             e -- the global envelope.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             vendor-dependent.
+*/
+
+void
+init_vendor_macros(e)
+       register ENVELOPE *e;
+{
+}
+\f/*
 **  GETLA -- get the current load average
 **
 **     This code stolen from la.c.
 **  GETLA -- get the current load average
 **
 **     This code stolen from la.c.
@@ -1009,18 +1120,35 @@ init_md(argc, argv)
 #define LA_MACH                5       /* MACH load averages (as on NeXT boxes) */
 #define LA_SHORT       6       /* read kmem for avenrun; interpret as short */
 #define LA_PROCSTR     7       /* read string ("1.17") from /proc/loadavg */
 #define LA_MACH                5       /* MACH load averages (as on NeXT boxes) */
 #define LA_SHORT       6       /* read kmem for avenrun; interpret as short */
 #define LA_PROCSTR     7       /* read string ("1.17") from /proc/loadavg */
+#define LA_READKSYM    8       /* SVR4: use MIOC_READKSYM ioctl call */
+#define LA_DGUX                9       /* special DGUX implementation */
+#define LA_HPUX                10      /* special HPUX implementation */
 
 /* do guesses based on general OS type */
 #ifndef LA_TYPE
 # define LA_TYPE       LA_ZERO
 #endif
 
 
 /* do guesses based on general OS type */
 #ifndef LA_TYPE
 # define LA_TYPE       LA_ZERO
 #endif
 
-#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
+#ifndef FSHIFT
+# if defined(unixpc)
+#  define FSHIFT       5
+# endif
 
 
-#include <nlist.h>
+# if defined(__alpha) || defined(IRIX)
+#  define FSHIFT       10
+# endif
 
 
-#ifdef IRIX64
-# define nlist         nlist64
+# if defined(_AIX3)
+#  define FSHIFT       16
+# endif
+#endif
+
+#ifndef FSHIFT
+# define FSHIFT                8
+#endif
+
+#ifndef FSCALE
+# define FSCALE                (1 << FSHIFT)
 #endif
 
 #ifndef LA_AVENRUN
 #endif
 
 #ifndef LA_AVENRUN
@@ -1031,6 +1159,14 @@ init_md(argc, argv)
 # endif
 #endif
 
 # endif
 #endif
 
+#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
+
+#include <nlist.h>
+
+#ifdef IRIX64
+# define nlist         nlist64
+#endif
+
 /* _PATH_UNIX should be defined in <paths.h> */
 #ifndef _PATH_UNIX
 # if defined(SYSTEM5)
 /* _PATH_UNIX should be defined in <paths.h> */
 #ifndef _PATH_UNIX
 # if defined(SYSTEM5)
@@ -1040,34 +1176,16 @@ init_md(argc, argv)
 # endif
 #endif
 
 # endif
 #endif
 
-struct nlist Nl[] =
+#ifdef _AUX_SOURCE
+struct nlist   Nl[2];
+#else
+struct nlist   Nl[] =
 {
        { LA_AVENRUN },
 {
        { LA_AVENRUN },
-#define        X_AVENRUN       0
        { 0 },
 };
        { 0 },
 };
-
-#ifndef FSHIFT
-# if defined(unixpc)
-#  define FSHIFT       5
-# endif
-
-# if defined(__alpha) || defined(IRIX)
-#  define FSHIFT       10
-# endif
-
-# if defined(_AIX3)
-#  define FSHIFT       16
-# endif
-#endif
-
-#ifndef FSHIFT
-# define FSHIFT                8
-#endif
-
-#ifndef FSCALE
-# define FSCALE                (1 << FSHIFT)
 #endif
 #endif
+#define        X_AVENRUN       0
 
 getla()
 {
 
 getla()
 {
@@ -1081,8 +1199,8 @@ getla()
        double avenrun[3];
 # endif
 #endif
        double avenrun[3];
 # endif
 #endif
-       extern off_t lseek();
        extern int errno;
        extern int errno;
+       extern off_t lseek();
 
        if (kmem < 0)
        {
 
        if (kmem < 0)
        {
@@ -1095,6 +1213,11 @@ getla()
                        return (-1);
                }
                (void) fcntl(kmem, F_SETFD, 1);
                        return (-1);
                }
                (void) fcntl(kmem, F_SETFD, 1);
+
+#ifdef _AUX_SOURCE
+               strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN);
+#endif
+
 #ifdef _AIX3
                if (knlist(Nl, 1, sizeof Nl[0]) < 0)
 #else
 #ifdef _AIX3
                if (knlist(Nl, 1, sizeof Nl[0]) < 0)
 #else
@@ -1127,7 +1250,7 @@ getla()
                        printf("getla: lseek or read: %s\n", errstring(errno));
                return (-1);
        }
                        printf("getla: lseek or read: %s\n", errstring(errno));
                return (-1);
        }
-#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
+# if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
        if (tTd(3, 5))
        {
                printf("getla: avenrun = %d", avenrun[0]);
        if (tTd(3, 5))
        {
                printf("getla: avenrun = %d", avenrun[0]);
@@ -1138,7 +1261,7 @@ getla()
        if (tTd(3, 1))
                printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
        return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
        if (tTd(3, 1))
                printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
        return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
-#else
+# else /* LA_TYPE == LA_FLOAT */
        if (tTd(3, 5))
        {
                printf("getla: avenrun = %g", avenrun[0]);
        if (tTd(3, 5))
        {
                printf("getla: avenrun = %g", avenrun[0]);
@@ -1149,15 +1272,61 @@ getla()
        if (tTd(3, 1))
                printf("getla: %d\n", (int) (avenrun[0] +0.5));
        return ((int) (avenrun[0] + 0.5));
        if (tTd(3, 1))
                printf("getla: %d\n", (int) (avenrun[0] +0.5));
        return ((int) (avenrun[0] + 0.5));
-#endif
+# endif
 }
 
 }
 
-#else
-#if LA_TYPE == LA_SUBR
+#endif /* LA_TYPE == LA_INT or LA_SHORT or LA_FLOAT */
+
+#if LA_TYPE == LA_READKSYM
+
+# include <sys/ksym.h>
+
+getla()
+{
+       static int kmem = -1;
+       long avenrun[3];
+       extern int errno;
+       struct mioc_rksym mirk;
+
+       if (kmem < 0)
+       {
+               kmem = open("/dev/kmem", 0, 0);
+               if (kmem < 0)
+               {
+                       if (tTd(3, 1))
+                               printf("getla: open(/dev/kmem): %s\n",
+                                       errstring(errno));
+                       return (-1);
+               }
+               (void) fcntl(kmem, F_SETFD, 1);
+       }
+       mirk.mirk_symname = LA_AVENRUN;
+       mirk.mirk_buf = avenrun;
+       mirk.mirk_buflen = sizeof(avenrun);
+       if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
+       {
+               if (tTd(3, 1))
+                       printf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
+                               errstring(errno));
+               return -1;
+       }
+       if (tTd(3, 5))
+       {
+               printf("getla: avenrun = %d", avenrun[0]);
+               if (tTd(3, 15))
+                       printf(", %d, %d", avenrun[1], avenrun[2]);
+               printf("\n");
+       }
+       if (tTd(3, 1))
+               printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+       return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+}
+
+#endif /* LA_TYPE == LA_READKSYM */
 
 
-#ifdef DGUX
+#if LA_TYPE == LA_DGUX
 
 
-#include <sys/dg_sys_info.h>
+# include <sys/dg_sys_info.h>
 
 int
 getla()
 
 int
 getla()
@@ -1173,11 +1342,22 @@ getla()
        return((int) (load_info.one_minute + 0.5));
 }
 
        return((int) (load_info.one_minute + 0.5));
 }
 
-#else
-# ifdef __hpux
+#endif /* LA_TYPE == LA_DGUX */
 
 
-#  include <sys/param.h>
-#  include <sys/pstat.h>
+#if LA_TYPE == LA_HPUX
+
+/* forward declarations to keep gcc from complaining */
+struct pst_dynamic;
+struct pst_status;
+struct pst_static;
+struct pst_vminfo;
+struct pst_diskinfo;
+struct pst_processor;
+struct pst_lv;
+struct pst_swapinfo;
+
+# include <sys/param.h>
+# include <sys/pstat.h>
 
 int
 getla()
 
 int
 getla()
@@ -1185,7 +1365,7 @@ getla()
        struct pst_dynamic pstd;
 
        if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
        struct pst_dynamic pstd;
 
        if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
-                            (size_t) 1 ,0) == -1)
+                            (size_t) 10) == -1)
                return 0;
 
         if (tTd(3, 1))
                return 0;
 
         if (tTd(3, 1))
@@ -1194,7 +1374,9 @@ getla()
        return (int) (pstd.psd_avg_1_min + 0.5);
 }
 
        return (int) (pstd.psd_avg_1_min + 0.5);
 }
 
-# else
+#endif /* LA_TYPE == LA_HPUX */
+
+#if LA_TYPE == LA_SUBR
 
 int
 getla()
 
 int
 getla()
@@ -1212,9 +1394,8 @@ getla()
        return ((int) (avenrun[0] + 0.5));
 }
 
        return ((int) (avenrun[0] + 0.5));
 }
 
-# endif /* __hpux */
-#endif /* DGUX */
-#else
+#endif /* LA_TYPE == LA_SUBR */
+
 #if LA_TYPE == LA_MACH
 
 /*
 #if LA_TYPE == LA_MACH
 
 /*
@@ -1248,8 +1429,8 @@ getla()
        return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
 }
 
        return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
 }
 
+#endif /* LA_TYPE == LA_MACH */
 
 
-#else
 #if LA_TYPE == LA_PROCSTR
 
 /*
 #if LA_TYPE == LA_PROCSTR
 
 /*
@@ -1272,7 +1453,7 @@ getla()
        FILE *fp;
 
        fp = fopen(_PATH_LOADAVG, "r");
        FILE *fp;
 
        fp = fopen(_PATH_LOADAVG, "r");
-       if (fp == NULL) 
+       if (fp == NULL)
        {
                if (tTd(3, 1))
                        printf("getla: fopen(%s): %s\n",
        {
                if (tTd(3, 1))
                        printf("getla: fopen(%s): %s\n",
@@ -1295,7 +1476,9 @@ getla()
        return ((int) (avenrun + 0.5));
 }
 
        return ((int) (avenrun + 0.5));
 }
 
-#else
+#endif /* LA_TYPE == LA_PROCSTR */
+
+#if LA_TYPE == LA_ZERO
 
 getla()
 {
 
 getla()
 {
@@ -1304,10 +1487,7 @@ getla()
        return (0);
 }
 
        return (0);
 }
 
-#endif
-#endif
-#endif
-#endif
+#endif /* LA_TYPE == LA_ZERO */
 
 
 /*
 
 
 /*
@@ -1411,30 +1591,45 @@ shouldqueue(pri, ctime)
 **             FALSE if we should accept new work.
 **
 **     Side Effects:
 **             FALSE if we should accept new work.
 **
 **     Side Effects:
-**             none.
+**             Sets process title when it is rejecting connections.
 */
 
 bool
 refuseconnections()
 {
 */
 
 bool
 refuseconnections()
 {
-       extern bool enoughspace();
+       extern bool enoughdiskspace();
+       extern void setproctitle __P((char *, ...));
 
 #ifdef XLA
        if (!xla_smtp_ok())
                return TRUE;
 #endif
 
 
 #ifdef XLA
        if (!xla_smtp_ok())
                return TRUE;
 #endif
 
-       /* this is probably too simplistic */
-       return CurrentLA >= RefuseLA || !enoughspace(MinBlocksFree + 1);
+       if (CurrentLA >= RefuseLA)
+       {
+               setproctitle("rejecting connections: load average: %d",
+                       CurrentLA);
+       }
+       else if (!enoughdiskspace(MinBlocksFree + 1))
+       {
+               setproctitle("rejecting connections: min free: %d",
+                       MinBlocksFree);
+       }
+       else if (MaxChildren > 0 && CurChildren >= MaxChildren)
+       {
+               setproctitle("rejecting connections: maximum children: %d",
+                       CurChildren);
+       }
+       else
+               return FALSE;
+       return TRUE;
 }
 \f/*
 **  SETPROCTITLE -- set process title for ps
 **
 **     Parameters:
 }
 \f/*
 **  SETPROCTITLE -- set process title for ps
 **
 **     Parameters:
-**             fmt -- a printf style format string.  If NULL, the first
-**                     parameter is a literal proctitle previously
-**                     returned by getproctitle.
-**             va_alist -- possible parameters to fmt.
+**             fmt -- a printf style format string.
+**             a, b, c -- possible parameters to fmt.
 **
 **     Returns:
 **             none.
 **
 **     Returns:
 **             none.
@@ -1449,7 +1644,7 @@ refuseconnections()
 #define SPT_BUILTIN    2       /* use libc builtin */
 #define SPT_PSTAT      3       /* use pstat(PSTAT_SETCMD, ...) */
 #define SPT_PSSTRINGS  4       /* use PS_STRINGS->... */
 #define SPT_BUILTIN    2       /* use libc builtin */
 #define SPT_PSTAT      3       /* use pstat(PSTAT_SETCMD, ...) */
 #define SPT_PSSTRINGS  4       /* use PS_STRINGS->... */
-#define SPT_WRITEUDOT  5       /* write u. area in kmem */
+#define SPT_SYSMIPS    5       /* use sysmips() supported by NEWS-OS 6 */
 
 #ifndef SPT_TYPE
 # define SPT_TYPE      SPT_REUSEARGV
 
 #ifndef SPT_TYPE
 # define SPT_TYPE      SPT_REUSEARGV
@@ -1466,6 +1661,11 @@ refuseconnections()
 #  ifndef PS_STRINGS   /* hmmmm....  apparently not available after all */
 #   undef SPT_TYPE
 #   define SPT_TYPE    SPT_REUSEARGV
 #  ifndef PS_STRINGS   /* hmmmm....  apparently not available after all */
 #   undef SPT_TYPE
 #   define SPT_TYPE    SPT_REUSEARGV
+#  else
+#   ifndef NKPDE                       /* FreeBSD 2.0 */
+#    define NKPDE 63
+typedef unsigned int   *pt_entry_t;
+#   endif
 #  endif
 # endif
 
 #  endif
 # endif
 
@@ -1475,6 +1675,11 @@ refuseconnections()
 #  define SETPROC_STATIC
 # endif
 
 #  define SETPROC_STATIC
 # endif
 
+# if SPT_TYPE == SPT_SYSMIPS
+#  include <sys/sysmips.h>
+#  include <sys/sysnews.h>
+# endif
+
 # ifndef SPT_PADCHAR
 #  define SPT_PADCHAR  ' '
 # endif
 # ifndef SPT_PADCHAR
 #  define SPT_PADCHAR  ' '
 # endif
@@ -1483,8 +1688,6 @@ refuseconnections()
 
 #if SPT_TYPE != SPT_BUILTIN
 
 
 #if SPT_TYPE != SPT_BUILTIN
 
-char   ProcTitleBuf[MAXLINE];
-
 /*VARARGS1*/
 void
 # ifdef __STDC__
 /*VARARGS1*/
 void
 # ifdef __STDC__
@@ -1498,45 +1701,52 @@ setproctitle(fmt, va_alist)
 # if SPT_TYPE != SPT_NONE
        register char *p;
        register int i;
 # if SPT_TYPE != SPT_NONE
        register char *p;
        register int i;
+       SETPROC_STATIC char buf[MAXLINE];
        VA_LOCAL_DECL
 #  if SPT_TYPE == SPT_PSTAT
        union pstun pst;
 #  endif
        VA_LOCAL_DECL
 #  if SPT_TYPE == SPT_PSTAT
        union pstun pst;
 #  endif
+#  if SPT_TYPE == SPT_REUSEARGV
        extern char **Argv;
        extern char *LastArgv;
        extern char **Argv;
        extern char *LastArgv;
+#  endif
 
 
-       VA_START(fmt);
-       if (fmt == NULL)
-       {
-               /* restore old proctitle */
-               (void) strcpy(ProcTitleBuf, va_arg(ap, char *));
-       }
-       else
-       {
-               p = ProcTitleBuf;
+       p = buf;
 
 
-               /* print sendmail: heading for grep */
-               (void) strcpy(p, "sendmail: ");
-               p += strlen(p);
+       /* print sendmail: heading for grep */
+       (void) strcpy(p, "sendmail: ");
+       p += strlen(p);
 
 
-               /* print the argument string */
-               (void) vsprintf(p, fmt, ap);
-       }
+       /* print the argument string */
+       VA_START(fmt);
+       (void) vsprintf(p, fmt, ap);
        VA_END;
 
        VA_END;
 
-       i = strlen(ProcTitleBuf);
+       i = strlen(buf);
+
+#  if SPT_TYPE == SPT_PSTAT
+       pst.pst_command = buf;
+       pstat(PSTAT_SETCMD, pst, i, 0, 0);
+#  endif
+#  if SPT_TYPE == SPT_PSSTRINGS
+       PS_STRINGS->ps_nargvstr = 1;
+       PS_STRINGS->ps_argvstr = buf;
+#  endif
+#  if SPT_TYPE == SPT_SYSMIPS
+       sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
+#  endif
+#  if SPT_TYPE == SPT_REUSEARGV
        if (i > LastArgv - Argv[0] - 2)
        {
                i = LastArgv - Argv[0] - 2;
        if (i > LastArgv - Argv[0] - 2)
        {
                i = LastArgv - Argv[0] - 2;
-               ProcTitleBuf[i] = '\0';
+               buf[i] = '\0';
        }
        }
-       (void) strcpy(Argv[0], ProcTitleBuf);
+       (void) strcpy(Argv[0], buf);
        p = &Argv[0][i];
        while (p < LastArgv)
                *p++ = SPT_PADCHAR;
        Argv[1] = NULL;
        p = &Argv[0][i];
        while (p < LastArgv)
                *p++ = SPT_PADCHAR;
        Argv[1] = NULL;
-#   endif /* SPT_TYPE == SPT_PSSTRINGS */
-#  endif /* SPT_TYPE == SPT_PSTAT */
+#  endif
 # endif /* SPT_TYPE != SPT_NONE */
 }
 
 # endif /* SPT_TYPE != SPT_NONE */
 }
 
@@ -1575,18 +1785,19 @@ reapchild(sig)
 #endif
                        break;
                }
 #endif
                        break;
                }
+               CurChildren--;
        }
 # else
 # ifdef WNOHANG
        union wait status;
 
        while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
        }
 # else
 # ifdef WNOHANG
        union wait status;
 
        while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
-               continue;
+               CurChildren--;
 # else /* WNOHANG */
        auto int status;
 
        while (wait(&status) > 0)
 # else /* WNOHANG */
        auto int status;
 
        while (wait(&status) > 0)
-               continue;
+               CurChildren--;
 # endif /* WNOHANG */
 # endif
 # ifdef SYS5SIGNALS
 # endif /* WNOHANG */
 # endif
 # ifdef SYS5SIGNALS
@@ -1595,6 +1806,107 @@ reapchild(sig)
        errno = olderrno;
 }
 \f/*
        errno = olderrno;
 }
 \f/*
+**  PUTENV -- emulation of putenv() in terms of setenv()
+**
+**     Not needed on Posix-compliant systems.
+**     This doesn't have full Posix semantics, but it's good enough
+**             for sendmail.
+**
+**     Parameter:
+**             env -- the environment to put.
+**
+**     Returns:
+**             none.
+*/
+
+#ifdef NEEDPUTENV
+
+# if NEEDPUTENV == 2           /* no setenv(3) call available */
+
+int
+putenv(str)
+       char *str;
+{
+       char **current;
+       int matchlen, envlen=0;
+       char *tmp;
+       char **newenv;
+       static int first=1;
+       extern char **environ;
+
+       /*
+        * find out how much of str to match when searching
+        * for a string to replace.
+        */
+       if ((tmp = index(str, '=')) == NULL || tmp == str)
+               matchlen = strlen(str);
+       else
+               matchlen = (int) (tmp - str);
+       ++matchlen;
+
+       /*
+        * Search for an existing string in the environment and find the
+        * length of environ.  If found, replace and exit.
+        */
+       for (current=environ; *current; current++) {
+               ++envlen;
+
+               if (strncmp(str, *current, matchlen) == 0) {
+                       /* found it, now insert the new version */
+                       *current = (char *)str;
+                       return(0);
+               }
+       }
+
+       /*
+        * There wasn't already a slot so add space for a new slot.
+        * If this is our first time through, use malloc(), else realloc().
+        */
+       if (first) {
+               newenv = (char **) malloc(sizeof(char *) * (envlen + 2));
+               if (newenv == NULL)
+                       return(-1);
+
+               first=0;
+               (void) memcpy(newenv, environ, sizeof(char *) * envlen);
+       } else {
+               newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2));
+               if (newenv == NULL)
+                       return(-1);
+       }
+
+       /* actually add in the new entry */
+       environ = newenv;
+       environ[envlen] = (char *)str;
+       environ[envlen+1] = NULL;
+
+       return(0);
+}
+
+#else                  /* implement putenv() in terms of setenv() */
+
+int
+putenv(env)
+       char *env;
+{
+       char *p;
+       int l;
+       char nbuf[100];
+
+       p = strchr(env, '=');
+       if (p == NULL)
+               return 0;
+       l = p - env;
+       if (l > sizeof nbuf - 1)
+               l = sizeof nbuf - 1;
+       bcopy(env, nbuf, l);
+       nbuf[l] = '\0';
+       return setenv(nbuf, ++p, 1);
+}
+
+# endif
+#endif
+\f/*
 **  UNSETENV -- remove a variable from the environment
 **
 **     Not needed on newer systems.
 **  UNSETENV -- remove a variable from the environment
 **
 **     Not needed on newer systems.
@@ -1732,7 +2044,7 @@ uname(name)
                        return (0);
        }
 #endif
                        return (0);
        }
 #endif
-       
+
        return (-1);
 }
 #endif /* HASUNAME */
        return (-1);
 }
 #endif /* HASUNAME */
@@ -1848,13 +2160,14 @@ static char sccsid[] = "@(#)getopt.c    4.3 (Berkeley) 3/9/86";
  * get option letter from argument vector
  */
 #ifdef _CONVEX_SOURCE
  * get option letter from argument vector
  */
 #ifdef _CONVEX_SOURCE
-extern int     optind, opterr;
+extern int     optind, opterr, optopt;
+extern char    *optarg;
 #else
 int    opterr = 1;             /* if error message should be printed */
 int    optind = 1;             /* index into parent argv vector */
 #else
 int    opterr = 1;             /* if error message should be printed */
 int    optind = 1;             /* index into parent argv vector */
+int    optopt = 0;             /* character checked for validity */
+char   *optarg = NULL;         /* argument associated with option */
 #endif
 #endif
-int    optopt;                 /* character checked for validity */
-char   *optarg;                /* argument associated with option */
 
 #define BADCH  (int)'?'
 #define EMSG   ""
 
 #define BADCH  (int)'?'
 #define EMSG   ""
@@ -1952,6 +2265,7 @@ vsprintf(s, fmt, ap)
 **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
 **
 **     Parameters:
 **  USERSHELLOK -- tell if a user's shell is ok for unrestricted use
 **
 **     Parameters:
+**             user -- the name of the user we are checking.
 **             shell -- the user's shell from /etc/passwd
 **
 **     Returns:
 **             shell -- the user's shell from /etc/passwd
 **
 **     Returns:
@@ -1965,6 +2279,11 @@ vsprintf(s, fmt, ap)
 #  define _PATH_SHELLS "/etc/shells"
 # endif
 
 #  define _PATH_SHELLS "/etc/shells"
 # endif
 
+# ifdef _AIX3
+#  include <userconf.h>
+#  include <usersec.h>
+# endif
+
 char   *DefaultUserShells[] =
 {
        "/bin/sh",              /* standard shell */
 char   *DefaultUserShells[] =
 {
        "/bin/sh",              /* standard shell */
@@ -1972,12 +2291,21 @@ char    *DefaultUserShells[] =
        "/bin/csh",             /* C shell */
        "/usr/bin/csh",
 #ifdef __hpux
        "/bin/csh",             /* C shell */
        "/usr/bin/csh",
 #ifdef __hpux
+# ifdef V4FS
+       "/usr/bin/rsh",         /* restricted Bourne shell */
+       "/usr/bin/ksh",         /* Korn shell */
+       "/usr/bin/rksh",        /* restricted Korn shell */
+       "/usr/bin/pam",
+       "/usr/bin/keysh",       /* key shell (extended Korn shell) */
+       "/usr/bin/posix/sh",
+# else
        "/bin/rsh",             /* restricted Bourne shell */
        "/bin/ksh",             /* Korn shell */
        "/bin/rksh",            /* restricted Korn shell */
        "/bin/pam",
        "/usr/bin/keysh",       /* key shell (extended Korn shell) */
        "/bin/posix/sh",
        "/bin/rsh",             /* restricted Bourne shell */
        "/bin/ksh",             /* Korn shell */
        "/bin/rksh",            /* restricted Korn shell */
        "/bin/pam",
        "/usr/bin/keysh",       /* key shell (extended Korn shell) */
        "/bin/posix/sh",
+# endif
 #endif
 #ifdef _AIX3
        "/bin/ksh",             /* Korn shell */
 #endif
 #ifdef _AIX3
        "/bin/ksh",             /* Korn shell */
@@ -1995,14 +2323,16 @@ char    *DefaultUserShells[] =
 #define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/"
 
 bool
 #define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/"
 
 bool
-usershellok(shell)
+usershellok(user, shell)
+       char *user;
        char *shell;
 {
 #if HASGETUSERSHELL
        register char *p;
        extern char *getusershell();
 
        char *shell;
 {
 #if HASGETUSERSHELL
        register char *p;
        extern char *getusershell();
 
-       if (shell == NULL || shell[0] == '\0')
+       if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
+           ConfigLevel <= 1)
                return TRUE;
 
        setusershell();
                return TRUE;
 
        setusershell();
@@ -2012,12 +2342,41 @@ usershellok(shell)
        endusershell();
        return p != NULL;
 #else
        endusershell();
        return p != NULL;
 #else
+# if USEGETCONFATTR
+       auto char *v;
+# endif
        register FILE *shellf;
        char buf[MAXLINE];
 
        register FILE *shellf;
        char buf[MAXLINE];
 
-       if (shell == NULL || shell[0] == '\0')
+       if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't'))
                return TRUE;
 
                return TRUE;
 
+# if USEGETCONFATTR
+       /*
+       **  Naturally IBM has a "better" idea.....
+       **
+       **      What a crock.  This interface isn't documented, it is
+       **      considered part of the security library (-ls), and it
+       **      only works if you are running as root (since the list
+       **      of valid shells is obviously a source of great concern).
+       **      I recommend that you do NOT define USEGETCONFATTR,
+       **      especially since you are going to have to set up an
+       **      /etc/shells anyhow to handle the cases where getconfattr
+       **      fails.
+       */
+
+       if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
+       {
+               while (*v != '\0')
+               {
+                       if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
+                               return TRUE;
+                       v += strlen(v) + 1;
+               }
+               return FALSE;
+       }
+# endif
+
        shellf = fopen(_PATH_SHELLS, "r");
        if (shellf == NULL)
        {
        shellf = fopen(_PATH_SHELLS, "r");
        if (shellf == NULL)
        {
@@ -2056,7 +2415,7 @@ usershellok(shell)
 #endif
 }
 \f/*
 #endif
 }
 \f/*
-**  FREESPACE -- see how much free space is on the queue filesystem
+**  FREEDISKSPACE -- see how much free space is on the queue filesystem
 **
 **     Only implemented if you have statfs.
 **
 **
 **     Only implemented if you have statfs.
 **
@@ -2103,7 +2462,7 @@ usershellok(shell)
 #endif
 
 long
 #endif
 
 long
-freespace(dir, bsize)
+freediskspace(dir, bsize)
        char *dir;
        long *bsize;
 {
        char *dir;
        long *bsize;
 {
@@ -2112,11 +2471,11 @@ freespace(dir, bsize)
        struct ustat fs;
        struct stat statbuf;
 #  define FSBLOCKSIZE  DEV_BSIZE
        struct ustat fs;
        struct stat statbuf;
 #  define FSBLOCKSIZE  DEV_BSIZE
-#  define FSF_BAVAIL   f_tfree
+#  define SFS_BAVAIL   f_tfree
 # else
 #  if defined(ultrix)
        struct fs_data fs;
 # else
 #  if defined(ultrix)
        struct fs_data fs;
-#   define FSF_BAVAIL  fd_bfreen
+#   define SFS_BAVAIL  fd_bfreen
 #   define FSBLOCKSIZE 1024L
 #  else
 #   if SFS_TYPE == SFS_STATVFS
 #   define FSBLOCKSIZE 1024L
 #  else
 #   if SFS_TYPE == SFS_STATVFS
@@ -2128,8 +2487,8 @@ freespace(dir, bsize)
 #   endif
 #  endif
 # endif
 #   endif
 #  endif
 # endif
-# ifndef FSF_BAVAIL
-#  define FSF_BAVAIL f_bavail
+# ifndef SFS_BAVAIL
+#  define SFS_BAVAIL f_bavail
 # endif
 
 # if SFS_TYPE == SFS_USTAT
 # endif
 
 # if SFS_TYPE == SFS_USTAT
@@ -2152,13 +2511,13 @@ freespace(dir, bsize)
        {
                if (bsize != NULL)
                        *bsize = FSBLOCKSIZE;
        {
                if (bsize != NULL)
                        *bsize = FSBLOCKSIZE;
-               return (fs.FSF_BAVAIL);
+               return (fs.SFS_BAVAIL);
        }
 #endif
        return (-1);
 }
 \f/*
        }
 #endif
        return (-1);
 }
 \f/*
-**  ENOUGHSPACE -- check to see if there is enough free space on the queue fs
+**  ENOUGHDISKSPACE -- is there enough free space on the queue fs?
 **
 **     Only implemented if you have statfs.
 **
 **
 **     Only implemented if you have statfs.
 **
@@ -2173,7 +2532,7 @@ freespace(dir, bsize)
 */
 
 bool
 */
 
 bool
-enoughspace(msize)
+enoughdiskspace(msize)
        long msize;
 {
        long bfree, bsize;
        long msize;
 {
        long bfree, bsize;
@@ -2181,14 +2540,14 @@ enoughspace(msize)
        if (MinBlocksFree <= 0 && msize <= 0)
        {
                if (tTd(4, 80))
        if (MinBlocksFree <= 0 && msize <= 0)
        {
                if (tTd(4, 80))
-                       printf("enoughspace: no threshold\n");
+                       printf("enoughdiskspace: no threshold\n");
                return TRUE;
        }
 
                return TRUE;
        }
 
-       if ((bfree = freespace(QueueDir, &bsize)) >= 0)
+       if ((bfree = freediskspace(QueueDir, &bsize)) >= 0)
        {
                if (tTd(4, 80))
        {
                if (tTd(4, 80))
-                       printf("enoughspace: bavail=%ld, need=%ld\n",
+                       printf("enoughdiskspace: bavail=%ld, need=%ld\n",
                                bfree, msize);
 
                /* convert msize to block count */
                                bfree, msize);
 
                /* convert msize to block count */
@@ -2211,7 +2570,7 @@ enoughspace(msize)
                }
        }
        else if (tTd(4, 80))
                }
        }
        else if (tTd(4, 80))
-               printf("enoughspace failure: min=%ld, need=%ld: %s\n",
+               printf("enoughdiskspace failure: min=%ld, need=%ld: %s\n",
                        MinBlocksFree, msize, errstring(errno));
        return TRUE;
 }
                        MinBlocksFree, msize, errstring(errno));
        return TRUE;
 }
@@ -2347,7 +2706,7 @@ lockfile(fd, filename, ext, type)
 
        if (ext == NULL)
                ext = "";
 
        if (ext == NULL)
                ext = "";
-               
+
        bzero(&lfd, sizeof lfd);
        if (bitset(LOCK_UN, type))
                lfd.l_type = F_UNLCK;
        bzero(&lfd, sizeof lfd);
        if (bitset(LOCK_UN, type))
                lfd.l_type = F_UNLCK;
@@ -2473,7 +2832,7 @@ chownsafe(fd)
        rval = fchown(tfd, DefUid, DefGid) != 0;
        close(tfd);
        unlink(s);
        rval = fchown(tfd, DefUid, DefGid) != 0;
        close(tfd);
        unlink(s);
-       setreuid(o_uid, o_euid);
+       setresuid(o_uid, o_euid, -1);
        setresgid(o_gid, o_egid, -1);
        return rval;
 #else
        setresgid(o_gid, o_egid, -1);
        return rval;
 #else
@@ -2546,9 +2905,10 @@ resetlimits()
 char *
 getcfname()
 {
 char *
 getcfname()
 {
+
        if (ConfFile != NULL)
                return ConfFile;
        if (ConfFile != NULL)
                return ConfFile;
-#ifdef NETINFO
+#if NETINFO
        {
                extern char *ni_propval();
                char *cflocation;
        {
                extern char *ni_propval();
                char *cflocation;
@@ -2559,6 +2919,7 @@ getcfname()
                        return cflocation;
        }
 #endif
                        return cflocation;
        }
 #endif
+
        return _PATH_SENDMAILCF;
 }
 \f/*
        return _PATH_SENDMAILCF;
 }
 \f/*
@@ -2601,6 +2962,31 @@ setvendor(vendor)
        return FALSE;
 }
 \f/*
        return FALSE;
 }
 \f/*
+**  VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
+**
+**     Vendor_pre_defaults is called before reading the configuration
+**     file; vendor_post_defaults is called immediately after.
+**
+**     Parameters:
+**             e -- the global environment to initialize.
+**
+**     Returns:
+**             none.
+*/
+
+void
+vendor_pre_defaults(e)
+       ENVELOPE *e;
+{
+}
+
+
+void
+vendor_post_defaults(e)
+       ENVELOPE *e;
+{
+}
+\f/*
 **  STRTOL -- convert string to long integer
 **
 **     For systems that don't have it in the C library.
 **  STRTOL -- convert string to long integer
 **
 **     For systems that don't have it in the C library.
@@ -2706,40 +3092,127 @@ strtol(nptr, endptr, base)
 
 #endif
 \f/*
 
 #endif
 \f/*
-**  SOLARIS_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+**  STRSTR -- find first substring in string
 **
 **
-**     Solaris versions at least through 2.3 don't properly deliver a
-**     canonical h_name field.  This tries to work around it.
+**     Parameters:
+**             big -- the big (full) string.
+**             little -- the little (sub) string.
+**
+**     Returns:
+**             A pointer to the first instance of little in big.
+**             big if little is the null string.
+**             NULL if little is not contained in big.
 */
 
 */
 
-#ifdef SOLARIS
+#ifdef NEEDSTRSTR
 
 
-extern int     h_errno;
+char *
+strstr(big, little)
+       char *big;
+       char *little;
+{
+       register char *p = big;
+       int l;
+
+       if (*little == '\0')
+               return big;
+       l = strlen(little);
+
+       while ((p = strchr(p, *little)) != NULL)
+       {
+               if (strncmp(p, little, l) == 0)
+                       return p;
+               p++;
+       }
+       return NULL;
+}
+
+#endif
+\f/*
+**  SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+**
+**     Some operating systems have wierd problems with the gethostbyXXX
+**     routines.  For example, Solaris versions at least through 2.3
+**     don't properly deliver a canonical h_name field.  This tries to
+**     work around these problems.
+*/
 
 struct hostent *
 
 struct hostent *
-solaris_gethostbyname(name)
-       const char *name;
+sm_gethostbyname(name)
+       char *name;
 {
 {
-# ifdef SOLARIS_2_3
+       struct hostent *h;
+#if defined(SOLARIS) && SOLARIS < 204 || defined(sony_news) && defined(__svr4)
+# if SOLARIS == 203
        static struct hostent hp;
        static char buf[1000];
        extern struct hostent *_switch_gethostbyname_r();
 
        static struct hostent hp;
        static char buf[1000];
        extern struct hostent *_switch_gethostbyname_r();
 
-       return _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
+       if (tTd(61, 10))
+               printf("_switch_gethostbyname_r(%s)... ", name);
+       h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
 # else
        extern struct hostent *__switch_gethostbyname();
 
 # else
        extern struct hostent *__switch_gethostbyname();
 
-       return __switch_gethostbyname(name);
+       if (tTd(61, 10))
+               printf("__switch_gethostbyname(%s)... ", name);
+       h = __switch_gethostbyname(name);
 # endif
 # endif
+#else
+       int nmaps;
+       char *maptype[MAXMAPSTACK];
+       short mapreturn[MAXMAPACTIONS];
+       char hbuf[MAXNAME];
+
+       if (tTd(61, 10))
+               printf("gethostbyname(%s)... ", name);
+       h = gethostbyname(name);
+       if (h == NULL)
+       {
+               if (tTd(61, 10))
+                       printf("failure\n");
+
+               nmaps = switch_map_find("hosts", maptype, mapreturn);
+               while (--nmaps >= 0)
+                       if (strcmp(maptype[nmaps], "nis") == 0 ||
+                           strcmp(maptype[nmaps], "files") == 0)
+                               break;
+               if (nmaps >= 0)
+               {
+                       /* try short name */
+                       if (strlen(name) > sizeof hbuf - 1)
+                               return NULL;
+                       strcpy(hbuf, name);
+                       shorten_hostname(hbuf);
+
+                       /* if it hasn't been shortened, there's no point */
+                       if (strcmp(hbuf, name) != 0)
+                       {
+                               if (tTd(61, 10))
+                                       printf("gethostbyname(%s)... ", hbuf);
+                               h = gethostbyname(hbuf);
+                       }
+               }
+       }
+#endif
+       if (tTd(61, 10))
+       {
+               if (h == NULL)
+                       printf("failure\n");
+               else
+                       printf("%s\n", h->h_name);
+       }
+       return h;
 }
 
 struct hostent *
 }
 
 struct hostent *
-solaris_gethostbyaddr(addr, len, type)
-       const char *addr;
+sm_gethostbyaddr(addr, len, type)
+       char *addr;
        int len;
        int type;
 {
        int len;
        int type;
 {
-# ifdef SOLARIS_2_3
+#if defined(SOLARIS) && SOLARIS < 204
+# if SOLARIS == 203
        static struct hostent hp;
        static char buf[1000];
        extern struct hostent *_switch_gethostbyaddr_r();
        static struct hostent hp;
        static char buf[1000];
        extern struct hostent *_switch_gethostbyaddr_r();
@@ -2750,9 +3223,149 @@ solaris_gethostbyaddr(addr, len, type)
 
        return __switch_gethostbyaddr(addr, len, type);
 # endif
 
        return __switch_gethostbyaddr(addr, len, type);
 # endif
+#else
+       return gethostbyaddr(addr, len, type);
+#endif
+}
+\f/*
+**  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
+*/
+
+struct passwd *
+sm_getpwnam(user)
+       char *user;
+{
+       return getpwnam(user);
 }
 
 }
 
+struct passwd *
+sm_getpwuid(uid)
+       UID_T uid;
+{
+       return getpwuid(uid);
+}
+\f/*
+**  LOAD_IF_NAMES -- load interface-specific names into $=w
+**
+**     Parameters:
+**             none.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             Loads $=w with the names of all the interfaces.
+*/
+
+#ifdef SIOCGIFCONF
+struct rtentry;
+struct mbuf;
+# include <arpa/inet.h>
+# include <sys/time.h>
+# include <net/if.h>
+#endif
+
+void
+load_if_names()
+{
+#ifdef SIOCGIFCONF
+       int s;
+       int i;
+        struct ifconf ifc;
+       char interfacebuf[1024];
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s == -1)
+               return;
+
+       /* get the list of known IP address from the kernel */
+        ifc.ifc_buf = interfacebuf;
+        ifc.ifc_len = sizeof interfacebuf;
+       if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
+       {
+               if (tTd(0, 4))
+                       printf("SIOGIFCONF failed: %s\n", errstring(errno));
+               close(s);
+               return;
+       }
+       close(s);
+
+       /* scan the list of IP address */
+       if (tTd(0, 40))
+               printf("scanning for interface specific names, ifc_len=%d\n",
+                       ifc.ifc_len);
+
+       for (i = 0; i < ifc.ifc_len; )
+       {
+               struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
+               struct sockaddr *sa = &ifr->ifr_addr;
+               struct in_addr ia;
+               struct hostent *hp;
+               char ip_addr[256];
+               extern char *inet_ntoa();
+               extern struct hostent *gethostbyaddr();
+
+#ifdef BSD4_4_SOCKADDR
+               if (sa->sa_len > sizeof ifr->ifr_addr)
+                       i += sizeof ifr->ifr_name + sa->sa_len;
+               else
+#endif
+                       i += sizeof *ifr;
+
+               if (tTd(0, 20))
+                       printf("%s\n", anynet_ntoa((SOCKADDR *) sa));
+
+               if (ifr->ifr_addr.sa_family != AF_INET)
+                       continue;
+
+               /* extract IP address from the list*/
+               ia = (((struct sockaddr_in *) sa)->sin_addr);
+
+               /* save IP address in text from */
+               (void) sprintf(ip_addr, "[%s]",
+                       inet_ntoa(((struct sockaddr_in *) sa)->sin_addr));
+               if (!wordinclass(ip_addr, 'w'))
+               {
+                       setclass('w', ip_addr);
+                       if (tTd(0, 4))
+                               printf("\ta.k.a.: %s\n", ip_addr);
+               }
+
+               /* skip "loopback" interface "lo" */
+               if (strcmp("lo0", ifr->ifr_name) == 0)
+                       continue;
+
+               /* lookup name with IP address */
+               hp = sm_gethostbyaddr((char *) &ia, sizeof(ia), AF_INET);
+               if (hp == NULL)
+               {
+                       syslog(LOG_CRIT, "gethostbyaddr() failed for %s\n",
+                               inet_ntoa(ia));
+                       continue;
+               }
+
+               /* save its cname */
+               if (!wordinclass(hp->h_name, 'w'))
+               {
+                       setclass('w', hp->h_name);
+                       if (tTd(0, 4))
+                               printf("\ta.k.a.: %s\n", hp->h_name);
+               }
+
+               /* save all it aliases name */
+               while (*hp->h_aliases)
+               {
+                       if (!wordinclass(*hp->h_aliases, 'w'))
+                       {
+                               setclass('w', *hp->h_aliases);
+                               if (tTd(0, 4))
+                               printf("\ta.k.a.: %s\n", *hp->h_aliases);
+                       }
+                       hp->h_aliases++;
+               }
+       }
 #endif
 #endif
+}
 \f/*
 **  NI_PROPVAL -- netinfo property value lookup routine
 **
 \f/*
 **  NI_PROPVAL -- netinfo property value lookup routine
 **
@@ -2784,7 +3397,7 @@ solaris_gethostbyaddr(addr, len, type)
 **             Caller should free the return value of ni_proval
 */
 
 **             Caller should free the return value of ni_proval
 */
 
-#ifdef NETINFO
+#if NETINFO
 
 # include <netinfo/ni.h>
 
 
 # include <netinfo/ni.h>
 
@@ -2892,7 +3505,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
                        continue;
                }
 
                        continue;
                }
 
-               /* 
+               /*
                **  Calculate number of bytes needed and build result
                */
 
                **  Calculate number of bytes needed and build result
                */
 
@@ -2905,7 +3518,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
                        strcpy(p, ninl.ni_namelist_val[j]);
                        p += strlen(p);
                        *p++ = sepchar;
                        strcpy(p, ninl.ni_namelist_val[j]);
                        p += strlen(p);
                        *p++ = sepchar;
-               } 
+               }
                *--p = '\0';
 
                ni_namelist_free(&ninl);
                *--p = '\0';
 
                ni_namelist_free(&ninl);
@@ -2937,6 +3550,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
 # undef syslog
 
 # ifdef __STDC__
 # undef syslog
 
 # ifdef __STDC__
+void
 hard_syslog(int pri, char *msg, ...)
 # else
 hard_syslog(pri, msg, va_alist)
 hard_syslog(int pri, char *msg, ...)
 # else
 hard_syslog(pri, msg, va_alist)
@@ -2958,3 +3572,149 @@ hard_syslog(pri, msg, va_alist)
 }
 
 #endif
 }
 
 #endif
+\f/*
+**  LOCAL_HOSTNAME_LENGTH
+**
+**     This is required to get sendmail to compile against BIND 4.9.x
+**     on Ultrix.
+*/
+
+#if defined(ultrix) && NAMED_BIND
+
+# include <resolv.h>
+# if __RES >= 19931104
+
+int
+local_hostname_length(hostname)
+       char *hostname;
+{
+       int len_host, len_domain;
+
+       if (!*_res.defdname)
+               res_init();
+       len_host = strlen(hostname);
+       len_domain = strlen(_res.defdname);
+       if (len_host > len_domain &&
+           (strcasecmp(hostname + len_host - len_domain,_res.defdname) == 0) &&
+           hostname[len_host - len_domain - 1] == '.')
+               return len_host - len_domain - 1;
+       else
+               return 0;
+}
+
+# endif
+#endif
+\f/*
+**  Compile-Time options
+*/
+
+char   *CompileOptions[] =
+{
+#if HESIOD
+       "HESIOD",
+#endif
+#ifdef LOG
+       "LOG",
+#endif
+#if MATCHGECOS
+       "MATCHGECOS",
+#endif
+#if NAMED_BIND
+       "NAMED_BIND",
+#endif
+#if NDBM
+       "NDBM",
+#endif
+#if NETINET
+       "NETINET",
+#endif
+#if NETINFO
+       "NETINFO",
+#endif
+#if NETISO
+       "NETISO",
+#endif
+#if NETNS
+       "NETNS",
+#endif
+#if NETUNIX
+       "NETUNIX",
+#endif
+#if NETX25
+       "NETX25",
+#endif
+#if NEWDB
+       "NEWDB",
+#endif
+#if NIS
+       "NIS",
+#endif
+#if NISPLUS
+       "NISPLUS",
+#endif
+#if SCANF
+       "SCANF",
+#endif
+#if SUID_ROOT_FILES_OK
+       "SUID_ROOT_FILES_OK",
+#endif
+#if USERDB
+       "USERDB",
+#endif
+#if XDEBUG
+       "XDEBUG",
+#endif
+#if XLA
+       "XLA",
+#endif
+       NULL
+};
+
+
+/*
+**  OS compile options.
+*/
+
+char   *OsCompileOptions[] =
+{
+#if HASFLOCK
+       "HASFLOCK",
+#endif
+#if HASGETUSERSHELL
+       "HASGETUSERSHELL",
+#endif
+#if HASINITGROUPS
+       "HASINITGROUPS",
+#endif
+#if HASLSTAT
+       "HASLSTAT",
+#endif
+#if HASSETREUID
+       "HASSETREUID",
+#endif
+#if HASSETSID
+       "HASSETSID",
+#endif
+#if HASSETVBUF
+       "HASSETVBUF",
+#endif
+#if HASUNAME
+       "HASUNAME",
+#endif
+#if IDENTPROTO
+       "IDENTPROTO",
+#endif
+#if IP_SRCROUTE
+       "IP_SRCROUTE",
+#endif
+#if SYS5SETPGRP
+       "SYS5SETPGRP",
+#endif
+#if SYSTEM5
+       "SYSTEM5",
+#endif
+#if USESETEUID
+       "USESETEUID",
+#endif
+       NULL
+};