X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftransports%2Fpipe.c;h=b94c223342a178f3e98ab3186eab1dd27c22c987;hb=b536a578fbabdc9d39da53d54a8d7700ba537431;hp=3f06b1dd6a96b484c1d7d18b72caa7e8c47d7943;hpb=cab0c27721a3c1f3a146e44bcc6462eefb9eb9e7;p=exim.git diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 3f06b1dd6..b94c22334 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -471,13 +471,18 @@ argv[1] = US"-c"; /* We have to take special action to handle the special "variable" called $pipe_addresses, which is not recognized by the normal expansion function. */ -DEBUG(D_transport) - debug_printf("shell pipe command before expansion:\n %s\n", cmd); - if (expand_arguments) { - uschar *s = cmd; - uschar *p = Ustrstr(cmd, "pipe_addresses"); + uschar * p = Ustrstr(cmd, "pipe_addresses"); + gstring * g = NULL; + + DEBUG(D_transport) + debug_printf("shell pipe command before expansion:\n %s\n", cmd); + + /* Allow $recipients in the expansion iff it comes from a system filter */ + + f.enable_dollar_recipients = addr && addr->parent && + Ustrcmp(addr->parent->address, "system-filter") == 0; if (p != NULL && ( (p > cmd && p[-1] == '$') || @@ -485,37 +490,30 @@ if (expand_arguments) { address_item *ad; uschar *q = p + 14; - int size = Ustrlen(cmd) + 64; - int offset; if (p[-1] == '{') { q++; p--; } - s = store_get(size); - offset = p - cmd - 1; - Ustrncpy(s, cmd, offset); + g = string_get(Ustrlen(cmd) + 64); + g = string_catn(g, cmd, p - cmd - 1); - for (ad = addr; ad != NULL; ad = ad->next) + for (ad = addr; ad; ad = ad->next) { /*XXX string_append_listele() ? */ - if (ad != addr) s = string_catn(s, &size, &offset, US" ", 1); - s = string_cat(s, &size, &offset, ad->address); + if (ad != addr) g = string_catn(g, US" ", 1); + g = string_cat(g, ad->address); } - s = string_cat(s, &size, &offset, q); - s[offset] = 0; + g = string_cat(g, q); + argv[2] = (cmd = string_from_gstring(g)) ? expand_string(cmd) : NULL; } + else + argv[2] = expand_string(cmd); - /* Allow $recipients in the expansion iff it comes from a system filter */ - - enable_dollar_recipients = addr != NULL && - addr->parent != NULL && - Ustrcmp(addr->parent->address, "system-filter") == 0; - argv[2] = expand_string(s); - enable_dollar_recipients = FALSE; + f.enable_dollar_recipients = FALSE; - if (argv[2] == NULL) + if (!argv[2]) { - addr->transport_return = search_find_defer? DEFER : expand_fail; + addr->transport_return = f.search_find_defer ? DEFER : expand_fail; addr->message = string_sprintf("Expansion of command \"%s\" " "in %s transport failed: %s", cmd, tname, expand_string_message); @@ -525,9 +523,14 @@ if (expand_arguments) DEBUG(D_transport) debug_printf("shell pipe command after expansion:\n %s\n", argv[2]); } -else argv[2] = cmd; +else + { + DEBUG(D_transport) + debug_printf("shell pipe command (no expansion):\n %s\n", cmd); + argv[2] = cmd; + } -argv[3] = (uschar *)0; +argv[3] = US 0; return TRUE; } @@ -563,12 +566,11 @@ const uschar *envlist = ob->environment; uschar *cmd, *ss; uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { - {0}, - tblock, - addr, - ob->check_string, - ob->escape_string, - ob->options /* set at initialization time */ + .tblock = tblock, + .addr = addr, + .check_string = ob->check_string, + .escape_string = ob->escape_string, + ob->options | topt_not_socket /* set at initialization time */ }; DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name); @@ -677,7 +679,7 @@ envp[envcount++] = US"SHELL=/bin/sh"; if (addr->host_list != NULL) envp[envcount++] = string_sprintf("HOST=%s", addr->host_list->name); -if (timestamps_utc) envp[envcount++] = US"TZ=UTC"; +if (f.timestamps_utc) envp[envcount++] = US"TZ=UTC"; else if (timezone_string != NULL && timezone_string[0] != 0) envp[envcount++] = string_sprintf("TZ=%s", timezone_string); @@ -696,10 +698,9 @@ if (envlist) } } -while ((ss = string_nextinlist(&envlist, &envsep, big_buffer, big_buffer_size)) - != NULL) +while ((ss = string_nextinlist(&envlist, &envsep, big_buffer, big_buffer_size))) { - if (envcount > sizeof(envp)/sizeof(uschar *) - 2) + if (envcount > nelem(envp) - 2) { addr->transport_return = DEFER; addr->message = string_sprintf("too many environment settings for " @@ -713,7 +714,7 @@ envp[envcount] = NULL; /* If the -N option is set, can't do any more. */ -if (dont_deliver) +if (f.dont_deliver) { DEBUG(D_transport) debug_printf("*** delivery by %s transport bypassed by -N option", @@ -813,7 +814,7 @@ bit here to let the sub-process get going, but it may still not complete. So we ignore all writing errors. (When in the test harness, we do do a short sleep so any debugging output is likely to be in the same order.) */ -if (running_in_test_harness) millisleep(500); +if (f.running_in_test_harness) millisleep(500); DEBUG(D_transport) debug_printf("Writing message to pipe\n"); @@ -836,7 +837,7 @@ if (ob->message_prefix != NULL) uschar *prefix = expand_string(ob->message_prefix); if (prefix == NULL) { - addr->transport_return = search_find_defer? DEFER : PANIC; + addr->transport_return = f.search_find_defer? DEFER : PANIC; addr->message = string_sprintf("Expansion of \"%s\" (prefix for %s " "transport) failed: %s", ob->message_prefix, tblock->name, expand_string_message); @@ -880,7 +881,7 @@ if (ob->message_suffix) uschar *suffix = expand_string(ob->message_suffix); if (!suffix) { - addr->transport_return = search_find_defer? DEFER : PANIC; + addr->transport_return = f.search_find_defer? DEFER : PANIC; addr->message = string_sprintf("Expansion of \"%s\" (suffix for %s " "transport) failed: %s", ob->message_suffix, tblock->name, expand_string_message); @@ -919,7 +920,7 @@ if (!written_ok) if (errno == ETIMEDOUT) { addr->message = string_sprintf("%stimeout while writing to pipe", - transport_filter_timed_out? "transport filter " : ""); + f.transport_filter_timed_out ? "transport filter " : ""); addr->transport_return = ob->timeout_defer? DEFER : FAIL; timeout = 1; } @@ -985,7 +986,7 @@ if ((rc = child_close(pid, timeout)) != 0) This prevents the transport_filter timeout message from getting overwritten by the exit error which is not the cause of the problem. */ - else if (transport_filter_timed_out) + else if (f.transport_filter_timed_out) { killpg(pid, SIGKILL); kill(outpid, SIGKILL); @@ -1073,7 +1074,8 @@ if ((rc = child_close(pid, timeout)) != 0) else if (!ob->ignore_status) { uschar *ss; - int size, ptr, i; + gstring * g; + int i; /* If temp_errors is "*" all codes are temporary. Initialization checks that it's either "*" or a list of numbers. If not "*", scan the list of @@ -1098,9 +1100,7 @@ if ((rc = child_close(pid, timeout)) != 0) addr->message = string_sprintf("Child process of %s transport returned " "%d", tblock->name, rc); - - ptr = Ustrlen(addr->message); - size = ptr + 1; + g = string_cat(NULL, addr->message); /* If the return code is > 128, it often means that a shell command was terminated by a signal. */ @@ -1112,35 +1112,34 @@ if ((rc = child_close(pid, timeout)) != 0) if (*ss != 0) { - addr->message = string_catn(addr->message, &size, &ptr, US" ", 1); - addr->message = string_cat (addr->message, &size, &ptr, ss); + g = string_catn(g, US" ", 1); + g = string_cat (g, ss); } /* Now add the command and arguments */ - addr->message = string_catn(addr->message, &size, &ptr, - US" from command:", 14); + g = string_catn(g, US" from command:", 14); for (i = 0; i < sizeof(argv)/sizeof(int *) && argv[i] != NULL; i++) { BOOL quote = FALSE; - addr->message = string_catn(addr->message, &size, &ptr, US" ", 1); + g = string_catn(g, US" ", 1); if (Ustrpbrk(argv[i], " \t") != NULL) { quote = TRUE; - addr->message = string_catn(addr->message, &size, &ptr, US"\"", 1); + g = string_catn(g, US"\"", 1); } - addr->message = string_cat(addr->message, &size, &ptr, argv[i]); + g = string_cat(g, argv[i]); if (quote) - addr->message = string_catn(addr->message, &size, &ptr, US"\"", 1); + g = string_catn(g, US"\"", 1); } /* Add previous filter timeout message, if present. */ if (*tmsg) - addr->message = string_cat(addr->message, &size, &ptr, tmsg); + g = string_cat(g, tmsg); - addr->message[ptr] = 0; /* Ensure concatenated string terminated */ + addr->message = string_from_gstring(g); } } }