diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/nogaim.c | 67 | ||||
| -rw-r--r-- | protocols/nogaim.h | 14 | ||||
| -rw-r--r-- | protocols/skype/skype.c | 14 | 
3 files changed, 94 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; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 40b1ed7b..f5b1f212 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -270,6 +270,20 @@ struct prpl {  	void *resv5;  }; +struct plugin_info +{ +	guint abiver; +	const char *name; +	const char *version; +	const char *description; +	const char *author; +	const char *url; +}; + +#ifdef WITH_PLUGINS +G_MODULE_EXPORT GList *get_plugins(); +#endif +  /* im_api core stuff. */  void nogaim_init();  G_MODULE_EXPORT GSList *get_connections(); diff --git a/protocols/skype/skype.c b/protocols/skype/skype.c index a21af8ef..bd8a1850 100644 --- a/protocols/skype/skype.c +++ b/protocols/skype/skype.c @@ -1762,3 +1762,17 @@ void init_plugin(void)  #endif  	register_protocol(ret);  } + +struct plugin_info *init_plugin_info(void) +{ +	static struct plugin_info info = { +		BITLBEE_ABI_VERSION_CODE, +		"skype", +		BITLBEE_VERSION, +		"Skype protocol plugin", +		NULL, +		NULL +	}; + +	return &info; +} | 
