Merge branch 'master' into transp_logging_1031
[users/jgh/exim.git] / src / src / transports / smtp.c
index 25cc5490a8273ef394849da4b8435327b4894728..04bee7fab3d26ccdbfdcb2319d065aca81351379 100644 (file)
@@ -35,6 +35,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(transport_instance, connection_max_messages) },
   { "data_timeout",         opt_time,
       (void *)offsetof(smtp_transport_options_block, data_timeout) },
+#ifdef EXPERIMENTAL_DBL
+  { "dbl_host_defer_query",      opt_stringptr,
+         (void *)offsetof(smtp_transport_options_block, dbl_host_defer_query) },
+#endif
   { "delay_after_cutoff", opt_bool,
       (void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
 #ifndef DISABLE_DKIM
@@ -233,6 +237,9 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* dkim_sign_headers */
   NULL                 /* dkim_strict */
 #endif
+#ifdef EXPERIMENTAL_DBL
+ ,NULL                 /* dbl_host_defer_query */
+#endif
 };
 
 
@@ -577,6 +584,52 @@ else
 
 
 
+#ifdef EXPERIMENTAL_DBL
+/*************************************************
+*          Write error message to database log   *
+*************************************************/
+
+/* This writes to the database log
+
+Arguments:
+  dbl_host_defer_query  dbl_host_defer_query from the transport options block
+  addr                  the address item containing error information
+  host                  the current host
+
+Returns:   nothing
+*/
+
+static void
+dbl_write_defer_log(uschar *dbl_host_defer_query, address_item *addr, host_item *host)
+{
+if (dbl_host_defer_query == NULL)
+       return;
+
+dbl_delivery_ip = string_copy(host->address);
+dbl_delivery_port = (host->port == PORT_NONE)? 25 : host->port;
+dbl_delivery_fqdn = string_copy(host->name);
+dbl_delivery_local_part = string_copy(addr->local_part);
+dbl_delivery_domain = string_copy(addr->domain);
+dbl_defer_errno = addr->basic_errno;
+
+dbl_defer_errstr = NULL;
+if (addr->message != NULL)
+  if (addr->basic_errno > 0)
+    dbl_defer_errstr = string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno));
+  else
+       dbl_defer_errstr = string_copy(addr->message);
+else if (addr->basic_errno > 0)
+  dbl_defer_errstr = string_copy(strerror(addr->basic_errno));
+
+DEBUG(D_transport) {
+       debug_printf("  DBL(host defer): dbl_host_defer_query=|%s| dbl_delivery_IP=%s\n", dbl_host_defer_query, dbl_delivery_ip);
+}
+expand_string(dbl_host_defer_query);
+}
+#endif
+
+
+
 /*************************************************
 *           Synchronize SMTP responses           *
 *************************************************/
@@ -1912,7 +1965,12 @@ if (!ok) ok = TRUE; else
 
     /* Set up confirmation if needed - applies only to SMTP */
 
-    if ((log_extra_selector & LX_smtp_confirmation) != 0 && !lmtp)
+    if (
+               #ifndef EXPERIMENTAL_DBL
+                       (log_extra_selector & LX_smtp_confirmation) != 0 &&
+               #endif
+                       !lmtp
+        )
       {
       uschar *s = string_printing(buffer);
       conf = (s == buffer)? (uschar *)string_copy(s) : s;
@@ -3051,6 +3109,11 @@ for (cutoff_retry = 0; expired &&
                          first_addr->basic_errno != ERRNO_TLSFAILURE)
         write_logs(first_addr, host);
 
+      #ifdef EXPERIMENTAL_DBL
+      if (rc == DEFER)
+        dbl_write_defer_log(ob->dbl_host_defer_query, first_addr, host);
+      #endif
+
       /* If STARTTLS was accepted, but there was a failure in setting up the
       TLS session (usually a certificate screwup), and the host is not in
       hosts_require_tls, and tls_tempfail_tryclear is true, try again, with
@@ -3073,6 +3136,10 @@ for (cutoff_retry = 0; expired &&
           expanded_hosts != NULL, &message_defer, TRUE);
         if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
           write_logs(first_addr, host);
+        #ifdef EXPERIMENTAL_DBL
+        if (rc == DEFER)
+          dbl_write_defer_log(ob->dbl_host_defer_query, first_addr, host);
+        #endif
         }
       #endif
       }