X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/09792322d9224b0407783a19c2dd57fd1a8bbd52..44bc8f0c2f3576b46bd6df1b818cb29eaf84df5b:/src/src/transports/pipe.c diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 39a9d8b47..d3841e050 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 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -326,12 +326,12 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_direct_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments, - int expand_fail, address_item *addr, uschar *tname, +set_up_direct_command(const uschar ***argvptr, uschar *cmd, + BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname, pipe_transport_options_block *ob) { BOOL permitted = FALSE; -uschar **argv; +const uschar **argv; uschar buffer[64]; /* Set up "transport " to be put in any error messages, and then @@ -353,11 +353,11 @@ argv = *argvptr; if (ob->allow_commands != NULL) { int sep = 0; - uschar *s, *p; + const uschar *s; + uschar *p; uschar buffer[256]; - s = expand_string(ob->allow_commands); - if (s == NULL) + if (!(s = expand_string(ob->allow_commands))) { addr->transport_return = DEFER; addr->message = string_sprintf("failed to expand string \"%s\" " @@ -365,10 +365,8 @@ if (ob->allow_commands != NULL) return FALSE; } - while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer))) != NULL) - { + while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer)))) if (Ustrcmp(p, argv[0]) == 0) { permitted = TRUE; break; } - } } /* If permitted is TRUE it means the command was found in the allowed list, and @@ -407,7 +405,7 @@ if (argv[0][0] != '/') { int sep = 0; uschar *p; - uschar *listptr = ob->path; + const uschar *listptr = ob->path; uschar buffer[1024]; while ((p = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) != NULL) @@ -453,10 +451,10 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_shell_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments, - int expand_fail, address_item *addr, uschar *tname) +set_up_shell_command(const uschar ***argvptr, uschar *cmd, + BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname) { -uschar **argv; +const uschar **argv; *argvptr = argv = store_get((4)*sizeof(uschar *)); @@ -491,11 +489,12 @@ if (expand_arguments) for (ad = addr; ad != NULL; ad = ad->next) { - if (ad != addr) string_cat(s, &size, &offset, US" ", 1); - string_cat(s, &size, &offset, ad->address, Ustrlen(ad->address)); + /*XXX string_append_listele() ? */ + if (ad != addr) s = string_catn(s, &size, &offset, US" ", 1); + s = string_cat(s, &size, &offset, ad->address); } - string_cat(s, &size, &offset, q, Ustrlen(q)); + s = string_cat(s, &size, &offset, q); s[offset] = 0; } @@ -551,11 +550,18 @@ pipe_transport_options_block *ob = int timeout = ob->timeout; BOOL written_ok = FALSE; BOOL expand_arguments; -uschar **argv; +const uschar **argv; uschar *envp[50]; -uschar *envlist = ob->environment; +const uschar *envlist = ob->environment; uschar *cmd, *ss; -uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n"; +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 */ +}; DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name); @@ -572,17 +578,20 @@ options. */ if (testflag(addr, af_pfr) && addr->local_part[0] == '|') { - if (ob->force_command) { - /* Enables expansion of $address_pipe into seperate arguments */ - setflag(addr,af_force_command); - cmd = ob->cmd; - expand_arguments = TRUE; - expand_fail = PANIC; - } else { - cmd = addr->local_part + 1; - while (isspace(*cmd)) cmd++; - expand_arguments = testflag(addr, af_expand_pipe); - expand_fail = FAIL; + if (ob->force_command) + { + /* Enables expansion of $address_pipe into seperate arguments */ + setflag(addr, af_force_command); + cmd = ob->cmd; + expand_arguments = TRUE; + expand_fail = PANIC; + } + else + { + cmd = addr->local_part + 1; + while (isspace(*cmd)) cmd++; + expand_arguments = testflag(addr, af_expand_pipe); + expand_fail = FAIL; } } else @@ -666,9 +675,9 @@ else if (timezone_string != NULL && timezone_string[0] != 0) /* Add any requested items */ -if (envlist != NULL) +if (envlist) { - envlist = expand_string(envlist); + envlist = expand_cstring(envlist); if (envlist == NULL) { addr->transport_return = DEFER; @@ -726,7 +735,7 @@ reading of the output pipe. */ uid/gid and current directory. Request that the new process be a process group leader, so we can kill it and all its children on a timeout. */ -if ((pid = child_open(argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0) +if ((pid = child_open(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0) { addr->transport_return = DEFER; addr->message = string_sprintf( @@ -840,23 +849,19 @@ if (ob->use_bsmtp) if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol)) goto END_WRITE; - for (a = addr; a != NULL; a = a->next) - { + for (a = addr; a; a = a->next) if (!transport_write_string(fd_in, "RCPT TO:<%s>%s", transport_rcpt_address(a, tblock->rcpt_include_affixes), eol)) goto END_WRITE; - } if (!transport_write_string(fd_in, "DATA%s", eol)) goto END_WRITE; } -/* Now the actual message - the options were set at initialization time */ +/* Now the actual message */ -if (!transport_write_message(addr, fd_in, ob->options, 0, tblock->add_headers, - tblock->remove_headers, ob->check_string, ob->escape_string, - tblock->rewrite_rules, tblock->rewrite_existflags)) +if (!transport_write_message(fd_in, &tctx, 0)) goto END_WRITE; /* Now any configured suffix */ @@ -1070,16 +1075,14 @@ if ((rc = child_close(pid, timeout)) != 0) else { - uschar *s = ob->temp_errors; + const uschar *s = ob->temp_errors; uschar *p; uschar buffer[64]; int sep = 0; addr->transport_return = FAIL; - while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer))) != NULL) - { + while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer)))) if (rc == Uatoi(p)) { addr->transport_return = DEFER; break; } - } } /* Ensure the message contains the expanded command and arguments. This @@ -1101,36 +1104,33 @@ if ((rc = child_close(pid, timeout)) != 0) if (*ss != 0) { - addr->message = string_cat(addr->message, &size, &ptr, US" ", 1); - addr->message = string_cat(addr->message, &size, &ptr, - ss, Ustrlen(ss)); + addr->message = string_catn(addr->message, &size, &ptr, US" ", 1); + addr->message = string_cat (addr->message, &size, &ptr, ss); } /* Now add the command and arguments */ - addr->message = string_cat(addr->message, &size, &ptr, + addr->message = string_catn(addr->message, &size, &ptr, US" from command:", 14); for (i = 0; i < sizeof(argv)/sizeof(int *) && argv[i] != NULL; i++) { BOOL quote = FALSE; - addr->message = string_cat(addr->message, &size, &ptr, US" ", 1); + addr->message = string_catn(addr->message, &size, &ptr, US" ", 1); if (Ustrpbrk(argv[i], " \t") != NULL) { quote = TRUE; - addr->message = string_cat(addr->message, &size, &ptr, US"\"", 1); + addr->message = string_catn(addr->message, &size, &ptr, US"\"", 1); } - addr->message = string_cat(addr->message, &size, &ptr, argv[i], - Ustrlen(argv[i])); + addr->message = string_cat(addr->message, &size, &ptr, argv[i]); if (quote) - addr->message = string_cat(addr->message, &size, &ptr, US"\"", 1); + addr->message = string_catn(addr->message, &size, &ptr, US"\"", 1); } /* Add previous filter timeout message, if present. */ - if (*tmsg != 0) - addr->message = string_cat(addr->message, &size, &ptr, tmsg, - Ustrlen(tmsg)); + if (*tmsg) + addr->message = string_cat(addr->message, &size, &ptr, tmsg); addr->message[ptr] = 0; /* Ensure concatenated string terminated */ }