diff options
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 459ba9ba9..d4513f25a 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -37,12 +37,12 @@ struct private_plugin_loader_t { * public functions */ plugin_loader_t public; - + /** * list of loaded plugins */ linked_list_t *plugins; - + /** * names of loaded plugins */ @@ -59,9 +59,9 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, void *handle; plugin_t *plugin; plugin_constructor_t constructor; - + snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, name); - + if (lib->integrity) { if (!lib->integrity->check_file(lib->integrity, name, file)) @@ -101,7 +101,7 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, return NULL; } DBG2("plugin '%s': loaded successfully", name); - + /* we do not store or free dlopen() handles, leak_detective requires * the modules to keep loaded until leak report */ return plugin; @@ -110,26 +110,50 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, /** * Implementation of plugin_loader_t.load_plugins. */ -static int load(private_plugin_loader_t *this, char *path, char *list) +static bool load(private_plugin_loader_t *this, char *path, char *list) { - plugin_t *plugin; enumerator_t *enumerator; char *token; - int count = 0; - + bool critical_failed = FALSE; + + if (path == NULL) + { + path = PLUGINDIR; + } + enumerator = enumerator_create_token(list, " ", " "); - while (enumerator->enumerate(enumerator, &token)) + while (!critical_failed && enumerator->enumerate(enumerator, &token)) { + plugin_t *plugin; + bool critical = FALSE; + int len; + + token = strdup(token); + len = strlen(token); + if (token[len-1] == '!') + { + critical = TRUE; + token[len-1] = '\0'; + } plugin = load_plugin(this, path, token); if (plugin) - { /* insert in front to destroy them in reverse order */ + { + /* insert in front to destroy them in reverse order */ this->plugins->insert_last(this->plugins, plugin); - this->names->insert_last(this->names, strdup(token)); - count++; + this->names->insert_last(this->names, token); + } + else + { + if (critical) + { + critical_failed = TRUE; + DBG1("loading critical plugin '%s' failed", token); + } + free(token); } } enumerator->destroy(enumerator); - return count; + return !critical_failed; } /** @@ -139,7 +163,7 @@ static void unload(private_plugin_loader_t *this) { plugin_t *plugin; char *name; - + while (this->plugins->remove_first(this->plugins, (void**)&plugin) == SUCCESS) { @@ -157,7 +181,7 @@ static void unload(private_plugin_loader_t *this) static enumerator_t* create_plugin_enumerator(private_plugin_loader_t *this) { return this->names->create_enumerator(this->names); -} +} /** * Implementation of plugin_loader_t.destroy @@ -175,15 +199,15 @@ static void destroy(private_plugin_loader_t *this) plugin_loader_t *plugin_loader_create() { private_plugin_loader_t *this = malloc_thing(private_plugin_loader_t); - - this->public.load = (int(*)(plugin_loader_t*, char *path, char *prefix))load; + + this->public.load = (bool(*)(plugin_loader_t*, char *path, char *prefix))load; this->public.unload = (void(*)(plugin_loader_t*))unload; this->public.create_plugin_enumerator = (enumerator_t*(*)(plugin_loader_t*))create_plugin_enumerator; this->public.destroy = (void(*)(plugin_loader_t*))destroy; - + this->plugins = linked_list_create(); this->names = linked_list_create(); - + return &this->public; } |