diff options
| author | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
| commit | 2e5fa45ddfbb5cffa1e78221f1cea706e2f298af (patch) | |
| tree | 86f69d36c56de3074280456eddc854a780b8e04b /libnm-core/nm-setting.c | |
| parent | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff) | |
New upstream version 1.19.90 upstream/1.19.90
Diffstat (limited to 'libnm-core/nm-setting.c')
| -rw-r--r-- | libnm-core/nm-setting.c | 559 |
1 files changed, 328 insertions, 231 deletions
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 2e9081df..4323b83c 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -199,10 +197,31 @@ _nm_sett_info_property_find_in_array (const NMSettInfoProperty *properties, guin return NULL; } +static GVariant * +_gprop_to_dbus_fcn_bytes (const GValue *val) +{ + nm_assert (G_VALUE_HOLDS (val, G_TYPE_BYTES)); + return nm_utils_gbytes_to_variant_ay (g_value_get_boxed (val)); +} + +static GVariant * +_gprop_to_dbus_fcn_enum (const GValue *val) +{ + return g_variant_new_int32 (g_value_get_enum (val)); +} + +static GVariant * +_gprop_to_dbus_fcn_flags (const GValue *val) +{ + return g_variant_new_uint32 (g_value_get_flags (val)); +} + void _properties_override_add_struct (GArray *properties_override, const NMSettInfoProperty *prop_info) { + NMSettInfoProperty *p; + nm_assert (properties_override); nm_assert (prop_info); nm_assert (prop_info->name || prop_info->param_spec); @@ -211,16 +230,25 @@ _properties_override_add_struct (GArray *properties_override, properties_override->len, prop_info->name ?: prop_info->param_spec->name)); - nm_assert (!prop_info->from_dbus || prop_info->dbus_type); - nm_assert (!prop_info->set_func || prop_info->dbus_type); + nm_assert (!prop_info->gprop_from_dbus_fcn || prop_info->dbus_type); + nm_assert (!prop_info->from_dbus_fcn || prop_info->dbus_type); + nm_assert (!prop_info->to_dbus_fcn || prop_info->dbus_type); + + nm_assert (!prop_info->to_dbus_fcn || !prop_info->gprop_to_dbus_fcn); + nm_assert (!prop_info->from_dbus_fcn || !prop_info->gprop_from_dbus_fcn); + + nm_assert (!prop_info->gprop_to_dbus_fcn || prop_info->param_spec); + nm_assert (!prop_info->gprop_from_dbus_fcn || prop_info->param_spec); g_array_append_vals (properties_override, prop_info, 1); if (!prop_info->name) { /* for convenience, allow omitting "name" if "param_spec" is given. */ - g_array_index (properties_override, - NMSettInfoProperty, - properties_override->len - 1).name = prop_info->param_spec->name; + p = &g_array_index (properties_override, + NMSettInfoProperty, + properties_override->len - 1); + nm_assert (p->param_spec); + p->name = p->param_spec->name; } } @@ -229,34 +257,34 @@ _properties_override_add_struct (GArray *properties_override, * @properties_override: an array collecting the overrides * @property_name: the name of the property to override * @dbus_type: the type of the property (in its D-Bus representation) - * @synth_func: (allow-none): function to call to synthesize a value for the property - * @set_func: (allow-none): function to call to set the value of the property + * @to_dbus_fcn: (allow-none): function to call to synthesize a value for the property + * @from_dbus_fcn: (allow-none): function to call to set the value of the property * * Registers a property named @property_name, which will be used in the D-Bus * serialization of objects of this setting type, but which does not correspond to * a #GObject property. * - * When serializing a setting to D-Bus, @synth_func will be called to synthesize + * When serializing a setting to D-Bus, @to_dbus_fcn will be called to synthesize * a value for the property. (If it returns %NULL, no value will be added to the - * serialization. If @synth_func is %NULL, the property will always be omitted + * serialization. If @to_dbus_fcn is %NULL, the property will always be omitted * in the serialization.) * * When deserializing a D-Bus representation into a setting, if @property_name - * is present, then @set_func will be called to set it. (If @set_func is %NULL + * is present, then @from_dbus_fcn will be called to set it. (If @from_dbus_fcn is %NULL * then the property will be ignored when deserializing.) */ void _properties_override_add_dbus_only (GArray *properties_override, const char *property_name, const GVariantType *dbus_type, - NMSettingPropertySynthFunc synth_func, - NMSettingPropertySetFunc set_func) + NMSettInfoPropToDBusFcn to_dbus_fcn, + NMSettInfoPropFromDBusFcn from_dbus_fcn) { _properties_override_add (properties_override, - .name = property_name, - .dbus_type = dbus_type, - .synth_func = synth_func, - .set_func = set_func); + .name = property_name, + .dbus_type = dbus_type, + .to_dbus_fcn = to_dbus_fcn, + .from_dbus_fcn = from_dbus_fcn); } /** @@ -264,26 +292,26 @@ _properties_override_add_dbus_only (GArray *properties_override, * @properties_override: an array collecting the overrides * @param_spec: the name of the property to override * @dbus_type: the type of the property (in its D-Bus representation) - * @get_func: (allow-none): function to call to get the value of the property - * @set_func: (allow-none): function to call to set the value of the property - * @not_set_func: (allow-none): function to call to indicate the property was not set + * @to_dbus_fcn: (allow-none): function to call to get the value of the property + * @from_dbus_fcn: (allow-none): function to call to set the value of the property + * @missing_from_dbus_fcn: (allow-none): function to call to indicate the property was not set * * Overrides the D-Bus representation of the #GObject property that shares the * same name as @param_spec. * - * When serializing a setting to D-Bus, if @get_func is non-%NULL, then it will + * When serializing a setting to D-Bus, if @to_dbus_fcn is non-%NULL, then it will * be called to get the property's value. If it returns a #GVariant, the * property will be added to the hash, and if it returns %NULL, the property - * will be omitted. (If @get_func is %NULL, the property will be read normally + * will be omitted. (If @to_dbus_fcn is %NULL, the property will be read normally * with g_object_get_property(), and added to the hash if it is not the default * value.) * * When deserializing a D-Bus representation into a setting, if a value with - * the name of @param_spec is present, then @set_func will be called to set it. - * (If @set_func is %NULL then the property will be set normally with + * the name of @param_spec is present, then @from_dbus_fcn will be called to set it. + * (If @from_dbus_fcn is %NULL then the property will be set normally with * g_object_set_property().) * - * If @not_set_func is non-%NULL, then it will be called when deserializing a + * If @missing_from_dbus_fcn is non-%NULL, then it will be called when deserializing a * representation that does NOT contain a value for the property. This can be used, * eg, if a new property needs to be initialized from some older deprecated property * when it is not present. @@ -292,18 +320,18 @@ void _properties_override_add_override (GArray *properties_override, GParamSpec *param_spec, const GVariantType *dbus_type, - NMSettingPropertyGetFunc get_func, - NMSettingPropertySetFunc set_func, - NMSettingPropertyNotSetFunc not_set_func) + NMSettInfoPropToDBusFcn to_dbus_fcn, + NMSettInfoPropFromDBusFcn from_dbus_fcn, + NMSettInfoPropMissingFromDBusFcn missing_from_dbus_fcn) { nm_assert (param_spec); _properties_override_add (properties_override, - .param_spec = param_spec, - .dbus_type = dbus_type, - .get_func = get_func, - .set_func = set_func, - .not_set_func = not_set_func); + .param_spec = param_spec, + .dbus_type = dbus_type, + .to_dbus_fcn = to_dbus_fcn, + .from_dbus_fcn = from_dbus_fcn, + .missing_from_dbus_fcn = missing_from_dbus_fcn); } /** @@ -311,8 +339,8 @@ _properties_override_add_override (GArray *properties_override, * @properties_override: an array collecting the overrides * @param_spec: the param spec of the property to transform. * @dbus_type: the type of the property (in its D-Bus representation) - * @to_dbus: function to convert from object to D-Bus format - * @from_dbus: function to convert from D-Bus to object format + * @gprop_to_dbus_fcn: function to convert from object to D-Bus format + * @gprop_from_dbus_fcn: function to convert from D-Bus to object format * * Indicates that @property on @setting_class does not have the same format as * its corresponding D-Bus representation, and so must be transformed when @@ -326,16 +354,16 @@ void _properties_override_add_transform (GArray *properties_override, GParamSpec *param_spec, const GVariantType *dbus_type, - NMSettingPropertyTransformToFunc to_dbus, - NMSettingPropertyTransformFromFunc from_dbus) + NMSettInfoPropGPropToDBusFcn gprop_to_dbus_fcn, + NMSettInfoPropGPropFromDBusFcn gprop_from_dbus_fcn) { nm_assert (param_spec); _properties_override_add (properties_override, - .param_spec = param_spec, - .dbus_type = dbus_type, - .to_dbus = to_dbus, - .from_dbus = from_dbus); + .param_spec = param_spec, + .dbus_type = dbus_type, + .gprop_to_dbus_fcn = gprop_to_dbus_fcn, + .gprop_from_dbus_fcn = gprop_from_dbus_fcn); } static NMSettInfoSetting _sett_info_settings[_NM_META_SETTING_TYPE_NUM]; @@ -478,6 +506,49 @@ _nm_setting_class_commit_full (NMSettingClass *setting_class, p->param_spec = property_specs[i]; } + for (i = 0; i < properties_override->len; i++) { + NMSettInfoProperty *p = &g_array_index (properties_override, NMSettInfoProperty, i); + GType vtype; + + if (p->dbus_type) + continue; + + nm_assert (p->param_spec); + nm_assert (!p->gprop_to_dbus_fcn); + + vtype = p->param_spec->value_type; + if (vtype == G_TYPE_BOOLEAN) + p->dbus_type = G_VARIANT_TYPE_BOOLEAN; + else if (vtype == G_TYPE_UCHAR) + p->dbus_type = G_VARIANT_TYPE_BYTE; + else if (vtype == G_TYPE_INT) + p->dbus_type = G_VARIANT_TYPE_INT32; + else if (vtype == G_TYPE_UINT) + p->dbus_type = G_VARIANT_TYPE_UINT32; + else if (vtype == G_TYPE_INT64) + p->dbus_type = G_VARIANT_TYPE_INT64; + else if (vtype == G_TYPE_UINT64) + p->dbus_type = G_VARIANT_TYPE_UINT64; + else if (vtype == G_TYPE_STRING) + p->dbus_type = G_VARIANT_TYPE_STRING; + else if (vtype == G_TYPE_DOUBLE) + p->dbus_type = G_VARIANT_TYPE_DOUBLE; + else if (vtype == G_TYPE_STRV) + p->dbus_type = G_VARIANT_TYPE_STRING_ARRAY; + else if (vtype == G_TYPE_BYTES) { + p->dbus_type = G_VARIANT_TYPE_BYTESTRING; + p->gprop_to_dbus_fcn = _gprop_to_dbus_fcn_bytes; + } else if (g_type_is_a (vtype, G_TYPE_ENUM)) { + p->dbus_type = G_VARIANT_TYPE_INT32; + p->gprop_to_dbus_fcn = _gprop_to_dbus_fcn_enum; + } else if (g_type_is_a (vtype, G_TYPE_FLAGS)) { + p->dbus_type = G_VARIANT_TYPE_UINT32; + p->gprop_to_dbus_fcn = _gprop_to_dbus_fcn_flags; + } + + nm_assert (p->dbus_type); + } + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMSettInfoProperty, name) == 0); g_array_sort (properties_override, nm_strcmp_p); @@ -609,73 +680,80 @@ _nm_setting_use_legacy_property (NMSetting *setting, /*****************************************************************************/ -static const GVariantType * -variant_type_for_gtype (GType type) -{ - if (type == G_TYPE_BOOLEAN) - return G_VARIANT_TYPE_BOOLEAN; - else if (type == G_TYPE_UCHAR) - return G_VARIANT_TYPE_BYTE; - else if (type == G_TYPE_INT) - return G_VARIANT_TYPE_INT32; - else if (type == G_TYPE_UINT) - return G_VARIANT_TYPE_UINT32; - else if (type == G_TYPE_INT64) - return G_VARIANT_TYPE_INT64; - else if (type == G_TYPE_UINT64) - return G_VARIANT_TYPE_UINT64; - else if (type == G_TYPE_STRING) - return G_VARIANT_TYPE_STRING; - else if (type == G_TYPE_DOUBLE) - return G_VARIANT_TYPE_DOUBLE; - else if (type == G_TYPE_STRV) - return G_VARIANT_TYPE_STRING_ARRAY; - else if (type == G_TYPE_BYTES) - return G_VARIANT_TYPE_BYTESTRING; - else if (g_type_is_a (type, G_TYPE_ENUM)) - return G_VARIANT_TYPE_INT32; - else if (g_type_is_a (type, G_TYPE_FLAGS)) - return G_VARIANT_TYPE_UINT32; - else - g_assert_not_reached (); -} - static GVariant * -get_property_for_dbus (NMSetting *setting, - const NMSettInfoProperty *property, - gboolean ignore_default) +property_to_dbus (const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection *connection, + NMSetting *setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options, + gboolean ignore_flags, + gboolean ignore_default) { - GValue prop_value = { 0, }; - GVariant *dbus_value; + const NMSettInfoProperty *property = &sett_info->property_infos[property_idx]; + GVariant *variant; - if (property->get_func) - return property->get_func (setting, property->name); - else - g_return_val_if_fail (property->param_spec != NULL, NULL); + nm_assert (property->dbus_type); - g_value_init (&prop_value, property->param_spec->value_type); - g_object_get_property (G_OBJECT (setting), property->param_spec->name, &prop_value); + if (!property->param_spec) { + if (!property->to_dbus_fcn) + return NULL; + } else if (!ignore_flags) { + if (!NM_FLAGS_HAS (property->param_spec->flags, G_PARAM_WRITABLE)) + return NULL; - if (ignore_default && g_param_value_defaults (property->param_spec, &prop_value)) { - g_value_unset (&prop_value); - return NULL; + if (NM_FLAGS_ANY (property->param_spec->flags, NM_SETTING_PARAM_GENDATA_BACKED)) + return NULL; + + if ( NM_FLAGS_HAS (property->param_spec->flags, NM_SETTING_PARAM_LEGACY) + && !_nm_utils_is_manager_process) + return NULL; + + if (NM_FLAGS_HAS (property->param_spec->flags, NM_SETTING_PARAM_SECRET)) { + if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_NO_SECRETS)) + return NULL; + if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)) { + NMSettingSecretFlags f; + + /* see also _nm_connection_serialize_secrets() */ + if (!nm_setting_get_secret_flags (setting, property->param_spec->name, &f, NULL)) + return NULL; + if (!NM_FLAGS_HAS (f, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + return NULL; + } + } else { + if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)) + return NULL; + } } - if (property->to_dbus) - dbus_value = property->to_dbus (&prop_value); - else if (property->dbus_type) - dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, property->dbus_type); - else if (g_type_is_a (prop_value.g_type, G_TYPE_ENUM)) - dbus_value = g_variant_new_int32 (g_value_get_enum (&prop_value)); - else if (g_type_is_a (prop_value.g_type, G_TYPE_FLAGS)) - dbus_value = g_variant_new_uint32 (g_value_get_flags (&prop_value)); - else if (prop_value.g_type == G_TYPE_BYTES) - dbus_value = nm_utils_gbytes_to_variant_ay (g_value_get_boxed (&prop_value)); - else - dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, variant_type_for_gtype (prop_value.g_type)); - g_value_unset (&prop_value); + if (property->to_dbus_fcn) { + variant = property->to_dbus_fcn (sett_info, property_idx, connection, setting, flags, options); + nm_g_variant_take_ref (variant); + } else { + nm_auto_unset_gvalue GValue prop_value = { 0, }; + + nm_assert (property->param_spec); + + g_value_init (&prop_value, property->param_spec->value_type); + + g_object_get_property (G_OBJECT (setting), property->param_spec->name, &prop_value); - return dbus_value; + if ( ignore_default + && g_param_value_defaults (property->param_spec, &prop_value)) + return NULL; + + if (property->gprop_to_dbus_fcn) { + variant = property->gprop_to_dbus_fcn (&prop_value); + nm_g_variant_take_ref (variant); + } else + variant = g_dbus_gvalue_to_gvariant (&prop_value, property->dbus_type); + } + + nm_assert (!variant || !g_variant_is_floating (variant)); + nm_assert (!variant || g_variant_is_of_type (variant, property->dbus_type)); + + return variant; } static gboolean @@ -683,13 +761,13 @@ set_property_from_dbus (const NMSettInfoProperty *property, GVariant *src_value, GValue *dst_value) { - g_return_val_if_fail (property->param_spec != NULL, FALSE); + nm_assert (property->param_spec); + nm_assert (property->dbus_type); - if (property->from_dbus) { + if (property->gprop_from_dbus_fcn) { if (!g_variant_type_equal (g_variant_get_type (src_value), property->dbus_type)) return FALSE; - - property->from_dbus (src_value, dst_value); + property->gprop_from_dbus_fcn (src_value, dst_value); } else if (dst_value->g_type == G_TYPE_BYTES) { if (!g_variant_is_of_type (src_value, G_VARIANT_TYPE_BYTESTRING)) return FALSE; @@ -719,6 +797,8 @@ set_property_from_dbus (const NMSettInfoProperty *property, * @setting: the #NMSetting * @connection: the #NMConnection containing @setting * @flags: hash flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * @options: the #NMConnectionSerializationOptions options to control + * what/how gets serialized. * * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING * mapping each setting property name to a value describing that property, @@ -728,11 +808,13 @@ set_property_from_dbus (const NMSettInfoProperty *property, * properties **/ GVariant * -_nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags) +_nm_setting_to_dbus (NMSetting *setting, + NMConnection *connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingPrivate *priv; GVariantBuilder builder; - GVariant *dbus_value; const NMSettInfoSetting *sett_info; guint n_properties, i; const char *const*gendata_keys; @@ -753,49 +835,14 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting)); for (i = 0; i < sett_info->property_infos_len; i++) { - const NMSettInfoProperty *property = &sett_info->property_infos[i]; - GParamSpec *prop_spec = property->param_spec; - - if (!prop_spec) { - if (!property->synth_func) - continue; - } else { - - /* For the moment, properties backed by a GObject property don't - * define a synth function. There is no problem supporting that, - * however, for now just disallow it. */ - nm_assert (!property->synth_func); - - if (!(prop_spec->flags & G_PARAM_WRITABLE)) - continue; - - if (NM_FLAGS_ANY (prop_spec->flags, NM_SETTING_PARAM_GENDATA_BACKED)) - continue; - - if ( (prop_spec->flags & NM_SETTING_PARAM_LEGACY) - && !_nm_utils_is_manager_process) - continue; - - if ( (flags & NM_CONNECTION_SERIALIZE_NO_SECRETS) - && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) - continue; - - if ( (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) - && !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) - continue; - } - - if (property->synth_func) - dbus_value = property->synth_func (sett_info, i, connection, setting, flags); - else - dbus_value = get_property_for_dbus (setting, property, TRUE); + gs_unref_variant GVariant *dbus_value = NULL; + dbus_value = property_to_dbus (sett_info, i, connection, setting, flags, options, FALSE, TRUE); if (dbus_value) { - /* Allow dbus_value to be either floating or not. */ - g_variant_take_ref (dbus_value); - - g_variant_builder_add (&builder, "{sv}", property->name, dbus_value); - g_variant_unref (dbus_value); + g_variant_builder_add (&builder, + "{sv}", + sett_info->property_infos[i].name, + dbus_value); } } @@ -829,10 +876,9 @@ _nm_setting_new_from_dbus (GType setting_type, NMSettingParseFlags parse_flags, GError **error) { + gs_unref_ptrarray GPtrArray *keys_keep_variant = NULL; gs_unref_object NMSetting *setting = NULL; gs_unref_hashtable GHashTable *keys = NULL; - const NMSettInfoSetting *sett_info; - guint i; g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL); g_return_val_if_fail (g_variant_is_of_type (setting_dict, NM_VARIANT_TYPE_SETTING), NULL); @@ -856,18 +902,19 @@ _nm_setting_new_from_dbus (GType setting_type, if (NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { GVariantIter iter; GVariant *entry, *entry_key; - char *key; + const char *key; - keys = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); + keys_keep_variant = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref); + keys = g_hash_table_new (nm_str_hash, g_str_equal); g_variant_iter_init (&iter, setting_dict); while ((entry = g_variant_iter_next_value (&iter))) { entry_key = g_variant_get_child_value (entry, 0); - key = g_strdup (g_variant_get_string (entry_key, NULL)); - g_variant_unref (entry_key); + g_ptr_array_add (keys_keep_variant, entry_key); g_variant_unref (entry); - if (!g_hash_table_add (keys, key)) { + key = g_variant_get_string (entry_key, NULL); + if (!g_hash_table_add (keys, (char *) key)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, _("duplicate property")); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), key); @@ -876,6 +923,47 @@ _nm_setting_new_from_dbus (GType setting_type, } } + if (!NM_SETTING_GET_CLASS (setting)->init_from_dbus (setting, + keys, + setting_dict, + connection_dict, + parse_flags, + error)) + return NULL; + + if ( NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT) + && g_hash_table_size (keys) > 0) { + GHashTableIter iter; + const char *key; + + g_hash_table_iter_init (&iter, keys); + if (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown property")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), key); + return NULL; + } + } + + return g_steal_pointer (&setting); +} + +static gboolean +init_from_dbus (NMSetting *setting, + GHashTable *keys, + GVariant *setting_dict, + GVariant *connection_dict, + guint /* NMSettingParseFlags */ parse_flags, + GError **error) +{ + const NMSettInfoSetting *sett_info; + + guint i; + + nm_assert (NM_IS_SETTING (setting)); + nm_assert (!NM_FLAGS_ANY (parse_flags, ~NM_SETTING_PARSE_FLAGS_ALL)); + nm_assert (!NM_FLAGS_ALL (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT | NM_SETTING_PARSE_FLAGS_BEST_EFFORT)); + sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting)); if (sett_info->detail.gendata_info) { @@ -891,10 +979,12 @@ _nm_setting_new_from_dbus (GType setting_type, g_hash_table_insert (hash, key, val); + if (keys) + g_hash_table_remove (keys, key); } _nm_setting_gendata_notify (setting, TRUE); - return g_steal_pointer (&setting); + return TRUE; } for (i = 0; i < sett_info->property_infos_len; i++) { @@ -908,11 +998,12 @@ _nm_setting_new_from_dbus (GType setting_type, value = g_variant_lookup_value (setting_dict, property_info->name, NULL); - if (value && keys) + if ( value + && keys) g_hash_table_remove (keys, property_info->name); if ( value - && property_info->set_func) { + && property_info->from_dbus_fcn) { if (!g_variant_type_equal (g_variant_get_type (value), property_info->dbus_type)) { /* for backward behavior, fail unless best-effort is chosen. */ @@ -926,37 +1017,37 @@ _nm_setting_new_from_dbus (GType setting_type, g_type_name (property_info->param_spec->value_type) : "(unknown)", g_variant_get_type_string (value)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property_info->name); - return NULL; + return FALSE; } - if (!property_info->set_func (setting, - connection_dict, - property_info->name, - value, - parse_flags, - &local)) { + if (!property_info->from_dbus_fcn (setting, + connection_dict, + property_info->name, + value, + parse_flags, + &local)) { if (!NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) continue; g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("failed to set property: %s"), local->message); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property_info->name); - return NULL; + return FALSE; } } else if ( !value - && property_info->not_set_func) { - if (!property_info->not_set_func (setting, - connection_dict, - property_info->name, - parse_flags, - &local)) { + && property_info->missing_from_dbus_fcn) { + if (!property_info->missing_from_dbus_fcn (setting, + connection_dict, + property_info->name, + parse_flags, + &local)) { if (!NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) continue; g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("failed to set property: %s"), local->message); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property_info->name); - return NULL; + return FALSE; } } else if ( value && property_info->param_spec) { @@ -976,7 +1067,7 @@ _nm_setting_new_from_dbus (GType setting_type, : "(unknown)"), g_variant_get_type_string (value)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property_info->name); - return NULL; + return FALSE; } if (!nm_g_object_set_property (G_OBJECT (setting), property_info->param_spec->name, &object_value, &local)) { @@ -986,26 +1077,12 @@ _nm_setting_new_from_dbus (GType setting_type, _("can not set property: %s"), local->message); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property_info->name); - return NULL; + return FALSE; } } } - if ( NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT) - && g_hash_table_size (keys) > 0) { - GHashTableIter iter; - const char *key; - - g_hash_table_iter_init (&iter, keys); - if (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("unknown property")); - g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), key); - return NULL; - } - } - - return g_steal_pointer (&setting); + return TRUE; } /** @@ -1028,12 +1105,12 @@ nm_setting_get_dbus_property_type (NMSetting *setting, g_return_val_if_fail (property_name != NULL, NULL); property = _nm_setting_class_get_property_info (NM_SETTING_GET_CLASS (setting), property_name); + g_return_val_if_fail (property != NULL, NULL); - if (property->dbus_type) - return property->dbus_type; - else - return variant_type_for_gtype (property->param_spec->value_type); + nm_assert (property->dbus_type); + + return property->dbus_type; } gboolean @@ -1342,8 +1419,10 @@ _nm_setting_should_compare_secret_property (NMSetting *setting, static NMTernary compare_property (const NMSettInfoSetting *sett_info, guint property_idx, - NMSetting *setting, - NMSetting *other, + NMConnection *con_a, + NMSetting *set_a, + NMConnection *con_b, + NMSetting *set_b, NMSettingCompareFlags flags) { const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx]; @@ -1372,19 +1451,18 @@ compare_property (const NMSettInfoSetting *sett_info, return NM_TERNARY_DEFAULT; if ( NM_FLAGS_HAS (param_spec->flags, NM_SETTING_PARAM_SECRET) - && !_nm_setting_should_compare_secret_property (setting, - other, + && !_nm_setting_should_compare_secret_property (set_a, + set_b, param_spec->name, flags)) return NM_TERNARY_DEFAULT; - if (other) { + if (set_b) { gs_unref_variant GVariant *value1 = NULL; gs_unref_variant GVariant *value2 = NULL; - value1 = get_property_for_dbus (setting, property_info, TRUE); - value2 = get_property_for_dbus (other, property_info, TRUE); - + value1 = property_to_dbus (sett_info, property_idx, con_a, set_a, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE, TRUE); + value2 = property_to_dbus (sett_info, property_idx, con_b, set_b, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE, TRUE); if (nm_property_compare (value1, value2) != 0) return NM_TERNARY_FALSE; } @@ -1395,8 +1473,10 @@ compare_property (const NMSettInfoSetting *sett_info, static NMTernary _compare_property (const NMSettInfoSetting *sett_info, guint property_idx, - NMSetting *setting, - NMSetting *other, + NMConnection *con_a, + NMSetting *set_a, + NMConnection *con_b, + NMSetting *set_b, NMSettingCompareFlags flags) { NMTernary compare_result; @@ -1404,14 +1484,16 @@ _compare_property (const NMSettInfoSetting *sett_info, nm_assert (sett_info); nm_assert (NM_IS_SETTING_CLASS (sett_info->setting_class)); nm_assert (property_idx < sett_info->property_infos_len); - nm_assert (NM_SETTING_GET_CLASS (setting) == sett_info->setting_class); - nm_assert (!other || NM_SETTING_GET_CLASS (other) == sett_info->setting_class); + nm_assert (NM_SETTING_GET_CLASS (set_a) == sett_info->setting_class); + nm_assert (!set_b || NM_SETTING_GET_CLASS (set_b) == sett_info->setting_class); - compare_result = NM_SETTING_GET_CLASS (setting)->compare_property (sett_info, - property_idx, - setting, - other, - flags); + compare_result = NM_SETTING_GET_CLASS (set_a)->compare_property (sett_info, + property_idx, + con_a, + set_a, + con_b, + set_b, + flags); nm_assert (NM_IN_SET (compare_result, NM_TERNARY_DEFAULT, NM_TERNARY_FALSE, @@ -1443,12 +1525,25 @@ nm_setting_compare (NMSetting *a, NMSetting *b, NMSettingCompareFlags flags) { + return _nm_setting_compare (NULL, a, NULL, b, flags); +} + +gboolean +_nm_setting_compare (NMConnection *con_a, + NMSetting *a, + NMConnection *con_b, + NMSetting *b, + NMSettingCompareFlags flags) +{ const NMSettInfoSetting *sett_info; guint i; g_return_val_if_fail (NM_IS_SETTING (a), FALSE); g_return_val_if_fail (NM_IS_SETTING (b), FALSE); + nm_assert (!con_a || NM_IS_CONNECTION (con_a)); + nm_assert (!con_b || NM_IS_CONNECTION (con_b)); + /* First check that both have the same type */ if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) return FALSE; @@ -1466,7 +1561,7 @@ nm_setting_compare (NMSetting *a, } for (i = 0; i < sett_info->property_infos_len; i++) { - if (_compare_property (sett_info, i, a, b, flags) == NM_TERNARY_FALSE) + if (_compare_property (sett_info, i, con_a, a, con_b, b, flags) == NM_TERNARY_FALSE) return FALSE; } @@ -1516,6 +1611,18 @@ nm_setting_diff (NMSetting *a, gboolean invert_results, GHashTable **results) { + return _nm_setting_diff (NULL, a, NULL, b, flags, invert_results, results); +} + +gboolean +_nm_setting_diff (NMConnection *con_a, + NMSetting *a, + NMConnection *con_b, + NMSetting *b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable **results) +{ const NMSettInfoSetting *sett_info; guint i; NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A; @@ -1533,6 +1640,9 @@ nm_setting_diff (NMSetting *a, g_return_val_if_fail (G_OBJECT_TYPE (a) == G_OBJECT_TYPE (b), FALSE); } + nm_assert (!con_a || NM_IS_CONNECTION (con_a)); + nm_assert (!con_b || NM_IS_CONNECTION (con_b)); + if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) { /* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */ @@ -1609,7 +1719,7 @@ nm_setting_diff (NMSetting *a, NMTernary compare_result; GParamSpec *prop_spec; - compare_result = _compare_property (sett_info, i, a, b, flags); + compare_result = _compare_property (sett_info, i, con_a, a, con_b, b, flags); if (compare_result == NM_TERNARY_DEFAULT) continue; @@ -1630,7 +1740,7 @@ nm_setting_diff (NMSetting *a, * * We need to double-check whether the property should be ignored by * looking at @a alone. */ - if (_compare_property (sett_info, i, a, NULL, flags) == NM_TERNARY_DEFAULT) + if (_compare_property (sett_info, i, con_a, a, NULL, NULL, flags) == NM_TERNARY_DEFAULT) continue; } @@ -2278,7 +2388,7 @@ nm_setting_to_string (NMSetting *setting) string = g_string_new (nm_setting_get_name (setting)); g_string_append_c (string, '\n'); - variant = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL); + variant = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_variant_iter_init (&iter, variant); while ((child = g_variant_iter_next_value (&iter))) { @@ -2300,7 +2410,8 @@ _nm_setting_get_deprecated_virtual_interface_name (const NMSettInfoSetting *sett guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingConnection *s_con; @@ -2612,21 +2723,6 @@ static void nm_setting_class_init (NMSettingClass *setting_class) { GObjectClass *object_class = G_OBJECT_CLASS (setting_class); - GModule *self_module; - gpointer func; - - /* loading libnm and legacy libraries libnm-util/libnm-glib at the same - * time is not supported. The reason is, that both libraries use the same - * glib type names ("NMSetting"), and glib does not support namespacing - * to allow for that. - * - * Arbitrarily, add a check here, see whether a known symbol from libnm-util - * is present. If it is, it indicates that the process is borked and we - * abort. */ - self_module = g_module_open (NULL, 0); - if (g_module_symbol (self_module, "nm_util_get_private", &func)) - g_error ("libnm-util symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); - g_module_close (self_module); g_type_class_add_private (setting_class, sizeof (NMSettingPrivate)); @@ -2642,6 +2738,7 @@ nm_setting_class_init (NMSettingClass *setting_class) setting_class->duplicate_copy_properties = duplicate_copy_properties; setting_class->enumerate_values = enumerate_values; setting_class->aggregate = aggregate; + setting_class->init_from_dbus = init_from_dbus; /** * NMSetting:name: |