diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-03-11 20:17:20 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-03-11 20:17:20 +0000 |
commit | d95d0269d8276d311650e1726aceeafbd8116c34 (patch) | |
tree | 2e96f0b4b30eb31d292e8d528d257a430f8dd2cc /hcid | |
parent | 181a211db506940ebdc18ee8707d85da6561f79e (diff) |
Add plugin loading support
Diffstat (limited to 'hcid')
-rw-r--r-- | hcid/plugin.c | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/hcid/plugin.c b/hcid/plugin.c index 32306a2c..46046116 100644 --- a/hcid/plugin.c +++ b/hcid/plugin.c @@ -26,14 +26,105 @@ #endif #include <glib.h> +#include <gmodule.h> #include "plugin.h" +#include "logging.h" + +static GSList *plugins = NULL; + +struct bluetooth_plugin { + GModule *module; + struct bluetooth_plugin_desc *desc; +}; + +static gboolean add_plugin(GModule *module, struct bluetooth_plugin_desc *desc) +{ + struct bluetooth_plugin *plugin; + + plugin = g_try_new0(struct bluetooth_plugin, 1); + if (plugin == NULL) + return FALSE; + + plugin->module = module; + plugin->desc = desc; + + plugins = g_slist_append(plugins, plugin); + + desc->init(); + + return TRUE; +} gboolean plugin_init(void) { - return FALSE; + GDir *dir; + const gchar *file; + gchar *filename; + + debug("Loading plugins"); + + dir = g_dir_open(PLUGINDIR, 0, NULL); + if (dir != NULL) { + while ((file = g_dir_read_name(dir)) != NULL) { + GModule *module; + struct bluetooth_plugin_desc *desc; + + if (g_str_has_prefix(file, "lib") == FALSE) + continue; + + filename = g_build_filename(PLUGINDIR, file, NULL); + + module = g_module_open(filename, 0); + if (module == NULL) { + error("Can't load plugin %s", filename); + continue; + } + + g_free(filename); + + debug("%s", g_module_name(module)); + + if (g_module_symbol(module, "bluetooth_plugin_desc", + (gpointer) &desc) == FALSE) { + error("Can't load plugin description"); + g_module_close(module); + continue; + } + + if (desc == NULL || desc->init == NULL) { + g_module_close(module); + continue; + } + + if (add_plugin(module, desc) == FALSE) + g_module_close(module); + } + + g_dir_close(dir); + } + + return TRUE; } void plugin_cleanup(void) { + GSList *list; + + debug("Cleanup plugins"); + + for (list = plugins; list; list = list->next) { + struct bluetooth_plugin *plugin = list->data; + + debug("%s", g_module_name(plugin->module)); + + if (plugin->desc->exit) + plugin->desc->exit(); + + g_module_close(plugin->module); + + g_free(plugin); + } + + g_slist_free(plugins); } |