X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=1421852aa1e8f8aba2216e2567b5720dec9a22a2;hb=fc16abb4d06c7ae375b227bd83473412c8985c6f;hp=d85f010e61d2fe8a5ba4f2fa5666009964703fbf;hpb=0cbf2b821bb13da0268556d0e30ea627d5592c60;p=exim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index d85f010e6..1421852aa 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* The main code for delivering a message. */ @@ -703,7 +703,7 @@ if (LOGGING(incoming_interface) && LOGGING(outgoing_interface) s = LOGGING(outgoing_port) ? string_append(s, sizep, ptrp, 2, US"]:", string_sprintf("%d", sending_port)) - : string_cat(s, sizep, ptrp, US"]", 1); + : string_catn(s, sizep, ptrp, US"]", 1); } return s; } @@ -711,25 +711,31 @@ return s; static uschar * -d_hostlog(uschar *s, int *sizep, int *ptrp, address_item *addr) +d_hostlog(uschar * s, int * sp, int * pp, address_item * addr) { -s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name, - US" [", addr->host_used->address, US"]"); +host_item * h = addr->host_used; + +s = string_append(s, sp, pp, 2, US" H=", h->name); + +if (LOGGING(dnssec) && h->dnssec == DS_YES) + s = string_cat(s, sp, pp, US" DS"); + +s = string_append(s, sp, pp, 3, US" [", h->address, US"]"); + if (LOGGING(outgoing_port)) - s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d", - addr->host_used->port)); + s = string_append(s, sp, pp, 2, US":", string_sprintf("%d", h->port)); #ifdef SUPPORT_SOCKS if (LOGGING(proxy) && proxy_local_address) { - s = string_append(s, sizep, ptrp, 3, US" PRX=[", proxy_local_address, US"]"); + s = string_append(s, sp, pp, 3, US" PRX=[", proxy_local_address, US"]"); if (LOGGING(outgoing_port)) - s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d", + s = string_append(s, sp, pp, 2, US":", string_sprintf("%d", proxy_local_port)); } #endif -return d_log_interface(s, sizep, ptrp); +return d_log_interface(s, sp, pp); } @@ -914,8 +920,7 @@ if (addr->transport->info->local) s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name); s = d_log_interface(s, &size, &ptr); if (addr->shadow_message) - s = string_cat(s, &size, &ptr, addr->shadow_message, - Ustrlen(addr->shadow_message)); + s = string_cat(s, &size, &ptr, addr->shadow_message); } /* Remote delivery */ @@ -926,7 +931,7 @@ else { s = d_hostlog(s, &size, &ptr, addr); if (continue_sequence > 1) - s = string_cat(s, &size, &ptr, US"*", 1); + s = string_catn(s, &size, &ptr, US"*", 1); #ifndef DISABLE_EVENT deliver_host_address = addr->host_used->address; @@ -1077,23 +1082,9 @@ malformed, it won't ever have gone near LDAP.) */ if (addr->message) { const uschar * s = string_printing(addr->message); - if (s != addr->message) - addr->message = US s; - /* deconst cast ok as string_printing known to have alloc'n'copied */ - if ( ( Ustrstr(s, "failed to expand") != NULL - || Ustrstr(s, "expansion of ") != NULL - ) - && ( Ustrstr(s, "mysql") != NULL - || Ustrstr(s, "pgsql") != NULL -#ifdef EXPERIMENTAL_REDIS - || Ustrstr(s, "redis") != NULL -#endif - || Ustrstr(s, "sqlite") != NULL - || Ustrstr(s, "ldap:") != NULL - || Ustrstr(s, "ldapdn:") != NULL - || Ustrstr(s, "ldapm:") != NULL - ) ) - addr->message = string_sprintf("Temporary internal error"); + + /* deconst cast ok as string_printing known to have alloc'n'copied */ + addr->message = expand_hide_passwords(US s); } /* If we used a transport that has one of the "return_output" options set, and @@ -1280,7 +1271,7 @@ else if (result == DEFER || result == PANIC) log_address = string_log_address(addr, LOGGING(all_parents), result == OK); - s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address)); + s = string_cat(s, &size, &ptr, log_address); /* Either driver_name contains something and driver_kind contains " router" or " transport" (note the leading space), or driver_name is @@ -1300,7 +1291,7 @@ else if (result == DEFER || result == PANIC) s = string_append(s, &size, &ptr, 2, US" ", driver_kind); sprintf(CS ss, " defer (%d)", addr->basic_errno); - s = string_cat(s, &size, &ptr, ss, Ustrlen(ss)); + s = string_cat(s, &size, &ptr, ss); if (addr->basic_errno > 0) s = string_append(s, &size, &ptr, 2, US": ", @@ -1398,7 +1389,7 @@ else log_address = string_log_address(addr, LOGGING(all_parents), result == OK); - s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address)); + s = string_cat(s, &size, &ptr, log_address); if (LOGGING(sender_on_delivery)) s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">"); @@ -2222,6 +2213,7 @@ for (addr2 = addr; addr2; addr2 = addr2->next) if (message_length > 0) { len = read(pfd[pipe_read], big_buffer, message_length); + big_buffer[big_buffer_size-1] = '\0'; /* guard byte */ if (len > 0) *sptr = string_copy(big_buffer); } } @@ -3857,7 +3849,8 @@ static void rmt_dlv_checked_write(int fd, char id, char subid, void * buf, int size) { uschar writebuffer[PIPE_HEADER_SIZE + BIG_BUFFER_SIZE]; -int header_length; +int header_length; +int ret; /* we assume that size can't get larger then BIG_BUFFER_SIZE which currently is set to 16k */ /* complain to log if someone tries with buffer sizes we can't handle*/ @@ -3887,8 +3880,7 @@ if (buf && size > 0) memcpy(writebuffer + PIPE_HEADER_SIZE, buf, size); size += PIPE_HEADER_SIZE; -int ret = write(fd, writebuffer, size); -if(ret != size) +if ((ret = write(fd, writebuffer, size)) != size) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed writing transport result to pipe: %s\n", ret == -1 ? strerror(errno) : "short write"); } @@ -4245,7 +4237,7 @@ for (delivery_count = 0; addr_remote; delivery_count++) addr_fallback = addr; } - else + else if (next) { while (next->next) next = next->next; next->next = addr_defer; @@ -4833,7 +4825,7 @@ if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0) para = store_get(size); for (;;) { - para = string_cat(para, &size, &ptr, buffer, Ustrlen(buffer)); + para = string_cat(para, &size, &ptr, buffer); if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0) break; } @@ -5228,7 +5220,7 @@ Any failures cause messages to be written to the log, except for missing files while queue running - another process probably completed delivery. As part of opening the data file, message_subdir gets set. */ -if (!spool_open_datafile(id)) +if ((deliver_datafile = spool_open_datafile(id)) < 0) return continue_closedown(); /* yields DELIVER_NOT_ATTEMPTED */ /* The value of message_size at this point has been set to the data length, @@ -6842,16 +6834,13 @@ prevents actual delivery. */ else if (!dont_deliver) retry_update(&addr_defer, &addr_failed, &addr_succeed); -/* Send DSN for successful messages */ -addr_dsntmp = addr_succeed; +/* Send DSN for successful messages if requested */ addr_senddsn = NULL; -while(addr_dsntmp) +for (addr_dsntmp = addr_succeed; addr_dsntmp; addr_dsntmp = addr_dsntmp->next) { /* af_ignore_error not honored here. it's not an error */ - DEBUG(D_deliver) - { - debug_printf("DSN: processing router : %s\n" + DEBUG(D_deliver) debug_printf("DSN: processing router : %s\n" "DSN: processing successful delivery address: %s\n" "DSN: Sender_address: %s\n" "DSN: orcpt: %s flags: %d\n" @@ -6866,7 +6855,6 @@ while(addr_dsntmp) addr_dsntmp->address, addr_dsntmp->dsn_aware ); - } /* send report if next hop not DSN aware or a router flagged "last DSN hop" and a report was requested */ @@ -6886,8 +6874,6 @@ while(addr_dsntmp) } else DEBUG(D_deliver) debug_printf("DSN: not sending DSN success message\n"); - - addr_dsntmp = addr_dsntmp->next; } if (addr_senddsn) @@ -6961,7 +6947,7 @@ if (addr_senddsn) if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0) fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid); else - fprintf(f, "X-Original-Envelope-ID: error decoding xtext formated ENVID\n"); + fprintf(f, "X-Original-Envelope-ID: error decoding xtext formatted ENVID\n"); } fputc('\n', f); @@ -7347,7 +7333,7 @@ wording. */ if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0) fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid); else - fprintf(f, "X-Original-Envelope-ID: error decoding xtext formated ENVID\n"); + fprintf(f, "X-Original-Envelope-ID: error decoding xtext formatted ENVID\n"); } fputc('\n', f); @@ -7409,6 +7395,9 @@ wording. */ if (dsn_ret == dsn_ret_hdrs) topt |= topt_no_body; else + { + struct stat statbuf; + /* no full body return at all? */ if (!bounce_return_body) { @@ -7417,16 +7406,18 @@ wording. */ if (dsn_ret == dsn_ret_full) dsnnotifyhdr = dsnlimitmsg; } + /* line length limited... return headers only if oversize */ /* size limited ... return headers only if limit reached */ - else if (bounce_return_size_limit > 0) - { - struct stat statbuf; - if (fstat(deliver_datafile, &statbuf) == 0 && statbuf.st_size > max) - { - topt |= topt_no_body; - dsnnotifyhdr = dsnlimitmsg; - } + else if ( max_received_linelength > bounce_return_linesize_limit + || ( bounce_return_size_limit > 0 + && fstat(deliver_datafile, &statbuf) == 0 + && statbuf.st_size > max + ) ) + { + topt |= topt_no_body; + dsnnotifyhdr = dsnlimitmsg; } + } #ifdef SUPPORT_I18N if (message_smtputf8) @@ -7756,6 +7747,7 @@ else if (addr_defer != (address_item *)(+1)) FILE *wmf = NULL; FILE *f = fdopen(fd, "wb"); uschar * bound; + int topt; if (warn_message_file) if (!(wmf = Ufopen(warn_message_file, "rb"))) @@ -7874,7 +7866,7 @@ else if (addr_defer != (address_item *)(+1)) if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0) fprintf(f,"Original-Envelope-ID: %s\n", dsn_envid); else - fprintf(f,"X-Original-Envelope-ID: error decoding xtext formated ENVID\n"); + fprintf(f,"X-Original-Envelope-ID: error decoding xtext formatted ENVID\n"); } fputc('\n', f); @@ -7902,7 +7894,7 @@ else if (addr_defer != (address_item *)(+1)) fflush(f); /* header only as required by RFC. only failure DSN needs to honor RET=FULL */ - int topt = topt_add_return_path | topt_no_body; + topt = 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 */ @@ -8093,8 +8085,17 @@ deliver_get_sender_address (uschar * id) int rc; uschar * new_sender_address, * save_sender_address; +BOOL save_qr = queue_running; + +/* make spool_open_datafile non-noisy on fail */ + +queue_running = TRUE; + +/* Side effect: message_subdir is set for the (possibly split) spool directory */ -if (!spool_open_datafile(id)) +deliver_datafile = spool_open_datafile(id); +queue_running = save_qr; +if (deliver_datafile < 0) return NULL; /* Save and restore the global sender_address. I'm not sure if we should