main.c revision a015320238a62a5531fc7e3946b3c854477c6c96
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "ioloop.h"
#include "lib-signals.h"
#include "network.h"
#include "env-util.h"
#include "fd-close-on-exec.h"
#include "auth-process.h"
#include "login-process.h"
#include "mail-process.h"
#include "ssl-init.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <syslog.h>
const char *process_names[PROCESS_TYPE_MAX] = {
"unknown",
"auth",
"login",
"imap",
"ssl-param"
};
struct hash_table *pids;
{
size_t i;
for (i = 0; i < max_len; i++) {
if (str[i] == '\0')
return TRUE;
}
return FALSE;
}
void clean_child_process(void)
{
/* remove all environment, we don't need them */
env_clean();
/* set the failure log */
env_put("USE_SYSLOG=1");
else
}
}
}
{
}
static void settings_reload(void)
{
i_warning("SIGHUP received - reloading configuration");
/* restart auth and login processes */
}
{
switch (status) {
case FATAL_LOGOPEN:
return "Can't open log file";
case FATAL_LOGWRITE:
return "Can't write to log file";
case FATAL_LOGERROR:
return "Internal logging error";
case FATAL_OUTOFMEM:
return "Out of memory";
case FATAL_EXEC:
return "exec() failed";
case FATAL_DEFAULT:
return NULL;
}
return NULL;
}
{
const char *process_type_name, *msg;
int status, process_type;
if (lib_signal_hup != 0) {
lib_signal_hup = 0;
}
/* get the type and remove from hash */
if (process_type == PROCESS_TYPE_MAIL)
if (process_type == PROCESS_TYPE_SSL_PARAM)
/* write errors to syslog */
if (status != 0) {
if (process_type == PROCESS_TYPE_LOGIN)
i_error("child %s (%s) returned error %d%s",
}
} else if (WIFSIGNALED(status)) {
if (process_type == PROCESS_TYPE_LOGIN)
i_error("child %s (%s) killed with signal %d",
}
}
i_warning("waitpid() failed: %m");
}
{
const char *p;
return NULL; /* defaults to "*" or "[::]" */
if (name[0] == '[') {
/* IPv6 address */
if (p == NULL)
p++;
if (*p == '\0')
p = NULL;
else if (*p != ':')
} else {
if (p != NULL)
}
if (p != NULL) {
}
/* IPv4 any */
return ip;
}
/* IPv6 any */
return ip;
}
/* Return the first IP if there happens to be multiple. */
if (ret != 0) {
i_fatal("Can't resolve address %s: %s",
}
if (ips_count < 1)
return ip;
}
static void open_fds(void)
{
const char *const *proto;
unsigned int imap_port = 143;
unsigned int pop3_port = 110;
#ifdef HAVE_SSL
unsigned int imaps_port = 993;
unsigned int pop3s_port = 995;
#else
unsigned int imaps_port = 0;
unsigned int pop3s_port = 0;
#endif
unsigned int port;
int *fd, i;
/* resolve */
/* initialize fds */
if (null_fd == -1)
for (i = 0; i < FD_MAX; i++)
mail_fd[i] = -1;
/* register wanted protocols */
} else {
}
if (*fd != -1)
if (*fd == -1)
}
for (i = 0; i < FD_MAX; i++) {
if (mail_fd[i] == -1) {
if (mail_fd[i] == -1)
i_fatal("dup(mail_fd[%d]) failed: %m", i);
}
}
/* close stdin and stdout. close stderr unless we're logging
i_fatal("dup2(0) failed: %m");
i_fatal("dup2(1) failed: %m");
i_fatal("dup(0) failed: %m");
}
}
static void open_logfile(void)
{
else {
/* log to file or stderr */
}
i_info("Dovecot starting up");
}
static void main_init(void)
{
/* deny file access from everyone else except owner */
(void)umask(0077);
open_logfile();
ssl_init();
}
static void main_deinit(void)
{
int i;
if (lib_signal_kill != 0)
/* make sure we log if child processes died unexpectedly */
ssl_deinit();
i_error("close(null_fd) failed: %m");
for (i = 0; i < FD_MAX; i++) {
i_error("close(mail_fd[%d]) failed: %m", i);
}
closelog();
}
static void daemonize(void)
{
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: dovecot [-F] [-c <config file>]\n");
}
{
/* parse arguments */
int foreground = FALSE;
int i;
lib_init();
for (i = 1; i < argc; i++) {
/* foreground */
foreground = TRUE;
/* config file */
i++;
configfile = argv[i];
return 0;
} else {
print_help();
}
}
/* read and verify settings before forking */
open_fds();
if (!foreground)
daemonize();
main_init();
main_deinit();
lib_deinit();
return 0;
}