X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=e5c951560a0d9b6e71db3355ea0611bd4ecc7a4d;hb=687cac44312c8adc6f999882b49f0705bcb8613c;hp=139ee837424c76d644a42e0089a976aa65a9cf57;hpb=60272099eb6529d6d748c7dd04412b35c09f37e2;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index 139ee8374..e5c951560 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -9,6 +9,7 @@ #include "exim.h" +#include "transports/smtp.h" #include @@ -3890,14 +3891,12 @@ for (;;) /* Normally we do not repeat this loop */ maxpipe = 0; FD_ZERO(&select_pipes); for (poffset = 0; poffset < remote_max_parallel; poffset++) - { if (parlist[poffset].pid != 0) { int fd = parlist[poffset].fd; FD_SET(fd, &select_pipes); if (fd > maxpipe) maxpipe = fd; } - } /* Stick in a 60-second timeout, just in case. */ @@ -4455,14 +4454,31 @@ for (delivery_count = 0; addr_remote; delivery_count++) if (continue_transport) { BOOL ok = Ustrcmp(continue_transport, tp->name) == 0; - if (ok && addr->host_list) + + /* 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 + if the continued_hostname connection is suitable. This is a layering + violation which is unfortunate as it requires we haul in the smtp + include file. */ + + if (ok) { - host_item *h; - ok = FALSE; - for (h = addr->host_list; h; h = h->next) - if (Ustrcmp(h->name, continue_hostname) == 0) -/*XXX should also check port here */ - { ok = TRUE; break; } + smtp_transport_options_block * ob; + + if ( !( tp->info->driver_name == US"smtp" + && (ob = (smtp_transport_options_block *)tp->options_block) + && ob->hosts_override && ob->hosts + ) + && addr->host_list + ) + { + host_item * h; + ok = FALSE; + for (h = addr->host_list; h; h = h->next) + if (Ustrcmp(h->name, continue_hostname) == 0) + /*XXX should also check port here */ + { ok = TRUE; break; } + } } /* Addresses not suitable; defer or queue for fallback hosts (which @@ -4470,7 +4486,10 @@ for (delivery_count = 0; addr_remote; delivery_count++) if (!ok) { - DEBUG(D_deliver) debug_printf("not suitable for continue_transport\n"); + DEBUG(D_deliver) debug_printf("not suitable for continue_transport (%s)\n", + Ustrcmp(continue_transport, tp->name) != 0 + ? string_sprintf("tpt %s vs %s", continue_transport, tp->name) + : string_sprintf("no host matching %s", continue_hostname)); if (serialize_key) enq_end(serialize_key); if (addr->fallback_hosts && !fallback) @@ -4501,9 +4520,12 @@ for (delivery_count = 0; addr_remote; delivery_count++) /* Set a flag indicating whether there are further addresses that list the continued host. This tells the transport to leave the channel open, - but not to pass it to another delivery process. */ + but not to pass it to another delivery process. We'd like to do that + for non-continue_transport cases too but the knowlege of which host is + connected to is too hard to manage. Perhaps we need a finer-grain + interface to the transport. */ - for (next = addr_remote; next; next = next->next) + for (next = addr_remote; next && !continue_more; next = next->next) { host_item *h; for (h = next->host_list; h; h = h->next) @@ -4607,7 +4629,7 @@ for (delivery_count = 0; addr_remote; delivery_count++) predictable settings for each delivery process, so do something explicit here rather they rely on the fixed reset in the random number function. */ - random_seed = running_in_test_harness? 42 + 2*delivery_count : 0; + random_seed = running_in_test_harness ? 42 + 2*delivery_count : 0; /* Set close-on-exec on the pipe so that it doesn't get passed on to a new process that may be forked to do another delivery down the same @@ -6045,9 +6067,7 @@ spool if the message is deferred, and in any case there are casing complications for local addresses. */ if (process_recipients != RECIP_IGNORE) - { for (i = 0; i < recipients_count; i++) - { if (!tree_search(tree_nonrecipients, recipients_list[i].address)) { recipient_item *r = recipients_list + i; @@ -6163,8 +6183,6 @@ if (process_recipients != RECIP_IGNORE) } #endif } - } - } DEBUG(D_deliver) { @@ -6229,10 +6247,8 @@ while (addr_new) /* Loop until all addresses dealt with */ not exist. In both cases, dbm_file is NULL. */ if (!(dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE))) - { DEBUG(D_deliver|D_retry|D_route|D_hints_lookup) debug_printf("no retry data available\n"); - } /* Scan the current batch of new addresses, to handle pipes, files and autoreplies, and determine which others are ready for routing. */ @@ -6624,7 +6640,6 @@ while (addr_new) /* Loop until all addresses dealt with */ if ((rc = match_isinlist(addr->domain, (const uschar **)&queue_domains, 0, &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) != OK) - { if (rc == DEFER) { addr->basic_errno = ERRNO_LISTDEFER; @@ -6636,7 +6651,6 @@ while (addr_new) /* Loop until all addresses dealt with */ addr->next = okaddr; okaddr = addr; } - } else { addr->basic_errno = ERRNO_QUEUE_DOMAIN; @@ -6671,7 +6685,7 @@ while (addr_new) /* Loop until all addresses dealt with */ &addr_succeed, v_none)) == DEFER) retry_add_item(addr, addr->router->retry_use_local_part - ? string_sprintf("R:%s@%s", addr->local_part, addr->domain) + ? string_sprintf("R:%s@%s", addr->local_part, addr->domain) : string_sprintf("R:%s", addr->domain), 0); @@ -7280,8 +7294,9 @@ if (addr_senddsn) /* Write the original email out */ + tctx.u.fd = fileno(f); tctx.options = topt_add_return_path | topt_no_body; - transport_write_message(fileno(f), &tctx, 0); + transport_write_message(&tctx, 0); fflush(f); fprintf(f,"\n--%s--\n", bound); @@ -7740,11 +7755,12 @@ wording. */ transport_ctx tctx = {0}; transport_instance tb = {0}; + tctx.u.fd = fileno(f); tctx.tblock = &tb; tctx.options = topt; tb.add_headers = dsnnotifyhdr; - transport_write_message(fileno(f), &tctx, 0); + transport_write_message(&tctx, 0); } fflush(f); @@ -8205,12 +8221,13 @@ else if (addr_defer != (address_item *)(+1)) fflush(f); /* header only as required by RFC. only failure DSN needs to honor RET=FULL */ + tctx.u.fd = fileno(f); tctx.options = topt_add_return_path | topt_no_body; transport_filter_argv = NULL; /* Just in case */ return_path = sender_address; /* In case not previously set */ /* Write the original email out */ - transport_write_message(fileno(f), &tctx, 0); + transport_write_message(&tctx, 0); fflush(f); fprintf(f,"\n--%s--\n", bound); @@ -8471,12 +8488,14 @@ if (cutthrough.fd >= 0 && cutthrough.callout_hold_only) else if (pid == 0) /* child: fork again to totally dosconnect */ { + close(pfd[1]); if ((pid = fork())) _exit(pid ? EXIT_FAILURE : EXIT_SUCCESS); smtp_proxy_tls(big_buffer, big_buffer_size, pfd[0], 5*60); exim_exit(0); } + close(pfd[0]); waitpid(pid, NULL, 0); (void) close(channel_fd); /* release the client socket */ channel_fd = pfd[1];