main.c revision 4403bc18add3e8a1392c9af8354e2c8430c47aa0
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek/* Copyright (C) 2002 Timo Sirainen */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "common.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "ioloop.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "lib-signals.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "network.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "env-util.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "fd-close-on-exec.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "auth-process.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "login-process.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include "ssl-init.h"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <stdio.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <stdlib.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <unistd.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <fcntl.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <syslog.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <sys/stat.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#include <sys/wait.h>
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekconst char *process_names[PROCESS_TYPE_MAX] = {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek "unknown",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek "auth",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek "login",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek "imap",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek "ssl-param"
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek};
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic const char *configfile = SYSCONFDIR "/" PACKAGE ".conf";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic struct ioloop *ioloop;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic struct timeout *to;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstruct hash_table *pids;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekint null_fd, imap_fd, imaps_fd;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekint validate_str(const char *str, size_t max_len)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek size_t i;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek for (i = 0; i < max_len; i++) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (str[i] == '\0')
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return TRUE;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return FALSE;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekvoid clean_child_process(void)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* remove all environment, we don't need them */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek env_clean();
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* set the failure log */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (set_log_path == NULL)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek env_put("IMAP_USE_SYSLOG=1");
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek else
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek env_put(t_strconcat("IMAP_LOGFILE=", set_log_path, NULL));
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (set_info_log_path != NULL) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek env_put(t_strconcat("IMAP_INFOLOGFILE=",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek set_info_log_path, NULL));
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (set_log_timestamp != NULL)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek env_put(t_strconcat("IMAP_LOGSTAMP=", set_log_timestamp, NULL));
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic void sig_quit(int signo __attr_unused__)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek io_loop_stop(ioloop);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic void settings_reload(void)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_warning("SIGHUP received - reloading configuration");
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek settings_read(configfile);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* restart auth and login processes */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek login_processes_destroy_all();
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek auth_processes_destroy_all();
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic const char *get_exit_status_message(enum fatal_exit_status status)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek switch (status) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_LOGOPEN:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return "Can't open log file";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_LOGWRITE:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return "Can't write to log file";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_LOGERROR:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return "Internal logging error";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_OUTOFMEM:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return "Out of memory";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_EXEC:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return "exec() failed";
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek case FATAL_DEFAULT:
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return NULL;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return NULL;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic void timeout_handler(void *context __attr_unused__,
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek struct timeout *timeout __attr_unused__)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek const char *process_type_name, *msg;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek pid_t pid;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek int status, process_type;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (lib_signal_hup != 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek settings_reload();
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek lib_signal_hup = 0;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* get the type and remove from hash */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek process_type = PID_GET_PROCESS_TYPE(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek PID_REMOVE_PROCESS_TYPE(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (process_type == PROCESS_TYPE_IMAP)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imap_process_destroyed(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (process_type == PROCESS_TYPE_SSL_PARAM)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek ssl_parameter_process_destroyed(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* write errors to syslog */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek process_type_name = process_names[process_type];
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (WIFEXITED(status)) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek status = WEXITSTATUS(status);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (status != 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (process_type == PROCESS_TYPE_LOGIN)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek login_process_abormal_exit(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek msg = get_exit_status_message(status);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek msg = msg == NULL ? "" :
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek t_strconcat(" (", msg, ")", NULL);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_error("child %s (%s) returned error %d%s",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek dec2str(pid), process_type_name,
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek status, msg);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek } else if (WIFSIGNALED(status)) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (process_type == PROCESS_TYPE_LOGIN)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek login_process_abormal_exit(pid);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_error("child %s (%s) killed with signal %d",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek dec2str(pid), process_type_name,
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek WTERMSIG(status));
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (pid == -1 && errno != EINTR && errno != ECHILD)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_warning("waitpid() failed: %m");
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic struct ip_addr *resolve_ip(const char *name)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek struct ip_addr *ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek int ret, ips_count;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (name == NULL)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return NULL; /* defaults to "*" or "::" */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (strcmp(name, "*") == 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* IPv4 any */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek ip = t_new(struct ip_addr, 1);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek net_get_ip_any4(ip);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (strcmp(name, "::") == 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* IPv6 any */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek ip = t_new(struct ip_addr, 1);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek net_get_ip_any6(ip);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek /* Return the first IP if there happens to be multiple. */
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek ret = net_gethostbyname(name, &ip, &ips_count);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (ret != 0) {
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_fatal("Can't resolve address %s: %s",
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek name, net_gethosterror(ret));
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (ips_count < 1)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_fatal("No IPs for address: %s", name);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek return ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozekstatic void open_fds(void)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek{
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek struct ip_addr *imap_ip, *imaps_ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imap_ip = resolve_ip(set_imap_listen);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imaps_ip = resolve_ip(set_imaps_listen);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (imaps_ip == NULL && set_imaps_listen == NULL)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imaps_ip = imap_ip;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek null_fd = open("/dev/null", O_RDONLY);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (null_fd == -1)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_fatal("Can't open /dev/null: %m");
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek fd_close_on_exec(null_fd, TRUE);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imap_fd = set_imap_port == 0 ? dup(null_fd) :
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek net_listen(imap_ip, &set_imap_port);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (imap_fd == -1)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_fatal("listen(%d) failed: %m", set_imap_port);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek fd_close_on_exec(imap_fd, TRUE);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#ifdef HAVE_SSL
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imaps_fd = set_ssl_disable || set_imaps_port == 0 ? dup(null_fd) :
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek net_listen(imaps_ip, &set_imaps_port);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#else
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek imaps_fd = dup(null_fd);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek#endif
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek if (imaps_fd == -1)
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek i_fatal("listen(%d) failed: %m", set_imaps_port);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek fd_close_on_exec(imaps_fd, TRUE);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek}
static void open_logfile(void)
{
if (set_log_path == NULL)
i_set_failure_syslog("imap-master", LOG_NDELAY, LOG_MAIL);
else {
/* log to file or stderr */
i_set_failure_file(set_log_path, "imap-master");
}
if (set_info_log_path != NULL)
i_set_info_file(set_info_log_path);
i_set_failure_timestamp_format(set_log_timestamp);
}
static void main_init(void)
{
/* deny file access from everyone else except owner */
(void)umask(0077);
open_logfile();
lib_init_signals(sig_quit);
pids = hash_create(default_pool, 128, NULL, NULL);
to = timeout_add(100, timeout_handler, NULL);
ssl_init();
auth_processes_init();
login_processes_init();
}
static void main_deinit(void)
{
if (lib_signal_kill != 0)
i_warning("Killed with signal %d", lib_signal_kill);
login_processes_deinit();
auth_processes_deinit();
ssl_deinit();
timeout_remove(to);
if (close(null_fd) < 0)
i_error("close(null_fd) failed: %m");
if (close(imap_fd) < 0)
i_error("close(imap_fd) failed: %m");
if (close(imaps_fd) < 0)
i_error("close(imaps_fd) failed: %m");
hash_destroy(pids);
closelog();
}
static void daemonize(void)
{
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");
}
static void print_help(void)
{
printf("Usage: imap-master [-F] [-c <config file>]\n");
}
int main(int argc, char *argv[])
{
/* parse arguments */
int foreground = FALSE;
int i;
lib_init();
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-F") == 0) {
/* foreground */
foreground = TRUE;
} else if (strcmp(argv[i], "-c") == 0) {
/* config file */
i++;
if (i == argc) i_fatal("Missing config file argument");
configfile = argv[i];
} else {
print_help();
i_fatal("Unknown argument: %s", argv[1]);
}
}
/* read and verify settings before forking */
settings_init();
settings_read(configfile);
open_fds();
if (!foreground)
daemonize();
ioloop = io_loop_create(system_pool);
main_init();
io_loop_run(ioloop);
main_deinit();
io_loop_destroy(ioloop);
lib_deinit();
return 0;
}