static void infinoted_plugin_manager_walk_directory( InfinotedPluginManager* manager, const InfBrowserIter* iter, InfinotedPluginInstance* instance, InfinotedPluginManagerWalkDirectoryFunc func) { /* This function walks the whole directory tree recursively and * registers running sessions with the given plugin instance. */ InfBrowser* browser; InfBrowserIter child; InfSessionProxy* proxy; browser = INF_BROWSER(manager->directory); if(inf_browser_is_subdirectory(browser, iter) == TRUE) { if(inf_browser_get_explored(browser, iter) == TRUE) { child = *iter; inf_browser_get_child(browser, &child); do { infinoted_plugin_manager_walk_directory(manager, &child, instance, func); } while(inf_browser_get_next(browser, &child)); } } else { proxy = inf_browser_get_session(browser, iter); if(proxy != NULL) { func(manager, instance, iter, proxy); } } }
static void infinoted_plugin_manager_unload_plugin(InfinotedPluginManager* manager, InfinotedPluginInstance* instance) { InfinotedPluginManagerPrivate* priv; InfinotedPluginManagerForeachConnectionData data; InfBrowserIter root; priv = INFINOTED_PLUGIN_MANAGER_PRIVATE(manager); priv->plugins = g_slist_remove(priv->plugins, instance); /* Unregister all sessions with the plugin */ inf_browser_get_root(INF_BROWSER(priv->directory), &root); infinoted_plugin_manager_walk_directory( manager, &root, instance, infinoted_plugin_manager_remove_session ); /* Unregister all connections with the plugin */ data.manager = manager; data.instance = instance; infd_directory_foreach_connection( priv->directory, infinoted_plugin_manager_unload_plugin_foreach_connection_func, &data ); if(instance->plugin->on_deinitialize != NULL) instance->plugin->on_deinitialize(instance+1); infinoted_log_info( priv->log, _("Unloaded plugin \"%s\" from \"%s\""), instance->plugin->name, g_module_name(instance->module) ); g_module_close(instance->module); g_free(instance); }
static gboolean infinoted_plugin_manager_load_plugin(InfinotedPluginManager* manager, const gchar* plugin_path, const gchar* plugin_name, GKeyFile* key_file, GError** error) { gchar* plugin_basename; gchar* plugin_filename; GModule* module; const InfinotedPlugin* plugin; InfinotedPluginInstance* instance; gboolean result; GError* local_error; InfBrowserIter root; InfinotedPluginManagerForeachConnectionData data; plugin_basename = g_strdup_printf( "libinfinoted-plugin-%s.%s", plugin_name, G_MODULE_SUFFIX ); plugin_filename = g_build_filename(plugin_path, plugin_basename, NULL); g_free(plugin_basename); module = g_module_open(plugin_filename, G_MODULE_BIND_LOCAL); g_free(plugin_filename); if(module == NULL) { g_set_error( error, infinoted_plugin_manager_error_quark(), INFINOTED_PLUGIN_MANAGER_ERROR_OPEN_FAILED, "%s", g_module_error() ); return FALSE; } if(g_module_symbol(module, "INFINOTED_PLUGIN", (gpointer*)&plugin) == FALSE) { g_set_error( error, infinoted_plugin_manager_error_quark(), INFINOTED_PLUGIN_MANAGER_ERROR_NO_ENTRY_POINT, "%s", g_module_error() ); g_module_close(module); return FALSE; } instance = g_malloc(sizeof(InfinotedPluginInstance) + plugin->info_size); instance->module = module; instance->plugin = plugin; /* Call on_info_initialize, allowing the plugin to set default values */ if(plugin->on_info_initialize != NULL) plugin->on_info_initialize(instance+1); /* Next, parse options from keyfile */ if(plugin->options != NULL) { local_error = NULL; result = infinoted_parameter_load_from_key_file( plugin->options, key_file, plugin->name, instance+1, &local_error ); if(result == FALSE) { g_free(instance); g_module_close(module); g_propagate_prefixed_error( error, local_error, "Failed to initialize plugin \"%s\": ", plugin_name ); return FALSE; } } /* Finally, call on_initialize, which allows the plugin to initialize * itself with the plugin options. */ if(plugin->on_initialize != NULL) { local_error = NULL; result = plugin->on_initialize(manager, instance+1, &local_error); if(local_error != NULL) { if(instance->plugin->on_deinitialize != NULL) instance->plugin->on_deinitialize(instance+1); g_free(instance); g_module_close(module); g_propagate_prefixed_error( error, local_error, "Failed to initialize plugin \"%s\": ", plugin_name ); return FALSE; } } /* Register initial connections with plugin */ data.manager = manager; data.instance = instance; infd_directory_foreach_connection( manager->directory, infinoted_plugin_manager_load_plugin_foreach_connection_func, &data ); /* Register initial sessions with plugin */ inf_browser_get_root(INF_BROWSER(manager->directory), &root); infinoted_plugin_manager_walk_directory( manager, &root, instance, infinoted_plugin_manager_add_session ); infinoted_log_info( manager->log, _("Loaded plugin \"%s\" from \"%s\""), plugin_name, g_module_name(module) ); manager->plugins = g_slist_prepend(manager->plugins, instance); return TRUE; }