aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/plugins/plugin_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c119
1 files changed, 74 insertions, 45 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 3ed30c572..5734c9092 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -17,7 +17,11 @@
#include "plugin_loader.h"
+#define _GNU_SOURCE
+#include <string.h>
#include <dlfcn.h>
+#include <limits.h>
+#include <stdio.h>
#include <debug.h>
#include <utils/linked_list.h>
@@ -42,68 +46,92 @@ struct private_plugin_loader_t {
};
/**
- * Implementation of plugin_loader_t.load_plugins.
+ * load a single plugin
*/
-static int load(private_plugin_loader_t *this, char *path, char *prefix)
+static plugin_t* load_plugin(private_plugin_loader_t *this,
+ char *path, char *name)
{
- enumerator_t *enumerator;
- char *file, *ending, *rel;
+ char file[PATH_MAX];
void *handle;
- int count = 0;
+ plugin_t *plugin;
+ plugin_constructor_t constructor;
- enumerator = enumerator_create_directory(path);
- if (!enumerator)
+ snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, name);
+
+ handle = dlopen(file, RTLD_LAZY);
+ if (handle == NULL)
{
- DBG1("opening plugin directory %s failed", path);
- return 0;
+ DBG1("loading plugin '%s' failed: %s", name, dlerror());
+ return NULL;
}
- DBG2("loading plugins from %s", path);
- while (enumerator->enumerate(enumerator, &rel, &file, NULL))
+ constructor = dlsym(handle, "plugin_create");
+ if (constructor == NULL)
{
- plugin_t *plugin;
- plugin_constructor_t constructor;
-
- ending = file + strlen(file) - 3;
- if (ending <= file || !streq(ending, ".so"))
- { /* only process .so libraries */
- continue;
- }
- if (!strneq(prefix, rel, strlen(prefix)))
- {
- continue;
- }
- handle = dlopen(file, RTLD_LAZY);
- if (handle == NULL)
+ DBG1("loading plugin '%s' failed: no plugin_create() function", name);
+ dlclose(handle);
+ return NULL;
+ }
+ plugin = constructor();
+ if (plugin == NULL)
+ {
+ DBG1("loading plugin '%s' failed: plugin_create() returned NULL", name);
+ dlclose(handle);
+ 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;
+}
+
+/**
+ * Implementation of plugin_loader_t.load_plugins.
+ */
+static int load(private_plugin_loader_t *this, char *path, char *list)
+{
+ plugin_t *plugin;
+ char *pos;
+ int count = 0;
+
+ list = strdupa(list);
+ while (TRUE)
+ {
+ pos = strchr(list, ' ');
+ if (pos)
{
- DBG1("loading plugin %s failed: %s", rel, dlerror());
- continue;
+ *pos = '\0';
}
- constructor = dlsym(handle, "plugin_create");
- if (constructor == NULL)
- {
- DBG1("plugin %s has no plugin_create() function, skipped", rel);
- dlclose(handle);
- continue;
+ plugin = load_plugin(this, path, list);
+ if (plugin)
+ { /* insert in front to destroy them in reverse order */
+ this->plugins->insert_last(this->plugins, plugin);
+ count++;
}
- plugin = constructor();
- if (plugin == NULL)
+ if (!pos)
{
- DBG1("plugin %s constructor failed, skipping", rel);
- dlclose(handle);
- continue;
+ break;
}
- DBG2("plugin %s loaded successfully", rel);
- /* insert in front to destroy them in reverse order */
- this->plugins->insert_last(this->plugins, plugin);
- /* we do not store or free dlopen() handles, leak_detective requires
- * the modules to keep loaded until leak report */
- count++;
+ list = pos + 1;
}
- enumerator->destroy(enumerator);
return count;
}
/**
+ * Implementation of plugin_loader_t.unload
+ */
+static void unload(private_plugin_loader_t *this)
+{
+ plugin_t *plugin;
+
+ while (this->plugins->remove_first(this->plugins,
+ (void**)&plugin) == SUCCESS)
+ {
+ plugin->destroy(plugin);
+ }
+}
+
+/**
* Implementation of plugin_loader_t.destroy
*/
static void destroy(private_plugin_loader_t *this)
@@ -120,6 +148,7 @@ 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.unload = (void(*)(plugin_loader_t*))unload;
this->public.destroy = (void(*)(plugin_loader_t*))destroy;
this->plugins = linked_list_create();