main.c revision 4c2ac2804213f22edb4fe8ce12af709c7571bdf0
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "common.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "ioloop.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "lib-signals.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "network.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "env-util.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "fd-close-on-exec.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "write-full.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "askpass.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "auth-process.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "dict-process.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "login-process.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "mail-process.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "syslog-util.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "ssl-init.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "log.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <stdio.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <stdlib.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <unistd.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <fcntl.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <syslog.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <sys/stat.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <sys/wait.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenconst char *process_names[PROCESS_TYPE_MAX] = {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "unknown",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "auth",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "auth-worker",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "login",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "imap",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "pop3",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "ssl-build-param",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "dict"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen};
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic const char *configfile = SYSCONFDIR "/" PACKAGE ".conf";
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic const char *env_tz;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstruct ioloop *ioloop;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstruct hash_table *pids;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenint null_fd, inetd_login_fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenuid_t master_uid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenchar program_path[PATH_MAX];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenchar ssl_manual_key_password[100];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#ifdef DEBUG
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic bool gdb;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#endif
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void listen_fds_open(bool retry);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void listen_fds_close(struct server_settings *server);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenbool validate_str(const char *str, size_t max_len)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen size_t i;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < max_len; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (str[i] == '\0')
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid child_process_init_env(void)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int facility;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* remove all environment, we don't need them */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen env_clean();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* we'll log through master process */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen env_put("LOG_TO_MASTER=1");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (env_tz != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen env_put(t_strconcat("TZ=", env_tz, NULL));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (settings_root == NULL ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen !syslog_facility_find(settings_root->defaults->syslog_facility,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &facility))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen facility = LOG_MAIL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen env_put(t_strdup_printf("SYSLOG_FACILITY=%d", facility));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (settings_root != NULL && !settings_root->defaults->version_ignore)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen env_put("DOVECOT_VERSION="PACKAGE_VERSION);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#ifdef DEBUG
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (gdb) env_put("GDB=1");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#endif
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid client_process_exec(const char *cmd, const char *title)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *executable, *p, **argv;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* very simple argument splitting. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*title == '\0')
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen argv = t_strsplit(cmd, " ");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen argv = t_strsplit(t_strconcat(cmd, " ", title, NULL), " ");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen executable = argv[0];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* hide the path, it's ugly */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen p = strrchr(argv[0], '/');
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (p != NULL) argv[0] = p+1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen execv(executable, (char **)argv);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void set_logfile(struct settings *set)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int facility;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*set->log_path == '\0') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!syslog_facility_find(set->syslog_facility, &facility))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen facility = LOG_MAIL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_set_failure_syslog("dovecot", LOG_NDELAY, facility);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* log to file or stderr */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_set_failure_file(set->log_path, "dovecot");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*set->info_log_path != '\0')
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_set_info_file(set->info_log_path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_set_failure_timestamp_format(set->log_timestamp);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void settings_reload(void)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct server_settings *old_set = settings_root;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_warning("SIGHUP received - reloading configuration");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* restart auth and login processes */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen login_processes_destroy_all();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen auth_processes_destroy_all();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dict_process_kill();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!master_settings_read(configfile, FALSE, FALSE))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_warning("Invalid configuration, keeping old one");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!IS_INETD()) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen listen_fds_close(old_set);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen listen_fds_open(TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen set_logfile(settings_root->defaults);
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen }
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen}
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainenstatic void sig_die(int signo, void *context __attr_unused__)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen which is too common at least while testing :) */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (signo != SIGINT)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_warning("Killed with signal %d", signo);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen io_loop_stop(ioloop);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void sig_reload_settings(int signo __attr_unused__,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen void *context __attr_unused__)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen settings_reload();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void sig_reopen_logs(int signo __attr_unused__,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen void *context __attr_unused__)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_logfile(settings_root->defaults);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainenstatic const char *get_exit_status_message(enum fatal_exit_status status)
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen{
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen switch (status) {
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_LOGOPEN:
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return "Can't open log file";
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_LOGWRITE:
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return "Can't write to log file";
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_LOGERROR:
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return "Internal logging error";
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_OUTOFMEM:
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return "Out of memory";
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_EXEC:
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return "exec() failed";
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen case FATAL_DEFAULT:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen return NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void sigchld_handler(int signo __attr_unused__,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen void *context __attr_unused__)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *process_type_name, *msg;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pid_t pid;
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen int status, process_type;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen bool abnormal_exit;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* get the type and remove from hash */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen process_type = PID_GET_PROCESS_TYPE(pid);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (process_type != PROCESS_TYPE_UNKNOWN)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen PID_REMOVE_PROCESS_TYPE(pid);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen abnormal_exit = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* write errors to syslog */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen process_type_name = process_names[process_type];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (WIFEXITED(status)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen status = WEXITSTATUS(status);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (status == 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen abnormal_exit = FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (process_type == PROCESS_TYPE_UNKNOWN) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("unknown child %s exited "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "successfully", dec2str(pid));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen msg = get_exit_status_message(status);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen msg = msg == NULL ? "" :
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen t_strconcat(" (", msg, ")", NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("child %s (%s) returned error %d%s",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dec2str(pid), process_type_name,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen status, msg);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else if (WIFSIGNALED(status)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("child %s (%s) killed with signal %d",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dec2str(pid), process_type_name,
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen WTERMSIG(status));
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen }
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen switch (process_type) {
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen case PROCESS_TYPE_LOGIN:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen login_process_destroyed(pid, abnormal_exit);
72cc352b25ad401b923436c6ed0f1f3adaffa737Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen case PROCESS_TYPE_IMAP:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen case PROCESS_TYPE_POP3:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_process_destroyed(pid);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen case PROCESS_TYPE_SSL_PARAM:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ssl_parameter_process_destroyed(pid);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen case PROCESS_TYPE_DICT:
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dict_process_restart();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (pid == -1 && errno != EINTR && errno != ECHILD)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_warning("waitpid() failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void resolve_ip(const char *set_name, const char *name,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct ip_addr *ip, unsigned int *port)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct ip_addr *ip_list;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *p;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int ips_count;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*name == '\0') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* defaults to "*" or "[::]" */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ip->family = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (name[0] == '[') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* IPv6 address */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen p = strchr(name, ']');
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (p == NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("%s: Missing ']' in address %s",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_name, name);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen name = t_strdup_until(name+1, p);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen p++;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*p == '\0')
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen p = NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else if (*p != ':') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("%s: Invalid data after ']' in address %s",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_name, name);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen p = strrchr(name, ':');
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (p != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen name = t_strdup_until(name, p);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (p != NULL) {
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen if (!is_numeric(p+1, '\0')) {
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen i_fatal("%s: Invalid port in address %s",
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen set_name, name);
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *port = atoi(p+1);
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen }
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (strcmp(name, "*") == 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* IPv4 any */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen net_get_ip_any4(ip);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (strcmp(name, "::") == 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* IPv6 any */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen net_get_ip_any6(ip);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* Return the first IP if there happens to be multiple. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = net_gethostbyname(name, &ip_list, &ips_count);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (ret != 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("%s: Can't resolve address %s: %s",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_name, name, net_gethosterror(ret));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen if (ips_count < 1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("%s: No IPs for address: %s", set_name, name);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *ip = ip_list[0];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainencheck_conflicts_set(const struct settings *set, const struct ip_addr *ip,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int port, const char *name1, const char *name2)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->listen_port == port && net_ip_compare(ip, &set->listen_ip) &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->listen_fd > 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("Protocols %s and %s are listening in same ip/port",
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen name1, name2);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->ssl_listen_port == port &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen net_ip_compare(ip, &set->ssl_listen_ip) && set->ssl_listen_fd > 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("Protocols %ss and %s are listening in same ip/port",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen name1, name2);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void check_conflicts(const struct ip_addr *ip, unsigned int port,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *proto)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct server_settings *server;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (server = settings_root; server != NULL; server = server->next) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen check_conflicts_set(server->imap, ip, port,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "imap", proto);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->pop3 != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen check_conflicts_set(server->pop3, ip, port,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "pop3", proto);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void listen_protocols(struct settings *set, bool retry)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct ip_addr *ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *const *proto;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int port;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int *fd, i;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->listen_port = set->protocol == MAIL_PROTOCOL_IMAP ? 143 : 110;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#ifdef HAVE_SSL
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->ssl_listen_port = set->protocol == MAIL_PROTOCOL_IMAP ? 993 : 995;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#else
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->ssl_listen_port = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#endif
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* resolve */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen resolve_ip("listen", set->listen, &set->listen_ip, &set->listen_port);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!set->ssl_disable) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen resolve_ip("ssl_listen", set->ssl_listen, &set->ssl_listen_ip,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &set->ssl_listen_port);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* if ssl_listen wasn't explicitly set in the config file,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen use the non-ssl IP settings for the ssl listener, too. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->ssl_listen_ip.family == 0 && *set->ssl_listen == '\0')
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->ssl_listen_ip = set->listen_ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* register wanted protocols */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen proto = t_strsplit_spaces(set->protocols, " ");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (; *proto != NULL; proto++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = NULL; ip = NULL; port = 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (strcasecmp(*proto, "imap") == 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->protocol == MAIL_PROTOCOL_IMAP) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = &set->listen_fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen port = set->listen_port;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ip = &set->listen_ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else if (strcasecmp(*proto, "imaps") == 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->protocol == MAIL_PROTOCOL_IMAP &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen !set->ssl_disable) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = &set->ssl_listen_fd;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen port = set->ssl_listen_port;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen ip = &set->ssl_listen_ip;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen }
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen } else if (strcasecmp(*proto, "pop3") == 0) {
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (set->protocol == MAIL_PROTOCOL_POP3) {
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen fd = &set->listen_fd;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen port = set->listen_port;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen ip = &set->listen_ip;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen }
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen } else if (strcasecmp(*proto, "pop3s") == 0) {
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (set->protocol == MAIL_PROTOCOL_POP3 &&
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen !set->ssl_disable) {
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen fd = &set->ssl_listen_fd;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen port = set->ssl_listen_port;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen ip = &set->ssl_listen_ip;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen }
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen } else {
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen i_fatal("Unknown protocol %s", *proto);
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen }
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (fd == NULL)
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen continue;
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (*fd != -1)
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen i_fatal("Protocol %s given more than once", *proto);
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (port == 0)
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen *fd = null_fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < 10; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *fd = net_listen(ip, &port, 8);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*fd != -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (errno == EADDRINUSE) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* retry */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else if (errno == EINTR &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen io_loop_is_running(ioloop)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* SIGHUPing sometimes gets us here.
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen we don't want to die. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* error */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen check_conflicts(ip, port, *proto);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!retry)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen break;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* wait a while and try again. we're SIGHUPing
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen so we most likely just closed it ourself.. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen sleep(1);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (*fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("listen(%d) failed: %m", port);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen net_set_nonblock(*fd, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd_close_on_exec(*fd, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->listen_fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->listen_fd = null_fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (set->ssl_listen_fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set->ssl_listen_fd = null_fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void listen_fds_open(bool retry)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct server_settings *server;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (server = settings_root; server != NULL; server = server->next) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen listen_protocols(server->imap, retry);
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen if (server->pop3 != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen listen_protocols(server->pop3, retry);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void listen_fds_close(struct server_settings *server)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (; server != NULL; server = server->next) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap->listen_fd != null_fd &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen close(server->imap->listen_fd) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("close(imap.listen_fd) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap->ssl_listen_fd != null_fd &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen close(server->imap->ssl_listen_fd) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("close(imap.ssl_listen_fd) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->pop3 != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->pop3->listen_fd != null_fd &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen close(server->pop3->listen_fd) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("close(pop3.listen_fd) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->pop3->ssl_listen_fd != null_fd &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen close(server->pop3->ssl_listen_fd) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("close(pop3.ssl_listen_fd) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic bool have_stderr_set(struct settings *set)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*set->log_path != '\0' &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen strcmp(set->log_path, "/dev/stderr") == 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (*set->info_log_path != '\0' &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen strcmp(set->info_log_path, "/dev/stderr") == 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic bool have_stderr(struct server_settings *server)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen while (server != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->imap != NULL && have_stderr_set(server->imap))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (server->pop3 != NULL && have_stderr_set(server->pop3))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen server = server->next;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void open_fds(void)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* initialize fds. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen null_fd = open("/dev/null", O_RDONLY);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (null_fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("Can't open /dev/null: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd_close_on_exec(null_fd, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* make sure all fds between 0..3 are used. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen while (null_fd < 4) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen null_fd = dup(null_fd);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (null_fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("dup(null_fd) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd_close_on_exec(null_fd, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!IS_INETD())
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen listen_fds_open(FALSE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* close stdin and stdout. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (dup2(null_fd, 0) < 0)
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen i_fatal("dup2(0) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (dup2(null_fd, 1) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("dup2(1) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void create_pid_file(const char *path)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *pid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pid = t_strconcat(dec2str(getpid()), "\n", NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("open(%s) failed: %m", path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (write_full(fd, pid, strlen(pid)) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("write() failed in %s: %m", path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)close(fd);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void main_init(bool log_error)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* deny file access from everyone else except owner */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)umask(0077);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* close stderr unless we're logging into /dev/stderr. keep as little
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen distance between closing it and opening the actual log file so that
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen we don't lose anything. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!have_stderr(settings_root)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (dup2(null_fd, 2) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("dup2(2) failed: %m");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_logfile(settings_root->defaults);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_info("Dovecot v"VERSION" starting up");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen log_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (log_error)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("This is Dovecot's error log");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_init();
925ef142ae6d9e854cd4e44fbcf2050e744b46beTimo Sirainen lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_ignore(SIGPIPE, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_ignore(SIGALRM, FALSE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_set_handler(SIGHUP, TRUE, sig_reload_settings, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_set_handler(SIGUSR1, TRUE, sig_reopen_logs, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pids = hash_create(default_pool, default_pool, 128, NULL, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen lib_signals_set_handler(SIGCHLD, TRUE, sigchld_handler, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ssl_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dict_process_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen auth_processes_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen login_processes_init();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen create_pid_file(t_strconcat(settings_root->defaults->base_dir,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "/master.pid", NULL));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void main_deinit(void)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)unlink(t_strconcat(settings_root->defaults->base_dir,
"/master.pid", NULL));
/* make sure we log if child processes died unexpectedly */
sigchld_handler(SIGCHLD, NULL);
login_processes_deinit();
auth_processes_deinit();
dict_process_deinit();
ssl_deinit();
lib_signals_unset_handler(SIGCHLD, sigchld_handler, NULL);
if (close(null_fd) < 0)
i_error("close(null_fd) failed: %m");
hash_destroy(pids);
lib_signals_deinit();
log_deinit();
closelog();
}
static void daemonize(struct settings *set)
{
pid_t pid;
pid = fork();
if (pid < 0)
i_fatal("fork() failed: %m");
if (pid != 0)
_exit(0);
if (setsid() < 0)
i_fatal("setsid() failed: %m");
if (chdir(set->base_dir) < 0)
i_fatal("chdir(%s) failed: %m", set->base_dir);
}
static void print_help(void)
{
printf(
"Usage: dovecot [-F] [-c <config file>] [-p] [-n] [-a]\n"
" [--exec-mail <protocol>] [--version] [--build-options]\n");
}
static void print_build_options(void)
{
printf("Build options:"
#ifdef IOLOOP_EPOLL
" ioloop=epoll"
#endif
#ifdef IOLOOP_KQUEUE
" ioloop=kqueue"
#endif
#ifdef IOLOOP_POLL
" ioloop=poll"
#endif
#ifdef IOLOOP_SELECT
" ioloop=select"
#endif
#ifdef IOLOOP_NOTIFY_DNOTIFY
" notify=dnotify"
#endif
#ifdef IOLOOP_NOTIFY_INOTIFY
" notify=inotify"
#endif
#ifdef IOLOOP_NOTIFY_KQUEUE
" notify=kqueue"
#endif
#ifdef HAVE_IPV6
" ipv6"
#endif
#ifdef HAVE_GNUTLS
" gnutls"
#endif
#ifdef HAVE_OPENSSL
" openssl"
#endif
"\nSQL drivers:"
#ifdef BUILD_MYSQL
" mysql"
#endif
#ifdef BUILD_PGSQL
" postgresql"
#endif
#ifdef BUILD_SQLITE
" sqlite"
#endif
"\nPassdb:"
#ifdef PASSDB_BSDAUTH
" bsdauth"
#endif
#ifdef PASSDB_CHECKPASSWORD
" checkpassword"
#endif
#ifdef PASSDB_LDAP
" ldap"
#endif
#ifdef PASSDB_PAM
" pam"
#endif
#ifdef PASSDB_PASSWD
" passwd"
#endif
#ifdef PASSDB_PASSWD_FILE
" passwd-file"
#endif
#ifdef PASSDB_SHADOW
" shadow"
#endif
#ifdef PASSDB_SQL
" sql"
#endif
#ifdef PASSDB_VPOPMAIL
" vpopmail"
#endif
"\nUserdb:"
#ifdef USERDB_CHECKPASSWORD
" checkpassword"
#endif
#ifdef USERDB_LDAP
" ldap"
#endif
#ifdef USERDB_PASSWD
" passwd"
#endif
#ifdef USERDB_PREFETCH
" prefetch"
#endif
#ifdef USERDB_PASSWD_FILE
" passwd-file"
#endif
#ifdef USERDB_SQL
" sql"
#endif
#ifdef USERDB_STATIC
" static"
#endif
#ifdef USERDB_VPOPMAIL
" vpopmail"
#endif
"\n");
}
int main(int argc, char *argv[])
{
/* parse arguments */
const char *exec_protocol = NULL, *exec_section = NULL, *user, *home;
bool foreground = FALSE, ask_key_pass = FALSE, log_error = FALSE;
bool dump_config = FALSE, dump_config_nondefaults = FALSE;
int i;
#ifdef DEBUG
gdb = getenv("GDB") != NULL;
#endif
lib_init();
master_uid = geteuid();
inetd_login_fd = -1;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-F") == 0) {
/* foreground */
foreground = TRUE;
} else if (strcmp(argv[i], "-a") == 0) {
dump_config = TRUE;
} else if (strcmp(argv[i], "-c") == 0) {
/* config file */
i++;
if (i == argc) i_fatal("Missing config file argument");
configfile = argv[i];
} else if (strcmp(argv[i], "-n") == 0) {
dump_config_nondefaults = dump_config = TRUE;
} else if (strcmp(argv[i], "-p") == 0) {
/* Ask SSL private key password */
ask_key_pass = TRUE;
} else if (strcmp(argv[i], "--exec-mail") == 0) {
/* <protocol> [<server section>]
read configuration and execute mail process */
i++;
if (i == argc) i_fatal("Missing protocol argument");
exec_protocol = argv[i];
if (i+1 != argc)
exec_section = argv[++i];
} else if (strcmp(argv[i], "--version") == 0) {
printf("%s\n", VERSION);
return 0;
} else if (strcmp(argv[i], "--build-options") == 0) {
print_build_options();
return 0;
} else if (strcmp(argv[i], "--log-error") == 0) {
log_error = TRUE;
foreground = TRUE;
} else {
print_help();
i_fatal("Unknown argument: %s", argv[1]);
}
}
if (getenv("DOVECOT_INETD") != NULL) {
/* starting through inetd. */
inetd_login_fd = dup(0);
if (inetd_login_fd == -1)
i_fatal("dup(0) failed: %m");
fd_close_on_exec(inetd_login_fd, TRUE);
foreground = TRUE;
}
if (dump_config) {
/* print the config file path before parsing it, so in case
of errors it's still shown */
printf("# %s\n", configfile);
}
/* read and verify settings before forking */
t_push();
master_settings_init();
if (!master_settings_read(configfile, exec_protocol != NULL,
dump_config))
exit(FATAL_DEFAULT);
t_pop();
if (dump_config) {
master_settings_dump(settings_root, dump_config_nondefaults);
return 0;
}
if (ask_key_pass) {
const char *prompt;
t_push();
prompt = t_strdup_printf("Give the password for SSL key file "
"%s: ",
settings_root->defaults->ssl_key_file);
askpass(prompt, ssl_manual_key_password,
sizeof(ssl_manual_key_password));
t_pop();
}
/* save TZ environment. AIX depends on it to get the timezone
correctly. */
env_tz = getenv("TZ");
user = getenv("USER");
home = getenv("HOME");
/* clean up the environment of everything */
env_clean();
/* put back the TZ */
if (env_tz != NULL)
env_put(t_strconcat("TZ=", env_tz, NULL));
if (exec_protocol != NULL) {
/* Put back user and home */
env_put(t_strconcat("USER=", user, NULL));
env_put(t_strconcat("HOME=", home, NULL));
mail_process_exec(exec_protocol, exec_section);
}
open_fds();
if (!foreground)
daemonize(settings_root->defaults);
ioloop = io_loop_create(system_pool);
main_init(log_error);
io_loop_run(ioloop);
main_deinit();
master_settings_deinit();
io_loop_destroy(&ioloop);
lib_deinit();
return 0;
}