deliver
[exim.git] / src / src / deliver.c
index 85b061b303559810500a27e6927e9b41ca49b99b..87e944b03799d0b92cf36e7880adf89cb1546574 100644 (file)
@@ -460,6 +460,9 @@ TRUE if the lists refer to the same hosts in the same order, except that
 This enables Exim to use a single SMTP transaction for sending to two entirely
 different domains that happen to end up pointing at the same hosts.
 
+We do not try to batch up different A-record host names that refer to the
+same IP.
+
 Arguments:
   one       points to the first host list
   two       points to the second host list
@@ -1192,7 +1195,7 @@ else
   if (addr->host_used)
     {
     g = d_hostlog(g, addr);
-    if (continue_sequence > 1)
+    if (continue_sequence > 1)         /*XXX this is wrong for a dropped proxyconn.  Would have to pass back from transport */
       g = string_catn(g, US"*", 1);
 
 #ifndef DISABLE_EVENT
@@ -4272,6 +4275,10 @@ for (int delivery_count = 0; addr_remote; delivery_count++)
       }
     }
 
+/*XXX need to defeat this when DANE is used - but we don't know that yet.
+So look out for the place it gets used.
+*/
+
   /* Get the flag which specifies whether the transport can handle different
   domains that nevertheless resolve to the same set of hosts. If it needs
   expanding, get variables set: $address_data, $domain_data, $localpart_data,
@@ -4350,6 +4357,11 @@ for (int delivery_count = 0; addr_remote; delivery_count++)
   /************************************************************************/
 
 
+/*XXX don't know yet if DANE will be used.  So tpt will have to
+check at the point if gets next addr from list, and skip/defer any
+nonmatch domains
+*/
+
   /* Pick off all addresses which have the same transport, errors address,
   destination, and extra headers. In some cases they point to the same host
   list, but we also need to check for identical host lists generated from
@@ -4496,6 +4508,7 @@ for (int delivery_count = 0; addr_remote; delivery_count++)
   if (continue_transport)
     {
     BOOL ok = Ustrcmp(continue_transport, tp->name) == 0;
+/*XXX do we need to check for a DANEd conn vs. a change of domain? */
 
     /* If the transport is about to override the host list do not check
     it here but take the cost of running the transport process to discover
@@ -5380,7 +5393,8 @@ Returns:       nothing
 static void
 print_dsn_diagnostic_code(const address_item *addr, FILE *f)
 {
-uschar *s = testflag(addr, af_pass_message) ? addr->message : NULL;
+uschar * s = testflag(addr, af_pass_message) ? addr->message : NULL;
+unsigned cnt;
 
 /* af_pass_message and addr->message set ? print remote host answer */
 if (s)
@@ -5392,19 +5406,32 @@ if (s)
   if (!(s = Ustrstr(addr->message, ": ")))
     return;                            /* not found, bail out */
   s += 2;  /* skip ": " */
-  fprintf(f, "Diagnostic-Code: smtp; ");
+  cnt = fprintf(f, "Diagnostic-Code: smtp; ");
   }
 /* no message available. do nothing */
 else return;
 
 while (*s)
+  {
+  if (cnt > 950)       /* RFC line length limit: 998 */
+    {
+    DEBUG(D_deliver) debug_printf("print_dsn_diagnostic_code() truncated line\n");
+    fputs("[truncated]", f);
+    break;
+    }
+
   if (*s == '\\' && s[1] == 'n')
     {
     fputs("\n ", f);    /* as defined in RFC 3461 */
     s += 2;
+    cnt += 2;
     }
   else
+    {
     fputc(*s++, f);
+    cnt++;
+    }
+  }
 
 fputc('\n', f);
 }
@@ -5511,10 +5538,11 @@ FILE * fp = NULL;
 if (!s || !*s)
   log_write(0, LOG_MAIN|LOG_PANIC,
     "Failed to expand %s: '%s'\n", varname, filename);
-else if (*s != '/' || is_tainted(s))
-  log_write(0, LOG_MAIN|LOG_PANIC,
-    "%s is not %s after expansion: '%s'\n",
-    varname, *s == '/' ? "untainted" : "absolute", s);
+else if (*s != '/')
+  log_write(0, LOG_MAIN|LOG_PANIC, "%s is not absolute after expansion: '%s'\n",
+    varname, s);
+else if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted %s after expansion: '%s'\n", varname, s))
+  ;
 else if (!(fp = Ufopen(s, "rb")))
   log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for %s "
     "message texts: %s", s, reason, strerror(errno));
@@ -6121,12 +6149,14 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT)
           {
           uschar *tmp = expand_string(tpname);
           address_file = address_pipe = NULL;
+          uschar *m;
           if (!tmp)
             p->message = string_sprintf("failed to expand \"%s\" as a "
               "system filter transport name", tpname);
-         if (is_tainted(tmp))
-            p->message = string_sprintf("attempt to used tainted value '%s' for"
-             "transport '%s' as a system filter", tmp, tpname);
+          { uschar *m;
+         if (m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname))
+            p->message = m;
+          }
           tpname = tmp;
           }
         else
@@ -7052,10 +7082,20 @@ if (  mua_wrapper
 
 
 /* If this is a run to continue deliveries to an external channel that is
-already set up, defer any local deliveries. */
+already set up, defer any local deliveries.
 
-if (continue_transport)
+jgh 2020/12/20: I don't see why; locals should be quick.
+The defer goes back to version 1.62 in 1997.  A local being still deliverable
+during a continued run might result from something like a defer during the
+original delivery, eg. in a DB lookup.  Unlikely but possible.
+
+To avoid delaying a local when combined with a callout-hold for a remote
+delivery, test continue_sequence rather than continue_transport. */
+
+if (continue_sequence > 1 && addr_local)
   {
+  DEBUG(D_deliver|D_retry|D_route)
+    debug_printf("deferring local deliveries due to continued-transport\n");
   if (addr_defer)
     {
     address_item *addr = addr_defer;
@@ -7831,11 +7871,11 @@ wording. */
            fprintf(fp, "Remote-MTA: X-ip; [%s]%s\n", hu->address, p);
            }
          if ((s = addr->smtp_greeting) && *s)
-           fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %s\n", s);
+           fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %.900s\n", s);
          if ((s = addr->helo_response) && *s)
-           fprintf(fp, "X-Remote-MTA-helo-response: X-str; %s\n", s);
+           fprintf(fp, "X-Remote-MTA-helo-response: X-str; %.900s\n", s);
          if ((s = addr->message) && *s)
-           fprintf(fp, "X-Exim-Diagnostic: X-str; %s\n", s);
+           fprintf(fp, "X-Exim-Diagnostic: X-str; %.900s\n", s);
          }
 #endif
          print_dsn_diagnostic_code(addr, fp);