From: Timo Sirainen Date: Sun, 12 Apr 2009 03:34:26 +0000 (-0400) Subject: imap and pop3 now use mail-storage-service API. X-Git-Tag: 2.0.alpha1~972 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b04762685272a53643ac2179939537a44c7c044;p=thirdparty%2Fdovecot%2Fcore.git imap and pop3 now use mail-storage-service API. --HG-- branch : HEAD --- diff --git a/src/imap/Makefile.am b/src/imap/Makefile.am index dbc6c17497..8322546c57 100644 --- a/src/imap/Makefile.am +++ b/src/imap/Makefile.am @@ -6,6 +6,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-dict \ + -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-mail \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-index \ diff --git a/src/imap/client.c b/src/imap/client.c index 9fce2472f8..229d3e9742 100644 --- a/src/imap/client.c +++ b/src/imap/client.c @@ -8,6 +8,7 @@ #include "istream.h" #include "ostream.h" #include "var-expand.h" +#include "master-service.h" #include "imap-resp-code.h" #include "imap-util.h" #include "mail-namespace.h" @@ -203,7 +204,7 @@ void client_destroy(struct client *client, const char *reason) /* quit the program */ my_client = NULL; - io_loop_stop(ioloop); + master_service_stop(service); } void client_disconnect(struct client *client, const char *reason) diff --git a/src/imap/common.h b/src/imap/common.h index e4102c9d79..5f0665ead1 100644 --- a/src/imap/common.h +++ b/src/imap/common.h @@ -23,7 +23,7 @@ enum client_workarounds { #include "client.h" #include "imap-settings.h" -extern struct ioloop *ioloop; +extern struct master_service *service; extern void (*hook_client_created)(struct client **client); diff --git a/src/imap/imap-settings.c b/src/imap/imap-settings.c index 455c3ca573..755f820665 100644 --- a/src/imap/imap-settings.c +++ b/src/imap/imap-settings.c @@ -59,68 +59,3 @@ struct setting_parser_info imap_setting_parser_info = { MEMBER(struct_size) sizeof(struct imap_settings), MEMBER(check_func) NULL }; - -static pool_t settings_pool = NULL; - -static void -parse_expand_vars(struct setting_parser_context *parser, const char *value) -{ - const char *const *expanded; - - expanded = t_strsplit(value, " "); - settings_parse_set_keys_expandeded(parser, settings_pool, expanded); - /* settings from userdb are in the VARS_EXPANDED list. for each - unknown setting in the list assume it's a plugin setting. */ - for (; *expanded != NULL; expanded++) { - if (settings_parse_is_valid_key(parser, *expanded)) - continue; - - value = getenv(t_str_ucase(*expanded)); - if (value == NULL) - continue; - - settings_parse_line(parser, t_strconcat("plugin/", *expanded, - "=", value, NULL)); - } -} - -void imap_settings_read(const struct imap_settings **set_r, - const struct mail_user_settings **user_set_r) -{ - static const struct setting_parser_info *roots[] = { - &imap_setting_parser_info, - &mail_user_setting_parser_info - }; - struct setting_parser_context *parser; - const char *value, *error; - void **sets; - - if (settings_pool == NULL) - settings_pool = pool_alloconly_create("imap settings", 4096); - else - p_clear(settings_pool); - - settings_parser_info_update(settings_pool, - mail_storage_get_dynamic_parsers()); - - parser = settings_parser_init_list(settings_pool, - roots, N_ELEMENTS(roots), - SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS); - - if (settings_parse_environ(parser) < 0) { - i_fatal("Error reading configuration: %s", - settings_parser_get_error(parser)); - } - - value = getenv("VARS_EXPANDED"); - if (value != NULL) - parse_expand_vars(parser, value); - - if (settings_parser_check(parser, settings_pool, &error) < 0) - i_fatal("Invalid settings: %s", error); - - sets = settings_parser_get_list(parser); - *set_r = sets[0]; - *user_set_r = sets[1]; - settings_parser_deinit(&parser); -} diff --git a/src/imap/imap-settings.h b/src/imap/imap-settings.h index 3d7fd2170c..ac1ba0fac5 100644 --- a/src/imap/imap-settings.h +++ b/src/imap/imap-settings.h @@ -17,7 +17,6 @@ struct imap_settings { const char *imap_id_log; }; -void imap_settings_read(const struct imap_settings **set_r, - const struct mail_user_settings **user_set_r); +extern struct setting_parser_info imap_setting_parser_info; #endif diff --git a/src/imap/main.c b/src/imap/main.c index 7225b0bbc8..d2f0616fff 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -2,25 +2,21 @@ #include "common.h" #include "ioloop.h" -#include "network.h" +#include "istream.h" #include "ostream.h" #include "str.h" #include "base64.h" -#include "istream.h" -#include "lib-signals.h" #include "restrict-access.h" #include "fd-close-on-exec.h" #include "process-title.h" -#include "module-dir.h" -#include "dict.h" -#include "mail-storage.h" +#include "master-service.h" +#include "mail-user.h" +#include "mail-storage-service.h" #include "commands.h" -#include "mail-namespace.h" #include #include #include -#include #define IS_STANDALONE() \ (getenv("IMAPLOGINTAG") == NULL) @@ -38,33 +34,17 @@ static struct client_workaround_list client_workaround_list[] = { { NULL, 0 } }; -struct ioloop *ioloop; - static struct io *log_io = NULL; -static struct module *modules = NULL; -static char log_prefix[128]; /* syslog() needs this to be permanent */ +struct master_service *service; void (*hook_client_created)(struct client **client) = NULL; -static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) -{ - /* warn about being killed because of some signal, except SIGINT (^C) - which is too common at least while testing :) */ - if (si->si_signo != SIGINT) { - i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)", - si->si_signo, dec2str(si->si_pid), - dec2str(si->si_uid), - lib_signal_code_to_str(si->si_signo, si->si_code)); - } - io_loop_stop(ioloop); -} - static void log_error_callback(void *context ATTR_UNUSED) { /* the log fd is closed, don't die when trying to log later */ i_set_failure_ignore_errors(TRUE); - io_loop_stop(ioloop); + master_service_stop(service); } static enum client_workarounds @@ -90,111 +70,12 @@ parse_workarounds(const struct imap_settings *set) return client_workarounds; } -static void open_logfile(void) -{ - const char *user; - - if (getenv("LOG_TO_MASTER") != NULL) { - i_set_failure_internal(); - return; - } - - if (getenv("LOG_PREFIX") != NULL) - i_strocpy(log_prefix, getenv("LOG_PREFIX"), sizeof(log_prefix)); - else { - user = getenv("USER"); - if (user == NULL) { - if (IS_STANDALONE()) - user = getlogin(); - if (user == NULL) - user = "??"; - } - if (strlen(user) >= sizeof(log_prefix)-6) { - /* quite a long user name, cut it */ - user = t_strndup(user, sizeof(log_prefix)-6-2); - user = t_strconcat(user, "..", NULL); - } - i_snprintf(log_prefix, sizeof(log_prefix), "imap(%s): ", user); - } - if (getenv("USE_SYSLOG") != NULL) { - const char *env = getenv("SYSLOG_FACILITY"); - i_set_failure_syslog(log_prefix, LOG_NDELAY, - env == NULL ? LOG_MAIL : atoi(env)); - } else { - /* log to file or stderr */ - i_set_failure_file(getenv("LOGFILE"), log_prefix); - } - - if (getenv("INFOLOGFILE") != NULL) - i_set_info_file(getenv("INFOLOGFILE")); - - i_set_failure_timestamp_format(getenv("LOGSTAMP")); -} - -static void main_preinit(const struct imap_settings **set_r, - const struct mail_user_settings **user_set_r) -{ - const char *version; - - version = getenv("DOVECOT_VERSION"); - if (version != NULL && strcmp(version, PACKAGE_VERSION) != 0) { - i_fatal("Dovecot version mismatch: " - "Master is v%s, imap is v"PACKAGE_VERSION" " - "(if you don't care, set version_ignore=yes)", version); - } - - /* Log file or syslog opening probably requires roots */ - open_logfile(); - - mail_storage_init(); - mail_storage_register_all(); - mailbox_list_register_all(); - - /* read settings after registering storages so they can have their - own setting definitions too */ - imap_settings_read(set_r, user_set_r); - - /* Load the plugins before chrooting. Their init() is called later. */ - modules = *(*user_set_r)->mail_plugins == '\0' ? NULL : - module_dir_load((*user_set_r)->mail_plugin_dir, - (*user_set_r)->mail_plugins, TRUE, version); - - restrict_access_by_env(getenv("HOME"), !IS_STANDALONE()); - restrict_access_allow_coredumps(TRUE); -} - -static void main_init(const struct imap_settings *set, - const struct mail_user_settings *user_set) +static void main_init(const struct imap_settings *set, struct mail_user *user, + bool dump_capability) { struct client *client; struct ostream *output; - struct mail_user *user; - const char *username, *home, *str, *tag, *error; - bool dump_capability; - - lib_signals_init(); - lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); - lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); - lib_signals_ignore(SIGPIPE, TRUE); - lib_signals_ignore(SIGALRM, FALSE); - - dump_capability = getenv("DUMP_CAPABILITY") != NULL; - - username = getenv("USER"); - if (username == NULL) { - if (IS_STANDALONE()) - username = getlogin(); - if (username == NULL) - i_fatal("USER environment missing"); - } - - home = getenv("HOME"); - if (set->mail_debug) { - home = getenv("HOME"); - i_info("Effective uid=%s, gid=%s, home=%s", - dec2str(geteuid()), dec2str(getegid()), - home != NULL ? home : "(none)"); - } + const char *str, *tag; if (set->shutdown_clients && !dump_capability) { /* If master dies, the log fd gets closed and we'll quit */ @@ -202,18 +83,9 @@ static void main_init(const struct imap_settings *set, log_error_callback, NULL); } - module_dir_init(modules); - dict_drivers_register_builtin(); - mail_users_init(user_set->auth_socket_path, set->mail_debug); clients_init(); commands_init(); - user = mail_user_alloc(username, user_set); - mail_user_set_home(user, home); - if (mail_user_init(user, &error) < 0) - i_fatal("Mail user initialization failed: %s", error); - if (mail_namespaces_init(user, &error) < 0) - i_fatal("Namespace initialization failed: %s", error); client = client_create(0, 1, user, set); client->workarounds = parse_workarounds(set); @@ -257,21 +129,18 @@ static void main_deinit(void) if (log_io != NULL) io_remove(&log_io); clients_deinit(); - - module_dir_unload(&modules); commands_deinit(); - mail_storage_deinit(); - mail_users_deinit(); - dict_drivers_unregister_builtin(); - - lib_signals_deinit(); - closelog(); } -int main(int argc ATTR_UNUSED, char *argv[], char *envp[]) +int main(int argc, char *argv[], char *envp[]) { + enum master_service_flags service_flags = 0; + enum mail_storage_service_flags storage_service_flags = 0; + struct mail_user *mail_user; const struct imap_settings *set; - const struct mail_user_settings *user_set; + const char *user; + bool dump_capability; + int c; #ifdef DEBUG if (!IS_STANDALONE() && getenv("GDB") == NULL) @@ -284,24 +153,49 @@ int main(int argc ATTR_UNUSED, char *argv[], char *envp[]) return 1; } - /* NOTE: we start rooted, so keep the code minimal until - restrict_access_by_env() is called */ - lib_init(); - main_preinit(&set, &user_set); + if (IS_STANDALONE()) + service_flags |= MASTER_SERVICE_FLAG_STANDALONE; + else + service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; + + dump_capability = getenv("DUMP_CAPABILITY") != NULL; + if (dump_capability) { + storage_service_flags |= + MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; + } + + service = master_service_init("imap", service_flags, argc, argv); + while ((c = getopt(argc, argv, master_service_getopt_string())) > 0) { + if (!master_service_parse_option(service, c, optarg)) + i_fatal("Unknown argument: %c", c); + } + + user = getenv("USER"); + if (user == NULL) { + if (IS_STANDALONE()) + user = getlogin(); + if (user == NULL) + i_fatal("USER environment missing"); + } + + mail_user = mail_storage_service_init_user(service, user, + &imap_setting_parser_info, + storage_service_flags); + set = mail_storage_service_get_settings(service); + restrict_access_allow_coredumps(TRUE); process_title_init(argv, envp); - ioloop = io_loop_create(); /* fake that we're running, so we know if client was destroyed while initializing */ - io_loop_set_running(ioloop); - main_init(set, user_set); - if (io_loop_is_running(ioloop)) - io_loop_run(ioloop); - main_deinit(); + io_loop_set_running(current_ioloop); - io_loop_destroy(&ioloop); - lib_deinit(); + main_init(set, mail_user, dump_capability); + if (io_loop_is_running(current_ioloop)) + master_service_run(service); + main_deinit(); + mail_storage_service_deinit_user(); + master_service_deinit(&service); return 0; } diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index d82a509f90..88933e30a5 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -340,9 +340,11 @@ mail_storage_service_init_post(struct master_service *service, if (*home != '\0') mail_user_set_home(mail_user, home); mail_user_set_vars(mail_user, geteuid(), service->name, NULL, NULL); - if (mail_user_init(mail_user, error_r) < 0 || - mail_namespaces_init(mail_user, error_r) < 0) { - *error_r = t_strdup(*error_r); + if (mail_user_init(mail_user, error_r) < 0) { + mail_user_unref(&mail_user); + return -1; + } + if (mail_namespaces_init(mail_user, error_r) < 0) { mail_user_unref(&mail_user); return -1; } @@ -458,8 +460,11 @@ mail_storage_service_init_user(struct master_service *service, const char *user, user_set->mail_plugins, TRUE, master_service_get_version_string(service)); - service_drop_privileges(user_set, system_groups_user, home, - (flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, FALSE); + if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) { + service_drop_privileges(user_set, system_groups_user, home, + (flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, + FALSE); + } /* privileges are now dropped */ dict_drivers_register_builtin(); @@ -549,9 +554,11 @@ int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, but we need the home sooner so do it separately here. */ home = user_expand_varstr(ctx->service, user, user_set->mail_home); - service_drop_privileges(user_set, system_groups_user, home, - (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, TRUE); - + if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) { + service_drop_privileges(user_set, system_groups_user, home, + (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, + TRUE); + } if (!ctx->modules_initialized) { /* privileges dropped for the first time. initialize the modules now to avoid code running as root. */ @@ -569,8 +576,8 @@ int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, master_service_set(ctx->service, "mail_home", t_strconcat(user_set->mail_chroot, "/", home, NULL)); } - if (mail_storage_service_init_post(ctx->service, user, home, - user_set, mail_user_r, error_r) < 0) + if (mail_storage_service_init_post(ctx->service, user, home, user_set, + mail_user_r, error_r) < 0) return -1; return 1; } diff --git a/src/lib-storage/mail-storage-service.h b/src/lib-storage/mail-storage-service.h index 2e9077335c..b3c03df769 100644 --- a/src/lib-storage/mail-storage-service.h +++ b/src/lib-storage/mail-storage-service.h @@ -7,7 +7,9 @@ enum mail_storage_service_flags { /* Lookup user from userdb */ MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP = 0x02, /* Force mail_debug=yes */ - MAIL_STORAGE_SERVICE_FLAG_DEBUG = 0x04 + MAIL_STORAGE_SERVICE_FLAG_DEBUG = 0x04, + /* Keep the current process permissions */ + MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS = 0x08 }; struct setting_parser_info; diff --git a/src/master/child-process.c b/src/master/child-process.c index dafbee020c..80cb61c8d8 100644 --- a/src/master/child-process.c +++ b/src/master/child-process.c @@ -48,6 +48,7 @@ void child_process_init_env(const struct master_settings *set) /* we'll log through master process */ env_put("LOG_TO_MASTER=1"); + env_put("DOVECONF_ENV=1"); if (env_tz != NULL) env_put(t_strconcat("TZ=", env_tz, NULL)); diff --git a/src/pop3/Makefile.am b/src/pop3/Makefile.am index bd702a379a..fbeb0198da 100644 --- a/src/pop3/Makefile.am +++ b/src/pop3/Makefile.am @@ -5,6 +5,7 @@ pkglibexec_PROGRAMS = pop3 AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-mail \ -I$(top_srcdir)/src/lib-storage diff --git a/src/pop3/client.c b/src/pop3/client.c index 637324e35c..bfda7605b4 100644 --- a/src/pop3/client.c +++ b/src/pop3/client.c @@ -8,6 +8,7 @@ #include "ostream.h" #include "str.h" #include "var-expand.h" +#include "master-service.h" #include "mail-storage.h" #include "commands.h" #include "mail-search-build.h" @@ -324,7 +325,7 @@ void client_destroy(struct client *client, const char *reason) /* quit the program */ my_client = NULL; - io_loop_stop(ioloop); + master_service_stop(service); } void client_disconnect(struct client *client, const char *reason) diff --git a/src/pop3/common.h b/src/pop3/common.h index e64e244d93..45cd93f3a4 100644 --- a/src/pop3/common.h +++ b/src/pop3/common.h @@ -17,7 +17,7 @@ enum uidl_keys { #include "client.h" #include "pop3-settings.h" -extern struct ioloop *ioloop; +extern struct master_service *service; extern void (*hook_client_created)(struct client **client); diff --git a/src/pop3/main.c b/src/pop3/main.c index a9286b17d8..cbfafb494b 100644 --- a/src/pop3/main.c +++ b/src/pop3/main.c @@ -2,25 +2,19 @@ #include "common.h" #include "ioloop.h" -#include "file-lock.h" -#include "network.h" -#include "lib-signals.h" +#include "istream.h" +#include "buffer.h" +#include "base64.h" #include "restrict-access.h" #include "fd-close-on-exec.h" -#include "base64.h" -#include "buffer.h" -#include "istream.h" #include "process-title.h" -#include "module-dir.h" +#include "master-service.h" #include "var-expand.h" -#include "dict.h" -#include "mail-storage.h" -#include "mail-namespace.h" +#include "mail-storage-service.h" #include #include #include -#include #define IS_STANDALONE() \ (getenv("LOGGED_IN") == NULL) @@ -36,33 +30,17 @@ static struct client_workaround_list client_workaround_list[] = { { NULL, 0 } }; -struct ioloop *ioloop; - +struct master_service *service; void (*hook_client_created)(struct client **client) = NULL; -static struct module *modules = NULL; -static char log_prefix[128]; /* syslog() needs this to be permanent */ static struct io *log_io = NULL; -static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) -{ - /* warn about being killed because of some signal, except SIGINT (^C) - which is too common at least while testing :) */ - if (si->si_signo != SIGINT) { - i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)", - si->si_signo, dec2str(si->si_pid), - dec2str(si->si_uid), - lib_signal_code_to_str(si->si_signo, si->si_code)); - } - io_loop_stop(ioloop); -} - static void log_error_callback(void *context ATTR_UNUSED) { /* the log fd is closed, don't die when trying to log later */ i_set_failure_ignore_errors(TRUE); - io_loop_stop(ioloop); + master_service_stop(service); } static enum client_workarounds @@ -112,120 +90,20 @@ static enum uidl_keys parse_uidl_keymask(const char *format) return mask; } -static void open_logfile(void) -{ - const char *user; - - if (getenv("LOG_TO_MASTER") != NULL) { - i_set_failure_internal(); - return; - } - - if (getenv("LOG_PREFIX") != NULL) - i_strocpy(log_prefix, getenv("LOG_PREFIX"), sizeof(log_prefix)); - else { - user = getenv("USER"); - if (user == NULL) user = "??"; - if (strlen(user) >= sizeof(log_prefix)-6) { - /* quite a long user name, cut it */ - user = t_strndup(user, sizeof(log_prefix)-6-2); - user = t_strconcat(user, "..", NULL); - } - i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s): ", user); - } - - if (getenv("USE_SYSLOG") != NULL) { - const char *env = getenv("SYSLOG_FACILITY"); - i_set_failure_syslog(log_prefix, LOG_NDELAY, - env == NULL ? LOG_MAIL : atoi(env)); - } else { - /* log to file or stderr */ - i_set_failure_file(getenv("LOGFILE"), log_prefix); - } - - if (getenv("INFOLOGFILE") != NULL) - i_set_info_file(getenv("INFOLOGFILE")); - - i_set_failure_timestamp_format(getenv("LOGSTAMP")); -} - -static void main_preinit(const struct pop3_settings **set_r, - const struct mail_user_settings **user_set_r) -{ - const char *version; - - version = getenv("DOVECOT_VERSION"); - if (version != NULL && strcmp(version, PACKAGE_VERSION) != 0) { - i_fatal("Dovecot version mismatch: " - "Master is v%s, pop3 is v"PACKAGE_VERSION" " - "(if you don't care, set version_ignore=yes)", version); - } - - /* Log file or syslog opening probably requires roots */ - open_logfile(); - - mail_storage_init(); - mail_storage_register_all(); - mailbox_list_register_all(); - - /* read settings after registering storages so they can have their - own setting definitions too */ - pop3_settings_read(set_r, user_set_r); - - /* Load the plugins before chrooting. Their init() is called later. */ - modules = *(*user_set_r)->mail_plugins == '\0' ? NULL : - module_dir_load((*user_set_r)->mail_plugin_dir, - (*user_set_r)->mail_plugins, TRUE, version); - - restrict_access_by_env(getenv("HOME"), !IS_STANDALONE()); - restrict_access_allow_coredumps(TRUE); -} - -static bool main_init(const struct pop3_settings *set, - const struct mail_user_settings *user_set) +static bool main_init(const struct pop3_settings *set, struct mail_user *user) { - struct mail_user *user; struct client *client; - const char *str, *error; + const char *str; bool ret = TRUE; - lib_signals_init(); - lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); - lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); - lib_signals_ignore(SIGPIPE, TRUE); - lib_signals_ignore(SIGALRM, FALSE); - - if (getenv("USER") == NULL) - i_fatal("USER environment missing"); - - if (set->mail_debug) { - const char *home; - - home = getenv("HOME"); - i_info("Effective uid=%s, gid=%s, home=%s", - dec2str(geteuid()), dec2str(getegid()), - home != NULL ? home : "(none)"); - } - if (set->shutdown_clients) { /* If master dies, the log fd gets closed and we'll quit */ log_io = io_add(STDERR_FILENO, IO_ERROR, log_error_callback, NULL); } - dict_drivers_register_builtin(); - mail_users_init(user_set->auth_socket_path, set->mail_debug); clients_init(); - module_dir_init(modules); - - user = mail_user_alloc(getenv("USER"), user_set); - mail_user_set_home(user, getenv("HOME")); - if (mail_user_init(user, &error) < 0) - i_fatal("Mail user initialization failed: %s", error); - if (mail_namespaces_init(user, &error) < 0) - i_fatal("Namespace initialization failed: %s", error); - client = client_create(0, 1, user, set); if (client == NULL) return FALSE; @@ -257,20 +135,17 @@ static void main_deinit(void) if (log_io != NULL) io_remove(&log_io); clients_deinit(); - - module_dir_unload(&modules); - mail_storage_deinit(); - mail_users_deinit(); - dict_drivers_unregister_builtin(); - - lib_signals_deinit(); - closelog(); } -int main(int argc ATTR_UNUSED, char *argv[], char *envp[]) +int main(int argc, char *argv[], char *envp[]) { + enum master_service_flags service_flags = 0; + enum mail_storage_service_flags storage_service_flags = + MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; + struct mail_user *mail_user; const struct pop3_settings *set; - const struct mail_user_settings *user_set; + const char *user; + int c; #ifdef DEBUG if (!IS_STANDALONE() && getenv("GDB") == NULL) @@ -283,20 +158,41 @@ int main(int argc ATTR_UNUSED, char *argv[], char *envp[]) return 1; } - /* NOTE: we start rooted, so keep the code minimal until - restrict_access_by_env() is called */ - lib_init(); - main_preinit(&set, &user_set); + if (IS_STANDALONE()) + service_flags |= MASTER_SERVICE_FLAG_STANDALONE; + else + service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; + + service = master_service_init("pop3", service_flags, argc, argv); + while ((c = getopt(argc, argv, master_service_getopt_string())) > 0) { + if (!master_service_parse_option(service, c, optarg)) + i_fatal("Unknown argument: %c", c); + } + user = getenv("USER"); + if (user == NULL) { + if (IS_STANDALONE()) + user = getlogin(); + if (user == NULL) + i_fatal("USER environment missing"); + } + + mail_user = mail_storage_service_init_user(service, user, + &pop3_setting_parser_info, + storage_service_flags); + set = mail_storage_service_get_settings(service); + restrict_access_allow_coredumps(TRUE); process_title_init(argv, envp); - ioloop = io_loop_create(); - if (main_init(set, user_set)) - io_loop_run(ioloop); - main_deinit(); + /* fake that we're running, so we know if client was destroyed + while initializing */ + io_loop_set_running(current_ioloop); - io_loop_destroy(&ioloop); - lib_deinit(); + if (main_init(set, mail_user)) + master_service_run(service); + main_deinit(); + mail_storage_service_deinit_user(); + master_service_deinit(&service); return 0; } diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c index 587ff7f22f..f38f453753 100644 --- a/src/pop3/pop3-settings.c +++ b/src/pop3/pop3-settings.c @@ -41,7 +41,7 @@ static struct pop3_settings pop3_default_settings = { MEMBER(pop3_enable_last) FALSE, MEMBER(pop3_reuse_xuidl) FALSE, MEMBER(pop3_lock_session) FALSE, - MEMBER(pop3_client_workarounds) NULL, + MEMBER(pop3_client_workarounds) "", MEMBER(pop3_logout_format) "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s", MEMBER(pop3_uidl_format) "%08Xu%08Xv" }; @@ -58,68 +58,3 @@ struct setting_parser_info pop3_setting_parser_info = { MEMBER(struct_size) sizeof(struct pop3_settings), MEMBER(check_func) NULL }; - -static pool_t settings_pool = NULL; - -static void -parse_expand_vars(struct setting_parser_context *parser, const char *value) -{ - const char *const *expanded; - - expanded = t_strsplit(value, " "); - settings_parse_set_keys_expandeded(parser, settings_pool, expanded); - /* settings from userdb are in the VARS_EXPANDED list. for each - unknown setting in the list assume it's a plugin setting. */ - for (; *expanded != NULL; expanded++) { - if (settings_parse_is_valid_key(parser, *expanded)) - continue; - - value = getenv(t_str_ucase(*expanded)); - if (value == NULL) - continue; - - settings_parse_line(parser, t_strconcat("plugin/", *expanded, - "=", value, NULL)); - } -} - -void pop3_settings_read(const struct pop3_settings **set_r, - const struct mail_user_settings **user_set_r) -{ - static const struct setting_parser_info *roots[] = { - &pop3_setting_parser_info, - &mail_user_setting_parser_info - }; - struct setting_parser_context *parser; - const char *value, *error; - void **sets; - - if (settings_pool == NULL) - settings_pool = pool_alloconly_create("pop3 settings", 4096); - else - p_clear(settings_pool); - - settings_parser_info_update(settings_pool, - mail_storage_get_dynamic_parsers()); - - parser = settings_parser_init_list(settings_pool, - roots, N_ELEMENTS(roots), - SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS); - - if (settings_parse_environ(parser) < 0) { - i_fatal("Error reading configuration: %s", - settings_parser_get_error(parser)); - } - - value = getenv("VARS_EXPANDED"); - if (value != NULL) - parse_expand_vars(parser, value); - - if (settings_parser_check(parser, settings_pool, &error) < 0) - i_fatal("Invalid settings: %s", error); - - sets = settings_parser_get_list(parser); - *set_r = sets[0]; - *user_set_r = sets[1]; - settings_parser_deinit(&parser); -} diff --git a/src/pop3/pop3-settings.h b/src/pop3/pop3-settings.h index 30bb7b62df..bf22574e4d 100644 --- a/src/pop3/pop3-settings.h +++ b/src/pop3/pop3-settings.h @@ -18,7 +18,6 @@ struct pop3_settings { const char *pop3_uidl_format; }; -void pop3_settings_read(const struct pop3_settings **set_r, - const struct mail_user_settings **user_set_r); +extern struct setting_parser_info pop3_setting_parser_info; #endif