Mercurial > dovecot > core-2.2
changeset 11748:10ff5c7e7f40 HEAD
module_dir_load(): Added support for checking binary name dependency.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 07 Jul 2010 15:18:46 +0100 |
parents | 4db258f7ce91 |
children | c53fb625b07e |
files | src/lib/module-dir.c src/lib/module-dir.h |
diffstat | 2 files changed, 41 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/module-dir.c Wed Jul 07 14:58:05 2010 +0100 +++ b/src/lib/module-dir.c Wed Jul 07 15:18:46 2010 +0100 @@ -67,8 +67,29 @@ } static bool -module_check_missing_dependencies(struct module *module, - struct module *all_modules) +module_check_wrong_binary_dependency(const struct module_dir_load_settings *set, + struct module *module) +{ + const char *symbol_name, *binary_dep; + + symbol_name = t_strconcat(module->name, "_binary_dependency", NULL); + binary_dep = dlsym(module->handle, symbol_name); + if (binary_dep == NULL) + return TRUE; + + if (set->binary_name == NULL || + strcmp(binary_dep, set->binary_name) == 0) + return TRUE; + + i_error("Can't load plugin %s: " + "Plugin is intended to be used only by %s binary (we're %s)", + module->name, binary_dep, set->binary_name); + return FALSE; +} + +static bool +module_check_missing_plugin_dependencies(struct module *module, + struct module *all_modules) { const char **deps; struct module *m; @@ -134,6 +155,7 @@ void *handle; struct module *module; const char *const *module_version; + bool failed = FALSE; if (set->ignore_dlopen_errors) { handle = quiet_dlopen(path, RTLD_GLOBAL | RTLD_NOW); @@ -143,7 +165,16 @@ handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); if (handle == NULL) { i_error("dlopen(%s) failed: %s", path, dlerror()); +#ifdef RTLD_LAZY + failed = TRUE; + /* try to give a better error message by lazily loading + the plugin and checking its dependencies */ + handle = dlopen(path, RTLD_LAZY); + if (handle == NULL) + return NULL; +#else return NULL; +#endif } } @@ -174,12 +205,12 @@ set->require_init_funcs) { i_error("Module doesn't have %s function: %s", module->init == NULL ? "init" : "deinit", path); - module->deinit = NULL; - module_free(module); - return NULL; - } + failed = TRUE; + } else if (!module_check_wrong_binary_dependency(set, module) || + !module_check_missing_plugin_dependencies(module, all_modules)) + failed = TRUE; - if (!module_check_missing_dependencies(module, all_modules)) { + if (failed) { module->deinit = NULL; module_free(module); return NULL;
--- a/src/lib/module-dir.h Wed Jul 07 14:58:05 2010 +0100 +++ b/src/lib/module-dir.h Wed Jul 07 15:18:46 2010 +0100 @@ -5,6 +5,9 @@ /* If version is non-NULL and the module contains a version symbol, fail the load if they're different. */ const char *version; + /* Binary name used for checking if plugin is tried to be loaded for + wrong binary. */ + const char *binary_name; /* Require all plugins to have <plugin_name>_init() function */ unsigned int require_init_funcs:1;