Mercurial > pidgin
diff libpurple/plugin.c @ 21269:68d6de0845f9
propagate from branch 'im.pidgin.charkins.dockletgeom' (head 0a163d30bd4e04f722543b3868eb2d934e5e1db8)
to branch 'im.pidgin.pidgin.next.minor' (head f286d10af3621cf62257f54718ae194d75be1916)
author | Casey Harkins <charkins@pidgin.im> |
---|---|
date | Sun, 28 Oct 2007 17:16:42 +0000 |
parents | fb8f9bf86315 |
children | 166b7949be3d |
line wrap: on
line diff
--- a/libpurple/plugin.c Sun Oct 28 17:08:49 2007 +0000 +++ b/libpurple/plugin.c Sun Oct 28 17:16:42 2007 +0000 @@ -58,13 +58,9 @@ #ifdef PURPLE_PLUGINS static GList *load_queue = NULL; static GList *plugin_loaders = NULL; +static GList *plugins_to_disable = NULL; #endif -/* - * TODO: I think the intention was to allow multiple load and unload - * callback functions. Perhaps using a GList instead of a - * pointer to a single function. - */ static void (*probe_cb)(void *) = NULL; static void *probe_cb_data = NULL; static void (*load_cb)(PurplePlugin *, void *) = NULL; @@ -254,7 +250,6 @@ * plugins being added to the global name space. * * G_MODULE_BIND_LOCAL was added in glib 2.3.3. - * TODO: I guess there's nothing we can do about that? */ #if GLIB_CHECK_VERSION(2,3,3) plugin->handle = g_module_open(filename, G_MODULE_BIND_LOCAL); @@ -625,7 +620,6 @@ plugin->loaded = TRUE; - /* TODO */ if (load_cb != NULL) load_cb(plugin, load_cb_data); @@ -643,43 +637,37 @@ { #ifdef PURPLE_PLUGINS GList *l; + GList *ll; g_return_val_if_fail(plugin != NULL, FALSE); - - loaded_plugins = g_list_remove(loaded_plugins, plugin); - if ((plugin->info != NULL) && PURPLE_IS_PROTOCOL_PLUGIN(plugin)) - protocol_plugins = g_list_remove(protocol_plugins, plugin); - g_return_val_if_fail(purple_plugin_is_loaded(plugin), FALSE); purple_debug_info("plugins", "Unloading plugin %s\n", plugin->info->name); - /* cancel any pending dialogs the plugin has */ - purple_request_close_with_handle(plugin); - purple_notify_close_with_handle(plugin); - - plugin->loaded = FALSE; - /* Unload all plugins that depend on this plugin. */ - while ((l = plugin->dependent_plugins) != NULL) - { + for (l = plugin->dependent_plugins; l != NULL; l = ll) { const char * dep_name = (const char *)l->data; PurplePlugin *dep_plugin; + /* Store a pointer to the next element in the list. + * This is because we'll be modifying this list in the loop. */ + ll = l->next; + dep_plugin = purple_plugins_find_with_id(dep_name); if (dep_plugin != NULL && purple_plugin_is_loaded(dep_plugin)) { if (!purple_plugin_unload(dep_plugin)) { - char *tmp; - - tmp = g_strdup_printf(_("The dependent plugin %s failed to unload."), - _(dep_plugin->info->name)); - - purple_notify_error(NULL, NULL, - _("There were errors unloading the plugin."), tmp); - g_free(tmp); + g_free(plugin->error); + plugin->error = g_strdup_printf(_("%s requires %s, but it failed to unload."), + _(plugin->info->name), + _(dep_plugin->info->name)); + return FALSE; + } + else + { + plugin->dependent_plugins = g_list_delete_link(plugin->dependent_plugins, l); } } } @@ -699,8 +687,8 @@ } if (plugin->native_plugin) { - if (plugin->info->unload != NULL) - plugin->info->unload(plugin); + if (plugin->info->unload && !plugin->info->unload(plugin)) + return FALSE; if (plugin->info->type == PURPLE_PLUGIN_PROTOCOL) { PurplePluginProtocolInfo *prpl_info; @@ -724,8 +712,7 @@ prpl_info->protocol_options = NULL; } } - } - else { + } else { PurplePlugin *loader; PurplePluginLoaderInfo *loader_info; @@ -736,14 +723,30 @@ loader_info = PURPLE_PLUGIN_LOADER_INFO(loader); - if (loader_info->unload != NULL) - loader_info->unload(plugin); + if (loader_info->unload && !loader_info->unload(plugin)) + return FALSE; } + /* cancel any pending dialogs the plugin has */ + purple_request_close_with_handle(plugin); + purple_notify_close_with_handle(plugin); + purple_signals_disconnect_by_handle(plugin); purple_plugin_ipc_unregister_all(plugin); - /* TODO */ + loaded_plugins = g_list_remove(loaded_plugins, plugin); + if ((plugin->info != NULL) && PURPLE_IS_PROTOCOL_PLUGIN(plugin)) + protocol_plugins = g_list_remove(protocol_plugins, plugin); + plugins_to_disable = g_list_remove(plugins_to_disable, plugin); + plugin->loaded = FALSE; + + /* We wouldn't be anywhere near here if the plugin wasn't loaded, so + * if plugin->error is set at all, it had to be from a previous + * unload failure. It's obviously okay now. + */ + g_free(plugin->error); + plugin->error = NULL; + if (unload_cb != NULL) unload_cb(plugin, unload_cb_data); @@ -757,6 +760,15 @@ #endif /* PURPLE_PLUGINS */ } +void +purple_plugin_disable(PurplePlugin *plugin) +{ + g_return_if_fail(plugin != NULL); + + if (!g_list_find(plugins_to_disable, plugin)) + plugins_to_disable = g_list_prepend(plugins_to_disable, plugin); +} + gboolean purple_plugin_reload(PurplePlugin *plugin) { @@ -1222,14 +1234,14 @@ #ifdef PURPLE_PLUGINS GList *pl; GList *files = NULL; - PurplePlugin *p; for (pl = purple_plugins_get_loaded(); pl != NULL; pl = pl->next) { - p = pl->data; + PurplePlugin *plugin = pl->data; - if (p->info->type != PURPLE_PLUGIN_PROTOCOL && - p->info->type != PURPLE_PLUGIN_LOADER) { - files = g_list_append(files, p->path); + if (plugin->info->type != PURPLE_PLUGIN_PROTOCOL && + plugin->info->type != PURPLE_PLUGIN_LOADER && + !g_list_find(plugins_to_disable, plugin)) { + files = g_list_append(files, plugin->path); } } @@ -1391,6 +1403,7 @@ if (probe_cb != NULL) probe_cb(probe_cb_data); + #endif /* PURPLE_PLUGINS */ } @@ -1464,7 +1477,6 @@ void purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data) { - /* TODO */ probe_cb = func; probe_cb_data = data; } @@ -1472,7 +1484,6 @@ void purple_plugins_unregister_probe_notify_cb(void (*func)(void *)) { - /* TODO */ probe_cb = NULL; probe_cb_data = NULL; } @@ -1481,7 +1492,6 @@ purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *), void *data) { - /* TODO */ load_cb = func; load_cb_data = data; } @@ -1489,7 +1499,6 @@ void purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *)) { - /* TODO */ load_cb = NULL; load_cb_data = NULL; } @@ -1498,7 +1507,6 @@ purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *), void *data) { - /* TODO */ unload_cb = func; unload_cb_data = data; } @@ -1506,7 +1514,6 @@ void purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *, void *)) { - /* TODO */ unload_cb = NULL; unload_cb_data = NULL; }