static void
never_error(uschar *log_msg, uschar *smtp_msg, int was_errno)
{
-uschar *emsg = (was_errno <= 0)? US"" :
- string_sprintf(": %s", strerror(was_errno));
+uschar *emsg = was_errno <= 0
+ ? US"" : string_sprintf(": %s", strerror(was_errno));
log_write(0, LOG_MAIN|LOG_PANIC, "%s%s", log_msg, emsg);
-if (smtp_out != NULL) smtp_printf("421 %s\r\n", FALSE, smtp_msg);
+if (smtp_out) smtp_printf("421 %s\r\n", FALSE, smtp_msg);
}
whofrom = string_append(NULL, 3, "[", sender_host_address, "]");
if (LOGGING(incoming_port))
- whofrom = string_append(whofrom, 2, ":", string_sprintf("%d", sender_host_port));
+ whofrom = string_fmt_append(whofrom, ":%d", sender_host_port);
if (LOGGING(incoming_interface))
- whofrom = string_append(whofrom, 4, " I=[",
- interface_address, "]:", string_sprintf("%d", interface_port));
+ whofrom = string_fmt_append(whofrom, " I=[%s]:%d",
+ interface_address, interface_port);
(void) string_from_gstring(whofrom); /* Terminate the newly-built string */
uschar *expanded = expand_string(smtp_accept_max_per_host);
if (expanded == NULL)
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host "
"failed for %s: %s", whofrom->s, expand_string_message);
}
uschar * nah = expand_string(raw_active_hostname);
if (!nah)
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
{
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand \"%s\" "
"(smtp_active_hostname): %s", raw_active_hostname,
finding the id, but turn it on again afterwards so that information about the
incoming connection is output. */
- if (debug_daemon) debug_selector = 0;
+ if (f.debug_daemon) debug_selector = 0;
verify_get_ident(IDENT_PORT);
host_build_sender_fullhost();
debug_selector = save_debug_selector;
/* Now disable debugging permanently if it's required only for the daemon
process. */
- if (debug_daemon) debug_selector = 0;
+ if (f.debug_daemon) debug_selector = 0;
/* If there are too many child processes for immediate delivery,
set the session_local_queue_only flag, which is initialized from the
/* Reclaim up the store used in accepting this message */
- return_path = sender_address = NULL;
- authenticated_sender = NULL;
- sending_ip_address = NULL;
- deliver_host_address = deliver_host =
- deliver_domain_orig = deliver_localpart_orig = NULL;
- dnslist_domain = dnslist_matched = NULL;
- callout_address = NULL;
-#ifndef DISABLE_DKIM
- dkim_cur_signer = NULL;
-#endif
- acl_var_m = NULL;
- store_reset(reset_point);
+ {
+ int r = receive_messagecount;
+ BOOL q = f.queue_only_policy;
+ smtp_reset(reset_point);
+ f.queue_only_policy = q;
+ receive_messagecount = r;
+ }
/* If queue_only is set or if there are too many incoming connections in
existence, session_local_queue_only will be TRUE. If it is not, check
If we are not root, we have to re-exec exim unless deliveries are being
done unprivileged. */
- else if (!queue_only_policy && !deliver_freeze)
+ else if (!f.queue_only_policy && !f.deliver_freeze)
{
pid_t dpid;
the data structures if necessary. */
#ifdef SUPPORT_TLS
- tls_close(TRUE, FALSE);
+ tls_close(NULL, TLS_NO_SHUTDOWN);
#endif
/* Reset SIGHUP and SIGCHLD in the child in both cases. */
DEBUG(D_any|D_v) debug_selector |= D_pid;
-if (inetd_wait_mode)
+if (f.inetd_wait_mode)
{
listen_socket_count = 1;
listen_sockets = store_get(sizeof(int));
}
-if (inetd_wait_mode || daemon_listen)
+if (f.inetd_wait_mode || f.daemon_listen)
{
/* If any option requiring a load average to be available during the
reception of a message is set, call os_getloadavg() while we are root
first, so that we can return non-zero if there are any syntax errors, and also
write to stderr. */
-if (daemon_listen && !inetd_wait_mode)
+if (f.daemon_listen && !f.inetd_wait_mode)
{
int *default_smtp_port;
int sep;
} /* daemon_listen but not inetd_wait_mode */
-if (daemon_listen)
+if (f.daemon_listen)
{
/* Do a sanity check on the max connects value just to save us from getting
setsid() for getting rid of the controlling terminal. For any OS that doesn't,
setsid() can be #defined as a no-op, or as something else. */
-if (background_daemon || inetd_wait_mode)
+if (f.background_daemon || f.inetd_wait_mode)
{
log_close_all(); /* Just in case anything was logged earlier */
search_tidyup(); /* Just in case any were used in reading the config. */
log_stderr = NULL; /* So no attempt to copy paniclog output */
}
-if (background_daemon)
+if (f.background_daemon)
{
/* If the parent process of this one has pid == 1, we are re-initializing the
daemon as the result of a SIGHUP. In this case, there is no need to do
/* We are now in the disconnected, daemon process (unless debugging). Set up
the listening sockets if required. */
-if (daemon_listen && !inetd_wait_mode)
+if (f.daemon_listen && !f.inetd_wait_mode)
{
int sk;
ip_address_item *ipa;
listen() stage instead. */
#ifdef TCP_FASTOPEN
- tcp_fastopen_ok = TRUE;
+ f.tcp_fastopen_ok = TRUE;
#endif
for(;;)
{
else
debug_printf("listening on %s port %d\n", ipa->address, ipa->port);
-#ifdef TCP_FASTOPEN
- if (setsockopt(listen_sockets[sk], IPPROTO_TCP, TCP_FASTOPEN,
+#if defined(TCP_FASTOPEN) && !defined(__APPLE__)
+ if ( f.tcp_fastopen_ok
+ && setsockopt(listen_sockets[sk], IPPROTO_TCP, TCP_FASTOPEN,
&smtp_connect_backlog, sizeof(smtp_connect_backlog)))
{
DEBUG(D_any) debug_printf("setsockopt FASTOPEN: %s\n", strerror(errno));
- tcp_fastopen_ok = FALSE;
+ f.tcp_fastopen_ok = FALSE;
}
#endif
/* Start listening on the bound socket, establishing the maximum backlog of
connections that is allowed. On success, continue to the next address. */
- if (listen(listen_sockets[sk], smtp_connect_backlog) >= 0) continue;
+ if (listen(listen_sockets[sk], smtp_connect_backlog) >= 0)
+ {
+#if defined(TCP_FASTOPEN) && defined(__APPLE__)
+ if ( f.tcp_fastopen_ok
+ && setsockopt(listen_sockets[sk], IPPROTO_TCP, TCP_FASTOPEN,
+ &on, sizeof(on)))
+ {
+ DEBUG(D_any) debug_printf("setsockopt FASTOPEN: %s\n", strerror(errno));
+ f.tcp_fastopen_ok = FALSE;
+ }
+#endif
+ continue;
+ }
/* Listening has failed. In an IPv6 environment, as for bind(), if listen()
fails with the error EADDRINUSE and we are doing IPv4 wildcard listening
The variable daemon_write_pid is used to control this. */
-if (running_in_test_harness || write_pid)
+if (f.running_in_test_harness || write_pid)
{
FILE *f;
/* Log the start up of a daemon - at least one of listening or queue running
must be set up. */
-if (inetd_wait_mode)
+if (f.inetd_wait_mode)
{
uschar *p = big_buffer;
sigalrm_seen = 1;
}
-else if (daemon_listen)
+else if (f.daemon_listen)
{
int i, j;
int smtp_ports = 0;
}
sigalrm_seen = FALSE;
- alarm(resignal_interval);
+ ALARM(resignal_interval);
}
else
leave the above message, because it ties up with the "child ended"
debugging messages. */
- if (debug_daemon) debug_selector = 0;
+ if (f.debug_daemon) debug_selector = 0;
/* Close any open listening sockets in the child */
signal(SIGALRM, SIG_DFL);
*p++ = '-';
*p++ = 'q';
- if (queue_2stage) *p++ = 'q';
- if (queue_run_first_delivery) *p++ = 'i';
- if (queue_run_force) *p++ = 'f';
- if (deliver_force_thaw) *p++ = 'f';
- if (queue_run_local) *p++ = 'l';
+ if (f.queue_2stage) *p++ = 'q';
+ if (f.queue_run_first_delivery) *p++ = 'i';
+ if (f.queue_run_force) *p++ = 'f';
+ if (f.deliver_force_thaw) *p++ = 'f';
+ if (f.queue_run_local) *p++ = 'l';
*p = 0;
extra[0] = queue_name
? string_sprintf("%sG%s", opt, queue_name) : opt;
if (deliver_selectstring)
{
- extra[extracount++] = deliver_selectstring_regex ? US"-Rr" : US"-R";
+ extra[extracount++] = f.deliver_selectstring_regex ? US"-Rr" : US"-R";
extra[extracount++] = deliver_selectstring;
}
if (deliver_selectstring_sender)
{
- extra[extracount++] = deliver_selectstring_sender_regex
+ extra[extracount++] = f.deliver_selectstring_sender_regex
? US"-Sr" : US"-S";
extra[extracount++] = deliver_selectstring_sender;
}
/* Reset the alarm clock */
sigalrm_seen = FALSE;
- alarm(queue_interval);
+ ALARM(queue_interval);
}
} /* sigalrm_seen */
new OS. In fact, the later addition of listening on specific interfaces only
requires this way of working anyway. */
- if (daemon_listen)
+ if (f.daemon_listen)
{
int sk, lcount, select_errno;
int max_socket = 0;
getpid());
for (sk = 0; sk < listen_socket_count; sk++)
(void)close(listen_sockets[sk]);
- alarm(0);
+ ALARM_CLR(0);
signal(SIGHUP, SIG_IGN);
sighup_argv[0] = exim_path;
exim_nullstd();