X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=7ec94edd76019a6eeb8db97edfef12e0a56f0be8;hb=55414b2;hp=5000f1cbc38a22b2f408c3798c0b1cfd431d5e92;hpb=506900aff65e12440fdd36a71e9172fc7af5830a;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index 5000f1cbc..7ec94edd7 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -63,10 +63,8 @@ static address_item *addr_new = NULL; static address_item *addr_remote = NULL; static address_item *addr_route = NULL; static address_item *addr_succeed = NULL; -#ifdef EXPERIMENTAL_DSN static address_item *addr_dsntmp = NULL; static address_item *addr_senddsn = NULL; -#endif static FILE *message_log = NULL; static BOOL update_spool; @@ -129,7 +127,7 @@ deliver_set_expansions(address_item *addr) { if (addr == NULL) { - uschar ***p = address_expansions; + const uschar ***p = address_expansions; while (*p != NULL) **p++ = NULL; return; } @@ -720,7 +718,7 @@ d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr) #ifdef EXPERIMENTAL_EVENT uschar * -event_raise(uschar * action, uschar * event, uschar * ev_data) +event_raise(uschar * action, const uschar * event, uschar * ev_data) { uschar * s; if (action) @@ -754,11 +752,11 @@ return NULL; } static void -msg_event_raise(uschar * event, address_item * addr) +msg_event_raise(const uschar * event, const address_item * addr) { -uschar * save_domain = deliver_domain; +const uschar * save_domain = deliver_domain; uschar * save_local = deliver_localpart; -uschar * save_host = deliver_host; +const uschar * save_host = deliver_host; if (!addr->transport) return; @@ -819,6 +817,10 @@ else s = string_append(s, &size, &ptr, 2, US"> ", log_address); } +if (log_extra_selector & LX_incoming_interface && sending_ip_address) + s = string_append(s, &size, &ptr, 3, US" I=[", sending_ip_address, US"]"); + /* for the port: string_sprintf("%d", sending_port) */ + if ((log_extra_selector & LX_sender_on_delivery) != 0 || msg) s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">"); @@ -1016,7 +1018,10 @@ malformed, it won't ever have gone near LDAP.) */ if (addr->message != NULL) { - addr->message = string_printing(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(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) && (Ustrstr(addr->message, "mysql") != NULL || Ustrstr(addr->message, "pgsql") != NULL || @@ -1073,11 +1078,12 @@ if (addr->return_file >= 0 && addr->return_filename != NULL) if (s != NULL) { uschar *p = big_buffer + Ustrlen(big_buffer); + const uschar * sp; while (p > big_buffer && isspace(p[-1])) p--; *p = 0; - s = string_printing(big_buffer); + sp = string_printing(big_buffer); log_write(0, LOG_MAIN, "<%s>: %s transport output: %s", - addr->address, tb->name, s); + addr->address, tb->name, sp); } (void)fclose(f); } @@ -2777,7 +2783,7 @@ sort_remote_deliveries(void) { int sep = 0; address_item **aptr = &addr_remote; -uschar *listptr = remote_sort_domains; +const uschar *listptr = remote_sort_domains; uschar *pattern; uschar patbuf[256]; @@ -2792,7 +2798,7 @@ while (*aptr != NULL && { address_item **next; deliver_domain = (*aptr)->domain; /* set $domain */ - if (match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1, + if (match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK) { aptr = &((*aptr)->next); @@ -2802,7 +2808,7 @@ while (*aptr != NULL && next = &((*aptr)->next); while (*next != NULL && (deliver_domain = (*next)->domain, /* Set $domain */ - match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1, + match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) != OK) next = &((*next)->next); @@ -3166,14 +3172,12 @@ while (!done) break; #endif -#ifdef EXPERIMENTAL_DSN case 'D': if (addr == NULL) goto ADDR_MISMATCH; memcpy(&(addr->dsn_aware), ptr, sizeof(addr->dsn_aware)); ptr += sizeof(addr->dsn_aware); DEBUG(D_deliver) debug_printf("DSN read: addr->dsn_aware = %d\n", addr->dsn_aware); break; -#endif case 'A': if (addr == NULL) @@ -3223,6 +3227,14 @@ while (!done) addr = addr->next; break; + /* Local interface address/port */ + case 'I': + if (*ptr) sending_ip_address = string_copy(ptr); + while (*ptr++) ; + if (*ptr) sending_port = atoi(ptr); + while (*ptr++) ; + break; + /* Z marks the logical end of the data. It is followed by '0' if continue_transport was NULL at the end of transporting, otherwise '1'. We need to know when it becomes NULL during a delivery down a passed SMTP @@ -4370,11 +4382,9 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) rmt_dlv_checked_write(fd, 'P', '0', NULL, 0); #endif -#ifdef EXPERIMENTAL_DSN memcpy(big_buffer, &addr->dsn_aware, sizeof(addr->dsn_aware)); rmt_dlv_checked_write(fd, 'D', '0', big_buffer, sizeof(addr->dsn_aware)); DEBUG(D_deliver) debug_printf("DSN write: addr->dsn_aware = %d\n", addr->dsn_aware); -#endif /* Retry information: for most success cases this will be null. */ @@ -4436,6 +4446,18 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) rmt_dlv_checked_write(fd, 'A', '0', big_buffer, ptr - big_buffer); } + /* Local interface address/port */ + if (log_extra_selector & LX_incoming_interface && sending_ip_address) + { + uschar * ptr = big_buffer; + sprintf(CS ptr, "%.128s", sending_ip_address); + while(*ptr++); + sprintf(CS ptr, "%d", sending_port); + while(*ptr++); + + rmt_dlv_checked_write(fd, 'I', '0', big_buffer, ptr - big_buffer); + } + /* Add termination flag, close the pipe, and that's it. The character after 'Z' indicates whether continue_transport is now NULL or not. A change from non-NULL to NULL indicates a problem with a continuing @@ -4562,7 +4584,7 @@ if (percent_hack_domains != NULL) deliver_domain = addr->domain; /* set $domain */ - while ((rc = match_isinlist(deliver_domain, &percent_hack_domains, 0, + while ((rc = match_isinlist(deliver_domain, (const uschar **)&percent_hack_domains, 0, &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) == OK && (t = Ustrrchr(local_part, '%')) != NULL) @@ -4814,7 +4836,6 @@ while (*s != 0) } -#ifdef EXPERIMENTAL_DSN /*********************************************************** * Print Diagnostic-Code for an address * ************************************************************/ @@ -4863,7 +4884,6 @@ while (*s) fputc('\n', f); } -#endif /* EXPERIMENTAL_DSN */ /************************************************* @@ -5577,13 +5597,11 @@ if (process_recipients != RECIP_IGNORE) if (r->pno >= 0) new->onetime_parent = recipients_list[r->pno].address; -#ifdef EXPERIMENTAL_DSN /* If DSN support is enabled, set the dsn flags and the original receipt to be passed on to other DSN enabled MTAs */ new->dsn_flags = r->dsn_flags & rf_dsnflags; new->dsn_orcpt = r->orcpt; DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s flags: %d\n", new->dsn_orcpt, new->dsn_flags); -#endif switch (process_recipients) { @@ -5658,7 +5676,7 @@ if (process_recipients != RECIP_IGNORE) if (process_recipients != RECIP_ACCEPT) { uschar * save_local = deliver_localpart; - uschar * save_domain = deliver_domain; + const uschar * save_domain = deliver_domain; deliver_localpart = expand_string( string_sprintf("${local_part:%s}", new->address)); @@ -5923,7 +5941,7 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ deliver_domain = addr->domain; /* set $domain */ if (!forced && hold_domains != NULL && - (rc = match_isinlist(addr->domain, &hold_domains, 0, + (rc = match_isinlist(addr->domain, (const uschar **)&hold_domains, 0, &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) != FAIL) { @@ -6130,7 +6148,7 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ addr_route = addr->next; deliver_domain = addr->domain; /* set $domain */ - if ((rc = match_isinlist(addr->domain, &queue_domains, 0, + if ((rc = match_isinlist(addr->domain, (const uschar **)&queue_domains, 0, &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) != OK) { @@ -6163,7 +6181,7 @@ while (addr_new != NULL) /* Loop until all addresses dealt with */ { int rc; address_item *addr = addr_route; - uschar *old_domain = addr->domain; + const uschar *old_domain = addr->domain; uschar *old_unique = addr->unique; addr_route = addr->next; addr->next = NULL; @@ -6528,31 +6546,7 @@ if (addr_remote != NULL) /* Precompile some regex that are used to recognize parameters in response to an EHLO command, if they aren't already compiled. */ - if (regex_PIPELINING == NULL) regex_PIPELINING = - regex_must_compile(US"\\n250[\\s\\-]PIPELINING(\\s|\\n|$)", FALSE, TRUE); - - if (regex_SIZE == NULL) regex_SIZE = - regex_must_compile(US"\\n250[\\s\\-]SIZE(\\s|\\n|$)", FALSE, TRUE); - - if (regex_AUTH == NULL) regex_AUTH = - regex_must_compile(US"\\n250[\\s\\-]AUTH\\s+([\\-\\w\\s]+)(?:\\n|$)", - FALSE, TRUE); - -#ifdef SUPPORT_TLS - if (regex_STARTTLS == NULL) regex_STARTTLS = - regex_must_compile(US"\\n250[\\s\\-]STARTTLS(\\s|\\n|$)", FALSE, TRUE); -#endif - -#ifndef DISABLE_PRDR - if (regex_PRDR == NULL) regex_PRDR = - regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE); -#endif - -#ifdef EXPERIMENTAL_DSN - /* Set the regex to check for DSN support on remote MTA */ - if (regex_DSN == NULL) regex_DSN = - regex_must_compile(US"\\n250[\\s\\-]DSN(\\s|\\n|$)", FALSE, TRUE); -#endif + deliver_init(); /* Now sort the addresses if required, and do the deliveries. The yield of do_remote_deliveries is FALSE when mua_wrapper is set and all addresses @@ -6661,7 +6655,6 @@ prevents actual delivery. */ else if (!dont_deliver) retry_update(&addr_defer, &addr_failed, &addr_succeed); -#ifdef EXPERIMENTAL_DSN /* Send DSN for successful messages */ addr_dsntmp = addr_succeed; addr_senddsn = NULL; @@ -6820,7 +6813,6 @@ if (addr_senddsn != NULL) rc = child_close(pid, 0); /* Waits for child to close, no timeout */ } } -#endif /*EXPERIMENTAL_DSN*/ /* If any addresses failed, we must send a message to somebody, unless af_ignore_error is set, in which case no action is taken. It is possible for @@ -6879,11 +6871,9 @@ while (addr_failed != NULL) it from the list, throw away any saved message file, log it, and mark the recipient done. */ - if (testflag(addr_failed, af_ignore_error) -#ifdef EXPERIMENTAL_DSN - || (((addr_failed->dsn_flags & rf_dsnflags) != 0) - && ((addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure)) -#endif + if ( testflag(addr_failed, af_ignore_error) + || ( ((addr_failed->dsn_flags & rf_dsnflags) != 0) + && ((addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure)) ) { addr = addr_failed; @@ -6937,12 +6927,10 @@ while (addr_failed != NULL) BOOL to_sender = strcmpic(sender_address, bounce_recipient) == 0; int max = (bounce_return_size_limit/DELIVER_IN_BUFFER_SIZE + 1) * DELIVER_IN_BUFFER_SIZE; -#ifdef EXPERIMENTAL_DSN uschar * bound; uschar *dsnlimitmsg; uschar *dsnnotifyhdr; int topt; -#endif DEBUG(D_deliver) debug_printf("sending error message to: %s\n", bounce_recipient); @@ -6996,7 +6984,6 @@ while (addr_failed != NULL) moan_write_from(f); fprintf(f, "To: %s\n", bounce_recipient); -#ifdef EXPERIMENTAL_DSN /* generate boundary string and output MIME-Headers */ bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand()); @@ -7004,7 +6991,6 @@ while (addr_failed != NULL) " report-type=delivery-status; boundary=%s\n" "MIME-Version: 1.0\n", bound); -#endif /* Open a template file if one is provided. Log failure to open, but carry on - default texts will be used. */ @@ -7029,12 +7015,10 @@ while (addr_failed != NULL) fprintf(f, "Subject: Mail delivery failed%s\n\n", to_sender? ": returning message to sender" : ""); -#ifdef EXPERIMENTAL_DSN /* output human readable part as text/plain section */ fprintf(f, "--%s\n" "Content-type: text/plain; charset=us-ascii\n\n", bound); -#endif if ((emf_text = next_emf(emf, US"intro"))) fprintf(f, "%s", CS emf_text); @@ -7161,7 +7145,6 @@ wording. */ fputc('\n', f); } -#ifdef EXPERIMENTAL_DSN /* output machine readable part */ fprintf(f, "--%s\n" "Content-type: message/delivery-status\n\n" @@ -7192,7 +7175,6 @@ wording. */ print_dsn_diagnostic_code(addr, f); } } -#endif /* Now copy the message, trying to give an intelligible comment if it is too long for it all to be copied. The limit isn't strictly @@ -7201,65 +7183,6 @@ wording. */ emf_text = next_emf(emf, US"copy"); -#ifndef EXPERIMENTAL_DSN - if (bounce_return_message) - { - int topt = topt_add_return_path; - if (!bounce_return_body) topt |= topt_no_body; - - if (emf_text) - fprintf(f, "%s", CS emf_text); - else - { - if (bounce_return_body) fprintf(f, -"------ This is a copy of the message, including all the headers. ------\n"); - else fprintf(f, -"------ This is a copy of the message's headers. ------\n"); - } - - /* While reading the "truncated" message, set return_size_limit to - the actual max testing value, rounded. We need to read the message - whether we are going to use it or not. */ - - { - int temp = bounce_return_size_limit; - bounce_return_size_limit = (max/1000)*1000; - emf_text = next_emf(emf, US"truncated"); - bounce_return_size_limit = temp; - } - - if (bounce_return_body && bounce_return_size_limit > 0) - { - struct stat statbuf; - if (fstat(deliver_datafile, &statbuf) == 0 && statbuf.st_size > max) - { - if (emf_text) - fprintf(f, "%s", CS emf_text); - else - fprintf(f, -"------ The body of the message is " OFF_T_FMT " characters long; only the first\n" -"------ %d or so are included here.\n", statbuf.st_size, max); - } - } - - fputc('\n', f); - fflush(f); - - transport_filter_argv = NULL; /* Just in case */ - return_path = sender_address; /* In case not previously set */ - transport_write_message(NULL, fileno(f), topt, - bounce_return_size_limit, NULL, NULL, NULL, NULL, NULL, 0); - } - - /* Write final text and close the template file if one is open */ - - if (emf) - { - if ((emf_text = next_emf(emf, US"final"))) - fprintf(f, "%s", CS emf_text); - (void)fclose(emf); - } -#else /* add message body we ignore the intro text from template and add the text for bounce_return_size_limit at the end. @@ -7317,7 +7240,6 @@ wording. */ (void)fclose(emf); fprintf(f, "\n--%s--\n", bound); -#endif /*EXPERIMENTAL_DSN*/ /* Close the file, which should send an EOF to the child process that is receiving the message. Wait for it to finish. */ @@ -7482,7 +7404,8 @@ else if (addr_defer != (address_item *)(+1)) if (deliver_domain != NULL) { - uschar *d = (testflag(addr, af_pfr))? addr->parent->domain : addr->domain; + const uschar *d = testflag(addr, af_pfr) + ? addr->parent->domain : addr->domain; /* The domain may be unset for an address that has never been routed because the system filter froze the message. */ @@ -7552,15 +7475,18 @@ else if (addr_defer != (address_item *)(+1)) is not sent. Another attempt will be made at the next delivery attempt (if it also defers). */ - if (!queue_2stage && delivery_attempted && -#ifdef EXPERIMENTAL_DSN - (((addr_defer->dsn_flags & rf_dsnflags) == 0) || - (addr_defer->dsn_flags & rf_notify_delay) == rf_notify_delay) && -#endif - delay_warning[1] > 0 && sender_address[0] != 0 && - (delay_warning_condition == NULL || - expand_check_condition(delay_warning_condition, - US"delay_warning", US"option"))) + if ( !queue_2stage + && delivery_attempted + && ( ((addr_defer->dsn_flags & rf_dsnflags) == 0) + || (addr_defer->dsn_flags & rf_notify_delay) == rf_notify_delay + ) + && delay_warning[1] > 0 + && sender_address[0] != 0 + && ( delay_warning_condition == NULL + || expand_check_condition(delay_warning_condition, + US"delay_warning", US"option") + ) + ) { int count; int show_time; @@ -7621,9 +7547,7 @@ else if (addr_defer != (address_item *)(+1)) uschar *wmf_text; FILE *wmf = NULL; FILE *f = fdopen(fd, "wb"); -#ifdef EXPERIMENTAL_DSN uschar * bound; -#endif if (warn_message_file) { @@ -7644,7 +7568,6 @@ else if (addr_defer != (address_item *)(+1)) moan_write_from(f); fprintf(f, "To: %s\n", recipients); -#ifdef EXPERIMENTAL_DSN /* generated boundary string and output MIME-Headers */ bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand()); @@ -7652,7 +7575,6 @@ else if (addr_defer != (address_item *)(+1)) " report-type=delivery-status; boundary=%s\n" "MIME-Version: 1.0\n", bound); -#endif if ((wmf_text = next_emf(wmf, US"header"))) fprintf(f, "%s\n", wmf_text); @@ -7660,12 +7582,10 @@ else if (addr_defer != (address_item *)(+1)) fprintf(f, "Subject: Warning: message %s delayed %s\n\n", message_id, warnmsg_delay); -#ifdef EXPERIMENTAL_DSN /* output human readable part as text/plain section */ fprintf(f, "--%s\n" "Content-type: text/plain; charset=us-ascii\n\n", bound); -#endif if ((wmf_text = next_emf(wmf, US"intro"))) fprintf(f, "%s", CS wmf_text); @@ -7704,10 +7624,8 @@ else if (addr_defer != (address_item *)(+1)) /* List the addresses, with error information if allowed */ -#ifdef EXPERIMENTAL_DSN /* store addr_defer for machine readable part */ address_item *addr_dsndefer = addr_defer; -#endif fputc('\n', f); while (addr_defer) { @@ -7736,7 +7654,6 @@ else if (addr_defer != (address_item *)(+1)) "and when that happens, the message will be returned to you.\n"); } -#ifdef EXPERIMENTAL_DSN /* output machine readable part */ fprintf(f, "\n--%s\n" "Content-type: message/delivery-status\n\n" @@ -7789,7 +7706,6 @@ else if (addr_defer != (address_item *)(+1)) fprintf(f,"\n--%s--\n", bound); fflush(f); -#endif /*EXPERIMENTAL_DSN*/ /* Close and wait for child process to complete, without a timeout. If there's an error, don't update the count. */ @@ -7927,6 +7843,39 @@ acl_where = ACL_WHERE_UNKNOWN; return final_yield; } + + +void +deliver_init(void) +{ +if (!regex_PIPELINING) regex_PIPELINING = + regex_must_compile(US"\\n250[\\s\\-]PIPELINING(\\s|\\n|$)", FALSE, TRUE); + +if (!regex_SIZE) regex_SIZE = + regex_must_compile(US"\\n250[\\s\\-]SIZE(\\s|\\n|$)", FALSE, TRUE); + +if (!regex_AUTH) regex_AUTH = + regex_must_compile(US"\\n250[\\s\\-]AUTH\\s+([\\-\\w\\s]+)(?:\\n|$)", + FALSE, TRUE); + +#ifdef SUPPORT_TLS +if (!regex_STARTTLS) regex_STARTTLS = + regex_must_compile(US"\\n250[\\s\\-]STARTTLS(\\s|\\n|$)", FALSE, TRUE); +#endif + +#ifndef DISABLE_PRDR +if (!regex_PRDR) regex_PRDR = + regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE); +#endif + +if (!regex_DSN) regex_DSN = + regex_must_compile(US"\\n250[\\s\\-]DSN(\\s|\\n|$)", FALSE, TRUE); + +if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA = + regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE); +} + + /* vi: aw ai sw=2 */ /* End of deliver.c */