transport dynamic modules
[exim.git] / src / src / daemon.c
index 88114d648122193bcf11e465813a56737515a89c..4088cb53210935ae2ac4ed73a746c234d546e346 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) The Exim Maintainers 2020 - 2023 */
+/* Copyright (c) The Exim Maintainers 2020 - 2024 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
@@ -311,7 +311,7 @@ if (smtp_accept_max_per_host)
   /* For speed, interpret a decimal number inline here */
   else
     {
-    uschar *s = expanded;
+    uschar * s = expanded;
     while (isdigit(*s))
       max_for_this_host = max_for_this_host * 10 + *s++ - '0';
     if (*s)
@@ -320,11 +320,12 @@ if (smtp_accept_max_per_host)
     }
   }
 
-/* If we have fewer connections than max_for_this_host, we can skip the tedious
-per host_address checks. Note that at this stage smtp_accept_count contains the
-count of *other* connections, not including this one. */
+/* If we have fewer total connections than max_for_this_host, we can skip the
+tedious per host_address checks. Note that at this stage smtp_accept_count
+contains the count of *other* connections, not including this one. */
 
-if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host)
+if (  smtp_slots
+   && max_for_this_host > 0 && smtp_accept_count >= max_for_this_host)
   {
   int host_accept_count = 0;
   int other_host_count = 0;    /* keep a count of non matches to optimise */
@@ -382,7 +383,7 @@ if (pid == 0)
 #endif
 
   smtp_accept_count++;    /* So that it includes this process */
-  connection_id = getpid();
+  set_connection_id();
 
   /* Log the connection if requested.
   In order to minimize the cost (because this is going to happen for every
@@ -392,9 +393,9 @@ if (pid == 0)
   arrange to unset the selector in the subprocess.
 
   jgh 2023/08/08 :- moved this logging in from the parent process, just
-  pre-fork.  There was a claim back from 2004 that smtp_accept_count could have
-  become out-of-date by the time the child could log it, and I can't see how
-  that could happen. */
+  pre-fork.  There was a claim back from 4.21 (when it was moved from
+  smtp_start_session()) that smtp_accept_count could have become out-of-date by
+  the time the child could log it, and I can't see how that could happen. */
 
   if (LOGGING(smtp_connection))
     {
@@ -404,7 +405,8 @@ if (pid == 0)
       save_log_selector &= ~L_smtp_connection;
     else if (LOGGING(connection_id))
       log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %Y "
-       "Ci=%lu (TCP/IP connection count = %d)", whofrom, connection_id, smtp_accept_count);
+       "Ci=%s (TCP/IP connection count = %d)",
+       whofrom, connection_id, smtp_accept_count);
     else
       log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %Y "
        "(TCP/IP connection count = %d)", whofrom, smtp_accept_count);
@@ -752,7 +754,7 @@ remember the pid for ticking off when the child completes. */
 
 if (pid < 0)
   never_error(US"daemon: accept process fork failed", US"Fork failed", errno);
-else
+else if (smtp_slots)
   {
   for (int i = 0; i < smtp_accept_max; ++i)
     if (smtp_slots[i].pid <= 0)
@@ -896,7 +898,7 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
   {
   DEBUG(D_any)
     {
-    debug_printf("child %d ended: status=0x%x\n", (int)pid, status);
+    debug_printf("child %ld ended: status=0x%x\n", (long)pid, status);
 #ifdef WCOREDUMP
     if (WIFEXITED(status))
       debug_printf("  normal exit, %d\n", WEXITSTATUS(status));
@@ -912,15 +914,16 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
   if (smtp_slots)
     {
     int i;
-    for (i = 0; i < smtp_accept_max; i++)
-      if (smtp_slots[i].pid == pid)
+    smtp_slot * sp;
+    for (i = 0, sp = smtp_slots; i < smtp_accept_max; i++, sp++)
+      if (sp->pid == pid)
         {
-        if (smtp_slots[i].host_address)
-          store_free(smtp_slots[i].host_address);
-        smtp_slots[i] = empty_smtp_slot;
+        if (sp->host_address)
+          store_free(sp->host_address);
+        *sp = empty_smtp_slot;
         if (--smtp_accept_count < 0) smtp_accept_count = 0;
         DEBUG(D_any) debug_printf("%d SMTP accept process%s now running\n",
-          smtp_accept_count, (smtp_accept_count == 1)? "" : "es");
+          smtp_accept_count, smtp_accept_count == 1 ? "" : "es");
         break;
         }
     if (i < smtp_accept_max) continue;  /* Found an accepting process */
@@ -983,7 +986,7 @@ static BOOL
 operate_on_pid_file(const enum pid_op operation, const pid_t pid)
 {
 char pid_line[sizeof(int) * 3 + 2];
-const int pid_len = snprintf(pid_line, sizeof(pid_line), "%d\n", (int)pid);
+const int pid_len = snprintf(pid_line, sizeof(pid_line), "%ld\n", (long)pid);
 BOOL lines_match = FALSE;
 uschar * path, * base, * dir;
 
@@ -1113,7 +1116,7 @@ since we may require privs for the containing directory */
 static void
 daemon_die(void)
 {
-int pid;
+pid_t pid;
 
 DEBUG(D_any) debug_printf("SIGTERM/SIGINT seen\n");
 #if !defined(DISABLE_TLS) && (defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT))
@@ -1321,8 +1324,8 @@ for (struct cmsghdr * cp = CMSG_FIRSTHDR(&msg);
   struct ucred * cr = (struct ucred *) CMSG_DATA(cp);
   if (cr->uid && cr->uid != exim_uid)
     {
-    DEBUG(D_queue_run) debug_printf("%s: sender creds pid %d uid %d gid %d\n",
-      __FUNCTION__, (int)cr->pid, (int)cr->uid, (int)cr->gid);
+    DEBUG(D_queue_run) debug_printf("%s: sender creds pid %ld uid %d gid %d\n",
+      __FUNCTION__, (long)cr->pid, (int)cr->uid, (int)cr->gid);
     }
 # elif defined(LOCAL_CREDS)                            /* BSD-ish */
   struct sockcred * cr = (struct sockcred *) CMSG_DATA(cp);
@@ -2157,7 +2160,7 @@ if (f.background_daemon)
     pid_t pid = exim_fork(US"daemon");
     if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
       "fork() failed when starting daemon: %s", strerror(errno));
-    if (pid > 0) exit(EXIT_SUCCESS);      /* in parent process, just exit */
+    if (pid > 0) exim_exit(EXIT_SUCCESS); /* in parent process, just exit */
     (void)setsid();                       /* release controlling terminal */
     f.daemon_listen = daemon_listen;
     }
@@ -2432,7 +2435,7 @@ if (f.inetd_wait_mode)
     sprintf(CS p, "with no wait timeout");
 
   log_write(0, LOG_MAIN,
-    "exim %s daemon started: pid=%d, launched with listening socket, %s",
+    "exim %s daemon started: pid=%ld, launched with listening socket, %s",
     version_string, getpid(), big_buffer);
   set_process_info("daemon(%s): pre-listening socket", version_string);
 
@@ -2538,7 +2541,7 @@ else if (f.daemon_listen)
     }
 
   log_write(0, LOG_MAIN,
-    "exim %s daemon started: pid=%d, %s, listening for %s",
+    "exim %s daemon started: pid=%ld, %s, listening for %s",
     version_string, getpid(), qinfo, big_buffer);
   set_process_info("daemon(%s): %s, listening for %s",
     version_string, qinfo, big_buffer);
@@ -2548,7 +2551,7 @@ else      /* no listening sockets, only queue-runs */
   {
   const uschar * s = describe_queue_runners();
   log_write(0, LOG_MAIN,
-    "exim %s daemon started: pid=%d, %s, not listening for SMTP",
+    "exim %s daemon started: pid=%ld, %s, not listening for SMTP",
     version_string, getpid(), s);
   set_process_info("daemon(%s): %s, not listening", version_string, s);
   }
@@ -2869,7 +2872,7 @@ for (;;)
 
   if (sighup_seen)
     {
-    log_write(0, LOG_MAIN, "pid %d: SIGHUP received: re-exec daemon",
+    log_write(0, LOG_MAIN, "pid %ld: SIGHUP received: re-exec daemon",
       getpid());
     close_daemon_sockets(daemon_notifier_fd, fd_polls, listen_socket_count);
     unlink_notifier_socket();
@@ -2878,7 +2881,7 @@ for (;;)
     sighup_argv[0] = exim_path;
     exim_nullstd();
     execv(CS exim_path, (char *const *)sighup_argv);
-    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "pid %d: exec of %s failed: %s",
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "pid %ld: exec of %s failed: %s",
       getpid(), exim_path, strerror(errno));
     log_close_all();
     }