From a8e6094e403ebc4bb5de976a152cfcc57ac1a49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 6 Feb 2014 10:31:24 +0100 Subject: [PATCH 01/16] cli: allow temporary connection modification by 'nmcli con modify' nmcli connection modify [--temporary] ... --- cli/src/connections.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 30ac2671ff..49c5dc85c0 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -268,7 +268,7 @@ usage (void) #endif " down [id | uuid | path | apath] \n\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [id | uuid | path] . \n\n" + " modify [--temporary] [id | uuid | path] . \n\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n\n" " delete [id | uuid | path] \n\n" @@ -7825,7 +7825,7 @@ modify_connection_cb (NMRemoteConnection *connection, } static NMCResultCode -do_connection_modify (NmCli *nmc, int argc, char **argv) +do_connection_modify (NmCli *nmc, gboolean temporary, int argc, char **argv) { NMConnection *connection = NULL; NMRemoteConnection *rc = NULL; @@ -7944,9 +7944,7 @@ do_connection_modify (NmCli *nmc, int argc, char **argv) goto finish; } - nm_remote_connection_commit_changes (rc, - modify_connection_cb, - nmc); + update_connection (!temporary, rc, modify_connection_cb, nmc); finish: nmc->should_wait = (nmc->return_value == NMC_RESULT_SUCCESS); g_free (value); @@ -8265,11 +8263,18 @@ parse_cmd (NmCli *nmc, int argc, char **argv) nmc->return_value = do_connection_load (nmc, argc-1, argv+1); } else if (matches (*argv, "modify") == 0) { + gboolean temporary = FALSE; + if (nmc_arg_is_help (*(argv+1))) { usage_connection_modify (); goto usage_exit; } - nmc->return_value = do_connection_modify (nmc, argc-1, argv+1); + next_arg (&argc, &argv); + if (nmc_arg_is_option (*argv, "temporary")) { + temporary = TRUE; + next_arg (&argc, &argv); + } + nmc->return_value = do_connection_modify (nmc, temporary, argc, argv); } else { usage (); From 431b75824b29e50f2ee80b6b0c8e56c0dc769572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 6 Feb 2014 11:12:18 +0100 Subject: [PATCH 02/16] cli: set vs. append property value by 'nmcli con modify' (rh #1044027) Previously 'nmcli con modify' appended values for multi-value properties. This commit makes 'nmcli con modify' overwrite the whole value. You can choose appending values by prefixing the setting.property with '+' sign. For simple (not container) properties the behaviour is the same both with and without the '+', of course. Synopsis: nmcli connection modify [+]. Example: ---> ipv4.dns = 1.2.3.4 $ nmcli connection modify my-em1 ipv4.dns 8.8.8.8 ---> ipv4.dns = 8.8.8.8 $ nmcli connection modify my-em1 +ipv4.dns 8.8.4.4 ---> ipv4.dns = 8.8.8.8 8.8.4.4 https://bugzilla.redhat.com/show_bug.cgi?id=1044027 --- cli/src/connections.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 49c5dc85c0..d204fab4b9 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -268,7 +268,7 @@ usage (void) #endif " down [id | uuid | path | apath] \n\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [--temporary] [id | uuid | path] . \n\n" + " modify [--temporary] [id | uuid | path] [+]. \n\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n\n" " delete [id | uuid | path] \n\n" @@ -416,10 +416,13 @@ usage_connection_modify (void) fprintf (stderr, _("Usage: nmcli connection modify { ARGUMENTS | help }\n" "\n" - "ARGUMENTS := [id | uuid | path] . []\n" + "ARGUMENTS := [id | uuid | path] [+]. \n" "\n" "Modify a single property in the connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path.\n\n")); + "The profile is identified by its name, UUID or D-Bus path.\n\n" + "\n" + "Examples:\n" + "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n\n")); } static void @@ -7825,7 +7828,10 @@ modify_connection_cb (NMRemoteConnection *connection, } static NMCResultCode -do_connection_modify (NmCli *nmc, gboolean temporary, int argc, char **argv) +do_connection_modify (NmCli *nmc, + gboolean temporary, + int argc, + char **argv) { NMConnection *connection = NULL; NMRemoteConnection *rc = NULL; @@ -7839,6 +7845,7 @@ do_connection_modify (NmCli *nmc, gboolean temporary, int argc, char **argv) char **strv = NULL; const char *setting_name; char *property_name = NULL; + gboolean append = FALSE; GError *error = NULL; nmc->should_wait = FALSE; @@ -7894,6 +7901,12 @@ do_connection_modify (NmCli *nmc, gboolean temporary, int argc, char **argv) nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; goto finish; } + + if (set_prop[0] == '+') { + set_prop++; + append = TRUE; + } + strv = g_strsplit (set_prop, ".", 2); if (g_strv_length (strv) != 2) { g_string_printf (nmc->return_text, _("Error: invalid . '%s'."), @@ -7937,6 +7950,8 @@ do_connection_modify (NmCli *nmc, gboolean temporary, int argc, char **argv) nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; } + if (!append) + nmc_setting_reset_property (setting, property_name, NULL); if (!nmc_setting_set_property (setting, property_name, value, &error)) { g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."), strv[0], strv[1], error->message); From a1c3021aa9b7e0f50fda7cb772b1374d2de12ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 12 Feb 2014 10:56:10 +0100 Subject: [PATCH 03/16] cli: allow modifying multiple properties by 'nmcli con modify' This is necessary especially for cases where properties depend on each other. So you need to set them in one command, else the profile won't validate. Examples: nmcli con mod em1-1 ipv4.method manual ipv4.addr "192.168.1.2/24,10.10.1.5/8" nmcli con mod profile ipv4.method link-local ipv4.addr "" --- cli/src/connections.c | 178 ++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 75 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index d204fab4b9..5f1e7ea3be 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -268,7 +268,7 @@ usage (void) #endif " down [id | uuid | path | apath] \n\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [--temporary] [id | uuid | path] [+]. \n\n" + " modify [--temporary] [id | uuid | path] ([+]. )+\n\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n\n" " delete [id | uuid | path] \n\n" @@ -416,12 +416,16 @@ usage_connection_modify (void) fprintf (stderr, _("Usage: nmcli connection modify { ARGUMENTS | help }\n" "\n" - "ARGUMENTS := [id | uuid | path] [+]. \n" + "ARGUMENTS := [id | uuid | path] ([+]. )+\n" "\n" - "Modify a single property in the connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path.\n\n" + "Modify one or more properties of the connection profile.\n" + "The profile is identified by its name, UUID or D-Bus path. The optional '+'\n" + "sign before the property instruct nmcli to append the value instead of \n" + "overwriting it.\n" "\n" "Examples:\n" + "nmcli con mod home-wifi wifi.ssid rakosnicek\n" + "nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, 10.10.1.5/8\"\n" "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n\n")); } @@ -7840,8 +7844,8 @@ do_connection_modify (NmCli *nmc, const char *con_type; const char *name; const char *selector = NULL; - const char *set_prop; - char *value = NULL; + const char *s_dot_p; + const char *value; char **strv = NULL; const char *setting_name; char *property_name = NULL; @@ -7850,6 +7854,15 @@ do_connection_modify (NmCli *nmc, nmc->should_wait = FALSE; + /* create NMClient */ + nmc->get_client (nmc); + + if (!nm_client_get_manager_running (nmc->client)) { + g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); + nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; + goto finish; + } + if (argc == 0) { g_string_printf (nmc->return_text, _("Error: No arguments provided.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; @@ -7869,102 +7882,117 @@ do_connection_modify (NmCli *nmc, name = *argv; } name = *argv; - next_arg (&argc, &argv); - set_prop = *argv; - next_arg (&argc, &argv); - value = g_strjoinv (" ", argv); - if (!name) { g_string_printf (nmc->return_text, _("Error: connection ID is missing.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; } - if (!set_prop) { - g_string_printf (nmc->return_text, _("Error: . argument is missing.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; - } - /* NULL value means deleting/setting default property value */ - - /* create NMClient */ - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto finish; - } - connection = find_connection (nmc->system_connections, selector, name, NULL); if (!connection) { g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), name); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; goto finish; } - - if (set_prop[0] == '+') { - set_prop++; - append = TRUE; - } - - strv = g_strsplit (set_prop, ".", 2); - if (g_strv_length (strv) != 2) { - g_string_printf (nmc->return_text, _("Error: invalid . '%s'."), - set_prop); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; - } - rc = nm_remote_settings_get_connection_by_uuid (nmc->system_settings, nm_connection_get_uuid (connection)); - + if (!rc) { + g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), name); + nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; + goto finish; + } s_con = nm_connection_get_setting_connection (NM_CONNECTION (rc)); g_assert (s_con); con_type = nm_setting_connection_get_connection_type (s_con); - setting_name = check_valid_name (strv[0], get_valid_settings_array (con_type), &error); - if (!setting_name) { - g_string_printf (nmc->return_text, _("Error: invalid or not allowed setting '%s': %s."), - strv[0], error->message); + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: . argument is missing.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; } - setting = nm_connection_get_setting_by_name (NM_CONNECTION (rc), setting_name); - if (!setting) { - setting = nmc_setting_new_for_name (setting_name); - if (!setting) { - /* This should really not happen */ - g_string_printf (nmc->return_text, - "Error: don't know how to create '%s' setting.", - setting_name); - nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - goto finish; - } - nm_connection_add_setting (NM_CONNECTION (rc), setting); - } - property_name = is_property_valid (setting, strv[1], &error); - if (!property_name) { - g_string_printf (nmc->return_text, _("Error: invalid property '%s': %s."), - strv[1], error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; - } - if (!append) - nmc_setting_reset_property (setting, property_name, NULL); - if (!nmc_setting_set_property (setting, property_name, value, &error)) { - g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."), - strv[0], strv[1], error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + /* Go through arguments and set properties */ + while (argc) { + s_dot_p = *argv; + next_arg (&argc, &argv); + value = *argv; + next_arg (&argc, &argv); + + if (!s_dot_p) { + g_string_printf (nmc->return_text, _("Error: . argument is missing.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + if (!value) { + g_string_printf (nmc->return_text, _("Error: value for '%s' is missing."), s_dot_p); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + /* Empty string will reset the value to default */ + if (value[0] == '\0') + value = NULL; + + if (s_dot_p[0] == '+') { + s_dot_p++; + append = TRUE; + } + + strv = g_strsplit (s_dot_p, ".", 2); + if (g_strv_length (strv) != 2) { + g_string_printf (nmc->return_text, _("Error: invalid . '%s'."), + s_dot_p); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + + setting_name = check_valid_name (strv[0], get_valid_settings_array (con_type), &error); + if (!setting_name) { + g_string_printf (nmc->return_text, _("Error: invalid or not allowed setting '%s': %s."), + strv[0], error->message); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + setting = nm_connection_get_setting_by_name (NM_CONNECTION (rc), setting_name); + if (!setting) { + setting = nmc_setting_new_for_name (setting_name); + if (!setting) { + /* This should really not happen */ + g_string_printf (nmc->return_text, + "Error: don't know how to create '%s' setting.", + setting_name); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto finish; + } + nm_connection_add_setting (NM_CONNECTION (rc), setting); + } + + property_name = is_property_valid (setting, strv[1], &error); + if (!property_name) { + g_string_printf (nmc->return_text, _("Error: invalid property '%s': %s."), + strv[1], error->message); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + + if (!append) + nmc_setting_reset_property (setting, property_name, NULL); + if (!nmc_setting_set_property (setting, property_name, value, &error)) { + g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."), + strv[0], strv[1], error->message); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + + g_strfreev (strv); + strv = NULL; } update_connection (!temporary, rc, modify_connection_cb, nmc); + finish: nmc->should_wait = (nmc->return_value == NMC_RESULT_SUCCESS); - g_free (value); g_free (property_name); - g_strfreev (strv); + if (strv) + g_strfreev (strv); g_clear_error (&error); return nmc->return_value; } From 363ec8de685dde94bf261a1b5c445a0d0915fe58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 6 Feb 2014 12:03:55 +0100 Subject: [PATCH 04/16] man: update nmcli manual page - 'nmcli con modify' description --- man/nmcli.1.in | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 856ebc5158..714efa89a2 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -21,7 +21,7 @@ .\" .\" Copyright (C) 2010 - 2014 Red Hat, Inc. .\" -.TH NMCLI "1" "14 January 2014" +.TH NMCLI "1" "17 February 2014" .SH NAME nmcli \- command\(hyline tool for controlling NetworkManager @@ -619,16 +619,25 @@ See also \fInm-settings\fP(5) for all NetworkManager settings and property names descriptions; and \fInmcli-examples\fP(5) for sample editor sessions. .RE .TP -.B modify [ id | uuid | path ] . [] +.B modify [--temporary] [ id | uuid | path ] [+]. +.B [+]. ... .br -Modify a single property in the connection. +Modify one or more properties in the connection profile. .br The connection is identified by its name, UUID or D-Bus path. If is ambiguous, a keyword \fIid\fP, \fIuuid\fP or \fIpath\fP can be used. See \fInm-settings\fP(5) for setting and property names, their descriptions and default values. This command supports abbreviations for \fIsetting name\fP -and \fIproperty name\fP provided they are unique. When \fIvalue\fP is not -specified, the property will be set to the default value (deleted). +and \fIproperty name\fP provided they are unique. Empty \fIvalue\fP ("") +removes the property value (sets the property to the default value). +The provided value overwrite the existing property value. If you want to +append to the existing value instead, use \fI+\fP prefix for the property name. +But it only has a real effect for multi-value (container) properties like ipv4.dns, +ipv4.addresses, etc. +.br +The changed values will be saved persistently by NetworkManager, unless +\fI--temporary\fP option is provided, in which case the changes won't persist +over NetworkManager restart. .TP .B delete [ id | uuid | path ] .br @@ -897,6 +906,14 @@ modifies 'autoconnect' property in the 'connection' setting of 'ethernet\(hy2' c .IP modifies 'mtu' property in the 'wifi' setting of 'Home Wi\(hyFi' connection. +.IP "\fB\f(CWnmcli con mod em1-1 ipv4.method manual ipv4.addr \(dq\&192.168.1.23/24 192.168.1.1, 10.10.1.5/8, 10.0.0.11\(dq\&\fP\fP" +.IP +sets manual addressing and the addresses in em1-1 profile. + +.IP "\fB\f(CWnmcli con modify ABC +ipv4.dns 8.8.8.8\fP\fP" +.IP +appends a Google public DNS server to DNS servers in ABC profile. + .SH NOTES \fInmcli\fP accepts abbreviations, as long as they are a unique prefix in the set of possible options. As new options get added, these abbreviations are not guaranteed From c1ace1b5b2e6815fd1e6cfe650218b0de32d7d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 17 Feb 2014 12:42:17 +0100 Subject: [PATCH 05/16] cli: support removing items from container-type properties in 'nmcli con modify' Synopsis: nmcli con modify -. 'value' can be empty ("") to remove the whole property value value (in this case the behaviour is the same as without '-'). Or the 'value' is an index of the item to remove, or an option name (for a few properties that have option names, like bond.options or ethernet.s390-options). $ nmcli con mod myeth ipv4.dns "10.0.0.55 10.0.0.66 8.8.8.8 8.8.4.4" ---> ipv4.dns: 10.0.0.55, 10.0.0.66, 8.8.8.8, 8.8.4.4 $ nmcli con mod myeth -ipv4.dns 1 ---> ipv4.dns: 10.0.0.55, 8.8.8.8, 8.8.4.4 ---> bond.options: mode=balance-rr $ nmcli con mod bond0 +bond.options "mii=500, downdelay=800" ---> bond.options: downdelay=800,miimon=500,mode=balance-rr $ nmcli con mod bond0 -bond.options downdelay ---> bond.options: miimon=500,mode=balance-rr --- cli/src/connections.c | 57 +++++++++++++++++++++++++++++++++---------- man/nmcli.1.in | 12 +++++---- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 5f1e7ea3be..71642539fe 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -268,7 +268,7 @@ usage (void) #endif " down [id | uuid | path | apath] \n\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [--temporary] [id | uuid | path] ([+]. )+\n\n" + " modify [--temporary] [id | uuid | path] ([+|-]. )+\n\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n\n" " delete [id | uuid | path] \n\n" @@ -416,17 +416,21 @@ usage_connection_modify (void) fprintf (stderr, _("Usage: nmcli connection modify { ARGUMENTS | help }\n" "\n" - "ARGUMENTS := [id | uuid | path] ([+]. )+\n" + "ARGUMENTS := [id | uuid | path] ([+|-]. )+\n" "\n" "Modify one or more properties of the connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path. The optional '+'\n" - "sign before the property instruct nmcli to append the value instead of \n" - "overwriting it.\n" + "The profile is identified by its name, UUID or D-Bus path. For multi-value\n" + "properties you can use optional '+' or '-' prefix to the property name.\n" + "The '+' sign instructs nmcli to append the value instead of overwriting it.\n" + "The '-' sign allows removing selected items instead of the whole value.\n" "\n" "Examples:\n" "nmcli con mod home-wifi wifi.ssid rakosnicek\n" "nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, 10.10.1.5/8\"\n" - "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n\n")); + "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n" + "nmcli con mod em1-1 -ipv4.dns 1\n" + "nmcli con mod bond0 +bond.options mii=500\n" + "nmcli con mod bond0 -bond.options downdelay\n\n")); } static void @@ -7850,6 +7854,7 @@ do_connection_modify (NmCli *nmc, const char *setting_name; char *property_name = NULL; gboolean append = FALSE; + gboolean remove = FALSE; GError *error = NULL; nmc->should_wait = FALSE; @@ -7934,6 +7939,9 @@ do_connection_modify (NmCli *nmc, if (s_dot_p[0] == '+') { s_dot_p++; append = TRUE; + } else if (s_dot_p[0] == '-') { + s_dot_p++; + remove = TRUE; } strv = g_strsplit (s_dot_p, ".", 2); @@ -7973,13 +7981,36 @@ do_connection_modify (NmCli *nmc, goto finish; } - if (!append) - nmc_setting_reset_property (setting, property_name, NULL); - if (!nmc_setting_set_property (setting, property_name, value, &error)) { - g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."), - strv[0], strv[1], error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + if (!remove) { + /* Set/add value */ + if (!append) + nmc_setting_reset_property (setting, property_name, NULL); + if (!nmc_setting_set_property (setting, property_name, value, &error)) { + g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."), + strv[0], strv[1], error->message); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + } 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, &error); + else + nmc_setting_remove_property_option (setting, property_name, value, 0, &error); + if (error) { + g_string_printf (nmc->return_text, _("Error: failed to remove a value from %s.%s: %s."), + strv[0], strv[1], error->message); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + } else + nmc_setting_reset_property (setting, property_name, NULL); } g_strfreev (strv); diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 714efa89a2..a140b369c6 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -619,8 +619,8 @@ See also \fInm-settings\fP(5) for all NetworkManager settings and property names descriptions; and \fInmcli-examples\fP(5) for sample editor sessions. .RE .TP -.B modify [--temporary] [ id | uuid | path ] [+]. -.B [+]. ... +.B modify [--temporary] [ id | uuid | path ] [+|-]. +.B [+|-]. ... .br Modify one or more properties in the connection profile. .br @@ -632,10 +632,12 @@ and \fIproperty name\fP provided they are unique. Empty \fIvalue\fP ("") removes the property value (sets the property to the default value). The provided value overwrite the existing property value. If you want to append to the existing value instead, use \fI+\fP prefix for the property name. -But it only has a real effect for multi-value (container) properties like ipv4.dns, -ipv4.addresses, etc. +If you want to remove just one item from container-type property, use \fI-\fP +prefix for the property name and specify its index (or option name) as +\fIvalue\fP. Of course, it only has a real effect for multi-value (container) +properties like ipv4.dns, ipv4.addresses, bond.options, etc. .br -The changed values will be saved persistently by NetworkManager, unless +The changes will be saved persistently by NetworkManager, unless \fI--temporary\fP option is provided, in which case the changes won't persist over NetworkManager restart. .TP From 1303ac3e9c86bedf12f8a3584ca0317ec5cc0dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 24 Feb 2014 10:50:11 +0100 Subject: [PATCH 06/16] libnm-util: add *_remove_*_by_value() functions for 'ipv4' and 'ipv6' settings nm_setting_ip4_config_remove_dns_by_value() nm_setting_ip4_config_remove_dns_search_by_value() nm_setting_ip4_config_remove_address_by_value() nm_setting_ip4_config_remove_route_by_value() nm_setting_ip6_config_remove_dns_by_value() nm_setting_ip6_config_remove_dns_search_by_value() nm_setting_ip6_config_remove_address_by_value() nm_setting_ip6_config_remove_route_by_value() --- libnm-util/libnm-util.ver | 8 ++ libnm-util/nm-setting-ip4-config.c | 132 ++++++++++++++++++++++++++++- libnm-util/nm-setting-ip4-config.h | 30 ++++--- libnm-util/nm-setting-ip6-config.c | 131 +++++++++++++++++++++++++++- libnm-util/nm-setting-ip6-config.h | 30 ++++--- 5 files changed, 307 insertions(+), 24 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 60614d2e4a..b3c74aaca3 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -361,9 +361,13 @@ global: nm_setting_ip4_config_get_type; nm_setting_ip4_config_new; nm_setting_ip4_config_remove_address; + nm_setting_ip4_config_remove_address_by_value; nm_setting_ip4_config_remove_dns; + nm_setting_ip4_config_remove_dns_by_value; nm_setting_ip4_config_remove_dns_search; + nm_setting_ip4_config_remove_dns_search_by_value; nm_setting_ip4_config_remove_route; + nm_setting_ip4_config_remove_route_by_value; nm_setting_ip6_config_add_address; nm_setting_ip6_config_add_dns; nm_setting_ip6_config_add_dns_search; @@ -393,9 +397,13 @@ global: nm_setting_ip6_config_new; nm_setting_ip6_config_privacy_get_type; nm_setting_ip6_config_remove_address; + nm_setting_ip6_config_remove_address_by_value; nm_setting_ip6_config_remove_dns; + nm_setting_ip6_config_remove_dns_by_value; nm_setting_ip6_config_remove_dns_search; + nm_setting_ip6_config_remove_dns_search_by_value; nm_setting_ip6_config_remove_route; + nm_setting_ip6_config_remove_route_by_value; nm_setting_need_secrets; nm_setting_new_from_hash; nm_setting_olpc_mesh_error_get_type; diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index 8a07293e40..bdb77783e8 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -218,6 +218,37 @@ nm_setting_ip4_config_remove_dns (NMSettingIP4Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_DNS); } +/** + * nm_setting_ip4_config_remove_dns_by_value: + * @setting: the #NMSettingIP4Config + * @dns: the DNS server to remove + * + * Removes the DNS server @dns. + * + * Returns: %TRUE if the DNS server was found and removed; %FALSE if it was not. + * domain was already known + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip4_config_remove_dns_by_value (NMSettingIP4Config *setting, guint32 dns) +{ + NMSettingIP4ConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + + priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->dns->len; i++) { + if (dns == g_array_index (priv->dns, guint32, i)) { + g_array_remove_index (priv->dns, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_DNS); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip4_config_clear_dns: * @setting: the #NMSettingIP4Config @@ -326,6 +357,39 @@ nm_setting_ip4_config_remove_dns_search (NMSettingIP4Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_DNS_SEARCH); } +/** + * nm_setting_ip4_config_remove_dns_search_by_value: + * @setting: the #NMSettingIP4Config + * @dns_search: the search domain to remove + * + * Removes the DNS search domain @dns_search. + * + * Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not. + * + * Since 0.9.10 + **/ +gboolean +nm_setting_ip4_config_remove_dns_search_by_value (NMSettingIP4Config *setting, + const char *dns_search) +{ + NMSettingIP4ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_search != NULL, FALSE); + g_return_val_if_fail (dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); + for (iter = priv->dns_search; iter; iter = g_slist_next (iter)) { + if (!strcmp (dns_search, (char *) iter->data)) { + priv->dns_search = g_slist_delete_link (priv->dns_search, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_DNS_SEARCH); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip4_config_clear_dns_searches: * @setting: the #NMSettingIP4Config @@ -436,6 +500,39 @@ nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES); } +/** + * nm_setting_ip4_config_remove_address_by_value: + * @setting: the #NMSettingIP4Config + * @address: the IP address to remove + * + * Removes the address @address. + * + * Returns: %TRUE if the address was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip4_config_remove_address_by_value (NMSettingIP4Config *setting, + NMIP4Address *address) +{ + NMSettingIP4ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + g_return_val_if_fail (address != NULL, FALSE); + + priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); + for (iter = priv->addresses; iter; iter = g_slist_next (iter)) { + if (nm_ip4_address_compare ((NMIP4Address *) iter->data, address)) { + nm_ip4_address_unref ((NMIP4Address *) iter->data); + priv->addresses = g_slist_delete_link (priv->addresses, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip4_config_clear_addresses: * @setting: the #NMSettingIP4Config @@ -547,6 +644,39 @@ nm_setting_ip4_config_remove_route (NMSettingIP4Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ROUTES); } +/** + * nm_setting_ip4_config_remove_route_by_value: + * @setting: the #NMSettingIP4Config + * @route: the route to remove + * + * Removes the route @route. + * + * Returns: %TRUE if the route was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip4_config_remove_route_by_value (NMSettingIP4Config *setting, + NMIP4Route *route) +{ + NMSettingIP4ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + g_return_val_if_fail (route != NULL, FALSE); + + priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); + for (iter = priv->routes; iter; iter = g_slist_next (iter)) { + if (nm_ip4_route_compare ((NMIP4Route *) iter->data, route)) { + nm_ip4_route_unref ((NMIP4Route *) iter->data); + priv->routes = g_slist_delete_link (priv->routes, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ROUTES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip4_config_clear_routes: * @setting: the #NMSettingIP4Config diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index 5f7f3d0017..3f0d006bfa 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -189,24 +189,32 @@ guint32 nm_setting_ip4_config_get_num_dns (NMSettingIP4Config * guint32 nm_setting_ip4_config_get_dns (NMSettingIP4Config *setting, guint32 i); gboolean nm_setting_ip4_config_add_dns (NMSettingIP4Config *setting, guint32 dns); void nm_setting_ip4_config_remove_dns (NMSettingIP4Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip4_config_remove_dns_by_value (NMSettingIP4Config *setting, guint32 dns); void nm_setting_ip4_config_clear_dns (NMSettingIP4Config *setting); -guint32 nm_setting_ip4_config_get_num_dns_searches (NMSettingIP4Config *setting); -const char * nm_setting_ip4_config_get_dns_search (NMSettingIP4Config *setting, guint32 i); -gboolean nm_setting_ip4_config_add_dns_search (NMSettingIP4Config *setting, const char *dns_search); -void nm_setting_ip4_config_remove_dns_search (NMSettingIP4Config *setting, guint32 i); -void nm_setting_ip4_config_clear_dns_searches (NMSettingIP4Config *setting); +guint32 nm_setting_ip4_config_get_num_dns_searches (NMSettingIP4Config *setting); +const char * nm_setting_ip4_config_get_dns_search (NMSettingIP4Config *setting, guint32 i); +gboolean nm_setting_ip4_config_add_dns_search (NMSettingIP4Config *setting, const char *dns_search); +void nm_setting_ip4_config_remove_dns_search (NMSettingIP4Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip4_config_remove_dns_search_by_value (NMSettingIP4Config *setting, const char *dns_search); +void nm_setting_ip4_config_clear_dns_searches (NMSettingIP4Config *setting); -guint32 nm_setting_ip4_config_get_num_addresses (NMSettingIP4Config *setting); -NMIP4Address *nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i); -gboolean nm_setting_ip4_config_add_address (NMSettingIP4Config *setting, NMIP4Address *address); -void nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i); -void nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting); +guint32 nm_setting_ip4_config_get_num_addresses (NMSettingIP4Config *setting); +NMIP4Address *nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i); +gboolean nm_setting_ip4_config_add_address (NMSettingIP4Config *setting, NMIP4Address *address); +void nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip4_config_remove_address_by_value (NMSettingIP4Config *setting, NMIP4Address *address); +void nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting); guint32 nm_setting_ip4_config_get_num_routes (NMSettingIP4Config *setting); NMIP4Route * nm_setting_ip4_config_get_route (NMSettingIP4Config *setting, guint32 i); gboolean nm_setting_ip4_config_add_route (NMSettingIP4Config *setting, NMIP4Route *route); void nm_setting_ip4_config_remove_route (NMSettingIP4Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip4_config_remove_route_by_value (NMSettingIP4Config *setting, NMIP4Route *route); void nm_setting_ip4_config_clear_routes (NMSettingIP4Config *setting); gboolean nm_setting_ip4_config_get_ignore_auto_routes (NMSettingIP4Config *setting); diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index 563e2b0c7e..d421d39ce6 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. */ #include @@ -241,6 +241,37 @@ nm_setting_ip6_config_remove_dns (NMSettingIP6Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_DNS); } +/** + * nm_setting_ip6_config_remove_dns_by_value: + * @setting: the #NMSettingIP6Config + * @dns: the IPv6 address of the DNS server to remove + * + * Removes the DNS server at index @i. + * + * Returns: %TRUE if the DNS server was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip6_config_remove_dns_by_value (NMSettingIP6Config *setting, + const struct in6_addr *addr) +{ + NMSettingIP6ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE); + + priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting); + for (iter = priv->dns; iter; iter = g_slist_next (iter)) { + if (!memcmp (addr, (struct in6_addr *) iter->data, sizeof (struct in6_addr))) { + priv->dns = g_slist_delete_link (priv->dns, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_DNS); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip6_config_clear_dns: * @setting: the #NMSettingIP6Config @@ -347,6 +378,39 @@ nm_setting_ip6_config_remove_dns_search (NMSettingIP6Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_DNS_SEARCH); } +/** + * nm_setting_ip6_config_remove_dns_search_by_value: + * @setting: the #NMSettingIP6Config + * @dns_search: the search domain to remove + * + * Removes the DNS search domain @dns_search. + * + * Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not. + * + * Since 0.9.10 + **/ +gboolean +nm_setting_ip6_config_remove_dns_search_by_value (NMSettingIP6Config *setting, + const char *dns_search) +{ + NMSettingIP6ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_search != NULL, FALSE); + g_return_val_if_fail (dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting); + for (iter = priv->dns_search; iter; iter = g_slist_next (iter)) { + if (!strcmp (dns_search, (char *) iter->data)) { + priv->dns_search = g_slist_delete_link (priv->dns_search, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_DNS_SEARCH); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip6_config_clear_dns_searches: * @setting: the #NMSettingIP6Config @@ -457,6 +521,38 @@ nm_setting_ip6_config_remove_address (NMSettingIP6Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_ADDRESSES); } +/** + * nm_setting_ip6_config_remove_address_by_value: + * @setting: the #NMSettingIP6Config + * @address: the address to remove + * + * Removes the address @address. + * + * Returns: %TRUE if the address was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip6_config_remove_address_by_value (NMSettingIP6Config *setting, + NMIP6Address *address) +{ + NMSettingIP6ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE); + g_return_val_if_fail (address != NULL, FALSE); + + priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting); + for (iter = priv->addresses; iter; iter = g_slist_next (iter)) { + if (nm_ip6_address_compare ((NMIP6Address *) iter->data, address)) { + priv->addresses = g_slist_delete_link (priv->addresses, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_ADDRESSES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip6_config_clear_addresses: * @setting: the #NMSettingIP6Config @@ -568,6 +664,39 @@ nm_setting_ip6_config_remove_route (NMSettingIP6Config *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_ROUTES); } +/** + * nm_setting_ip6_config_remove_route_by_value: + * @setting: the #NMSettingIP6Config + * @route: the route to remove + * + * Removes the route @route. + * + * Returns: %TRUE if the route was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_ip6_config_remove_route_by_value (NMSettingIP6Config *setting, + NMIP6Route *route) +{ + NMSettingIP6ConfigPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE); + g_return_val_if_fail (route != NULL, FALSE); + + priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting); + for (iter = priv->routes; iter; iter = g_slist_next (iter)) { + if (nm_ip6_route_compare ((NMIP6Route *) iter->data, route)) { + nm_ip6_route_unref ((NMIP6Route *) iter->data); + priv->routes = g_slist_delete_link (priv->routes, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_ROUTES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_ip6_config_clear_routes: * @setting: the #NMSettingIP6Config diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h index 29650486c2..d1f4ca842c 100644 --- a/libnm-util/nm-setting-ip6-config.h +++ b/libnm-util/nm-setting-ip6-config.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2012 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef NM_SETTING_IP6_CONFIG_H @@ -219,24 +219,32 @@ guint32 nm_setting_ip6_config_get_num_dns (NMSettingIP const struct in6_addr *nm_setting_ip6_config_get_dns (NMSettingIP6Config *setting, guint32 i); gboolean nm_setting_ip6_config_add_dns (NMSettingIP6Config *setting, const struct in6_addr *dns); void nm_setting_ip6_config_remove_dns (NMSettingIP6Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip6_config_remove_dns_by_value (NMSettingIP6Config *setting, const struct in6_addr *dns); void nm_setting_ip6_config_clear_dns (NMSettingIP6Config *setting); -guint32 nm_setting_ip6_config_get_num_dns_searches (NMSettingIP6Config *setting); -const char * nm_setting_ip6_config_get_dns_search (NMSettingIP6Config *setting, guint32 i); -gboolean nm_setting_ip6_config_add_dns_search (NMSettingIP6Config *setting, const char *dns_search); -void nm_setting_ip6_config_remove_dns_search (NMSettingIP6Config *setting, guint32 i); -void nm_setting_ip6_config_clear_dns_searches (NMSettingIP6Config *setting); +guint32 nm_setting_ip6_config_get_num_dns_searches (NMSettingIP6Config *setting); +const char * nm_setting_ip6_config_get_dns_search (NMSettingIP6Config *setting, guint32 i); +gboolean nm_setting_ip6_config_add_dns_search (NMSettingIP6Config *setting, const char *dns_search); +void nm_setting_ip6_config_remove_dns_search (NMSettingIP6Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip6_config_remove_dns_search_by_value (NMSettingIP6Config *setting, const char *dns_search); +void nm_setting_ip6_config_clear_dns_searches (NMSettingIP6Config *setting); -guint32 nm_setting_ip6_config_get_num_addresses (NMSettingIP6Config *setting); -NMIP6Address * nm_setting_ip6_config_get_address (NMSettingIP6Config *setting, guint32 i); -gboolean nm_setting_ip6_config_add_address (NMSettingIP6Config *setting, NMIP6Address *address); -void nm_setting_ip6_config_remove_address (NMSettingIP6Config *setting, guint32 i); -void nm_setting_ip6_config_clear_addresses (NMSettingIP6Config *setting); +guint32 nm_setting_ip6_config_get_num_addresses (NMSettingIP6Config *setting); +NMIP6Address * nm_setting_ip6_config_get_address (NMSettingIP6Config *setting, guint32 i); +gboolean nm_setting_ip6_config_add_address (NMSettingIP6Config *setting, NMIP6Address *address); +void nm_setting_ip6_config_remove_address (NMSettingIP6Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip6_config_remove_address_by_value (NMSettingIP6Config *setting, NMIP6Address *address); +void nm_setting_ip6_config_clear_addresses (NMSettingIP6Config *setting); guint32 nm_setting_ip6_config_get_num_routes (NMSettingIP6Config *setting); NMIP6Route * nm_setting_ip6_config_get_route (NMSettingIP6Config *setting, guint32 i); gboolean nm_setting_ip6_config_add_route (NMSettingIP6Config *setting, NMIP6Route *route); void nm_setting_ip6_config_remove_route (NMSettingIP6Config *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_ip6_config_remove_route_by_value (NMSettingIP6Config *setting, NMIP6Route *route); void nm_setting_ip6_config_clear_routes (NMSettingIP6Config *setting); gboolean nm_setting_ip6_config_get_ignore_auto_routes (NMSettingIP6Config *setting); From 7c817d41764c11f780c3a64ef5495efdb055e2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 24 Feb 2014 16:38:56 +0100 Subject: [PATCH 07/16] libnm-util: add *_remove_*_by_value() functions for '802-1x' setting nm_setting_802_1x_remove_eap_method_by_value() nm_setting_802_1x_remove_altsubject_match_by_value() nm_setting_802_1x_remove_phase2_altsubject_match_by_value() --- libnm-util/libnm-util.ver | 3 ++ libnm-util/nm-setting-8021x.c | 99 +++++++++++++++++++++++++++++++++++ libnm-util/nm-setting-8021x.h | 32 ++++++----- 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index b3c74aaca3..1a4ebc9d24 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -172,8 +172,11 @@ global: nm_setting_802_1x_get_type; nm_setting_802_1x_new; nm_setting_802_1x_remove_altsubject_match; + nm_setting_802_1x_remove_altsubject_match_by_value; nm_setting_802_1x_remove_eap_method; + nm_setting_802_1x_remove_eap_method_by_value; nm_setting_802_1x_remove_phase2_altsubject_match; + nm_setting_802_1x_remove_phase2_altsubject_match_by_value; nm_setting_802_1x_set_ca_cert; nm_setting_802_1x_set_client_cert; nm_setting_802_1x_set_phase2_ca_cert; diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index c7debbef90..ce4886a4db 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -276,6 +276,38 @@ nm_setting_802_1x_remove_eap_method (NMSetting8021x *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); } +/** + * nm_setting_802_1x_remove_eap_method_by_value: + * @setting: the #NMSetting8021x + * @eap: the name of the EAP method to remove + * + * Removes the allowed EAP method @method. + * + * Returns: %TRUE if the EAP method was founs and removed, %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_802_1x_remove_eap_method_by_value (NMSetting8021x *setting, + const char *eap) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (eap != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->eap; iter; iter = g_slist_next (iter)) { + if (!strcmp (eap, (char *) iter->data)) { + priv->eap = g_slist_delete_link (priv->eap, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_802_1x_clear_eap_methods: * @setting: the #NMSetting8021x @@ -682,6 +714,39 @@ nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, guint32 i) g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); } +/** + * nm_setting_802_1x_remove_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @altsubject_match: the altSubjectName to remove + * + * Removes the allowed altSubjectName @altsubject_match. + * + * Returns: %TRUE if the alternative subject name match was found and removed, + * %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_802_1x_remove_altsubject_match_by_value (NMSetting8021x *setting, + const char *altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (altsubject_match, (char *) iter->data)) { + priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_802_1x_clear_altsubject_matches: * @setting: the #NMSetting8021x @@ -1229,6 +1294,40 @@ nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, guint g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); } + +/** + * nm_setting_802_1x_remove_phase2_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @phase2_altsubject_match: the "phase 2" altSubjectName to remove + * + * Removes the allowed "phase 2" altSubjectName @phase2_altsubject_match. + * + * Returns: %TRUE if the alternative subject name match for "phase 2" was found and removed, + * %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_802_1x_remove_phase2_altsubject_match_by_value (NMSetting8021x *setting, + const char *phase2_altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (phase2_altsubject_match, (char *) iter->data)) { + priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_802_1x_clear_phase2_altsubject_matches: * @setting: the #NMSetting8021x diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 8381fed7ce..263630ec00 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2012 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -170,6 +170,8 @@ guint32 nm_setting_802_1x_get_num_eap_methods (NMSetting8 const char * nm_setting_802_1x_get_eap_method (NMSetting8021x *setting, guint32 i); gboolean nm_setting_802_1x_add_eap_method (NMSetting8021x *setting, const char *eap); void nm_setting_802_1x_remove_eap_method (NMSetting8021x *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_802_1x_remove_eap_method_by_value (NMSetting8021x *setting, const char *eap); void nm_setting_802_1x_clear_eap_methods (NMSetting8021x *setting); const char * nm_setting_802_1x_get_identity (NMSetting8021x *setting); @@ -195,11 +197,14 @@ const char * nm_setting_802_1x_get_subject_match (NMSetting8 guint32 nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting); const char * nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, - guint32 i); + guint32 i); gboolean nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting, - const char *altsubject_match); + const char *altsubject_match); void nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, - guint32 i); + guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_802_1x_remove_altsubject_match_by_value (NMSetting8021x *setting, + const char *altsubject_match); void nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting); NMSetting8021xCKScheme nm_setting_802_1x_get_client_cert_scheme (NMSetting8021x *setting); @@ -232,14 +237,17 @@ gboolean nm_setting_802_1x_set_phase2_ca_cert (NMSetting8 const char * nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting); -guint32 nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting); -const char * nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, - guint32 i); -gboolean nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting, - const char *phase2_altsubject_match); -void nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, - guint32 i); -void nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting); +guint32 nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, + guint32 i); +gboolean nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting, + const char *phase2_altsubject_match); +void nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, + guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_802_1x_remove_phase2_altsubject_match_by_value (NMSetting8021x *setting, + const char *phase2_altsubject_match); +void nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting); NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_client_cert_scheme (NMSetting8021x *setting); const GByteArray * nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting); From b59bd759569fda1e445f81b33cd1a2a78ae83838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 24 Feb 2014 19:11:14 +0100 Subject: [PATCH 08/16] libnm-util: add *_remove_*_by_value() functions for 'connection' setting nm_setting_connection_remove_permission_by_value() nm_setting_connection_remove_secondary_by_value() --- libnm-util/libnm-util.ver | 2 + libnm-util/nm-setting-connection.c | 78 ++++++++++++++++++++++++++++++ libnm-util/nm-setting-connection.h | 11 ++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 1a4ebc9d24..44be29bc13 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -267,7 +267,9 @@ global: nm_setting_connection_new; nm_setting_connection_permissions_user_allowed; nm_setting_connection_remove_permission; + nm_setting_connection_remove_permission_by_value; nm_setting_connection_remove_secondary; + nm_setting_connection_remove_secondary_by_value; nm_setting_dcb_error_get_type; nm_setting_dcb_error_quark; nm_setting_dcb_flags_get_type; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 3f75ab7e9d..4e793a2e0a 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -447,6 +447,51 @@ nm_setting_connection_remove_permission (NMSettingConnection *setting, g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS); } +/** + * nm_setting_connection_remove_permission_by_value: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Removes the permission from the connection. + * At this time, only the "user" permission type is supported, and @pitem must + * be a username. See #NMSettingConnection:permissions: for more details. + * + * Returns: %TRUE if the permission was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + */ +gboolean +nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (ptype, FALSE); + g_return_val_if_fail (strlen (ptype) > 0, FALSE); + g_return_val_if_fail (detail == NULL, FALSE); + + /* Only "user" for now... */ + g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (strcmp (pitem, p->item) == 0) { + permission_free ((Permission *) iter->data); + priv->permissions = g_slist_delete_link (priv->permissions, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS); + return TRUE; + } + } + return FALSE; +} /** * nm_setting_connection_get_autoconnect: @@ -660,6 +705,39 @@ nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 id g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES); } +/** + * nm_setting_connection_remove_secondary_by_value: + * @setting: the #NMSettingConnection + * @sec_uuid: the secondary connection UUID to remove + * + * Removes the secondary coonnection UUID @sec_uuid. + * + * Returns: %TRUE if the secondary connection UUID was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting, + const char *sec_uuid) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (sec_uuid != NULL, FALSE); + g_return_val_if_fail (sec_uuid[0] != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + for (iter = priv->secondaries; iter; iter = g_slist_next (iter)) { + if (!strcmp (sec_uuid, (char *) iter->data)) { + priv->secondaries = g_slist_delete_link (priv->secondaries, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_connection_get_gateway_ping_timeout: * @setting: the #NMSettingConnection diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 5e3147e2ec..ff2af7a2c8 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2012 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -128,14 +128,23 @@ gboolean nm_setting_connection_add_permission (NMSettingConnection *set const char *detail); void nm_setting_connection_remove_permission (NMSettingConnection *setting, guint32 idx); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail); + const char *nm_setting_connection_get_master (NMSettingConnection *setting); gboolean nm_setting_connection_is_slave_type (NMSettingConnection *setting, const char *type); const char *nm_setting_connection_get_slave_type (NMSettingConnection *setting); + guint32 nm_setting_connection_get_num_secondaries (NMSettingConnection *setting); const char *nm_setting_connection_get_secondary (NMSettingConnection *setting, guint32 idx); gboolean nm_setting_connection_add_secondary (NMSettingConnection *setting, const char *sec_uuid); void nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 idx); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting, const char *sec_uuid); NM_AVAILABLE_IN_0_9_10 guint32 nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting); From ca0aa8139c9fda6b8cd8d3ce67da3adb11d8c189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 25 Feb 2014 09:14:38 +0100 Subject: [PATCH 09/16] libnm-util: add *_remove_*_by_value() functions for '802-3-ethernet' setting nm_setting_wired_remove_mac_blacklist_item_by_value() and missing nm_setting_wired_clear_mac_blacklist_items() --- libnm-util/libnm-util.ver | 2 ++ libnm-util/nm-setting-wired.c | 58 ++++++++++++++++++++++++++++++++++- libnm-util/nm-setting-wired.h | 7 ++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 44be29bc13..e45dbd8c80 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -512,6 +512,7 @@ global: nm_setting_wimax_new; nm_setting_wired_add_mac_blacklist_item; nm_setting_wired_add_s390_option; + nm_setting_wired_clear_mac_blacklist_items; nm_setting_wired_error_get_type; nm_setting_wired_error_quark; nm_setting_wired_get_auto_negotiate; @@ -533,6 +534,7 @@ global: nm_setting_wired_get_valid_s390_options; nm_setting_wired_new; nm_setting_wired_remove_mac_blacklist_item; + nm_setting_wired_remove_mac_blacklist_item_by_value; nm_setting_wired_remove_s390_option; nm_setting_wireless_add_mac_blacklist_item; nm_setting_wireless_add_seen_bssid; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index b9fc07df87..50c7e75688 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -297,6 +297,7 @@ nm_setting_wired_add_mac_blacklist_item (NMSettingWired *setting, const char *ma priv->mac_address_blacklist = g_slist_append (priv->mac_address_blacklist, g_ascii_strup (mac, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); return TRUE; } @@ -323,6 +324,61 @@ nm_setting_wired_remove_mac_blacklist_item (NMSettingWired *setting, guint32 idx g_free (elt->data); priv->mac_address_blacklist = g_slist_delete_link (priv->mac_address_blacklist, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wired_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWired + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_wired_remove_mac_blacklist_item_by_value (NMSettingWired *setting, const char *mac) +{ + NMSettingWiredPrivate *priv; + GSList *iter; + guint8 buf[32]; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + if (!nm_utils_hwaddr_aton (mac, ARPHRD_ETHER, buf)) + return FALSE; + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + for (iter = priv->mac_address_blacklist; iter; iter = g_slist_next (iter)) { + if (!strcasecmp (mac, (char *) iter->data)) { + priv->mac_address_blacklist = g_slist_delete_link (priv->mac_address_blacklist, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wired_clear_mac_blacklist_items: + * @setting: the #NMSettingWired + * + * Removes all blacklisted MAC addresses. + * + * Since: 0.9.10 + **/ +void +nm_setting_wired_clear_mac_blacklist_items (NMSettingWired *setting) +{ + g_return_if_fail (NM_IS_SETTING_WIRED (setting)); + + g_slist_free_full (NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist, g_free); + NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); } /** diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index d26ef19630..9580b0a8b4 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -103,6 +103,11 @@ gboolean nm_setting_wired_add_mac_blacklist_item (NMSettingWired * NM_AVAILABLE_IN_0_9_10 void nm_setting_wired_remove_mac_blacklist_item (NMSettingWired *setting, guint32 idx); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_wired_remove_mac_blacklist_item_by_value (NMSettingWired *setting, + const char *mac); +NM_AVAILABLE_IN_0_9_10 +void nm_setting_wired_clear_mac_blacklist_items (NMSettingWired *setting); guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); From de646d95887fccfd3bfc8e4bc9c85a99c50f55dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 25 Feb 2014 09:52:28 +0100 Subject: [PATCH 10/16] libnm-util: add *_remove_*_by_value() functions for '802-11-wireless' setting nm_setting_wired_remove_mac_blacklist_item_by_value() Also add missing function nm_setting_wired_clear_mac_blacklist_items() and notify about mac-address-blacklist changes. --- libnm-util/libnm-util.ver | 2 ++ libnm-util/nm-setting-wireless.c | 58 +++++++++++++++++++++++++++++++- libnm-util/nm-setting-wireless.h | 7 +++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index e45dbd8c80..f437415c7b 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -539,6 +539,7 @@ global: nm_setting_wireless_add_mac_blacklist_item; nm_setting_wireless_add_seen_bssid; nm_setting_wireless_ap_security_compatible; + nm_setting_wireless_clear_mac_blacklist_items; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; nm_setting_wireless_get_band; @@ -561,6 +562,7 @@ global: nm_setting_wireless_get_type; nm_setting_wireless_new; nm_setting_wireless_remove_mac_blacklist_item; + nm_setting_wireless_remove_mac_blacklist_item_by_value; nm_setting_wireless_security_add_group; nm_setting_wireless_security_add_pairwise; nm_setting_wireless_security_add_proto; diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index e467662977..8c3ea07cc8 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -533,6 +533,7 @@ nm_setting_wireless_add_mac_blacklist_item (NMSettingWireless *setting, const ch priv->mac_address_blacklist = g_slist_append (priv->mac_address_blacklist, g_ascii_strup (mac, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); return TRUE; } @@ -559,6 +560,61 @@ nm_setting_wireless_remove_mac_blacklist_item (NMSettingWireless *setting, guint g_free (elt->data); priv->mac_address_blacklist = g_slist_delete_link (priv->mac_address_blacklist, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wireless_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWireless + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_wireless_remove_mac_blacklist_item_by_value (NMSettingWireless *setting, const char *mac) +{ + NMSettingWirelessPrivate *priv; + GSList *iter; + guint8 buf[32]; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + if (!nm_utils_hwaddr_aton (mac, ARPHRD_ETHER, buf)) + return FALSE; + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + for (iter = priv->mac_address_blacklist; iter; iter = g_slist_next (iter)) { + if (!strcasecmp (mac, (char *) iter->data)) { + priv->mac_address_blacklist = g_slist_delete_link (priv->mac_address_blacklist, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_clear_mac_blacklist_items: + * @setting: the #NMSettingWireless + * + * Removes all blacklisted MAC addresses. + * + * Since: 0.9.10 + **/ +void +nm_setting_wireless_clear_mac_blacklist_items (NMSettingWireless *setting) +{ + g_return_if_fail (NM_IS_SETTING_WIRELESS (setting)); + + g_slist_free_full (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist, g_free); + NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); } /** diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index 6ad82f6e4b..221a921a34 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -145,6 +145,11 @@ gboolean nm_setting_wireless_add_mac_blacklist_item (NMSettingWire NM_AVAILABLE_IN_0_9_10 void nm_setting_wireless_remove_mac_blacklist_item (NMSettingWireless *setting, guint32 idx); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_wireless_remove_mac_blacklist_item_by_value (NMSettingWireless *setting, + const char *mac); +NM_AVAILABLE_IN_0_9_10 +void nm_setting_wireless_clear_mac_blacklist_items (NMSettingWireless *setting); guint32 nm_setting_wireless_get_mtu (NMSettingWireless *setting); gboolean nm_setting_wireless_get_hidden (NMSettingWireless *setting); From 1e5370b4d23beb10e335f49a96090ade8ba28da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 25 Feb 2014 10:19:07 +0100 Subject: [PATCH 11/16] libnm-util: add *_remove_*_by_value() functions for '802-11-wireless-security' setting nm_setting_wireless_security_remove_proto_by_value() nm_setting_wireless_security_remove_pairwise_by_value() nm_setting_wireless_security_remove_group_by_value() --- libnm-util/libnm-util.ver | 3 + libnm-util/nm-setting-wireless-security.c | 101 +++++++++++++++++++++- libnm-util/nm-setting-wireless-security.h | 38 ++++---- 3 files changed, 125 insertions(+), 17 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index f437415c7b..b2bec419a2 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -591,8 +591,11 @@ global: nm_setting_wireless_security_get_wep_tx_keyidx; nm_setting_wireless_security_new; nm_setting_wireless_security_remove_group; + nm_setting_wireless_security_remove_group_by_value; nm_setting_wireless_security_remove_pairwise; + nm_setting_wireless_security_remove_pairwise_by_value; nm_setting_wireless_security_remove_proto; + nm_setting_wireless_security_remove_proto_by_value; nm_setting_wireless_security_set_wep_key; nm_utils_ap_mode_security_valid; nm_utils_bin2hexstr; diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index 1bb7693d76..29c9150767 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -256,6 +256,38 @@ nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, g g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); } +/** + * nm_setting_wireless_security_remove_proto_by_value: + * @setting: the #NMSettingWirelessSecurity + * @proto: the protocol to remove, one of "wpa" or "rsn" + * + * Removes a protocol from the allowed protocol list. + * + * Returns: %TRUE if the protocol was found and removed; %FALSE it it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *setting, + const char *proto) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (proto != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->proto; iter; iter = g_slist_next (iter)) { + if (strcasecmp (proto, (char *) iter->data) == 0) { + priv->proto = g_slist_delete_link (priv->proto, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_wireless_security_clear_protos: * @setting: the #NMSettingWirelessSecurity @@ -371,6 +403,39 @@ nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); } +/** + * nm_setting_wireless_security_remove_pairwise_by_value: + * @setting: the #NMSettingWirelessSecurity + * @pairwise: the encryption algorithm to remove, one of "tkip" or "ccmp" + * + * Removes an encryption algorithm from the allowed pairwise encryption + * algorithm list. + * + * Returns: %TRUE if the encryption algorith was found and removed; %FALSE it it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting, + const char *pairwise) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (pairwise != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) { + if (strcasecmp (pairwise, (char *) iter->data) == 0) { + priv->pairwise = g_slist_delete_link (priv->pairwise, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_wireless_security_clear_pairwise: * @setting: the #NMSettingWirelessSecurity @@ -487,6 +552,40 @@ nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, g g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); } +/** + * nm_setting_wireless_security_remove_group_by_value: + * @setting: the #NMSettingWirelessSecurity + * @group: the encryption algorithm to remove, one of "wep40", "wep104", + * "tkip", or "ccmp" + * + * Removes an encryption algorithm from the allowed groupwise encryption + * algorithm list. + * + * Returns: %TRUE if the algorithm was found and removed; %FALSE it it was not. + * + * Since: 0.9.10 + **/ +gboolean +nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting, + const char *group) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (group != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->group; iter; iter = g_slist_next (iter)) { + if (strcasecmp (group, (char *) iter->data) == 0) { + priv->group = g_slist_delete_link (priv->group, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_wireless_security_clear_groups: * @setting: the #NMSettingWirelessSecurity diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h index d9e972c049..eabbe66e39 100644 --- a/libnm-util/nm-setting-wireless-security.h +++ b/libnm-util/nm-setting-wireless-security.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. + * (C) Copyright 2007 - 2014 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -137,23 +137,29 @@ NMSetting * nm_setting_wireless_security_new (void); const char *nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting); -guint32 nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting); -const char *nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i); -gboolean nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto); -void nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i); -void nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting); +guint32 nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting); -guint32 nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting); -const char *nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i); -gboolean nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise); -void nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i); -void nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting); +guint32 nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise); +void nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting); -guint32 nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting); -const char *nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i); -gboolean nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group); -void nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i); -void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); +guint32 nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group); +void nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting); NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting); From 642cfdeebfae3adbe52f9596f7996481d69045d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 25 Feb 2014 12:30:30 +0100 Subject: [PATCH 12/16] libnm-util: add *_remove_*_by_value() functions for 'vlan' setting nm_setting_vlan_remove_priority_by_value() nm_setting_vlan_remove_priority_str_by_value() --- libnm-util/libnm-util.ver | 2 + libnm-util/nm-setting-vlan.c | 74 +++++++++++++++++++++++++++++++++++- libnm-util/nm-setting-vlan.h | 13 ++++++- 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index b2bec419a2..09f7c58f69 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -488,6 +488,8 @@ global: nm_setting_vlan_get_type; nm_setting_vlan_new; nm_setting_vlan_remove_priority; + nm_setting_vlan_remove_priority_by_value; + nm_setting_vlan_remove_priority_str_by_value; nm_setting_vpn_add_data_item; nm_setting_vpn_add_secret; nm_setting_vpn_error_get_type; diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c index 9a37ca8da5..ac1a4bae48 100644 --- a/libnm-util/nm-setting-vlan.c +++ b/libnm-util/nm-setting-vlan.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. + * (C) Copyright 2011 - 2014 Red Hat, Inc. */ #include @@ -421,6 +421,78 @@ nm_setting_vlan_remove_priority (NMSettingVlan *setting, set_map (setting, map, g_slist_delete_link (list, item)); } +/** + * nm_setting_vlan_remove_priority_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @from: the priority to map to @to + * @to: the priority to map @from to + * + * Removes the priority map @form:@to from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + */ +gboolean +nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to) +{ + GSList *list = NULL, *iter = NULL; + PriorityMap *item; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + list = get_map (setting, map); + for (iter = list; iter; iter = g_slist_next (iter)) { + item = iter->data; + if (item->from == from && item->to == to) { + priority_map_free ((PriorityMap *) (iter->data)); + set_map (setting, map, g_slist_delete_link (list, iter)); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_vlan_remove_priority_str_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @str: the string which contains a priority map, like "3:7" + * + * Removes the priority map @str from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + * + * Since: 0.9.10 + */ +gboolean +nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str) +{ + GSList *list; + PriorityMap *item; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + list = get_map (setting, map); + item = priority_map_new_from_str (map, str); + if (!item) + return FALSE; + + return nm_setting_vlan_remove_priority_by_value (setting, map, item->from, item->to); +} + /** * nm_setting_vlan_clear_priorities: * @setting: the #NMSettingVlan diff --git a/libnm-util/nm-setting-vlan.h b/libnm-util/nm-setting-vlan.h index 019c6da071..e865cd4977 100644 --- a/libnm-util/nm-setting-vlan.h +++ b/libnm-util/nm-setting-vlan.h @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 Red Hat, Inc. + * (C) Copyright 2011 - 2014 Red Hat, Inc. */ #ifndef NM_SETTING_VLAN_H @@ -136,6 +136,17 @@ void nm_setting_vlan_remove_priority (NMSettingVlan *setting, NMVlanPriorityMap map, guint32 idx); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to); + +NM_AVAILABLE_IN_0_9_10 +gboolean nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str); + void nm_setting_vlan_clear_priorities (NMSettingVlan *setting, NMVlanPriorityMap map); gboolean nm_setting_vlan_add_priority_str (NMSettingVlan *setting, From f29ad0bd52cb1df58e814b0a189567de2f6aa14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 24 Feb 2014 11:50:05 +0100 Subject: [PATCH 13/16] cli: allow removing properties by-value (in addition to by-index) It works both in 'nmcli con modify' and 'nmcli con edit'. The following properties are supported (all container-type properties except properties with option names): ipv4.dns ipv4.dns-searches ipv4.addresses ipv4.routes ipv6.dns ipv6.dns-searches ipv6.addresses ipv6.routes 802-1x.eap 802-1x.altsubject-matches 802-1x.phase2-altsubject-matches connection.permissions connection.secondary 802-3-ethernet.mac-address-blacklist 802-11-wireless.mac-address-blacklist 802-11-wireless-security.proto 802-11-wireless-security.pairwise 802-11-wireless-security.group vlan.ingress-priority-map vlan.egress-priority-map --- cli/src/settings.c | 748 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 592 insertions(+), 156 deletions(-) diff --git a/cli/src/settings.c b/cli/src/settings.c index d420b721a5..f207e2c879 100644 --- a/cli/src/settings.c +++ b/cli/src/settings.c @@ -2017,6 +2017,31 @@ check_and_set_string (NMSetting *setting, return TRUE; \ } +#define DEFINE_REMOVER_INDEX_OR_VALUE(def_func, s_macro, num_func, rem_func_idx, rem_func_val) \ + static gboolean \ + def_func (NMSetting *setting, const char *prop, const char *value, guint32 idx, GError **error) \ + { \ + guint32 num; \ + if (value) { \ + gboolean ret; \ + char *value_stripped = g_strstrip (g_strdup (value)); \ + ret = rem_func_val (s_macro (setting), value_stripped, error); \ + g_free (value_stripped); \ + return ret; \ + } \ + num = num_func (s_macro (setting)); \ + if (num == 0) { \ + g_set_error_literal (error, 1, 0, _("no item to remove")); \ + return FALSE; \ + } \ + if (idx >= num) { \ + g_set_error (error, 1, 0, _("index '%d' is not in range <0-%d>"), idx, num - 1); \ + return FALSE; \ + } \ + rem_func_idx (s_macro (setting), idx); \ + return TRUE; \ + } + #define DEFINE_REMOVER_OPTION(def_func, s_macro, rem_func) \ static gboolean \ def_func (NMSetting *setting, const char *prop, const char *option, guint32 idx, GError **error) \ @@ -2351,10 +2376,24 @@ nmc_property_connection_set_permissions (NMSetting *setting, const char *prop, c return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_connection_remove_idx_permissions, - NM_SETTING_CONNECTION, - nm_setting_connection_get_num_permissions, - nm_setting_connection_remove_permission) + +static gboolean +_validate_and_remove_connection_permission (NMSettingConnection *setting, + const char *perm, + GError **error) +{ + gboolean ret; + + ret = nm_setting_connection_remove_permission_by_value (setting, "user", perm, NULL); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain permission '%s'"), perm); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_connection_remove_permissions, + NM_SETTING_CONNECTION, + nm_setting_connection_get_num_permissions, + nm_setting_connection_remove_permission, + _validate_and_remove_connection_permission) static const char * nmc_property_connection_describe_permissions (NMSetting *setting, const char *prop) @@ -2424,11 +2463,31 @@ nmc_property_connection_set_secondaries (NMSetting *setting, const char *prop, c return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_connection_remove_idx_secondaries, - NM_SETTING_CONNECTION, - nm_setting_connection_get_num_secondaries, - nm_setting_connection_remove_secondary) +static gboolean +_validate_and_remove_connection_secondary (NMSettingConnection *setting, + const char *secondary_uuid, + GError **error) +{ + gboolean ret; + + if (!nm_utils_is_uuid (secondary_uuid)) { + g_set_error (error, 1, 0, + _("the value '%s' is not a valid UUID"), secondary_uuid); + return FALSE; + } + + ret = nm_setting_connection_remove_secondary_by_value (setting, secondary_uuid); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain UUID '%s'"), secondary_uuid); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_connection_remove_secondaries, + NM_SETTING_CONNECTION, + nm_setting_connection_get_num_secondaries, + nm_setting_connection_remove_secondary, + _validate_and_remove_connection_secondary) /* --- NM_SETTING_802_1X_SETTING_NAME property setter functions --- */ #define DEFINE_SETTER_STR_LIST(def_func, set_func) \ @@ -2516,19 +2575,50 @@ nmc_property_802_1X_set_eap (NMSetting *setting, const char *prop, const char *v const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd", NULL }; return check_and_add_802_1X_eap (setting, prop, val, valid_eap, error); } -DEFINE_REMOVER_INDEX (nmc_property_802_1X_remove_idx_eap, - NM_SETTING_802_1X, - nm_setting_802_1x_get_num_eap_methods, - nm_setting_802_1x_remove_eap_method) + +static gboolean +_validate_and_remove_eap_method (NMSetting8021x *setting, + const char *eap, + GError **error) +{ + gboolean ret; + + ret = nm_setting_802_1x_remove_eap_method_by_value(setting, eap); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain EAP method '%s'"), eap); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_802_1X_remove_eap, + NM_SETTING_802_1X, + nm_setting_802_1x_get_num_eap_methods, + nm_setting_802_1x_remove_eap_method, + _validate_and_remove_eap_method) + /* 'ca-cert' */ DEFINE_SETTER_CERT (nmc_property_802_1X_set_ca_cert, nm_setting_802_1x_set_ca_cert) /* 'altsubject-matches' */ DEFINE_SETTER_STR_LIST (nmc_property_802_1X_set_altsubject_matches, nm_setting_802_1x_add_altsubject_match) -DEFINE_REMOVER_INDEX (nmc_property_802_1X_remove_idx_altsubject_matches, - NM_SETTING_802_1X, - nm_setting_802_1x_get_num_altsubject_matches, - nm_setting_802_1x_remove_altsubject_match) + +static gboolean +_validate_and_remove_altsubject_match (NMSetting8021x *setting, + const char *altsubject_match, + GError **error) +{ + gboolean ret; + + ret = nm_setting_802_1x_remove_altsubject_match_by_value (setting, altsubject_match); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain alternative subject match '%s'"), + altsubject_match); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_802_1X_remove_altsubject_matches, + NM_SETTING_802_1X, + nm_setting_802_1x_get_num_altsubject_matches, + nm_setting_802_1x_remove_altsubject_match, + _validate_and_remove_altsubject_match) /* 'client-cert' */ DEFINE_SETTER_CERT (nmc_property_802_1X_set_client_cert, nm_setting_802_1x_set_client_cert) @@ -2538,10 +2628,26 @@ DEFINE_SETTER_CERT (nmc_property_802_1X_set_phase2_ca_cert, nm_setting_802_1x_se /* 'phase2-altsubject-matches' */ DEFINE_SETTER_STR_LIST (nmc_property_802_1X_set_phase2_altsubject_matches, nm_setting_802_1x_add_phase2_altsubject_match) -DEFINE_REMOVER_INDEX (nmc_property_802_1X_remove_idx_phase2_altsubject_matches, - NM_SETTING_802_1X, - nm_setting_802_1x_get_num_phase2_altsubject_matches, - nm_setting_802_1x_remove_phase2_altsubject_match) + +static gboolean +_validate_and_remove_phase2_altsubject_match (NMSetting8021x *setting, + const char *phase2_altsubject_match, + GError **error) +{ + gboolean ret; + + ret = nm_setting_802_1x_remove_phase2_altsubject_match_by_value (setting, phase2_altsubject_match); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain \"phase2\" alternative subject match '%s'"), + phase2_altsubject_match); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_802_1X_remove_phase2_altsubject_matches, + NM_SETTING_802_1X, + nm_setting_802_1x_get_num_phase2_altsubject_matches, + nm_setting_802_1x_remove_phase2_altsubject_match, + _validate_and_remove_phase2_altsubject_match) /* 'phase2-client-cert' */ DEFINE_SETTER_CERT (nmc_property_802_1X_set_phase2_client_cert, nm_setting_802_1x_set_phase2_client_cert) @@ -2863,10 +2969,30 @@ nmc_property_ipv4_set_dns (NMSetting *setting, const char *prop, const char *val g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv4_remove_idx_dns, - NM_SETTING_IP4_CONFIG, - nm_setting_ip4_config_get_num_dns, - nm_setting_ip4_config_remove_dns) + +static gboolean +_validate_and_remove_ipv4_dns (NMSettingIP4Config *setting, + const char *dns, + GError **error) +{ + guint32 ip4_addr; + gboolean ret; + + if (inet_pton (AF_INET, dns, &ip4_addr) < 1) { + g_set_error (error, 1, 0, _("invalid IPv4 address '%s'"), dns); + return FALSE; + } + + ret = nm_setting_ip4_config_remove_dns_by_value (setting, ip4_addr); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain DNS server '%s'"), dns); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv4_remove_dns, + NM_SETTING_IP4_CONFIG, + nm_setting_ip4_config_get_num_dns, + nm_setting_ip4_config_remove_dns, + _validate_and_remove_ipv4_dns) static const char * nmc_property_ipv4_describe_dns (NMSetting *setting, const char *prop) @@ -2896,49 +3022,94 @@ nmc_property_ipv4_set_dns_search (NMSetting *setting, const char *prop, const ch return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv4_remove_idx_dns_search, - NM_SETTING_IP4_CONFIG, - nm_setting_ip4_config_get_num_dns_searches, - nm_setting_ip4_config_remove_dns_search) + +static gboolean +_validate_and_remove_ipv4_dns_search (NMSettingIP4Config *setting, + const char *dns_search, + GError **error) +{ + gboolean ret; + + ret = nm_setting_ip4_config_remove_dns_search_by_value (setting, dns_search); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain DNS search domain '%s'"), + dns_search); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv4_remove_dns_search, + NM_SETTING_IP4_CONFIG, + nm_setting_ip4_config_get_num_dns_searches, + nm_setting_ip4_config_remove_dns_search, + _validate_and_remove_ipv4_dns_search) /* 'addresses' */ +static NMIP4Address * +_parse_ipv4_address (const char *address, GError **error) +{ + char **addrv; + NMIP4Address *ip4addr; + + addrv = nmc_strsplit_set (address, " \t", 0); + if (g_strv_length (addrv) > 2) { + g_set_error (error, 1, 0, _("'%s' is not valid (use ip[/prefix] [gateway])"), + address); + g_strfreev (addrv); + return NULL; + } + ip4addr = nmc_parse_and_build_ip4_address (addrv[0], addrv[1], error); + g_strfreev (addrv); + return ip4addr; +} + static gboolean nmc_property_ipv4_set_addresses (NMSetting *setting, const char *prop, const char *val, GError **error) { char **strv = NULL, **iter; - char **addrv; - NMIP4Address *ip4addr = NULL; + NMIP4Address *ip4addr; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); strv = nmc_strsplit_set (val, ",", 0); for (iter = strv; iter && *iter; iter++) { char *address = g_strstrip (*iter); - addrv = nmc_strsplit_set (address, " \t", 0); - if (g_strv_length (addrv) > 2) { - g_set_error (error, 1, 0, _("'%s' is not valid (use ip[/prefix] [gateway])"), - address); - g_strfreev (addrv); - g_strfreev (strv); - return FALSE; - } - ip4addr = nmc_parse_and_build_ip4_address (addrv[0], addrv[1], error); + ip4addr = _parse_ipv4_address (address, error); if (!ip4addr) { - g_strfreev (addrv); g_strfreev (strv); return FALSE; } nm_setting_ip4_config_add_address (NM_SETTING_IP4_CONFIG (setting), ip4addr); - g_strfreev (addrv); + nm_ip4_address_unref (ip4addr); } g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv4_remove_idx_addresses, - NM_SETTING_IP4_CONFIG, - nm_setting_ip4_config_get_num_addresses, - nm_setting_ip4_config_remove_address) + +static gboolean +_validate_and_remove_ipv4_address (NMSettingIP4Config *setting, + const char *address, + GError **error) +{ + NMIP4Address *ip4addr; + gboolean ret; + + ip4addr = _parse_ipv4_address (address, error); + if (!ip4addr) + return FALSE; + + ret = nm_setting_ip4_config_remove_address_by_value (setting, ip4addr); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain IP address '%s'"), address); + nm_ip4_address_unref (ip4addr); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv4_remove_addresses, + NM_SETTING_IP4_CONFIG, + nm_setting_ip4_config_get_num_addresses, + nm_setting_ip4_config_remove_address, + _validate_and_remove_ipv4_address) static const char * nmc_property_ipv4_describe_addresses (NMSetting *setting, const char *prop) @@ -2985,43 +3156,71 @@ nmc_property_out2in_addresses (const char *out_format) } /* 'routes' */ +static NMIP4Route * +_parse_ipv4_route (const char *route, GError **error) +{ + char **routev; + NMIP4Route *ip4route; + + routev = nmc_strsplit_set (route, " \t", 0); + if (g_strv_length (routev) < 2 || g_strv_length (routev) > 3) { + g_set_error (error, 1, 0, _("'%s' is not valid (use ip/[prefix] next-hop [metric])"), + route); + g_strfreev (routev); + return NULL; + } + ip4route = nmc_parse_and_build_ip4_route (routev[0], routev[1], routev[2], error); + g_strfreev (routev); + return ip4route; +} + static gboolean nmc_property_ipv4_set_routes (NMSetting *setting, const char *prop, const char *val, GError **error) { char **strv = NULL, **iter; - char **routev; - NMIP4Route *ip4route = NULL; + NMIP4Route *ip4route; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); strv = nmc_strsplit_set (val, ",", 0); for (iter = strv; iter && *iter; iter++) { char *route = g_strstrip (*iter); - routev = nmc_strsplit_set (route, " \t", 0); - if (g_strv_length (routev) < 2 || g_strv_length (routev) > 3) { - g_set_error (error, 1, 0, _("'%s' is not valid (use ip/[prefix] next-hop [metric])"), - route); - g_strfreev (routev); - g_strfreev (strv); - return FALSE; - } - ip4route = nmc_parse_and_build_ip4_route (routev[0], routev[1], routev[2], error); + ip4route = _parse_ipv4_route (route, error); if (!ip4route) { - g_strfreev (routev); g_strfreev (strv); return FALSE; } nm_setting_ip4_config_add_route (NM_SETTING_IP4_CONFIG (setting), ip4route); - g_strfreev (routev); + nm_ip4_route_unref (ip4route); } g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv4_remove_idx_routes, - NM_SETTING_IP4_CONFIG, - nm_setting_ip4_config_get_num_routes, - nm_setting_ip4_config_remove_route) + +static gboolean +_validate_and_remove_ipv4_route (NMSettingIP4Config *setting, + const char *route, + GError **error) +{ + NMIP4Route *ip4route; + gboolean ret; + + ip4route = _parse_ipv4_route (route, error); + if (!ip4route) + return FALSE; + + ret = nm_setting_ip4_config_remove_route_by_value (setting, ip4route); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain route '%s'"), route); + nm_ip4_route_unref (ip4route); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv4_remove_routes, + NM_SETTING_IP4_CONFIG, + nm_setting_ip4_config_get_num_routes, + nm_setting_ip4_config_remove_route, + _validate_and_remove_ipv4_route) static const char * nmc_property_ipv4_describe_routes (NMSetting *setting, const char *prop) @@ -3109,10 +3308,30 @@ nmc_property_ipv6_set_dns (NMSetting *setting, const char *prop, const char *val g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv6_remove_idx_dns, - NM_SETTING_IP6_CONFIG, - nm_setting_ip6_config_get_num_dns, - nm_setting_ip6_config_remove_dns) + +static gboolean +_validate_and_remove_ipv6_dns (NMSettingIP6Config *setting, + const char *dns, + GError **error) +{ + struct in6_addr ip6_addr; + gboolean ret; + + if (inet_pton (AF_INET6, dns, &ip6_addr) < 1) { + g_set_error (error, 1, 0, _("invalid IPv6 address '%s'"), dns); + return FALSE; + } + + ret = nm_setting_ip6_config_remove_dns_by_value (setting, &ip6_addr); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain DNS server '%s'"), dns); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv6_remove_dns, + NM_SETTING_IP6_CONFIG, + nm_setting_ip6_config_get_num_dns, + nm_setting_ip6_config_remove_dns, + _validate_and_remove_ipv6_dns) static const char * nmc_property_ipv6_describe_dns (NMSetting *setting, const char *prop) @@ -3148,49 +3367,93 @@ nmc_property_ipv6_set_dns_search (NMSetting *setting, const char *prop, const ch return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv6_remove_idx_dns_search, - NM_SETTING_IP6_CONFIG, - nm_setting_ip6_config_get_num_dns_searches, - nm_setting_ip6_config_remove_dns_search) + +static gboolean +_validate_and_remove_ipv6_dns_search (NMSettingIP6Config *setting, + const char *dns_search, + GError **error) +{ + gboolean ret; + + ret = nm_setting_ip6_config_remove_dns_search_by_value (setting, dns_search); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain DNS search domain '%s'"), + dns_search); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv6_remove_dns_search, + NM_SETTING_IP6_CONFIG, + nm_setting_ip6_config_get_num_dns_searches, + nm_setting_ip6_config_remove_dns_search, + _validate_and_remove_ipv6_dns_search) /* 'addresses' */ +static NMIP6Address * +_parse_ipv6_address (const char *address, GError **error) +{ + char **addrv; + NMIP6Address *ip6addr; + + addrv = nmc_strsplit_set (address, " \t", 0); + if (g_strv_length (addrv) > 2) { + g_set_error (error, 1, 0, _("'%s' is not valid (use ip[/prefix] [gateway])"), + address); + g_strfreev (addrv); + return NULL; + } + ip6addr = nmc_parse_and_build_ip6_address (addrv[0], addrv[1], error); + g_strfreev (addrv); + return ip6addr; +} + static gboolean nmc_property_ipv6_set_addresses (NMSetting *setting, const char *prop, const char *val, GError **error) { char **strv = NULL, **iter; - char **addrv; - NMIP6Address *ip6addr = NULL; + NMIP6Address *ip6addr; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); strv = nmc_strsplit_set (val, ",", 0); for (iter = strv; iter && *iter; iter++) { char *address = g_strstrip (*iter); - addrv = nmc_strsplit_set (address, " \t", 0); - if (g_strv_length (addrv) > 2) { - g_set_error (error, 1, 0, _("'%s' is not valid (use ip[/prefix] [gateway])"), - address); - g_strfreev (addrv); - g_strfreev (strv); - return FALSE; - } - ip6addr = nmc_parse_and_build_ip6_address (addrv[0], addrv[1], error); + ip6addr = _parse_ipv6_address (address, error); if (!ip6addr) { - g_strfreev (addrv); g_strfreev (strv); return FALSE; } nm_setting_ip6_config_add_address (NM_SETTING_IP6_CONFIG (setting), ip6addr); - g_strfreev (addrv); + nm_ip6_address_unref (ip6addr); } g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv6_remove_idx_addresses, - NM_SETTING_IP6_CONFIG, - nm_setting_ip6_config_get_num_addresses, - nm_setting_ip6_config_remove_address) + +static gboolean +_validate_and_remove_ipv6_address (NMSettingIP6Config *setting, + const char *address, + GError **error) +{ + NMIP6Address *ip6addr; + gboolean ret; + + ip6addr = _parse_ipv6_address (address, error); + if (!ip6addr) + return FALSE; + + ret = nm_setting_ip6_config_remove_address_by_value (setting, ip6addr); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain IP address '%s'"), address); + nm_ip6_address_unref (ip6addr); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv6_remove_addresses, + NM_SETTING_IP6_CONFIG, + nm_setting_ip6_config_get_num_addresses, + nm_setting_ip6_config_remove_address, + _validate_and_remove_ipv6_address) static const char * nmc_property_ipv6_describe_addresses (NMSetting *setting, const char *prop) @@ -3202,43 +3465,71 @@ nmc_property_ipv6_describe_addresses (NMSetting *setting, const char *prop) } /* 'routes' */ +static NMIP6Route * +_parse_ipv6_route (const char *route, GError **error) +{ + char **routev; + NMIP6Route *ip6route; + + routev = nmc_strsplit_set (route, " \t", 0); + if (g_strv_length (routev) < 2 || g_strv_length (routev) > 3) { + g_set_error (error, 1, 0, _("'%s' is not valid (use /prefix [metric])"), + route); + g_strfreev (routev); + return NULL; + } + ip6route = nmc_parse_and_build_ip6_route (routev[0], routev[1], routev[2], error); + g_strfreev (routev); + return ip6route; +} + static gboolean nmc_property_ipv6_set_routes (NMSetting *setting, const char *prop, const char *val, GError **error) { char **strv = NULL, **iter; - char **routev; - NMIP6Route *ip6route = NULL; + NMIP6Route *ip6route; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); strv = nmc_strsplit_set (val, ",", 0); for (iter = strv; iter && *iter; iter++) { char *route = g_strstrip (*iter); - routev = nmc_strsplit_set (route, " \t", 0); - if (g_strv_length (routev) < 2 || g_strv_length (routev) > 3) { - g_set_error (error, 1, 0, _("'%s' is not valid (use /prefix [metric])"), - route); - g_strfreev (routev); - g_strfreev (strv); - return FALSE; - } - ip6route = nmc_parse_and_build_ip6_route (routev[0], routev[1], routev[2], error); + ip6route = _parse_ipv6_route (route, error); if (!ip6route) { - g_strfreev (routev); g_strfreev (strv); return FALSE; } nm_setting_ip6_config_add_route (NM_SETTING_IP6_CONFIG (setting), ip6route); - g_strfreev (routev); + nm_ip6_route_unref (ip6route); } g_strfreev (strv); return TRUE; } -DEFINE_REMOVER_INDEX (nmc_property_ipv6_remove_idx_routes, - NM_SETTING_IP6_CONFIG, - nm_setting_ip6_config_get_num_routes, - nm_setting_ip6_config_remove_route) + +static gboolean +_validate_and_remove_ipv6_route (NMSettingIP6Config *setting, + const char *route, + GError **error) +{ + NMIP6Route *ip6route; + gboolean ret; + + ip6route = _parse_ipv6_route (route, error); + if (!ip6route) + return FALSE; + + ret = nm_setting_ip6_config_remove_route_by_value (setting, ip6route); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain route '%s'"), route); + nm_ip6_route_unref (ip6route); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_ipv6_remove_routes, + NM_SETTING_IP6_CONFIG, + nm_setting_ip6_config_get_num_routes, + nm_setting_ip6_config_remove_route, + _validate_and_remove_ipv6_route) static const char * nmc_property_ipv6_describe_routes (NMSetting *setting, const char *prop) @@ -3397,23 +3688,68 @@ nmc_property_vlan_set_egress_priority_map (NMSetting *setting, const char *prop, } static gboolean -nmc_property_vlan_remove_idx_ingress_priority_map (NMSetting *setting, - const char *prop, - const char *option, - guint32 idx, - GError **error) +nmc_property_vlan_remove_priority_map (NMSetting *setting, + const char *prop, + const char *value, + guint32 idx, + NMVlanPriorityMap map, + GError **error) { - return nmc_property_vlan_remove_prio_map (setting, prop, idx, NM_VLAN_INGRESS_MAP, error); + /* If value != NULL, remove by value */ + if (value) { + gboolean ret; + char **prio_map; + char *val = g_strdup (value); + + prio_map = nmc_vlan_parse_priority_maps (val, map, error); + if (!prio_map) + return FALSE; + if (prio_map[1]) + printf (_("Warning: only one mapping at a time is supported; taking the first one (%s)\n"), + prio_map[0]); + ret = nm_setting_vlan_remove_priority_str_by_value (NM_SETTING_VLAN (setting), + map, + prio_map[0]); + + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain mapping '%s'"), prio_map[0]); + g_free (val); + g_strfreev (prio_map); + return ret; + } + + /* Else remove by index */ + return nmc_property_vlan_remove_prio_map (setting, prop, idx, map, error); } static gboolean -nmc_property_vlan_remove_idx_egress_priority_map (NMSetting *setting, - const char *prop, - const char *option, - guint32 idx, - GError **error) +nmc_property_vlan_remove_ingress_priority_map (NMSetting *setting, + const char *prop, + const char *value, + guint32 idx, + GError **error) { - return nmc_property_vlan_remove_prio_map (setting, prop, idx, NM_VLAN_EGRESS_MAP, error); + return nmc_property_vlan_remove_priority_map (setting, + prop, + value, + idx, + NM_VLAN_INGRESS_MAP, + error); +} + +static gboolean +nmc_property_vlan_remove_egress_priority_map (NMSetting *setting, + const char *prop, + const char *value, + guint32 idx, + GError **error) +{ + return nmc_property_vlan_remove_priority_map (setting, + prop, + value, + idx, + NM_VLAN_EGRESS_MAP, + error); } /* --- NM_SETTING_VPN_SETTING_NAME property setter functions --- */ @@ -3475,10 +3811,30 @@ DEFINE_ALLOWED_VAL_FUNC (nmc_property_wired_allowed_duplex, wired_valid_duplexes DEFINE_SETTER_MAC_BLACKLIST (nmc_property_wired_set_mac_address_blacklist, NM_SETTING_WIRED, nm_setting_wired_add_mac_blacklist_item) -DEFINE_REMOVER_INDEX (nmc_property_wired_remove_idx_mac_address_blacklist, - NM_SETTING_WIRED, - nm_setting_wired_get_num_mac_blacklist_items, - nm_setting_wired_remove_mac_blacklist_item) + +static gboolean +_validate_and_remove_wired_mac_blacklist_item (NMSettingWired *setting, + const char *mac, + GError **error) +{ + gboolean ret; + guint8 buf[32]; + + if (!nm_utils_hwaddr_aton (mac, ARPHRD_ETHER, buf)) { + g_set_error (error, 1, 0, _("'%s' is not a valid MAC address"), mac); + return FALSE; + } + + ret = nm_setting_wired_remove_mac_blacklist_item_by_value (setting, mac); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain MAC address '%s'"), mac); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wired_remove_mac_address_blacklist, + NM_SETTING_WIRED, + nm_setting_wired_get_num_mac_blacklist_items, + nm_setting_wired_remove_mac_blacklist_item, + _validate_and_remove_wired_mac_blacklist_item) /* 's390-subchannels' */ static gboolean @@ -3623,10 +3979,30 @@ nmc_property_wifi_set_channel (NMSetting *setting, const char *prop, const char DEFINE_SETTER_MAC_BLACKLIST (nmc_property_wireless_set_mac_address_blacklist, NM_SETTING_WIRELESS, nm_setting_wireless_add_mac_blacklist_item) -DEFINE_REMOVER_INDEX (nmc_property_wireless_remove_idx_mac_address_blacklist, - NM_SETTING_WIRELESS, - nm_setting_wireless_get_num_mac_blacklist_items, - nm_setting_wireless_remove_mac_blacklist_item) + +static gboolean +_validate_and_remove_wifi_mac_blacklist_item (NMSettingWireless *setting, + const char *mac, + GError **error) +{ + gboolean ret; + guint8 buf[32]; + + if (!nm_utils_hwaddr_aton (mac, ARPHRD_ETHER, buf)) { + g_set_error (error, 1, 0, _("'%s' is not a valid MAC address"), mac); + return FALSE; + } + + ret = nm_setting_wireless_remove_mac_blacklist_item_by_value (setting, mac); + if (!ret) + g_set_error (error, 1, 0, _("the property doesn't contain MAC address '%s'"), mac); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wireless_remove_mac_address_blacklist, + NM_SETTING_WIRELESS, + nm_setting_wireless_get_num_mac_blacklist_items, + nm_setting_wireless_remove_mac_blacklist_item, + _validate_and_remove_wifi_mac_blacklist_item) /* --- NM_SETTING_WIRELESS_SECURITY_SETTING_NAME property setter functions --- */ /* 'key-mgmt' */ @@ -3662,10 +4038,30 @@ nmc_property_wifi_sec_set_proto (NMSetting *setting, const char *prop, const cha { return check_and_add_wifi_sec_proto (setting, prop, val, wifi_sec_valid_protos, error); } -DEFINE_REMOVER_INDEX (nmc_property_wifi_sec_remove_idx_proto, - NM_SETTING_WIRELESS_SECURITY, - nm_setting_wireless_security_get_num_protos, - nm_setting_wireless_security_remove_proto) + +static gboolean +_validate_and_remove_wifi_sec_proto (NMSettingWirelessSecurity *setting, + const char *proto, + GError **error) +{ + gboolean ret; + const char *valid; + + valid = nmc_string_is_valid (proto, wifi_sec_valid_protos, error); + if (!valid) + return FALSE; + + ret = nm_setting_wireless_security_remove_proto_by_value (setting, proto); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain protocol '%s'"), proto); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wifi_sec_remove_proto, + NM_SETTING_WIRELESS_SECURITY, + nm_setting_wireless_security_get_num_protos, + nm_setting_wireless_security_remove_proto, + _validate_and_remove_wifi_sec_proto) DEFINE_SETTER_STR_LIST_MULTI (check_and_add_wifi_sec_pairwise, NM_SETTING_WIRELESS_SECURITY, @@ -3680,10 +4076,30 @@ nmc_property_wifi_sec_set_pairwise (NMSetting *setting, const char *prop, const { return check_and_add_wifi_sec_pairwise (setting, prop, val, wifi_sec_valid_pairwises, error); } -DEFINE_REMOVER_INDEX (nmc_property_wifi_sec_remove_idx_pairwise, - NM_SETTING_WIRELESS_SECURITY, - nm_setting_wireless_security_get_num_pairwise, - nm_setting_wireless_security_remove_pairwise) + +static gboolean +_validate_and_remove_wifi_sec_pairwise (NMSettingWirelessSecurity *setting, + const char *pairwise, + GError **error) +{ + gboolean ret; + const char *valid; + + valid = nmc_string_is_valid (pairwise, wifi_sec_valid_pairwises, error); + if (!valid) + return FALSE; + + ret = nm_setting_wireless_security_remove_pairwise_by_value (setting, pairwise); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain protocol '%s'"), pairwise); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wifi_sec_remove_pairwise, + NM_SETTING_WIRELESS_SECURITY, + nm_setting_wireless_security_get_num_pairwise, + nm_setting_wireless_security_remove_pairwise, + _validate_and_remove_wifi_sec_pairwise) DEFINE_SETTER_STR_LIST_MULTI (check_and_add_wifi_sec_group, NM_SETTING_WIRELESS_SECURITY, @@ -3698,10 +4114,30 @@ nmc_property_wifi_sec_set_group (NMSetting *setting, const char *prop, const cha { return check_and_add_wifi_sec_group (setting, prop, val, wifi_sec_valid_groups, error); } -DEFINE_REMOVER_INDEX (nmc_property_wifi_sec_remove_idx_group, - NM_SETTING_WIRELESS_SECURITY, - nm_setting_wireless_security_get_num_groups, - nm_setting_wireless_security_remove_group) + +static gboolean +_validate_and_remove_wifi_sec_group (NMSettingWirelessSecurity *setting, + const char *group, + GError **error) +{ + gboolean ret; + const char *valid; + + valid = nmc_string_is_valid (group, wifi_sec_valid_groups, error); + if (!valid) + return FALSE; + + ret = nm_setting_wireless_security_remove_group_by_value (setting, group); + if (!ret) + g_set_error (error, 1, 0, + _("the property doesn't contain protocol '%s'"), group); + return ret; +} +DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wifi_sec_remove_group, + NM_SETTING_WIRELESS_SECURITY, + nm_setting_wireless_security_get_num_groups, + nm_setting_wireless_security_remove_group, + _validate_and_remove_wifi_sec_group) DEFINE_ALLOWED_VAL_FUNC (nmc_property_wifi_sec_allowed_group, wifi_sec_valid_groups) /* 'wep-key' */ @@ -4120,7 +4556,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (802_1X, EAP), nmc_property_802_1X_get_eap, nmc_property_802_1X_set_eap, - nmc_property_802_1X_remove_idx_eap, + nmc_property_802_1X_remove_eap, NULL, NULL, NULL); @@ -4169,7 +4605,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (802_1X, ALTSUBJECT_MATCHES), nmc_property_802_1X_get_altsubject_matches, nmc_property_802_1X_set_altsubject_matches, - nmc_property_802_1X_remove_idx_altsubject_matches, + nmc_property_802_1X_remove_altsubject_matches, NULL, NULL, NULL); @@ -4239,7 +4675,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (802_1X, PHASE2_ALTSUBJECT_MATCHES), nmc_property_802_1X_get_phase2_altsubject_matches, nmc_property_802_1X_set_phase2_altsubject_matches, - nmc_property_802_1X_remove_idx_phase2_altsubject_matches, + nmc_property_802_1X_remove_phase2_altsubject_matches, NULL, NULL, NULL); @@ -4582,7 +5018,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (CONNECTION, PERMISSIONS), nmc_property_connection_get_permissions, nmc_property_connection_set_permissions, - nmc_property_connection_remove_idx_permissions, + nmc_property_connection_remove_permissions, nmc_property_connection_describe_permissions, NULL, NULL); @@ -4610,7 +5046,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (CONNECTION, SECONDARIES), nmc_property_connection_get_secondaries, nmc_property_connection_set_secondaries, - nmc_property_connection_remove_idx_secondaries, + nmc_property_connection_remove_secondaries, NULL, NULL, NULL); @@ -4856,28 +5292,28 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (IP4_CONFIG, DNS), nmc_property_ipv4_get_dns, nmc_property_ipv4_set_dns, - nmc_property_ipv4_remove_idx_dns, + nmc_property_ipv4_remove_dns, nmc_property_ipv4_describe_dns, NULL, NULL); nmc_add_prop_funcs (GLUE (IP4_CONFIG, DNS_SEARCH), nmc_property_ipv4_get_dns_search, nmc_property_ipv4_set_dns_search, - nmc_property_ipv4_remove_idx_dns_search, + nmc_property_ipv4_remove_dns_search, NULL, NULL, NULL); nmc_add_prop_funcs (GLUE (IP4_CONFIG, ADDRESSES), nmc_property_ipv4_get_addresses, nmc_property_ipv4_set_addresses, - nmc_property_ipv4_remove_idx_addresses, + nmc_property_ipv4_remove_addresses, nmc_property_ipv4_describe_addresses, NULL, nmc_property_out2in_addresses); nmc_add_prop_funcs (GLUE (IP4_CONFIG, ROUTES), nmc_property_ipv4_get_routes, nmc_property_ipv4_set_routes, - nmc_property_ipv4_remove_idx_routes, + nmc_property_ipv4_remove_routes, nmc_property_ipv4_describe_routes, NULL, nmc_property_out2in_routes); @@ -4942,28 +5378,28 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (IP6_CONFIG, DNS), nmc_property_ipv6_get_dns, nmc_property_ipv6_set_dns, - nmc_property_ipv6_remove_idx_dns, + nmc_property_ipv6_remove_dns, nmc_property_ipv6_describe_dns, NULL, NULL); nmc_add_prop_funcs (GLUE (IP6_CONFIG, DNS_SEARCH), nmc_property_ipv6_get_dns_search, nmc_property_ipv6_set_dns_search, - nmc_property_ipv6_remove_idx_dns_search, + nmc_property_ipv6_remove_dns_search, NULL, NULL, NULL); nmc_add_prop_funcs (GLUE (IP6_CONFIG, ADDRESSES), nmc_property_ipv6_get_addresses, nmc_property_ipv6_set_addresses, - nmc_property_ipv6_remove_idx_addresses, + nmc_property_ipv6_remove_addresses, nmc_property_ipv6_describe_addresses, NULL, nmc_property_out2in_addresses); nmc_add_prop_funcs (GLUE (IP6_CONFIG, ROUTES), nmc_property_ipv6_get_routes, nmc_property_ipv6_set_routes, - nmc_property_ipv6_remove_idx_routes, + nmc_property_ipv6_remove_routes, nmc_property_ipv6_describe_routes, NULL, nmc_property_out2in_routes); @@ -5285,14 +5721,14 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (VLAN, INGRESS_PRIORITY_MAP), nmc_property_vlan_get_ingress_priority_map, nmc_property_vlan_set_ingress_priority_map, - nmc_property_vlan_remove_idx_ingress_priority_map, + nmc_property_vlan_remove_ingress_priority_map, NULL, NULL, NULL); nmc_add_prop_funcs (GLUE (VLAN, EGRESS_PRIORITY_MAP), nmc_property_vlan_get_egress_priority_map, nmc_property_vlan_set_egress_priority_map, - nmc_property_vlan_remove_idx_egress_priority_map, + nmc_property_vlan_remove_egress_priority_map, NULL, NULL, NULL); @@ -5389,7 +5825,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (WIRED, MAC_ADDRESS_BLACKLIST), nmc_property_wired_get_mac_address_blacklist, nmc_property_wired_set_mac_address_blacklist, - nmc_property_wired_remove_idx_mac_address_blacklist, + nmc_property_wired_remove_mac_address_blacklist, NULL, NULL, NULL); @@ -5493,7 +5929,7 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (WIRELESS, MAC_ADDRESS_BLACKLIST), nmc_property_wireless_get_mac_address_blacklist, nmc_property_wireless_set_mac_address_blacklist, - nmc_property_wireless_remove_idx_mac_address_blacklist, + nmc_property_wireless_remove_mac_address_blacklist, NULL, NULL, NULL); @@ -5544,21 +5980,21 @@ nmc_properties_init (void) nmc_add_prop_funcs (GLUE (WIRELESS_SECURITY, PROTO), nmc_property_wifi_sec_get_proto, nmc_property_wifi_sec_set_proto, - nmc_property_wifi_sec_remove_idx_proto, + nmc_property_wifi_sec_remove_proto, NULL, nmc_property_wifi_sec_allowed_proto, NULL); nmc_add_prop_funcs (GLUE (WIRELESS_SECURITY, PAIRWISE), nmc_property_wifi_sec_get_pairwise, nmc_property_wifi_sec_set_pairwise, - nmc_property_wifi_sec_remove_idx_pairwise, + nmc_property_wifi_sec_remove_pairwise, NULL, nmc_property_wifi_sec_allowed_pairwise, NULL); nmc_add_prop_funcs (GLUE (WIRELESS_SECURITY, GROUP), nmc_property_wifi_sec_get_group, nmc_property_wifi_sec_set_group, - nmc_property_wifi_sec_remove_idx_group, + nmc_property_wifi_sec_remove_group, NULL, nmc_property_wifi_sec_allowed_group, NULL); From a5673d113c901fb262712748274f4e85549e97ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 25 Feb 2014 11:59:03 +0100 Subject: [PATCH 14/16] cli: update 'remove' command description for 'nmcli con edit' to reflect that user can specify a value or index to remove values. --- cli/src/connections.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 71642539fe..509a63c8f5 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -6180,18 +6180,25 @@ editor_sub_usage (const char *command) "This command sets provided to this property\n")); break; case NMC_EDITOR_SUB_CMD_ADD: - printf (_("add [] :: add new option to the property\n\n" - "This command add provided to this property, if " + printf (_("add [] :: append new value to the property\n\n" + "This command adds provided to this property, if " "the property is of a container type. For single-valued " - "properties it replaces the value (same as 'set').\n")); + "properties the property value is replaced (same as 'set').\n")); break; case NMC_EDITOR_SUB_CMD_CHANGE: printf (_("change :: change current value\n\n" "Displays current value and allows editing it.\n")); break; case NMC_EDITOR_SUB_CMD_REMOVE: - printf (_("remove [|