about summary refs log tree commit diff
path: root/cli/src/network-manager.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2014-07-06 03:04:17 +0200
committerMichael Biebl <biebl@debian.org>2014-07-06 03:04:17 +0200
commit3ce667b6ee6b86291bbe60ef93cba7f11a5c5400 (patch)
treeaf3daa7221e898b72f3de26eb2cf0c1b1c8661b0 /cli/src/network-manager.c
parentf02d31d95af29678092d1ff01f714621bc9dcc0f (diff)
parent33491bc4279481db8ae47213e34a6d695a0e8830 (diff)
Merge tag 'upstream/0.9.10.0'
Upstream version 0.9.10.0
Diffstat (limited to 'cli/src/network-manager.c')
-rw-r--r--cli/src/network-manager.c920
1 files changed, 617 insertions, 303 deletions
diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c
index 8fb5f6cf..ed074c6d 100644
--- a/cli/src/network-manager.c
+++ b/cli/src/network-manager.c
@@ -14,7 +14,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2010 - 2012 Red Hat, Inc.
+ * (C) Copyright 2010 - 2014 Red Hat, Inc.
  */
 
 #include "config.h"
@@ -32,67 +32,223 @@
 #include "network-manager.h"
 
 
-/* Available fields for 'nm status' */
+/* Available fields for 'general status' */
 static NmcOutputField nmc_fields_nm_status[] = {
-	{"RUNNING",        N_("RUNNING"),         15, NULL, 0},  /* 0 */
-	{"VERSION",        N_("VERSION"),         10, NULL, 0},  /* 1 */
-	{"STATE",          N_("STATE"),           15, NULL, 0},  /* 2 */
-	{"NET-ENABLED",    N_("NET-ENABLED"),     13, NULL, 0},  /* 3 */
-	{"WIFI-HARDWARE",  N_("WIFI-HARDWARE"),   15, NULL, 0},  /* 4 */
-	{"WIFI",           N_("WIFI"),            10, NULL, 0},  /* 5 */
-	{"WWAN-HARDWARE",  N_("WWAN-HARDWARE"),   15, NULL, 0},  /* 6 */
-	{"WWAN",           N_("WWAN"),            10, NULL, 0},  /* 7 */
-	{"WIMAX-HARDWARE", N_("WIMAX-HARDWARE"),  15, NULL, 0},  /* 8 */
-	{"WIMAX",          N_("WIMAX"),           10, NULL, 0},  /* 9 */
-	{NULL,             NULL,                  0, NULL, 0}
+	{"RUNNING",      N_("RUNNING"),      15},  /* 0 */
+	{"VERSION",      N_("VERSION"),      10},  /* 1 */
+	{"STATE",        N_("STATE"),        15},  /* 2 */
+	{"STARTUP",      N_("STARTUP"),      10},  /* 3 */
+	{"CONNECTIVITY", N_("CONNECTIVITY"), 15},  /* 4 */
+	{"NETWORKING",   N_("NETWORKING"),   13},  /* 5 */
+	{"WIFI-HW",      N_("WIFI-HW"),      15},  /* 6 */
+	{"WIFI",         N_("WIFI"),         10},  /* 7 */
+	{"WWAN-HW",      N_("WWAN-HW"),      15},  /* 8 */
+	{"WWAN",         N_("WWAN"),         10},  /* 9 */
+	{"WIMAX-HW",     N_("WIMAX-HW"),     15},  /* 10 */
+	{"WIMAX",        N_("WIMAX"),        10},  /* 11 */
+	{NULL,           NULL,                0}
 };
 #if WITH_WIMAX
-#define NMC_FIELDS_NM_STATUS_ALL     "RUNNING,VERSION,STATE,NET-ENABLED,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN,WIMAX-HARDWARE,WIMAX"
+#define NMC_FIELDS_NM_STATUS_ALL     "RUNNING,VERSION,STATE,STARTUP,CONNECTIVITY,NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN,WIMAX-HW,WIMAX"
+#define NMC_FIELDS_NM_STATUS_SWITCH  "NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN,WIMAX-HW,WIMAX"
+#define NMC_FIELDS_NM_STATUS_RADIO   "WIFI-HW,WIFI,WWAN-HW,WWAN,WIMAX-HW,WIMAX"
 #else
-#define NMC_FIELDS_NM_STATUS_ALL     "RUNNING,VERSION,STATE,NET-ENABLED,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN"
+#define NMC_FIELDS_NM_STATUS_ALL     "RUNNING,VERSION,STATE,STARTUP,CONNECTIVITY,NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN"
+#define NMC_FIELDS_NM_STATUS_SWITCH  "NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN"
+#define NMC_FIELDS_NM_STATUS_RADIO   "WIFI-HW,WIFI,WWAN-HW,WWAN"
 #endif
-#define NMC_FIELDS_NM_STATUS_COMMON  "RUNNING,STATE,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN"
-#define NMC_FIELDS_NM_NET_ENABLED    "NET-ENABLED"
+#define NMC_FIELDS_NM_STATUS_COMMON  "STATE,CONNECTIVITY,WIFI-HW,WIFI,WWAN-HW,WWAN"
+#define NMC_FIELDS_NM_NETWORKING     "NETWORKING"
 #define NMC_FIELDS_NM_WIFI           "WIFI"
 #define NMC_FIELDS_NM_WWAN           "WWAN"
 #define NMC_FIELDS_NM_WIMAX          "WIMAX"
+#define NMC_FIELDS_NM_CONNECTIVITY   "CONNECTIVITY"
 
-/* Available fields for 'nm permissions' */
+
+/* Available fields for 'general permissions' */
 static NmcOutputField nmc_fields_nm_permissions[] = {
-	{"PERMISSION",     N_("PERMISSION"),      57, NULL, 0},  /* 0 */
-	{"VALUE",          N_("VALUE"),           10, NULL, 0},  /* 1 */
-	{NULL,             NULL,                  0, NULL, 0}
+	{"PERMISSION", N_("PERMISSION"), 57},  /* 0 */
+	{"VALUE",      N_("VALUE"),      10},  /* 1 */
+	{NULL,         NULL,              0}
 };
 #define NMC_FIELDS_NM_PERMISSIONS_ALL     "PERMISSION,VALUE"
 #define NMC_FIELDS_NM_PERMISSIONS_COMMON  "PERMISSION,VALUE"
 
+/* Available fields for 'general logging' */
+static NmcOutputField nmc_fields_nm_logging[] = {
+	{"LEVEL",   N_("LEVEL"),   10},  /* 0 */
+	{"DOMAINS", N_("DOMAINS"), 70},  /* 1 */
+	{NULL,      NULL,           0}
+};
+#define NMC_FIELDS_NM_LOGGING_ALL     "LEVEL,DOMAINS"
+#define NMC_FIELDS_NM_LOGGING_COMMON  "LEVEL,DOMAINS"
+
 
 /* glib main loop variable - defined in nmcli.c */
 extern GMainLoop *loop;
 
+
+static void
+usage_general (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli general { COMMAND | help }\n\n"
+	           "COMMAND := { status | hostname | permissions | logging }\n\n"
+	           "  status\n\n"
+	           "  hostname [<hostname>]\n\n"
+	           "  permissions\n\n"
+	           "  logging [level <log level>] [domains <log domains>]\n\n"));
+}
+
+static void
+usage_general_status (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli general status { help }\n"
+	           "\n"
+	           "Show overall status of NetworkManager.\n"
+	           "'status' is the default action, which means 'nmcli gen' calls 'nmcli gen status'\n\n"));
+}
+
+static void
+usage_general_hostname (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli general hostname { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [<hostname>]\n"
+	           "\n"
+	           "Get or change persistent system hostname.\n"
+	           "With no arguments, this prints currently configured hostname. When you pass\n"
+	           "a hostname, NetworkManager will set it as the new persistent system hostname.\n\n"));
+}
+
+static void
+usage_general_permissions (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli general permissions { help }\n"
+	           "\n"
+	           "Show caller permissions for authenticated operations.\n\n"));
+}
+
+static void
+usage_general_logging (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli general logging { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [level <log level>] [domains <log domains>]\n"
+	           "\n"
+	           "Get or change NetworkManager logging level and domains.\n"
+	           "Without any argument current logging level and domains are shown. In order to\n"
+	           "change logging state, provide level and/or domain. Please refer to the man page\n"
+	           "for the list of possible logging domains.\n\n"));
+}
+
+static void
+usage_networking (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli networking { COMMAND | help }\n\n"
+	           "COMMAND := { [ on | off | connectivity ] }\n\n"
+	           "  on\n\n"
+	           "  off\n\n"
+	           "  connectivity [check]\n\n"));
+}
+
+static void
+usage_networking_on (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli networking on { help }\n"
+	           "\n"
+	           "Switch networking on.\n\n"));
+}
+
+static void
+usage_networking_off (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli networking off { help }\n"
+	           "\n"
+	           "Switch networking off.\n\n"));
+}
+
+static void
+usage_networking_connectivity (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli networking connectivity { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [check]\n"
+	           "\n"
+	           "Get network connectivity state.\n"
+	           "The optional 'check' argument makes NetworkManager re-check the connectivity.\n\n"));
+
+}
+
 static void
-usage (void)
+usage_radio (void)
 {
 	fprintf (stderr,
-	         _("Usage: nmcli nm { COMMAND | help }\n\n"
+	         _("Usage: nmcli radio { COMMAND | help }\n\n"
 #if WITH_WIMAX
-	         "  COMMAND := { status | permissions | enable | sleep | wifi | wwan | wimax }\n\n"
+	           "COMMAND := { all | wifi | wwan | wimax }\n\n"
+	           "  all | wifi | wwan | wimax [ on | off ]\n\n"
 #else
-	         "  COMMAND := { status | permissions | enable | sleep | wifi | wwan }\n\n"
-#endif
-	         "  status\n"
-	         "  permissions\n"
-	         "  enable [true|false]\n"
-	         "  sleep [true|false]\n"
-	         "  wifi [on|off]\n"
-	         "  wwan [on|off]\n"
-#if WITH_WIMAX
-	         "  wimax [on|off]\n"
+	           "COMMAND := { all | wifi | wwan }\n\n"
+	           "  all | wifi | wwan [ on | off ]\n\n"
 #endif
-	         "\n"
 	         ));
 }
 
+static void
+usage_radio_all (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli radio all { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [on | off]\n"
+	           "\n"
+	           "Get status of all radio switches, or turn them on/off.\n\n"));
+}
+
+static void
+usage_radio_wifi (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli radio wifi { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [on | off]\n"
+	           "\n"
+	           "Get status of Wi-Fi radio switch, or turn it on/off.\n\n"));
+}
+
+static void
+usage_radio_wwan (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli radio wwan { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [on | off]\n"
+	           "\n"
+	           "Get status of mobile broadband radio switch, or turn it on/off.\n\n"));
+}
+
+#if WITH_WIMAX
+static void
+usage_radio_wimax (void)
+{
+	fprintf (stderr,
+	         _("Usage: nmcli radio wimax { ARGUMENTS | help }\n"
+	           "\n"
+	           "ARGUMENTS := [on | off]\n"
+	           "\n"
+	           "Get status of WiMAX radio switch, or turn it on/off.\n\n"));
+}
+#endif
+
 /* quit main loop */
 static void
 quit (void)
@@ -124,11 +280,30 @@ nm_state_to_string (NMState state)
 	}
 }
 
-static NMCResultCode
-show_nm_status (NmCli *nmc)
+static const char *
+nm_connectivity_to_string (NMConnectivityState connectivity)
+{
+	switch (connectivity) {
+	case NM_CONNECTIVITY_NONE:
+		return _("none");
+	case NM_CONNECTIVITY_PORTAL:
+		return _("portal");
+	case NM_CONNECTIVITY_LIMITED:
+		return _("limited");
+	case NM_CONNECTIVITY_FULL:
+		return _("full");
+	case NM_CONNECTIVITY_UNKNOWN:
+	default:
+		return _("unknown");
+	}
+}
+
+static gboolean
+show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_flds)
 {
-	gboolean nm_running;
+	gboolean nm_running, startup = FALSE;
 	NMState state = NM_STATE_UNKNOWN;
+	NMConnectivityState connectivity = NM_CONNECTIVITY_UNKNOWN;
 	const char *net_enabled_str;
 	const char *wireless_hw_enabled_str, *wireless_enabled_str;
 	const char *wwan_hw_enabled_str, *wwan_enabled_str;
@@ -137,11 +312,10 @@ show_nm_status (NmCli *nmc)
 #endif
 	GError *error = NULL;
 	const char *fields_str;
-	const char *fields_all =    NMC_FIELDS_NM_STATUS_ALL;
-	const char *fields_common = NMC_FIELDS_NM_STATUS_COMMON;
-	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
-	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
-	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+	const char *fields_all =    print_flds ? print_flds : NMC_FIELDS_NM_STATUS_ALL;
+	const char *fields_common = print_flds ? print_flds : NMC_FIELDS_NM_STATUS_COMMON;
+	NmcOutputField *tmpl, *arr;
+	size_t tmpl_len;
 
 	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
 		fields_str = fields_common;
@@ -150,26 +324,27 @@ show_nm_status (NmCli *nmc)
 	else
 		fields_str = nmc->required_fields;
 
-	nmc->allowed_fields = nmc_fields_nm_status;
-	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+	tmpl = nmc_fields_nm_status;
+	tmpl_len = sizeof (nmc_fields_nm_status);
+	nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error);
 
 	if (error) {
-		if (error->code == 0)
-			g_string_printf (nmc->return_text, _("Error: 'nm status': %s"), error->message);
-		else
-			g_string_printf (nmc->return_text, _("Error: 'nm status': %s; allowed fields: %s"), error->message, NMC_FIELDS_NM_STATUS_ALL);
+		g_string_printf (nmc->return_text, _("Error: only these fields are allowed: %s"), fields_all);
 		g_error_free (error);
 		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-		return nmc->return_value;
+		return FALSE;
 	}
 
-	nm_running = nmc_is_nm_running (nmc, NULL);
+	nmc->get_client (nmc); /* create NMClient */
+
+	nm_running = nm_client_get_manager_running (nmc->client);
 	if (nm_running) {
 		if (!nmc_versions_match (nmc))
-			goto error;
+			return FALSE;
 
-		nmc->get_client (nmc); /* create NMClient */
 		state = nm_client_get_state (nmc->client);
+		startup = nm_client_get_startup (nmc->client);
+		connectivity = nm_client_get_connectivity (nmc->client);
 		net_enabled_str = nm_client_networking_get_enabled (nmc->client) ? _("enabled") : _("disabled");
 		wireless_hw_enabled_str = nm_client_wireless_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
 		wireless_enabled_str = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
@@ -189,30 +364,30 @@ show_nm_status (NmCli *nmc)
 #endif
 	}
 
-	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
-	nmc->print_fields.header_name = _("NetworkManager status");
-	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-
-	nmc->allowed_fields[0].value = nm_running ? _("running") : _("not running");
-	nmc->allowed_fields[1].value = nm_running ? nm_client_get_version (nmc->client) : _("unknown");
-	nmc->allowed_fields[2].value = nm_state_to_string (state);
-	nmc->allowed_fields[3].value = net_enabled_str;
-	nmc->allowed_fields[4].value = wireless_hw_enabled_str;
-	nmc->allowed_fields[5].value = wireless_enabled_str;
-	nmc->allowed_fields[6].value = wwan_hw_enabled_str;
-	nmc->allowed_fields[7].value = wwan_enabled_str;
+	nmc->print_fields.header_name = pretty_header_name ? (char *) pretty_header_name : _("NetworkManager status");
+	arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES);
+	g_ptr_array_add (nmc->output_data, arr);
+
+	arr = nmc_dup_fields_array (tmpl, tmpl_len, 0);
+	set_val_strc (arr, 0, nm_running ? _("running") : _("not running"));
+	set_val_strc (arr, 1, nm_running ? nm_client_get_version (nmc->client) : _("unknown"));
+	set_val_strc (arr, 2, nm_state_to_string (state));
+	set_val_strc (arr, 3, nm_running ? (startup ? _("starting") : _("started")) : _("unknown"));
+	set_val_strc (arr, 4, nm_connectivity_to_string (connectivity));
+	set_val_strc (arr, 5, net_enabled_str);
+	set_val_strc (arr, 6, wireless_hw_enabled_str);
+	set_val_strc (arr, 7, wireless_enabled_str);
+	set_val_strc (arr, 8, wwan_hw_enabled_str);
+	set_val_strc (arr, 9, wwan_enabled_str);
 #if WITH_WIMAX
-	nmc->allowed_fields[8].value = wimax_hw_enabled_str;
-	nmc->allowed_fields[9].value = wimax_enabled_str;
+	set_val_strc (arr, 10, wimax_hw_enabled_str);
+	set_val_strc (arr, 11, wimax_enabled_str);
 #endif
+	g_ptr_array_add (nmc->output_data, arr);
 
-	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+	print_data (nmc);  /* Print all data */
 
-	return NMC_RESULT_SUCCESS;
-
-error:
-	return nmc->return_value;
+	return TRUE;
 }
 
 #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK     "org.freedesktop.NetworkManager.enable-disable-network"
@@ -274,7 +449,7 @@ permission_result_to_string (NMClientPermissionResult perm_result)
 	}
 }
 
-static NMCResultCode
+static gboolean
 show_nm_permissions (NmCli *nmc)
 {
 	NMClientPermission perm;
@@ -282,9 +457,8 @@ show_nm_permissions (NmCli *nmc)
 	const char *fields_str;
 	const char *fields_all =    NMC_FIELDS_NM_PERMISSIONS_ALL;
 	const char *fields_common = NMC_FIELDS_NM_PERMISSIONS_COMMON;
-	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
-	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
-	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
+	NmcOutputField *tmpl, *arr;
+	size_t tmpl_len;
 
 	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
 		fields_str = fields_common;
@@ -293,311 +467,451 @@ show_nm_permissions (NmCli *nmc)
 	else
 		fields_str = nmc->required_fields;
 
-	nmc->allowed_fields = nmc_fields_nm_permissions;
-	nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
+	tmpl = nmc_fields_nm_permissions;
+	tmpl_len = sizeof (nmc_fields_nm_permissions);
+	nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error);
 
 	if (error) {
-		if (error->code == 0)
-			g_string_printf (nmc->return_text, _("Error: 'nm permissions': %s"), error->message);
-		else
-			g_string_printf (nmc->return_text, _("Error: 'nm permissions': %s; allowed fields: %s"), error->message, NMC_FIELDS_NM_PERMISSIONS_ALL);
+		g_string_printf (nmc->return_text, _("Error: 'general permissions': %s"), error->message);
 		g_error_free (error);
 		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-		return nmc->return_value;
-	}
-
-	if (!nmc_is_nm_running (nmc, &error)) {
-		if (error) {
-			g_string_printf (nmc->return_text, _("Error: Can't find out if NetworkManager is running: %s."), error->message);
-			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
-			g_error_free (error);
-		} else {
-			g_string_printf (nmc->return_text, _("Error: NetworkManager is not running."));
-			nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING;
-		}
-		goto error;
+		return FALSE;
 	}
 
 	nmc->get_client (nmc); /* create NMClient */
 
-	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
+	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;
+		return FALSE;
+	}
+
 	nmc->print_fields.header_name = _("NetworkManager permissions");
-	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
+	arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES);
+	g_ptr_array_add (nmc->output_data, arr);
 
 	for (perm = NM_CLIENT_PERMISSION_NONE + 1; perm <= NM_CLIENT_PERMISSION_LAST; perm++) {
 		NMClientPermissionResult perm_result = nm_client_get_permission_result (nmc->client, perm);
 
-		set_val_str (nmc->allowed_fields, 0, permission_to_string (perm));
-		set_val_str (nmc->allowed_fields, 1, permission_result_to_string (perm_result));
-		nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-		print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+		arr = nmc_dup_fields_array (tmpl, tmpl_len, 0);
+		set_val_strc (arr, 0, permission_to_string (perm));
+		set_val_strc (arr, 1, permission_result_to_string (perm_result));
+		g_ptr_array_add (nmc->output_data, arr);
 	}
-	return NMC_RESULT_SUCCESS;
+	print_data (nmc);  /* Print all data */
 
-error:
-	return nmc->return_value;
+	return TRUE;
 }
 
-/* libnm-glib doesn't provide API fro Sleep method - implement D-Bus call ourselves */
-static void networking_set_sleep (NmCli *nmc, gboolean in_sleep)
+static gboolean
+show_general_logging (NmCli *nmc)
 {
-	DBusGConnection *connection = NULL;
-	DBusGProxy *proxy = NULL;
-	GError *err = NULL;
+	char *level = NULL;
+	char *domains = NULL;
+	GError *error = NULL;
+	const char *fields_str;
+	const char *fields_all =    NMC_FIELDS_NM_LOGGING_ALL;
+	const char *fields_common = NMC_FIELDS_NM_LOGGING_COMMON;
+	NmcOutputField *tmpl, *arr;
+	size_t tmpl_len;
 
-	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
-	if (!connection) {
-		g_string_printf (nmc->return_text, _("Error: Couldn't connect to system bus: %s"), err->message);
-		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
-		g_error_free (err);
-		goto gone;
+	if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
+		fields_str = fields_common;
+	else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
+		fields_str = fields_all;
+	else
+		fields_str = nmc->required_fields;
+
+	tmpl = nmc_fields_nm_logging;
+	tmpl_len = sizeof (nmc_fields_nm_logging);
+	nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error);
+
+	if (error) {
+		g_string_printf (nmc->return_text, _("Error: 'general logging': %s"), error->message);
+		g_error_free (error);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return FALSE;
 	}
 
-	proxy = dbus_g_proxy_new_for_name (connection,
-	                                   "org.freedesktop.NetworkManager",
-	                                   "/org/freedesktop/NetworkManager",
-	                                   "org.freedesktop.NetworkManager");
-	if (!proxy) {
-		g_string_printf (nmc->return_text, _("Error: Couldn't create D-Bus object proxy."));
-		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
-		goto gone;
+	nmc->get_client (nmc); /* create NMClient */
+	nm_client_get_logging (nmc->client, &level, &domains, &error);
+	if (error) {
+		g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		g_error_free (error);
+		return FALSE;
 	}
 
-	if (!dbus_g_proxy_call (proxy, "Sleep", &err, G_TYPE_BOOLEAN, in_sleep, G_TYPE_INVALID, G_TYPE_INVALID)) {
-		g_string_printf (nmc->return_text, _("Error in sleep: %s"), err->message);
+	nmc->print_fields.header_name = _("NetworkManager logging");
+	arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES);
+	g_ptr_array_add (nmc->output_data, arr);
+
+	arr = nmc_dup_fields_array (tmpl, tmpl_len, 0);
+	set_val_str (arr, 0, level);
+	set_val_str (arr, 1, domains);
+	g_ptr_array_add (nmc->output_data, arr);
+
+	print_data (nmc);  /* Print all data */
+
+	return TRUE;
+}
+
+static void
+save_hostname_cb (NMRemoteSettings *settings, GError *error, gpointer user_data)
+{
+	NmCli *nmc = (NmCli *) user_data;
+
+	if (error) {
+		g_string_printf (nmc->return_text, _("Error: failed to set hostname: (%d) %s"),
+		                 error->code, error->message);
 		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
-		g_error_free (err);
 	}
-
-gone:
-	if (connection) dbus_g_connection_unref (connection);
-	if (proxy) g_object_unref (proxy);
+	quit ();
 }
 
-/* entry point function for global network manager related commands 'nmcli nm' */
+/*
+ * Entry point function for general operations 'nmcli general'
+ */
 NMCResultCode
-do_network_manager (NmCli *nmc, int argc, char **argv)
+do_general (NmCli *nmc, int argc, char **argv)
 {
 	GError *error = NULL;
-	gboolean sleep_flag;
-	gboolean enable_net;
-	gboolean enable_wifi;
-	gboolean enable_wwan;
-#if WITH_WIMAX
-	gboolean enable_wimax;
-#endif
-	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
-	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
-	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
 
 	if (argc == 0) {
-		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-			goto opt_error;
-		nmc->return_value = show_nm_status (nmc);
+		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+			g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+			goto finish;
+		}
+		show_nm_status (nmc, NULL, NULL);
 	}
 
 	if (argc > 0) {
-		if (matches (*argv, "status") == 0) {
-			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-				goto opt_error;
-			nmc->return_value = show_nm_status (nmc);
+		if (nmc_arg_is_help (*argv)) {
+			usage_general ();
+		}
+		else if (matches (*argv, "status") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_general_status ();
+				goto finish;
+			}
+			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+				g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto finish;
+			}
+			show_nm_status (nmc, NULL, NULL);
+		}
+		else if (matches (*argv, "hostname") == 0) {
+			NMRemoteSettings *rem_settings;
+
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_general_hostname ();
+				goto finish;
+			}
+
+			/* get system settings */
+			if (!(rem_settings = nm_remote_settings_new (NULL))) {
+				g_string_printf (nmc->return_text, _("Error: Could not get system settings."));
+				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				goto finish;
+			}
+
+			if (next_arg (&argc, &argv) != 0) {
+				/* no arguments -> get hostname */
+				char *hostname = NULL;
+
+				g_object_get (rem_settings, NM_REMOTE_SETTINGS_HOSTNAME, &hostname, NULL);
+				if (hostname)
+					printf ("%s\n", hostname);
+				g_free (hostname);
+			} else {
+				/* hostname provided -> set it */
+				const char *hostname = *argv;
+
+				if (next_arg (&argc, &argv) == 0)
+					printf ("Warning: ignoring extra garbage after '%s' hostname\n", hostname);
+
+				nmc->should_wait = TRUE;
+				nm_remote_settings_save_hostname (rem_settings, hostname, save_hostname_cb, nmc);
+			}
 		}
 		else if (matches (*argv, "permissions") == 0) {
-			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-				goto opt_error;
-			nmc->return_value = show_nm_permissions (nmc);
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_general_permissions ();
+				goto finish;
+			}
+			if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+				g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto finish;
+			}
+			show_nm_permissions (nmc);
 		}
-		else if (matches (*argv, "enable") == 0) {
+		else if (matches (*argv, "logging") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_general_logging ();
+				goto finish;
+			}
 			if (next_arg (&argc, &argv) != 0) {
-				/* no argument, show current state of networking */
-				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-					goto opt_error;
-				if (nmc->required_fields && strcasecmp (nmc->required_fields, "NET-ENABLED")) {
-					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
-					                 nmc->required_fields, NMC_FIELDS_NM_NET_ENABLED);
+				/* no arguments -> get logging level and domains */
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+					g_string_printf (nmc->return_text, _("Error: %s."), error->message);
 					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
+					goto finish;
 				}
-				nmc->allowed_fields = nmc_fields_nm_status;
-				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_NET_ENABLED, nmc->allowed_fields, NULL);
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
-				nmc->print_fields.header_name = _("Networking enabled");
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-
-				if (nmc_is_nm_running (nmc, NULL)) {
-					nmc->get_client (nmc); /* create NMClient */
-					nmc->allowed_fields[3].value = nm_client_networking_get_enabled (nmc->client) ? _("enabled") : _("disabled");
-				} else
-					nmc->allowed_fields[3].value = _("unknown");
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				show_general_logging (nmc);
 			} else {
-				if (!strcmp (*argv, "true"))
-					enable_net = TRUE;
-				else if (!strcmp (*argv, "false"))
-					enable_net = FALSE;
-				else {
-					g_string_printf (nmc->return_text, _("Error: invalid 'enable' parameter: '%s'; use 'true' or 'false'."), *argv);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
+				/* arguments provided -> set logging level and domains */
+				const char *level = NULL;
+				const char *domains = NULL;
+				nmc_arg_t exp_args[] = { {"level",   TRUE, &level,   TRUE},
+				                         {"domains", TRUE, &domains, TRUE},
+				                         {NULL} };
+
+				if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, &error)) {
+					g_string_assign (nmc->return_text, error->message);
+					nmc->return_value = error->code;
+					goto finish;
 				}
+
 				nmc->get_client (nmc); /* create NMClient */
-				nm_client_networking_set_enabled (nmc->client, enable_net);
+				nm_client_set_logging (nmc->client, level, domains, &error);
+				if (error) {
+					if (g_error_matches (error, DBUS_GERROR, DBUS_GERROR_ACCESS_DENIED))
+						g_string_printf (nmc->return_text, _("Error: access denied to set logging; %s"), error->message);
+					else
+						g_string_printf (nmc->return_text, _("Error: %s"), error->message);
+					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+					goto finish;
+				}
 			}
 		}
-		else if (matches (*argv, "sleep") == 0) {
+		else {
+			usage_general ();
+			g_string_printf (nmc->return_text, _("Error: 'general' command '%s' is not valid."), *argv);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		}
+	}
+
+finish:
+	if (error)
+		g_error_free (error);
+	return nmc->return_value;
+}
+
+static gboolean
+nmc_switch_show (NmCli *nmc, const char *switch_name, const char *header)
+{
+	g_return_val_if_fail (nmc != NULL, FALSE);
+	g_return_val_if_fail (switch_name != NULL, FALSE);
+
+	if (nmc->required_fields && strcasecmp (nmc->required_fields, switch_name) != 0) {
+		g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here (allowed field: %s)"),
+		                 nmc->required_fields, switch_name);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return FALSE;
+	}
+	if (nmc->print_output == NMC_PRINT_NORMAL)
+		nmc->print_output = NMC_PRINT_TERSE;
+
+	if (!nmc->required_fields)
+		nmc->required_fields = g_strdup (switch_name);
+	return show_nm_status (nmc, header, NULL);
+}
+
+static gboolean
+nmc_switch_parse_on_off (NmCli *nmc, const char *arg1, const char *arg2, gboolean *res)
+{
+	g_return_val_if_fail (nmc != NULL, FALSE);
+	g_return_val_if_fail (arg1 && arg2, FALSE);
+	g_return_val_if_fail (res != NULL, FALSE);
+
+	if (!strcmp (arg2, "on"))
+		*res = TRUE;
+	else if (!strcmp (arg2, "off"))
+		*res = FALSE;
+	else {
+		g_string_printf (nmc->return_text, _("Error: invalid '%s' argument: '%s' (use on/off)."), arg1, arg2);
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+show_networking_connectivity (NmCli *nmc)
+{
+	return nmc_switch_show (nmc, NMC_FIELDS_NM_CONNECTIVITY, _("Connectivity"));
+}
+
+/*
+ * Entry point function for 'nmcli networking'
+ */
+NMCResultCode
+do_networking (NmCli *nmc, int argc, char **argv)
+{
+	gboolean enable_flag;
+
+	if (argc == 0)
+		nmc_switch_show (nmc, NMC_FIELDS_NM_NETWORKING, _("Networking"));
+	else if (argc > 0) {
+		if (nmc_arg_is_help (*argv)) {
+			usage_networking ();
+		} else if (matches (*argv, "connectivity") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_networking_connectivity ();
+				goto finish;
+			}
 			if (next_arg (&argc, &argv) != 0) {
-				g_string_printf (nmc->return_text, _("Error: Sleeping status is not exported by NetworkManager."));
-				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+				/* no arguments -> get current state */
+				show_networking_connectivity (nmc);
+			} else if (matches (*argv, "check") == 0) {
+				GError *error = NULL;
+
+				nmc->get_client (nmc); /* create NMClient */
+				nm_client_check_connectivity (nmc->client, NULL, &error);
+				if (error) {
+					g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+					nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+					g_clear_error (&error);
+				} else
+					show_networking_connectivity (nmc);
 			} else {
-				if (!strcmp (*argv, "true"))
-					sleep_flag = TRUE;
-				else if (!strcmp (*argv, "false"))
-					sleep_flag = FALSE;
-				else {
-					g_string_printf (nmc->return_text, _("Error: invalid 'sleep' parameter: '%s'; use 'true' or 'false'."), *argv);
+				usage_networking ();
+				g_string_printf (nmc->return_text, _("Error: 'networking connectivity' command '%s' is not valid."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+			}
+		} else if (nmc_switch_parse_on_off (nmc, *(argv-1), *argv, &enable_flag)) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				if (enable_flag)
+					usage_networking_on ();
+				else
+					usage_networking_off ();
+				goto finish;
+			}
+
+			nmc->get_client (nmc); /* create NMClient */
+			nm_client_networking_set_enabled (nmc->client, enable_flag);
+		} else {
+			usage_networking ();
+			g_string_printf (nmc->return_text, _("Error: 'networking' command '%s' is not valid."), *argv);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		}
+	}
+
+finish:
+	quit ();
+	return nmc->return_value;
+}
+
+/*
+ * Entry point function for radio switch commands 'nmcli radio'
+ */
+NMCResultCode
+do_radio (NmCli *nmc, int argc, char **argv)
+{
+	GError *error = NULL;
+	gboolean enable_flag;
+
+	if (argc == 0) {
+		if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+			g_string_printf (nmc->return_text, _("Error: %s."), error->message);
+			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+			g_error_free (error);
+			goto finish;
+		}
+		show_nm_status (nmc, _("Radio switches"), NMC_FIELDS_NM_STATUS_RADIO);
+	}
+
+	if (argc > 0) {
+		if (nmc_arg_is_help (*argv)) {
+			usage_radio ();
+		}
+		else if (matches (*argv, "all") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_radio_all ();
+				goto finish;
+			}
+			if (next_arg (&argc, &argv) != 0) {
+				/* no argument, show all radio switches */
+				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) {
+					g_string_printf (nmc->return_text, _("Error: %s."), error->message);
 					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
+					g_error_free (error);
+					goto finish;
 				}
-				networking_set_sleep (nmc, sleep_flag);
+				show_nm_status (nmc, _("Radio switches"), NMC_FIELDS_NM_STATUS_RADIO);
+			} else {
+				if (!nmc_switch_parse_on_off (nmc, *(argv-1), *argv, &enable_flag))
+					goto finish;
+
+				nmc->get_client (nmc); /* create NMClient */
+				nm_client_wireless_set_enabled (nmc->client, enable_flag);
+				nm_client_wimax_set_enabled (nmc->client, enable_flag);
+				nm_client_wwan_set_enabled (nmc->client, enable_flag);
 			}
 		}
 		else if (matches (*argv, "wifi") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_radio_wifi ();
+				goto finish;
+			}
 			if (next_arg (&argc, &argv) != 0) {
 				/* no argument, show current WiFi state */
-				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-					goto opt_error;
-				if (nmc->required_fields && strcasecmp (nmc->required_fields, "WIFI")) {
-					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
-					                 nmc->required_fields, NMC_FIELDS_NM_WIFI);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
-				nmc->allowed_fields = nmc_fields_nm_status;
-				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WIFI, nmc->allowed_fields, NULL);
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
-				nmc->print_fields.header_name = _("WiFi enabled");
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-
-				if (nmc_is_nm_running (nmc, NULL)) {
-					nmc->get_client (nmc); /* create NMClient */
-					nmc->allowed_fields[5].value = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
-				} else
-					nmc->allowed_fields[5].value = _("unknown");
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				nmc_switch_show (nmc, NMC_FIELDS_NM_WIFI, _("Wi-Fi radio switch"));
 			} else {
-				if (!strcmp (*argv, "on"))
-					enable_wifi = TRUE;
-				else if (!strcmp (*argv, "off"))
-					enable_wifi = FALSE;
-				else {
-					g_string_printf (nmc->return_text, _("Error: invalid 'wifi' parameter: '%s'."), *argv);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
+				if (!nmc_switch_parse_on_off (nmc, *(argv-1), *argv, &enable_flag))
+					goto finish;
+				
 				nmc->get_client (nmc); /* create NMClient */
-				nm_client_wireless_set_enabled (nmc->client, enable_wifi);
+				nm_client_wireless_set_enabled (nmc->client, enable_flag);
 			}
 		}
 		else if (matches (*argv, "wwan") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_radio_wwan ();
+				goto finish;
+			}
 			if (next_arg (&argc, &argv) != 0) {
-				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-					goto opt_error;
-				/* no argument, show current WWAN state */
-				if (nmc->required_fields && strcasecmp (nmc->required_fields, "WWAN")) {
-					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
-					                 nmc->required_fields, NMC_FIELDS_NM_WWAN);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
-				nmc->allowed_fields = nmc_fields_nm_status;
-				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WWAN, nmc->allowed_fields, NULL);
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
-				nmc->print_fields.header_name = _("WWAN enabled");
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-
-				if (nmc_is_nm_running (nmc, NULL)) {
-					nmc->get_client (nmc); /* create NMClient */
-					nmc->allowed_fields[7].value = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled");
-				} else
-					nmc->allowed_fields[7].value = _("unknown");
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				/* no argument, show current WWAN (mobile broadband) state */
+				nmc_switch_show (nmc, NMC_FIELDS_NM_WWAN, _("WWAN radio switch"));
 			} else {
-				if (!strcmp (*argv, "on"))
-					enable_wwan = TRUE;
-				else if (!strcmp (*argv, "off"))
-					enable_wwan = FALSE;
-				else {
-					g_string_printf (nmc->return_text, _("Error: invalid 'wwan' parameter: '%s'."), *argv);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
+				if (!nmc_switch_parse_on_off (nmc, *(argv-1), *argv, &enable_flag))
+					goto finish;
+
 				nmc->get_client (nmc); /* create NMClient */
-				nm_client_wwan_set_enabled (nmc->client, enable_wwan);
+				nm_client_wwan_set_enabled (nmc->client, enable_flag);
 			}
 		}
 #if WITH_WIMAX
 		else if (matches (*argv, "wimax") == 0) {
+			if (nmc_arg_is_help (*(argv+1))) {
+				usage_radio_wimax ();
+				goto finish;
+			}
 			if (next_arg (&argc, &argv) != 0) {
-				if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
-					goto opt_error;
 				/* no argument, show current WiMAX state */
-				if (nmc->required_fields && strcasecmp (nmc->required_fields, "WIMAX")) {
-					g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"),
-					                 nmc->required_fields, NMC_FIELDS_NM_WIMAX);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
-				nmc->allowed_fields = nmc_fields_nm_status;
-				nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WIMAX, nmc->allowed_fields, NULL);
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
-				nmc->print_fields.header_name = _("WiMAX enabled");
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-
-				if (nmc_is_nm_running (nmc, NULL)) {
-					nmc->get_client (nmc); /* create NMClient */
-					nmc->allowed_fields[9].value = nm_client_wimax_get_enabled (nmc->client) ? _("enabled") : _("disabled");
-				} else
-					nmc->allowed_fields[9].value = _("unknown");
-				nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag;
-				print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
+				nmc_switch_show (nmc, NMC_FIELDS_NM_WIMAX, _("WiMAX radio switch"));
 			} else {
-				if (!strcmp (*argv, "on"))
-					enable_wimax = TRUE;
-				else if (!strcmp (*argv, "off"))
-					enable_wimax = FALSE;
-				else {
-					g_string_printf (nmc->return_text, _("Error: invalid 'wimax' parameter: '%s'."), *argv);
-					nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-					goto end;
-				}
+				if (!nmc_switch_parse_on_off (nmc, *(argv-1), *argv, &enable_flag))
+					goto finish;
+
 				nmc->get_client (nmc); /* create NMClient */
-				nm_client_wimax_set_enabled (nmc->client, enable_wimax);
+				nm_client_wimax_set_enabled (nmc->client, enable_flag);
 			}
 		}
 #endif
-		else if (   matches (*argv, "help") == 0
-		         || (g_str_has_prefix (*argv, "-")  && matches ((*argv)+1, "help") == 0)
-		         || (g_str_has_prefix (*argv, "--") && matches ((*argv)+2, "help") == 0)) {
-			usage ();
-		}
 		else {
-			usage ();
-			g_string_printf (nmc->return_text, _("Error: 'nm' command '%s' is not valid."), *argv);
+			usage_radio ();
+			g_string_printf (nmc->return_text, _("Error: 'radio' command '%s' is not valid."), *argv);
 			nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
 		}
 	}
 
-end:
+finish:
 	quit ();
 	return nmc->return_value;
-
-opt_error:
-	quit ();
-	g_string_printf (nmc->return_text, _("Error: %s."), error->message);
-	nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
-	g_error_free (error);
-	return nmc->return_value;
 }
+