Treat ECONNRESET the same as an end-of-file indication.
[exim.git] / src / src / exim.c
index 32ddb96d24265ec1f45b5e1189281516656f11a4..e083858f87adde371894e088a30fccc0fb801bb4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.19 2005/05/03 14:20:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.30 2005/10/20 15:19:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -406,10 +406,10 @@ for (i = 0; i <= 2; i++)
     if (devnull < 0) devnull = open("/dev/null", O_RDWR);
     if (devnull < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
       string_open_failed(errno, "/dev/null"));
-    if (devnull != i) dup2(devnull, i);
+    if (devnull != i) (void)dup2(devnull, i);
     }
   }
-if (devnull > 2) close(devnull);
+if (devnull > 2) (void)close(devnull);
 }
 
 
@@ -459,19 +459,19 @@ if (smtp_input)
   #ifdef SUPPORT_TLS
   tls_close(FALSE);      /* Shut down the TLS library */
   #endif
-  close(fileno(smtp_in));
-  close(fileno(smtp_out));
+  (void)close(fileno(smtp_in));
+  (void)close(fileno(smtp_out));
   smtp_in = NULL;
   }
 else
   {
-  close(0);                                           /* stdin */
-  if ((debug_selector & D_resolver) == 0)  close(1);  /* stdout */
-  if (debug_selector == 0)                            /* stderr */
+  (void)close(0);                                          /* stdin */
+  if ((debug_selector & D_resolver) == 0) (void)close(1);  /* stdout */
+  if (debug_selector == 0)                                 /* stderr */
     {
     if (!synchronous_delivery)
       {
-      close(2);
+      (void)close(2);
       log_stderr = NULL;
       }
     (void)setsid();
@@ -586,7 +586,8 @@ exit(rc);
 *************************************************/
 
 /* Called to extract the port from the values given to -oMa and -oMi.
-It also checks the syntax of the address.
+It also checks the syntax of the address, and terminates it before the
+port data when a port is extracted.
 
 Argument:
   address   the address, with possible port on the end
@@ -598,7 +599,7 @@ Returns:    the port, or zero if there isn't one
 static int
 check_port(uschar *address)
 {
-int port = host_extract_port(address);
+int port = host_address_extract_port(address);
 if (string_is_ip_address(address, NULL) == 0)
   {
   fprintf(stderr, "exim abandoned: \"%s\" is not an IP address\n", address);
@@ -662,6 +663,10 @@ The log options are held in two unsigned ints (because there became too many
 for one). The top bit in the table means "put in 2nd selector". This does not
 yet apply to debug options, so the "=" facility sets only the first selector.
 
+The "all" selector, which must be equal to 0xffffffff, is recognized specially.
+It sets all the bits in both selectors. However, there is a facility for then
+unsetting certain bits, because we want to turn off "memory" in the debug case.
+
 A bad value for a debug setting is treated as an unknown option - error message
 to stderr and die. For log settings, which come from the configuration file,
 we write to the log on the way out...
@@ -669,6 +674,8 @@ we write to the log on the way out...
 Arguments:
   selector1      address of the first bit string
   selector2      address of the second bit string, or NULL
+  notall1        bits to exclude from "all" for selector1
+  notall2        bits to exclude from "all" for selector2
   string         the configured string
   options        the table of option names
   count          size of table
@@ -678,8 +685,8 @@ Returns:         nothing on success - bomb out on failure
 */
 
 static void
-decode_bits(unsigned int *selector1, unsigned int *selector2, uschar *string,
-  bit_table *options, int count, uschar *which)
+decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1,
+  int notall2, uschar *string, bit_table *options, int count, uschar *which)
 {
 uschar *errmsg;
 if (string == NULL) return;
@@ -732,14 +739,23 @@ else for(;;)
         unsigned int bit = middle->bit;
         unsigned int *selector;
 
-        /* The value with all bits set means "set all bits in both selectors"
+        /* The value with all bits set means "force all bits in both selectors"
         in the case where two are being handled. However, the top bit in the
-        second selector is never set. */
+        second selector is never set. When setting, some bits can be excluded.
+        */
 
         if (bit == 0xffffffff)
           {
-          *selector1 = adding? bit : 0;
-          if (selector2 != NULL) *selector2 = adding? 0x7fffffff : 0;
+          if (adding)
+            {
+            *selector1 = 0xffffffff ^ notall1;
+            if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2;
+            }
+          else
+            {
+            *selector1 = 0;
+            if (selector2 != NULL) *selector2 = 0;
+            }
           }
 
         /* Otherwise, the 0x80000000 bit means "this value, without the top
@@ -817,6 +833,9 @@ fprintf(f, "Using tdb\n");
 #endif
 
 fprintf(f, "Support for:");
+#ifdef SUPPORT_CRYPTEQ
+  fprintf(f, " crypteq");
+#endif
 #if HAVE_ICONV
   fprintf(f, " iconv()");
 #endif
@@ -842,6 +861,12 @@ fprintf(f, "Support for:");
   fprintf(f, " OpenSSL");
   #endif
 #endif
+#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
+  fprintf(f, " translate_ip_address");
+#endif
+#ifdef SUPPORT_MOVE_FROZEN_MESSAGES
+  fprintf(f, " move_frozen_messages");
+#endif
 #ifdef WITH_CONTENT_SCAN
   fprintf(f, " Content_Scanning");
 #endif
@@ -902,6 +927,9 @@ fprintf(f, "Lookups:");
 #ifdef LOOKUP_PGSQL
   fprintf(f, " pgsql");
 #endif
+#ifdef LOOKUP_SQLITE
+  fprintf(f, " sqlite");
+#endif
 #ifdef LOOKUP_TESTDB
   fprintf(f, " testdb");
 #endif
@@ -1919,7 +1947,7 @@ for (i = 1; i < argc; i++)
         argrest++;
         }
       if (*argrest != 0)
-        decode_bits(&selector, NULL, argrest, debug_options,
+        decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options,
           debug_options_count, US"debug");
       debug_selector = selector;
       }
@@ -1971,6 +1999,7 @@ for (i = 1; i < argc; i++)
         { badarg = TRUE; break; }
       }
     originator_name = argrest;
+    sender_name_forced = TRUE;
     break;
 
 
@@ -3040,7 +3069,7 @@ readconf_main();
 
 /* Handle the decoding of logging options. */
 
-decode_bits(&log_write_selector, &log_extra_selector, log_selector_string,
+decode_bits(&log_write_selector, &log_extra_selector, 0, 0, log_selector_string,
   log_options, log_options_count, US"log");
 
 DEBUG(D_any)
@@ -3281,11 +3310,12 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
 on this in the code, which always uses fully qualified names, but it's useful
 for core dumps etc. Don't complain if it fails - the spool directory might not
 be generally accessible and calls with the -C option (and others) have lost
-privilege by now. */
+privilege by now. Before the chdir, we try to ensure that the directory exists.
+*/
 
 if (Uchdir(spool_directory) != 0)
   {
-  (void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, TRUE);
+  (void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE);
   (void)Uchdir(spool_directory);
   }
 
@@ -3297,7 +3327,7 @@ script. */
 
 if (bi_option)
   {
-  fclose(config_file);
+  (void)fclose(config_file);
   if (bi_command != NULL)
     {
     int i = 0;
@@ -3889,7 +3919,7 @@ for (i = 0;;)
 
 /* If we cannot get a user login, log the incident and give up, unless the
 configuration specifies something to use. When running in the test harness,
-any setting of unknown_login overrides the actual login name. */
+any setting of unknown_login overrides the actual name. */
 
 if (originator_login == NULL || running_in_test_harness)
   {
@@ -3923,12 +3953,17 @@ DEBUG(D_receive) debug_printf("originator: uid=%d gid=%d login=%s name=%s\n",
 
 /* Run in daemon and/or queue-running mode. The function daemon_go() never
 returns. We leave this till here so that the originator_ fields are available
-for incoming messages via the daemon. */
+for incoming messages via the daemon. The daemon cannot be run in mua_wrapper
+mode. */
 
 if (daemon_listen || queue_interval > 0)
   {
-  if (mua_wrapper) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Daemon cannot be "
-    "run when mua_wrapper is set");
+  if (mua_wrapper)
+    {
+    fprintf(stderr, "Daemon cannot be run when mua_wrapper is set\n");
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Daemon cannot be run when "
+      "mua_wrapper is set");
+    }
   daemon_go();
   }
 
@@ -4254,7 +4289,7 @@ sender_ident. */
 
 else if (is_inetd)
   {
-  fclose(stderr);
+  (void)fclose(stderr);
   exim_nullstd();                       /* Re-open to /dev/null */
   verify_get_ident(IDENT_PORT);
   host_build_sender_fullhost();
@@ -4284,7 +4319,7 @@ else if (!is_inetd) sender_host_unknown = TRUE;
 if exim is started from inetd. In this case fd 0 will be set to the socket,
 but fd 1 will not be set. This also happens for passed SMTP channels. */
 
-if (fstat(1, &statbuf) < 0) dup2(0, 1);
+if (fstat(1, &statbuf) < 0) (void)dup2(0, 1);
 
 /* Set up the incoming protocol name and the state of the program. Root
 is allowed to force received protocol via the -oMr option above, and if we are
@@ -4610,7 +4645,7 @@ while (more)
     if (ftest_prefix != NULL) printf("Prefix    = %s\n", ftest_prefix);
     if (ftest_suffix != NULL) printf("Suffix    = %s\n", ftest_suffix);
 
-    chdir("/");   /* Get away from wherever the user is running this from */
+    (void)chdir("/");   /* Get away from wherever the user is running this from */
 
     /* Now we run either a system filter test, or a user filter test, or both.
     In the latter case, headers added by the system filter will persist and be