X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/6c6d6e483411af2c087ff258f4041d38eb65e775..803628d5b0b175dfa78f0b19b35213ace01207b1:/src/src/daemon.c diff --git a/src/src/daemon.c b/src/src/daemon.c index 2d10387f6..779518f9f 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with running Exim as a daemon */ @@ -341,6 +341,7 @@ arrange to unset the selector in the subprocess. */ if (LOGGING(smtp_connection)) { uschar *list = hosts_connection_nolog; + memset(sender_host_cache, 0, sizeof(sender_host_cache)); if (list != NULL && verify_check_host(&list) == OK) save_log_selector &= ~L_smtp_connection; else @@ -650,8 +651,8 @@ if (pid == 0) if (geteuid() != root_uid && !deliver_drop_privilege) { signal(SIGALRM, SIG_DFL); - (void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, FALSE, 2, US"-Mc", - message_id); + (void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, FALSE, + 2, US"-Mc", message_id); /* Control does not return here. */ } @@ -735,6 +736,7 @@ else (void)close(dup_accept_socket); /* Release any store used in this process, including the store used for holding the incoming host address and an expanded active_hostname. */ +log_close_all(); store_reset(reset_point); sender_host_address = NULL; } @@ -864,10 +866,10 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) /* If it wasn't an accepting process, see if it was a queue-runner process that we are tracking. */ - if (queue_pid_slots != NULL) + if (queue_pid_slots) { - for (i = 0; i < queue_run_max; i++) - { + int max = atoi(expand_string(queue_run_max)); + for (i = 0; i < max; i++) if (queue_pid_slots[i] == pid) { queue_pid_slots[i] = 0; @@ -876,7 +878,6 @@ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) queue_run_count, (queue_run_count == 1)? "" : "es"); break; } - } } } } @@ -914,6 +915,7 @@ int *listen_sockets = NULL; int listen_socket_count = 0; ip_address_item *addresses = NULL; time_t last_connection_time = (time_t)0; +int local_queue_run_max = atoi(expand_string(queue_run_max)); /* If any debugging options are set, turn on the D_pid bit so that all debugging lines get the pid added. */ @@ -925,13 +927,12 @@ if (inetd_wait_mode) int on = 1; listen_socket_count = 1; - listen_sockets = store_get(sizeof(int *)); + listen_sockets = store_get(sizeof(int)); (void) close(3); if (dup2(0, 3) == -1) - { log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to dup inetd socket safely away: %s", strerror(errno)); - } + listen_sockets[0] = 3; (void) close(0); (void) close(1); @@ -955,8 +956,10 @@ if (inetd_wait_mode) /* As per below, when creating sockets ourselves, we handle tcp_nodelay for our own buffering; we assume though that inetd set the socket REUSEADDR. */ - if (tcp_nodelay) setsockopt(3, IPPROTO_TCP, TCP_NODELAY, - (uschar *)(&on), sizeof(on)); + if (tcp_nodelay) + if (setsockopt(3, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on))) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to set socket NODELAY: %s", + strerror(errno)); } @@ -1095,11 +1098,11 @@ if (daemon_listen && !inetd_wait_mode) { joinstr[0] = sep; joinstr[1] = ' '; - *ptr = string_cat(*ptr, sizeptr, ptrptr, US"<", 1); + *ptr = string_catn(*ptr, sizeptr, ptrptr, US"<", 1); } - *ptr = string_cat(*ptr, sizeptr, ptrptr, joinstr, 2); - *ptr = string_cat(*ptr, sizeptr, ptrptr, s, Ustrlen(s)); + *ptr = string_catn(*ptr, sizeptr, ptrptr, joinstr, 2); + *ptr = string_cat (*ptr, sizeptr, ptrptr, s); } if (new_smtp_port != NULL) @@ -1274,7 +1277,7 @@ if (daemon_listen && !inetd_wait_mode) for (ipa = addresses; ipa != NULL; ipa = ipa->next) listen_socket_count++; - listen_sockets = store_get(sizeof(int *) * listen_socket_count); + listen_sockets = store_get(sizeof(int) * listen_socket_count); } /* daemon_listen but not inetd_wait_mode */ @@ -1379,8 +1382,7 @@ if (daemon_listen && !inetd_wait_mode) wildcard = ipa->address[0] == 0; } - listen_sockets[sk] = ip_socket(SOCK_STREAM, af); - if (listen_sockets[sk] < 0) + if ((listen_sockets[sk] = ip_socket(SOCK_STREAM, af)) < 0) { if (check_special_case(0, addresses, ipa, FALSE)) { @@ -1570,11 +1572,11 @@ originator_login = ((pw = getpwuid(exim_uid)) != NULL)? /* Get somewhere to keep the list of queue-runner pids if we are keeping track of them (and also if we are doing queue runs). */ -if (queue_interval > 0 && queue_run_max > 0) +if (queue_interval > 0 && local_queue_run_max > 0) { int i; - queue_pid_slots = store_get(queue_run_max * sizeof(pid_t)); - for (i = 0; i < queue_run_max; i++) queue_pid_slots[i] = 0; + queue_pid_slots = store_get(local_queue_run_max * sizeof(pid_t)); + for (i = 0; i < local_queue_run_max; i++) queue_pid_slots[i] = 0; } /* Set up the handler for termination of child processes. */ @@ -1602,7 +1604,7 @@ if (inetd_wait_mode) log_write(0, LOG_MAIN, "exim %s daemon started: pid=%d, launched with listening socket, %s", version_string, getpid(), big_buffer); - set_process_info("daemon: pre-listening socket"); + set_process_info("daemon(%s): pre-listening socket", version_string); /* set up the timeout logic */ sigalrm_seen = 1; @@ -1613,12 +1615,11 @@ else if (daemon_listen) int i, j; int smtp_ports = 0; int smtps_ports = 0; - ip_address_item *ipa; - uschar *p = big_buffer; - uschar *qinfo = (queue_interval > 0)? - string_sprintf("-q%s", readconf_printtime(queue_interval)) - : - US"no queue runs"; + ip_address_item * ipa; + uschar * p = big_buffer; + uschar * qinfo = queue_interval > 0 + ? string_sprintf("-q%s", readconf_printtime(queue_interval)) + : US"no queue runs"; /* Build a list of listening addresses in big_buffer, but limit it to 10 items. The style is for backwards compatibility. @@ -1629,30 +1630,30 @@ else if (daemon_listen) for (j = 0; j < 2; j++) { - for (i = 0, ipa = addresses; i < 10 && ipa != NULL; i++, ipa = ipa->next) + for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next) { /* First time round, look for SMTP ports; second time round, look for SMTPS ports. For the first one of each, insert leading text. */ if (host_is_tls_on_connect_port(ipa->port) == (j > 0)) { - if (j == 0) - { - if (smtp_ports++ == 0) + if (j == 0) + { + if (smtp_ports++ == 0) { memcpy(p, "SMTP on", 8); p += 7; } - } - else - { - if (smtps_ports++ == 0) + } + else + { + if (smtps_ports++ == 0) { (void)sprintf(CS p, "%sSMTPS on", - (smtp_ports == 0)? "":" and for "); - while (*p != 0) p++; + smtp_ports == 0 ? "" : " and for "); + while (*p) p++; } - } + } /* Now the information about the port (and sometimes interface) */ @@ -1677,7 +1678,7 @@ else if (daemon_listen) } } - if (ipa != NULL) + if (ipa) { memcpy(p, " ...", 5); p += 4; @@ -1687,22 +1688,24 @@ else if (daemon_listen) log_write(0, LOG_MAIN, "exim %s daemon started: pid=%d, %s, listening for %s", version_string, getpid(), qinfo, big_buffer); - set_process_info("daemon: %s, listening for %s", qinfo, big_buffer); + set_process_info("daemon(%s): %s, listening for %s", + version_string, qinfo, big_buffer); } else { + uschar * s = *queue_name + ? string_sprintf("-qG%s/%s", queue_name, readconf_printtime(queue_interval)) + : string_sprintf("-q%s", readconf_printtime(queue_interval)); log_write(0, LOG_MAIN, - "exim %s daemon started: pid=%d, -q%s, not listening for SMTP", - version_string, getpid(), readconf_printtime(queue_interval)); - set_process_info("daemon: -q%s, not listening", - readconf_printtime(queue_interval)); + "exim %s daemon started: pid=%d, %s, not listening for SMTP", + version_string, getpid(), s); + set_process_info("daemon(%s): %s, not listening", version_string, s); } /* Do any work it might be useful to amortize over our children (eg: compile regex) */ -deliver_init(); dns_pattern_init(); #ifdef WITH_CONTENT_SCAN @@ -1789,7 +1792,7 @@ for (;;) re-exec is required. */ if (queue_interval > 0 && - (queue_run_max <= 0 || queue_run_count < queue_run_max)) + (local_queue_run_max <= 0 || queue_run_count < local_queue_run_max)) { if ((pid = fork()) == 0) { @@ -1833,21 +1836,22 @@ for (;;) if (deliver_force_thaw) *p++ = 'f'; if (queue_run_local) *p++ = 'l'; *p = 0; - extra[0] = opt; + extra[0] = queue_name + ? string_sprintf("%sG%s", opt, queue_name) : opt; /* If -R or -S were on the original command line, ensure they get passed on. */ - if (deliver_selectstring != NULL) + if (deliver_selectstring) { - extra[extracount++] = deliver_selectstring_regex? US"-Rr" : US"-R"; + extra[extracount++] = deliver_selectstring_regex ? US"-Rr" : US"-R"; extra[extracount++] = deliver_selectstring; } - if (deliver_selectstring_sender != NULL) + if (deliver_selectstring_sender) { - extra[extracount++] = deliver_selectstring_sender_regex? - US"-Sr" : US"-S"; + extra[extracount++] = deliver_selectstring_sender_regex + ? US"-Sr" : US"-S"; extra[extracount++] = deliver_selectstring_sender; } @@ -1874,15 +1878,13 @@ for (;;) else { int i; - for (i = 0; i < queue_run_max; ++i) - { + for (i = 0; i < local_queue_run_max; ++i) if (queue_pid_slots[i] <= 0) { queue_pid_slots[i] = pid; queue_run_count++; break; } - } DEBUG(D_any) debug_printf("%d queue-runner process%s running\n", queue_run_count, (queue_run_count == 1)? "" : "es"); }