-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 \
#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"
/* quit the program */
my_client = NULL;
- io_loop_stop(ioloop);
+ master_service_stop(service);
}
void client_disconnect(struct client *client, const char *reason)
#include "client.h"
#include "imap-settings.h"
-extern struct ioloop *ioloop;
+extern struct master_service *service;
extern void (*hook_client_created)(struct client **client);
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);
-}
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
#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)
{ 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
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 */
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);
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)
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;
}
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;
}
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();
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. */
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;
}
/* 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;
/* 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));
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
#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"
/* quit the program */
my_client = NULL;
- io_loop_stop(ioloop);
+ master_service_stop(service);
}
void client_disconnect(struct client *client, const char *reason)
#include "client.h"
#include "pop3-settings.h"
-extern struct ioloop *ioloop;
+extern struct master_service *service;
extern void (*hook_client_created)(struct client **client);
#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)
{ 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
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;
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)
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;
}
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"
};
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);
-}
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