]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/deliver.c
Fix post-transport-crash: safeguard for missing spool BUG 1671
[user/henk/code/exim.git] / src / src / deliver.c
index c796de040229fd73061285305c4942dc4069a141..b5aa9b9a75d1a211622ca73b0a3b75dc6ad3f9f3 100644 (file)
@@ -9,6 +9,7 @@
 
 
 #include "exim.h"
+#include <assert.h>
 
 
 /* Data block for keeping track of subprocesses for parallel remote
@@ -676,39 +677,78 @@ while (addr->parent != NULL)
 
 
 
+/*************************************************
+*      Delivery logging support functions        *
+*************************************************/
+
+/* The LOGGING() checks in d_log_interface() are complicated for backwards
+compatibility. When outgoing interface logging was originally added, it was
+conditional on just incoming_interface (which is off by default). The
+outgoing_interface option is on by default to preserve this behaviour, but
+you can enable incoming_interface and disable outgoing_interface to get I=
+fields on incoming lines only.
+
+Arguments:
+  s         The log line buffer
+  sizep     Pointer to the buffer size
+  ptrp      Pointer to current index into buffer
+  addr      The address to be logged
+
+Returns:    New value for s
+*/
 
 static uschar *
-d_hostlog(uschar * s, int * sizep, int * ptrp, address_item * addr)
+d_log_interface(uschar *s, int *sizep, int *ptrp)
 {
-  s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
-    US" [", addr->host_used->address, US"]");
+if (LOGGING(incoming_interface) && LOGGING(outgoing_interface)
+    && sending_ip_address != NULL)
+  {
+  s = string_append(s, sizep, ptrp, 2, US" I=[", sending_ip_address);
   if (LOGGING(outgoing_port))
-    s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
-      addr->host_used->port));
-  return s;
+    s = string_append(s, sizep, ptrp, 2, US"]:",
+      string_sprintf("%d", sending_port));
+  else
+    s = string_cat(s, sizep, ptrp, "]", 1);
+  }
+return s;
+}
+
+
+
+static uschar *
+d_hostlog(uschar *s, int *sizep, int *ptrp, address_item *addr)
+{
+s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
+  US" [", addr->host_used->address, US"]");
+if (LOGGING(outgoing_port))
+  s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
+    addr->host_used->port));
+return d_log_interface(s, sizep, ptrp);
 }
 
+
+
 #ifdef SUPPORT_TLS
 static uschar *
 d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
 {
-  if (LOGGING(tls_cipher) && addr->cipher != NULL)
-    s = string_append(s, sizep, ptrp, 2, US" X=", addr->cipher);
-  if (LOGGING(tls_certificate_verified) && addr->cipher != NULL)
-    s = string_append(s, sizep, ptrp, 2, US" CV=",
-      testflag(addr, af_cert_verified)
-      ?
+if (LOGGING(tls_cipher) && addr->cipher != NULL)
+  s = string_append(s, sizep, ptrp, 2, US" X=", addr->cipher);
+if (LOGGING(tls_certificate_verified) && addr->cipher != NULL)
+  s = string_append(s, sizep, ptrp, 2, US" CV=",
+    testflag(addr, af_cert_verified)
+    ?
 #ifdef EXPERIMENTAL_DANE
-        testflag(addr, af_dane_verified)
-      ? "dane"
-      :
+      testflag(addr, af_dane_verified)
+    ? "dane"
+    :
 #endif
-        "yes"
-      : "no");
-  if (LOGGING(tls_peerdn) && addr->peerdn != NULL)
-    s = string_append(s, sizep, ptrp, 3, US" DN=\"",
-      string_printing(addr->peerdn), US"\"");
-  return s;
+      "yes"
+    : "no");
+if (LOGGING(tls_peerdn) && addr->peerdn != NULL)
+  s = string_append(s, sizep, ptrp, 3, US" DN=\"",
+    string_printing(addr->peerdn), US"\"");
+return s;
 }
 #endif
 
@@ -816,10 +856,6 @@ else
   s = string_append(s, &size, &ptr, 2, US"> ", log_address);
   }
 
-if (LOGGING(incoming_interface) && sending_ip_address)
-  s = string_append(s, &size, &ptr, 3, US" I=[", sending_ip_address, US"]");
-  /* for the port:  string_sprintf("%d", sending_port) */
-
 if (LOGGING(sender_on_delivery) || msg)
   s = string_append(s, &size, &ptr, 3, US" F=<",
 #ifdef EXPERIMENTAL_INTERNATIONAL
@@ -862,6 +898,7 @@ if (addr->transport->info->local)
   {
   if (addr->host_list)
     s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name);
+  s = d_log_interface(s, &size, &ptr);
   if (addr->shadow_message != NULL)
     s = string_cat(s, &size, &ptr, addr->shadow_message,
       Ustrlen(addr->shadow_message));
@@ -7898,17 +7935,36 @@ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA =
 uschar *
 deliver_get_sender_address (uschar * id)
 {
+int rc;
+uschar * new_sender_address,
+       * save_sender_address;
+
 if (!spool_open_datafile(id))
   return NULL;
 
+/* Save and restore the global sender_address.  I'm not sure if we should
+not save/restore all the other global variables too, because
+spool_read_header() may change all of them. But OTOH, when this
+deliver_get_sender_address() gets called, the current message is done
+already and nobody needs the globals anymore. (HS12, 2015-08-21) */
+
 sprintf(CS spoolname, "%s-H", id);
-if (spool_read_header(spoolname, TRUE, TRUE) != spool_read_OK)
+save_sender_address = sender_address;
+
+rc = spool_read_header(spoolname, TRUE, TRUE);
+
+new_sender_address = sender_address;
+sender_address = save_sender_address;
+
+if (rc != spool_read_OK)
   return NULL;
 
+assert(new_sender_address);
+
 (void)close(deliver_datafile);
 deliver_datafile = -1;
 
-return sender_address;
+return new_sender_address;
 }
 
 /* vi: aw ai sw=2