diff options
| author | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
| commit | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (patch) | |
| tree | cce7b0b02d28fae2df9fdf2c1804cacd1500f2d7 /clients/cli | |
| parent | 9a6dcbf895f9da01768e64b73cec88c16157d91e (diff) | |
New upstream version 1.18.0 upstream/1.18.0
Diffstat (limited to 'clients/cli')
| -rw-r--r-- | clients/cli/connections.c | 256 | ||||
| -rw-r--r-- | clients/cli/devices.c | 1 | ||||
| -rw-r--r-- | clients/cli/general.c | 4 | ||||
| -rw-r--r-- | clients/cli/meson.build | 2 | ||||
| -rw-r--r-- | clients/cli/settings.c | 261 | ||||
| -rw-r--r-- | clients/cli/settings.h | 13 | ||||
| -rw-r--r-- | clients/cli/utils.c | 3 |
7 files changed, 199 insertions, 341 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 6db44f87..6ee3b49f 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1276,12 +1276,18 @@ static void update_secrets_in_connection (NMRemoteConnection *remote, NMConnection *local) { GetSecretsData data = { 0, }; + GType setting_type; int i; data.local = local; data.loop = g_main_loop_new (NULL, FALSE); for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + setting_type = nm_meta_setting_infos[i].get_setting_gtype(); + if (!nm_connection_get_setting (NM_CONNECTION (remote), setting_type)) + continue; + if (!nm_meta_setting_info_editor_has_secrets (nm_meta_setting_info_editor_find_by_gtype (setting_type))) + continue; data.setting_name = nm_meta_setting_infos[i].setting_name; nm_remote_connection_get_secrets_async (remote, nm_meta_setting_infos[i].setting_name, @@ -1522,15 +1528,13 @@ split_required_fields_for_con_show (const char *input, char **active_flds, GError **error) { - char **fields, **iter; - char *dot; - GString *str1, *str2; - gboolean found; + gs_free const char **fields = NULL; + const char *const*iter; + nm_auto_free_gstring GString *str1 = NULL; + nm_auto_free_gstring GString *str2 = NULL; gboolean group_profile = FALSE; gboolean group_active = FALSE; - gboolean success = TRUE; - gboolean is_all, is_common; - int i; + gboolean do_free; if (!input) { *profile_flds = NULL; @@ -1541,25 +1545,30 @@ split_required_fields_for_con_show (const char *input, str1 = g_string_new (NULL); str2 = g_string_new (NULL); - /* Split supplied fields string */ - fields = g_strsplit_set (input, ",", -1); + fields = nm_utils_strsplit_set_with_empty (input, ","); for (iter = fields; iter && *iter; iter++) { - g_strstrip (*iter); - dot = strchr (*iter, '.'); + char *s_mutable = (char *) (*iter); + char *dot; + gboolean is_all; + gboolean is_common; + gboolean found; + int i; + + g_strstrip (s_mutable); + dot = strchr (s_mutable, '.'); if (dot) *dot = '\0'; - is_all = !dot && strcasecmp (*iter, "all") == 0; - is_common = !dot && strcasecmp (*iter, "common") == 0; + is_all = !dot && strcasecmp (s_mutable, "all") == 0; + is_common = !dot && strcasecmp (s_mutable, "common") == 0; found = FALSE; - for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { if ( is_all || is_common - || !strcasecmp (*iter, nm_meta_setting_infos[i].setting_name)) { + || !strcasecmp (s_mutable, nm_meta_setting_infos[i].setting_name)) { if (dot) *dot = '.'; - g_string_append (str1, *iter); + g_string_append (str1, s_mutable); g_string_append_c (str1, ','); found = TRUE; break; @@ -1567,12 +1576,13 @@ split_required_fields_for_con_show (const char *input, } if (found) continue; + for (i = 0; nmc_fields_con_active_details_groups[i]; i++) { if ( is_all || is_common - || !strcasecmp (*iter, nmc_fields_con_active_details_groups[i]->name)) { + || !strcasecmp (s_mutable, nmc_fields_con_active_details_groups[i]->name)) { if (dot) *dot = '.'; - g_string_append (str2, *iter); + g_string_append (str2, s_mutable); g_string_append_c (str2, ','); found = TRUE; break; @@ -1581,55 +1591,49 @@ split_required_fields_for_con_show (const char *input, if (!found) { if (dot) *dot = '.'; - if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_PROFILE)) + if (!strcasecmp (s_mutable, CON_SHOW_DETAIL_GROUP_PROFILE)) group_profile = TRUE; - else if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_ACTIVE)) + else if (!strcasecmp (s_mutable, CON_SHOW_DETAIL_GROUP_ACTIVE)) group_active = TRUE; else { - char *allowed1 = nm_meta_abstract_infos_get_names_str ((const NMMetaAbstractInfo *const*) nm_meta_setting_infos_editor_p (), NULL); - char *allowed2 = nm_meta_abstract_infos_get_names_str ((const NMMetaAbstractInfo *const*) nmc_fields_con_active_details_groups, NULL); + gs_free char *allowed1 = nm_meta_abstract_infos_get_names_str ((const NMMetaAbstractInfo *const*) nm_meta_setting_infos_editor_p (), NULL); + gs_free char *allowed2 = nm_meta_abstract_infos_get_names_str ((const NMMetaAbstractInfo *const*) nmc_fields_con_active_details_groups, NULL); + g_set_error (error, NMCLI_ERROR, 0, _("invalid field '%s'; allowed fields: %s and %s, or %s,%s"), - *iter, allowed1, allowed2, CON_SHOW_DETAIL_GROUP_PROFILE, CON_SHOW_DETAIL_GROUP_ACTIVE); - g_free (allowed1); - g_free (allowed2); - success = FALSE; - break; + s_mutable, allowed1, allowed2, CON_SHOW_DETAIL_GROUP_PROFILE, CON_SHOW_DETAIL_GROUP_ACTIVE); + return FALSE; } } } - if (fields) - g_strfreev (fields); /* Handle pseudo groups: profile, active */ - if (success && group_profile) { + if (group_profile) { if (str1->len > 0) { g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), CON_SHOW_DETAIL_GROUP_PROFILE); - success = FALSE; - } else - g_string_assign (str1, "all,"); + return FALSE; + } + g_string_assign (str1, "all,"); } - if (success && group_active) { + if (group_active) { if (str2->len > 0) { g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), CON_SHOW_DETAIL_GROUP_ACTIVE); - success = FALSE; - } else - g_string_assign (str2, "all,"); + return FALSE; + } + g_string_assign (str2, "all,"); } - if (success) { - if (str1->len > 0) - g_string_truncate (str1, str1->len - 1); - if (str2->len > 0) - g_string_truncate (str2, str2->len - 1); - *profile_flds = g_string_free (str1, str1->len == 0); - *active_flds = g_string_free (str2, str2->len == 0); - } else { - g_string_free (str1, TRUE); - g_string_free (str2, TRUE); - } - return success; + if (str1->len > 0) + g_string_truncate (str1, str1->len - 1); + if (str2->len > 0) + g_string_truncate (str2, str2->len - 1); + + do_free = (str1->len == 0); + *profile_flds = g_string_free (g_steal_pointer (&str1), do_free); + do_free = (str2->len == 0); + *active_flds = g_string_free (g_steal_pointer (&str2), do_free); + return TRUE; } typedef enum { @@ -1870,7 +1874,7 @@ parse_preferred_connection_order (const char *order, GError **error) gboolean inverse, unique; int i; - strv = nm_utils_strsplit_set (order, ":", FALSE); + strv = nm_utils_strsplit_set (order, ":"); if (!strv) { g_set_error (error, NMCLI_ERROR, 0, _("incorrect string '%s' of '--order' option"), order); @@ -2674,7 +2678,7 @@ parse_passwords (const char *passwd_file, GError **error) return NULL; } - strv = nm_utils_strsplit_set (contents, "\r\n", FALSE); + strv = nm_utils_strsplit_set (contents, "\r\n"); for (iter = strv; *iter; iter++) { gs_free char *iter_s = g_strdup (*iter); @@ -3959,11 +3963,12 @@ set_property (NMClient *client, char modifier, GError **error) { - gs_free char *property_name = NULL, *value_free = NULL; + gs_free char *property_name = NULL; + gs_free_error GError *local = NULL; NMSetting *setting; - GError *local = NULL; - g_assert (setting_name && setting_name[0]); + nm_assert (setting_name && setting_name[0]); + nm_assert (NM_IN_SET (modifier, '\0', '+', '-')); setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { @@ -3977,48 +3982,26 @@ set_property (NMClient *client, g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("Error: invalid property '%s': %s."), property, local->message); - g_clear_error (&local); return FALSE; } - if (modifier != '-') { - /* Set/add value */ - if (modifier != '+') { - /* We allow the existing property value to be passed as parameter, - * so make a copy if we are going to free it. - */ - value = value_free = g_strdup (value); - nmc_setting_reset_property (setting, property_name, NULL); - } - if (!nmc_setting_set_property (client, setting, property_name, value, &local)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: failed to modify %s.%s: %s."), - setting_name, property, local->message); - g_clear_error (&local); - return FALSE; - } - } else { - /* Remove value - * - either empty: remove whole value - * - or specified by index <0-n>: remove item at the index - * - or option name: remove item with the option name - */ - if (value) { - unsigned long idx; - - if (nmc_string_to_uint (value, TRUE, 0, G_MAXUINT32, &idx)) - nmc_setting_remove_property_option (setting, property_name, NULL, idx, &local); - else - nmc_setting_remove_property_option (setting, property_name, value, 0, &local); - if (local) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: failed to remove a value from %s.%s: %s."), - setting_name, property, local->message); - g_clear_error (&local); - return FALSE; - } - } else - nmc_setting_reset_property (setting, property_name, NULL); + if (!nmc_setting_set_property (client, + setting, + property_name, + ( (modifier == '-' && !value) + ? '\0' + : modifier), + value, + &local)) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: failed to %s %s.%s: %s."), + ( modifier != '-' + ? "modify" + : "remove a value from"), + setting_name, + property, + local->message); + return FALSE; } /* Don't ask for this property in interactive mode. */ @@ -6904,7 +6887,6 @@ property_edit_submenu (NmCli *nmc, gs_free char *cmd_property_user = NULL; gs_free char *cmd_property_arg = NULL; gs_free char *prop_val_user = NULL; - nm_auto_unset_gvalue GValue prop_g_value = G_VALUE_INIT; gboolean removed; gboolean dirty; @@ -6954,24 +6936,17 @@ property_edit_submenu (NmCli *nmc, } else prop_val_user = g_strdup (cmd_property_arg); - /* nmc_setting_set_property() only adds new value, thus we have to - * remove the original value and save it for error cases. - */ - if (cmdsub == NMC_EDITOR_SUB_CMD_SET) { - nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value); - nmc_property_set_default_value (curr_setting, prop_name); - } - - set_result = nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err); + set_result = nmc_setting_set_property (nmc->client, + curr_setting, + prop_name, + (cmdsub == NMC_EDITOR_SUB_CMD_SET) + ? '\0' + : '+', + prop_val_user, + &tmp_err); if (!set_result) { g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); - if (cmdsub == NMC_EDITOR_SUB_CMD_SET) { - /* Block change signals and restore original value */ - g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); - nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value); - g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); - } } break; @@ -6982,41 +6957,23 @@ property_edit_submenu (NmCli *nmc, _("Edit '%s' value: "), prop_name); - nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value); - nmc_property_set_default_value (curr_setting, prop_name); - - if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err)) { + if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, '\0', prop_val_user, &tmp_err)) { g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); - g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); - nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value); - g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); } break; case NMC_EDITOR_SUB_CMD_REMOVE: - if (cmd_property_arg) { - unsigned long val_int = G_MAXUINT32; - gs_free char *option = NULL; - - if (!nmc_string_to_uint (cmd_property_arg, TRUE, 0, G_MAXUINT32, &val_int)) { - option = g_strdup (cmd_property_arg); - g_strstrip (option); - } - - if (!nmc_setting_remove_property_option (curr_setting, prop_name, - option, - (guint32) val_int, - &tmp_err)) { - g_print (_("Error: %s\n"), tmp_err->message); - g_clear_error (&tmp_err); - } - } else { - if (!nmc_setting_reset_property (curr_setting, prop_name, &tmp_err)) { - g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name, - tmp_err->message); - g_clear_error (&tmp_err); - } + if (!nmc_setting_set_property (nmc->client, + curr_setting, + prop_name, + ( cmd_property_arg + ? '-' + : '\0'), + cmd_property_arg, + &tmp_err)) { + g_print (_("Error: %s\n"), tmp_err->message); + g_clear_error (&tmp_err); } break; @@ -7367,8 +7324,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t _("Enter '%s' value: "), prop_name); - /* Set property value */ - if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, prop_val_user, &tmp_err)) { + if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '+', prop_val_user, &tmp_err)) { g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); } @@ -7428,8 +7384,13 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t prop_name); } - /* Set property value */ - if (!nmc_setting_set_property (nmc->client, ss, prop_name, cmd_arg_v, &tmp_err)) { + /* setting a value in edit mode "appends". That seems unexpected behavior. */ + if (!nmc_setting_set_property (nmc->client, + ss, + prop_name, + cmd_arg_v ? '+' : '\0', + cmd_arg_v, + &tmp_err)) { g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); @@ -7526,8 +7487,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t if (!prop_name) break; - /* Delete property value */ - if (!nmc_setting_reset_property (menu_ctx.curr_setting, prop_name, &tmp_err)) { + if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '\0', NULL, &tmp_err)) { g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); @@ -7577,8 +7537,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t prop_name = is_property_valid (ss, cmd_arg_p, &tmp_err); if (prop_name) { - /* Delete property value */ - if (!nmc_setting_reset_property (ss, prop_name, &tmp_err)) { + if (!nmc_setting_set_property (nmc->client, ss, prop_name, '\0', NULL, &tmp_err)) { g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); @@ -8148,6 +8107,9 @@ editor_init_existing_connection (NMConnection *connection) NMSettingWireless *s_wireless; NMSettingConnection *s_con; + /* FIXME: this approach of connecting handlers to do something is fundamentally + * flawed. See the comment in nmc_setting_ip6_connect_handlers(). */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); s_proxy = nm_connection_get_setting_proxy (connection); @@ -8585,7 +8547,7 @@ delete_cb (GObject *con, GAsyncResult *result, gpointer user_data) if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; g_string_printf (info->nmc->return_text, _("Error: not all connections deleted.")); - g_printerr (_("Error: Connection deletion failed: %s"), + g_printerr (_("Error: Connection deletion failed: %s\n"), error->message); g_error_free (error); info->nmc->return_value = NMC_RESULT_ERROR_CON_DEL; diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 04a8c988..ad3a44c4 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -3888,6 +3888,7 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) info->nmc = nmc; info->device = device; info->hotspot = TRUE; + info->create = TRUE; nm_client_add_and_activate_connection_async (nmc->client, connection, diff --git a/clients/cli/general.c b/clients/cli/general.c index 2c22bdc9..d713426b 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -23,7 +23,7 @@ #include <stdlib.h> -#include "nm-common-macros.h" +#include "nm-libnm-core-intern/nm-common-macros.h" #include "nm-client-utils.h" @@ -1350,7 +1350,7 @@ do_overview (NmCli *nmc, int argc, char **argv) g_print (_("Use \"nmcli device show\" to get complete information about known devices and\n" "\"nmcli connection show\" to get an overview on active connection profiles.\n" "\n" - "Consult nmcli(1) and nmcli-examples(5) manual pages for complete usage details.\n")); + "Consult nmcli(1) and nmcli-examples(7) manual pages for complete usage details.\n")); return NMC_RESULT_SUCCESS; } diff --git a/clients/cli/meson.build b/clients/cli/meson.build index 11fe1cd1..396466a2 100644 --- a/clients/cli/meson.build +++ b/clients/cli/meson.build @@ -22,7 +22,7 @@ deps = [ libnm_dep, libnmc_base_dep, libnmc_dep, - nm_core_dep, + libnm_core_dep, readline_dep, ] diff --git a/clients/cli/settings.c b/clients/cli/settings.c index a04c8eb6..2446cb08 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -24,7 +24,7 @@ #include <stdlib.h> #include <arpa/inet.h> -#include "nm-common-macros.h" +#include "nm-libnm-core-intern/nm-common-macros.h" #include "nm-client-utils.h" #include "nm-vpn-helpers.h" @@ -89,7 +89,7 @@ ipv4_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat static void ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) { - static GValue value = G_VALUE_INIT; + static GPtrArray *old_value = NULL; static gboolean answered = FALSE; static gboolean answer = FALSE; @@ -103,17 +103,17 @@ ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) answer = get_answer ("ipv4.addresses", NULL); } if (answer) { - if (G_IS_VALUE (&value)) - g_value_unset (&value); - nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value); + nm_clear_pointer (&old_value, g_ptr_array_unref); + g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL); g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL); } } } else { answered = FALSE; - if (G_IS_VALUE (&value)) { - nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value); - g_value_unset (&value); + if (old_value) { + gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value); + + g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL); } } @@ -142,6 +142,25 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat } } else { answered = FALSE; + /* FIXME: editor_init_existing_connection() and registering handlers is not the + * right approach. + * + * This only happens to work because in nmcli's edit mode + * tends to append addresses -- instead of setting them. + * If we would change that (to behavior I'd expect), we'd get: + * + * nmcli> set ipv6.addresses fc01::1:5/68 + * Do you also want to set 'ipv6.method' to 'manual'? [yes]: y + * nmcli> set ipv6.addresses fc01::1:6/68 + * Do you also want to set 'ipv6.method' to 'manual'? [yes]: + * + * That's because nmc_setting_set_property() calls set_fcn(). With modifier '\0' + * (set), it would first clear all addresses before adding the address. Thereby + * emitting multiple property changed signals. + * + * That can be avoided by freezing/thawing the signals, but this solution + * here is ugly in general. + */ if (!g_strcmp0 (nm_setting_ip_config_get_method (NM_SETTING_IP_CONFIG (object)), NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) g_object_set (object, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); } @@ -152,7 +171,7 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat static void ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) { - static GValue value = G_VALUE_INIT; + static GPtrArray *old_value = NULL; static gboolean answered = FALSE; static gboolean answer = FALSE; @@ -166,17 +185,17 @@ ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) answer = get_answer ("ipv6.addresses", NULL); } if (answer) { - if (G_IS_VALUE (&value)) - g_value_unset (&value); - nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value); + nm_clear_pointer (&old_value, g_ptr_array_unref); + g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL); g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL); } } } else { answered = FALSE; - if (G_IS_VALUE (&value)) { - nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value); - g_value_unset (&value); + if (old_value) { + gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value); + + g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL); } } @@ -319,7 +338,7 @@ _set_fcn_precheck_connection_secondaries (NMClient *client, char **iter; gboolean modified = FALSE; - strv0 = nm_utils_strsplit_set (value, " \t,", FALSE); + strv0 = nm_utils_strsplit_set (value, " \t,"); if (!strv0) return TRUE; @@ -509,152 +528,73 @@ nmc_setting_get_property_parsable (NMSetting *setting, const char *prop, GError return get_property_val (setting, prop, NM_META_ACCESSOR_GET_TYPE_PARSABLE, TRUE, error); } -static gboolean -_set_fcn_call (const NMMetaPropertyInfo *property_info, - NMSetting *setting, - const char *value, - GError **error) -{ - return property_info->property_type->set_fcn (property_info, - nmc_meta_environment, - nmc_meta_environment_arg, - setting, - value, - error); -} - -/* - * Generic function for setting property value. - * - * Sets property=value in setting by calling specialized functions. - * If value is NULL then default property value is set. - * - * Returns: TRUE on success; FALSE on failure and sets error - */ gboolean -nmc_setting_set_property (NMClient *client, NMSetting *setting, const char *prop, const char *value, GError **error) +nmc_setting_set_property (NMClient *client, + NMSetting *setting, + const char *prop, + char modifier, + const char *value, + GError **error) { const NMMetaPropertyInfo *property_info; + gs_free char *value_to_free = NULL; + gboolean success; g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (NM_IN_SET (modifier, '\0', '-', '+'), FALSE); - if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - - if (!value) { - /* No value argument sets default value */ - nmc_property_set_default_value (setting, prop); - return TRUE; - } - - if (property_info->property_type->set_fcn) { - switch (property_info->setting_info->general->meta_type) { - case NM_META_SETTING_TYPE_CONNECTION: - if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) { - gs_free char *value_coerced = NULL; - - if (!_set_fcn_precheck_connection_secondaries (client, value, &value_coerced, error)) - return FALSE; + if (!(property_info = nm_meta_property_info_find_by_setting (setting, prop))) + goto out_fail_read_only; + if (!property_info->property_type->set_fcn) + goto out_fail_read_only; - return _set_fcn_call (property_info, - setting, - value_coerced ?: value, - error); - } - break; - default: - break; - } - return _set_fcn_call (property_info, - setting, - value, - error); - } + if ( NM_IN_SET (modifier, '+', '-') + && !value) { + /* nothing to do. */ + return TRUE; } - g_set_error_literal (error, 1, 0, _("the property can't be changed")); - return FALSE; -} - -void -nmc_property_set_default_value (NMSetting *setting, const char *prop) -{ - GValue value = G_VALUE_INIT; - GParamSpec *param_spec; - - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop); - if (param_spec) { - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (param_spec)); - g_param_value_set_default (param_spec, &value); - g_object_set_property (G_OBJECT (setting), prop, &value); + if ( modifier == '-' + && !property_info->property_type->set_supports_remove) { + /* The property is a plain property. It does not support '-'. + * + * Maybe we should fail, but just return silently. */ + return TRUE; } -} - -/* - * Generic function for resetting (single value) properties. - * - * The function resets the property value to the default one. It respects - * nmcli restrictions for changing properties. So if 'set_func' is NULL, - * resetting the value is denied. - * - * Returns: TRUE on success; FALSE on failure and sets error - */ -gboolean -nmc_setting_reset_property (NMSetting *setting, const char *prop, GError **error) -{ - const NMMetaPropertyInfo *property_info; - - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->property_type->set_fcn) { - nmc_property_set_default_value (setting, prop); - return TRUE; + if (value) { + switch (property_info->setting_info->general->meta_type) { + case NM_META_SETTING_TYPE_CONNECTION: + if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) { + if (!_set_fcn_precheck_connection_secondaries (client, value, &value_to_free, error)) + return FALSE; + if (value_to_free) + value = value_to_free; + } + break; + default: + break; } } - g_set_error_literal (error, 1, 0, _("the property can't be changed")); + g_object_freeze_notify (G_OBJECT (setting)); + success = property_info->property_type->set_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, + setting, + modifier, + value, + error); + g_object_thaw_notify (G_OBJECT (setting)); + return success; + +out_fail_read_only: + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("the property can't be changed")); return FALSE; } /* - * Generic function for removing items for collection-type properties. - * - * If 'option' is not NULL, it tries to remove it, otherwise 'idx' is used. - * For single-value properties (not having specialized remove function) this - * function does nothing and just returns TRUE. - * - * Returns: TRUE on success; FALSE on failure and sets error - */ -gboolean -nmc_setting_remove_property_option (NMSetting *setting, - const char *prop, - const char *option, - guint32 idx, - GError **error) -{ - const NMMetaPropertyInfo *property_info; - - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->property_type->remove_fcn) { - return property_info->property_type->remove_fcn (property_info, - nmc_meta_environment, - nmc_meta_environment_arg, - setting, - option, - idx, - error); - } - } - - return TRUE; -} - -/* * Get valid property names for a setting. * * Returns: string array with the properties or NULL on failure. @@ -749,41 +689,6 @@ nmc_setting_get_property_desc (NMSetting *setting, const char *prop) nmcli_desc ?: ""); } -/* - * Gets setting:prop property value and returns it in 'value'. - * Caller is responsible for freeing the GValue resources using g_value_unset() - */ -gboolean -nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value) -{ - GParamSpec *param_spec; - - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop); - if (param_spec) { - memset (value, 0, sizeof (GValue)); - g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (param_spec)); - g_object_get_property (G_OBJECT (setting), prop, value); - return TRUE; - } - return FALSE; -} - -/* - * Sets setting:prop property value from 'value'. - */ -gboolean -nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value) -{ - GParamSpec *param_spec; - - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop); - if (param_spec && G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (param_spec)) { - g_object_set_property (G_OBJECT (setting), prop, value); - return TRUE; - } - return FALSE; -} - /*****************************************************************************/ gboolean diff --git a/clients/cli/settings.h b/clients/cli/settings.h index 4e7e38df..1ff93685 100644 --- a/clients/cli/settings.h +++ b/clients/cli/settings.h @@ -45,20 +45,9 @@ char *nmc_setting_get_property_parsable (NMSetting *setting, gboolean nmc_setting_set_property (NMClient *client, NMSetting *setting, const char *prop, + char modifier, const char *val, GError **error); -gboolean nmc_setting_reset_property (NMSetting *setting, - const char *prop, - GError **error); -gboolean nmc_setting_remove_property_option (NMSetting *setting, - const char *prop, - const char *option, - guint32 idx, - GError **error); -void nmc_property_set_default_value (NMSetting *setting, const char *prop); - -gboolean nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value); -gboolean nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value); gboolean setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop); diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 0e74ba88..a8b81279 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -508,7 +508,8 @@ nmc_string_to_arg_array (const char *line, const char *delim, gboolean unquote, gs_free const char **arr0 = NULL; char **arr; - arr0 = nm_utils_strsplit_set (line ?: "", delim ?: " \t", FALSE); + arr0 = nm_utils_strsplit_set (line ?: "", + delim ?: " \t"); if (!arr0) arr = g_new0 (char *, 1); else |