diff options
| -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);  } | 
