comparison src/plugin.c @ 12926:2c4f20ff387c

[gaim-migrate @ 15279] SF Patch #1403656 from Nick Hebner "This patch makes plugin unloading take into account plugins that depend on the plugin being unloaded. All plugins dependent on the plugin in question are unloaded before this plugin is, so there are not problems with missing dependencies." committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Wed, 18 Jan 2006 18:21:59 +0000
parents 69713c02a702
children 92ae94619e2c
comparison
equal deleted inserted replaced
12925:fd734d1fb2f4 12926:2c4f20ff387c
502 502
503 dep_plugin = gaim_plugins_find_with_id(dep_name); 503 dep_plugin = gaim_plugins_find_with_id(dep_name);
504 504
505 if (dep_plugin == NULL) 505 if (dep_plugin == NULL)
506 { 506 {
507 char buf[BUFSIZ]; 507 char *tmp;
508 508
509 g_snprintf(buf, sizeof(buf), 509 tmp = g_strdup_printf(
510 _("The required plugin %s was not found. " 510 _("The required plugin %s was not found. "
511 "Please install this plugin and try again."), 511 "Please install this plugin and try again."),
512 dep_name); 512 dep_name);
513 513
514 gaim_notify_error(NULL, NULL, 514 gaim_notify_error(NULL, NULL,
515 _("Gaim was unable to load your plugin."), 515 _("Gaim encountered errors loading the plugin."), tmp);
516 buf); 516 g_free(tmp);
517 517
518 if (dep_list != NULL) 518 if (dep_list != NULL)
519 g_list_free(dep_list); 519 g_list_free(dep_list);
520 520
521 return FALSE; 521 return FALSE;
531 531
532 if (!gaim_plugin_is_loaded(dep_plugin)) 532 if (!gaim_plugin_is_loaded(dep_plugin))
533 { 533 {
534 if (!gaim_plugin_load(dep_plugin)) 534 if (!gaim_plugin_load(dep_plugin))
535 { 535 {
536 char buf[BUFSIZ]; 536 char *tmp;
537 537
538 g_snprintf(buf, sizeof(buf), 538 tmp = g_strdup_printf(_("The required plugin %s was unable to load."),
539 _("The required plugin %s was unable to load."), 539 plugin->info->name);
540 plugin->info->name);
541 540
542 gaim_notify_error(NULL, NULL, 541 gaim_notify_error(NULL, NULL,
543 _("Gaim was unable to load your plugin."), 542 _("Gaim was unable to load your plugin."), tmp);
544 buf); 543 g_free(tmp);
545 544
546 if (dep_list != NULL) 545 if (dep_list != NULL)
547 g_list_free(dep_list); 546 g_list_free(dep_list);
548 547
549 return FALSE; 548 return FALSE;
550 } 549 }
551 } 550 }
551 }
552
553 /* Third pass: note that other plugins are dependencies of this plugin.
554 * This is done separately in case we had to bail out earlier. */
555 for (l = dep_list; l != NULL; l = l->next)
556 {
557 GaimPlugin *dep_plugin = (GaimPlugin *)l->data;
558 dep_plugin->dependent_plugins = g_list_prepend(dep_plugin->dependent_plugins, plugin->info->id);
552 } 559 }
553 560
554 if (dep_list != NULL) 561 if (dep_list != NULL)
555 g_list_free(dep_list); 562 g_list_free(dep_list);
556 563
599 606
600 gboolean 607 gboolean
601 gaim_plugin_unload(GaimPlugin *plugin) 608 gaim_plugin_unload(GaimPlugin *plugin)
602 { 609 {
603 #ifdef GAIM_PLUGINS 610 #ifdef GAIM_PLUGINS
611 GList *l;
612
604 g_return_val_if_fail(plugin != NULL, FALSE); 613 g_return_val_if_fail(plugin != NULL, FALSE);
605 614
606 loaded_plugins = g_list_remove(loaded_plugins, plugin); 615 loaded_plugins = g_list_remove(loaded_plugins, plugin);
607 if ((plugin->info != NULL) && GAIM_IS_PROTOCOL_PLUGIN(plugin)) 616 if ((plugin->info != NULL) && GAIM_IS_PROTOCOL_PLUGIN(plugin))
608 protocol_plugins = g_list_remove(protocol_plugins, plugin); 617 protocol_plugins = g_list_remove(protocol_plugins, plugin);
614 /* cancel any pending dialogs the plugin has */ 623 /* cancel any pending dialogs the plugin has */
615 gaim_request_close_with_handle(plugin); 624 gaim_request_close_with_handle(plugin);
616 gaim_notify_close_with_handle(plugin); 625 gaim_notify_close_with_handle(plugin);
617 626
618 plugin->loaded = FALSE; 627 plugin->loaded = FALSE;
628
629 /* Unload all plugins that depend on this plugin. */
630 for (l = plugin->dependent_plugins; l != NULL; l = l->next)
631 {
632 const char * dep_name = (const char *)l->data;
633 GaimPlugin *dep_plugin;
634
635 dep_plugin = gaim_plugins_find_with_id(dep_name);
636
637 if (dep_plugin != NULL && gaim_plugin_is_loaded(dep_plugin))
638 {
639 if (!gaim_plugin_unload(dep_plugin))
640 {
641 char *translated_name = g_strdup(_(dep_plugin->info->name));
642 char *tmp;
643
644 tmp = g_strdup_printf(_("The dependent plugin %s failed to unload."),
645 translated_name);
646 g_free(translated_name);
647
648 gaim_notify_error(NULL, NULL,
649 _("Gaim encountered errors unloading the plugin."), tmp);
650 g_free(tmp);
651 }
652 }
653 }
654
655 /* Remove this plugin from each dependency's dependent_plugins list. */
656 for (l = plugin->info->dependencies; l != NULL; l = l->next)
657 {
658 const char *dep_name = (const char *)l->data;
659 GaimPlugin *dependency;
660
661 dependency = gaim_plugins_find_with_id(dep_name);
662
663 dependency->dependent_plugins = g_list_remove(dependency->dependent_plugins, plugin->info->id);
664 }
619 665
620 if (plugin->native_plugin) { 666 if (plugin->native_plugin) {
621 if (plugin->info->unload != NULL) 667 if (plugin->info->unload != NULL)
622 plugin->info->unload(plugin); 668 plugin->info->unload(plugin);
623 669