X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=52270368ee3b7fc4eaacd991a303529772e2ce0f;hb=6707bfa9fb78858de938a1abca2846c820c5ded7;hp=d0e6d1c2ecbd9660b30ddcd7666c4687c84c3b10;hpb=7c60296900bdff369ffd2bf54eecfe6097b997a4;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index d0e6d1c2e..52270368e 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 - 2022 */ +/* Copyright (c) The Exim Maintainers 2020 - 2023 */ /* 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 */ @@ -723,7 +723,7 @@ child_done(address_item * addr, const uschar * now) { while (addr->parent) { - address_item *aa; + address_item * aa; addr = addr->parent; if (--addr->child_count > 0) return; /* Incomplete parent */ @@ -1278,7 +1278,7 @@ if (LOGGING(deliver_time)) /* string_cat() always leaves room for the terminator. Release the store we used to build the line after writing it. */ -log_write(0, flags, "%s", string_from_gstring(g)); +log_write(0, flags, "%Y", g); #ifndef DISABLE_EVENT if (!msg) msg_event_raise(US"msg:delivery", addr); @@ -1337,25 +1337,21 @@ if (LOGGING(deliver_time)) if (addr->message) g = string_append(g, 2, US": ", addr->message); - { - const uschar * s = string_from_gstring(g); +/* Log the deferment in the message log, but don't clutter it +up with retry-time defers after the first delivery attempt. */ - /* Log the deferment in the message log, but don't clutter it - up with retry-time defers after the first delivery attempt. */ +if (f.deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE) + deliver_msglog("%s %.*s\n", now, g->ptr, g->s); - if (f.deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE) - deliver_msglog("%s %s\n", now, s); +/* Write the main log and reset the store. +For errors of the type "retry time not reached" (also remotes skipped +on queue run), logging is controlled by L_retry_defer. Note that this kind +of error number is negative, and all the retry ones are less than any +others. */ - /* Write the main log and reset the store. - For errors of the type "retry time not reached" (also remotes skipped - on queue run), logging is controlled by L_retry_defer. Note that this kind - of error number is negative, and all the retry ones are less than any - others. */ - - log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags, - "== %s", s); - } +log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags, + "== %Y", g); store_reset(reset_point); return; @@ -1421,16 +1417,12 @@ if (LOGGING(deliver_time)) /* Do the logging. For the message log, "routing failed" for those cases, just to make it clearer. */ - { - const uschar * s = string_from_gstring(g); - - if (driver_kind) - deliver_msglog("%s %s failed for %s\n", now, driver_kind, s); - else - deliver_msglog("%s %s\n", now, s); +if (driver_kind) + deliver_msglog("%s %s failed for %.*s\n", now, driver_kind, g->ptr, g->s); +else + deliver_msglog("%s %.*s\n", now, g->ptr, g->s); - log_write(0, LOG_MAIN, "** %s", s); - } +log_write(0, LOG_MAIN, "** %Y", g); store_reset(reset_point); return; @@ -2371,7 +2363,9 @@ if ((pid = exim_fork(US"delivery-local")) == 0) addr->local_part, tp->name); /* Setting these globals in the subprocess means we need never clear them */ - transport_name = addr->transport->name; + + transport_name = tp->name; + if (addr->router) router_name = addr->router->name; driver_srcfile = tp->srcfile; driver_srcline = tp->srcline; @@ -2382,7 +2376,7 @@ if ((pid = exim_fork(US"delivery-local")) == 0) { ok = transport_set_up_command(&transport_filter_argv, tp->filter_command, - TRUE, PANIC, addr, FALSE, US"transport filter", NULL); + TSUC_EXPAND_ARGS, PANIC, addr, US"transport filter", NULL); transport_filter_timeout = tp->filter_timeout; } else transport_filter_argv = NULL; @@ -3351,8 +3345,8 @@ while (!done) pipeheader[PIPE_HEADER_SIZE] = '\0'; DEBUG(D_deliver) - debug_printf("got %ld bytes (pipeheader) from transport process %d\n", - (long) got, pid); + debug_printf("got %ld bytes (pipeheader) '%c' from transport process %d\n", + (long) got, *id, pid); { /* If we can't decode the pipeheader, the subprocess seems to have a @@ -3467,7 +3461,7 @@ while (!done) /* Put the amount of data written into the parlist block */ - case 'S': + case 'S': /* Size */ memcpy(&(p->transport_count), ptr, sizeof(transport_count)); ptr += sizeof(transport_count); break; @@ -3557,7 +3551,7 @@ while (!done) if (*subid > '1') setflag(addr, af_tcp_fastopen_data); break; - case 'D': + case 'D': /* DSN */ if (!addr) goto ADDR_MISMATCH; memcpy(&(addr->dsn_aware), ptr, sizeof(addr->dsn_aware)); ptr += sizeof(addr->dsn_aware); @@ -4663,7 +4657,9 @@ all pipes, so I do not see a reason to use non-blocking IO here host_item *h; /* Setting these globals in the subprocess means we need never clear them */ - transport_name = addr->transport->name; + + transport_name = tp->name; + if (addr->router) router_name = addr->router->name; driver_srcfile = tp->srcfile; driver_srcline = tp->srcline; @@ -5370,6 +5366,11 @@ while (*s) fprintf(f, "\n "); /* sic (because space follows) */ count = 0; } + else if (count > 254) /* arbitrary limit */ + { + fprintf(f, "[truncated]"); + do s++; while (*s && !(*s == '\\' && s[1] == '\n')); + } } } @@ -5561,69 +5562,14 @@ Limit to about 1024 chars total. */ static void dsn_put_wrapped(FILE * fp, const uschar * header, const uschar * s) { -const uschar * t; -int llen = fprintf(fp, "%s", CS header), sleft = Ustrlen(s); -int remain = 1022 - llen; - -if (*s && remain > 0) - { - for(;;) - { - unsigned ltail; /* source chars to skip */ - - /* Chop at a newline, or end of string */ - - if ((t = Ustrchr(s, '\\')) && t[1] == 'n') - ltail = 2; - else if ((t = Ustrchr(s, '\n'))) - ltail = 1; - else - { - t = s + sleft; - ltail = 0; - } - - /* If that is too long, search backward for a space */ +gstring * g = string_cat(NULL, header); - if ((llen + t - s) > 78) - { - const uschar * u; - for (u = s + 78 - llen; u > s + 10; --u) if (*u == ' ') break; - if (u > s + 10) - { /* found a space to linebreak at */ - llen = u - s; - remain -= fprintf(fp, "%.*s", (int)llen, s); - s += ++llen; /* skip the space also */ - } - else if (llen < 78) - { /* just linebreak at 78 */ - llen = 78 - llen; - remain -= fprintf(fp, "%.*s", llen, s); - s += llen; - } - else /* header rather long */ - llen = 0; - } - else - { - llen = t - s; - remain -= fprintf(fp, "%.*s", llen, s); - s = t + ltail; - } +g = string_cat(g, s); +gstring_release_unused(g); +fprintf(fp, "%s\n", wrap_header(string_from_gstring(g), 79, 1023, US" ", 1)); +} - sleft -= llen; - remain -= 2; - if (!*s || remain <= 0) - break; - fputs("\n ", fp); - llen = 1; /* one for the leading space output above */ - } - if (s[-1] != '\n') fputs("\n", fp); - } -else - fputs("\n", fp); -} /************************************************* @@ -6004,7 +5950,7 @@ wording. */ tctx.u.fd = fileno(fp); tctx.tblock = &tb; - tctx.options = topt; + tctx.options = topt | topt_truncate_headers; tb.add_headers = dsnnotifyhdr; /*XXX no checking for failure! buggy! */ @@ -6035,7 +5981,7 @@ wording. */ if (rc != 0) { - uschar *s = US""; + uschar * s = US""; if (now - received_time.tv_sec < retry_maximum_timeout && !addr_defer) { addr_defer = (address_item *)(+1); @@ -6222,7 +6168,7 @@ fprintf(f, "--%s\n" 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; +tctx.options = topt_add_return_path | topt_truncate_headers | topt_no_body; transport_filter_argv = NULL; /* Just in case */ return_path = sender_address; /* In case not previously set */ @@ -6383,7 +6329,7 @@ if (addr_senddsn) /* Write the original email out */ tctx.u.fd = fd; - tctx.options = topt_add_return_path | topt_no_body; + tctx.options = topt_add_return_path | topt_truncate_headers | topt_no_body; /*XXX hmm, FALSE(fail) retval ignored. Could error for any number of reasons, and they are not handled. */ transport_write_message(&tctx, 0); @@ -6438,7 +6384,7 @@ Returns: When the global variable mua_wrapper is FALSE: */ int -deliver_message(uschar *id, BOOL forced, BOOL give_up) +deliver_message(uschar * id, BOOL forced, BOOL give_up) { int i, rc; int final_yield = DELIVER_ATTEMPTED_NORMAL; @@ -6524,7 +6470,7 @@ opening the data file, message_subdir gets set. */ 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, +/* tHe value of message_size at this point has been set to the data length, plus one for the blank line that notionally precedes the data. */ /* Now read the contents of the header file, which will set up the headers in @@ -6557,8 +6503,8 @@ give up; if the message has been around for sufficiently long, remove it. */ if (rc != spool_read_hdrerror) { received_time.tv_sec = received_time.tv_usec = 0; - /*XXX subsec precision?*/ - for (i = 0; i < 6; i++) + /*III subsec precision?*/ + for (i = 0; i < MESSAGE_ID_TIME_LEN; i++) received_time.tv_sec = received_time.tv_sec * BASE_62 + tab62[id[i] - '0']; }