main.c revision 868572d42fb8c1e90ea5ab6a5cc5d98f16aec3b6
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr/* Copyright (C) 2002 Timo Sirainen */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "common.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "ioloop.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "lib-signals.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "network.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "auth-process.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include "login-process.h"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <stdlib.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <unistd.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <fcntl.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <syslog.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <sys/stat.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr#include <sys/wait.h>
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frconst char *process_names[PROCESS_TYPE_MAX] = {
cae3584efccc63f544c8748bd13d80e11bc79aefgza "unknown",
cae3584efccc63f544c8748bd13d80e11bc79aefgza "auth",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr "login",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr "imap"
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr};
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic IOLoop ioloop;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic Timeout to_children;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frHashTable *pids;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frint null_fd, imap_fd, imaps_fd;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frint validate_str(const char *str, int max_len)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr int i;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr for (i = 0; i < max_len; i++) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (str[i] == '\0')
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr return TRUE;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr return FALSE;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frvoid clean_child_process(void)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr extern char **environ;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* remove all environment, we don't need them */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (environ != NULL)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr *environ = NULL;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* set the failure log */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (set_log_path != NULL) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr putenv((char *) t_strconcat("IMAP_LOGFILE=",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr set_log_path, NULL));
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (set_log_timestamp != NULL) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr putenv((char *) t_strconcat("IMAP_LOGSTAMP=",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr set_log_timestamp, NULL));
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(null_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(imap_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(imaps_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* close fds for auth/login processes */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr login_processes_cleanup();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr auth_processes_cleanup();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr closelog();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void sig_quit(int signo __attr_unused__)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr io_loop_stop(ioloop);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void children_check_timeout(void *context __attr_unused__,
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr Timeout timeout __attr_unused__)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr const char *process_type_name;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr pid_t pid;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr int status, process_type;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* get the type and remove from hash */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr process_type = PID_GET_PROCESS_TYPE(pid);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr PID_REMOVE_PROCESS_TYPE(pid);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (process_type == PROCESS_TYPE_IMAP)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imap_process_destroyed(pid);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* write errors to syslog */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr process_type_name = process_names[process_type];
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (WIFEXITED(status)) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr status = WEXITSTATUS(status);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (status != 0) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_error("child %d (%s) returned error %d",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (int)pid, process_type_name, status);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr } else if (WIFSIGNALED(status)) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_error("child %d (%s) killed with signal %d",
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (int)pid, process_type_name, WTERMSIG(status));
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (pid == -1 && errno != EINTR && errno != ECHILD)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_warning("waitpid() failed: %m");
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic IPADDR *resolve_ip(const char *name)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr IPADDR *ip;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr int ret, ips_count;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (set_imap_listen == NULL || *set_imap_listen == '\0')
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr return NULL;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr ret = net_gethostbyname(name, &ip, &ips_count);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (ret != 0)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("Can't resolve address: %s", set_imap_listen);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (ips_count < 1)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("No IPs for address: %s", set_imap_listen);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr return ip;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void open_fds(void)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr IPADDR *imap_ip, *imaps_ip;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imap_ip = resolve_ip(set_imap_listen);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imaps_ip = resolve_ip(set_imaps_listen);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (imaps_ip == NULL && set_imaps_listen == NULL)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imaps_ip = imap_ip;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr null_fd = open("/dev/null", O_RDONLY);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (null_fd == -1)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("Can't open /dev/null: %m");
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imap_fd = set_imap_port == 0 ? dup(null_fd) :
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr net_listen(imap_ip, &set_imap_port);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (imap_fd == -1) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("listen(%d) failed: %ms", set_imap_port);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr imaps_fd = set_ssl_cert_file == NULL || set_ssl_key_file == NULL ||
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr set_imaps_port == 0 ? dup(null_fd) :
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr net_listen(imaps_ip, &set_imaps_port);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (imaps_fd == -1) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("listen(%d) failed: %m", set_imaps_port);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void main_init()
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr lib_init_signals(sig_quit);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* deny file access from everyone else except owner */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)umask(0077);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (set_log_path == NULL) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr openlog("imap-master", LOG_NDELAY, LOG_MAIL);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_panic_handler(i_syslog_panic_handler);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_fatal_handler(i_syslog_fatal_handler);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_error_handler(i_syslog_error_handler);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_warning_handler(i_syslog_warning_handler);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr } else {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* log failures into specified log file */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_failure_file(set_log_path, "imap-master");
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_set_failure_timestamp_format(set_log_timestamp);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr pids = hash_create(default_pool, 128, NULL, NULL);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr to_children = timeout_add(100, children_check_timeout, NULL);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr auth_processes_init();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr login_processes_init();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void main_deinit(void)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (lib_signal_kill != 0)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_warning("Killed with signal %d", lib_signal_kill);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr login_processes_deinit();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr auth_processes_deinit();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr timeout_remove(to_children);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(null_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(imap_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr (void)close(imaps_fd);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr hash_destroy(pids);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr closelog();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frstatic void daemonize(void)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr pid_t pid;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr pid = fork();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (pid < 0)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("fork() failed: %m");
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (pid != 0)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr _exit(0);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.frint main(int argc, char *argv[])
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr{
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* parse arguments */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr const char *configfile = SYSCONFDIR "/" PACKAGE ".conf";
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr int foreground = FALSE;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr int i;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr lib_init();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr for (i = 1; i < argc; i++) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (strcmp(argv[i], "-F") == 0) {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* foreground */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr foreground = TRUE;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr } else if (strcmp(argv[i], "-c") == 0) {
cae3584efccc63f544c8748bd13d80e11bc79aefgza /* config file */
cae3584efccc63f544c8748bd13d80e11bc79aefgza i++;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (i == argc) i_fatal("Missing config file argument");
9749441a0e8072f43e955fba47e07bfd015d0a45Stéphane Graber configfile = argv[i];
9749441a0e8072f43e955fba47e07bfd015d0a45Stéphane Graber } else {
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr i_fatal("Unknown argument: %s", argv[1]);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr }
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr /* read and verify settings before forking */
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr settings_read(configfile);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr open_fds();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr if (!foreground)
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr daemonize();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr ioloop = io_loop_create();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr main_init();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr io_loop_run(ioloop);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr main_deinit();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr io_loop_destroy(ioloop);
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr lib_deinit();
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr return 0;
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr}
f8d0243a78c65ea3c46eb60fbeef799c3f6e9a5blxc@zitta.fr