summary refs log tree commit diff
path: root/clients/cli
diff options
context:
space:
mode:
Diffstat (limited to 'clients/cli')
-rw-r--r--clients/cli/connections.c64
-rw-r--r--clients/cli/devices.c46
-rw-r--r--clients/cli/utils.h18
3 files changed, 79 insertions, 49 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 44e34d56..2b9c4a25 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -4273,45 +4273,36 @@ set_bond_option (NmCli *nmc, NMConnection *con, const OptionInfo *option, const
 {
 	NMSettingBond *s_bond;
 	gboolean success;
+	gs_free char *name = NULL;
+	char *p;
 
 	s_bond = nm_connection_get_setting_bond (con);
 	g_return_val_if_fail (s_bond, FALSE);
 
-	if (!value)
-		return TRUE;
-
-	if (strcmp (option->option, "mode") == 0) {
-		value = nmc_bond_validate_mode (value, error);
-		if (!value)
-			return FALSE;
+	name = g_strdup (option->option);
+	for (p = name; p[0]; p++) {
+		if (p[0] == '-')
+			p[0] = '_';
+	}
 
-		if (g_strcmp0 (value, "active-backup") == 0) {
-			const char *primary[] = { "primary", NULL };
-			enable_options (NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, primary);
-		}
+	if (nm_str_is_empty (value)) {
+		nm_setting_bond_remove_option (s_bond, name);
+		success = TRUE;
+	} else
+		success = _nm_meta_setting_bond_add_option (NM_SETTING (s_bond), name, value, error);
 
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MODE, value);
-	} else if (strcmp (option->option, "primary") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_PRIMARY, value);
-	else if (strcmp (option->option, "miimon") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON, value);
-	else if (strcmp (option->option, "downdelay") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, value);
-	else if (strcmp (option->option, "updelay") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY, value);
-	else if (strcmp (option->option, "arp-interval") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL, value);
-	else if (strcmp (option->option, "arp-ip-target") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, value);
-	else if (strcmp (option->option, "lacp-rate") == 0)
-		success = nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_LACP_RATE, value);
-	else
-		g_return_val_if_reached (FALSE);
+	if (!success)
+		return FALSE;
 
-	if (!success) {
-		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-		             _("Error: error adding bond option '%s=%s'."),
-		             option->option, value);
+	if (success) {
+		if (nm_streq (name, NM_SETTING_BOND_OPTION_MODE)) {
+			value = nmc_bond_validate_mode (value, error);
+			if (nm_streq (value, "active-backup")) {
+				enable_options (NM_SETTING_BOND_SETTING_NAME,
+				                NM_SETTING_BOND_OPTIONS,
+				                NM_MAKE_STRV ("primary"));
+			}
+		}
 	}
 
 	return success;
@@ -4718,13 +4709,18 @@ nmc_process_connection_properties (NmCli *nmc,
 		ensure_settings (connection, slv_settings);
 		ensure_settings (connection, type_settings);
 
-		option_orig = **argv;
-		if (!option_orig) {
+		if (*argc <= 0) {
 			g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
 			                     _("Error: <setting>.<property> argument is missing."));
 			return FALSE;
 		}
 
+		nm_assert (argv);
+		nm_assert (*argv);
+		nm_assert (**argv);
+
+		option_orig = **argv;
+
 		switch (option_orig[0]) {
 		case '+': modifier = NM_META_ACCESSOR_MODIFIER_ADD; option = &option_orig[1]; break;
 		case '-': modifier = NM_META_ACCESSOR_MODIFIER_DEL; option = &option_orig[1]; break;
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index 27f72e77..38201b33 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -168,14 +168,14 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS)
 		return nm_device_get_product (d);
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_DRIVER:
 		s = nm_device_get_driver (d);
-		return s ?: nmc_meta_generic_get_str_i18n (N_("(unknown)"), get_type);
+		return s ?: nmc_meta_generic_get_unknown (get_type);
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_DRIVER_VERSION:
 		return nm_device_get_driver_version (d);
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_FIRMWARE_VERSION:
 		return nm_device_get_firmware_version (d);
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_HWADDR:
 		s = nm_device_get_hw_address (d);
-		return s ?: nmc_meta_generic_get_str_i18n (N_("(unknown)"), get_type);
+		return s ?: nmc_meta_generic_get_unknown (get_type);
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_MTU:
 		return (*out_to_free = g_strdup_printf ("%u", (guint) nm_device_get_mtu (d)));
 	case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_STATE:
@@ -2268,10 +2268,19 @@ typedef struct {
 } ModifyInfo;
 
 static void
+modify_info_free (ModifyInfo *info)
+{
+	g_strfreev (info->argv);
+	nm_g_slice_free (info);
+}
+
+NM_AUTO_DEFINE_FCN_VOID0 (ModifyInfo *, _auto_free_modify_info, modify_info_free)
+
+static void
 modify_reapply_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 {
 	NMDevice *device = NM_DEVICE (object);
-	ModifyInfo *info = user_data;
+	nm_auto (_auto_free_modify_info) ModifyInfo *info = user_data;
 	NmCli *nmc = info->nmc;
 	GError *error = NULL;
 
@@ -2289,7 +2298,6 @@ modify_reapply_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 		         nm_device_get_iface (device));
 	}
 
-	g_slice_free (ModifyInfo, info);
 	quit ();
 }
 
@@ -2299,7 +2307,7 @@ modify_get_applied_cb (GObject *object,
                        gpointer user_data)
 {
 	NMDevice *device = NM_DEVICE (object);
-	ModifyInfo *info = user_data;
+	nm_auto (_auto_free_modify_info) ModifyInfo *info = user_data;
 	NmCli *nmc = info->nmc;
 	gs_free_error GError *error = NULL;
 	NMConnection *connection;
@@ -2317,7 +2325,6 @@ modify_get_applied_cb (GObject *object,
 		                 nm_object_get_path (NM_OBJECT (device)),
 		                 error->message);
 		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
-		g_slice_free (ModifyInfo, info);
 		quit ();
 		return;
 	}
@@ -2328,22 +2335,29 @@ modify_get_applied_cb (GObject *object,
 	if (!nmc_process_connection_properties (info->nmc, connection, &argc, &argv, TRUE, &error)) {
 		g_string_assign (nmc->return_text, error->message);
 		nmc->return_value = error->code;
-		g_slice_free (ModifyInfo, info);
 		quit ();
 		return;
 	}
 
-	if (nmc->complete)
+	if (nmc->complete) {
 		quit ();
-	else
-		nm_device_reapply_async (device, connection, version_id, 0, NULL, modify_reapply_cb, info);
+		return;
+	}
+
+	nm_device_reapply_async (device,
+	                         connection,
+	                         version_id,
+	                         0,
+	                         NULL,
+	                         modify_reapply_cb,
+	                         g_steal_pointer (&info));
 }
 
 static void
 do_device_modify (const NMCCommand *cmd, NmCli *nmc, int argc, const char *const*argv)
 {
 	NMDevice *device = NULL;
-	ModifyInfo *info = NULL;
+	ModifyInfo *info;
 	gs_free_error GError *error = NULL;
 
 	next_arg (nmc, &argc, &argv, NULL);
@@ -2360,10 +2374,12 @@ do_device_modify (const NMCCommand *cmd, NmCli *nmc, int argc, const char *const
 	nmc->nowait_flag = (nmc->timeout == 0);
 	nmc->should_wait++;
 
-	info = g_slice_new0 (ModifyInfo);
-	info->nmc = nmc;
-	info->argc = argc;
-	info->argv = nm_utils_strv_dup ((char **) argv, argc, TRUE);
+	info = g_slice_new (ModifyInfo);
+	*info = (ModifyInfo) {
+		.nmc  = nmc,
+		.argc = argc,
+		.argv = nm_utils_strv_dup ((char **) argv, argc, TRUE),
+	};
 
 	nm_device_get_applied_connection_async (device, 0, NULL, modify_get_applied_cb, info);
 }
diff --git a/clients/cli/utils.h b/clients/cli/utils.h
index d7ad738f..02b81b70 100644
--- a/clients/cli/utils.h
+++ b/clients/cli/utils.h
@@ -289,6 +289,24 @@ nmc_meta_generic_get_str_i18n (const char *s, NMMetaAccessorGetType get_type)
 }
 
 static inline const char *
+nmc_meta_generic_get_str_i18n_null (const char *s, NMMetaAccessorGetType get_type)
+{
+	if (get_type == NM_META_ACCESSOR_GET_TYPE_PARSABLE) {
+		/* in parsable mode, return NULL. That is useful if @s is a pretty string
+		 * to describe a missing value (like "(unknown)"). We don't want to print
+		 * that for parsable mode. */
+		return NULL;
+	}
+	return nmc_meta_generic_get_str_i18n (s, get_type);
+}
+
+static inline const char *
+nmc_meta_generic_get_unknown (NMMetaAccessorGetType get_type)
+{
+	return nmc_meta_generic_get_str_i18n_null (N_("(unknown)"), get_type);
+}
+
+static inline const char *
 nmc_meta_generic_get_bool (gboolean val, NMMetaAccessorGetType get_type)
 {
 	return nmc_meta_generic_get_str_i18n (val ? N_("yes") : N_("no"), get_type);