diff options
Diffstat (limited to 'protocols/nogaim.c')
-rw-r--r-- | protocols/nogaim.c | 67 |
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; |