libnm-util: raise CHANGED signal in nm_connection_clear_secrets only on change

Often, nm_connection_clear_secrets does have no consequences, because
there is nothing to be cleared. Only raise a signal, if something
actually changed.

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2013-12-11 14:33:49 +01:00
parent f53f39847a
commit 0f38213129
5 changed files with 74 additions and 24 deletions

View file

@ -841,15 +841,20 @@ nm_connection_clear_secrets (NMConnection *connection)
{
GHashTableIter iter;
NMSetting *setting;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
nm_setting_clear_secrets (setting);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
changed |= _nm_setting_clear_secrets (setting);
g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
}
g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
g_signal_emit (connection, signals[CHANGED], 0);
if (changed)
g_signal_emit (connection, signals[CHANGED], 0);
}
/**
@ -868,15 +873,20 @@ nm_connection_clear_secrets_with_flags (NMConnection *connection,
{
GHashTableIter iter;
NMSetting *setting;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
nm_setting_clear_secrets_with_flags (setting, func, user_data);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
changed |= _nm_setting_clear_secrets_with_flags (setting, func, user_data);
g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
}
g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
g_signal_emit (connection, signals[CHANGED], 0);
if (changed)
g_signal_emit (connection, signals[CHANGED], 0);
}
/**

View file

@ -42,6 +42,12 @@ GType _nm_setting_lookup_setting_type (const char *name);
GType _nm_setting_lookup_setting_type_by_quark (GQuark error_quark);
gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b);
gboolean _nm_setting_clear_secrets (NMSetting *setting);
gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data);
/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated
* connection can be replaced by a already-defined connection. This flag only
* takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE

View file

@ -649,7 +649,7 @@ compare_property (NMSetting *setting,
return same;
}
static void
static gboolean
clear_secrets_with_flags (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
@ -661,7 +661,7 @@ clear_secrets_with_flags (NMSetting *setting,
gboolean changed = TRUE;
if (priv->secrets == NULL)
return;
return FALSE;
/* Iterate through secrets hash and check each entry */
g_hash_table_iter_init (&iter, priv->secrets);
@ -677,6 +677,8 @@ clear_secrets_with_flags (NMSetting *setting,
if (changed)
g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
return changed;
}
static void

View file

@ -814,47 +814,69 @@ nm_setting_enumerate_values (NMSetting *setting,
**/
void
nm_setting_clear_secrets (NMSetting *setting)
{
_nm_setting_clear_secrets (setting);
}
gboolean
_nm_setting_clear_secrets (NMSetting *setting)
{
GParamSpec **property_specs;
guint n_property_specs;
guint i;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_SETTING (setting));
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
for (i = 0; i < n_property_specs; i++) {
GParamSpec *prop_spec = property_specs[i];
GValue value = G_VALUE_INIT;
if (prop_spec->flags & NM_SETTING_PARAM_SECRET) {
GValue value = G_VALUE_INIT;
g_value_init (&value, prop_spec->value_type);
g_param_value_set_default (prop_spec, &value);
g_object_set_property (G_OBJECT (setting), prop_spec->name, &value);
g_object_get_property (G_OBJECT (setting), prop_spec->name, &value);
if (!g_param_value_defaults (prop_spec, &value)) {
g_param_value_set_default (prop_spec, &value);
g_object_set_property (G_OBJECT (setting), prop_spec->name, &value);
changed = TRUE;
}
g_value_unset (&value);
}
}
g_free (property_specs);
return changed;
}
static void
static gboolean
clear_secrets_with_flags (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data)
{
GValue value = G_VALUE_INIT;
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
gboolean changed = FALSE;
/* Clear the secret if the user function says to do so */
nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL);
if (func (setting, pspec->name, flags, user_data) == TRUE) {
GValue value = G_VALUE_INIT;
g_value_init (&value, pspec->value_type);
g_param_value_set_default (pspec, &value);
g_object_set_property (G_OBJECT (setting), pspec->name, &value);
g_object_get_property (G_OBJECT (setting), pspec->name, &value);
if (!g_param_value_defaults (pspec, &value)) {
g_param_value_set_default (pspec, &value);
g_object_set_property (G_OBJECT (setting), pspec->name, &value);
changed = TRUE;
}
g_value_unset (&value);
}
return changed;
}
/**
@ -870,26 +892,36 @@ void
nm_setting_clear_secrets_with_flags (NMSetting *setting,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data)
{
_nm_setting_clear_secrets_with_flags (setting, func, user_data);
}
gboolean
_nm_setting_clear_secrets_with_flags (NMSetting *setting,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data)
{
GParamSpec **property_specs;
guint n_property_specs;
guint i;
gboolean changed = FALSE;
g_return_if_fail (setting);
g_return_if_fail (NM_IS_SETTING (setting));
g_return_if_fail (func != NULL);
g_return_val_if_fail (setting, FALSE);
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
g_return_val_if_fail (func != NULL, FALSE);
property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
for (i = 0; i < n_property_specs; i++) {
if (property_specs[i]->flags & NM_SETTING_PARAM_SECRET) {
NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting,
property_specs[i],
func,
user_data);
changed |= NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting,
property_specs[i],
func,
user_data);
}
}
g_free (property_specs);
return changed;
}
/**

View file

@ -200,7 +200,7 @@ typedef struct {
const GParamSpec *prop_spec,
NMSettingCompareFlags flags);
void (*clear_secrets_with_flags) (NMSetting *setting,
gboolean (*clear_secrets_with_flags) (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data);