summary refs log tree commit diff
path: root/clients/nm-online.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/nm-online.c')
-rw-r--r--clients/nm-online.c172
1 files changed, 82 insertions, 90 deletions
diff --git a/clients/nm-online.c b/clients/nm-online.c
index e8f0be1a..60ea41cb 100644
--- a/clients/nm-online.c
+++ b/clients/nm-online.c
@@ -45,50 +45,70 @@
 
 typedef struct
 {
+	GMainLoop *loop;
+	NMClient *client;
+	gboolean exit_no_nm;
+	gboolean wait_startup;
 	gint64 start_timestamp_ms;
 	gint64 end_timestamp_ms;
 	gint64 progress_step_duration;
 	gboolean quiet;
-} Timeout;
+	guint retval;
+} OnlineData;
 
 static void
-client_properties_changed (GObject *object,
-                           GParamSpec *pspec,
-                           gpointer loop)
+quit_if_connected (OnlineData *data)
 {
-	NMClient *client = NM_CLIENT (object);
 	NMState state;
-	gboolean wait_startup = GPOINTER_TO_UINT (g_object_get_data (object, WAIT_STARTUP_TAG));
 
-	if (!nm_client_get_nm_running (client))
-		return;
-
-	if (wait_startup) {
-		if (!nm_client_get_startup (client))
-			g_main_loop_quit (loop);
+	state = nm_client_get_state (data->client);
+	if (!nm_client_get_nm_running (data->client)) {
+		if (data->exit_no_nm) {
+			data->retval = 1;
+			g_main_loop_quit (data->loop);
+		}
+	} else if (data->wait_startup) {
+		if (!nm_client_get_startup (data->client)) {
+			data->retval = 0;
+			g_main_loop_quit (data->loop);
+		}
 	} else {
-		state = nm_client_get_state (client);
 		if (   state == NM_STATE_CONNECTED_LOCAL
 		    || state == NM_STATE_CONNECTED_SITE
-		    || state == NM_STATE_CONNECTED_GLOBAL)
-			g_main_loop_quit (loop);
+		    || state == NM_STATE_CONNECTED_GLOBAL) {
+			data->retval = 0;
+			g_main_loop_quit (data->loop);
+		}
+	}
+	if (data->exit_no_nm && (state != NM_STATE_CONNECTING)) {
+		data->retval = 1;
+		g_main_loop_quit (data->loop);
 	}
 }
 
+static void
+client_properties_changed (GObject *object,
+                           GParamSpec *pspec,
+                           gpointer user_data)
+{
+	OnlineData *data = user_data;
+	quit_if_connected (data);
+}
+
 static gboolean
-handle_timeout (gpointer data)
+handle_timeout (gpointer user_data)
 {
-	const Timeout *timeout = data;
+	const OnlineData *data = user_data;
 	const gint64 now = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
-	gint64 remaining_ms = timeout->end_timestamp_ms - now;
-	const gint64 elapsed_ms = now - timeout->start_timestamp_ms;
+	gint64 remaining_ms = data->end_timestamp_ms - now;
+	const gint64 elapsed_ms = now - data->start_timestamp_ms;
 	int progress_next_step_i = 0;
 
-	if (!timeout->quiet) {
+	if (!data->quiet) {
 		int i;
 
 		/* calculate the next step (not the current): floor()+1 */
-		progress_next_step_i = (elapsed_ms / timeout->progress_step_duration) + 1;
+		progress_next_step_i = (elapsed_ms / data->progress_step_duration) + 1;
 		progress_next_step_i = MIN (progress_next_step_i, PROGRESS_STEPS);
 
 		g_print ("\r%s", _("Connecting"));
@@ -99,12 +119,12 @@ handle_timeout (gpointer data)
 	}
 
 	if (remaining_ms <= 3) {
-		if (!timeout->quiet)
+		if (!data->quiet)
 			g_print ("\n");
 		exit (1);
 	}
 
-	if (!timeout->quiet) {
+	if (!data->quiet) {
 		gint64 rem;
 
 		/* synchronize the timeout with the ticking of the seconds. */
@@ -116,43 +136,56 @@ handle_timeout (gpointer data)
 			remaining_ms = rem;
 
 		/* synchronize the timeout with the steps of the progress bar. */
-		rem = (progress_next_step_i * timeout->progress_step_duration) - elapsed_ms;
+		rem = (progress_next_step_i * data->progress_step_duration) - elapsed_ms;
 		if (rem <= 3)
-			rem = rem + timeout->progress_step_duration;
+			rem = rem + data->progress_step_duration;
 		rem = rem + 10; /* add small offset to awake a bit after the time out */
 		if (remaining_ms > rem)
 			remaining_ms = rem;
 	}
 
-	g_timeout_add (remaining_ms, handle_timeout, (void *) timeout);
+	g_timeout_add (remaining_ms, handle_timeout, user_data);
 	return G_SOURCE_REMOVE;
 }
 
+static void
+got_client (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+	OnlineData *data = user_data;
+	GError *error = NULL;
+
+	data->client = nm_client_new_finish (res, &error);
+	if (!data->client) {
+		g_printerr (_("Error: Could not create NMClient object: %s."),
+		            error->message);
+		g_error_free (error);
+		data->retval = 1;
+		g_main_loop_quit (data->loop);
+	}
+
+	g_signal_connect (data->client, "notify",
+	                  G_CALLBACK (client_properties_changed), user_data);
+	quit_if_connected (data);
+}
+
 int
 main (int argc, char *argv[])
 {
+	OnlineData data = { 0, };
 	int t_secs = 30;
-	gboolean exit_no_nm = FALSE;
-	gboolean wait_startup = FALSE;
-	Timeout timeout;
 	GOptionContext *opt_ctx = NULL;
 	gboolean success;
-	NMClient *client;
-	NMState state = NM_STATE_UNKNOWN;
-	GMainLoop *loop;
 	gint64 remaining_ms;
-	GError *error = NULL;
 
 	GOptionEntry options[] = {
 		{"timeout", 't', 0, G_OPTION_ARG_INT, &t_secs, N_("Time to wait for a connection, in seconds (without the option, default value is 30)"), "<timeout>"},
-		{"exit", 'x', 0, G_OPTION_ARG_NONE, &exit_no_nm, N_("Exit immediately if NetworkManager is not running or connecting"), NULL},
-		{"quiet", 'q', 0, G_OPTION_ARG_NONE, &timeout.quiet, N_("Don't print anything"), NULL},
-		{"wait-for-startup", 's', 0, G_OPTION_ARG_NONE, &wait_startup, N_("Wait for NetworkManager startup instead of a connection"), NULL},
+		{"exit", 'x', 0, G_OPTION_ARG_NONE, &data.exit_no_nm, N_("Exit immediately if NetworkManager is not running or connecting"), NULL},
+		{"quiet", 'q', 0, G_OPTION_ARG_NONE, &data.quiet, N_("Don't print anything"), NULL},
+		{"wait-for-startup", 's', 0, G_OPTION_ARG_NONE, &data.wait_startup, N_("Wait for NetworkManager startup instead of a connection"), NULL},
 		{NULL}
 	};
 
-	timeout.start_timestamp_ms = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
-	timeout.quiet = FALSE;
+	data.start_timestamp_ms = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
 
 	/* Set locale to be able to use environment variables */
 	setlocale (LC_ALL, "");
@@ -184,62 +217,21 @@ main (int argc, char *argv[])
 		            _("Invalid option.  Please use --help to see a list of valid options."));
 		return 2;
 	}
-	remaining_ms = t_secs * 1000;
-
 	nm_g_type_init ();
 
-	client = nm_client_new (NULL, &error);
-	if (!client) {
-		g_printerr (_("Error: Could not create NMClient object: %s."), error->message);
-		g_error_free (error);
-		return 2;
-	}
-
-	loop = g_main_loop_new (NULL, FALSE);
-
-	g_object_set_data (G_OBJECT (client), WAIT_STARTUP_TAG, GUINT_TO_POINTER (wait_startup));
-	state = nm_client_get_state (client);
-	if (!nm_client_get_nm_running (client)) {
-		if (exit_no_nm) {
-			g_object_unref (client);
-			return 1;
-		}
-	} else if (wait_startup) {
-		if (!nm_client_get_startup (client)) {
-			g_object_unref (client);
-			return 0;
-		}
-	} else {
-		if (   state == NM_STATE_CONNECTED_LOCAL
-		    || state == NM_STATE_CONNECTED_SITE
-		    || state == NM_STATE_CONNECTED_GLOBAL) {
-			g_object_unref (client);
-			return 0;
-		}
-	}
-	if (exit_no_nm && (state != NM_STATE_CONNECTING)) {
-		g_object_unref (client);
-		return 1;
-	}
-
-	if (remaining_ms == 0) {
-		g_object_unref (client);
-		return 1;
-	}
-
-	g_signal_connect (client, "notify",
-	                  G_CALLBACK (client_properties_changed), loop);
-
-	timeout.end_timestamp_ms = timeout.start_timestamp_ms + remaining_ms;
-	timeout.progress_step_duration = (timeout.end_timestamp_ms - timeout.start_timestamp_ms + PROGRESS_STEPS/2) / PROGRESS_STEPS;
+	data.loop = g_main_loop_new (NULL, FALSE);
 
-	g_timeout_add (timeout.quiet ? remaining_ms : 0,
-	               handle_timeout, &timeout);
+	remaining_ms = t_secs * 1000;
+	data.end_timestamp_ms = data.start_timestamp_ms + remaining_ms;
+	data.progress_step_duration = (data.end_timestamp_ms - data.start_timestamp_ms + PROGRESS_STEPS/2) / PROGRESS_STEPS;
 
-	g_main_loop_run (loop);
-	g_main_loop_unref (loop);
+	g_timeout_add (data.quiet ? remaining_ms : 0, handle_timeout, &data);
+	nm_client_new_async (NULL, got_client, &data);
 
-	g_object_unref (client);
+	g_main_loop_run (data.loop);
+	g_main_loop_unref (data.loop);
+	if (data.client)
+		g_object_unref (data.client);
 
-	return 0;
+	return data.retval;
 }