Exemple #1
0
// Simple wrapper for a common D-Bus pattern.
GVariant * g_dbus_simple_send(GDBusConnection *bus, GDBusMessage *msg, const gchar *type)
{
    GDBusMessage *reply;
    GVariant *body;
    gchar *fmt;

    if (!(reply = g_dbus_send(bus, msg, 0, -1, 0, 0, 0))) {
        g_object_unref(msg);
        return NULL;
    }

    body  = g_dbus_message_get_body(reply);
    fmt   = g_dbus_message_print(reply, 0);

    g_variant_ref(body);

    if (g_strcmp0(g_variant_type_peek_string(g_variant_get_type(body)), type) != 0) {
        g_message("body type %s does not match expected type %s, message: %s",
                  g_variant_type_peek_string(g_variant_get_type(body)),
                  type,
                  fmt);
        g_variant_unref(body);

        // return error
        body = NULL;
    }

    g_free(fmt);
    g_object_unref(reply);
    g_object_unref(msg);
    return body;
}
Exemple #2
0
// returns object path of default adapter or NULL if failed
// this object path must be freed with g_free()
gchar* bluez_get_default_adapter(GDBusConnection* conn)
{
    GError* error = NULL;

    GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez",
                                                       "/",
                                                       "org.bluez.Manager",
                                                       "DefaultAdapter");
    if(call_message == NULL)
    {
        g_printf("g_dbus_message_new_method_call failed\n");

        return NULL;
    }

    GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn,
                                                                          call_message,
                                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                          -1,
                                                                          NULL,
                                                                          NULL,
                                                                          &error);
    if(reply_message == NULL)
    {
        g_printf("g_dbus_connection_send_message_with_reply_sync failed\n");

        return NULL;
    }

    if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
        printf("Error occured\n");

        g_dbus_message_to_gerror(reply_message, &error);
        g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message);

        g_error_free(error);

        return NULL;
    }


    GVariant* variant = g_dbus_message_get_body(reply_message);

    // get first child, as this is the object path of the default interface of bluez
    GVariant* var_child = g_variant_get_child_value(variant, 0);

    const gchar* tmp_path = g_variant_get_string(var_child, NULL);

    // copy content of tmp_path to obj_path, as tmp_path gets freed after unref of the variant
    gchar* obj_path = g_strdup(tmp_path);

    // cleanup
    g_variant_unref(var_child);

    g_object_unref(call_message);
    g_object_unref(reply_message);

    return obj_path;
}
Exemple #3
0
static GDBusMessage *
on_filter_func (GDBusConnection *connection,
                GDBusMessage *message,
                gboolean incoming,
                gpointer user_data)
{
  GError *error = NULL;
  GDBusMessage *reply;

  if (incoming &&
      g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
      g_str_equal (g_dbus_message_get_path (message), "/bork") &&
      g_str_equal (g_dbus_message_get_interface (message), "borkety.Bork") &&
      g_str_equal (g_dbus_message_get_member (message), "Echo"))
    {
      reply = g_dbus_message_new_method_reply (message);
      g_dbus_message_set_body (reply, g_dbus_message_get_body (message));
      g_dbus_connection_send_message (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error);
      if (error != NULL)
        {
          g_warning ("Couldn't send DBus message: %s", error->message);
          g_error_free (error);
        }
      g_object_unref (reply);
      g_object_unref (message);
      return NULL;
    }

  return message;
}
static char *
xdp_connection_lookup_app_id_sync (GDBusConnection       *connection,
                                   const char            *sender,
                                   GCancellable          *cancellable,
                                   GError               **error)
{
  g_autoptr(GDBusMessage) msg = NULL;
  g_autoptr(GDBusMessage) reply = NULL;
  char *app_id = NULL;
  GVariant *body;
  guint32 pid;

  G_LOCK (app_ids);
  if (app_ids)
    app_id = g_strdup (g_hash_table_lookup (app_ids, sender));
  G_UNLOCK (app_ids);

  if (app_id != NULL)
    return app_id;

  msg = g_dbus_message_new_method_call ("org.freedesktop.DBus",
                                        "/org/freedesktop/DBus",
                                        "org.freedesktop.DBus",
                                        "GetConnectionUnixProcessID");
  g_dbus_message_set_body (msg, g_variant_new ("(s)", sender));

  reply = g_dbus_connection_send_message_with_reply_sync (connection, msg,
                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                          30000,
                                                          NULL,
                                                          cancellable,
                                                          error);
  if (reply == NULL)
    return NULL;

  if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't find peer app id");
      return NULL;
    }

  body = g_dbus_message_get_body (reply);

  g_variant_get (body, "(u)", &pid);

  app_id = get_app_id_from_pid (pid, error);
  if (app_id)
    {
      G_LOCK (app_ids);
      ensure_app_ids ();
      g_hash_table_insert (app_ids, g_strdup (sender), g_strdup (app_id));
      G_UNLOCK (app_ids);
    }

  return app_id;
}
Exemple #5
0
GVariant* bluez_characteristic_get_value(GDBusConnection* conn, const gchar* char_path)
{
    GError* error = NULL;

    GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez",
                                                       char_path,
                                                       "org.bluez.Characteristic",
                                                       "GetProperties");
    if(call_message == NULL)
    {
        g_printf("g_dbus_message_new_method_call failed\n");

        return NULL;
    }

    GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn,
                                                                          call_message,
                                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                          -1,
                                                                          NULL,
                                                                          NULL,
                                                                          &error);
    if(reply_message == NULL)
    {
        g_printf("g_dbus_connection_send_message_with_reply_sync failed\n");

        return NULL;
    }

    if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
        g_printf("Error occured\n");

        g_dbus_message_to_gerror(reply_message, &error);
        g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message);

        g_error_free(error);

        return NULL;
    }



    GVariant* var_body = g_dbus_message_get_body(reply_message);

    g_variant_ref(var_body);

    // cleanup
    g_object_unref(call_message);
    g_object_unref(reply_message);

    return var_body;
}
Exemple #6
0
// returns the object path to a given device or NULL if failed
// object path has to be freed with g_free()
gchar* bluez_find_device(GDBusConnection* conn, const gchar* adapter_path, const char* bt_addr)
{
    GError* error = NULL;

    GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez",
                                                       adapter_path,
                                                       "org.bluez.Adapter",
                                                       "FindDevice");
    if(call_message == NULL)
    {
        return NULL;
    }

    GVariant* variant_addr = g_variant_new_string(bt_addr);
    GVariant* variant_body = g_variant_new_tuple(&variant_addr, 1);

    g_dbus_message_set_body(call_message, variant_body);

    GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn,
                                                                          call_message,
                                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                          -1,
                                                                          NULL,
                                                                          NULL,
                                                                          &error);
    if(reply_message == NULL)
    {
        return NULL;
    }

    if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
        return NULL;
    }

    GVariant* variant = g_dbus_message_get_body(reply_message);

    // get first child, as this is the object path of the default interface of bluez
    GVariant* var_child = g_variant_get_child_value(variant, 0);

    const gchar* tmp_path = g_variant_get_string(var_child, NULL);

    // copy content of tmp_path to obj_path, as tmp_path gets freed after unref of the variant
    gchar* obj_path = g_strdup(tmp_path);

    // cleanup
    g_variant_unref(var_child);

    g_object_unref(call_message);
    g_object_unref(reply_message);

    return obj_path;
}
Exemple #7
0
static void
open_file_msg_cb (GObject *source_object,
                  GAsyncResult *res,
                  gpointer user_data)
{
  FilechooserPortalData *data = user_data;
  GtkFileChooserNative *self = data->self;
  GDBusMessage *reply;
  GError *error = NULL;

  reply = g_dbus_connection_send_message_with_reply_finish (data->connection, res, &error);

  if (reply && g_dbus_message_to_gerror (reply, &error))
    g_clear_object (&reply);

  if (reply == NULL)
    {
      if (!data->hidden)
        _gtk_native_dialog_emit_response (GTK_NATIVE_DIALOG (self), GTK_RESPONSE_DELETE_EVENT);
      g_warning ("Can't open portal file chooser: %s", error->message);
      g_error_free (error);
      filechooser_portal_data_free (data);
      self->mode_data = NULL;
      return;
    }

  g_variant_get_child (g_dbus_message_get_body (reply), 0, "o",
                       &data->portal_handle);

  if (data->hidden)
    {
      /* The dialog was hidden before we got the handle, close it now */
      send_close (data);
      filechooser_portal_data_free (data);
      self->mode_data = NULL;
    }
  else
    {
      data->portal_response_signal_id =
        g_dbus_connection_signal_subscribe (data->connection,
                                            "org.freedesktop.portal.Desktop",
                                            "org.freedesktop.portal.Request",
                                            "Response",
                                            data->portal_handle,
                                            NULL,
                                            G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
                                            response_cb,
                                            self, NULL);
    }

  g_object_unref (reply);
}
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;
}
Exemple #9
0
static gboolean
cloud_spy_dispatcher_connection_send_message (GDBusConnection * connection, GDBusMessage * message, GDBusSendMessageFlags flags, volatile guint32 * out_serial, GError ** error)
{
  CloudSpyDispatcherInvocation * self = (CloudSpyDispatcherInvocation *) connection;
  GVariant * result;

  (void) flags;
  (void) out_serial;
  (void) error;

  result = g_variant_ref (g_dbus_message_get_body (message));
  g_simple_async_result_set_op_res_gpointer (self->res, result, g_variant_unref);
  g_simple_async_result_complete (self->res);

  return TRUE;
}
Exemple #10
0
static gint64
arv_rtkit_get_int_property (GDBusConnection *connection, const char* propname, GError **error) {

	GDBusMessage *message;
	GDBusMessage *reply;
	GError *local_error = NULL;
	GVariant *body;
	GVariant *parameter;
	GVariant *variant;
	const GVariantType *variant_type;
	gint64 value;

	message = g_dbus_message_new_method_call (RTKIT_SERVICE_NAME,
						  RTKIT_OBJECT_PATH,
						  "org.freedesktop.DBus.Properties",
						  "Get");
	g_dbus_message_set_body (message, g_variant_new ("(ss)", "org.freedesktop.RealtimeKit1", propname));

	reply = g_dbus_connection_send_message_with_reply_sync (connection, message,
								G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000, NULL, NULL,
								&local_error);
	g_object_unref (message);

	if (local_error != NULL) {
		g_propagate_error (error, local_error);
		return 0;
	}

	if (g_dbus_message_get_message_type (reply) != G_DBUS_MESSAGE_TYPE_METHOD_RETURN) {
		local_error = g_error_new (ARV_RTKIT_ERROR, ARV_RTKIT_ERROR_PERMISSION_DENIED,
					   "%s", g_dbus_message_get_error_name (reply));
		g_propagate_error (error, local_error);
		g_object_unref (reply);
		return 0;
	}

	if (!g_variant_type_equal ("v", g_dbus_message_get_signature (reply))) {
		local_error = g_error_new (ARV_RTKIT_ERROR, ARV_RTKIT_ERROR_WRONG_REPLY,
					   "Invalid reply signature");
		g_propagate_error (error, local_error);
		g_object_unref (reply);
		return 0;
	}

	body = g_dbus_message_get_body (reply);
	parameter = g_variant_get_child_value (body, 0);
	variant = g_variant_get_variant (parameter);

	variant_type = g_variant_get_type (variant);

	if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32))
		value = g_variant_get_int32 (variant);
	else if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64))
		value = g_variant_get_int64 (variant);
	else
		value = 0;

	g_variant_unref (parameter);
	g_variant_unref (variant);
	g_object_unref (reply);

	return value;
}
gboolean
eas_gdbus_call_finish (struct eas_gdbus_client *client, GAsyncResult *result,
		       guint cancel_serial, const gchar *out_params,
		       va_list *ap, GError **error)
{
	GDBusMessage *reply;
	gchar *out_params_type = (gchar *) out_params;
	gboolean success = FALSE;
	GVariant *v;

	reply = g_dbus_connection_send_message_with_reply_finish(client->connection,
								 result, error);
	if (cancel_serial) {
		GDBusMessage *message;

		message = g_dbus_message_new_method_call (EAS_SERVICE_NAME,
							  EAS_SERVICE_COMMON_OBJECT_PATH,
							  EAS_SERVICE_COMMON_INTERFACE,
							  "cancel_request");
		g_dbus_message_set_body (message,
					 g_variant_new ("(su)",
							client->account_uid,
							cancel_serial));

		g_dbus_connection_send_message (client->connection,
						message,
						G_DBUS_SEND_MESSAGE_FLAGS_NONE,
						NULL, NULL);

		g_object_unref (message);
	}

	if (!reply)
		return FALSE;

	/* g_variant_is_of_type() will fail to match a DBus return
	   of (sas) with a format string of (s^as), where the ^ is
	   required to make it convert to a strv instead of something
	   more complicated. So we remove all ^ characters from the
	   string that we show to g_variant_is_of_type(). Ick. */
	if (out_params && strchr (out_params, '^')) {
		gchar *x, *y;

		out_params_type = g_strdup (out_params);

		x = y = strchr (out_params_type, '^');
		y++;

		while (*y) {
			if (*y == '^')
				y++;
			else
				*(x++) = *(y++);
		}
		*x = 0;
	}
	switch (g_dbus_message_get_message_type (reply)) {
	case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
		/* An empty (successful) response will give a NULL GVariant here */
		v = g_dbus_message_get_body (reply);
		if (!out_params) {
			if (v)
				goto inval;
			else {
				success = TRUE;
				break;
			}
		}
		if (!g_variant_is_of_type (v, G_VARIANT_TYPE (out_params_type))) {
		inval:
			g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
				     "ActiveSync DBus call returned invalid response type %s",
				     v?g_variant_get_type_string (v):"()");
			goto out;
			g_object_unref (reply);
		}
		g_variant_get_va (v, out_params, NULL, ap);
		success = TRUE;
		break;

	case G_DBUS_MESSAGE_TYPE_ERROR:
		g_dbus_message_to_gerror (reply, error);
		break;

	default:
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
			     "EAS DBus call returned weird message type %d",
			     g_dbus_message_get_message_type (reply));
		break;
	}

 out:
	if (out_params_type != out_params)
		g_free (out_params_type);

	g_object_unref (reply);
	return success;
}
static GDBusMessage *
notification_filter_func (GDBusConnection *connection,
                          GDBusMessage    *message,
                          gboolean        *incoming,
                          gpointer         user_data)
{
    GDBusMessage *ret = NULL;
    gboolean transient = FALSE;
    gchar *sender_str = NULL;

    CsNotificationWatcher *watcher = CS_NOTIFICATION_WATCHER (user_data);

    if (incoming &&
        g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
        g_strcmp0 (g_dbus_message_get_interface (message), NOTIFICATIONS_INTERFACE) == 0 &&
        g_strcmp0 (g_dbus_message_get_member (message), NOTIFY_METHOD) == 0)
    {
        GVariant *body = g_dbus_message_get_body (message);

        if (body != NULL &&
            g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE) &&
            g_variant_n_children (body) >= 7)
        {
            GVariant *hints, *sender;

            if (debug_mode)
            {
                GVariant *dbg_var = NULL;
                const gchar *dbg_str;

                g_printerr ("Notification received...\n");

                dbg_var = g_variant_get_child_value (body, 0);

                if (dbg_var != NULL && g_variant_is_of_type (dbg_var, G_VARIANT_TYPE_STRING))
                {
                    dbg_str = g_variant_get_string (dbg_var, NULL);

                    if (dbg_str != NULL)
                    {
                        g_printerr ("Sender: %s\n", dbg_str);
                    }
                }

                g_clear_pointer (&dbg_var, g_variant_unref);

                dbg_var = g_variant_get_child_value (body, 3);

                if (dbg_var != NULL && g_variant_is_of_type (dbg_var, G_VARIANT_TYPE_STRING))
                {
                    dbg_str = g_variant_get_string (dbg_var, NULL);

                    if (dbg_str != NULL)
                    {
                        g_printerr ("Summary: %s\n", dbg_str);
                    }
                }

                g_clear_pointer (&dbg_var, g_variant_unref);

                dbg_var = g_variant_get_child_value (body, 4);

                if (dbg_var != NULL && g_variant_is_of_type (dbg_var, G_VARIANT_TYPE_STRING))
                {
                    dbg_str = g_variant_get_string (dbg_var, NULL);

                    if (dbg_str != NULL)
                    {
                        g_printerr ("Body: %s\n", dbg_str);
                    }
                }

                g_clear_pointer (&dbg_var, g_variant_unref);
            }

            hints = g_variant_get_child_value (body, 6);

            if (hints != NULL && g_variant_is_of_type (hints, G_VARIANT_TYPE_DICTIONARY))
            {
                GVariant *transient_hint;

                transient_hint = g_variant_lookup_value (hints, "transient", NULL);

                if (transient_hint)
                {
                    transient = g_variant_get_boolean (transient_hint);
                }

                g_clear_pointer (&transient_hint, g_variant_unref);
            }

            g_clear_pointer (&hints, g_variant_unref);

            sender = g_variant_get_child_value (body, 0);

            if (sender)
            {
                sender_str = g_variant_dup_string (sender, NULL);
            }

            g_clear_pointer (&sender, g_variant_unref);
        }
    }
    else
    {
        ret = message;
    }

    if (ret == NULL && !transient)
    {
        NotificationIdleData *data = g_slice_new0 (NotificationIdleData);

        data->watcher = watcher;
        data->sender = sender_str;

        g_idle_add (idle_notify_received, data);
    }

    return ret;
}
Exemple #13
0
gboolean
e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd,
			      GError **error)
{
	gint success = FALSE;
	GError *local_error = NULL;
	GDBusConnection *connection;
	GDBusMessage *message, *reply;
	gchar *name;

	connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
	if (local_error) {
		g_warning ("could not get system bus: %s\n",
			   local_error->message);
		g_propagate_error (error, local_error);
		return FALSE;
	}

	g_dbus_connection_set_exit_on_close (connection, FALSE);
	/* Create a new message on the KRB_DBUS_INTERFACE */
	message = g_dbus_message_new_method_call (KRB_DBUS_INTERFACE,
						  KRB_DBUS_PATH,
						  KRB_DBUS_INTERFACE,
						  "acquireTgt");
	if (!message) {
		g_object_unref (connection);
		return FALSE;
	}

	/* Appends the data as an argument to the message */
	name = g_strdup_printf ("%s@%s", empd->username, empd->krb_realm);
	g_dbus_message_set_body (message, g_variant_new ("(s)", name));

	/* Sends the message: Have a 300 sec wait timeout  */
	reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 300 * 1000, NULL, NULL, &local_error);
	g_free (name);

	if (!local_error && reply) {
		if (g_dbus_message_to_gerror (reply, &local_error)) {
			g_object_unref (reply);
			reply = NULL;
		}
	}

	if (local_error) {
		g_dbus_error_strip_remote_error (local_error);
		g_propagate_error (error, local_error);
	}

	if (reply) {
		GVariant *body = g_dbus_message_get_body (reply);
		if (body) {
			g_variant_get (body, "(b)", &success);
		}
		g_object_unref (reply);
	}

	/* Free the message */
	g_object_unref (message);
	g_object_unref (connection);

	return success && !local_error;
}
static gboolean
do_command (GDBusConnection *connection)
{
        GDBusMessage *reply;

        if (do_quit) {
                reply = screensaver_send_message_void (connection, "Quit", FALSE);
                goto done;
        }

        if (do_query) {
                GVariant     *body;
                gboolean      v;

                if (! screensaver_is_running (connection)) {
                        g_message ("Screensaver is not running!");
                        goto done;
                }

                reply = screensaver_send_message_void (connection, "GetActive", TRUE);
                if (reply == NULL) {
                        g_message ("Did not receive a reply from the screensaver.");
                        goto done;
                }

                body = g_dbus_message_get_body (reply);
                g_variant_get (body, "(b)", &v);
                g_object_unref (reply);

                if (v)  {
                        g_print (_("The screensaver is active\n"));
                } else {
                        g_print (_("The screensaver is inactive\n"));
                }
        }

        if (do_time) {
                GVariant *body;
                gboolean  v;
                gint32    t;

                reply = screensaver_send_message_void (connection, "GetActive", TRUE);
                if (reply == NULL) {
                        g_message ("Did not receive a reply from the screensaver.");
                        goto done;
                }

                body = g_dbus_message_get_body (reply);
                g_variant_get (body, "(b)", &v);
                g_object_unref (reply);

                if (v) {
                        reply = screensaver_send_message_void (connection, "GetActiveTime", TRUE);
                        if (reply == NULL) {
                                g_message ("Did not receive a reply from the screensaver.");
                                goto done;
                        }

                        body = g_dbus_message_get_body (reply);
                        g_variant_get (body, "(u)", &t);
                        g_object_unref (reply);

                        g_print (ngettext ("The screensaver has been active for %d second.\n", "The screensaver has been active for %d seconds.\n", t), t);
                } else {
                        g_print (_("The screensaver is not currently active.\n"));
                }
        }

        if (do_lock) {
				if (g_strcmp0 (away_message, "DEFAULT") == 0) {
					reply = screensaver_send_message_string (connection, "Lock", away_message);
				}
				else {
					gchar * custom_message = g_strdup_printf("CUSTOM###%s", away_message);
					reply = screensaver_send_message_string (connection, "Lock", custom_message);
					g_free (custom_message);
				}
                if (reply == NULL) {
                        g_message ("Did not receive a reply from the screensaver.");
                        goto done;
                }
                g_object_unref (reply);
        }

        if (do_activate) {
                reply = screensaver_send_message_bool (connection, "SetActive", TRUE);
                if (reply == NULL) {
                        g_message ("Did not receive a reply from the screensaver.");
                        goto done;
                }
                g_object_unref (reply);
        }

        if (do_deactivate) {
                reply = screensaver_send_message_bool (connection, "SetActive", FALSE);
                if (reply == NULL) {
                        g_message ("Did not receive a reply from the screensaver.");
                        goto done;
                }
                g_object_unref (reply);
        }

 done:
        g_main_loop_quit (loop);
        return FALSE;
}
Exemple #15
0
/**
 * fu_util_get_details:
 **/
static gboolean
fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error)
{
	GVariant *body;
	GVariant *val;
	gint fd;
	gint retval;
	_cleanup_object_unref_ GDBusMessage *message = NULL;
	_cleanup_object_unref_ GDBusMessage *request = NULL;
	_cleanup_object_unref_ GUnixFDList *fd_list = NULL;

	/* check args */
	if (g_strv_length (values) != 1) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Invalid arguments: expected 'filename'");
		return FALSE;
	}

	/* open file */
	fd = open (values[0], O_RDONLY);
	if (fd < 0) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INVALID_FILE,
			     "failed to open %s",
			     values[0]);
		return FALSE;
	}

	/* set out of band file descriptor */
	fd_list = g_unix_fd_list_new ();
	retval = g_unix_fd_list_append (fd_list, fd, NULL);
	g_assert (retval != -1);
	request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
						  FWUPD_DBUS_PATH,
						  FWUPD_DBUS_INTERFACE,
						  "GetDetails");
	g_dbus_message_set_unix_fd_list (request, fd_list);

	/* g_unix_fd_list_append did a dup() already */
	close (fd);

	/* send message */
	body = g_variant_new ("(h)", fd > -1 ? 0 : -1);
	g_dbus_message_set_body (request, body);
	message = g_dbus_connection_send_message_with_reply_sync (priv->conn,
								  request,
								  G_DBUS_SEND_MESSAGE_FLAGS_NONE,
								  -1,
								  NULL,
								  NULL,
								  error);
	if (message == NULL) {
		g_dbus_error_strip_remote_error (*error);
		return FALSE;
	}
	if (g_dbus_message_to_gerror (message, error)) {
		g_dbus_error_strip_remote_error (*error);
		return FALSE;
	}

	/* print results */
	val = g_dbus_message_get_body (message);
	fu_util_print_metadata (val);
	return TRUE;
}
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;
}
gboolean
xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(XdgAppDeploy) app_deploy = NULL;
  g_autoptr(XdgAppDeploy) runtime_deploy = NULL;
  g_autoptr(GFile) app_files = NULL;
  g_autoptr(GFile) runtime_files = NULL;
  g_autoptr(GFile) app_id_dir = NULL;
  g_autoptr(GFile) app_cache_dir = NULL;
  g_autoptr(GFile) app_data_dir = NULL;
  g_autoptr(GFile) app_config_dir = NULL;
  g_autoptr(GFile) home = NULL;
  g_autoptr(GFile) user_font1 = NULL;
  g_autoptr(GFile) user_font2 = NULL;
  g_autoptr(XdgAppSessionHelper) session_helper = NULL;
  g_autofree char *runtime = NULL;
  g_autofree char *default_command = NULL;
  g_autofree char *runtime_ref = NULL;
  g_autofree char *app_ref = NULL;
  g_autofree char *doc_mount_path = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GKeyFile) runtime_metakey = NULL;
  g_autoptr(GPtrArray) argv_array = NULL;
  g_auto(GStrv) envp = NULL;
  g_autoptr(GPtrArray) dbus_proxy_argv = NULL;
  g_autofree char *monitor_path = NULL;
  const char *app;
  const char *branch = "master";
  const char *command = "/bin/sh";
  int i;
  int rest_argv_start, rest_argc;
  int sync_proxy_pipes[2];
  g_autoptr(XdgAppContext) arg_context = NULL;
  g_autoptr(XdgAppContext) app_context = NULL;
  g_autoptr(XdgAppContext) overrides = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;

  context = g_option_context_new ("APP [args...] - Run an app");

  rest_argc = 0;
  for (i = 1; i < argc; i++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[i][0] != '-')
        {
          rest_argv_start = i;
          rest_argc = argc - i;
          argc = i;
          break;
        }
    }

  arg_context = xdg_app_context_new ();
  g_option_context_add_group (context, xdg_app_context_get_options (arg_context));

  if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (rest_argc == 0)
    return usage_error (context, "APP must be specified", error);

  app = argv[rest_argv_start];

  if (opt_branch)
    branch = opt_branch;

  if (!xdg_app_is_valid_name (app))
    return xdg_app_fail (error, "'%s' is not a valid application name", app);

  if (!xdg_app_is_valid_branch (branch))
    return xdg_app_fail (error, "'%s' is not a valid branch name", branch);

  app_ref = xdg_app_build_app_ref (app, branch, opt_arch);

  app_deploy = xdg_app_find_deploy_for_ref (app_ref, cancellable, error);
  if (app_deploy == NULL)
    return FALSE;

  metakey = xdg_app_deploy_get_metadata (app_deploy);

  argv_array = g_ptr_array_new_with_free_func (g_free);
  dbus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
  g_ptr_array_add (argv_array, g_strdup (HELPER));
  g_ptr_array_add (argv_array, g_strdup ("-l"));

  if (!xdg_app_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error))
    return FALSE;

  if (opt_runtime)
    runtime = opt_runtime;
  else
    {
      runtime = g_key_file_get_string (metakey, "Application", opt_devel ? "sdk" : "runtime", error);
      if (*error)
        return FALSE;
    }

  runtime_ref = g_build_filename ("runtime", runtime, NULL);

  runtime_deploy = xdg_app_find_deploy_for_ref (runtime_ref, cancellable, error);
  if (runtime_deploy == NULL)
    return FALSE;

  runtime_metakey = xdg_app_deploy_get_metadata (runtime_deploy);

  app_context = xdg_app_context_new ();
  if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error))
    return FALSE;
  if (!xdg_app_context_load_metadata (app_context, metakey, error))
    return FALSE;

  overrides = xdg_app_deploy_get_overrides (app_deploy);
  xdg_app_context_merge (app_context, overrides);

  xdg_app_context_merge (app_context, arg_context);

  if (!xdg_app_run_add_extension_args (argv_array, runtime_metakey, runtime_ref, cancellable, error))
    return FALSE;

  if ((app_id_dir = xdg_app_ensure_data_dir (app, cancellable, error)) == NULL)
      return FALSE;

  app_cache_dir = g_file_get_child (app_id_dir, "cache");
  g_ptr_array_add (argv_array, g_strdup ("-B"));
  g_ptr_array_add (argv_array, g_strdup_printf ("/var/cache=%s", gs_file_get_path_cached (app_cache_dir)));

  app_data_dir = g_file_get_child (app_id_dir, "data");
  g_ptr_array_add (argv_array, g_strdup ("-B"));
  g_ptr_array_add (argv_array, g_strdup_printf ("/var/data=%s", gs_file_get_path_cached (app_data_dir)));

  app_config_dir = g_file_get_child (app_id_dir, "config");
  g_ptr_array_add (argv_array, g_strdup ("-B"));
  g_ptr_array_add (argv_array, g_strdup_printf ("/var/config=%s", gs_file_get_path_cached (app_config_dir)));

  app_files = xdg_app_deploy_get_files (app_deploy);
  runtime_files = xdg_app_deploy_get_files (runtime_deploy);

  default_command = g_key_file_get_string (metakey, "Application", "command", error);
  if (*error)
    return FALSE;
  if (opt_command)
    command = opt_command;
  else
    command = default_command;

  session_helper = xdg_app_session_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
								  G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
								  "org.freedesktop.XdgApp",
								  "/org/freedesktop/XdgApp/SessionHelper",
								  NULL, NULL);
  if (session_helper &&
      xdg_app_session_helper_call_request_monitor_sync (session_helper,
                                                        &monitor_path,
                                                        NULL, NULL))
    {
      g_ptr_array_add (argv_array, g_strdup ("-m"));
      g_ptr_array_add (argv_array, monitor_path);
    }
  else
    g_ptr_array_add (argv_array, g_strdup ("-r"));

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (session_bus)
    {
      g_autoptr (GError) local_error = NULL;
      g_autoptr (GDBusMessage) reply = NULL;
      g_autoptr (GDBusMessage) msg = g_dbus_message_new_method_call ("org.freedesktop.portal.Documents",
                                                                     "/org/freedesktop/portal/documents",
                                                                     "org.freedesktop.portal.Documents",
                                                                     "GetMountPoint");
      g_dbus_message_set_body (msg, g_variant_new ("()"));
      reply = g_dbus_connection_send_message_with_reply_sync (session_bus, msg,
                                                              G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                              30000,
                                                              NULL,
                                                              NULL,
                                                              NULL);
      if (reply)
        {
          if (g_dbus_message_to_gerror (reply, &local_error))
            {
              g_warning ("Can't get document portal: %s\n", local_error->message);
            }
          else
            g_variant_get (g_dbus_message_get_body (reply),
                           "(^ay)", &doc_mount_path);
        }
    }

  xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv, doc_mount_path,
                                    app, app_context, app_id_dir);

  g_ptr_array_add (argv_array, g_strdup ("-b"));
  g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/fonts=%s", SYSTEM_FONTS_DIR));

  if (opt_devel)
    g_ptr_array_add (argv_array, g_strdup ("-c"));

  home = g_file_new_for_path (g_get_home_dir ());
  user_font1 = g_file_resolve_relative_path (home, ".local/share/fonts");
  user_font2 = g_file_resolve_relative_path (home, ".fonts");

  if (g_file_query_exists (user_font1, NULL))
    {
      g_autofree char *path = g_file_get_path (user_font1);
      g_ptr_array_add (argv_array, g_strdup ("-b"));
      g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path));
    }
  else if (g_file_query_exists (user_font2, NULL))
    {
      g_autofree char *path = g_file_get_path (user_font2);
      g_ptr_array_add (argv_array, g_strdup ("-b"));
      g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path));
    }

  /* Must run this before spawning the dbus proxy, to ensure it
     ends up in the app cgroup */
  xdg_app_run_in_transient_unit (app);

  if (dbus_proxy_argv->len > 0)
    {
      char x;

      if (pipe (sync_proxy_pipes) < 0)
	{
	  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to create sync pipe");
	  return FALSE;
	}

      g_ptr_array_insert (dbus_proxy_argv, 0, g_strdup (DBUSPROXY));
      g_ptr_array_insert (dbus_proxy_argv, 1, g_strdup_printf ("--fd=%d", sync_proxy_pipes[1]));

      g_ptr_array_add (dbus_proxy_argv, NULL); /* NULL terminate */

      if (!g_spawn_async (NULL,
			  (char **)dbus_proxy_argv->pdata,
			  NULL,
			  G_SPAWN_SEARCH_PATH,
			  dbus_spawn_child_setup,
			  GINT_TO_POINTER (sync_proxy_pipes[1]),
			  NULL, error))
	return FALSE;

      close (sync_proxy_pipes[1]);

      /* Sync with proxy, i.e. wait until its listening on the sockets */
      if (read (sync_proxy_pipes[0], &x, 1) != 1)
	{
	  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to sync with dbus proxy");
	  return FALSE;
	}

      g_ptr_array_add (argv_array, g_strdup ("-S"));
      g_ptr_array_add (argv_array, g_strdup_printf ("%d", sync_proxy_pipes[0]));
    }

  g_ptr_array_add (argv_array, g_strdup ("-a"));
  g_ptr_array_add (argv_array, g_file_get_path (app_files));
  g_ptr_array_add (argv_array, g_strdup ("-I"));
  g_ptr_array_add (argv_array, g_strdup (app));
  g_ptr_array_add (argv_array, g_file_get_path (runtime_files));

  g_ptr_array_add (argv_array, g_strdup (command));
  for (i = 1; i < rest_argc; i++)
    g_ptr_array_add (argv_array, g_strdup (argv[rest_argv_start + i]));

  g_ptr_array_add (argv_array, NULL);

  envp = g_get_environ ();
  envp = xdg_app_run_apply_env_default (envp);

  envp = xdg_app_run_apply_env_vars (envp, app_context);

  envp = xdg_app_run_apply_env_appid (envp, app_id_dir);

  if (execvpe (HELPER, (char **)argv_array->pdata, envp) == -1)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to start app");
      return FALSE;
    }

  /* Not actually reached... */
  return TRUE;
}