diff options
Diffstat (limited to 'src/settings/nm-settings.c')
| -rw-r--r-- | src/settings/nm-settings.c | 276 |
1 files changed, 152 insertions, 124 deletions
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2253d56a..5bb629dc 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -214,9 +214,9 @@ connection_ready_changed (NMSettingsConnection *conn, static void plugin_connection_added (NMSettingsPlugin *config, NMSettingsConnection *connection, - NMSettings *self) + gpointer user_data) { - claim_connection (self, connection); + claim_connection (NM_SETTINGS (user_data), connection); } static void @@ -237,7 +237,7 @@ load_connections (NMSettings *self) // priority plugin. for (elt = plugin_connections; elt; elt = g_slist_next (elt)) - claim_connection (self, elt->data); + claim_connection (self, NM_SETTINGS_CONNECTION (elt->data)); g_slist_free (plugin_connections); @@ -306,15 +306,15 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, GVariant *parameters) { NMSettings *self = NM_SETTINGS (obj); - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection = NULL; gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; const char *uuid; g_variant_get (parameters, "(&s)", &uuid); - sett_conn = nm_settings_get_connection_by_uuid (self, uuid); - if (!sett_conn) { + connection = nm_settings_get_connection_by_uuid (self, uuid); + if (!connection) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No connection with the UUID was found."); @@ -329,7 +329,7 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, goto error; } - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -338,7 +338,7 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); return; error: @@ -362,7 +362,6 @@ _clear_connections_cached_list (NMSettingsPrivate *priv) 0xdeaddead, sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); #endif - nm_clear_g_free (&priv->connections_cached_list); } @@ -481,8 +480,8 @@ nm_settings_get_connection_by_path (NMSettings *self, const char *path) priv = NM_SETTINGS_GET_PRIVATE (self); - connection = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + connection = (NMSettingsConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !connection || !NM_IS_SETTINGS_CONNECTION (connection)) return NULL; @@ -526,6 +525,28 @@ nm_settings_get_unmanaged_specs (NMSettings *self) return priv->unmanaged_specs; } +static NMSettingsPlugin * +get_plugin (NMSettings *self, gboolean has_add_connection) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + g_return_val_if_fail (self != NULL, NULL); + + /* Do any of the plugins support the given capability? */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); + + if (!has_add_connection) + return plugin; + + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (iter->data)->add_connection != NULL) + return plugin; + } + + return NULL; +} + static gboolean find_spec (GSList *spec_list, const char *spec) { @@ -586,49 +607,67 @@ unrecognized_specs_changed (NMSettingsPlugin *config, nm_settings_plugin_get_unrecognized_specs); } -static void -add_plugin (NMSettings *self, NMSettingsPlugin *plugin, const char *path) +static gboolean +add_plugin (NMSettings *self, NMSettingsPlugin *plugin) { NMSettingsPrivate *priv; + const char *path; - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_SETTINGS_PLUGIN (plugin)); + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (plugin), FALSE); priv = NM_SETTINGS_GET_PRIVATE (self); - nm_assert (!g_slist_find (priv->plugins, plugin)); + if (g_slist_find (priv->plugins, plugin)) { + /* don't add duplicates. */ + return FALSE; + } priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); + nm_settings_plugin_init (plugin); + + + path = g_object_get_qdata (G_OBJECT (plugin), plugin_module_path_quark ()); - nm_settings_plugin_initialize (plugin); + _LOGI ("Loaded settings plugin: %s (%s)", G_OBJECT_TYPE_NAME (plugin), path ?: "internal"); - _LOGI ("Loaded settings plugin: %s (%s%s%s)", - G_OBJECT_TYPE_NAME (plugin), - NM_PRINT_FMT_QUOTED (path, "\"", path, "\"", "internal")); + return TRUE; } static gboolean -add_plugin_load_file (NMSettings *self, const char *pname, GError **error) +plugin_loaded (GSList *list, const char *path) +{ + GSList *iter; + + g_return_val_if_fail (path != NULL, TRUE); + + for (iter = list; iter; iter = g_slist_next (iter)) { + const char *list_path = g_object_get_qdata (G_OBJECT (iter->data), + plugin_module_path_quark ()); + + if (g_strcmp0 (path, list_path) == 0) + return TRUE; + } + + return FALSE; +} + +static gboolean +load_plugin (NMSettings *self, GSList **list, const char *pname, GError **error) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); gs_free char *full_name = NULL; gs_free char *path = NULL; - gs_unref_object NMSettingsPlugin *plugin = NULL; - GModule *module; - NMSettingsPluginFactoryFunc factory_func; - GSList *iter; + gs_unref_object GObject *obj = NULL; + GModule *plugin; + GObject * (*factory_func) (void); struct stat st; int errsv; full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); path = g_module_build_path (NMPLUGINDIR, full_name); - for (iter = priv->plugins; iter; iter = iter->next) { - if (nm_streq0 (path, - g_object_get_qdata (iter->data, - plugin_module_path_quark ()))) - return TRUE; - } + if (plugin_loaded (*list, path)) + return TRUE; if (stat (path, &st) != 0) { errsv = errno; @@ -648,8 +687,8 @@ add_plugin_load_file (NMSettings *self, const char *pname, GError **error) return TRUE; } - module = g_module_open (path, G_MODULE_BIND_LOCAL); - if (!module) { + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + if (!plugin) { _LOGW ("could not load plugin '%s' from file '%s': %s", pname, path, g_module_error ()); return TRUE; @@ -657,46 +696,48 @@ add_plugin_load_file (NMSettings *self, const char *pname, GError **error) /* errors after this point are fatal, because we loaded the shared library already. */ - if (!g_module_symbol (module, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { + if (!g_module_symbol (plugin, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not find plugin '%s' factory function.", pname); - g_module_close (module); + g_module_close (plugin); return FALSE; } /* after accessing the plugin we cannot unload it anymore, because the glib * types cannot be properly unregistered. */ - g_module_make_resident (module); + g_module_make_resident (plugin); - plugin = (*factory_func) (); - if (!NM_IS_SETTINGS_PLUGIN (plugin)) { + obj = (*factory_func) (); + if (!obj || !NM_IS_SETTINGS_PLUGIN (obj)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "plugin '%s' returned invalid settings plugin", + "Plugin '%s' returned invalid system config object.", pname); return FALSE; } - add_plugin (self, NM_SETTINGS_PLUGIN (plugin), path); - g_object_set_qdata_full (G_OBJECT (plugin), - plugin_module_path_quark (), - g_steal_pointer (&path), - g_free); + g_object_set_qdata_full (obj, plugin_module_path_quark (), path, g_free); + path = NULL; + if (add_plugin (self, NM_SETTINGS_PLUGIN (obj))) + *list = g_slist_append (*list, g_steal_pointer (&obj)); + return TRUE; } static void -add_plugin_keyfile (NMSettings *self) +add_keyfile_plugin (NMSettings *self) { gs_unref_object NMSKeyfilePlugin *keyfile_plugin = NULL; keyfile_plugin = nms_keyfile_plugin_new (); - add_plugin (self, NM_SETTINGS_PLUGIN (keyfile_plugin), NULL); + if (!add_plugin (self, NM_SETTINGS_PLUGIN (keyfile_plugin))) + g_return_if_reached (); } static gboolean load_plugins (NMSettings *self, const char **plugins, GError **error) { + GSList *list = NULL; const char **iter; gboolean keyfile_added = FALSE; gboolean success = TRUE; @@ -724,15 +765,15 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - if (nm_streq (pname, "no-ibft")) + if (!strcmp (pname, "no-ibft")) continue; - if (has_no_ibft && nm_streq (pname, "ibft")) + if (has_no_ibft && !strcmp (pname, "ibft")) continue; /* keyfile plugin is built-in now */ - if (nm_streq (pname, "keyfile")) { + if (strcmp (pname, "keyfile") == 0) { if (!keyfile_added) { - add_plugin_keyfile (self); + add_keyfile_plugin (self); keyfile_added = TRUE; } continue; @@ -746,25 +787,27 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - success = add_plugin_load_file (self, pname, error); + success = load_plugin (self, &list, pname, error); if (!success) break; - if (add_ibft && nm_streq (pname, "ifcfg-rh")) { + if (add_ibft && !strcmp (pname, "ifcfg-rh")) { /* The plugin ibft is not explicitly mentioned but we just enabled "ifcfg-rh". * Enable "ibft" by default after "ifcfg-rh". */ pname = "ibft"; add_ibft = FALSE; - success = add_plugin_load_file (self, "ibft", error); + success = load_plugin (self, &list, "ibft", error); if (!success) break; } } /* If keyfile plugin was not among configured plugins, add it as the last one */ - if (!keyfile_added && success) - add_plugin_keyfile (self); + if (!keyfile_added) + add_keyfile_plugin (self); + + g_slist_free_full (list, g_object_unref); return success; } @@ -888,33 +931,29 @@ openconnect_migrate_hack (NMConnection *connection) } static void -claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) +claim_connection (NMSettings *self, NMSettingsConnection *connection) { - NMSettingsPrivate *priv; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; const char *path; NMSettingsConnection *existing; - g_return_if_fail (NM_IS_SETTINGS (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); - g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (sett_conn))); - - priv = NM_SETTINGS_GET_PRIVATE (self); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))); /* prevent duplicates */ - if (!c_list_is_empty (&sett_conn->_connections_lst)) { - nm_assert (c_list_contains (&priv->connections_lst_head, &sett_conn->_connections_lst)); + if (!c_list_is_empty (&connection->_connections_lst)) { + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); return; } - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - if (!nm_connection_normalize (nm_settings_connection_get_connection (sett_conn), NULL, NULL, &error)) { + if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { _LOGW ("plugin provided invalid connection: %s", error->message); g_error_free (error); return; } - existing = nm_settings_get_connection_by_uuid (self, nm_settings_connection_get_uuid (sett_conn)); + existing = nm_settings_get_connection_by_uuid (self, nm_settings_connection_get_uuid (connection)); if (existing) { /* Cannot add duplicate connections per UUID. Just return without action and * log a warning. @@ -927,56 +966,51 @@ claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) * error out. That should not happen unless the admin misconfigured the system * to create conflicting connections. */ _LOGW ("plugin provided duplicate connection with UUID %s", - nm_settings_connection_get_uuid (sett_conn)); + nm_settings_connection_get_uuid (connection)); return; } /* Read timestamp from look-aside file and put it into the connection's data */ - nm_settings_connection_read_and_fill_timestamp (sett_conn); + nm_settings_connection_read_and_fill_timestamp (connection); /* Read seen-bssids from look-aside file and put it into the connection's data */ - nm_settings_connection_read_and_fill_seen_bssids (sett_conn); + nm_settings_connection_read_and_fill_seen_bssids (connection); /* Ensure its initial visibility is up-to-date */ - nm_settings_connection_recheck_visibility (sett_conn); + nm_settings_connection_recheck_visibility (connection); /* Evil openconnect migration hack */ - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - openconnect_migrate_hack (nm_settings_connection_get_connection (sett_conn)); + openconnect_migrate_hack (NM_CONNECTION (connection)); /* This one unexports the connection, it needs to run late to give the active * connection a chance to deal with its reference to this settings connection. */ - g_signal_connect_after (sett_conn, NM_SETTINGS_CONNECTION_REMOVED, + g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (connection_updated), self); - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) { - g_signal_connect (sett_conn, "notify::" NM_SETTINGS_CONNECTION_READY, + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY, G_CALLBACK (connection_ready_changed), self); } _clear_connections_cached_list (priv); - g_object_ref (sett_conn); + g_object_ref (connection); /* FIXME(shutdown): The NMSettings instance can't be disposed * while there is any exported connection. Ideally we should * unexport all connections on NMSettings' disposal, but for now * leak @self on termination when there are connections alive. */ g_object_ref (self); priv->connections_len++; - c_list_link_tail (&priv->connections_lst_head, &sett_conn->_connections_lst); + c_list_link_tail (&priv->connections_lst_head, &connection->_connections_lst); - path = nm_dbus_object_export (NM_DBUS_OBJECT (sett_conn)); + path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); - nm_utils_log_connection_diff (nm_settings_connection_get_connection (sett_conn), - NULL, - LOGL_DEBUG, - LOGD_CORE, - "new connection", "++ ", + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ", path); /* Only emit the individual connection-added signal after connections @@ -987,13 +1021,13 @@ claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) &interface_info_settings, &signal_info_new_connection, "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); - g_signal_emit (self, signals[CONNECTION_ADDED], 0, sett_conn); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); } - nm_settings_connection_added (sett_conn); + nm_settings_connection_added (connection); } static gboolean @@ -1045,7 +1079,7 @@ nm_settings_add_connection (NMSettings *self, /* Make sure a connection with this UUID doesn't already exist */ c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { - if (nm_streq0 (uuid, nm_settings_connection_get_uuid (candidate))) { + if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate)))) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS, @@ -1079,13 +1113,8 @@ nm_settings_add_connection (NMSettings *self, added = nm_settings_plugin_add_connection (plugin, connection, save_to_disk, &add_error); if (added) { - if (secrets) { - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_update_secrets (nm_settings_connection_get_connection (added), - NULL, - secrets, - NULL); - } + if (secrets) + nm_connection_update_secrets (NM_CONNECTION (added), NULL, secrets, NULL); claim_connection (self, added); return added; } @@ -1103,7 +1132,7 @@ nm_settings_add_connection (NMSettings *self, static void send_agent_owned_secrets (NMSettings *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMAuthSubject *subject) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); @@ -1113,12 +1142,12 @@ send_agent_owned_secrets (NMSettings *self, * as agent-owned secrets are the only ones we send back to be saved. * Only send secrets to agents of the same UID that called update too. */ - for_agent = nm_simple_connection_new_clone (nm_settings_connection_get_connection (sett_conn)); + for_agent = nm_simple_connection_new_clone (NM_CONNECTION (connection)); nm_connection_clear_secrets_with_flags (for_agent, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), for_agent, subject); } @@ -1161,8 +1190,7 @@ pk_add_cb (NMAuthChain *chain, } else { /* Authorized */ connection = nm_auth_chain_get_data (chain, "connection"); - nm_assert (connection); - + g_assert (connection); save_to_disk = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "save-to-disk")); added = nm_settings_add_connection (self, connection, save_to_disk, &error); } @@ -1253,6 +1281,14 @@ nm_settings_add_connection_dbus (NMSettings *self, goto done; } + /* Do any of the plugins support adding? */ + if (!get_plugin (self, TRUE)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_SUPPORTED, + "None of the registered plugins support add."); + goto done; + } + if (!nm_auth_is_subject_in_acl_set_error (connection, subject, NM_SETTINGS_ERROR, @@ -1576,21 +1612,20 @@ have_connection_for_device (NMSettings *self, NMDevice *device) NMSettingWired *s_wired; const char *setting_hwaddr; const char *perm_hw_addr; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ - c_list_for_each_entry (sett_conn, &priv->connections_lst_head, _connections_lst) { - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); + c_list_for_each_entry (connection, &priv->connections_lst_head, _connections_lst) { const char *ctype, *iface; - if (!nm_device_check_connection_compatible (device, connection, NULL)) + if (!nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) continue; - s_con = nm_connection_get_setting_connection (connection); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); iface = nm_setting_connection_get_interface_name (s_con); if (iface && strcmp (iface, nm_device_get_iface (device)) != 0) @@ -1601,15 +1636,14 @@ have_connection_for_device (NMSettings *self, NMDevice *device) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; - s_wired = nm_connection_get_setting_wired (connection); + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (connection)); - if ( !s_wired - && nm_streq (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { + if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { /* No wired setting; therefore the PPPoE connection applies to any device */ return TRUE; } - nm_assert (s_wired); + g_assert (s_wired != NULL); setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); if (setting_hwaddr) { @@ -1653,11 +1687,11 @@ default_wired_clear_tag (NMSettings *self, NMSettingsConnection *connection, gboolean add_to_no_auto_default) { - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_DEVICE (device)); - nm_assert (NM_IS_SETTINGS_CONNECTION (connection)); - nm_assert (device == g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ())); - nm_assert (connection == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())); + g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (device == g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ())); + g_return_if_fail (connection == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())); g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL); g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); @@ -1832,7 +1866,7 @@ get_property (GObject *object, guint prop_id, : NULL); break; case PROP_CAN_MODIFY: - g_value_set_boolean (value, TRUE); + g_value_set_boolean (value, !!get_plugin (self, TRUE)); break; case PROP_CONNECTIONS: if (priv->connections_loaded) { @@ -1896,7 +1930,6 @@ finalize (GObject *object) { NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSList *iter; _clear_connections_cached_list (priv); @@ -1905,12 +1938,7 @@ finalize (GObject *object) g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); - while ((iter = priv->plugins)) { - gs_unref_object NMSettingsPlugin *plugin = iter->data; - - priv->plugins = g_slist_delete_link (priv->plugins, iter); - g_signal_handlers_disconnect_by_data (plugin, self); - } + g_slist_free_full (priv->plugins, g_object_unref); g_clear_object (&priv->agent_mgr); |