X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Ftransports%2Fpipe.c;h=5470c72ded944e80fd486d6d7141f33693cff2e6;hb=3fc73bdc7aa8ac2b2b290033f602bdb947ae8049;hp=8b87e4a95909c57ed6fd74877b9f9c111c243bcc;hpb=4c04137d73637107669e02b21f890387aaa2ef34;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 8b87e4a95..5470c72de 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. */ @@ -95,6 +95,17 @@ address can appear in the tables drtables.c. */ int pipe_transport_options_count = sizeof(pipe_transport_options)/sizeof(optionlist); + +#ifdef MACRO_PREDEF + +/* Dummy values */ +pipe_transport_options_block pipe_transport_option_defaults = {0}; +void pipe_transport_init(transport_instance *tblock) {} +BOOL pipe_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;} + +#else /*!MACRO_PREDEF*/ + + /* Default private options block for the pipe transport. */ pipe_transport_options_block pipe_transport_option_defaults = { @@ -460,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 */ + + enable_dollar_recipients = addr && addr->parent && + Ustrcmp(addr->parent->address, "system-filter") == 0; if (p != NULL && ( (p > cmd && p[-1] == '$') || @@ -474,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; - if (argv[2] == NULL) + if (!argv[2]) { - addr->transport_return = search_find_defer? DEFER : expand_fail; + addr->transport_return = search_find_defer ? DEFER : expand_fail; addr->message = string_sprintf("Expansion of command \"%s\" " "in %s transport failed: %s", cmd, tname, expand_string_message); @@ -514,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; } @@ -552,11 +566,11 @@ const uschar *envlist = ob->environment; uschar *cmd, *ss; uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { - 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); @@ -684,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 " @@ -739,6 +752,7 @@ if ((pid = child_open(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0) strerror(errno)); return FALSE; } +tctx.u.fd = fd_in; /* Now fork a process to handle the output that comes down the pipe. */ @@ -829,7 +843,7 @@ if (ob->message_prefix != NULL) expand_string_message); return FALSE; } - if (!transport_write_block(fd_in, prefix, Ustrlen(prefix))) + if (!transport_write_block(&tctx, prefix, Ustrlen(prefix), FALSE)) goto END_WRITE; } @@ -857,7 +871,7 @@ if (ob->use_bsmtp) /* Now the actual message */ -if (!transport_write_message(fd_in, &tctx, 0)) +if (!transport_write_message(&tctx, 0)) goto END_WRITE; /* Now any configured suffix */ @@ -873,7 +887,7 @@ if (ob->message_suffix) expand_string_message); return FALSE; } - if (!transport_write_block(fd_in, suffix, Ustrlen(suffix))) + if (!transport_write_block(&tctx, suffix, Ustrlen(suffix), FALSE)) goto END_WRITE; } @@ -1060,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 @@ -1085,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. */ @@ -1099,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); } } } @@ -1150,4 +1162,5 @@ if (addr->transport_return != OK) return FALSE; } +#endif /*!MACRO_PREDEF*/ /* End of transport/pipe.c */