]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Added support for plugins.
authorTimo Sirainen <tss@iki.fi>
Mon, 8 Mar 2010 15:28:29 +0000 (17:28 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 8 Mar 2010 15:28:29 +0000 (17:28 +0200)
--HG--
branch : HEAD

src/doveadm/Makefile.am
src/doveadm/doveadm-mail.c
src/doveadm/doveadm-settings.c [new file with mode: 0644]
src/doveadm/doveadm-settings.h [new file with mode: 0644]
src/doveadm/doveadm.c

index 92793d6c516587bdb544b779603a9daf2b1b59f5..60c0578f0d5ab99d70399cdb8451b1bd124281ab 100644 (file)
@@ -1,7 +1,10 @@
+doveadm_moduledir = $(moduledir)/doveadm
+
 bin_PROGRAMS = doveadm
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
+       -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-auth \
        -I$(top_srcdir)/src/lib-dict \
        -I$(top_srcdir)/src/lib-master \
@@ -10,21 +13,32 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib-index \
        -I$(top_srcdir)/src/lib-storage \
        -I$(top_srcdir)/src/auth \
+       -DMODULEDIR=\""$(moduledir)"\" \
+       -DDOVEADM_MODULEDIR=\""$(doveadm_moduledir)"\" \
        -DPKG_RUNDIR=\""$(rundir)"\"
 
+if !BUILD_SHARED_LIBS
+unused_objects = \
+       ../lib/mountpoint.o \
+       ../lib-imap/imap-util.o
+endif
+
 cmd_pw_libs = \
        ../auth/libpassword.a \
        ../lib-ntlm/libntlm.a \
        ../lib-otp/libotp.a
 
-doveadm_LDADD = \
-       $(cmd_pw_libs) $(AUTH_LIBS) \
+libs = \
        $(LIBDOVECOT_STORAGE) \
+       $(cmd_pw_libs) \
+       $(unused_objects)
+
+doveadm_LDADD = \
+       $(libs) $(AUTH_LIBS) \
        $(LIBDOVECOT) \
        $(MODULE_LIBS)
 doveadm_DEPENDENCIES = \
-       $(cmd_pw_libs) \
-       $(LIBDOVECOT_STORAGE) \
+       $(libs) \
        $(LIBDOVECOT_DEPS)
 
 doveadm_SOURCES = \
@@ -38,9 +52,11 @@ doveadm_SOURCES = \
        doveadm-mail.c \
        doveadm-penalty.c \
        doveadm-pw.c \
+       doveadm-settings.c \
        doveadm-who.c
 
 noinst_HEADERS = \
        doveadm.h \
        doveadm-dump.h \
-       doveadm-mail.h
+       doveadm-mail.h \
+       doveadm-settings.h
index 1fc5b6e22d198a2febce2a73ff389ab3d2ed1f70..654aa9db9720fa0e23bf86f4cb2597c904e14cf7 100644 (file)
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "lib-signals.h"
 #include "ioloop.h"
+#include "module-dir.h"
 #include "master-service.h"
 #include "mail-user.h"
 #include "mail-namespace.h"
@@ -11,6 +12,7 @@
 #include "mail-storage-settings.h"
 #include "mail-storage-service.h"
 #include "doveadm.h"
+#include "doveadm-settings.h"
 #include "doveadm-mail.h"
 
 #include <stdio.h>
@@ -75,40 +77,11 @@ static void cmd_force_resync(struct mail_user *user, const char *args[])
        mailbox_free(&box);
 }
 
-static void
-doveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username,
-                        enum mail_storage_service_flags service_flags,
-                        const char *args[])
-{
-       struct mail_storage_service_ctx *storage_service;
-       struct mail_storage_service_user *service_user;
-       struct mail_storage_service_input input;
-       struct mail_user *mail_user;
-       const char *error;
-
-       if (username == NULL)
-               i_fatal("USER environment is missing and -u option not used");
-
-       memset(&input, 0, sizeof(input));
-       input.username = username;
-
-       storage_service = mail_storage_service_init(master_service, NULL,
-                                                   service_flags);
-       if (mail_storage_service_lookup_next(storage_service, &input,
-                                            &service_user, &mail_user,
-                                            &error) <= 0)
-               i_fatal("%s", error);
-       cmd(mail_user, args);
-       mail_user_unref(&mail_user);
-       mail_storage_service_user_free(&service_user);
-       mail_storage_service_deinit(&storage_service);
-}
-
 static int
 doveadm_mail_next_user(doveadm_mail_command_t *cmd,
                       struct mail_storage_service_ctx *storage_service,
                       const struct mail_storage_service_input *input,
-                      const char *args[])
+                      const char *args[], const char **error_r)
 {
        struct mail_storage_service_user *service_user;
        struct mail_user *mail_user;
@@ -119,24 +92,51 @@ doveadm_mail_next_user(doveadm_mail_command_t *cmd,
        ret = mail_storage_service_lookup(storage_service, input,
                                          &service_user, &error);
        if (ret <= 0) {
-               if (ret == 0) {
-                       i_info("User no longer exists, skipping");
-                       return 0;
-               } else {
-                       i_error("User lookup failed: %s", error);
-                       return -1;
+               if (ret < 0) {
+                       *error_r = t_strdup_printf("User lookup failed: %s",
+                                                  error);
                }
+               return ret;
        }
+
        if (mail_storage_service_next(storage_service, service_user,
                                      &mail_user, &error) < 0) {
-               i_error("User init failed: %s", error);
+               *error_r = t_strdup_printf("User init failed: %s", error);
                mail_storage_service_user_free(&service_user);
                return -1;
        }
+
        cmd(mail_user, args);
        mail_storage_service_user_free(&service_user);
        mail_user_unref(&mail_user);
-       return 0;
+       return 1;
+}
+
+static void
+doveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username,
+                        enum mail_storage_service_flags service_flags,
+                        const char *args[])
+{
+       struct mail_storage_service_ctx *storage_service;
+       struct mail_storage_service_input input;
+       const char *error;
+       int ret;
+
+       if (username == NULL)
+               i_fatal("USER environment is missing and -u option not used");
+
+       memset(&input, 0, sizeof(input));
+       input.username = username;
+
+       storage_service = mail_storage_service_init(master_service, NULL,
+                                                   service_flags);
+       ret = doveadm_mail_next_user(cmd, storage_service, &input,
+                                    args, &error);
+       if (ret < 0)
+               i_fatal("%s", error);
+       else if (ret == 0)
+               i_fatal("User no longer exists");
+       mail_storage_service_deinit(&storage_service);
 }
 
 static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
@@ -152,7 +152,7 @@ doveadm_mail_all_users(doveadm_mail_command_t *cmd,
        struct mail_storage_service_input input;
        struct mail_storage_service_ctx *storage_service;
        unsigned int user_idx, user_count, interval, n;
-       const char *user;
+       const char *user, *error;
        int ret;
 
        service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
@@ -177,7 +177,11 @@ doveadm_mail_all_users(doveadm_mail_command_t *cmd,
                input.username = user;
                T_BEGIN {
                        ret = doveadm_mail_next_user(cmd, storage_service,
-                                                    &input, args);
+                                                    &input, args, &error);
+                       if (ret < 0)
+                               i_error("%s", error);
+                       else if (ret == 0)
+                               i_info("User no longer exists, skipping");
                } T_END;
                if (ret < 0)
                        break;
@@ -204,7 +208,8 @@ doveadm_mail_all_users(doveadm_mail_command_t *cmd,
 static void
 doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
 {
-       enum mail_storage_service_flags service_flags = 0;
+       enum mail_storage_service_flags service_flags =
+               MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
        const char *username;
        bool all_users = FALSE;
        int c;
@@ -268,7 +273,7 @@ void doveadm_mail_usage(void)
 
 void doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
 {
-       fprintf(stderr, "doveadm %s %s\n", cmd->name,
+       fprintf(stderr, "doveadm %s <user>|-a %s\n", cmd->name,
                cmd->usage_args == NULL ? "" : cmd->usage_args);
        exit(0);
 }
@@ -290,11 +295,24 @@ static struct doveadm_mail_cmd mail_commands[] = {
 
 void doveadm_mail_init(void)
 {
+       struct module_dir_load_settings mod_set;
        unsigned int i;
 
        i_array_init(&doveadm_mail_cmds, 32);
        for (i = 0; i < N_ELEMENTS(mail_commands); i++)
                doveadm_mail_register_cmd(&mail_commands[i]);
+
+       memset(&mod_set, 0, sizeof(mod_set));
+       mod_set.version = master_service_get_version_string(master_service);
+       mod_set.require_init_funcs = TRUE;
+       mod_set.debug = doveadm_debug;
+
+       /* load all configured mail plugins */
+       mail_storage_service_modules =
+               module_dir_load_missing(mail_storage_service_modules,
+                                       doveadm_settings->mail_plugin_dir,
+                                       doveadm_settings->mail_plugins,
+                                       &mod_set);
 }
 
 void doveadm_mail_deinit(void)
diff --git a/src/doveadm/doveadm-settings.c b/src/doveadm/doveadm-settings.c
new file mode 100644 (file)
index 0000000..2b41918
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "settings-parser.h"
+#include "doveadm-settings.h"
+
+#undef DEF
+#define DEF(type, name) \
+       { type, #name, offsetof(struct doveadm_settings, name), NULL }
+
+static const struct setting_define doveadm_setting_defines[] = {
+       DEF(SET_STR, mail_plugins),
+       DEF(SET_STR, mail_plugin_dir),
+
+       SETTING_DEFINE_LIST_END
+};
+
+const struct doveadm_settings doveadm_default_settings = {
+       .mail_plugins = "",
+       .mail_plugin_dir = MODULEDIR
+};
+
+const struct setting_parser_info doveadm_setting_parser_info = {
+       .module_name = "doveadm",
+       .defines = doveadm_setting_defines,
+       .defaults = &doveadm_default_settings,
+
+       .type_offset = (size_t)-1,
+       .struct_size = sizeof(struct doveadm_settings),
+
+       .parent_offset = (size_t)-1
+};
+
+const struct doveadm_settings *doveadm_settings;
diff --git a/src/doveadm/doveadm-settings.h b/src/doveadm/doveadm-settings.h
new file mode 100644 (file)
index 0000000..8611042
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef DOVEADM_SETTINGS_H
+#define DOVEADM_SETTINGS_H
+
+struct doveadm_settings {
+       const char *mail_plugins;
+       const char *mail_plugin_dir;
+};
+
+extern const struct setting_parser_info doveadm_setting_parser_info;
+extern const struct doveadm_settings *doveadm_settings;
+
+#endif
index fc3b0bad41e10e20cab5ef93a0fbe139c1de6165..fafc97f2eca80d0ab6d901fbaba5bbd19cd6814b 100644 (file)
@@ -2,8 +2,11 @@
 
 #include "lib.h"
 #include "array.h"
+#include "module-dir.h"
 #include "master-service.h"
+#include "master-service-settings.h"
 #include "doveadm-mail.h"
+#include "doveadm-settings.h"
 #include "doveadm.h"
 
 #include <stdio.h>
@@ -13,6 +16,7 @@
 
 bool doveadm_verbose = FALSE, doveadm_debug = FALSE;
 
+static struct module *modules = NULL;
 static ARRAY_DEFINE(doveadm_cmds, struct doveadm_cmd);
 
 void doveadm_register_cmd(const struct doveadm_cmd *cmd)
@@ -83,9 +87,31 @@ static bool doveadm_try_run(const char *cmd_name, int argc, char *argv[])
        return FALSE;
 }
 
+static void doveadm_load_modules(void)
+{
+       struct module_dir_load_settings mod_set;
+
+       /* some doveadm plugins have dependencies to mail plugins. we can load
+          only those whose dependencies have been loaded earlier, the rest are
+          ignored. */
+       memset(&mod_set, 0, sizeof(mod_set));
+       mod_set.version = master_service_get_version_string(master_service);
+       mod_set.require_init_funcs = TRUE;
+       mod_set.debug = doveadm_debug;
+       mod_set.ignore_dlopen_errors = TRUE;
+
+       modules = module_dir_load_missing(modules, DOVEADM_MODULEDIR,
+                                         NULL, &mod_set);
+       module_dir_init(modules);
+}
+
 int main(int argc, char *argv[])
 {
-       const char *cmd_name;
+       const struct setting_parser_info *set_roots[] = {
+               &doveadm_setting_parser_info,
+               NULL
+       };
+       const char *cmd_name, *error;
        int c;
 
        /* "+" is GNU extension to stop at the first non-option.
@@ -93,16 +119,6 @@ int main(int argc, char *argv[])
        master_service = master_service_init("doveadm",
                                             MASTER_SERVICE_FLAG_STANDALONE,
                                             &argc, &argv, "+Dv");
-       i_array_init(&doveadm_cmds, 32);
-       doveadm_mail_init();
-       doveadm_register_cmd(&doveadm_cmd_help);
-       doveadm_register_cmd(&doveadm_cmd_auth);
-       doveadm_register_cmd(&doveadm_cmd_user);
-       doveadm_register_cmd(&doveadm_cmd_dump);
-       doveadm_register_cmd(&doveadm_cmd_pw);
-       doveadm_register_cmd(&doveadm_cmd_who);
-       doveadm_register_cmd(&doveadm_cmd_penalty);
-
        while ((c = master_getopt(master_service)) > 0) {
                switch (c) {
                case 'D':
@@ -116,6 +132,23 @@ int main(int argc, char *argv[])
                        return FATAL_DEFAULT;
                }
        }
+
+       if (master_service_settings_read_simple(master_service, set_roots,
+                                               &error) < 0)
+               i_fatal("Error reading configuration: %s", error);
+       doveadm_settings = master_service_settings_get_others(master_service)[0];
+
+       i_array_init(&doveadm_cmds, 32);
+       doveadm_register_cmd(&doveadm_cmd_help);
+       doveadm_register_cmd(&doveadm_cmd_auth);
+       doveadm_register_cmd(&doveadm_cmd_user);
+       doveadm_register_cmd(&doveadm_cmd_dump);
+       doveadm_register_cmd(&doveadm_cmd_pw);
+       doveadm_register_cmd(&doveadm_cmd_who);
+       doveadm_register_cmd(&doveadm_cmd_penalty);
+       doveadm_mail_init();
+       doveadm_load_modules();
+
        if (optind == argc)
                usage();
 
@@ -129,8 +162,9 @@ int main(int argc, char *argv[])
            !doveadm_mail_try_run(cmd_name, argc, argv))
                usage();
 
-       master_service_deinit(&master_service);
        doveadm_mail_deinit();
+       module_dir_unload(&modules);
        array_free(&doveadm_cmds);
+       master_service_deinit(&master_service);
        return 0;
 }