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; | 
