/* If requested, add a terminating "." line (SMTP output). */
-if (tctx->options & topt_end_dot && !write_chunk(tctx, US".\n", 2))
- return FALSE;
+if (tctx->options & topt_end_dot)
+ {
+ smtp_debug_cmd(US".", 0);
+ if (!write_chunk(tctx, US".\n", 2))
+ return FALSE;
+ }
/* Write out any remaining data in the buffer before returning. */
? !write_chunk(tctx, US".\n", 2)
: !write_chunk(tctx, US"\n.\n", 3)
) )
- yield = FALSE;
+ { smtp_debug_cmd(US".", 0); yield = FALSE; }
/* Write out any remaining data in the buffer. */
DEBUG(D_exec) debug_print_argv(argv);
exim_nullstd(); /* Ensure std{out,err} exist */
+/* argv[0] should be untainted, from child_exec_exim() */
execv(CS argv[0], (char *const *)argv);
DEBUG(D_any) debug_printf("execv failed: %s\n", strerror(errno));
*/
BOOL
-transport_set_up_command(const uschar ***argvptr, uschar *cmd,
+transport_set_up_command(const uschar *** argvptr, const uschar * cmd,
BOOL expand_arguments, int expand_failed, address_item *addr,
- uschar *etext, uschar **errptr)
+ const uschar * etext, uschar ** errptr)
{
-const uschar **argv;
-uschar *s, *ss;
-int address_count = 0;
-int argcount = 0;
-int max_args;
+const uschar ** argv, * s;
+int address_count = 0, argcount = 0, max_args;
/* Get store in which to build an argument list. Count the number of addresses
supplied, and allow for that many arguments, plus an additional 60, which
arguments are verbatim. Copy each argument into a new string. */
s = cmd;
-while (isspace(*s)) s++;
+Uskip_whitespace(&s);
-for (; *s != 0 && argcount < max_args; argcount++)
+for (; *s && argcount < max_args; argcount++)
{
if (*s == '\'')
{
- ss = s + 1;
- while (*ss != 0 && *ss != '\'') ss++;
- argv[argcount] = ss = store_get(ss - s++, cmd);
- while (*s != 0 && *s != '\'') *ss++ = *s++;
- if (*s != 0) s++;
- *ss++ = 0;
+ int n = Ustrcspn(++s, "'");
+ argv[argcount] = string_copyn(s, n);
+ if (*(s += n) == '\'') s++;
}
else
argv[argcount] = string_dequote(CUSS &s);
- while (isspace(*s)) s++;
+ Uskip_whitespace(&s);
}
-argv[argcount] = US 0;
+argv[argcount] = NULL;
/* If *s != 0 we have run out of argument slots. */
-if (*s != 0)
+if (*s)
{
uschar *msg = string_sprintf("Too many arguments in command \"%s\" in "
"%s", cmd, etext);
- if (addr != NULL)
+ if (addr)
{
addr->transport_return = FAIL;
addr->message = msg;
if (expand_arguments)
{
- BOOL allow_dollar_recipients = addr != NULL &&
- addr->parent != NULL &&
- Ustrcmp(addr->parent->address, "system-filter") == 0;
+ BOOL allow_dollar_recipients = addr && addr->parent
+ && Ustrcmp(addr->parent->address, "system-filter") == 0;
- for (int i = 0; argv[i] != US 0; i++)
+ for (int i = 0; argv[i]; i++)
{
-
/* Handle special fudge for passing an address list */
- if (addr != NULL &&
+ if (addr &&
(Ustrcmp(argv[i], "$pipe_addresses") == 0 ||
Ustrcmp(argv[i], "${pipe_addresses}") == 0))
{
/* Handle special case of $address_pipe when af_force_command is set */
- else if (addr != NULL && testflag(addr,af_force_command) &&
+ else if (addr && testflag(addr,af_force_command) &&
(Ustrcmp(argv[i], "$address_pipe") == 0 ||
Ustrcmp(argv[i], "${address_pipe}") == 0))
{
/* +1 because addr->local_part[0] == '|' since af_force_command is set */
s = expand_string(addr->local_part + 1);
- if (!s || *s == '\0')
+ if (!s || !*s)
{
addr->transport_return = FAIL;
addr->message = string_sprintf("Expansion of \"%s\" "
return FALSE;
}
- while (isspace(*s)) s++; /* strip leading space */
+ Uskip_whitespace(&s); /* strip leading space */
while (*s && address_pipe_argcount < address_pipe_max_args)
{
if (*s == '\'')
- {
- int n;
- for (ss = s + 1; *ss && *ss != '\''; ) ss++;
- n = ss - s++;
- address_pipe_argv[address_pipe_argcount++] = ss = store_get(n, s);
- while (*s && *s != '\'') *ss++ = *s++;
- if (*s) s++;
- *ss++ = 0;
- }
- else address_pipe_argv[address_pipe_argcount++] =
- string_copy(string_dequote(CUSS &s));
- while (isspace(*s)) s++; /* strip space after arg */
+ {
+ int n = Ustrcspn(++s, "'");
+ argv[argcount] = string_copyn(s, n);
+ if (*(s += n) == '\'') s++;
+ }
+ else
+ address_pipe_argv[address_pipe_argcount++] = string_dequote(CUSS &s);
+ Uskip_whitespace(&s); /* strip space after arg */
}
- address_pipe_argv[address_pipe_argcount] = US 0;
+ address_pipe_argv[address_pipe_argcount] = NULL;
/* If *s != 0 we have run out of argument slots. */
- if (*s != 0)
+ if (*s)
{
uschar *msg = string_sprintf("Too many arguments in $address_pipe "
"\"%s\" in %s", addr->local_part + 1, etext);
- if (addr != NULL)
+ if (addr)
{
addr->transport_return = FAIL;
addr->message = msg;
}
/* address_pipe_argcount - 1
- * because we are replacing $address_pipe in the argument list
- * with the first thing it expands to */
+ because we are replacing $address_pipe in the argument list
+ with the first thing it expands to */
+
if (argcount + address_pipe_argcount - 1 > max_args)
{
addr->transport_return = FAIL;
[argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0] */
for (int address_pipe_i = 0;
- address_pipe_argv[address_pipe_i] != US 0;
+ address_pipe_argv[address_pipe_i];
address_pipe_i++, argcount++)
argv[i++] = address_pipe_argv[address_pipe_i];
DEBUG(D_transport)
{
debug_printf("direct command after expansion:\n");
- for (int i = 0; argv[i] != US 0; i++)
+ for (int i = 0; argv[i]; i++)
debug_printf(" argv[%d] = %s\n", i, string_printing(argv[i]));
}
}