comparison libpurple/plugin.c @ 21187:a8332645ce5b

Honor the return value of a plugin's unload function.
author Richard Laager <rlaager@wiktel.com>
date Sat, 06 Oct 2007 22:43:55 +0000
parents df58938e9f61
children a06ddc1513e2
comparison
equal deleted inserted replaced
20743:c757b4773a77 21187:a8332645ce5b
641 gboolean 641 gboolean
642 purple_plugin_unload(PurplePlugin *plugin) 642 purple_plugin_unload(PurplePlugin *plugin)
643 { 643 {
644 #ifdef PURPLE_PLUGINS 644 #ifdef PURPLE_PLUGINS
645 GList *l; 645 GList *l;
646 GList *ll;
646 647
647 g_return_val_if_fail(plugin != NULL, FALSE); 648 g_return_val_if_fail(plugin != NULL, FALSE);
648
649 loaded_plugins = g_list_remove(loaded_plugins, plugin);
650 if ((plugin->info != NULL) && PURPLE_IS_PROTOCOL_PLUGIN(plugin))
651 protocol_plugins = g_list_remove(protocol_plugins, plugin);
652
653 g_return_val_if_fail(purple_plugin_is_loaded(plugin), FALSE); 649 g_return_val_if_fail(purple_plugin_is_loaded(plugin), FALSE);
654 650
655 purple_debug_info("plugins", "Unloading plugin %s\n", plugin->info->name); 651 purple_debug_info("plugins", "Unloading plugin %s\n", plugin->info->name);
656 652
657 /* cancel any pending dialogs the plugin has */
658 purple_request_close_with_handle(plugin);
659 purple_notify_close_with_handle(plugin);
660
661 plugin->loaded = FALSE;
662
663 /* Unload all plugins that depend on this plugin. */ 653 /* Unload all plugins that depend on this plugin. */
664 while ((l = plugin->dependent_plugins) != NULL) 654 for (l = plugin->dependent_plugins, l != NULL, l = ll) {
665 {
666 const char * dep_name = (const char *)l->data; 655 const char * dep_name = (const char *)l->data;
667 PurplePlugin *dep_plugin; 656 PurplePlugin *dep_plugin;
657
658 /* Store a pointer to the next element in the list.
659 * This is because we'll be modifying this list in the loop. */
660 ll = l->next;
668 661
669 dep_plugin = purple_plugins_find_with_id(dep_name); 662 dep_plugin = purple_plugins_find_with_id(dep_name);
670 663
671 if (dep_plugin != NULL && purple_plugin_is_loaded(dep_plugin)) 664 if (dep_plugin != NULL && purple_plugin_is_loaded(dep_plugin))
672 { 665 {
676 669
677 tmp = g_strdup_printf(_("The dependent plugin %s failed to unload."), 670 tmp = g_strdup_printf(_("The dependent plugin %s failed to unload."),
678 _(dep_plugin->info->name)); 671 _(dep_plugin->info->name));
679 672
680 purple_notify_error(NULL, NULL, 673 purple_notify_error(NULL, NULL,
681 _("There were errors unloading the plugin."), tmp); 674 _("There were errors unloading the plugin."), tmp);
682 g_free(tmp); 675 g_free(tmp);
676
677 return FALSE;
683 } 678 }
684 } 679 else
685 } 680 {
686 681 plugin->dependent_plugins = g_list_remove(plugin->dependent_plugins, dep_name);
687 /* Remove this plugin from each dependency's dependent_plugins list. */ 682 }
688 for (l = plugin->info->dependencies; l != NULL; l = l->next) 683 }
689 {
690 const char *dep_name = (const char *)l->data;
691 PurplePlugin *dependency;
692
693 dependency = purple_plugins_find_with_id(dep_name);
694
695 if (dependency != NULL)
696 dependency->dependent_plugins = g_list_remove(dependency->dependent_plugins, plugin->info->id);
697 else
698 purple_debug_error("plugins", "Unable to remove from dependency list for %s\n", dep_name);
699 } 684 }
700 685
701 if (plugin->native_plugin) { 686 if (plugin->native_plugin) {
702 if (plugin->info->unload != NULL) 687 if (plugin->info->unload != NULL)
703 plugin->info->unload(plugin); 688 if (!plugin->info->unload(plugin))
689 return FALSE;
704 690
705 if (plugin->info->type == PURPLE_PLUGIN_PROTOCOL) { 691 if (plugin->info->type == PURPLE_PLUGIN_PROTOCOL) {
706 PurplePluginProtocolInfo *prpl_info; 692 PurplePluginProtocolInfo *prpl_info;
707 GList *l; 693 GList *l;
708 694
722 if (prpl_info->protocol_options != NULL) { 708 if (prpl_info->protocol_options != NULL) {
723 g_list_free(prpl_info->protocol_options); 709 g_list_free(prpl_info->protocol_options);
724 prpl_info->protocol_options = NULL; 710 prpl_info->protocol_options = NULL;
725 } 711 }
726 } 712 }
727 } 713 } else {
728 else {
729 PurplePlugin *loader; 714 PurplePlugin *loader;
730 PurplePluginLoaderInfo *loader_info; 715 PurplePluginLoaderInfo *loader_info;
731 716
732 loader = find_loader_for_plugin(plugin); 717 loader = find_loader_for_plugin(plugin);
733 718
735 return FALSE; 720 return FALSE;
736 721
737 loader_info = PURPLE_PLUGIN_LOADER_INFO(loader); 722 loader_info = PURPLE_PLUGIN_LOADER_INFO(loader);
738 723
739 if (loader_info->unload != NULL) 724 if (loader_info->unload != NULL)
740 loader_info->unload(plugin); 725 if (!loader_info->unload(plugin))
741 } 726 return FALSE;
727 }
728
729 /* cancel any pending dialogs the plugin has */
730 purple_request_close_with_handle(plugin);
731 purple_notify_close_with_handle(plugin);
742 732
743 purple_signals_disconnect_by_handle(plugin); 733 purple_signals_disconnect_by_handle(plugin);
744 purple_plugin_ipc_unregister_all(plugin); 734 purple_plugin_ipc_unregister_all(plugin);
735
736 loaded_plugins = g_list_remove(loaded_plugins, plugin);
737 if ((plugin->info != NULL) && PURPLE_IS_PROTOCOL_PLUGIN(plugin))
738 protocol_plugins = g_list_remove(protocol_plugins, plugin);
739 plugin->loaded = FALSE;
745 740
746 /* TODO */ 741 /* TODO */
747 if (unload_cb != NULL) 742 if (unload_cb != NULL)
748 unload_cb(plugin, unload_cb_data); 743 unload_cb(plugin, unload_cb_data);
749 744
1389 } 1384 }
1390 } 1385 }
1391 1386
1392 if (probe_cb != NULL) 1387 if (probe_cb != NULL)
1393 probe_cb(probe_cb_data); 1388 probe_cb(probe_cb_data);
1389
1394 #endif /* PURPLE_PLUGINS */ 1390 #endif /* PURPLE_PLUGINS */
1395 } 1391 }
1396 1392
1397 gboolean 1393 gboolean
1398 purple_plugin_register(PurplePlugin *plugin) 1394 purple_plugin_register(PurplePlugin *plugin)