int
main (int   argc,
      char *argv[])
{
  GDBusConnection *c;
  GError *error;
  gboolean ret;

  error = NULL;
  c = g_bus_get_sync (G_BUS_TYPE_SESSION,
                      NULL, /* GCancellable* */
                      &error);
  g_assert_no_error (error);

  error = NULL;
  g_dbus_connection_emit_signal (c,
                                 NULL, /* const gchar *destination_bus_name */
                                 "/org/gtk/GDBus/FlushObject",
                                 "org.gtk.GDBus.FlushInterface",
                                 "SomeSignal",
                                 NULL, /* GVariant *parameters */
                                 &error);
  g_assert_no_error (error);

  error = NULL;
  ret = g_dbus_connection_flush_sync (c,
                                      NULL, /* GCancellable* */
                                      &error);
  g_assert_no_error (error);
  g_assert (ret);

  /* and now exit immediately! */
  return 0;
}
static GDBusMessage *
screensaver_send_message_void (GDBusConnection *connection,
                               const char      *name,
                               gboolean         expect_reply)
{
        GDBusMessage *message, *reply;
        GError       *error;

        g_return_val_if_fail (connection != NULL, NULL);
        g_return_val_if_fail (name != NULL, NULL);

        message = g_dbus_message_new_method_call (GS_SERVICE,
                                                  GS_PATH,
                                                  GS_INTERFACE,
                                                  name);
        if (message == NULL) {
                g_warning ("Couldn't allocate the dbus message");
                return NULL;
        }

        error = NULL;

        if (! expect_reply) {
                reply = NULL;

                g_dbus_connection_send_message (connection,
                                                message,
                                                G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                NULL,
                                                &error);

        } else {
                reply = g_dbus_connection_send_message_with_reply_sync (connection,
                                                                        message,
                                                                        G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                        -1,
                                                                        NULL,
                                                                        NULL,
                                                                        &error);
        }

        if (error != NULL) {
                g_warning ("unable to send message: %s", error->message);
                g_clear_error (&error);
        }

        g_dbus_connection_flush_sync (connection, NULL, &error);
        if (error != NULL) {
                g_warning ("unable to flush message queue: %s", error->message);
                g_clear_error (&error);
        }

        g_object_unref (message);

        return reply;
}
static
void
deactivate_dbus_based_screensaver(const char *d_service, const char *d_path,
                                  const char *d_interface)
{
    if (!connection)
        screensaver_connect();

    if (!connection)
        return;

    if (is_dbus_based_screensaver_active(d_service, d_path, d_interface)) {
        // screen saver is active already, deactivating timer makes no sense
        return;
    }

    GDBusMessage *msg = g_dbus_message_new_method_call(d_service, d_path, d_interface,
                                                       "SimulateUserActivity");
    if (!msg)
        return;

    GError *error = NULL;
    g_dbus_connection_send_message(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error);

    if (error != NULL) {
        trace_error("%s, can't send message, %s\n", __func__, error->message);
        g_clear_error(&error);
        goto err;
    }

    // workaround Plasma 5 issue by calling GetSessionIdleTime after SimulateUserActivity
    if (config.quirks.plasma5_screensaver) {
        msg = g_dbus_message_new_method_call(d_service, d_path, d_interface, "GetSessionIdleTime");

        error = NULL;
        g_dbus_connection_send_message(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL,
                                       &error);

        if (error != NULL) {
            trace_error("%s, can't send message, %s\n", __func__, error->message);
            g_clear_error(&error);
            goto err;
        }
    }

    g_dbus_connection_flush_sync(connection, NULL, &error);
    if (error != NULL) {
        trace_error("%s, can't flush dbus connection, %s\n", __func__, error->message);
        g_clear_error(&error);
        goto err;
    }

err:
    g_object_unref(msg);
}
static
int
is_dbus_based_screensaver_active(const char *d_service, const char *d_path,
                                 const char *d_interface)
{
    GDBusMessage *msg = NULL;
    GDBusMessage *reply = NULL;
    uint32_t ret = 0;

    assert(connection);

    // detect is screen saver already active
    msg = g_dbus_message_new_method_call(d_service, d_path, d_interface, "GetActive");
    if (!msg) {
        trace_error("%s, can't allocate GDBusMessage\n", __func__);
        goto err;
    }

    GError *error = NULL;
    reply = g_dbus_connection_send_message_with_reply_sync(connection, msg,
                                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1,
                                                           NULL, NULL, &error);
    if (error) {
        trace_error("%s, can't send message, %s\n", __func__, error->message);
        g_clear_error(&error);
        goto err;
    }

    g_dbus_connection_flush_sync(connection, NULL, &error);
    if (error != NULL) {
        trace_error("%s, can't flush dbus connection, %s\n", __func__, error->message);
        g_clear_error(&error);
        goto err;
    }

    GVariant *v = g_dbus_message_get_body(reply);
    v = g_variant_get_child_value(v, 0);
    if (g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN))
        ret = g_variant_get_boolean(v);
    else
        ret = 0;

err:
    if (reply)
        g_object_unref(reply);

    if (msg)
        g_object_unref(msg);

    return ret;
}
Example #5
0
static void
handle_method_call (GDBusConnection       *connection,
		    const gchar           *sender,
		    const gchar           *object_path,
		    const gchar           *interface_name,
		    const gchar           *method_name,
		    GVariant              *parameters,
		    GDBusMethodInvocation *invocation,
		    gpointer               user_data)
{
  /* Push off the idle timeout */
  establish_timeout ();

  if (g_strcmp0 (method_name, "Exit") == 0)
    {
      destroy_windows ();

      g_dbus_method_invocation_return_value (invocation, NULL);
      g_dbus_connection_flush_sync (connection, NULL, NULL);

      gtk_main_quit ();
    }
  else if (g_strcmp0 (method_name, "CreateWindow") == 0)
    {
      int width, height;
      gboolean alpha, maximized;

      g_variant_get (parameters, "(iibb)", &width, &height, &alpha, &maximized);

      create_window (width, height, alpha, maximized);
      g_dbus_method_invocation_return_value (invocation, NULL);
    }
  else if (g_strcmp0 (method_name, "WaitWindows") == 0)
    {
      wait_windows_invocations = g_list_prepend (wait_windows_invocations, invocation);
      check_finish_wait_windows ();
    }
  else if (g_strcmp0 (method_name, "DestroyWindows") == 0)
    {
      destroy_windows ();
      g_dbus_method_invocation_return_value (invocation, NULL);
    }
}
int
main (int argc, char *argv[])
{
	GDBusConnection *connection;
	GError *error = NULL;

	nm_g_type_init ();

	connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private-dhcp",
	                                                     G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
	                                                     NULL, NULL, &error);
	if (!connection) {
		g_dbus_error_strip_remote_error (error);
		g_printerr ("Error: could not connect to NetworkManager D-Bus socket: %s\n",
		            error->message);
		g_error_free (error);
		fatal_error ();
	}

	if (!g_dbus_connection_emit_signal (connection,
	                                    NULL,
	                                    "/",
	                                    NM_DHCP_CLIENT_DBUS_IFACE,
	                                    "Event",
	                                    build_signal_parameters (),
	                                    &error)) {
		g_dbus_error_strip_remote_error (error);
		g_printerr ("Error: Could not send DHCP Event signal: %s\n", error->message);
		g_error_free (error);
		fatal_error ();
	}

	if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
		g_dbus_error_strip_remote_error (error);
		g_printerr ("Error: Could not flush D-Bus connection: %s\n", error->message);
		g_error_free (error);
		fatal_error ();
	}

	g_object_unref (connection);
	return 0;
}
Example #7
0
void
g_vfs_job_progress_callback (goffset current_num_bytes,
                             goffset total_num_bytes,
                             gpointer user_data)
{
  GVfsJobProgress *job = G_VFS_JOB_PROGRESS (user_data);
  GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);

  g_debug ("g_vfs_job_progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes);

  if (job->callback_obj_path == NULL || job->progress_proxy == NULL)
    return;

  gvfs_dbus_progress_call_progress (job->progress_proxy,
                                    current_num_bytes,
                                    total_num_bytes,
                                    NULL,
                                    NULL,
                                    NULL);
  g_dbus_connection_flush_sync (g_dbus_method_invocation_get_connection (dbus_job->invocation), NULL, NULL);
}
static
uint32_t
detect_dbus_based_screensavers(void)
{
    GDBusMessage *msg, *reply;
    uint32_t ret;

    assert(connection);

    // enumerate all services
    msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
                                         "org.freedesktop.DBus", "ListNames");
    if (!msg) {
        trace_error("%s, can't allocate GDBusMessage\n", __func__);
        ret = 0;
        goto err_1;
    }

    GError *error = NULL;
    reply = g_dbus_connection_send_message_with_reply_sync(connection, msg,
                                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1,
                                                           NULL, NULL, &error);
    if (error != NULL) {
        trace_error("%s, can't send message, %s\n", __func__, error->message);
        g_clear_error(&error);
        ret = 0;
        goto err_2;
    }

    g_dbus_connection_flush_sync(connection, NULL, &error);
    if (error != NULL) {
        trace_error("%s, can't flush dbus connection, %s\n", __func__, error->message);
        g_clear_error(&error);
        ret = 0;
        goto err_3;
    }

    // iterate over the list
    GVariant *v = g_dbus_message_get_body(reply);
    GVariantIter *iter;
    gchar *str;

    uint32_t flags = 0;
    g_variant_get(v, "(as)", &iter);
    while (g_variant_iter_loop(iter, "s", &str)) {
        if (strcmp(str, GS_SERVICE) == 0)
            flags |= SST_GNOME_SCREENSAVER;

        if (strcmp(str, KS_SERVICE) == 0)
            flags |= SST_KDE_SCREENSAVER;

        if (strcmp(str, FDOS_SERVICE) == 0)
            flags |= SST_FDO_SCREENSAVER;

        if (strcmp(str, CINNAMON_SERVICE) == 0)
            flags |= SST_CINNAMON_SCREENSAVER;
    }
    g_variant_iter_free(iter);
    ret = flags;

err_3:
    g_object_unref(reply);
err_2:
    g_object_unref(msg);
err_1:
    return ret;
}
Example #9
0
int
main (int argc, char **argv)
{
	GOptionContext *context;
	GError *error = NULL;
	GDBusConnection *bus;
	GDBusProxy *mpris;
	GDBusProxy *queue;
	GApplication *app;
	gboolean loaded;
	gboolean scanned;
	GVariant *state;

#ifdef ENABLE_NLS
	/* initialize i18n */
	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);
#endif
	/* setup */
	setlocale (LC_ALL, "");
	g_type_init ();
	g_set_prgname ("rhythmbox-client");

	/* parse arguments */
	context = g_option_context_new (NULL);
	g_option_context_add_main_entries (context, args, NULL);
	g_option_context_parse (context, &argc, &argv, &error);
	if (annoy (&error))
		exit (1);

	rb_debug_init (debug);

	app = g_application_new ("org.gnome.Rhythmbox3", G_APPLICATION_IS_LAUNCHER);
	if (g_application_register (app, NULL, &error) == FALSE) {
		if (check_running) {
			rb_debug ("no running instance found");
			exit (2);
		} else if (quit) {
			rb_debug ("no existing instance to quit");
			exit (0);
		}

		rb_debug ("uh.. what?");
		exit (0);
	}


	/* are we just checking if it's running? */
	if (check_running) {
		rb_debug ("running instance found");
		exit (0);
	}

	/* wait until it's ready to accept control */
	state = g_action_group_get_action_state (G_ACTION_GROUP (app), "LoadURI");
	if (state == NULL) {
		rb_debug ("couldn't get app startup state");
		exit (0);
	}

	bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
	g_variant_get (state, "(bb)", &loaded, &scanned);
	if ((loaded && scanned) == FALSE) {
		GMainLoop *loop;
		GDBusProxy *app_proxy;

		rb_debug ("waiting for app startup");
		loop = g_main_loop_new (NULL, FALSE);
		g_signal_connect (app, "action-state-changed", G_CALLBACK (state_changed_cb), loop);

		/* dbus implementation of GApplication doesn't do action state updates yet */
		app_proxy = g_dbus_proxy_new_sync (bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL,
						   "org.gnome.Rhythmbox3",
						   "/org/gnome/Rhythmbox3",
						   "org.gtk.Actions",
						   NULL,
						   &error);
		if (app_proxy == NULL || proxy_has_name_owner (app_proxy) == FALSE) {
			g_warning ("unable to wait for app startup: %s", error->message);
			g_clear_error (&error);
		} else {
			g_object_set_data (G_OBJECT (app_proxy), "actual-app", app);
			g_signal_connect (app_proxy, "g-signal", G_CALLBACK (state_changed_signal_cb), loop);
			g_main_loop_run (loop);
			rb_debug ("app is now started enough");
		}
	}

	/* create proxies */
	mpris = g_dbus_proxy_new_sync (bus,
				       G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
				       NULL,
				       "org.mpris.MediaPlayer2.rhythmbox",
				       "/org/mpris/MediaPlayer2",
				       "org.mpris.MediaPlayer2.Player",
				       NULL,
				       &error);
	if (mpris == NULL || proxy_has_name_owner (mpris) == FALSE) {
		g_warning ("MPRIS D-Bus interface not available, some things won't work");
		if (next || previous || (seek != 0) || play || do_pause || play_pause || stop || volume_up || volume_down || (set_volume > -0.01)) {
			exit (1);
		}
	}

	queue = g_dbus_proxy_new_sync (bus,
				       G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
				       NULL,
				       "org.gnome.Rhythmbox3",
				       "/org/gnome/Rhythmbox3/PlayQueue",
				       "org.gnome.Rhythmbox3.PlayQueue",
				       NULL,
				       &error);
	if (queue == NULL || proxy_has_name_owner (queue) == FALSE) {
		g_warning ("Play queue interface not available, some things won't work");
		if (enqueue || clear_queue) {
			exit (1);
		}
	}

	/* activate or quit */
	if (quit) {
		rb_debug ("quitting existing instance");
		g_action_group_activate_action (G_ACTION_GROUP (app), "Quit", NULL);
		exit (0);
	}

	/* don't present if we're doing something else */
	if (next || previous || (seek != 0) ||
	    clear_queue ||
	    play_uri || other_stuff ||
	    play || do_pause || play_pause || stop || toggle_shuffle ||
	    print_playing || print_playing_format ||
	    (set_volume > -0.01) || volume_up || volume_down || print_volume /*|| mute || unmute*/ || (set_rating > -0.01))
		no_present = TRUE;

	/* present */
	if (!no_present) {
		g_application_activate (app);
	}

	/* set song rating */
	if (set_rating >= 0.0 && set_rating <= 5.0) {
		rb_debug ("rate song");

		rate_song (mpris, set_rating);
	}

	if (toggle_shuffle) {
		rb_debug("toggle shuffle");
		g_action_group_activate_action (G_ACTION_GROUP (app), "ToggleShuffle", NULL);
		annoy(&error);
	}

	/* skip to next or previous track */
	if (next) {
		rb_debug ("next track");
		g_dbus_proxy_call_sync (mpris, "Next", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
		annoy (&error);
	} else if (previous) {
		rb_debug ("previous track");
		g_dbus_proxy_call_sync (mpris, "Previous", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
		annoy (&error);
	}

	/* seek in track */
	if (seek != 0) {
		GHashTable *properties;
		rb_debug ("seek");

		properties = get_playing_song_info (mpris);
		if (properties != NULL) {
			GVariant *v = g_hash_table_lookup (properties, "mpris:trackid");
			if (v != NULL) {
				g_dbus_proxy_call_sync (mpris,
							"SetPosition",
							g_variant_new ("(ox)", g_variant_get_string (v, NULL), seek),
							G_DBUS_CALL_FLAGS_NONE,
							-1,
							NULL,
							&error);
				annoy (&error);
			}
		}
	}

	/* add/enqueue */
	if (clear_queue) {
		g_dbus_proxy_call_sync (queue, "ClearQueue", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
		annoy (&error);
	}
	if (other_stuff) {
		int i;
		for (i = 0; other_stuff[i] != NULL; i++) {
			GFile *file;
			char *fileuri;

			file = g_file_new_for_commandline_arg (other_stuff[i]);
			fileuri = g_file_get_uri (file);
			if (fileuri == NULL) {
				g_warning ("couldn't convert \"%s\" to a URI", other_stuff[i]);
				continue;
			}

			if (enqueue) {
				rb_debug ("enqueueing %s", fileuri);
				g_dbus_proxy_call_sync (queue, "AddToQueue", g_variant_new ("(s)", fileuri), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
				annoy (&error);
			} else {
				rb_debug ("importing %s", fileuri);
				g_action_group_activate_action (G_ACTION_GROUP (app), "LoadURI", g_variant_new ("(sb)", fileuri, FALSE));
			}
			g_free (fileuri);
			g_object_unref (file);
		}
	}

	/* select/activate/play source */
	if (select_source) {
		rb_debug ("selecting source %s", select_source);
		g_action_group_activate_action (G_ACTION_GROUP (app), "ActivateSource", g_variant_new ("(su)", select_source, 0));
	} else if (activate_source) {
		rb_debug ("activating source %s", activate_source);
		g_action_group_activate_action (G_ACTION_GROUP (app), "ActivateSource", g_variant_new ("(su)", activate_source, 1));
	} else if (play_source) {
		rb_debug ("playing source %s", play_source);
		g_action_group_activate_action (G_ACTION_GROUP (app), "ActivateSource", g_variant_new ("(su)", play_source, 2));
	}

	/* play uri */
	if (play_uri) {
		GFile *file;
		char *fileuri;

		file = g_file_new_for_commandline_arg (play_uri);
		fileuri = g_file_get_uri (file);
		if (fileuri == NULL) {
			g_warning ("couldn't convert \"%s\" to a URI", play_uri);
		} else {
			rb_debug ("loading and playing %s", fileuri);
			g_action_group_activate_action (G_ACTION_GROUP (app), "LoadURI", g_variant_new ("(sb)", fileuri, TRUE));
			annoy (&error);
		}
		g_free (fileuri);
		g_object_unref (file);
	}

	/* play/pause/stop */
	if (mpris) {
		GVariant *v;
		gboolean is_playing = FALSE;

		v = g_dbus_proxy_get_cached_property (mpris, "PlaybackStatus");
		if (v != NULL) {
			is_playing = (g_strcmp0 (g_variant_get_string (v, NULL), "Playing") == 0);
			g_variant_unref (v);
		}

		if (play || do_pause || play_pause) {
			if (is_playing != play || play_pause) {
				rb_debug ("calling PlayPause to change playback state");
				g_dbus_proxy_call_sync (mpris, "PlayPause", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
				annoy (&error);
			} else {
				rb_debug ("no need to change playback state");
			}
		} else if (stop) {
			g_warning ("not implemented yet");
		}
	}

	/* get/set volume, mute/unmute */
	if (set_volume > -0.01) {
		g_dbus_proxy_call_sync (mpris,
					"org.freedesktop.DBus.Properties.Set",
					g_variant_new ("(ssv)", "org.mpris.MediaPlayer2.Player", "Volume", g_variant_new_double (set_volume)),
					G_DBUS_CALL_FLAGS_NONE,
					-1,
					NULL,
					&error);
		annoy (&error);
	} else if (volume_up || volume_down) {
		GVariant *v;

		v = g_dbus_proxy_get_cached_property (mpris, "Volume");
		if (v != NULL) {

			set_volume = g_variant_get_double (v) + (volume_up ? 0.1 : -0.1);
			g_dbus_proxy_call_sync (mpris,
						"org.freedesktop.DBus.Properties.Set",
						g_variant_new ("(ssv)", "org.mpris.MediaPlayer2.Player", "Volume", g_variant_new_double (set_volume)),
						G_DBUS_CALL_FLAGS_NONE,
						-1,
						NULL,
						&error);
			annoy (&error);

			g_variant_unref (v);
		}
	}
	/* no mute for now? */
	/*
	} else if (unmute || mute) {
		org_gnome_Rhythmbox_Player_set_mute (player_proxy, unmute ? FALSE : TRUE, &error);
		annoy (&error);
	}
	*/

	if (print_volume) {
		gdouble volume = 1.0;
		GVariant *v = g_dbus_proxy_get_cached_property (mpris, "Volume");
		if (v != NULL) {
			volume = g_variant_get_double (v);
			g_variant_unref (v);
		}
		g_print (_("Playback volume is %f.\n"), volume);
	}

	/* print playing song */
	if (print_playing_format) {
		print_playing_song (mpris, print_playing_format);
	} else if (print_playing) {
		print_playing_song_default (mpris);
	}

	if (mpris) {
		g_object_unref (mpris);
	}

	g_dbus_connection_flush_sync (bus, NULL, NULL);
	g_option_context_free (context);

	return 0;
}
int
main (int argc, char *argv[])
{
	gs_unref_object GDBusConnection *connection = NULL;
	gs_free_error GError *error = NULL;
	gs_unref_variant GVariant *parameters = NULL;
	gs_unref_variant GVariant *result = NULL;
	gboolean success = FALSE;
	guint try_count = 0;
	gint64 time_end;

	nm_g_type_init ();

	/* FIXME: g_dbus_connection_new_for_address_sync() tries to connect to the socket in
	 * non-blocking mode, which can easily fail with EAGAIN, causing the creation of the
	 * socket to fail with "Could not connect: Resource temporarily unavailable".
	 *
	 * We should instead create the GIOStream ourself and block on connecting to
	 * the socket. */
	connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private-dhcp",
	                                                     G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
	                                                     NULL, NULL, &error);
	if (!connection) {
		g_dbus_error_strip_remote_error (error);
		_LOGE ("could not connect to NetworkManager D-Bus socket: %s",
		       error->message);
		goto out;
	}

	parameters = build_signal_parameters ();

	time_end = g_get_monotonic_time () + (200 * 1000L); /* retry for at most 200 milliseconds */

do_notify:
	try_count++;
	result = g_dbus_connection_call_sync (connection,
	                                      NULL,
	                                      NM_DHCP_HELPER_SERVER_OBJECT_PATH,
	                                      NM_DHCP_HELPER_SERVER_INTERFACE_NAME,
	                                      NM_DHCP_HELPER_SERVER_METHOD_NOTIFY,
	                                      parameters,
	                                      NULL,
	                                      G_DBUS_CALL_FLAGS_NONE,
	                                      1000,
	                                      NULL,
	                                      &error);

	if (!result) {
		gs_free char *s_err = NULL;

		s_err = g_dbus_error_get_remote_error (error);
		if (NM_IN_STRSET (s_err, "org.freedesktop.DBus.Error.UnknownMethod")) {
			gint64 remaining_time = time_end - g_get_monotonic_time ();

			/* I am not sure that a race can actually happen, as we register the object
			 * on the server side during GDBusServer:new-connection signal.
			 *
			 * However, there was also a race for subscribing to an event, so let's just
			 * do some retry. */
			if (remaining_time > 0) {
				_LOGi ("failure to call notify: %s (retry %u)", error->message, try_count);
				g_usleep (NM_MIN (NM_CLAMP ((gint64) (100L * (1L << try_count)), 5000, 25000), remaining_time));
				g_clear_error (&error);
				goto do_notify;
			}
		}
		_LOGW ("failure to call notify: %s (try signal via Event)", error->message);
		g_clear_error (&error);

		/* for backward compatibilty, try to emit the signal. There is no stable
		 * API between the dhcp-helper and NetworkManager. However, while upgrading
		 * the NetworkManager package, a newer helper might want to notify an
		 * older server, which still uses the "Event". */
		if (!g_dbus_connection_emit_signal (connection,
		                                    NULL,
		                                    "/",
		                                    NM_DHCP_CLIENT_DBUS_IFACE,
		                                    "Event",
		                                    parameters,
		                                    &error)) {
			g_dbus_error_strip_remote_error (error);
			_LOGE ("could not send DHCP Event signal: %s", error->message);
			goto out;
		}
		/* We were able to send the asynchronous Event. Consider that a success. */
		success = TRUE;
	} else
		success = TRUE;

	if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
		g_dbus_error_strip_remote_error (error);
		_LOGE ("could not flush D-Bus connection: %s", error->message);
		success = FALSE;
		goto out;
	}

out:
	if (!success)
		kill_pid ();
	return success ? EXIT_SUCCESS : EXIT_FAILURE;
}