summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/plugin_loader.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2014-03-11 20:48:48 +0100
committerYves-Alexis Perez <corsac@debian.org>2014-03-11 20:48:48 +0100
commit15fb7904f4431a6e7c305fd08732458f7f885e7e (patch)
treec93b60ee813af70509f00f34e29ebec311762427 /src/libstrongswan/plugins/plugin_loader.c
parent5313d2d78ca150515f7f5eb39801c100690b6b29 (diff)
downloadvyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.tar.gz
vyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.zip
Imported Upstream version 5.1.2
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c158
1 files changed, 155 insertions, 3 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 5ed0a9b0f..08a8442ea 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Tobias Brunner
+ * Copyright (C) 2010-2014 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -28,6 +28,7 @@
#include <utils/debug.h>
#include <library.h>
#include <collections/hashtable.h>
+#include <collections/array.h>
#include <collections/linked_list.h>
#include <plugins/plugin.h>
#include <utils/integrity_checker.h>
@@ -936,18 +937,146 @@ static bool find_plugin(char *path, char *name, char *buf, char **file)
return FALSE;
}
+/**
+ * Used to sort plugins by priority
+ */
+typedef struct {
+ /* name of the plugin */
+ char *name;
+ /* the plugins priority */
+ int prio;
+ /* default priority */
+ int def;
+} plugin_priority_t;
+
+static void plugin_priority_free(const plugin_priority_t *this, int idx,
+ void *user)
+{
+ free(this->name);
+}
+
+/**
+ * Sort plugins and their priority by name
+ */
+static int plugin_priority_cmp_name(const plugin_priority_t *a,
+ const plugin_priority_t *b)
+{
+ return strcmp(a->name, b->name);
+}
+
+/**
+ * Sort plugins by decreasing priority or default priority then by name
+ */
+static int plugin_priority_cmp(const plugin_priority_t *a,
+ const plugin_priority_t *b, void *user)
+{
+ int diff;
+
+ diff = b->prio - a->prio;
+ if (!diff)
+ { /* the same priority, use default order */
+ diff = b->def - a->def;
+ if (!diff)
+ { /* same default priority (i.e. both were not found in that list) */
+ return strcmp(a->name, b->name);
+ }
+ }
+ return diff;
+}
+
+
+/**
+ * Determine the list of plugins to load via load option in each plugin's
+ * config section.
+ */
+static char *modular_pluginlist(char *list)
+{
+ enumerator_t *enumerator;
+ array_t *given, *final;
+ plugin_priority_t item, *current, found;
+ char *plugin, *plugins = NULL;
+ int i = 0, max_prio;
+
+ if (!lib->settings->get_bool(lib->settings, "%s.load_modular", FALSE,
+ lib->ns))
+ {
+ return list;
+ }
+
+ given = array_create(sizeof(plugin_priority_t), 0);
+ final = array_create(sizeof(plugin_priority_t), 0);
+
+ enumerator = enumerator_create_token(list, " ", " ");
+ while (enumerator->enumerate(enumerator, &plugin))
+ {
+ item.name = strdup(plugin);
+ item.prio = i++;
+ array_insert(given, ARRAY_TAIL, &item);
+ }
+ enumerator->destroy(enumerator);
+ array_sort(given, (void*)plugin_priority_cmp_name, NULL);
+ /* the maximum priority used for plugins not found in this list */
+ max_prio = i + 1;
+
+ enumerator = lib->settings->create_section_enumerator(lib->settings,
+ "%s.plugins", lib->ns);
+ while (enumerator->enumerate(enumerator, &plugin))
+ {
+ item.prio = lib->settings->get_int(lib->settings,
+ "%s.plugins.%s.load", 0, lib->ns, plugin);
+ if (!item.prio)
+ {
+ if (!lib->settings->get_bool(lib->settings,
+ "%s.plugins.%s.load", FALSE, lib->ns, plugin))
+ {
+ continue;
+ }
+ item.prio = 1;
+ }
+ item.name = plugin;
+ item.def = max_prio;
+ if (array_bsearch(given, &item, (void*)plugin_priority_cmp_name,
+ &found) != -1)
+ {
+ item.def = max_prio - found.prio;
+ }
+ array_insert(final, ARRAY_TAIL, &item);
+ }
+ enumerator->destroy(enumerator);
+ array_destroy_function(given, (void*)plugin_priority_free, NULL);
+
+ array_sort(final, (void*)plugin_priority_cmp, NULL);
+
+ enumerator = array_create_enumerator(final);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ char *prev = plugins;
+ if (asprintf(&plugins, "%s %s", plugins ?: "", current->name) < 0)
+ {
+ plugins = prev;
+ break;
+ }
+ free(prev);
+ }
+ enumerator->destroy(enumerator);
+ array_destroy(final);
+ return plugins;
+}
+
METHOD(plugin_loader_t, load_plugins, bool,
private_plugin_loader_t *this, char *list)
{
enumerator_t *enumerator;
- char *default_path = NULL, *token;
+ char *default_path = NULL, *plugins, *token;
bool critical_failed = FALSE;
#ifdef PLUGINDIR
default_path = PLUGINDIR;
#endif /* PLUGINDIR */
- enumerator = enumerator_create_token(list, " ", " ");
+ plugins = modular_pluginlist(list);
+
+ enumerator = enumerator_create_token(plugins, " ", " ");
while (!critical_failed && enumerator->enumerate(enumerator, &token))
{
plugin_entry_t *entry;
@@ -1006,6 +1135,10 @@ METHOD(plugin_loader_t, load_plugins, bool,
free(this->loaded_plugins);
this->loaded_plugins = loaded_plugins_list(this);
}
+ if (plugins != list)
+ {
+ free(plugins);
+ }
return !critical_failed;
}
@@ -1170,3 +1303,22 @@ plugin_loader_t *plugin_loader_create()
return &this->public;
}
+
+/*
+ * See header
+ */
+void plugin_loader_add_plugindirs(char *basedir, char *plugins)
+{
+ enumerator_t *enumerator;
+ char *name, path[PATH_MAX], dir[64];
+
+ enumerator = enumerator_create_token(plugins, " ", "");
+ while (enumerator->enumerate(enumerator, &name))
+ {
+ snprintf(dir, sizeof(dir), "%s", name);
+ translate(dir, "-", "_");
+ snprintf(path, sizeof(path), "%s/%s/.libs", basedir, dir);
+ lib->plugins->add_path(lib->plugins, path);
+ }
+ enumerator->destroy(enumerator);
+}