X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/92914be2140997c19f610d7f5f17fa0d9c347b9c..HEAD:/src/src/deliver.c diff --git a/src/src/deliver.c b/src/src/deliver.c index c9a1d074b..eadc96d22 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2020 - 2023 */ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -27,7 +27,7 @@ typedef struct pardata { int transport_count; /* returned transport count value */ BOOL done; /* no more data needed */ uschar *msg; /* error message */ - uschar *return_path; /* return_path for these addresses */ + const uschar *return_path; /* return_path for these addresses */ } pardata; /* Values for the process_recipients variable */ @@ -77,7 +77,7 @@ static pardata *parlist = NULL; static struct pollfd *parpoll; static int return_count; static uschar *frozen_info = US""; -static uschar *used_return_path = NULL; +static const uschar * used_return_path = NULL; @@ -144,7 +144,7 @@ Returns: a pointer to an initialized address_item */ address_item * -deliver_make_addr(uschar *address, BOOL copy) +deliver_make_addr(const uschar * address, BOOL copy) { address_item * addr = store_get(sizeof(address_item), GET_UNTAINTED); *addr = address_defaults; @@ -575,7 +575,7 @@ Returns: TRUE or FALSE */ static BOOL -same_strings(uschar *one, uschar *two) +same_strings(const uschar * one, const uschar * two) { if (one == two) return TRUE; /* Includes the case where both NULL */ if (!one || !two) return FALSE; @@ -859,9 +859,10 @@ Return: string expansion from listener, or NULL */ uschar * -event_raise(uschar * action, const uschar * event, uschar * ev_data, int * errnop) +event_raise(const uschar * action, const uschar * event, const uschar * ev_data, + int * errnop) { -uschar * s; +const uschar * s; if (action) { DEBUG(D_deliver) @@ -872,7 +873,7 @@ if (action) event_name = event; event_data = ev_data; - if (!(s = expand_string(action)) && *expand_string_message) + if (!(s = expand_cstring(action)) && *expand_string_message) log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand event_action %s in %s: %s\n", event, transport_name ? transport_name : US"main", expand_string_message); @@ -880,7 +881,8 @@ if (action) event_name = event_data = NULL; /* If the expansion returns anything but an empty string, flag for - the caller to modify his normal processing + the caller to modify his normal processing. Copy the string to + de-const it. */ if (s && *s) { @@ -888,7 +890,7 @@ if (action) debug_printf("Event(%s): event_action returned \"%s\"\n", event, s); if (errnop) *errnop = ERRNO_EVENT; - return s; + return string_copy(s); } } return NULL; @@ -898,9 +900,10 @@ void msg_event_raise(const uschar * event, const address_item * addr) { const uschar * save_domain = deliver_domain; -uschar * save_local = deliver_localpart; +const uschar * save_local = deliver_localpart; const uschar * save_host = deliver_host; const uschar * save_address = deliver_host_address; +uschar * save_rn = router_name, * save_tn = transport_name; const int save_port = deliver_host_port; router_name = addr->router ? addr->router->name : NULL; @@ -937,7 +940,8 @@ deliver_host_address = save_address; deliver_host = save_host; deliver_localpart = save_local; deliver_domain = save_domain; -router_name = transport_name = NULL; +router_name = save_rn; +transport_name = save_tn; } #endif /*DISABLE_EVENT*/ @@ -950,13 +954,13 @@ router_name = transport_name = NULL; * Generate local part for logging * *************************************************/ -static uschar * -string_get_lpart_sub(const address_item * addr, uschar * s) +static const uschar * +string_get_lpart_sub(const address_item * addr, const uschar * s) { #ifdef SUPPORT_I18N if (testflag(addr, af_utf8_downcvt)) { - uschar * t = string_localpart_utf8_to_alabel(s, NULL); + const uschar * t = string_localpart_utf8_to_alabel(s, NULL); return t ? t : s; /* t is NULL on a failed conversion */ } #endif @@ -975,7 +979,7 @@ Returns: the new value of the buffer pointer static gstring * string_get_localpart(address_item * addr, gstring * yield) { -uschar * s; +const uschar * s; if (testflag(addr, af_include_affixes) && (s = addr->prefix)) yield = string_cat(yield, string_get_lpart_sub(addr, s)); @@ -1245,6 +1249,14 @@ else g = string_catn(g, US" K", 2); } +#ifndef DISABLE_DKIM + if (addr->dkim_used && LOGGING(dkim_verbose)) + { + g = string_catn(g, US" DKIM=", 6); + g = string_cat(g, addr->dkim_used); + } +#endif + /* confirmation message (SMTP (host_used) and LMTP (driver_name)) */ if ( LOGGING(smtp_confirmation) @@ -1850,8 +1862,9 @@ if (tp->gid_set) } else if (tp->expand_gid) { + GET_OPTION("group"); if (!route_find_expanded_group(tp->expand_gid, tp->name, US"transport", gidp, - &(addr->message))) + &addr->message)) { common_error(FALSE, addr, ERRNO_GIDFAIL, NULL); return FALSE; @@ -1877,6 +1890,7 @@ it does not provide a passwd value from which a gid can be taken. */ else if (tp->expand_uid) { struct passwd *pw; + GET_OPTION("user"); if (!route_find_expanded_user(tp->expand_uid, tp->name, US"transport", &pw, uidp, &(addr->message))) { @@ -1980,6 +1994,7 @@ check_message_size(transport_instance *tp, address_item *addr) int rc = OK; int size_limit; +GET_OPTION("message_size_limit"); deliver_set_expansions(addr); size_limit = expand_string_integer(tp->message_size_limit, TRUE); deliver_set_expansions(NULL); @@ -2028,7 +2043,7 @@ static BOOL previously_transported(address_item *addr, BOOL testing) { uschar * s = string_sprintf("%s/%s", - addr->unique + (testflag(addr, af_homonym)? 3:0), addr->transport->name); + addr->unique + (testflag(addr, af_homonym) ? 3:0), addr->transport->name); if (tree_search(tree_nonrecipients, s) != 0) { @@ -2142,6 +2157,7 @@ if(addr->prop.errors_address) else return_path = sender_address; +GET_OPTION("return_path"); if (tp->return_path) { uschar * new_return_path = expand_string(tp->return_path); @@ -2171,6 +2187,7 @@ if (!findugid(addr, tp, &uid, &gid, &use_initgroups)) return; home directory set in the address may already be expanded; a flag is set to indicate that. In other cases we must expand it. */ +GET_OPTION("home_directory"); if ( (deliver_home = tp->home_dir) /* Set in transport, or */ || ( (deliver_home = addr->home_dir) /* Set in address and */ && !testflag(addr, af_home_expanded) /* not expanded */ @@ -2200,6 +2217,7 @@ all users have access. It is necessary to be in a visible directory for some operating systems when running pipes, as some commands (e.g. "rm" under Solaris 2.5) require this. */ +GET_OPTION("current_directory"); working_directory = tp->current_dir ? tp->current_dir : addr->current_dir; if (working_directory) { @@ -2444,8 +2462,7 @@ if ((pid = exim_fork(US"delivery-local")) == 0) and close the pipe we were writing down before exiting. */ (void)close(pfd[pipe_write]); - search_tidyup(); - exit(EXIT_SUCCESS); + exim_exit(EXIT_SUCCESS); } /* Back in the main process: panic if the fork did not succeed. This seems @@ -2597,36 +2614,40 @@ if ((status & 0xffff) != 0) /* If SPECIAL_WARN is set in the top address, send a warning message. */ -if (addr->special_action == SPECIAL_WARN && addr->transport->warn_message) +if (addr->special_action == SPECIAL_WARN) { - int fd; - uschar *warn_message; - pid_t pid; + uschar * warn_message = addr->transport->warn_message; + GET_OPTION("quota_warn_message"); + if (warn_message) + { + int fd; + pid_t pid; - DEBUG(D_deliver) debug_printf("Warning message requested by transport\n"); + DEBUG(D_deliver) debug_printf("Warning message requested by transport\n"); - if (!(warn_message = expand_string(addr->transport->warn_message))) - log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand \"%s\" (warning " - "message for %s transport): %s", addr->transport->warn_message, - addr->transport->name, expand_string_message); + if (!(warn_message = expand_string(warn_message))) + log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand \"%s\" (warning " + "message for %s transport): %s", addr->transport->warn_message, + addr->transport->name, expand_string_message); - else if ((pid = child_open_exim(&fd, US"tpt-warning-message")) > 0) - { - FILE *f = fdopen(fd, "wb"); - if (errors_reply_to && !contains_header(US"Reply-To", warn_message)) - fprintf(f, "Reply-To: %s\n", errors_reply_to); - fprintf(f, "Auto-Submitted: auto-replied\n"); - if (!contains_header(US"From", warn_message)) - moan_write_from(f); - fprintf(f, "%s", CS warn_message); + else if ((pid = child_open_exim(&fd, US"tpt-warning-message")) > 0) + { + FILE * f = fdopen(fd, "wb"); + if (errors_reply_to && !contains_header(US"Reply-To", warn_message)) + fprintf(f, "Reply-To: %s\n", errors_reply_to); + fprintf(f, "Auto-Submitted: auto-replied\n"); + if (!contains_header(US"From", warn_message)) + moan_write_from(f); + fprintf(f, "%s", CS warn_message); - /* Close and wait for child process to complete, without a timeout. */ + /* Close and wait for child process to complete, without a timeout. */ - (void)fclose(f); - (void)child_close(pid, 0); - } + (void)fclose(f); + (void)child_close(pid, 0); + } - addr->special_action = SPECIAL_NONE; + addr->special_action = SPECIAL_NONE; + } } } @@ -2642,6 +2663,7 @@ tpt_parallel_check(transport_instance * tp, address_item * addr, uschar ** key) { unsigned max_parallel; +GET_OPTION("max_parallel"); if (!tp->max_parallel) return FALSE; max_parallel = (unsigned) expand_string_integer(tp->max_parallel, TRUE); @@ -2765,6 +2787,7 @@ while (addr_local) /* Expand the batch_id string for comparison with other addresses. Expansion failure suppresses batching. */ + GET_OPTION("batch_id"); if (tp->batch_id) { deliver_set_expansions(addr); @@ -2819,11 +2842,12 @@ while (addr_local) if (ok && batch_id) { - uschar *bid; - address_item *save_nextnext = next->next; + uschar * bid; + address_item * save_nextnext = next->next; next->next = NULL; /* Expansion for a single address */ deliver_set_expansions(next); next->next = save_nextnext; + GET_OPTION("batch_id"); bid = expand_string(tp->batch_id); deliver_set_expansions(NULL); if (!bid) @@ -3121,7 +3145,7 @@ while (addr_local) if (result == DEFER || testflag(addr2, af_lt_retry_exists)) { int flags = result == DEFER ? 0 : rf_delete; - uschar *retry_key = string_copy(tp->retry_use_local_part + uschar * retry_key = string_copy(tp->retry_use_local_part ? addr2->address_retry_key : addr2->domain_retry_key); *retry_key = 'T'; retry_add_item(addr2, retry_key, flags); @@ -3571,7 +3595,14 @@ while (!done) switch (*subid) { - case 3: /* explicit notification of continued-connection (non)use; +#ifndef DISABLE_DKIM + case '4': /* DKIM information */ + addr->dkim_used = string_copy(ptr); + while(*ptr++); + break; +#endif + + case '3': /* explicit notification of continued-connection (non)use; overrides caller's knowlege. */ if (*ptr & BIT(1)) setflag(addr, af_new_conn); else if (*ptr & BIT(2)) setflag(addr, af_cont_conn); @@ -4439,9 +4470,10 @@ nonmatch domains else return_path = sender_address; + GET_OPTION("return_path"); if (tp->return_path) { - uschar *new_return_path = expand_string(tp->return_path); + uschar * new_return_path = expand_string(tp->return_path); if (new_return_path) return_path = new_return_path; else if (!f.expand_string_forcedfail) @@ -4886,6 +4918,15 @@ all pipes, so I do not see a reason to use non-blocking IO here rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer); } +#ifndef DISABLE_DKIM + if (addr->dkim_used && LOGGING(dkim_verbose)) + { + DEBUG(D_deliver) debug_printf("dkim used: %s\n", addr->dkim_used); + ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->dkim_used) + 1; + rmt_dlv_checked_write(fd, 'A', '4', big_buffer, ptr - big_buffer); + } +#endif + if (testflag(addr, af_new_conn) || testflag(addr, af_cont_conn)) { DEBUG(D_deliver) debug_printf("%scontinued-connection\n", @@ -4984,7 +5025,7 @@ all pipes, so I do not see a reason to use non-blocking IO here big_buffer[0] = continue_transport ? '1' : '0'; rmt_dlv_checked_write(fd, 'Z', '0', big_buffer, 1); (void)close(fd); - exit(EXIT_SUCCESS); + exim_exit(EXIT_SUCCESS); } /* Back in the mainline: close the unwanted half of the pipe. */ @@ -5086,7 +5127,7 @@ Returns: OK int deliver_split_address(address_item * addr) { -uschar * address = addr->address; +const uschar * address = addr->address; uschar * domain; uschar * t; int len; @@ -5103,7 +5144,7 @@ where they are locally interpreted. [The new draft "821" is more explicit on this, Jan 1999.] We know the syntax is valid, so this can be done by simply removing quoting backslashes and any unquoted doublequotes. */ -t = addr->cc_local_part = store_get(len+1, address); +addr->cc_local_part = t = store_get(len+1, address); while(len-- > 0) { int c = *address++; @@ -5115,7 +5156,7 @@ while(len-- > 0) } else *t++ = c; } -*t = 0; +*t = '\0'; /* We do the percent hack only for those domains that are listed in percent_hack_domains. A loop is required, to copy with multiple %-hacks. */ @@ -5123,8 +5164,8 @@ percent_hack_domains. A loop is required, to copy with multiple %-hacks. */ if (percent_hack_domains) { int rc; - uschar *new_address = NULL; - uschar *local_part = addr->cc_local_part; + uschar * new_address = NULL; + const uschar * local_part = addr->cc_local_part; deliver_domain = addr->domain; /* set $domain */ @@ -5261,12 +5302,12 @@ Returns: TRUE if the address is not hidden */ static BOOL -print_address_information(address_item *addr, FILE *f, uschar *si, uschar *sc, - uschar *se) +print_address_information(address_item * addr, FILE * f, uschar * si, + uschar * sc, uschar * se) { BOOL yield = TRUE; -uschar *printed = US""; -address_item *ancestor = addr; +const uschar * printed = US""; +address_item * ancestor = addr; while (ancestor->parent) ancestor = ancestor->parent; fprintf(f, "%s", CS si); @@ -5281,8 +5322,8 @@ else if (!testflag(addr, af_pfr) || !addr->parent) else { - uschar *s = addr->address; - uschar *ss; + const uschar * s = addr->address; + const uschar * ss; if (addr->address[0] == '>') { ss = US"mail"; s++; } else if (addr->address[0] == '|') ss = US"pipe"; @@ -5296,7 +5337,7 @@ fprintf(f, "%s", CS string_printing(printed)); if (ancestor != addr) { - uschar *original = ancestor->onetime_parent; + const uschar * original = ancestor->onetime_parent; if (!original) original= ancestor->address; if (strcmpic(original, printed) != 0) fprintf(f, "%s(%sgenerated from %s)", sc, @@ -5533,18 +5574,18 @@ return actual_time; static FILE * expand_open(const uschar * filename, - const uschar * varname, const uschar * reason) + const uschar * optname, const uschar * reason) { const uschar * s = expand_cstring(filename); FILE * fp = NULL; if (!s || !*s) log_write(0, LOG_MAIN|LOG_PANIC, - "Failed to expand %s: '%s'\n", varname, filename); + "Failed to expand %s: '%s'\n", optname, 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); + optname, *s == '/' ? "untainted" : "absolute", 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)); @@ -5675,6 +5716,7 @@ else /* Open a template file if one is provided. Log failure to open, but carry on - default texts will be used. */ + GET_OPTION("bounce_message_file"); if (bounce_message_file) emf = expand_open(bounce_message_file, US"bounce_message_file", US"error"); @@ -5743,7 +5785,7 @@ wording. */ if (addr->return_file >= 0) { - paddr = &(addr->next); + paddr = &addr->next; filecount++; } @@ -5850,6 +5892,9 @@ wording. */ for (address_item * addr = handled_addr; addr; addr = addr->next) { host_item * hu; +#ifdef EXPERIMENTAL_DSN_INFO + const uschar * s; +#endif print_dsn_addr_action(fp, addr, US"failed", US"5.0.0"); @@ -5857,8 +5902,6 @@ wording. */ { fprintf(fp, "Remote-MTA: dns; %s\n", hu->name); #ifdef EXPERIMENTAL_DSN_INFO - { - const uschar * s; if (hu->address) { uschar * p = hu->port == 25 @@ -5869,12 +5912,15 @@ wording. */ dsn_put_wrapped(fp, US"X-Remote-MTA-smtp-greeting: X-str; ", s); if ((s = addr->helo_response) && *s) dsn_put_wrapped(fp, US"X-Remote-MTA-helo-response: X-str; ", s); - if ((s = addr->message) && *s) + if (testflag(addr, af_pass_message) && (s = addr->message) && *s) dsn_put_wrapped(fp, US"X-Exim-Diagnostic: X-str; ", s); - } #endif print_dsn_diagnostic_code(addr, fp); } +#ifdef EXPERIMENTAL_DSN_INFO + else if (testflag(addr, af_pass_message) && (s = addr->message) && *s) + dsn_put_wrapped(fp, US"X-Exim-Diagnostic: X-str; ", s); +#endif fputc('\n', fp); } @@ -6030,6 +6076,7 @@ transport_ctx tctx = {{0}}; if (pid <= 0) return FALSE; +GET_OPTION("warn_message_file"); if (warn_message_file) wmf = expand_open(warn_message_file, US"warn_message_file", US"warning"); @@ -6384,7 +6431,7 @@ Returns: When the global variable mua_wrapper is FALSE: */ int -deliver_message(uschar * id, BOOL forced, BOOL give_up) +deliver_message(const uschar * id, BOOL forced, BOOL give_up) { int i, rc; int final_yield = DELIVER_ATTEMPTED_NORMAL; @@ -6729,6 +6776,7 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) /* Any error in the filter file causes a delivery to be abandoned. */ + GET_OPTION("system_filter"); redirect.string = system_filter; redirect.isfile = TRUE; redirect.check_owner = redirect.check_group = FALSE; @@ -6908,12 +6956,14 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (p->address[0] == '|') { type = US"pipe"; + GET_OPTION("system_filter_pipe_transport"); tpname = system_filter_pipe_transport; address_pipe = p->address; } else if (p->address[0] == '>') { type = US"reply"; + GET_OPTION("system_filter_reply_transport"); tpname = system_filter_reply_transport; } else @@ -6921,11 +6971,13 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (p->address[Ustrlen(p->address)-1] == '/') { type = US"directory"; + GET_OPTION("system_filter_directory_transport"); tpname = system_filter_directory_transport; } else { type = US"file"; + GET_OPTION("system_filter_file_transport"); tpname = system_filter_file_transport; } address_file = p->address; @@ -6969,7 +7021,7 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (!p->transport) { - address_item *badp = p; + address_item * badp = p; p = p->next; if (!addr_last) addr_new = p; else addr_last->next = p; badp->local_part = badp->address; /* Needed for log line */ @@ -7009,8 +7061,9 @@ 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; - address_item *new = deliver_make_addr(r->address, FALSE); + recipient_item * r = recipients_list + i; + address_item * new = deliver_make_addr(r->address, FALSE); + new->prop.errors_address = r->errors_to; #ifdef SUPPORT_I18N if ((new->prop.utf8_msg = message_smtputf8)) @@ -7070,6 +7123,8 @@ if (process_recipients != RECIP_IGNORE) case RECIP_FAIL: new->message = US"delivery cancelled by administrator"; + /* not setting af_pass_message here means that will not + appear in the bounce message */ /* Fall through */ /* Common code for the failure cases above. If this is not a bounce @@ -7078,7 +7133,7 @@ if (process_recipients != RECIP_IGNORE) The incident has already been logged. */ RECIP_QUEUE_FAILED: - if (sender_address[0]) + if (*sender_address) { new->next = addr_failed; addr_failed = new; @@ -7107,9 +7162,10 @@ if (process_recipients != RECIP_IGNORE) #ifndef DISABLE_EVENT if (process_recipients != RECIP_ACCEPT && event_action) { - uschar * save_local = deliver_localpart; + const uschar * save_local = deliver_localpart; const uschar * save_domain = deliver_domain; - uschar * addr = new->address, * errmsg = NULL; + const uschar * addr = new->address; + uschar * errmsg = NULL; int start, end, dom; if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) @@ -7239,7 +7295,7 @@ while (addr_new) /* Loop until all addresses dealt with */ addr->unique = string_sprintf("%s:%s", addr->address, addr->parent->unique + - (testflag(addr->parent, af_homonym)? 3:0)); + (testflag(addr->parent, af_homonym) ? 3:0)); addr->address_retry_key = addr->domain_retry_key = string_sprintf("T:%s", addr->unique); @@ -7676,7 +7732,7 @@ while (addr_new) /* Loop until all addresses dealt with */ else if (testflag(addr, af_dr_retry_exists)) { - uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key, + uschar * altkey = string_sprintf("%s:<%s>", addr->address_retry_key, sender_address); retry_add_item(addr, altkey, rf_delete); retry_add_item(addr, addr->address_retry_key, rf_delete); @@ -8358,7 +8414,7 @@ else if (addr_defer != (address_item *)(+1)) for (i = 0; i < recipients_count; i++) { - uschar *r = recipients_list[i].address; + const uschar * r = recipients_list[i].address; if (Ustrcmp(otaddr->onetime_parent, r) == 0) t = i; if (Ustrcmp(otaddr->address, r) == 0) break; } @@ -8386,7 +8442,7 @@ else if (addr_defer != (address_item *)(+1)) if (sender_address[0]) { - uschar * s = addr->prop.errors_address; + const uschar * s = addr->prop.errors_address; if (!s) s = sender_address; if (Ustrstr(recipients, s) == NULL) recipients = string_sprintf("%s%s%s", recipients, @@ -8405,54 +8461,57 @@ else if (addr_defer != (address_item *)(+1)) || addr_defer->dsn_flags & rf_notify_delay ) && delay_warning[1] > 0 - && sender_address[0] != 0 - && ( !delay_warning_condition - || expand_check_condition(delay_warning_condition, - US"delay_warning", US"option") - ) - ) + && sender_address[0] != 0) { - int count; - int show_time; - int queue_time = time(NULL) - received_time.tv_sec; - - queue_time = test_harness_fudged_queue_time(queue_time); - - /* See how many warnings we should have sent by now */ + GET_OPTION("delay_warning_condition"); + if ( ( !delay_warning_condition + || expand_check_condition(delay_warning_condition, + US"delay_warning", US"option") + ) + ) + { + int count; + int show_time; + int queue_time = time(NULL) - received_time.tv_sec; - for (count = 0; count < delay_warning[1]; count++) - if (queue_time < delay_warning[count+2]) break; + queue_time = test_harness_fudged_queue_time(queue_time); - show_time = delay_warning[count+1]; + /* See how many warnings we should have sent by now */ - if (count >= delay_warning[1]) - { - int extra; - int last_gap = show_time; - if (count > 1) last_gap -= delay_warning[count]; - extra = (queue_time - delay_warning[count+1])/last_gap; - show_time += last_gap * extra; - count += extra; - } + for (count = 0; count < delay_warning[1]; count++) + if (queue_time < delay_warning[count+2]) break; - DEBUG(D_deliver) - { - debug_printf("time on queue = %s id %s addr %s\n", - readconf_printtime(queue_time), message_id, addr_defer->address); - debug_printf("warning counts: required %d done %d\n", count, - warning_count); - } + show_time = delay_warning[count+1]; - /* We have computed the number of warnings there should have been by now. - If there haven't been enough, send one, and up the count to what it should - have been. */ + if (count >= delay_warning[1]) + { + int extra; + int last_gap = show_time; + if (count > 1) last_gap -= delay_warning[count]; + extra = (queue_time - delay_warning[count+1])/last_gap; + show_time += last_gap * extra; + count += extra; + } - if (warning_count < count) - if (send_warning_message(recipients, queue_time, show_time)) + DEBUG(D_deliver) { - warning_count = count; - update_spool = TRUE; /* Ensure spool rewritten */ + debug_printf("time on queue = %s id %s addr %s\n", + readconf_printtime(queue_time), message_id, addr_defer->address); + debug_printf("warning counts: required %d done %d\n", count, + warning_count); } + + /* We have computed the number of warnings there should have been by now. + If there haven't been enough, send one, and up the count to what it should + have been. */ + + if (warning_count < count) + if (send_warning_message(recipients, queue_time, show_time)) + { + warning_count = count; + update_spool = TRUE; /* Ensure spool rewritten */ + } + } } /* Clear deliver_domain */