summary refs log tree commit diff
path: root/clients/cli/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/cli/common.c')
-rw-r--r--clients/cli/common.c150
1 files changed, 87 insertions, 63 deletions
diff --git a/clients/cli/common.c b/clients/cli/common.c
index 2fc8aaf6..04ccf8dc 100644
--- a/clients/cli/common.c
+++ b/clients/cli/common.c
@@ -1,22 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- *  nmcli - command-line tool for controlling NetworkManager
- *  Common functions and data shared between files.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2012 - 2018 Red Hat, Inc.
+ * Copyright (C) 2012 - 2018 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -1201,14 +1185,13 @@ nmc_parse_lldp_capabilities (guint value)
 static void
 command_done (GObject *object, GAsyncResult *res, gpointer user_data)
 {
-	GSimpleAsyncResult *simple = (GSimpleAsyncResult *)res;
+	GTask *task = G_TASK (res);
 	NmCli *nmc = user_data;
-	GError *error = NULL;
+	gs_free_error GError *error = NULL;
 
-	if (g_simple_async_result_propagate_error (simple, &error)) {
+	if (!g_task_propagate_boolean (task, &error)) {
 		nmc->return_value = error->code;
 		g_string_assign (nmc->return_text, error->message);
-		g_error_free (error);
 	}
 
 	if (!nmc->should_wait)
@@ -1216,40 +1199,42 @@ command_done (GObject *object, GAsyncResult *res, gpointer user_data)
 }
 
 typedef struct {
-	NmCli *nmc;
 	const NMCCommand *cmd;
 	int argc;
 	char **argv;
-	GSimpleAsyncResult *simple;
+	GTask *task;
 } CmdCall;
 
 static void
-call_cmd (NmCli *nmc, GSimpleAsyncResult *simple, const NMCCommand *cmd, int argc, char **argv);
+call_cmd (NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, char **argv);
 
 static void
 got_client (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
-	GError *error = NULL;
+	gs_unref_object GTask *task = NULL;
+	gs_free_error GError *error = NULL;
 	CmdCall *call = user_data;
-	NmCli *nmc = call->nmc;
+	NmCli *nmc;
+
+	task = g_steal_pointer (&call->task);
+	nmc = g_task_get_task_data (task);
 
 	nmc->should_wait--;
 	nmc->client = nm_client_new_finish (res, &error);
 
 	if (!nmc->client) {
-		g_simple_async_result_set_error (call->simple, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN,
-		                                 _("Error: Could not create NMClient object: %s."), error->message);
-		g_error_free (error);
-		g_simple_async_result_complete (call->simple);
+		g_task_return_new_error (task, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN,
+		                         _("Error: Could not create NMClient object: %s."),
+		                         error->message);
 	} else {
-		call_cmd (nmc, call->simple, call->cmd, call->argc, call->argv);
+		call_cmd (nmc, g_steal_pointer (&task), call->cmd, call->argc, call->argv);
 	}
 
 	g_slice_free (CmdCall, call);
 }
 
 static void
-call_cmd (NmCli *nmc, GSimpleAsyncResult *simple, const NMCCommand *cmd, int argc, char **argv)
+call_cmd (NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, char **argv)
 {
 	CmdCall *call;
 
@@ -1257,20 +1242,23 @@ call_cmd (NmCli *nmc, GSimpleAsyncResult *simple, const NMCCommand *cmd, int arg
 
 		/* Check whether NetworkManager is running */
 		if (cmd->needs_nm_running && !nm_client_get_nm_running (nmc->client)) {
-			g_simple_async_result_set_error (simple, NMCLI_ERROR, NMC_RESULT_ERROR_NM_NOT_RUNNING,
-			                                 _("Error: NetworkManager is not running."));
-		} else
+			g_task_return_new_error (task, NMCLI_ERROR, NMC_RESULT_ERROR_NM_NOT_RUNNING,
+			                         _("Error: NetworkManager is not running."));
+		} else {
 			nmc->return_value = cmd->func (nmc, argc, argv);
-		g_simple_async_result_complete_in_idle (simple);
-		g_object_unref (simple);
+			g_task_return_boolean (task, TRUE);
+		}
+
+		g_object_unref (task);
 	} else {
+		nm_assert (nmc->client == NULL);
+
 		nmc->should_wait++;
 		call = g_slice_new0 (CmdCall);
-		call->nmc = nmc;
 		call->cmd = cmd;
 		call->argc = argc;
 		call->argv = argv;
-		call->simple = simple;
+		call->task = task;
 		nm_client_new_async (NULL, got_client, call);
 	}
 }
@@ -1306,16 +1294,13 @@ void
 nmc_do_cmd (NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, char **argv)
 {
 	const NMCCommand *c;
-	GSimpleAsyncResult *simple;
+	gs_unref_object GTask *task = NULL;
 
-	simple = g_simple_async_result_new (NULL,
-	                                    command_done,
-	                                    nmc,
-	                                    nmc_do_cmd);
+	task = nm_g_task_new (NULL, NULL, nmc_do_cmd, command_done, nmc);
+	g_task_set_task_data (task, nmc, NULL);
 
 	if (argc == 0 && nmc->complete) {
-		g_simple_async_result_complete_in_idle (simple);
-		g_object_unref (simple);
+		g_task_return_boolean (task, TRUE);
 		return;
 	}
 
@@ -1325,8 +1310,7 @@ nmc_do_cmd (NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, char
 				g_print ("%s\n", c->cmd);
 		}
 		nmc_complete_help (cmd);
-		g_simple_async_result_complete_in_idle (simple);
-		g_object_unref (simple);
+		g_task_return_boolean (task, TRUE);
 		return;
 	}
 
@@ -1341,32 +1325,26 @@ nmc_do_cmd (NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, char
 			nmc_complete_help (*(argv+1));
 		if (!nmc->complete && c->usage && nmc_arg_is_help (*(argv+1))) {
 			c->usage ();
-			g_simple_async_result_complete_in_idle (simple);
-			g_object_unref (simple);
+			g_task_return_boolean (task, TRUE);
 		} else {
-			call_cmd (nmc, simple, c, argc, argv);
+			call_cmd (nmc, g_steal_pointer (&task), c, argc, argv);
 		}
 	} else if (cmd) {
 		/* Not a known command. */
 		if (nmc_arg_is_help (cmd) && c->usage) {
 			c->usage ();
-			g_simple_async_result_complete_in_idle (simple);
-			g_object_unref (simple);
+			g_task_return_boolean (task, TRUE);
 		} else {
-			g_simple_async_result_set_error (simple, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-			                                 _("Error: argument '%s' not understood. Try passing --help instead."), cmd);
-			g_simple_async_result_complete_in_idle (simple);
-			g_object_unref (simple);
+			g_task_return_new_error (task, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+			                         _("Error: argument '%s' not understood. Try passing --help instead."), cmd);
 		}
 	} else if (c->func) {
 		/* No command, run the default handler. */
-		call_cmd (nmc, simple, c, argc, argv);
+		call_cmd (nmc, g_steal_pointer (&task), c, argc, argv);
 	} else {
 		/* No command and no default handler. */
-		g_simple_async_result_set_error (simple, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-		                                 _("Error: missing argument. Try passing --help."));
-		g_simple_async_result_complete_in_idle (simple);
-		g_object_unref (simple);
+		g_task_return_new_error (task, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+		                         _("Error: missing argument. Try passing --help."));
 	}
 }
 
@@ -1434,10 +1412,56 @@ nmc_error_get_simple_message (GError *error)
 	/* Return a clear message instead of the obscure D-Bus policy error */
 	if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED))
 		return _("access denied");
+	if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
+		return _("NetworkManager is not running");
 	else
 		return error->message;
 }
 
+GVariant *
+nmc_dbus_call_sync (NmCli *nmc,
+                    const char *object_path,
+                    const char *interface_name,
+                    const char *method_name,
+                    GVariant *parameters,
+                    const GVariantType *reply_type,
+                    GError **error)
+{
+	gs_unref_object GDBusConnection *connection = NULL;
+	gs_free_error GError *local = NULL;
+	GVariant *result;
+
+	if (nmc->timeout == -1)
+		nmc->timeout = 90;
+
+	connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local);
+	if (!connection) {
+		g_set_error (error,
+		             NMCLI_ERROR,
+		             NMC_RESULT_ERROR_UNKNOWN,
+		             _("Error: error connecting to system bus: %s"),
+		             local->message);
+		return NULL;
+	}
+
+	result = g_dbus_connection_call_sync (connection,
+	                                      "org.freedesktop.NetworkManager",
+	                                      object_path,
+	                                      interface_name,
+	                                      method_name,
+	                                      parameters,
+	                                      reply_type,
+	                                      G_DBUS_CALL_FLAGS_NONE,
+	                                      nmc->timeout * 1000,
+	                                      NULL,
+	                                      error);
+
+	if (error && *error)
+		g_dbus_error_strip_remote_error (*error);
+
+	return result;
+}
+
 /*****************************************************************************/
 
 NM_UTILS_LOOKUP_STR_DEFINE (nm_connectivity_to_string, NMConnectivityState,