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