Avoid build conflict vs. FreeBSD /usr/include/sys/file.h
[users/heiko/exim.git] / src / src / daemon.c
index 1ec0fd2e089e9717bb416e00b9ca65cbf6623e53..b91b43746159ef16f3393de4abe749591c1ab85e 100644 (file)
@@ -21,7 +21,7 @@ typedef struct smtp_slot {
 /* An empty slot for initializing (Standard C does not allow constructor
 expressions in assignments except as initializers in declarations). */
 
-static smtp_slot empty_smtp_slot = { 0, NULL };
+static smtp_slot empty_smtp_slot = { .pid = 0, .host_address = NULL };
 
 
 
@@ -109,7 +109,7 @@ never_error(uschar *log_msg, uschar *smtp_msg, int was_errno)
 uschar *emsg = (was_errno <= 0)? US"" :
   string_sprintf(": %s", strerror(was_errno));
 log_write(0, LOG_MAIN|LOG_PANIC, "%s%s", log_msg, emsg);
-if (smtp_out != NULL) smtp_printf("421 %s\r\n", smtp_msg);
+if (smtp_out != NULL) smtp_printf("421 %s\r\n", FALSE, smtp_msg);
 }
 
 
@@ -189,7 +189,7 @@ if (getsockname(accept_socket, (struct sockaddr *)(&interface_sockaddr),
   {
   log_write(0, LOG_MAIN | ((errno == ECONNRESET)? 0 : LOG_PANIC),
     "getsockname() failed: %s", strerror(errno));
-  smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n");
+  smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n", FALSE);
   goto ERROR_RETURN;
   }
 
@@ -222,7 +222,7 @@ if (smtp_accept_max > 0 && smtp_accept_count >= smtp_accept_max)
   DEBUG(D_any) debug_printf("rejecting SMTP connection: count=%d max=%d\n",
     smtp_accept_count, smtp_accept_max);
   smtp_printf("421 Too many concurrent SMTP connections; "
-    "please try again later.\r\n");
+    "please try again later.\r\n", FALSE);
   log_write(L_connection_reject,
             LOG_MAIN, "Connection from %s refused: too many connections",
     whofrom);
@@ -241,7 +241,7 @@ if (smtp_load_reserve >= 0)
     {
     DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n",
       (double)load_average/1000.0);
-    smtp_printf("421 Too much load; please try again later.\r\n");
+    smtp_printf("421 Too much load; please try again later.\r\n", FALSE);
     log_write(L_connection_reject,
               LOG_MAIN, "Connection from %s refused: load average = %.2f",
       whofrom, (double)load_average/1000.0);
@@ -312,7 +312,7 @@ if ((max_for_this_host > 0) &&
       "IP address: count=%d max=%d\n",
       host_accept_count, max_for_this_host);
     smtp_printf("421 Too many concurrent SMTP connections "
-      "from this IP address; please try again later.\r\n");
+      "from this IP address; please try again later.\r\n", FALSE);
     log_write(L_connection_reject,
               LOG_MAIN, "Connection from %s refused: too many connections "
       "from that IP address", whofrom);
@@ -396,7 +396,7 @@ if (pid == 0)
           "(smtp_active_hostname): %s", raw_active_hostname,
           expand_string_message);
         smtp_printf("421 Local configuration error; "
-          "please try again later.\r\n");
+          "please try again later.\r\n", FALSE);
         mac_smtp_fflush();
         search_tidyup();
         _exit(EXIT_FAILURE);
@@ -1173,6 +1173,8 @@ if (daemon_listen && !inetd_wait_mode)
   while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
     if (!isdigit(*s))
       {
+      int size = 0, len = 0;
+
       list = tls_in.on_connect_ports;
       tls_in.on_connect_ports = NULL;
       sep = 0;
@@ -1180,13 +1182,13 @@ if (daemon_listen && !inetd_wait_mode)
        {
         if (!isdigit(*s))
          {
-         struct servent *smtp_service = getservbyname(CS s, "tcp");
+         struct servent * smtp_service = getservbyname(CS s, "tcp");
          if (!smtp_service)
            log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "TCP port \"%s\" not found", s);
-         s= string_sprintf("%d", (int)ntohs(smtp_service->s_port));
+         s = string_sprintf("%d", (int)ntohs(smtp_service->s_port));
          }
        tls_in.on_connect_ports = string_append_listele(tls_in.on_connect_ports,
-           ':', s);
+           &size, &len, ':', s);
        }
       break;
       }
@@ -1409,7 +1411,7 @@ if (daemon_listen && !inetd_wait_mode)
 
 #ifdef IPV6_V6ONLY
     if (af == AF_INET6 && wildcard &&
-        setsockopt(listen_sockets[sk], IPPROTO_IPV6, IPV6_V6ONLY, (char *)(&on),
+        setsockopt(listen_sockets[sk], IPPROTO_IPV6, IPV6_V6ONLY, CS (&on),
           sizeof(on)) < 0)
       log_write(0, LOG_MAIN, "Setting IPV6_V6ONLY on daemon's IPv6 wildcard "
         "socket failed (%s): carrying on without it", strerror(errno));
@@ -1420,7 +1422,7 @@ if (daemon_listen && !inetd_wait_mode)
     smtp port for listening. */
 
     if (setsockopt(listen_sockets[sk], SOL_SOCKET, SO_REUSEADDR,
-                   (uschar *)(&on), sizeof(on)) < 0)
+                   US (&on), sizeof(on)) < 0)
       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "setting SO_REUSEADDR on socket "
         "failed when starting daemon: %s", strerror(errno));
 
@@ -1428,7 +1430,7 @@ if (daemon_listen && !inetd_wait_mode)
     disable this because it breaks some broken clients. */
 
     if (tcp_nodelay) setsockopt(listen_sockets[sk], IPPROTO_TCP, TCP_NODELAY,
-      (uschar *)(&on), sizeof(on));
+      US (&on), sizeof(on));
 
     /* Now bind the socket to the required port; if Exim is being restarted
     it may not always be possible to bind immediately, even with SO_REUSEADDR
@@ -1635,7 +1637,7 @@ else if (daemon_listen)
   int i, j;
   int smtp_ports = 0;
   int smtps_ports = 0;
-  ip_address_item * ipa;
+  ip_address_item * ipa, * i2;
   uschar * p = big_buffer;
   uschar * qinfo = queue_interval > 0
     ? string_sprintf("-q%s", readconf_printtime(queue_interval))
@@ -1673,7 +1675,7 @@ else if (daemon_listen)
        /* Now the information about the port (and sometimes interface) */
 
        if (ipa->address[0] == ':' && ipa->address[1] == 0)
-         {
+         {                                             /* v6 wildcard */
          if (ipa->next && ipa->next->address[0] == 0 &&
              ipa->next->port == ipa->port)
            {
@@ -1685,20 +1687,24 @@ else if (daemon_listen)
          else
            p += sprintf(CS p, " port %d (IPv6)", ipa->port);
          }
-       else if (ipa->address[0] == 0)
+       else if (ipa->address[0] == 0)                  /* v4 wildcard */
          p += sprintf(CS p, " port %d (IPv4)", ipa->port);
-       else if (  i > 0
-               && host_is_tls_on_connect_port(ipa[-1].port) == (j > 0)
-               && Ustrcmp(ipa->address, ipa[-1].address) == 0
-               )
+       else                            /* check for previously-seen IP */
          {
-         if (p[-1] == '}') p--;
-         while (isdigit(*--p)) ;
-         p += sprintf(CS p+1, "%s%d,%d}", *p == ',' ? "" : "{",
-           ipa[-1].port, ipa->port);
+         for (i2 = addresses; i2 != ipa; i2 = i2->next)
+           if (  host_is_tls_on_connect_port(i2->port) == (j > 0)
+              && Ustrcmp(ipa->address, i2->address) == 0
+              )
+             {                         /* found; append port to list */
+             if (p[-1] == '}') p--;
+             while (isdigit(*--p)) ;
+             p +=  1 + sprintf(CS p+1, "%s%d,%d}", *p == ',' ? "" : "{",
+               i2->port, ipa->port);
+             break;
+             }
+         if (i2 == ipa)                /* first-time IP */
+           p += sprintf(CS p, " [%s]:%d", ipa->address, ipa->port);
          }
-       else
-         p += sprintf(CS p, " [%s]:%d", ipa->address, ipa->port);
        }
       }