BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / daemon.c
index 91c1534..dd1b4bf 100644 (file)
@@ -3,18 +3,43 @@
  * Copyright (c) 1988 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1988 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.
  */
 
 #include <errno.h>
 #include "sendmail.h"
  */
 
 #include <errno.h>
 #include "sendmail.h"
-# include <sys/mx.h>
 
 #ifndef lint
 #ifdef DAEMON
 
 #ifndef lint
 #ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c   5.37 (Berkeley) %G% (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c   5.37 (Berkeley) 3/2/91 (with daemon mode)";
 #else
 #else
-static char sccsid[] = "@(#)daemon.c   5.37 (Berkeley) %G% (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c   5.37 (Berkeley) 3/2/91 (without daemon mode)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -58,8 +83,6 @@ int la;       /* load average */
 **             Convert the entry in hbuf into a canonical form.  It
 **             may not be larger than hbufsize.
 */
 **             Convert the entry in hbuf into a canonical form.  It
 **             may not be larger than hbufsize.
 */
-
-static FILE    *MailPort;      /* port that mail comes in on */
 \f/*
 **  GETREQUESTS -- open mail IPC port and get requests.
 **
 \f/*
 **  GETREQUESTS -- open mail IPC port and get requests.
 **
@@ -120,6 +143,7 @@ getrequests()
          severe:
 # ifdef LOG
                if (LogLevel > 0)
          severe:
 # ifdef LOG
                if (LogLevel > 0)
+                       syslog(LOG_ALERT, "cannot get connection");
 # endif LOG
                finis();
        }
 # endif LOG
                finis();
        }
@@ -150,13 +174,117 @@ getrequests()
        if (tTd(15, 1))
                printf("getrequests: %d\n", DaemonSocket);
 
        if (tTd(15, 1))
                printf("getrequests: %d\n", DaemonSocket);
 
-       struct wh wbuf;
+       for (;;)
+       {
+               register int pid;
+               auto int lotherend;
+               extern int RefuseLA;
+
+               /* see if we are rejecting connections */
+               while ((la = getla()) > RefuseLA)
+               {
+                       setproctitle("rejecting connections: load average: %.2f", (double)la);
+                       sleep(5);
+               }
+
+               /* wait for a connection */
+               setproctitle("accepting connections");
+               do
+               {
+                       errno = 0;
+                       lotherend = sizeof RealHostAddr;
+                       t = accept(DaemonSocket,
+                           (struct sockaddr *)&RealHostAddr, &lotherend);
+               } while (t < 0 && errno == EINTR);
+               if (t < 0)
+               {
+                       syserr("getrequests: accept");
+                       sleep(5);
+                       continue;
+               }
+
+               /*
+               **  Create a subprocess to process the mail.
+               */
+
+               if (tTd(15, 2))
+                       printf("getrequests: forking (fd = %d)\n", t);
+
+               pid = fork();
+               if (pid < 0)
+               {
+                       syserr("daemon: cannot fork");
+                       sleep(10);
+                       (void) close(t);
+                       continue;
+               }
+
+               if (pid == 0)
+               {
+                       extern struct hostent *gethostbyaddr();
+                       register struct hostent *hp;
+                       char buf[MAXNAME];
+
+                       /*
+                       **  CHILD -- return to caller.
+                       **      Collect verified idea of sending host.
+                       **      Verify calling user id if possible here.
+                       */
+
+                       (void) signal(SIGCHLD, SIG_DFL);
+
+                       /* determine host name */
+                       hp = gethostbyaddr((char *) &RealHostAddr.sin_addr, sizeof RealHostAddr.sin_addr, AF_INET);
+                       if (hp != NULL)
+                               (void) strcpy(buf, hp->h_name);
+                       else
+                       {
+                               extern char *inet_ntoa();
+
+                               /* produce a dotted quad */
+                               (void) sprintf(buf, "[%s]",
+                                       inet_ntoa(RealHostAddr.sin_addr));
+                       }
+
+                       /* should we check for illegal connection here? XXX */
+
+                       RealHostName = newstr(buf);
+
+                       (void) close(DaemonSocket);
+                       InChannel = fdopen(t, "r");
+                       OutChannel = fdopen(dup(t), "w");
+                       if (tTd(15, 2))
+                               printf("getreq: returning\n");
+# ifdef LOG
+                       if (LogLevel > 11)
+                               syslog(LOG_DEBUG, "connected, pid=%d", getpid());
+# endif LOG
+                       return;
+               }
 
 
-       wbuf.index = index;
-       wbuf.count = 0;
-       wbuf.ccount = cnt;
-       wbuf.data = buf;
-       write(MailPort, &wbuf, sizeof wbuf);
+               /* close the port so that others will hang (for a while) */
+               (void) close(t);
+       }
+       /*NOTREACHED*/
+}
+\f/*
+**  CLRDAEMON -- reset the daemon connection
+**
+**     Parameters:
+**             none.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             releases any resources used by the passive daemon.
+*/
+
+clrdaemon()
+{
+       if (DaemonSocket >= 0)
+               (void) close(DaemonSocket);
+       DaemonSocket = -1;
 }
 \f/*
 **  MAKECONNECTION -- make a connection to an SMTP socket on another machine.
 }
 \f/*
 **  MAKECONNECTION -- make a connection to an SMTP socket on another machine.
@@ -270,11 +398,7 @@ again:
                printf("makeconnection (%s [%s])\n", host,
                    inet_ntoa(SendmailAddress.sin_addr.s_addr));
 
                printf("makeconnection (%s [%s])\n", host,
                    inet_ntoa(SendmailAddress.sin_addr.s_addr));
 
-#ifdef NVMUNIX
-       s = socket(AF_INET, SOCK_STREAM, 0, 0);
-#else NVMUNIX
        s = socket(AF_INET, SOCK_STREAM, 0);
        s = socket(AF_INET, SOCK_STREAM, 0);
-#endif NVMUNIX
        if (s < 0)
        {
                syserr("makeconnection: no socket");
        if (s < 0)
        {
                syserr("makeconnection: no socket");
@@ -294,14 +418,9 @@ again:
        if (CurEnv->e_xfp != NULL)
                (void) fflush(CurEnv->e_xfp);           /* for debugging */
        errno = 0;                                      /* for debugging */
        if (CurEnv->e_xfp != NULL)
                (void) fflush(CurEnv->e_xfp);           /* for debugging */
        errno = 0;                                      /* for debugging */
-#ifdef NVMUNIX
-       bind(s, &SendmailAddress, sizeof SendmailAddress, 0);
-       if (connect(s, &SendmailAddress, sizeof SendmailAddress, 0) < 0)
-#else NVMUNIX
        SendmailAddress.sin_family = AF_INET;
        if (connect(s,
            (struct sockaddr *)&SendmailAddress, sizeof SendmailAddress) < 0)
        SendmailAddress.sin_family = AF_INET;
        if (connect(s,
            (struct sockaddr *)&SendmailAddress, sizeof SendmailAddress) < 0)
-#endif NVMUNIX
        {
                sav_errno = errno;
                (void) close(s);
        {
                sav_errno = errno;
                (void) close(s);