X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=4bc8c5f2c56aedc3f96d5193050b71f16d13c577;hb=0e8a94711a90ed63933a10ac7598e8743432837c;hp=fdff074142b8ec5687ed7f79d3195a0ec84d878e;hpb=148e1ac6c5645e53f4f80eeb4978565b5ca4233b;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index fdff07414..4bc8c5f2c 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/deliver.c,v 1.35 2006/07/04 09:07:20 ph10 Exp $ */ +/* $Cambridge: exim/src/src/deliver.c,v 1.42 2007/01/23 12:33:08 magnus Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2006 */ +/* Copyright (c) University of Cambridge 1995 - 2007 */ /* See the file NOTICE for conditions of use and distribution. */ /* The main code for delivering a message. */ @@ -774,7 +774,7 @@ if (addr->return_file >= 0 && addr->return_filename != NULL) { BOOL return_output = FALSE; struct stat statbuf; - fsync(addr->return_file); + (void)EXIMfsync(addr->return_file); /* If there is no output, do nothing. */ @@ -1433,10 +1433,10 @@ int rc = OK; int size_limit; deliver_set_expansions(addr); -size_limit = expand_string_integer(tp->message_size_limit); +size_limit = expand_string_integer(tp->message_size_limit, TRUE); deliver_set_expansions(NULL); -if (size_limit < 0) +if (expand_string_message != NULL) { rc = DEFER; if (size_limit == -1) @@ -1979,7 +1979,7 @@ if (!shadowing) /* Ensure the journal file is pushed out to disk. */ - if (fsync(journal_fd) < 0) + if (EXIMfsync(journal_fd) < 0) log_write(0, LOG_MAIN|LOG_PANIC, "failed to fsync journal: %s", strerror(errno)); } @@ -4941,6 +4941,9 @@ else if (system_filter != NULL && process_recipients != RECIP_FAIL_TIMEOUT) while (p != NULL) { + if (parent->child_count == SHRT_MAX) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "system filter generated more " + "than %d delivery addresses", SHRT_MAX); parent->child_count++; p->parent = parent; @@ -5452,8 +5455,10 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ } /* Get the routing retry status, saving the two retry keys (with and - without the local part) for subsequent use. Ignore retry records that - are too old. */ + without the local part) for subsequent use. If there is no retry record for + the standard address routing retry key, we look for the same key with the + sender attached, because this form is used by the smtp transport after a + 4xx response to RCPT when address_retry_include_sender is true. */ addr->domain_retry_key = string_sprintf("R:%s", addr->domain); addr->address_retry_key = string_sprintf("R:%s@%s", addr->local_part, @@ -5466,12 +5471,22 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ domain_retry_record = dbfn_read(dbm_file, addr->domain_retry_key); if (domain_retry_record != NULL && now - domain_retry_record->time_stamp > retry_data_expire) - domain_retry_record = NULL; + domain_retry_record = NULL; /* Ignore if too old */ address_retry_record = dbfn_read(dbm_file, addr->address_retry_key); if (address_retry_record != NULL && now - address_retry_record->time_stamp > retry_data_expire) - address_retry_record = NULL; + address_retry_record = NULL; /* Ignore if too old */ + + if (address_retry_record == NULL) + { + uschar * altkey = string_sprintf("%s:<%s>", addr->address_retry_key, + sender_address); + address_retry_record = dbfn_read(dbm_file, altkey); + if (address_retry_record != NULL && + now - address_retry_record->time_stamp > retry_data_expire) + address_retry_record = NULL; /* Ignore if too old */ + } } DEBUG(D_deliver|D_retry) @@ -5503,19 +5518,29 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ (void)post_process_one(addr, DEFER, LOG_MAIN, DTYPE_ROUTER, 0); } - /* If queue_running, defer routing unless no retry data or we've - passed the next retry time, or this message is forced. However, - if the retry time has expired, allow the routing attempt. - If it fails again, the address will be failed. This ensures that + /* If we are in a queue run, defer routing unless there is no retry data or + we've passed the next retry time, or this message is forced. In other + words, ignore retry data when not in a queue run. + + However, if the domain retry time has expired, always allow the routing + attempt. If it fails again, the address will be failed. This ensures that each address is routed at least once, even after long-term routing failures. If there is an address retry, check that too; just wait for the next retry time. This helps with the case when the temporary error on the address was really message-specific rather than address specific, since - it allows other messages through. */ + it allows other messages through. + + We also wait for the next retry time if this is a message sent down an + existing SMTP connection (even though that will be forced). Otherwise there + will be far too many attempts for an address that gets a 4xx error. In + fact, after such an error, we should not get here because, the host should + not be remembered as one this message needs. However, there was a bug that + used to cause this to happen, so it is best to be on the safe side. */ - else if (!deliver_force && queue_running && + else if (((queue_running && !deliver_force) || continue_hostname != NULL) + && ((domain_retry_record != NULL && now < domain_retry_record->next_try && !domain_retry_record->expired) @@ -6547,6 +6572,9 @@ if (addr_defer == NULL) readconf_printtime(time(NULL) - received_time)); else log_write(0, LOG_MAIN, "Completed"); + + /* Unset deliver_freeze so that we won't try to move the spool files further down */ + deliver_freeze = FALSE; } /* If there are deferred addresses, we are keeping this message because it is