FreeBSD: TLS: preload configuration items
[exim.git] / src / src / transports / pipe.c
index 0ce281fd0d2af39468cbb9a4290fb02c561c5431..1cb574ee72c791a4e98b2699774b930e9b18fd62 100644 (file)
@@ -2,7 +2,8 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -21,72 +22,50 @@ with "*" are not settable by the user but are used by the option-reading
 software for alternative value types. Some options are stored in the transport
 instance block so as to be publicly visible; these are flagged with opt_public.
 */
 software for alternative value types. Some options are stored in the transport
 instance block so as to be publicly visible; these are flagged with opt_public.
 */
+#define LOFF(field) OPT_OFF(pipe_transport_options_block, field)
 
 optionlist pipe_transport_options[] = {
 
 optionlist pipe_transport_options[] = {
-  { "allow_commands",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, allow_commands) },
+  { "allow_commands",    opt_stringptr,        LOFF(allow_commands) },
   { "batch_id",          opt_stringptr | opt_public,
   { "batch_id",          opt_stringptr | opt_public,
-      (void *)offsetof(transport_instance, batch_id) },
+      OPT_OFF(transport_instance, batch_id) },
   { "batch_max",         opt_int | opt_public,
   { "batch_max",         opt_int | opt_public,
-      (void *)offsetof(transport_instance, batch_max) },
-  { "check_string",      opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, check_string) },
-  { "command",           opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, cmd) },
-  { "environment",       opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, environment) },
-  { "escape_string",     opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, escape_string) },
-  { "force_command",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, force_command) },
-  { "freeze_exec_fail",  opt_bool,
-      (void *)offsetof(pipe_transport_options_block, freeze_exec_fail) },
-  { "freeze_signal",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, freeze_signal) },
-  { "ignore_status",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, ignore_status) },
+      OPT_OFF(transport_instance, batch_max) },
+  { "check_string",      opt_stringptr,        LOFF(check_string) },
+  { "command",           opt_stringptr,        LOFF(cmd) },
+  { "environment",       opt_stringptr,        LOFF(environment) },
+  { "escape_string",     opt_stringptr,        LOFF(escape_string) },
+  { "force_command",         opt_bool, LOFF(force_command) },
+  { "freeze_exec_fail",  opt_bool,     LOFF(freeze_exec_fail) },
+  { "freeze_signal",     opt_bool,     LOFF(freeze_signal) },
+  { "ignore_status",     opt_bool,     LOFF(ignore_status) },
   { "log_defer_output",  opt_bool | opt_public,
   { "log_defer_output",  opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_defer_output) },
+      OPT_OFF(transport_instance, log_defer_output) },
   { "log_fail_output",   opt_bool | opt_public,
   { "log_fail_output",   opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_fail_output) },
+      OPT_OFF(transport_instance, log_fail_output) },
   { "log_output",        opt_bool | opt_public,
   { "log_output",        opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_output) },
-  { "max_output",        opt_mkint,
-      (void *)offsetof(pipe_transport_options_block, max_output) },
-  { "message_prefix",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, message_prefix) },
-  { "message_suffix",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, message_suffix) },
-  { "path",              opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, path) },
-  { "permit_coredump",   opt_bool,
-      (void *)offsetof(pipe_transport_options_block, permit_coredump) },
+      OPT_OFF(transport_instance, log_output) },
+  { "max_output",        opt_mkint,    LOFF(max_output) },
+  { "message_prefix",    opt_stringptr,        LOFF(message_prefix) },
+  { "message_suffix",    opt_stringptr,        LOFF(message_suffix) },
+  { "path",              opt_stringptr,        LOFF(path) },
+  { "permit_coredump",   opt_bool,     LOFF(permit_coredump) },
   { "pipe_as_creator",   opt_bool | opt_public,
   { "pipe_as_creator",   opt_bool | opt_public,
-      (void *)offsetof(transport_instance, deliver_as_creator) },
-  { "restrict_to_path",  opt_bool,
-      (void *)offsetof(pipe_transport_options_block, restrict_to_path) },
+      OPT_OFF(transport_instance, deliver_as_creator) },
+  { "restrict_to_path",  opt_bool,     LOFF(restrict_to_path) },
   { "return_fail_output",opt_bool | opt_public,
   { "return_fail_output",opt_bool | opt_public,
-      (void *)offsetof(transport_instance, return_fail_output) },
+      OPT_OFF(transport_instance, return_fail_output) },
   { "return_output",     opt_bool | opt_public,
   { "return_output",     opt_bool | opt_public,
-      (void *)offsetof(transport_instance, return_output) },
-  { "temp_errors",       opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, temp_errors) },
-  { "timeout",           opt_time,
-      (void *)offsetof(pipe_transport_options_block, timeout) },
-  { "timeout_defer",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, timeout_defer) },
-  { "umask",             opt_octint,
-      (void *)offsetof(pipe_transport_options_block, umask) },
-  { "use_bsmtp",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_bsmtp) },
+      OPT_OFF(transport_instance, return_output) },
+  { "temp_errors",       opt_stringptr,        LOFF(temp_errors) },
+  { "timeout",           opt_time,     LOFF(timeout) },
+  { "timeout_defer",     opt_bool,     LOFF(timeout_defer) },
+  { "umask",             opt_octint,   LOFF(umask) },
+  { "use_bsmtp",         opt_bool,     LOFF(use_bsmtp) },
   #ifdef HAVE_SETCLASSRESOURCES
   #ifdef HAVE_SETCLASSRESOURCES
-  { "use_classresources", opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_classresources) },
+  { "use_classresources", opt_bool,    LOFF(use_classresources) },
   #endif
   #endif
-  { "use_crlf",          opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_crlf) },
-  { "use_shell",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_shell) },
+  { "use_crlf",          opt_bool,     LOFF(use_crlf) },
+  { "use_shell",         opt_bool,     LOFF(use_shell) },
 };
 
 /* Size of the options list. An extern variable has to be used so that its
 };
 
 /* Size of the options list. An extern variable has to be used so that its
@@ -165,13 +144,6 @@ pipe_transport_setup(transport_instance *tblock, address_item *addrlist,
 pipe_transport_options_block *ob =
   (pipe_transport_options_block *)(tblock->options_block);
 
 pipe_transport_options_block *ob =
   (pipe_transport_options_block *)(tblock->options_block);
 
-addrlist = addrlist;  /* Keep compiler happy */
-dummy = dummy;
-uid = uid;
-gid = gid;
-errmsg = errmsg;
-ob = ob;
-
 #ifdef HAVE_SETCLASSRESOURCES
 if (ob->use_classresources)
   {
 #ifdef HAVE_SETCLASSRESOURCES
 if (ob->use_classresources)
   {
@@ -463,7 +435,7 @@ set_up_shell_command(const uschar ***argvptr, uschar *cmd,
 {
 const uschar **argv;
 
 {
 const uschar **argv;
 
-*argvptr = argv = store_get((4)*sizeof(uschar *));
+*argvptr = argv = store_get((4)*sizeof(uschar *), FALSE);
 
 argv[0] = US"/bin/sh";
 argv[1] = US"-c";
 
 argv[0] = US"/bin/sh";
 argv[1] = US"-c";
@@ -473,8 +445,7 @@ $pipe_addresses, which is not recognized by the normal expansion function. */
 
 if (expand_arguments)
   {
 
 if (expand_arguments)
   {
-  uschar *s = cmd;
-  uschar *p = Ustrstr(cmd, "pipe_addresses");
+  uschar * p = Ustrstr(cmd, "pipe_addresses");
   gstring * g = NULL;
 
   DEBUG(D_transport)
   gstring * g = NULL;
 
   DEBUG(D_transport)
@@ -482,14 +453,13 @@ if (expand_arguments)
 
   /* Allow $recipients in the expansion iff it comes from a system filter */
 
 
   /* Allow $recipients in the expansion iff it comes from a system filter */
 
-  enable_dollar_recipients = addr && addr->parent &&
+  f.enable_dollar_recipients = addr && addr->parent &&
     Ustrcmp(addr->parent->address, "system-filter") == 0;
 
   if (p != NULL && (
          (p > cmd && p[-1] == '$') ||
          (p > cmd + 1 && p[-2] == '$' && p[-1] == '{' && p[14] == '}')))
     {
     Ustrcmp(addr->parent->address, "system-filter") == 0;
 
   if (p != NULL && (
          (p > cmd && p[-1] == '$') ||
          (p > cmd + 1 && p[-2] == '$' && p[-1] == '{' && p[14] == '}')))
     {
-    address_item *ad;
     uschar *q = p + 14;
 
     if (p[-1] == '{') { q++; p--; }
     uschar *q = p + 14;
 
     if (p[-1] == '{') { q++; p--; }
@@ -497,7 +467,7 @@ if (expand_arguments)
     g = string_get(Ustrlen(cmd) + 64);
     g = string_catn(g, cmd, p - cmd - 1);
 
     g = string_get(Ustrlen(cmd) + 64);
     g = string_catn(g, cmd, p - cmd - 1);
 
-    for (ad = addr; ad; ad = ad->next)
+    for (address_item * ad = addr; ad; ad = ad->next)
       {
       /*XXX string_append_listele() ? */
       if (ad != addr) g = string_catn(g, US" ", 1);
       {
       /*XXX string_append_listele() ? */
       if (ad != addr) g = string_catn(g, US" ", 1);
@@ -510,11 +480,11 @@ if (expand_arguments)
   else
     argv[2] = expand_string(cmd);
 
   else
     argv[2] = expand_string(cmd);
 
-  enable_dollar_recipients = FALSE;
+  f.enable_dollar_recipients = FALSE;
 
   if (!argv[2])
     {
 
   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);
     addr->message = string_sprintf("Expansion of command \"%s\" "
       "in %s transport failed: %s",
       cmd, tname, expand_string_message);
@@ -567,12 +537,11 @@ const uschar *envlist = ob->environment;
 uschar *cmd, *ss;
 uschar *eol = ob->use_crlf ? US"\r\n" : US"\n";
 transport_ctx tctx = {
 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);
 };
 
 DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
@@ -589,7 +558,6 @@ symbol. In other cases, the command is supplied as one of the pipe transport's
 options. */
 
 if (testflag(addr, af_pfr) && addr->local_part[0] == '|')
 options. */
 
 if (testflag(addr, af_pfr) && addr->local_part[0] == '|')
-  {
   if (ob->force_command)
     {
     /* Enables expansion of $address_pipe into separate arguments */
   if (ob->force_command)
     {
     /* Enables expansion of $address_pipe into separate arguments */
@@ -605,7 +573,6 @@ if (testflag(addr, af_pfr) && addr->local_part[0] == '|')
     expand_arguments = testflag(addr, af_expand_pipe);
     expand_fail = FAIL;
     }
     expand_arguments = testflag(addr, af_expand_pipe);
     expand_fail = FAIL;
     }
-  }
 else
   {
   cmd = ob->cmd;
 else
   {
   cmd = ob->cmd;
@@ -618,13 +585,20 @@ else
  * coming from addr->local_part[0] == '|'
  */
 
  * coming from addr->local_part[0] == '|'
  */
 
-if (cmd == NULL || *cmd == '\0')
+if (!cmd || !*cmd)
   {
   addr->transport_return = DEFER;
   addr->message = string_sprintf("no command specified for %s transport",
     tblock->name);
   return FALSE;
   }
   {
   addr->transport_return = DEFER;
   addr->message = string_sprintf("no command specified for %s transport",
     tblock->name);
   return FALSE;
   }
+if (is_tainted(cmd))
+  {
+  addr->message = string_sprintf("Tainted '%s' (command "
+    "for %s transport) not permitted", cmd, tblock->name);
+  addr->transport_return = PANIC;
+  return FALSE;
+  }
 
 /* When a pipe is set up by a filter file, there may be values for $thisaddress
 and numerical the variables in existence. These are passed in
 
 /* When a pipe is set up by a filter file, there may be values for $thisaddress
 and numerical the variables in existence. These are passed in
@@ -634,8 +608,8 @@ if (expand_arguments && addr->pipe_expandn)
   {
   uschar **ss = addr->pipe_expandn;
   expand_nmax = -1;
   {
   uschar **ss = addr->pipe_expandn;
   expand_nmax = -1;
-  if (*ss != NULL) filter_thisaddress = *ss++;
-  while (*ss != NULL)
+  if (*ss) filter_thisaddress = *ss++;
+  while (*ss)
     {
     expand_nstring[++expand_nmax] = *ss;
     expand_nlength[expand_nmax] = Ustrlen(*ss++);
     {
     expand_nstring[++expand_nmax] = *ss;
     expand_nlength[expand_nmax] = Ustrlen(*ss++);
@@ -681,16 +655,14 @@ envp[envcount++] = US"SHELL=/bin/sh";
 if (addr->host_list != NULL)
   envp[envcount++] = string_sprintf("HOST=%s", addr->host_list->name);
 
 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);
 
 /* Add any requested items */
 
 if (envlist)
 else if (timezone_string != NULL && timezone_string[0] != 0)
   envp[envcount++] = string_sprintf("TZ=%s", timezone_string);
 
 /* Add any requested items */
 
 if (envlist)
-  {
-  envlist = expand_cstring(envlist);
-  if (envlist == NULL)
+  if (!(envlist = expand_cstring(envlist)))
     {
     addr->transport_return = DEFER;
     addr->message = string_sprintf("failed to expand string \"%s\" "
     {
     addr->transport_return = DEFER;
     addr->message = string_sprintf("failed to expand string \"%s\" "
@@ -698,13 +670,13 @@ if (envlist)
       expand_string_message);
     return FALSE;
     }
       expand_string_message);
     return FALSE;
     }
-  }
 
 
-while ((ss = string_nextinlist(&envlist, &envsep, big_buffer, big_buffer_size)))
+while ((ss = string_nextinlist(&envlist, &envsep, NULL, 0)))
    {
    if (envcount > nelem(envp) - 2)
      {
      addr->transport_return = DEFER;
    {
    if (envcount > nelem(envp) - 2)
      {
      addr->transport_return = DEFER;
+     addr->basic_errno = E2BIG;
      addr->message = string_sprintf("too many environment settings for "
        "%s transport", tblock->name);
      return FALSE;
      addr->message = string_sprintf("too many environment settings for "
        "%s transport", tblock->name);
      return FALSE;
@@ -716,7 +688,7 @@ envp[envcount] = NULL;
 
 /* If the -N option is set, can't do any more. */
 
 
 /* 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",
   {
   DEBUG(D_transport)
     debug_printf("*** delivery by %s transport bypassed by -N option",
@@ -746,7 +718,8 @@ 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. */
 
 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(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0)
+if ((pid = child_open(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE,
+                       US"pipe-tpt-cmd")) < 0)
   {
   addr->transport_return = DEFER;
   addr->message = string_sprintf(
   {
   addr->transport_return = DEFER;
   addr->message = string_sprintf(
@@ -758,7 +731,7 @@ tctx.u.fd = fd_in;
 
 /* Now fork a process to handle the output that comes down the pipe. */
 
 
 /* Now fork a process to handle the output that comes down the pipe. */
 
-if ((outpid = fork()) < 0)
+if ((outpid = exim_fork(US"pipe-tpt-output")) < 0)
   {
   addr->basic_errno = errno;
   addr->transport_return = DEFER;
   {
   addr->basic_errno = errno;
   addr->transport_return = DEFER;
@@ -816,7 +789,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.) */
 
 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);
+testharness_pause_ms(500);
 
 DEBUG(D_transport) debug_printf("Writing message to pipe\n");
 
 
 DEBUG(D_transport) debug_printf("Writing message to pipe\n");
 
@@ -834,12 +807,12 @@ transport_count = 0;
 
 /* First write any configured prefix information */
 
 
 /* First write any configured prefix information */
 
-if (ob->message_prefix != NULL)
+if (ob->message_prefix)
   {
   uschar *prefix = expand_string(ob->message_prefix);
   {
   uschar *prefix = expand_string(ob->message_prefix);
-  if (prefix == NULL)
+  if (!prefix)
     {
     {
-    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);
     addr->message = string_sprintf("Expansion of \"%s\" (prefix for %s "
       "transport) failed: %s", ob->message_prefix, tblock->name,
       expand_string_message);
@@ -856,12 +829,10 @@ than one address available here, all must be included. Force SMTP dot-handling.
 
 if (ob->use_bsmtp)
   {
 
 if (ob->use_bsmtp)
   {
-  address_item *a;
-
   if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol))
     goto END_WRITE;
 
   if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol))
     goto END_WRITE;
 
-  for (a = addr; a; a = a->next)
+  for (address_item * a = addr; a; a = a->next)
     if (!transport_write_string(fd_in,
         "RCPT TO:<%s>%s",
         transport_rcpt_address(a, tblock->rcpt_include_affixes),
     if (!transport_write_string(fd_in,
         "RCPT TO:<%s>%s",
         transport_rcpt_address(a, tblock->rcpt_include_affixes),
@@ -883,7 +854,7 @@ if (ob->message_suffix)
   uschar *suffix = expand_string(ob->message_suffix);
   if (!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);
     addr->message = string_sprintf("Expansion of \"%s\" (suffix for %s "
       "transport) failed: %s", ob->message_suffix, tblock->name,
       expand_string_message);
@@ -922,7 +893,7 @@ if (!written_ok)
   if (errno == ETIMEDOUT)
     {
     addr->message = string_sprintf("%stimeout while writing to pipe",
   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;
     }
     addr->transport_return = ob->timeout_defer? DEFER : FAIL;
     timeout = 1;
     }
@@ -943,7 +914,7 @@ if (!written_ok)
       addr->more_errno,
       (addr->more_errno == EX_EXECFAILED)? ": unable to execute command" : "");
     else if (errno == ERRNO_WRITEINCOMPLETE)
       addr->more_errno,
       (addr->more_errno == EX_EXECFAILED)? ": unable to execute command" : "");
     else if (errno == ERRNO_WRITEINCOMPLETE)
-      addr->message = string_sprintf("Failed repeatedly to write data");
+      addr->message = US"Failed repeatedly to write data";
     else
       addr->message = string_sprintf("Error %d", errno);
     return FALSE;
     else
       addr->message = string_sprintf("Error %d", errno);
     return FALSE;
@@ -956,8 +927,8 @@ above timed out. */
 
 if ((rc = child_close(pid, timeout)) != 0)
   {
 
 if ((rc = child_close(pid, timeout)) != 0)
   {
-  uschar *tmsg = (addr->message == NULL)? US"" :
-    string_sprintf(" (preceded by %s)", addr->message);
+  uschar * tmsg = addr->message
+    ? string_sprintf(" (preceded by %s)", addr->message) : US"";
 
   /* The process did not complete in time; kill its process group and fail
   the delivery. It appears to be necessary to kill the output process too, as
 
   /* The process did not complete in time; kill its process group and fail
   the delivery. It appears to be necessary to kill the output process too, as
@@ -988,7 +959,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. */
 
   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);
     {
     killpg(pid, SIGKILL);
     kill(outpid, SIGKILL);
@@ -1063,7 +1034,7 @@ if ((rc = child_close(pid, timeout)) != 0)
     {
     /* Always handle execve() failure specially if requested to */
 
     {
     /* Always handle execve() failure specially if requested to */
 
-    if (ob->freeze_exec_fail && (rc == EX_EXECFAILED))
+    if (ob->freeze_exec_fail  &&  rc == EX_EXECFAILED)
       {
       addr->transport_return = DEFER;
       addr->special_action = SPECIAL_FREEZE;
       {
       addr->transport_return = DEFER;
       addr->special_action = SPECIAL_FREEZE;
@@ -1077,7 +1048,6 @@ if ((rc = child_close(pid, timeout)) != 0)
       {
       uschar *ss;
       gstring * g;
       {
       uschar *ss;
       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
 
       /* 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
@@ -1112,7 +1082,7 @@ if ((rc = child_close(pid, timeout)) != 0)
           rc-128, os_strsignal(rc-128)) :
         US os_strexit(rc);
 
           rc-128, os_strsignal(rc-128)) :
         US os_strexit(rc);
 
-      if (*ss != 0)
+      if (*ss)
         {
         g = string_catn(g, US" ", 1);
         g = string_cat (g, ss);
         {
         g = string_catn(g, US" ", 1);
         g = string_cat (g, ss);
@@ -1122,7 +1092,7 @@ if ((rc = child_close(pid, timeout)) != 0)
 
       g = string_catn(g, US" from command:", 14);
 
 
       g = string_catn(g, US" from command:", 14);
 
-      for (i = 0; i < sizeof(argv)/sizeof(int *) && argv[i] != NULL; i++)
+      for (int i = 0; i < sizeof(argv)/sizeof(int *) && argv[i] != NULL; i++)
         {
         BOOL quote = FALSE;
         g = string_catn(g, US" ", 1);
         {
         BOOL quote = FALSE;
         g = string_catn(g, US" ", 1);