dovecot-2.0: Added module_dir_load_missing() and module_get_plug...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Dec 7 21:45:57 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/f0a6461b86ee
changeset: 10416:f0a6461b86ee
user: Timo Sirainen <tss at iki.fi>
date: Mon Dec 07 14:42:57 2009 -0500
description:
Added module_dir_load_missing() and module_get_plugin_name().
diffstat:
2 files changed, 71 insertions(+), 31 deletions(-)
src/lib/module-dir.c | 93 +++++++++++++++++++++++++++++++++-----------------
src/lib/module-dir.h | 9 ++++
diffs (199 lines):
diff -r 3662241f75f2 -r f0a6461b86ee src/lib/module-dir.c
--- a/src/lib/module-dir.c Mon Dec 07 13:34:35 2009 -0500
+++ b/src/lib/module-dir.c Mon Dec 07 14:42:57 2009 -0500
@@ -185,17 +185,27 @@ static int module_name_cmp(const char *c
return strcmp(s1, s2);
}
-static bool module_want_load(const char **names, const char *name)
-{
- size_t len;
-
- if (names == NULL)
- return TRUE;
+static const char *module_name_drop_suffix(const char *name)
+{
+ unsigned int len;
len = strlen(name);
if (len > 7 && strcmp(name + len - 7, "_plugin") == 0)
name = t_strndup(name, len - 7);
-
+ return name;
+}
+
+const char *module_get_plugin_name(struct module *module)
+{
+ return module_name_drop_suffix(module->name);
+}
+
+static bool module_want_load(const char **names, const char *name)
+{
+ if (names == NULL)
+ return TRUE;
+
+ name = module_name_drop_suffix(name);
for (; *names != NULL; names++) {
if (strcmp(*names, name) == 0) {
*names = "";
@@ -222,14 +232,25 @@ static void check_duplicates(ARRAY_TYPE(
}
}
+static bool module_is_loaded(struct module *modules, const char *name)
+{
+ struct module *module;
+
+ for (module = modules; module != NULL; module = module->next) {
+ if (strcmp(module->name, name) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
static struct module *
-module_dir_load_real(const char *dir, const char *module_names,
+module_dir_load_real(struct module *old_modules,
+ const char *dir, const char **module_names,
bool require_init_funcs, const char *version)
{
DIR *dirp;
struct dirent *d;
const char *name, *p, *const *names_p;
- const char **module_names_arr;
struct module *modules, *module, **module_pos;
unsigned int i, count;
ARRAY_TYPE(const_string) names;
@@ -275,32 +296,31 @@ module_dir_load_real(const char *dir, co
array_sort(&names, module_name_cmp);
names_p = array_get(&names, &count);
- if (module_names == NULL)
- module_names_arr = NULL;
- else {
- module_names_arr = t_strsplit_spaces(module_names, ", ");
+ if (module_names != NULL) {
/* allow giving the module names also in non-base form.
convert them in here. */
- for (i = 0; module_names_arr[i] != NULL; i++) {
- module_names_arr[i] =
- module_file_get_name(module_names_arr[i]);
- }
- }
-
+ for (i = 0; module_names[i] != NULL; i++)
+ module_names[i] = module_file_get_name(module_names[i]);
+ }
+
+ modules = old_modules;
module_pos = &modules;
+ while (*module_pos != NULL)
+ module_pos = &(*module_pos)->next;
for (i = 0; i < count; i++) T_BEGIN {
const char *path, *stripped_name;
name = names_p[i];
stripped_name = module_file_get_name(name);
- if (!module_want_load(module_names_arr, stripped_name))
+ if (!module_want_load(module_names, stripped_name) ||
+ module_is_loaded(old_modules, stripped_name))
module = NULL;
else {
path = t_strconcat(dir, "/", name, NULL);
module = module_load(path, stripped_name,
require_init_funcs, version,
modules);
- if (module == NULL && module_names_arr != NULL)
+ if (module == NULL && module_names != NULL)
i_fatal("Couldn't load required plugins");
}
@@ -310,12 +330,12 @@ module_dir_load_real(const char *dir, co
}
} T_END;
- if (module_names_arr != NULL) {
+ if (module_names != NULL) {
/* make sure all modules were found */
- for (; *module_names_arr != NULL; module_names_arr++) {
- if (**module_names_arr != '\0') {
+ for (; *module_names != NULL; module_names++) {
+ if (**module_names != '\0') {
i_fatal("Plugin %s not found from directory %s",
- *module_names_arr, dir);
+ *module_names, dir);
}
}
}
@@ -330,10 +350,22 @@ struct module *module_dir_load(const cha
struct module *module_dir_load(const char *dir, const char *module_names,
bool require_init_funcs, const char *version)
{
+ return module_dir_load_missing(NULL, dir, module_names,
+ require_init_funcs, version);
+}
+
+struct module *
+module_dir_load_missing(struct module *old_modules,
+ const char *dir, const char *module_names,
+ bool require_init_funcs, const char *version)
+{
struct module *modules;
T_BEGIN {
- modules = module_dir_load_real(dir, module_names,
+ const char **arr = module_names == NULL ? NULL :
+ t_strsplit_spaces(module_names, ", ");
+
+ modules = module_dir_load_real(old_modules, dir, arr,
require_init_funcs, version);
} T_END;
return modules;
@@ -344,11 +376,10 @@ void module_dir_init(struct module *modu
struct module *module;
for (module = modules; module != NULL; module = module->next) {
- if (module->init != NULL) {
- T_BEGIN {
- module->init(module);
- } T_END;
- }
+ if (module->init != NULL && !module->initialized) T_BEGIN {
+ module->initialized = TRUE;
+ module->init(module);
+ } T_END;
}
}
diff -r 3662241f75f2 -r f0a6461b86ee src/lib/module-dir.h
--- a/src/lib/module-dir.h Mon Dec 07 13:34:35 2009 -0500
+++ b/src/lib/module-dir.h Mon Dec 07 14:42:57 2009 -0500
@@ -8,6 +8,8 @@ struct module {
void (*init)(struct module *module);
void (*deinit)(void);
+ unsigned int initialized:1;
+
struct module *next;
};
@@ -16,6 +18,11 @@ struct module {
the module contains a version symbol, fail the load if they're different. */
struct module *module_dir_load(const char *dir, const char *module_names,
bool require_init_funcs, const char *version);
+/* Load modules that aren't already loaded. */
+struct module *
+module_dir_load_missing(struct module *old_modules,
+ const char *dir, const char *module_names,
+ bool require_init_funcs, const char *version);
/* Call init() in all modules */
void module_dir_init(struct module *modules);
/* Call deinit() in all modules and mark them NULL so module_dir_unload()
@@ -29,5 +36,7 @@ void *module_get_symbol_quiet(struct mod
/* Returns module's base name from the filename. */
const char *module_file_get_name(const char *fname);
+/* Returns module's name without "_plugin" suffix. */
+const char *module_get_plugin_name(struct module *module);
#endif
More information about the dovecot-cvs
mailing list