]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/deliver.c
Close dangling file. Bug 1379
[user/henk/code/exim.git] / src / src / deliver.c
index 27a4344c50ce0aa751c2a8cdb63895018b614381..5000f1cbc38a22b2f408c3798c0b1cfd431d5e92 100644 (file)
@@ -3844,9 +3844,20 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
     }
 
   /* Get the flag which specifies whether the transport can handle different
     }
 
   /* Get the flag which specifies whether the transport can handle different
-  domains that nevertheless resolve to the same set of hosts. */
-
-  multi_domain = tp->multi_domain;
+  domains that nevertheless resolve to the same set of hosts. If it needs
+  expanding, get variables set: $address_data, $domain_data, $localpart_data,
+  $host, $host_address, $host_port. */
+  if (tp->expand_multi_domain)
+    deliver_set_expansions(addr);
+
+  if (exp_bool(addr, US"transport", tp->name, D_transport,
+               US"multi_domain", tp->multi_domain, tp->expand_multi_domain,
+               &multi_domain) != OK)
+    {
+    deliver_set_expansions(NULL);
+    remote_post_process(addr, LOG_MAIN|LOG_PANIC, addr->message, fallback);
+    continue;
+    }
 
   /* Get the maximum it can handle in one envelope, with zero meaning
   unlimited, which is forced for the MUA wrapper case. */
 
   /* Get the maximum it can handle in one envelope, with zero meaning
   unlimited, which is forced for the MUA wrapper case. */
@@ -3915,26 +3926,35 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
   entirely different domains. The host list pointers can be NULL in the case
   where the hosts are defined in the transport. There is also a configured
   maximum limit of addresses that can be handled at once (see comments above
   entirely different domains. The host list pointers can be NULL in the case
   where the hosts are defined in the transport. There is also a configured
   maximum limit of addresses that can be handled at once (see comments above
-  for how it is computed). */
+  for how it is computed).
+  If the transport does not handle multiple domains, enforce that also,
+  and if it might need a per-address check for this, re-evaluate it.
+  */
 
   while ((next = *anchor) != NULL && address_count < address_count_max)
     {
 
   while ((next = *anchor) != NULL && address_count < address_count_max)
     {
-    if ((multi_domain || Ustrcmp(next->domain, addr->domain) == 0)
-        &&
-        tp == next->transport
-        &&
-        same_hosts(next->host_list, addr->host_list)
-        &&
-        same_strings(next->p.errors_address, addr->p.errors_address)
-        &&
-        same_headers(next->p.extra_headers, addr->p.extra_headers)
-        &&
-        same_ugid(tp, next, addr)
-        &&
-        (next->p.remove_headers == addr->p.remove_headers ||
-          (next->p.remove_headers != NULL &&
-           addr->p.remove_headers != NULL &&
-           Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0)))
+    BOOL md;
+    if (  (multi_domain || Ustrcmp(next->domain, addr->domain) == 0)
+       && tp == next->transport
+       && same_hosts(next->host_list, addr->host_list)
+       && same_strings(next->p.errors_address, addr->p.errors_address)
+       && same_headers(next->p.extra_headers, addr->p.extra_headers)
+       && same_ugid(tp, next, addr)
+       && (  next->p.remove_headers == addr->p.remove_headers
+         || (  next->p.remove_headers != NULL
+            && addr->p.remove_headers != NULL
+            && Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0
+         )  )
+       && (  !multi_domain
+         || (  (
+               !tp->expand_multi_domain || (deliver_set_expansions(next), 1),
+               exp_bool(addr,
+                   US"transport", next->transport->name, D_transport,
+                   US"multi_domain", next->transport->multi_domain,
+                   next->transport->expand_multi_domain, &md) == OK
+               )
+            && md
+       )  )  )
       {
       *anchor = next->next;
       next->next = NULL;
       {
       *anchor = next->next;
       next->next = NULL;
@@ -3944,6 +3964,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
       address_count++;
       }
     else anchor = &(next->next);
       address_count++;
       }
     else anchor = &(next->next);
+    deliver_set_expansions(NULL);
     }
 
   /* If we are acting as an MUA wrapper, all addresses must go in a single
     }
 
   /* If we are acting as an MUA wrapper, all addresses must go in a single
@@ -4793,8 +4814,56 @@ while (*s != 0)
 }
 
 
 }
 
 
+#ifdef EXPERIMENTAL_DSN
+/***********************************************************
+*         Print Diagnostic-Code for an address             *
+************************************************************/
+
+/* This function is called to print the error information out of an address for
+a bounce or a warning message. It tries to format the message reasonably as
+required by RFC 3461 by adding a space after each newline
+
+we assume that this function is only called if addr->host_used is set and if so
+a useable addr->message is available containing some Exim description with ": \n" 
+ending, followed by the L/SMTP error message.
+
+Arguments:
+  addr         the address
+  f            the FILE to print on
+
+Returns:       nothing
+*/
+
+static void
+print_dsn_diagnostic_code(const address_item *addr, FILE *f)
+{
+uschar * s;
+
+/* check host_used, af_pass_message flag and addr->message for safety reasons */
+if (!addr->host_used && testflag(addr, af_pass_message) && addr->message)
+  return;
+
+/* search first ": ". we assume to find the remote-MTA answer there */
+DEBUG(D_deliver)
+  debug_printf("DSN Diagnostic-Code: addr->dsn_message = %s\n", addr->message);
+if (!(s = Ustrstr(addr->message, ": ")))
+  return;                              /* not found, bail out */
+
+fprintf(f, "Diagnostic-Code: smtp; ");
 
 
+s += 2;  /* skip ": " */
+while (*s)
+  if (*s == '\\' && s[1] == 'n')
+    {
+    fputs("\n ", f);    /* as defined in RFC 3461 */
+    s += 2;
+    }
+  else
+    fputc(*s++, f);
 
 
+fputc('\n', f);
+}
+#endif  /* EXPERIMENTAL_DSN */
 
 
 /*************************************************
 
 
 /*************************************************
@@ -6660,14 +6729,13 @@ if (addr_senddsn != NULL)
     FILE *f = fdopen(fd, "wb");
     /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
     int topt = topt_add_return_path | topt_no_body;
     FILE *f = fdopen(fd, "wb");
     /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
     int topt = topt_add_return_path | topt_no_body;
-    uschar boundaryStr[64];
+    uschar * bound;
      
     DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address);
   
     /* build unique id for MIME boundary */
      
     DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address);
   
     /* build unique id for MIME boundary */
-    snprintf(boundaryStr, sizeof(boundaryStr)-1, TIME_T_FMT "-eximdsn-%d",
-      time(NULL), rand());
-    DEBUG(D_deliver) debug_printf("DSN: MIME boundary: %s\n", boundaryStr);
+    bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
+    DEBUG(D_deliver) debug_printf("DSN: MIME boundary: %s\n", bound);
   
     if (errors_reply_to)
       fprintf(f, "Reply-To: %s\n", errors_reply_to);
   
     if (errors_reply_to)
       fprintf(f, "Reply-To: %s\n", errors_reply_to);
@@ -6684,7 +6752,7 @@ if (addr_senddsn != NULL)
    
        "This message was created automatically by mail delivery software.\n"
        " ----- The following addresses had successful delivery notifications -----\n",
    
        "This message was created automatically by mail delivery software.\n"
        " ----- The following addresses had successful delivery notifications -----\n",
-      qualify_domain_sender, sender_address, boundaryStr, boundaryStr);
+      qualify_domain_sender, sender_address, bound, bound);
 
     addr_dsntmp = addr_senddsn;
     while(addr_dsntmp)
 
     addr_dsntmp = addr_senddsn;
     while(addr_dsntmp)
@@ -6702,7 +6770,7 @@ if (addr_senddsn != NULL)
     fprintf(f, "--%s\n"
        "Content-type: message/delivery-status\n\n"
        "Reporting-MTA: dns; %s\n",
     fprintf(f, "--%s\n"
        "Content-type: message/delivery-status\n\n"
        "Reporting-MTA: dns; %s\n",
-      boundaryStr, smtp_active_hostname);
+      bound, smtp_active_hostname);
 
     if (dsn_envid != NULL) {
       /* must be decoded from xtext: see RFC 3461:6.3a */
 
     if (dsn_envid != NULL) {
       /* must be decoded from xtext: see RFC 3461:6.3a */
@@ -6735,7 +6803,7 @@ if (addr_senddsn != NULL)
       fputc('\n', f);
       }
 
       fputc('\n', f);
       }
 
-    fprintf(f, "--%s\nContent-type: text/rfc822-headers\n\n", boundaryStr);
+    fprintf(f, "--%s\nContent-type: text/rfc822-headers\n\n", bound);
            
     fflush(f);
     transport_filter_argv = NULL;   /* Just in case */
            
     fflush(f);
     transport_filter_argv = NULL;   /* Just in case */
@@ -6745,8 +6813,7 @@ if (addr_senddsn != NULL)
     transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
     fflush(f);
 
     transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
     fflush(f);
 
-    fprintf(f,"\n");       
-    fprintf(f,"--%s--\n", boundaryStr);
+    fprintf(f,"\n--%s--\n", bound);
 
     fflush(f);
     fclose(f);
 
     fflush(f);
     fclose(f);
@@ -6871,7 +6938,7 @@ while (addr_failed != NULL)
       int max = (bounce_return_size_limit/DELIVER_IN_BUFFER_SIZE + 1) *
         DELIVER_IN_BUFFER_SIZE;
 #ifdef EXPERIMENTAL_DSN
       int max = (bounce_return_size_limit/DELIVER_IN_BUFFER_SIZE + 1) *
         DELIVER_IN_BUFFER_SIZE;
 #ifdef EXPERIMENTAL_DSN
-      uschar boundaryStr[64];
+      uschar * bound;
       uschar *dsnlimitmsg;
       uschar *dsnnotifyhdr;
       int topt;
       uschar *dsnlimitmsg;
       uschar *dsnnotifyhdr;
       int topt;
@@ -6931,13 +6998,12 @@ while (addr_failed != NULL)
 
 #ifdef EXPERIMENTAL_DSN
       /* generate boundary string and output MIME-Headers */
 
 #ifdef EXPERIMENTAL_DSN
       /* generate boundary string and output MIME-Headers */
-      snprintf(boundaryStr, sizeof(boundaryStr)-1, TIME_T_FMT "-eximdsn-%d",
-       time(NULL), rand());
+      bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
 
       fprintf(f, "Content-Type: multipart/report;"
            " report-type=delivery-status; boundary=%s\n"
          "MIME-Version: 1.0\n",
 
       fprintf(f, "Content-Type: multipart/report;"
            " report-type=delivery-status; boundary=%s\n"
          "MIME-Version: 1.0\n",
-       boundaryStr);
+       bound);
 #endif
 
       /* Open a template file if one is provided. Log failure to open, but
 #endif
 
       /* Open a template file if one is provided. Log failure to open, but
@@ -6967,7 +7033,7 @@ while (addr_failed != NULL)
       /* output human readable part as text/plain section */
       fprintf(f, "--%s\n"
          "Content-type: text/plain; charset=us-ascii\n\n",
       /* output human readable part as text/plain section */
       fprintf(f, "--%s\n"
          "Content-type: text/plain; charset=us-ascii\n\n",
-       boundaryStr);
+       bound);
 #endif
 
       if ((emf_text = next_emf(emf, US"intro")))
 #endif
 
       if ((emf_text = next_emf(emf, US"intro")))
@@ -7100,7 +7166,7 @@ wording. */
       fprintf(f, "--%s\n"
          "Content-type: message/delivery-status\n\n"
          "Reporting-MTA: dns; %s\n",
       fprintf(f, "--%s\n"
          "Content-type: message/delivery-status\n\n"
          "Reporting-MTA: dns; %s\n",
-       boundaryStr, smtp_active_hostname);
+       bound, smtp_active_hostname);
 
       if (dsn_envid)
        {
 
       if (dsn_envid)
        {
@@ -7120,8 +7186,11 @@ wording. */
            "Status: 5.0.0\n",
            addr->address);
         if (addr->host_used && addr->host_used->name)
            "Status: 5.0.0\n",
            addr->address);
         if (addr->host_used && addr->host_used->name)
-          fprintf(f, "Remote-MTA: dns; %s\nDiagnostic-Code: smtp; %d\n",
-           addr->host_used->name, addr->basic_errno);
+          {
+          fprintf(f, "Remote-MTA: dns; %s\n",
+           addr->host_used->name);
+          print_dsn_diagnostic_code(addr, f);
+          }
         }
 #endif
 
         }
 #endif
 
@@ -7202,7 +7271,7 @@ wording. */
          bounce_return_size_limit is always honored.
       */
   
          bounce_return_size_limit is always honored.
       */
   
-      fprintf(f, "\n--%s\n", boundaryStr);
+      fprintf(f, "\n--%s\n", bound);
 
       dsnlimitmsg = US"X-Exim-DSN-Information: Due to administrative limits only headers are returned";
       dsnnotifyhdr = NULL;
 
       dsnlimitmsg = US"X-Exim-DSN-Information: Due to administrative limits only headers are returned";
       dsnnotifyhdr = NULL;
@@ -7247,7 +7316,7 @@ wording. */
       if (emf)
         (void)fclose(emf);
  
       if (emf)
         (void)fclose(emf);
  
-      fprintf(f, "\n--%s--\n", boundaryStr);
+      fprintf(f, "\n--%s--\n", bound);
 #endif /*EXPERIMENTAL_DSN*/
 
       /* Close the file, which should send an EOF to the child process
 #endif /*EXPERIMENTAL_DSN*/
 
       /* Close the file, which should send an EOF to the child process
@@ -7553,7 +7622,7 @@ else if (addr_defer != (address_item *)(+1))
         FILE *wmf = NULL;
         FILE *f = fdopen(fd, "wb");
 #ifdef EXPERIMENTAL_DSN
         FILE *wmf = NULL;
         FILE *f = fdopen(fd, "wb");
 #ifdef EXPERIMENTAL_DSN
-       uschar boundaryStr[64];
+       uschar * bound;
 #endif
 
         if (warn_message_file)
 #endif
 
         if (warn_message_file)
@@ -7577,13 +7646,12 @@ else if (addr_defer != (address_item *)(+1))
 
 #ifdef EXPERIMENTAL_DSN
         /* generated boundary string and output MIME-Headers */
 
 #ifdef EXPERIMENTAL_DSN
         /* generated boundary string and output MIME-Headers */
-        snprintf(boundaryStr, sizeof(boundaryStr)-1,
-         TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
+        bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
 
         fprintf(f, "Content-Type: multipart/report;"
            " report-type=delivery-status; boundary=%s\n"
            "MIME-Version: 1.0\n",
 
         fprintf(f, "Content-Type: multipart/report;"
            " report-type=delivery-status; boundary=%s\n"
            "MIME-Version: 1.0\n",
-         boundaryStr);
+         bound);
 #endif
 
         if ((wmf_text = next_emf(wmf, US"header")))
 #endif
 
         if ((wmf_text = next_emf(wmf, US"header")))
@@ -7596,7 +7664,7 @@ else if (addr_defer != (address_item *)(+1))
         /* output human readable part as text/plain section */
         fprintf(f, "--%s\n"
            "Content-type: text/plain; charset=us-ascii\n\n",
         /* output human readable part as text/plain section */
         fprintf(f, "--%s\n"
            "Content-type: text/plain; charset=us-ascii\n\n",
-         boundaryStr);
+         bound);
 #endif
 
         if ((wmf_text = next_emf(wmf, US"intro")))
 #endif
 
         if ((wmf_text = next_emf(wmf, US"intro")))
@@ -7673,7 +7741,7 @@ else if (addr_defer != (address_item *)(+1))
         fprintf(f, "\n--%s\n"
            "Content-type: message/delivery-status\n\n"
            "Reporting-MTA: dns; %s\n",
         fprintf(f, "\n--%s\n"
            "Content-type: message/delivery-status\n\n"
            "Reporting-MTA: dns; %s\n",
-         boundaryStr,
+         bound,
          smtp_active_hostname);
  
 
          smtp_active_hostname);
  
 
@@ -7697,14 +7765,17 @@ else if (addr_defer != (address_item *)(+1))
           fprintf(f,"Final-Recipient: rfc822;%s\n", addr_dsndefer->address);
           fprintf(f,"Status: 4.0.0\n");
           if (addr_dsndefer->host_used && addr_dsndefer->host_used->name)
           fprintf(f,"Final-Recipient: rfc822;%s\n", addr_dsndefer->address);
           fprintf(f,"Status: 4.0.0\n");
           if (addr_dsndefer->host_used && addr_dsndefer->host_used->name)
-            fprintf(f,"Remote-MTA: dns; %s\nDiagnostic-Code: smtp; %d\n", 
-                   addr_dsndefer->host_used->name, addr_dsndefer->basic_errno);
+            {
+            fprintf(f,"Remote-MTA: dns; %s\n", 
+                   addr_dsndefer->host_used->name);
+            print_dsn_diagnostic_code(addr_dsndefer, f);
+            }
           addr_dsndefer = addr_dsndefer->next;
           }
 
         fprintf(f, "\n--%s\n"
            "Content-type: text/rfc822-headers\n\n",
           addr_dsndefer = addr_dsndefer->next;
           }
 
         fprintf(f, "\n--%s\n"
            "Content-type: text/rfc822-headers\n\n",
-         boundaryStr);
+         bound);
 
         fflush(f);
         /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
 
         fflush(f);
         /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
@@ -7715,7 +7786,7 @@ else if (addr_defer != (address_item *)(+1))
         transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
         fflush(f);
 
         transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
         fflush(f);
 
-        fprintf(f,"\n--%s--\n", boundaryStr);
+        fprintf(f,"\n--%s--\n", bound);
 
         fflush(f);
 #endif /*EXPERIMENTAL_DSN*/
 
         fflush(f);
 #endif /*EXPERIMENTAL_DSN*/