]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap and pop3 now use mail-storage-service API.
authorTimo Sirainen <tss@iki.fi>
Sun, 12 Apr 2009 03:34:26 +0000 (23:34 -0400)
committerTimo Sirainen <tss@iki.fi>
Sun, 12 Apr 2009 03:34:26 +0000 (23:34 -0400)
--HG--
branch : HEAD

15 files changed:
src/imap/Makefile.am
src/imap/client.c
src/imap/common.h
src/imap/imap-settings.c
src/imap/imap-settings.h
src/imap/main.c
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-storage-service.h
src/master/child-process.c
src/pop3/Makefile.am
src/pop3/client.c
src/pop3/common.h
src/pop3/main.c
src/pop3/pop3-settings.c
src/pop3/pop3-settings.h

index dbc6c17497126f08c4ecb3fc1723c554205e65e4..8322546c573c7aba3f33ad2bea945df009bd1117 100644 (file)
@@ -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 \
index 9fce2472f84b50d0d33e981215a50862e29bf69f..229d3e9742522319c26551217bc0637e1fbf0661 100644 (file)
@@ -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)
index e4102c9d794be5afe8fb93e4d9d31cc4a7817daf..5f0665ead1efc784e300b2e993f4bddbdda66285 100644 (file)
@@ -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);
 
index 455c3ca573d42ed32b305a91eec765b3cfb02cb2..755f82066520caa9059573cd7c10bf6281648538 100644 (file)
@@ -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);
-}
index 3d7fd2170c580c5a6fe3b7363f4de1ed1312e2d8..ac1ba0fac56cee952e520b07959702f7705af069 100644 (file)
@@ -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
index 7225b0bbc875a99455921035f785c29938b0cde7..d2f0616fffb5fe74cfbc20a60ef12d48481932fc 100644 (file)
@@ -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 <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
 
 #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;
 }
index d82a509f9093969e5e6b33a46bc424c8eec53173..88933e30a5b9b3b99a70f34c761f9325fe8e69dd 100644 (file)
@@ -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;
 }
index 2e9077335c39086fdd795f72ce57b8ccdae56ab0..b3c03df769f25143899bcfd4bbcfa4fd9ca8ca63 100644 (file)
@@ -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;
index dafbee020ccac844ec311d1ad3d719ec2d8ed67b..80cb61c8d8891d4900585002502c3f6c1502c264 100644 (file)
@@ -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));
 
index bd702a379af8f06da717d95f221dfb4958b3ffa0..fbeb0198da1a87470832c2462def4ff69e92caf5 100644 (file)
@@ -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
index 637324e35c5c4fde6cb06cb038208e8a238611b7..bfda7605b4aa1dfa2ca8c4e02a622f18277c237f 100644 (file)
@@ -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)
index e64e244d93319ae89a688e5ae4ec3f3964d1b842..45cd93f3a441c58f39da0779fe1830efc4d95a04 100644 (file)
@@ -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);
 
index a9286b17d8d76d8e5bf3e0412b79a83710a9ed62..cbfafb494b19a3ec2f47c644d9f170ac66810246 100644 (file)
@@ -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 <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
 
 #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;
 }
index 587ff7f22f3a06f1c257a93a87026ee0b4537a99..f38f4537538beeed626ba36b4b3d526c9deb7858 100644 (file)
@@ -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);
-}
index 30bb7b62df05585f2f3b5557e1c602dea3a682be..bf22574e4dd878faf4562fb050437787448ecc22 100644 (file)
@@ -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