aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/nogaim.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/nogaim.c')
-rw-r--r--protocols/nogaim.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index c9cbb033..9ed3b64b 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -39,24 +39,84 @@
GSList *connections;
#ifdef WITH_PLUGINS
+GList *plugins = NULL;
+
+static gint pluginscmp(gconstpointer a, gconstpointer b, gpointer data)
+{
+ const struct plugin_info *ia = a;
+ const struct plugin_info *ib = b;
+
+ return g_strcasecmp(ia->name, ib->name);
+}
+
gboolean load_plugin(char *path)
{
+ GList *l;
+ struct plugin_info *i;
+ struct plugin_info *info;
+ struct plugin_info * (*info_function) (void) = NULL;
void (*init_function) (void);
GModule *mod = g_module_open(path, G_MODULE_BIND_LAZY);
+ gboolean loaded = FALSE;
if (!mod) {
log_message(LOGLVL_ERROR, "Error loading plugin `%s': %s\n", path, g_module_error());
return FALSE;
}
+ if (g_module_symbol(mod, "init_plugin_info", (gpointer *) &info_function)) {
+ info = info_function();
+
+ if (info->abiver != BITLBEE_ABI_VERSION_CODE) {
+ log_message(LOGLVL_ERROR,
+ "`%s' uses ABI %u but %u is required\n",
+ path, info->abiver,
+ BITLBEE_ABI_VERSION_CODE);
+ g_module_close(mod);
+ return FALSE;
+ }
+
+ if (!info->name || !info->version) {
+ log_message(LOGLVL_ERROR,
+ "Name or version missing from the "
+ "plugin info in `%s'\n", path);
+ g_module_close(mod);
+ return FALSE;
+ }
+
+ for (l = plugins; l; l = l->next) {
+ i = l->data;
+
+ if (g_strcasecmp(i->name, info->name) == 0) {
+ loaded = TRUE;
+ break;
+ }
+ }
+
+ if (loaded) {
+ log_message(LOGLVL_WARNING,
+ "%s plugin already loaded\n",
+ info->name);
+ g_module_close(mod);
+ return FALSE;
+ }
+ } else {
+ log_message(LOGLVL_WARNING, "Can't find function `init_plugin_info' in `%s'\n", path);
+ }
+
if (!g_module_symbol(mod, "init_plugin", (gpointer *) &init_function)) {
log_message(LOGLVL_WARNING, "Can't find function `init_plugin' in `%s'\n", path);
+ g_module_close(mod);
return FALSE;
}
- init_function();
+ if (info_function) {
+ plugins = g_list_insert_sorted_with_data(plugins, info,
+ pluginscmp, NULL);
+ }
+ init_function();
return TRUE;
}
@@ -86,6 +146,11 @@ void load_plugins(void)
g_dir_close(dir);
}
}
+
+GList *get_plugins()
+{
+ return plugins;
+}
#endif
GList *protocols = NULL;