Tidying and compiler-silencing
[exim.git] / src / src / smtp_in.c
index daaab91724d027b735549466204ce500c7b41177..cb6469811925754158b4a0358b9146e0ecfbd74e 100644 (file)
@@ -131,28 +131,35 @@ to the circular buffer that holds a list of the last n received. */
 *                Local static variables          *
 *************************************************/
 
 *                Local static variables          *
 *************************************************/
 
-static auth_instance *authenticated_by;
-static BOOL auth_advertised;
+static struct {
+  BOOL auth_advertised                 :1;
 #ifdef SUPPORT_TLS
 #ifdef SUPPORT_TLS
-static BOOL tls_advertised;
+  BOOL tls_advertised                  :1;
 # ifdef EXPERIMENTAL_REQUIRETLS
 # ifdef EXPERIMENTAL_REQUIRETLS
-static BOOL requiretls_advertised;
+  BOOL requiretls_advertised           :1;
 # endif
 #endif
 # endif
 #endif
-static BOOL dsn_advertised;
-static BOOL esmtp;
-static BOOL helo_required = FALSE;
-static BOOL helo_verify = FALSE;
-static BOOL helo_seen;
-static BOOL helo_accept_junk;
-static BOOL count_nonmail;
-static BOOL rcpt_smtp_response_same;
-static BOOL rcpt_in_progress;
-static int  nonmail_command_count;
-static BOOL smtp_exit_function_called = 0;
+  BOOL dsn_advertised                  :1;
+  BOOL esmtp                           :1;
+  BOOL helo_required                   :1;
+  BOOL helo_verify                     :1;
+  BOOL helo_seen                       :1;
+  BOOL helo_accept_junk                        :1;
+  BOOL rcpt_smtp_response_same         :1;
+  BOOL rcpt_in_progress                        :1;
+  BOOL smtp_exit_function_called       :1;
 #ifdef SUPPORT_I18N
 #ifdef SUPPORT_I18N
-static BOOL smtputf8_advertised;
+  BOOL smtputf8_advertised             :1;
 #endif
 #endif
+} fl = {
+  .helo_required = FALSE,
+  .helo_verify = FALSE,
+  .smtp_exit_function_called = FALSE,
+};
+
+static auth_instance *authenticated_by;
+static int  count_nonmail;
+static int  nonmail_command_count;
 static int  synprot_error_count;
 static int  unknown_command_count;
 static int  sync_cmd_limit;
 static int  synprot_error_count;
 static int  unknown_command_count;
 static int  sync_cmd_limit;
@@ -374,7 +381,7 @@ return FALSE;
 static BOOL
 check_sync(void)
 {
 static BOOL
 check_sync(void)
 {
-if (!smtp_enforce_sync || !sender_host_address || sender_host_notsocket)
+if (!smtp_enforce_sync || !sender_host_address || f.sender_host_notsocket)
   return TRUE;
 
 return wouldblock_reading();
   return TRUE;
 
 return wouldblock_reading();
@@ -388,10 +395,12 @@ static BOOL
 pipeline_response(void)
 {
 if (  !smtp_enforce_sync || !sender_host_address
 pipeline_response(void)
 {
 if (  !smtp_enforce_sync || !sender_host_address
-   || sender_host_notsocket || !smtp_in_pipelining_advertised)
+   || f.sender_host_notsocket || !f.smtp_in_pipelining_advertised)
   return FALSE;
 
   return FALSE;
 
-return !wouldblock_reading();
+if (wouldblock_reading()) return FALSE;
+f.smtp_in_pipelining_used = TRUE;
+return TRUE;
 }
 
 
 }
 
 
@@ -621,7 +630,7 @@ for(;;)
   /* Unless PIPELINING was offered, there should be no next command
   until after we ack that chunk */
 
   /* Unless PIPELINING was offered, there should be no next command
   until after we ack that chunk */
 
-  if (!smtp_in_pipelining_advertised && !check_sync())
+  if (!f.smtp_in_pipelining_advertised && !check_sync())
     {
     unsigned n = smtp_inend - smtp_inptr;
     if (n > 32) n = 32;
     {
     unsigned n = smtp_inend - smtp_inptr;
     if (n > 32) n = 32;
@@ -918,14 +927,14 @@ be tidier to have it only in one place, but when it was added, it was easier to
 do it that way, so as not to have to mess with the code for the RCPT command,
 which sometimes uses smtp_printf() and sometimes smtp_respond(). */
 
 do it that way, so as not to have to mess with the code for the RCPT command,
 which sometimes uses smtp_printf() and sometimes smtp_respond(). */
 
-if (rcpt_in_progress)
+if (fl.rcpt_in_progress)
   {
   if (rcpt_smtp_response == NULL)
     rcpt_smtp_response = string_copy(big_buffer);
   {
   if (rcpt_smtp_response == NULL)
     rcpt_smtp_response = string_copy(big_buffer);
-  else if (rcpt_smtp_response_same &&
+  else if (fl.rcpt_smtp_response_same &&
            Ustrcmp(rcpt_smtp_response, big_buffer) != 0)
            Ustrcmp(rcpt_smtp_response, big_buffer) != 0)
-    rcpt_smtp_response_same = FALSE;
-  rcpt_in_progress = FALSE;
+    fl.rcpt_smtp_response_same = FALSE;
+  fl.rcpt_in_progress = FALSE;
   }
 
 /* Now write the string */
   }
 
 /* Now write the string */
@@ -1518,7 +1527,7 @@ bad:
     }
   else
     {
     }
   else
     {
-    proxy_session_failed = TRUE;
+    f.proxy_session_failed = TRUE;
     DEBUG(D_receive)
       debug_printf("Failure to extract proxied host, only QUIT allowed\n");
     }
     DEBUG(D_receive)
       debug_printf("Failure to extract proxied host, only QUIT allowed\n");
     }
@@ -1604,7 +1613,7 @@ for (p = cmd_list; p < cmd_list_end; p++)
   {
 #ifdef SUPPORT_PROXY
   /* Only allow QUIT command if Proxy Protocol parsing failed */
   {
 #ifdef SUPPORT_PROXY
   /* Only allow QUIT command if Proxy Protocol parsing failed */
-  if (proxy_session && proxy_session_failed && p->cmd != QUIT_CMD)
+  if (proxy_session && f.proxy_session_failed && p->cmd != QUIT_CMD)
     continue;
 #endif
   if (  p->len
     continue;
 #endif
   if (  p->len
@@ -1619,7 +1628,7 @@ for (p = cmd_list; p < cmd_list_end; p++)
         check_sync &&                                  /* Local flag set */
         smtp_enforce_sync &&                           /* Global flag set */
         sender_host_address != NULL &&                 /* Not local input */
         check_sync &&                                  /* Local flag set */
         smtp_enforce_sync &&                           /* Global flag set */
         sender_host_address != NULL &&                 /* Not local input */
-        !sender_host_notsocket)                        /* Really is a socket */
+        !f.sender_host_notsocket)                        /* Really is a socket */
       return BADSYN_CMD;
 
     /* The variables $smtp_command and $smtp_command_argument point into the
       return BADSYN_CMD;
 
     /* The variables $smtp_command and $smtp_command_argument point into the
@@ -1658,7 +1667,7 @@ for (p = cmd_list; p < cmd_list_end; p++)
 
 #ifdef SUPPORT_PROXY
 /* Only allow QUIT command if Proxy Protocol parsing failed */
 
 #ifdef SUPPORT_PROXY
 /* Only allow QUIT command if Proxy Protocol parsing failed */
-if (proxy_session && proxy_session_failed)
+if (proxy_session && f.proxy_session_failed)
   return PROXY_FAIL_IGNORE_CMD;
 #endif
 
   return PROXY_FAIL_IGNORE_CMD;
 #endif
 
@@ -1668,7 +1677,7 @@ if (  smtp_inptr < smtp_inend             /* Outstanding input */
    && check_sync                       /* Local flag set */
    && smtp_enforce_sync                        /* Global flag set */
    && sender_host_address              /* Not local input */
    && check_sync                       /* Local flag set */
    && smtp_enforce_sync                        /* Global flag set */
    && sender_host_address              /* Not local input */
-   && !sender_host_notsocket)          /* Really is a socket */
+   && !f.sender_host_notsocket)                /* Really is a socket */
   return BADSYN_CMD;
 
 return OTHER_CMD;
   return BADSYN_CMD;
 
 return OTHER_CMD;
@@ -1745,10 +1754,10 @@ const uschar * hostname = sender_fullhost
 if (host_checking)
   return string_sprintf("SMTP connection from %s", hostname);
 
 if (host_checking)
   return string_sprintf("SMTP connection from %s", hostname);
 
-if (sender_host_unknown || sender_host_notsocket)
+if (f.sender_host_unknown || f.sender_host_notsocket)
   return string_sprintf("SMTP connection from %s", sender_ident);
 
   return string_sprintf("SMTP connection from %s", sender_ident);
 
-if (is_inetd)
+if (f.is_inetd)
   return string_sprintf("SMTP connection from %s (via inetd)", hostname);
 
 if (LOGGING(incoming_interface) && interface_address != NULL)
   return string_sprintf("SMTP connection from %s (via inetd)", hostname);
 
 if (LOGGING(incoming_interface) && interface_address != NULL)
@@ -1833,7 +1842,7 @@ for (i = 0; i < smtp_ch_index; i++)
 if (!(s = string_from_gstring(g))) s = US"";
 
 log_write(0, LOG_MAIN, "no MAIL in %sSMTP connection from %s D=%s%s",
 if (!(s = string_from_gstring(g))) s = US"";
 
 log_write(0, LOG_MAIN, "no MAIL in %sSMTP connection from %s D=%s%s",
-  tcp_in_fastopen ? US"TFO " : US"",
+  f.tcp_in_fastopen ? US"TFO " : US"",
   host_and_ident(FALSE), string_timesince(&smtp_connection_start), s);
 }
 
   host_and_ident(FALSE), string_timesince(&smtp_connection_start), s);
 }
 
@@ -1884,7 +1893,7 @@ check_helo(uschar *s)
 {
 uschar *start = s;
 uschar *end = s + Ustrlen(s);
 {
 uschar *start = s;
 uschar *end = s + Ustrlen(s);
-BOOL yield = helo_accept_junk;
+BOOL yield = fl.helo_accept_junk;
 
 /* Discard any previous helo name */
 
 
 /* Discard any previous helo name */
 
@@ -2013,20 +2022,20 @@ message_linecount = 0;
 message_size = -1;
 acl_added_headers = NULL;
 acl_removed_headers = NULL;
 message_size = -1;
 acl_added_headers = NULL;
 acl_removed_headers = NULL;
-queue_only_policy = FALSE;
+f.queue_only_policy = FALSE;
 rcpt_smtp_response = NULL;
 rcpt_smtp_response = NULL;
-rcpt_smtp_response_same = TRUE;
-rcpt_in_progress = FALSE;
-deliver_freeze = FALSE;                              /* Can be set by ACL */
+fl.rcpt_smtp_response_same = TRUE;
+fl.rcpt_in_progress = FALSE;
+f.deliver_freeze = FALSE;                              /* Can be set by ACL */
 freeze_tell = freeze_tell_config;                    /* Can be set by ACL */
 fake_response = OK;                                  /* Can be set by ACL */
 #ifdef WITH_CONTENT_SCAN
 freeze_tell = freeze_tell_config;                    /* Can be set by ACL */
 fake_response = OK;                                  /* Can be set by ACL */
 #ifdef WITH_CONTENT_SCAN
-no_mbox_unspool = FALSE;                             /* Can be set by ACL */
+f.no_mbox_unspool = FALSE;                             /* Can be set by ACL */
 #endif
 #endif
-submission_mode = FALSE;                             /* Can be set by ACL */
-suppress_local_fixups = suppress_local_fixups_default; /* Can be set by ACL */
-active_local_from_check = local_from_check;          /* Can be set by ACL */
-active_local_sender_retain = local_sender_retain;    /* Can be set by ACL */
+f.submission_mode = FALSE;                             /* Can be set by ACL */
+f.suppress_local_fixups = f.suppress_local_fixups_default; /* Can be set by ACL */
+f.active_local_from_check = local_from_check;          /* Can be set by ACL */
+f.active_local_sender_retain = local_sender_retain;    /* Can be set by ACL */
 sending_ip_address = NULL;
 return_path = sender_address = NULL;
 sender_data = NULL;                                 /* Can be set by ACL */
 sending_ip_address = NULL;
 return_path = sender_address = NULL;
 sender_data = NULL;                                 /* Can be set by ACL */
@@ -2054,14 +2063,14 @@ spf_result_guessed = FALSE;
 dkim_cur_signer = dkim_signers =
 dkim_signing_domain = dkim_signing_selector = dkim_signatures = NULL;
 dkim_cur_signer = dkim_signers = dkim_signing_domain = dkim_signing_selector = NULL;
 dkim_cur_signer = dkim_signers =
 dkim_signing_domain = dkim_signing_selector = dkim_signatures = NULL;
 dkim_cur_signer = dkim_signers = dkim_signing_domain = dkim_signing_selector = NULL;
-dkim_disable_verify = FALSE;
+f.dkim_disable_verify = FALSE;
 dkim_collect_input = 0;
 dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL;
 dkim_key_length = 0;
 dkim_verify_signers = US"$dkim_signers";
 #endif
 #ifdef EXPERIMENTAL_DMARC
 dkim_collect_input = 0;
 dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL;
 dkim_key_length = 0;
 dkim_verify_signers = US"$dkim_signers";
 #endif
 #ifdef EXPERIMENTAL_DMARC
-dmarc_has_been_checked = dmarc_disable_verify = dmarc_enable_forensic = FALSE;
+f.dmarc_has_been_checked = f.dmarc_disable_verify = f.dmarc_enable_forensic = FALSE;
 dmarc_domain_policy = dmarc_status = dmarc_status_text =
 dmarc_used_domain = NULL;
 #endif
 dmarc_domain_policy = dmarc_status = dmarc_status_text =
 dmarc_used_domain = NULL;
 #endif
@@ -2224,7 +2233,7 @@ while (done <= 0)
 
       if (  !sender_domain
          && sender_address[0] != 0 && sender_address[0] != '@')
 
       if (  !sender_domain
          && sender_address[0] != 0 && sender_address[0] != '@')
-       if (allow_unqualified_sender)
+       if (f.allow_unqualified_sender)
          {
          sender_address = rewrite_address_qualify(sender_address, FALSE);
          DEBUG(D_receive) debug_printf("unqualified address %s accepted "
          {
          sender_address = rewrite_address_qualify(sender_address, FALSE);
          DEBUG(D_receive) debug_printf("unqualified address %s accepted "
@@ -2280,7 +2289,7 @@ while (done <= 0)
       add it to the list of recipients. */
 
       if (!recipient_domain)
       add it to the list of recipients. */
 
       if (!recipient_domain)
-       if (allow_unqualified_recipient)
+       if (f.allow_unqualified_recipient)
          {
          DEBUG(D_receive) debug_printf("unqualified address %s accepted\n",
            recipient);
          {
          DEBUG(D_receive) debug_printf("unqualified address %s accepted\n",
            recipient);
@@ -2358,6 +2367,7 @@ return done - 2;  /* Convert yield values */
 
 
 
 
 
 
+#ifdef SUPPORT_TLS
 static BOOL
 smtp_log_tls_fail(uschar * errstr)
 {
 static BOOL
 smtp_log_tls_fail(uschar * errstr)
 {
@@ -2369,6 +2379,7 @@ if (Ustrncmp(conn_info, US"SMTP ", 5) == 0) conn_info += 5;
 log_write(0, LOG_MAIN, "TLS error on %s %s", conn_info, errstr);
 return FALSE;
 }
 log_write(0, LOG_MAIN, "TLS error on %s %s", conn_info, errstr);
 return FALSE;
 }
+#endif
 
 
 
 
 
 
@@ -2386,7 +2397,7 @@ if (  getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_INFO, &tinfo, &len) == 0
    )
   {
   DEBUG(D_receive) debug_printf("TCP_FASTOPEN mode connection (state TCP_SYN_RECV)\n");
    )
   {
   DEBUG(D_receive) debug_printf("TCP_FASTOPEN mode connection (state TCP_SYN_RECV)\n");
-  tcp_in_fastopen = TRUE;
+  f.tcp_in_fastopen = TRUE;
   }
 # endif
 }
   }
 # endif
 }
@@ -2422,21 +2433,21 @@ smtp_ch_index = 0;
 
 /* Default values for certain variables */
 
 
 /* Default values for certain variables */
 
-helo_seen = esmtp = helo_accept_junk = FALSE;
+fl.helo_seen = fl.esmtp = fl.helo_accept_junk = FALSE;
 smtp_mailcmd_count = 0;
 count_nonmail = TRUE_UNSET;
 synprot_error_count = unknown_command_count = nonmail_command_count = 0;
 smtp_delay_mail = smtp_rlm_base;
 smtp_mailcmd_count = 0;
 count_nonmail = TRUE_UNSET;
 synprot_error_count = unknown_command_count = nonmail_command_count = 0;
 smtp_delay_mail = smtp_rlm_base;
-auth_advertised = FALSE;
-smtp_in_pipelining_advertised = FALSE;
-pipelining_enable = TRUE;
+fl.auth_advertised = FALSE;
+f.smtp_in_pipelining_advertised = f.smtp_in_pipelining_used = FALSE;
+f.pipelining_enable = TRUE;
 sync_cmd_limit = NON_SYNC_CMD_NON_PIPELINING;
 sync_cmd_limit = NON_SYNC_CMD_NON_PIPELINING;
-smtp_exit_function_called = FALSE;    /* For avoiding loop in not-quit exit */
+fl.smtp_exit_function_called = FALSE;    /* For avoiding loop in not-quit exit */
 
 /* If receiving by -bs from a trusted user, or testing with -bh, we allow
 authentication settings from -oMaa to remain in force. */
 
 
 /* If receiving by -bs from a trusted user, or testing with -bh, we allow
 authentication settings from -oMaa to remain in force. */
 
-if (!host_checking && !sender_host_notsocket)
+if (!host_checking && !f.sender_host_notsocket)
   sender_host_auth_pubname = sender_host_authenticated = NULL;
 authenticated_by = NULL;
 
   sender_host_auth_pubname = sender_host_authenticated = NULL;
 authenticated_by = NULL;
 
@@ -2445,14 +2456,14 @@ tls_in.cipher = tls_in.peerdn = NULL;
 tls_in.ourcert = tls_in.peercert = NULL;
 tls_in.sni = NULL;
 tls_in.ocsp = OCSP_NOT_REQ;
 tls_in.ourcert = tls_in.peercert = NULL;
 tls_in.sni = NULL;
 tls_in.ocsp = OCSP_NOT_REQ;
-tls_advertised = FALSE;
+fl.tls_advertised = FALSE;
 # ifdef EXPERIMENTAL_REQUIRETLS
 # ifdef EXPERIMENTAL_REQUIRETLS
-requiretls_advertised = FALSE;
+fl.requiretls_advertised = FALSE;
 # endif
 #endif
 # endif
 #endif
-dsn_advertised = FALSE;
+fl.dsn_advertised = FALSE;
 #ifdef SUPPORT_I18N
 #ifdef SUPPORT_I18N
-smtputf8_advertised = FALSE;
+fl.smtputf8_advertised = FALSE;
 #endif
 
 /* Reset ACL connection variables */
 #endif
 
 /* Reset ACL connection variables */
@@ -2526,7 +2537,7 @@ the flag sender_host_notsocket is used to suppress it.
 If smtp_accept_max and smtp_accept_reserve are set, keep some connections in
 reserve for certain hosts and/or networks. */
 
 If smtp_accept_max and smtp_accept_reserve are set, keep some connections in
 reserve for certain hosts and/or networks. */
 
-if (!sender_host_unknown)
+if (!f.sender_host_unknown)
   {
   int rc;
   BOOL reserved_host = FALSE;
   {
   int rc;
   BOOL reserved_host = FALSE;
@@ -2570,7 +2581,7 @@ if (!sender_host_unknown)
     #define OPTSTYLE 3
   #endif
 
     #define OPTSTYLE 3
   #endif
 
-  if (!host_checking && !sender_host_notsocket)
+  if (!host_checking && !f.sender_host_notsocket)
     {
     #if OPTSTYLE == 1
     EXIM_SOCKLEN_T optlen = sizeof(struct ip_options) + MAX_IPOPTLEN;
     {
     #if OPTSTYLE == 1
     EXIM_SOCKLEN_T optlen = sizeof(struct ip_options) + MAX_IPOPTLEN;
@@ -2717,7 +2728,7 @@ if (!sender_host_unknown)
   setting is an attempt to get rid of some hanging connections that stick in
   read() when the remote end (usually a dialup) goes away. */
 
   setting is an attempt to get rid of some hanging connections that stick in
   read() when the remote end (usually a dialup) goes away. */
 
-  if (smtp_accept_keepalive && !sender_host_notsocket)
+  if (smtp_accept_keepalive && !f.sender_host_notsocket)
     ip_keepalive(fileno(smtp_out), sender_host_address, FALSE);
 
   /* If the current host matches host_lookup, set the name by doing a
     ip_keepalive(fileno(smtp_out), sender_host_address, FALSE);
 
   /* If the current host matches host_lookup, set the name by doing a
@@ -2848,23 +2859,23 @@ if (!sender_host_unknown)
   addresses in the headers. For a site that permits no qualification, this
   won't take long, however. */
 
   addresses in the headers. For a site that permits no qualification, this
   won't take long, however. */
 
-  allow_unqualified_sender =
+  f.allow_unqualified_sender =
     verify_check_host(&sender_unqualified_hosts) == OK;
 
     verify_check_host(&sender_unqualified_hosts) == OK;
 
-  allow_unqualified_recipient =
+  f.allow_unqualified_recipient =
     verify_check_host(&recipient_unqualified_hosts) == OK;
 
   /* Determine whether HELO/EHLO is required for this host. The requirement
   can be hard or soft. */
 
     verify_check_host(&recipient_unqualified_hosts) == OK;
 
   /* Determine whether HELO/EHLO is required for this host. The requirement
   can be hard or soft. */
 
-  helo_required = verify_check_host(&helo_verify_hosts) == OK;
-  if (!helo_required)
-    helo_verify = verify_check_host(&helo_try_verify_hosts) == OK;
+  fl.helo_required = verify_check_host(&helo_verify_hosts) == OK;
+  if (!fl.helo_required)
+    fl.helo_verify = verify_check_host(&helo_try_verify_hosts) == OK;
 
   /* Determine whether this hosts is permitted to send syntactic junk
   after a HELO or EHLO command. */
 
 
   /* Determine whether this hosts is permitted to send syntactic junk
   after a HELO or EHLO command. */
 
-  helo_accept_junk = verify_check_host(&helo_accept_junk_hosts) == OK;
+  fl.helo_accept_junk = verify_check_host(&helo_accept_junk_hosts) == OK;
   }
 
 /* For batch SMTP input we are now done. */
   }
 
 /* For batch SMTP input we are now done. */
@@ -2876,7 +2887,7 @@ if (smtp_batched_input) return TRUE;
 
 #ifdef SUPPORT_PROXY
 proxy_session = FALSE;
 
 #ifdef SUPPORT_PROXY
 proxy_session = FALSE;
-proxy_session_failed = FALSE;
+f.proxy_session_failed = FALSE;
 if (check_proxy_protocol_host())
   setup_proxy_protocol_host();
 #endif
 if (check_proxy_protocol_host())
   setup_proxy_protocol_host();
 #endif
@@ -3081,7 +3092,7 @@ smtp_respond(uschar* code, int codelen, BOOL final, uschar *msg)
 int esclen = 0;
 uschar *esc = US"";
 
 int esclen = 0;
 uschar *esc = US"";
 
-if (!final && no_multiline_responses) return;
+if (!final && f.no_multiline_responses) return;
 
 if (codelen > 4)
   {
 
 if (codelen > 4)
   {
@@ -3095,14 +3106,14 @@ be tidier to have it only in one place, but when it was added, it was easier to
 do it that way, so as not to have to mess with the code for the RCPT command,
 which sometimes uses smtp_printf() and sometimes smtp_respond(). */
 
 do it that way, so as not to have to mess with the code for the RCPT command,
 which sometimes uses smtp_printf() and sometimes smtp_respond(). */
 
-if (rcpt_in_progress)
+if (fl.rcpt_in_progress)
   {
   if (rcpt_smtp_response == NULL)
     rcpt_smtp_response = string_copy(msg);
   {
   if (rcpt_smtp_response == NULL)
     rcpt_smtp_response = string_copy(msg);
-  else if (rcpt_smtp_response_same &&
+  else if (fl.rcpt_smtp_response_same &&
            Ustrcmp(rcpt_smtp_response, msg) != 0)
            Ustrcmp(rcpt_smtp_response, msg) != 0)
-    rcpt_smtp_response_same = FALSE;
-  rcpt_in_progress = FALSE;
+    fl.rcpt_smtp_response_same = FALSE;
+  fl.rcpt_in_progress = FALSE;
   }
 
 /* Now output the message, splitting it up into multiple lines if necessary.
   }
 
 /* Now output the message, splitting it up into multiple lines if necessary.
@@ -3117,7 +3128,7 @@ for (;;)
     smtp_printf("%.3s%c%.*s%s\r\n", !final, code, final ? ' ':'-', esclen, esc, msg);
     return;
     }
     smtp_printf("%.3s%c%.*s%s\r\n", !final, code, final ? ' ':'-', esclen, esc, msg);
     return;
     }
-  else if (nl[1] == 0 || no_multiline_responses)
+  else if (nl[1] == 0 || f.no_multiline_responses)
     {
     smtp_printf("%.3s%c%.*s%.*s\r\n", !final, code, final ? ' ':'-', esclen, esc,
       (int)(nl - msg), msg);
     {
     smtp_printf("%.3s%c%.*s%.*s\r\n", !final, code, final ? ' ':'-', esclen, esc,
       (int)(nl - msg), msg);
@@ -3289,8 +3300,8 @@ unless the sender_verify_fail log selector has been turned off. */
 if (sender_verified_failed &&
     !testflag(sender_verified_failed, af_sverify_told))
   {
 if (sender_verified_failed &&
     !testflag(sender_verified_failed, af_sverify_told))
   {
-  BOOL save_rcpt_in_progress = rcpt_in_progress;
-  rcpt_in_progress = FALSE;  /* So as not to treat these as the error */
+  BOOL save_rcpt_in_progress = fl.rcpt_in_progress;
+  fl.rcpt_in_progress = FALSE;  /* So as not to treat these as the error */
 
   setflag(sender_verified_failed, af_sverify_told);
 
 
   setflag(sender_verified_failed, af_sverify_told);
 
@@ -3322,7 +3333,7 @@ if (sender_verified_failed &&
         sender_verified_failed->address,
         sender_verified_failed->user_message));
 
         sender_verified_failed->address,
         sender_verified_failed->user_message));
 
-  rcpt_in_progress = save_rcpt_in_progress;
+  fl.rcpt_in_progress = save_rcpt_in_progress;
   }
 
 /* Sort out text for logging */
   }
 
 /* Sort out text for logging */
@@ -3347,7 +3358,7 @@ interactions between temp_details and return_error_details. One day it should
 be re-implemented in a tidier fashion. */
 
 else
 be re-implemented in a tidier fashion. */
 
 else
-  if (acl_temp_details && user_msg)
+  if (f.acl_temp_details && user_msg)
     {
     if (  smtp_return_error_details
        && sender_verified_failed
     {
     if (  smtp_return_error_details
        && sender_verified_failed
@@ -3435,13 +3446,13 @@ uschar *log_msg = NULL;
 
 /* Check for recursive acll */
 
 
 /* Check for recursive acll */
 
-if (smtp_exit_function_called)
+if (fl.smtp_exit_function_called)
   {
   log_write(0, LOG_PANIC, "smtp_notquit_exit() called more than once (%s)",
     reason);
   return;
   }
   {
   log_write(0, LOG_PANIC, "smtp_notquit_exit() called more than once (%s)",
     reason);
   return;
   }
-smtp_exit_function_called = TRUE;
+fl.smtp_exit_function_called = TRUE;
 
 /* Call the not-QUIT ACL, if there is one, unless no reason is given. */
 
 
 /* Call the not-QUIT ACL, if there is one, unless no reason is given. */
 
@@ -3517,27 +3528,27 @@ if (sender_helo_name == NULL)
 else if (sender_host_address == NULL)
   {
   HDEBUG(D_receive) debug_printf("no client IP address: assume success\n");
 else if (sender_host_address == NULL)
   {
   HDEBUG(D_receive) debug_printf("no client IP address: assume success\n");
-  helo_verified = TRUE;
+  f.helo_verified = TRUE;
   }
 
 /* Deal with the more common case when there is a sending IP address */
 
 else if (sender_helo_name[0] == '[')
   {
   }
 
 /* Deal with the more common case when there is a sending IP address */
 
 else if (sender_helo_name[0] == '[')
   {
-  helo_verified = Ustrncmp(sender_helo_name+1, sender_host_address,
+  f.helo_verified = Ustrncmp(sender_helo_name+1, sender_host_address,
     Ustrlen(sender_host_address)) == 0;
 
 #if HAVE_IPV6
     Ustrlen(sender_host_address)) == 0;
 
 #if HAVE_IPV6
-  if (!helo_verified)
+  if (!f.helo_verified)
     {
     if (strncmpic(sender_host_address, US"::ffff:", 7) == 0)
     {
     if (strncmpic(sender_host_address, US"::ffff:", 7) == 0)
-      helo_verified = Ustrncmp(sender_helo_name + 1,
+      f.helo_verified = Ustrncmp(sender_helo_name + 1,
         sender_host_address + 7, Ustrlen(sender_host_address) - 7) == 0;
     }
 #endif
 
   HDEBUG(D_receive)
         sender_host_address + 7, Ustrlen(sender_host_address) - 7) == 0;
     }
 #endif
 
   HDEBUG(D_receive)
-    { if (helo_verified) debug_printf("matched host address\n"); }
+    { if (f.helo_verified) debug_printf("matched host address\n"); }
   }
 
 /* Do a reverse lookup if one hasn't already given a positive or negative
   }
 
 /* Do a reverse lookup if one hasn't already given a positive or negative
@@ -3552,7 +3563,7 @@ else
   /* If a host name is known, check it and all its aliases. */
 
   if (sender_host_name)
   /* If a host name is known, check it and all its aliases. */
 
   if (sender_host_name)
-    if ((helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0))
+    if ((f.helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0))
       {
       sender_helo_dnssec = sender_host_dnssec;
       HDEBUG(D_receive) debug_printf("matched host name\n");
       {
       sender_helo_dnssec = sender_host_dnssec;
       HDEBUG(D_receive) debug_printf("matched host name\n");
@@ -3561,19 +3572,19 @@ else
       {
       uschar **aliases = sender_host_aliases;
       while (*aliases)
       {
       uschar **aliases = sender_host_aliases;
       while (*aliases)
-        if ((helo_verified = strcmpic(*aliases++, sender_helo_name) == 0))
+        if ((f.helo_verified = strcmpic(*aliases++, sender_helo_name) == 0))
          {
          sender_helo_dnssec = sender_host_dnssec;
          break;
          }
 
          {
          sender_helo_dnssec = sender_host_dnssec;
          break;
          }
 
-      HDEBUG(D_receive) if (helo_verified)
+      HDEBUG(D_receive) if (f.helo_verified)
           debug_printf("matched alias %s\n", *(--aliases));
       }
 
   /* Final attempt: try a forward lookup of the helo name */
 
           debug_printf("matched alias %s\n", *(--aliases));
       }
 
   /* Final attempt: try a forward lookup of the helo name */
 
-  if (!helo_verified)
+  if (!f.helo_verified)
     {
     int rc;
     host_item h;
     {
     int rc;
     host_item h;
@@ -3595,7 +3606,7 @@ else
       for (hh = &h; hh; hh = hh->next)
         if (Ustrcmp(hh->address, sender_host_address) == 0)
           {
       for (hh = &h; hh; hh = hh->next)
         if (Ustrcmp(hh->address, sender_host_address) == 0)
           {
-          helo_verified = TRUE;
+          f.helo_verified = TRUE;
          if (h.dnssec == DS_YES) sender_helo_dnssec = TRUE;
           HDEBUG(D_receive)
            {
          if (h.dnssec == DS_YES) sender_helo_dnssec = TRUE;
           HDEBUG(D_receive)
            {
@@ -3608,7 +3619,7 @@ else
     }
   }
 
     }
   }
 
-if (!helo_verified) helo_verify_failed = TRUE;  /* We've tried ... */
+if (!f.helo_verified) f.helo_verify_failed = TRUE;  /* We've tried ... */
 return yield;
 }
 
 return yield;
 }
 
@@ -3755,7 +3766,7 @@ static int
 qualify_recipient(uschar ** recipient, uschar * smtp_cmd_data, uschar * tag)
 {
 int rd;
 qualify_recipient(uschar ** recipient, uschar * smtp_cmd_data, uschar * tag)
 {
 int rd;
-if (allow_unqualified_recipient || strcmpic(*recipient, US"postmaster") == 0)
+if (f.allow_unqualified_recipient || strcmpic(*recipient, US"postmaster") == 0)
   {
   DEBUG(D_receive) debug_printf("unqualified address %s accepted\n",
     *recipient);
   {
   DEBUG(D_receive) debug_printf("unqualified address %s accepted\n",
     *recipient);
@@ -3857,7 +3868,7 @@ for the host). Note: we do NOT reset AUTH at this point. */
 smtp_reset(reset_point);
 message_ended = END_NOTSTARTED;
 
 smtp_reset(reset_point);
 message_ended = END_NOTSTARTED;
 
-chunking_state = chunking_offered ? CHUNKING_OFFERED : CHUNKING_NOT_OFFERED;
+chunking_state = f.chunking_offered ? CHUNKING_OFFERED : CHUNKING_NOT_OFFERED;
 
 cmd_list[CMD_LIST_RSET].is_mail_cmd = TRUE;
 cmd_list[CMD_LIST_HELO].is_mail_cmd = TRUE;
 
 cmd_list[CMD_LIST_RSET].is_mail_cmd = TRUE;
 cmd_list[CMD_LIST_HELO].is_mail_cmd = TRUE;
@@ -3960,7 +3971,7 @@ while (done <= 0)
       authentication_failed = TRUE;
       cmd_list[CMD_LIST_AUTH].is_mail_cmd = FALSE;
 
       authentication_failed = TRUE;
       cmd_list[CMD_LIST_AUTH].is_mail_cmd = FALSE;
 
-      if (!auth_advertised && !allow_auth_unadvertised)
+      if (!fl.auth_advertised && !f.allow_auth_unadvertised)
        {
        done = synprot_error(L_smtp_protocol_error, 503, NULL,
          US"AUTH command used when not advertised");
        {
        done = synprot_error(L_smtp_protocol_error, 503, NULL,
          US"AUTH command used when not advertised");
@@ -4019,7 +4030,7 @@ while (done <= 0)
 
       for (au = auths; au; au = au->next)
        if (strcmpic(s, au->public_name) == 0 && au->server &&
 
       for (au = auths; au; au = au->next)
        if (strcmpic(s, au->public_name) == 0 && au->server &&
-           (au->advertised || allow_auth_unadvertised))
+           (au->advertised || f.allow_auth_unadvertised))
          break;
 
       if (au)
          break;
 
       if (au)
@@ -4056,13 +4067,13 @@ while (done <= 0)
     case HELO_CMD:
       HAD(SCH_HELO);
       hello = US"HELO";
     case HELO_CMD:
       HAD(SCH_HELO);
       hello = US"HELO";
-      esmtp = FALSE;
+      fl.esmtp = FALSE;
       goto HELO_EHLO;
 
     case EHLO_CMD:
       HAD(SCH_EHLO);
       hello = US"EHLO";
       goto HELO_EHLO;
 
     case EHLO_CMD:
       HAD(SCH_EHLO);
       hello = US"EHLO";
-      esmtp = TRUE;
+      fl.esmtp = TRUE;
 
     HELO_EHLO:      /* Common code for HELO and EHLO */
       cmd_list[CMD_LIST_HELO].is_mail_cmd = FALSE;
 
     HELO_EHLO:      /* Common code for HELO and EHLO */
       cmd_list[CMD_LIST_HELO].is_mail_cmd = FALSE;
@@ -4098,9 +4109,9 @@ while (done <= 0)
       is set, ensure that the HELO name matches the actual host. If helo_verify
       is set, do the same check, but softly. */
 
       is set, ensure that the HELO name matches the actual host. If helo_verify
       is set, do the same check, but softly. */
 
-      if (!sender_host_unknown)
+      if (!f.sender_host_unknown)
        {
        {
-       BOOL old_helo_verified = helo_verified;
+       BOOL old_helo_verified = f.helo_verified;
        uschar *p = smtp_cmd_data;
 
        while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
        uschar *p = smtp_cmd_data;
 
        while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
@@ -4129,20 +4140,20 @@ while (done <= 0)
        now obsolescent, since the verification can now be requested selectively
        at ACL time. */
 
        now obsolescent, since the verification can now be requested selectively
        at ACL time. */
 
-       helo_verified = helo_verify_failed = sender_helo_dnssec = FALSE;
-       if (helo_required || helo_verify)
+       f.helo_verified = f.helo_verify_failed = sender_helo_dnssec = FALSE;
+       if (fl.helo_required || fl.helo_verify)
          {
          BOOL tempfail = !smtp_verify_helo();
          {
          BOOL tempfail = !smtp_verify_helo();
-         if (!helo_verified)
+         if (!f.helo_verified)
            {
            {
-           if (helo_required)
+           if (fl.helo_required)
              {
              smtp_printf("%d %s argument does not match calling host\r\n", FALSE,
                tempfail? 451 : 550, hello);
              log_write(0, LOG_MAIN|LOG_REJECT, "%srejected \"%s %s\" from %s",
                tempfail? "temporarily " : "",
                hello, sender_helo_name, host_and_ident(FALSE));
              {
              smtp_printf("%d %s argument does not match calling host\r\n", FALSE,
                tempfail? 451 : 550, hello);
              log_write(0, LOG_MAIN|LOG_REJECT, "%srejected \"%s %s\" from %s",
                tempfail? "temporarily " : "",
                hello, sender_helo_name, host_and_ident(FALSE));
-             helo_verified = old_helo_verified;
+             f.helo_verified = old_helo_verified;
              break;                   /* End of HELO/EHLO processing */
              }
            HDEBUG(D_all) debug_printf("%s verification failed but host is in "
              break;                   /* End of HELO/EHLO processing */
              }
            HDEBUG(D_all) debug_printf("%s verification failed but host is in "
@@ -4180,17 +4191,17 @@ while (done <= 0)
       some broken systems expect each response to be in a single packet, arrange
       that the entire reply is sent in one write(). */
 
       some broken systems expect each response to be in a single packet, arrange
       that the entire reply is sent in one write(). */
 
-      auth_advertised = FALSE;
-      smtp_in_pipelining_advertised = FALSE;
+      fl.auth_advertised = FALSE;
+      f.smtp_in_pipelining_advertised = FALSE;
 #ifdef SUPPORT_TLS
 #ifdef SUPPORT_TLS
-      tls_advertised = FALSE;
+      fl.tls_advertised = FALSE;
 # ifdef EXPERIMENTAL_REQUIRETLS
 # ifdef EXPERIMENTAL_REQUIRETLS
-      requiretls_advertised = FALSE;
+      fl.requiretls_advertised = FALSE;
 # endif
 #endif
 # endif
 #endif
-      dsn_advertised = FALSE;
+      fl.dsn_advertised = FALSE;
 #ifdef SUPPORT_I18N
 #ifdef SUPPORT_I18N
-      smtputf8_advertised = FALSE;
+      fl.smtputf8_advertised = FALSE;
 #endif
 
       smtp_code = US"250 ";        /* Default response code plus space*/
 #endif
 
       smtp_code = US"250 ";        /* Default response code plus space*/
@@ -4236,7 +4247,7 @@ while (done <= 0)
       /* If we received EHLO, we must create a multiline response which includes
       the functions supported. */
 
       /* If we received EHLO, we must create a multiline response which includes
       the functions supported. */
 
-      if (esmtp)
+      if (fl.esmtp)
        {
        g->s[3] = '-';
 
        {
        g->s[3] = '-';
 
@@ -4276,7 +4287,7 @@ while (done <= 0)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-DSN\r\n", 6);
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-DSN\r\n", 6);
-         dsn_advertised = TRUE;
+         fl.dsn_advertised = TRUE;
          }
 
        /* Advertise ETRN/VRFY/EXPN if there's are ACL checking whether a host is
          }
 
        /* Advertise ETRN/VRFY/EXPN if there's are ACL checking whether a host is
@@ -4301,13 +4312,13 @@ while (done <= 0)
        /* Exim is quite happy with pipelining, so let the other end know that
        it is safe to use it, unless advertising is disabled. */
 
        /* Exim is quite happy with pipelining, so let the other end know that
        it is safe to use it, unless advertising is disabled. */
 
-       if (pipelining_enable &&
+       if (f.pipelining_enable &&
            verify_check_host(&pipelining_advertise_hosts) == OK)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-PIPELINING\r\n", 13);
          sync_cmd_limit = NON_SYNC_CMD_PIPELINING;
            verify_check_host(&pipelining_advertise_hosts) == OK)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-PIPELINING\r\n", 13);
          sync_cmd_limit = NON_SYNC_CMD_PIPELINING;
-         smtp_in_pipelining_advertised = TRUE;
+         f.smtp_in_pipelining_advertised = TRUE;
          }
 
 
          }
 
 
@@ -4349,7 +4360,7 @@ while (done <= 0)
                  g = string_catn(g, smtp_code, 3);
                  g = string_catn(g, US"-AUTH", 5);
                  first = FALSE;
                  g = string_catn(g, smtp_code, 3);
                  g = string_catn(g, US"-AUTH", 5);
                  first = FALSE;
-                 auth_advertised = TRUE;
+                 fl.auth_advertised = TRUE;
                  }
                saveptr = g->ptr;
                g = string_catn(g, US" ", 1);
                  }
                saveptr = g->ptr;
                g = string_catn(g, US" ", 1);
@@ -4369,7 +4380,7 @@ while (done <= 0)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-CHUNKING\r\n", 11);
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-CHUNKING\r\n", 11);
-         chunking_offered = TRUE;
+         f.chunking_offered = TRUE;
          chunking_state = CHUNKING_OFFERED;
          }
 
          chunking_state = CHUNKING_OFFERED;
          }
 
@@ -4384,7 +4395,7 @@ while (done <= 0)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-STARTTLS\r\n", 11);
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-STARTTLS\r\n", 11);
-         tls_advertised = TRUE;
+         fl.tls_advertised = TRUE;
          }
 
 # ifdef EXPERIMENTAL_REQUIRETLS
          }
 
 # ifdef EXPERIMENTAL_REQUIRETLS
@@ -4394,7 +4405,7 @@ while (done <= 0)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-REQUIRETLS\r\n", 13);
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-REQUIRETLS\r\n", 13);
-         requiretls_advertised = TRUE;
+         fl.requiretls_advertised = TRUE;
          }
 # endif
 #endif
          }
 # endif
 #endif
@@ -4414,7 +4425,7 @@ while (done <= 0)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-SMTPUTF8\r\n", 11);
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-SMTPUTF8\r\n", 11);
-         smtputf8_advertised = TRUE;
+         fl.smtputf8_advertised = TRUE;
          }
 #endif
 
          }
 #endif
 
@@ -4443,12 +4454,12 @@ while (done <= 0)
          memmove(cr, cr + 1, (g->ptr--) - (cr - g->s));
        debug_printf("SMTP>> %s", g->s);
        }
          memmove(cr, cr + 1, (g->ptr--) - (cr - g->s));
        debug_printf("SMTP>> %s", g->s);
        }
-      helo_seen = TRUE;
+      fl.helo_seen = TRUE;
 
       /* Reset the protocol and the state, abandoning any previous message. */
       received_protocol =
        (sender_host_address ? protocols : protocols_local)
 
       /* Reset the protocol and the state, abandoning any previous message. */
       received_protocol =
        (sender_host_address ? protocols : protocols_local)
-         [ (esmtp
+         [ (fl.esmtp
            ? pextend + (sender_host_authenticated ? pauthed : 0)
            : pnormal)
          + (tls_in.active.sock >= 0 ? pcrpted : 0)
            ? pextend + (sender_host_authenticated ? pauthed : 0)
            : pnormal)
          + (tls_in.active.sock >= 0 ? pcrpted : 0)
@@ -4471,7 +4482,7 @@ while (done <= 0)
       was_rej_mail = TRUE;               /* Reset if accepted */
       env_mail_type_t * mail_args;       /* Sanity check & validate args */
 
       was_rej_mail = TRUE;               /* Reset if accepted */
       env_mail_type_t * mail_args;       /* Sanity check & validate args */
 
-      if (helo_required && !helo_seen)
+      if (fl.helo_required && !fl.helo_seen)
        {
        smtp_printf("503 HELO or EHLO required\r\n", FALSE);
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
        {
        smtp_printf("503 HELO or EHLO required\r\n", FALSE);
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
@@ -4515,7 +4526,7 @@ while (done <= 0)
 
       /* Loop, checking for ESMTP additions to the MAIL FROM command. */
 
 
       /* Loop, checking for ESMTP additions to the MAIL FROM command. */
 
-      if (esmtp) for(;;)
+      if (fl.esmtp) for(;;)
        {
        uschar *name, *value, *end;
        unsigned long int size;
        {
        uschar *name, *value, *end;
        unsigned long int size;
@@ -4578,7 +4589,7 @@ while (done <= 0)
          is included only if configured in at build time. */
 
          case ENV_MAIL_OPT_RET:
          is included only if configured in at build time. */
 
          case ENV_MAIL_OPT_RET:
-           if (dsn_advertised)
+           if (fl.dsn_advertised)
              {
              /* Check if RET has already been set */
              if (dsn_ret > 0)
              {
              /* Check if RET has already been set */
              if (dsn_ret > 0)
@@ -4603,7 +4614,7 @@ while (done <= 0)
              }
            break;
          case ENV_MAIL_OPT_ENVID:
              }
            break;
          case ENV_MAIL_OPT_ENVID:
-           if (dsn_advertised)
+           if (fl.dsn_advertised)
              {
              /* Check if the dsn envid has been already set */
              if (dsn_envid)
              {
              /* Check if the dsn envid has been already set */
              if (dsn_envid)
@@ -4695,7 +4706,7 @@ while (done <= 0)
 
 #ifdef SUPPORT_I18N
          case ENV_MAIL_OPT_UTF8:
 
 #ifdef SUPPORT_I18N
          case ENV_MAIL_OPT_UTF8:
-           if (!smtputf8_advertised)
+           if (!fl.smtputf8_advertised)
              {
              done = synprot_error(L_smtp_syntax_error, 501, NULL,
                US"SMTPUTF8 used when not advertised");
              {
              done = synprot_error(L_smtp_syntax_error, 501, NULL,
                US"SMTPUTF8 used when not advertised");
@@ -4717,12 +4728,9 @@ while (done <= 0)
 #if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS)
          case ENV_MAIL_OPT_REQTLS:
            {
 #if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS)
          case ENV_MAIL_OPT_REQTLS:
            {
-           const uschar * list = value;
-           int sep = ',';
-           const uschar * opt;
            uschar * r, * t;
 
            uschar * r, * t;
 
-           if (!requiretls_advertised)
+           if (!fl.requiretls_advertised)
              {
              done = synprot_error(L_smtp_syntax_error, 555, NULL,
                US"unadvertised MAIL option: REQUIRETLS");
              {
              done = synprot_error(L_smtp_syntax_error, 555, NULL,
                US"unadvertised MAIL option: REQUIRETLS");
@@ -4844,7 +4852,7 @@ while (done <= 0)
       of the SMTP connection. */
 
       if (!sender_domain && *sender_address)
       of the SMTP connection. */
 
       if (!sender_domain && *sender_address)
-       if (allow_unqualified_sender)
+       if (f.allow_unqualified_sender)
          {
          sender_domain = Ustrlen(sender_address) + 1;
          sender_address = rewrite_address_qualify(sender_address, FALSE);
          {
          sender_domain = Ustrlen(sender_address) + 1;
          sender_address = rewrite_address_qualify(sender_address, FALSE);
@@ -4872,7 +4880,7 @@ while (done <= 0)
       if (acl_smtp_mail)
        {
        rc = acl_check(ACL_WHERE_MAIL, NULL, acl_smtp_mail, &user_msg, &log_msg);
       if (acl_smtp_mail)
        {
        rc = acl_check(ACL_WHERE_MAIL, NULL, acl_smtp_mail, &user_msg, &log_msg);
-       if (rc == OK && !smtp_in_pipelining_advertised && !check_sync())
+       if (rc == OK && !f.smtp_in_pipelining_advertised && !check_sync())
          goto SYNC_FAILURE;
        }
       else
          goto SYNC_FAILURE;
        }
       else
@@ -4899,7 +4907,7 @@ while (done <= 0)
          smtp_user_msg(US"250", user_msg);
          }
        smtp_delay_rcpt = smtp_rlr_base;
          smtp_user_msg(US"250", user_msg);
          }
        smtp_delay_rcpt = smtp_rlr_base;
-       recipients_discarded = (rc == DISCARD);
+       f.recipients_discarded = (rc == DISCARD);
        was_rej_mail = FALSE;
        }
       else
        was_rej_mail = FALSE;
        }
       else
@@ -4918,7 +4926,7 @@ while (done <= 0)
     case RCPT_CMD:
       HAD(SCH_RCPT);
       rcpt_count++;
     case RCPT_CMD:
       HAD(SCH_RCPT);
       rcpt_count++;
-      was_rcpt = rcpt_in_progress = TRUE;
+      was_rcpt = fl.rcpt_in_progress = TRUE;
 
       /* There must be a sender address; if the sender was rejected and
       pipelining was advertised, we assume the client was pipelining, and do not
 
       /* There must be a sender address; if the sender was rejected and
       pipelining was advertised, we assume the client was pipelining, and do not
@@ -4927,7 +4935,7 @@ while (done <= 0)
 
       if (sender_address == NULL)
        {
 
       if (sender_address == NULL)
        {
-       if (smtp_in_pipelining_advertised && last_was_rej_mail)
+       if (f.smtp_in_pipelining_advertised && last_was_rej_mail)
          {
          smtp_printf("503 sender not yet given\r\n", FALSE);
          was_rej_mail = TRUE;
          {
          smtp_printf("503 sender not yet given\r\n", FALSE);
          was_rej_mail = TRUE;
@@ -4956,14 +4964,14 @@ while (done <= 0)
       orcpt = NULL;
       flags = 0;
 
       orcpt = NULL;
       flags = 0;
 
-      if (esmtp) for(;;)
+      if (fl.esmtp) for(;;)
        {
        uschar *name, *value;
 
        if (!extract_option(&name, &value))
          break;
 
        {
        uschar *name, *value;
 
        if (!extract_option(&name, &value))
          break;
 
-       if (dsn_advertised && strcmpic(name, US"ORCPT") == 0)
+       if (fl.dsn_advertised && strcmpic(name, US"ORCPT") == 0)
          {
          /* Check whether orcpt has been already set */
          if (orcpt)
          {
          /* Check whether orcpt has been already set */
          if (orcpt)
@@ -4976,7 +4984,7 @@ while (done <= 0)
          DEBUG(D_receive) debug_printf("DSN orcpt: %s\n", orcpt);
          }
 
          DEBUG(D_receive) debug_printf("DSN orcpt: %s\n", orcpt);
          }
 
-       else if (dsn_advertised && strcmpic(name, US"NOTIFY") == 0)
+       else if (fl.dsn_advertised && strcmpic(name, US"NOTIFY") == 0)
          {
          /* Check if the notify flags have been already set */
          if (flags > 0)
          {
          /* Check if the notify flags have been already set */
          if (flags > 0)
@@ -5115,12 +5123,12 @@ while (done <= 0)
       there may be a delay in this, re-check for a synchronization error
       afterwards, unless pipelining was advertised. */
 
       there may be a delay in this, re-check for a synchronization error
       afterwards, unless pipelining was advertised. */
 
-      if (recipients_discarded)
+      if (f.recipients_discarded)
        rc = DISCARD;
       else
        if (  (rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
                      &log_msg)) == OK
        rc = DISCARD;
       else
        if (  (rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
                      &log_msg)) == OK
-          && !smtp_in_pipelining_advertised && !check_sync())
+          && !f.smtp_in_pipelining_advertised && !check_sync())
          goto SYNC_FAILURE;
 
       /* The ACL was happy */
          goto SYNC_FAILURE;
 
       /* The ACL was happy */
@@ -5157,7 +5165,7 @@ while (done <= 0)
        log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
          "discarded by %s ACL%s%s", host_and_ident(TRUE),
          sender_address_unrewritten? sender_address_unrewritten : sender_address,
        log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
          "discarded by %s ACL%s%s", host_and_ident(TRUE),
          sender_address_unrewritten? sender_address_unrewritten : sender_address,
-         smtp_cmd_argument, recipients_discarded? "MAIL" : "RCPT",
+         smtp_cmd_argument, f.recipients_discarded? "MAIL" : "RCPT",
          log_msg ? US": " : US"", log_msg ? log_msg : US"");
        }
 
          log_msg ? US": " : US"", log_msg ? log_msg : US"");
        }
 
@@ -5227,19 +5235,19 @@ while (done <= 0)
       receive_getc = bdat_getc;
       receive_ungetc = bdat_ungetc;
 
       receive_getc = bdat_getc;
       receive_ungetc = bdat_ungetc;
 
-      dot_ends = FALSE;
+      f.dot_ends = FALSE;
 
       goto DATA_BDAT;
       }
 
     case DATA_CMD:
       HAD(SCH_DATA);
 
       goto DATA_BDAT;
       }
 
     case DATA_CMD:
       HAD(SCH_DATA);
-      dot_ends = TRUE;
+      f.dot_ends = TRUE;
 
       DATA_BDAT:               /* Common code for DATA and BDAT */
       if (!discarded && recipients_count <= 0)
        {
 
       DATA_BDAT:               /* Common code for DATA and BDAT */
       if (!discarded && recipients_count <= 0)
        {
-       if (rcpt_smtp_response_same && rcpt_smtp_response != NULL)
+       if (fl.rcpt_smtp_response_same && rcpt_smtp_response != NULL)
          {
          uschar *code = US"503";
          int len = Ustrlen(rcpt_smtp_response);
          {
          uschar *code = US"503";
          int len = Ustrlen(rcpt_smtp_response);
@@ -5250,7 +5258,7 @@ while (done <= 0)
            rcpt_smtp_response[len-2] = 0;
          smtp_respond(code, 3, FALSE, rcpt_smtp_response);
          }
            rcpt_smtp_response[len-2] = 0;
          smtp_respond(code, 3, FALSE, rcpt_smtp_response);
          }
-       if (smtp_in_pipelining_advertised && last_was_rcpt)
+       if (f.smtp_in_pipelining_advertised && last_was_rcpt)
          smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE,
            smtp_names[smtp_connection_had[smtp_ch_index-1]]);
        else
          smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE,
            smtp_names[smtp_connection_had[smtp_ch_index-1]]);
        else
@@ -5285,10 +5293,10 @@ while (done <= 0)
        else
          {
          uschar * acl = acl_smtp_predata ? acl_smtp_predata : US"accept";
        else
          {
          uschar * acl = acl_smtp_predata ? acl_smtp_predata : US"accept";
-         enable_dollar_recipients = TRUE;
+         f.enable_dollar_recipients = TRUE;
          rc = acl_check(ACL_WHERE_PREDATA, NULL, acl, &user_msg,
            &log_msg);
          rc = acl_check(ACL_WHERE_PREDATA, NULL, acl, &user_msg,
            &log_msg);
-         enable_dollar_recipients = FALSE;
+         f.enable_dollar_recipients = FALSE;
          if (rc == OK && !check_sync())
            goto SYNC_FAILURE;
 
          if (rc == OK && !check_sync())
            goto SYNC_FAILURE;
 
@@ -5378,13 +5386,13 @@ while (done <= 0)
        done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
       else
        {
        done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
       else
        {
-       BOOL save_log_testing_mode = log_testing_mode;
-       address_test_mode = log_testing_mode = TRUE;
+       BOOL save_log_testing_mode = f.log_testing_mode;
+       f.address_test_mode = f.log_testing_mode = TRUE;
        (void) verify_address(deliver_make_addr(smtp_cmd_data, FALSE),
          smtp_out, vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, -1,
          NULL, NULL, NULL);
        (void) verify_address(deliver_make_addr(smtp_cmd_data, FALSE),
          smtp_out, vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, -1,
          NULL, NULL, NULL);
-       address_test_mode = FALSE;
-       log_testing_mode = save_log_testing_mode;    /* true for -bh */
+       f.address_test_mode = FALSE;
+       f.log_testing_mode = save_log_testing_mode;    /* true for -bh */
        }
       break;
 
        }
       break;
 
@@ -5393,7 +5401,7 @@ while (done <= 0)
 
     case STARTTLS_CMD:
       HAD(SCH_STARTTLS);
 
     case STARTTLS_CMD:
       HAD(SCH_STARTTLS);
-      if (!tls_advertised)
+      if (!fl.tls_advertised)
        {
        done = synprot_error(L_smtp_protocol_error, 503, NULL,
          US"STARTTLS command used when not advertised");
        {
        done = synprot_error(L_smtp_protocol_error, 503, NULL,
          US"STARTTLS command used when not advertised");
@@ -5460,7 +5468,7 @@ while (done <= 0)
       if ((rc = tls_server_start(tls_require_ciphers, &s)) == OK)
        {
        if (!tls_remember_esmtp)
       if ((rc = tls_server_start(tls_require_ciphers, &s)) == OK)
        {
        if (!tls_remember_esmtp)
-         helo_seen = esmtp = auth_advertised = smtp_in_pipelining_advertised = FALSE;
+         fl.helo_seen = fl.esmtp = fl.auth_advertised = f.smtp_in_pipelining_advertised = FALSE;
        cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE;
        cmd_list[CMD_LIST_AUTH].is_mail_cmd = TRUE;
        cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
        cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE;
        cmd_list[CMD_LIST_AUTH].is_mail_cmd = TRUE;
        cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
@@ -5474,7 +5482,7 @@ while (done <= 0)
          }
        received_protocol =
          (sender_host_address ? protocols : protocols_local)
          }
        received_protocol =
          (sender_host_address ? protocols : protocols_local)
-           [ (esmtp
+           [ (fl.esmtp
              ? pextend + (sender_host_authenticated ? pauthed : 0)
              : pnormal)
            + (tls_in.active.sock >= 0 ? pcrpted : 0)
              ? pextend + (sender_host_authenticated ? pauthed : 0)
              : pnormal)
            + (tls_in.active.sock >= 0 ? pcrpted : 0)
@@ -5605,8 +5613,8 @@ while (done <= 0)
       if (sender_address || recipients_count > 0)
        log_write(L_lost_incoming_connection, LOG_MAIN,
          "unexpected %s while reading SMTP command from %s%s%s D=%s",
       if (sender_address || recipients_count > 0)
        log_write(L_lost_incoming_connection, LOG_MAIN,
          "unexpected %s while reading SMTP command from %s%s%s D=%s",
-         sender_host_unknown ? "EOF" : "disconnection",
-         tcp_in_fastopen && !tcp_in_fastopen_logged ? US"TFO " : US"",
+         f.sender_host_unknown ? "EOF" : "disconnection",
+         f.tcp_in_fastopen && !f.tcp_in_fastopen_logged ? US"TFO " : US"",
          host_and_ident(FALSE), smtp_read_error,
          string_timesince(&smtp_connection_start)
          );
          host_and_ident(FALSE), smtp_read_error,
          string_timesince(&smtp_connection_start)
          );
@@ -5614,7 +5622,7 @@ while (done <= 0)
       else
        log_write(L_smtp_connection, LOG_MAIN, "%s %slost%s D=%s",
          smtp_get_connection_info(),
       else
        log_write(L_smtp_connection, LOG_MAIN, "%s %slost%s D=%s",
          smtp_get_connection_info(),
-         tcp_in_fastopen && !tcp_in_fastopen_logged ? US"TFO " : US"",
+         f.tcp_in_fastopen && !f.tcp_in_fastopen_logged ? US"TFO " : US"",
          smtp_read_error,
          string_timesince(&smtp_connection_start)
          );
          smtp_read_error,
          string_timesince(&smtp_connection_start)
          );
@@ -5809,7 +5817,7 @@ while (done <= 0)
       log_write(0, LOG_MAIN|LOG_REJECT, "SMTP protocol synchronization error "
        "(next input sent too soon: pipelining was%s advertised): "
        "rejected \"%s\" %s next input=\"%s\"",
       log_write(0, LOG_MAIN|LOG_REJECT, "SMTP protocol synchronization error "
        "(next input sent too soon: pipelining was%s advertised): "
        "rejected \"%s\" %s next input=\"%s\"",
-       smtp_in_pipelining_advertised ? "" : " not",
+       f.smtp_in_pipelining_advertised ? "" : " not",
        smtp_cmd_buffer, host_and_ident(TRUE),
        string_printing(smtp_inptr));
       smtp_notquit_exit(US"synchronization-error", US"554",
        smtp_cmd_buffer, host_and_ident(TRUE),
        string_printing(smtp_inptr));
       smtp_notquit_exit(US"synchronization-error", US"554",