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);
}
Ejemplo n.º 2
0
/* The GNOME 3 Shell holds an X grab when we're in the overview;
 * ask it to bounce out before we try locking the screen.
 */
static void
request_shell_exit_overview (GSGrab *grab)
{
        GDBusMessage *message;

        /* Shouldn't happen, but... */
        if (!grab->priv->session_bus)
                return;

        message = g_dbus_message_new_method_call ("org.gnome.Shell",
                                                  "/org/gnome/Shell",
                                                  "org.freedesktop.DBus.Properties",
                                                  "Set");
        g_dbus_message_set_body (message,
                                 g_variant_new ("(ssv)",
                                                "org.gnome.Shell",
                                                "OverviewActive",
                                                g_variant_new ("b",
                                                               FALSE)));

        g_dbus_connection_send_message (grab->priv->session_bus,
                                        message,
                                        G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                        NULL,
                                        NULL);
        g_object_unref (message);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
void
arv_rtkit_make_high_priority (GDBusConnection *connection, pid_t thread, int nice_level, GError **error)
{
	GDBusMessage *message;
	GDBusMessage *reply;
	GError *local_error = NULL;

	message = g_dbus_message_new_method_call (RTKIT_SERVICE_NAME,
						  RTKIT_OBJECT_PATH,
						  "org.freedesktop.RealtimeKit1",
						  "MakeThreadHighPriority");
	g_dbus_message_set_body (message, g_variant_new ("(ti)", thread, nice_level));

	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;
	}

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

	g_object_unref (reply);
}
Ejemplo n.º 5
0
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;
}
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
void bluez_unregister_watcher(GDBusConnection* conn, const gchar* service_path)
{
    GError* error = NULL;

    GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez",
                                                       service_path,
                                                       "org.bluez.Characteristic",
                                                       "UnregisterCharacteristicsWatcher");
    if(call_message == NULL)
    {
        printf("g_dbus_message_new_method_call failed\n");

        return;
    }

    gchar path[255];
    g_snprintf(path, 255, "/test/bluez/%d", getpid());

    GVariant* variant_addr = g_variant_new_object_path(path);
    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)
    {
        printf("g_dbus_connection_send_message_with_reply_sync failed\n");

        return;
    }

    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;
    }

    // cleanup
    g_object_unref(call_message);
    g_object_unref(reply_message);
}
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;
}
Ejemplo n.º 11
0
static CloudSpyDispatcherInvocation *
cloud_spy_dispatcher_invocation_new (GDBusMethodInfo * method, GVariant * parameters, GSimpleAsyncResult * res)
{
  CloudSpyDispatcherInvocation * invocation;

  invocation = g_slice_new (CloudSpyDispatcherInvocation);
  invocation->magic = &cloud_spy_dispatcher_magic;

  invocation->ref_count = 1;

  invocation->method = g_dbus_method_info_ref (method);
  invocation->parameters = g_variant_ref (parameters);
  invocation->res = res;

  invocation->call_message = g_dbus_message_new_method_call (NULL, "/org/boblycat/frida/Foo", "org.boblycat.Frida.Foo", method->name);
  g_dbus_message_set_serial (invocation->call_message, 1);

  return invocation;
}
/* see gdbus-example-server.c for the server implementation */
static gint
get_server_stdout (GDBusConnection  *connection,
                   const gchar      *name_owner,
                   GError          **error)
{
  GDBusMessage *method_call_message;
  GDBusMessage *method_reply_message;
  GUnixFDList *fd_list;
  gint fd;

  fd = -1;
  method_call_message = NULL;
  method_reply_message = NULL;

  method_call_message = g_dbus_message_new_method_call (name_owner,
                                                        "/org/gtk/GDBus/TestObject",
                                                        "org.gtk.GDBus.TestInterface",
                                                        "GimmeStdout");
  method_reply_message = g_dbus_connection_send_message_with_reply_sync (connection,
                                                                         method_call_message,
                                                                         -1,
                                                                         NULL, /* out_serial */
                                                                         NULL, /* cancellable */
                                                                         error);
  if (method_reply_message == NULL)
      goto out;

  if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
      g_dbus_message_to_gerror (method_reply_message, error);
      goto out;
    }

  fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
  fd = g_unix_fd_list_get (fd_list, 0, error);

 out:
  g_object_unref (method_call_message);
  g_object_unref (method_reply_message);

  return fd;
}
Ejemplo n.º 13
0
static void steadyflow_iapp_service_proxy_set_visible (SteadyflowIAppService* self, gboolean visible, GError** error) {
	GDBusMessage *_message;
	GVariant *_arguments;
	GVariantBuilder _arguments_builder;
	GDBusMessage *_reply_message;
	G_IO_ERROR;
	_message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "net.launchpad.steadyflow.App", "SetVisible");
	g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE);
	g_variant_builder_add_value (&_arguments_builder, g_variant_new_boolean (visible));
	_arguments = g_variant_builder_end (&_arguments_builder);
	g_dbus_message_set_body (_message, _arguments);
	_reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error);
	g_object_unref (_message);
	if (!_reply_message) {
		return;
	}
	if (g_dbus_message_to_gerror (_reply_message, error)) {
		g_object_unref (_reply_message);
		return;
	}
	g_object_unref (_reply_message);
}
Ejemplo n.º 14
0
static gint
gdkevent_poll (GPollFD *ufds,
               guint    nfds,
               gint     timeout_)
{
	GDBusMessage *message;
	GVariant *body;
	GError *error = NULL;
	GTimeVal now;
	long diff;
	gint ret;

	g_get_current_time(&now);
	diff = time_val_difference(&now, &last_time);

	/* Log if the delay was more than a tenth of a second */
	if (diff > (G_USEC_PER_SEC / 10)) {
		message = g_dbus_message_new_method_call(NULL, "/",
		                                         "org.perfkit.Agent.GdkEvent",
		                                         "Delay");
		body = g_variant_new("(dd)",
		                     TV2DOUBLE(last_time),
		                     TV2DOUBLE(now));
		g_dbus_message_set_body(message, body);
		if (!g_dbus_connection_send_message(connection, message,
		                                    G_DBUS_SEND_MESSAGE_FLAGS_NONE,
		                                    NULL, &error)) {
			CRITICAL(Gdk, "Error sending message: %s", error->message);
			g_error_free(error);
		}
	}

	ret = poll_func(ufds, nfds, timeout_);

	g_get_current_time(&now);
	last_time = now;

	return ret;
}
Ejemplo n.º 15
0
static void
writeback_cancel_remote_operation (GCancellable      *cancellable,
                                   WritebackFileData *data)
{
	TrackerWritebackDispatcherPrivate *priv;
	GDBusMessage *message;
        gchar *uris[2];

	priv = TRACKER_WRITEBACK_DISPATCHER_GET_PRIVATE (data->self);

	uris[0] = g_file_get_uri (data->file);
	uris[1] = NULL;

	message = g_dbus_message_new_method_call (TRACKER_WRITEBACK_SERVICE,
	                                          TRACKER_WRITEBACK_PATH,
	                                          TRACKER_WRITEBACK_INTERFACE,
	                                          "CancelTasks");

	g_dbus_message_set_body (message, g_variant_new ("(^as)", uris));
	g_dbus_connection_send_message (priv->d_connection, message,
	                                G_DBUS_SEND_MESSAGE_FLAGS_NONE,
	                                NULL, NULL);
	g_free (uris[0]);
}
Ejemplo n.º 16
0
static void
send_close (FilechooserPortalData *data)
{
  GDBusMessage *message;
  GError *error = NULL;

  message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop",
                                            "/org/freedesktop/portal/desktop",
                                            "org.freedesktop.portal.FileChooser",
                                            "Close");
  g_dbus_message_set_body (message,
                           g_variant_new ("(o)", data->portal_handle));

  if (!g_dbus_connection_send_message (data->connection,
                                       message,
                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                       NULL, &error))
    {
      g_warning ("unable to send FileChooser Close message: %s", error->message);
      g_error_free (error);
    }

  g_object_unref (message);
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
/**
 * fu_util_refresh_internal:
 **/
static gboolean
fu_util_refresh_internal (FuUtilPrivate *priv,
				  const gchar *data_fn,
				  const gchar *sig_fn,
				  GError **error)
{
	GVariant *body;
	gint fd;
	gint fd_sig;
	_cleanup_object_unref_ GDBusMessage *request = NULL;
	_cleanup_object_unref_ GUnixFDList *fd_list = NULL;

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

	/* set out of band file descriptor */
	fd_list = g_unix_fd_list_new ();
	g_unix_fd_list_append (fd_list, fd, NULL);
	g_unix_fd_list_append (fd_list, fd_sig, NULL);
	request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
						  FWUPD_DBUS_PATH,
						  FWUPD_DBUS_INTERFACE,
						  "UpdateMetadata");
	g_dbus_message_set_unix_fd_list (request, fd_list);

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

	/* send message */
	body = g_variant_new ("(hh)", fd, fd_sig);
	g_dbus_message_set_body (request, body);
	g_dbus_connection_send_message_with_reply (priv->conn,
						   request,
						   G_DBUS_SEND_MESSAGE_FLAGS_NONE,
						   -1,
						   NULL,
						   NULL,
						   fu_util_update_cb,
						   priv);
	g_main_loop_run (priv->loop);
	if (priv->message == NULL) {
		g_dbus_error_strip_remote_error (priv->error);
		g_propagate_error (error, priv->error);
		return FALSE;
	}
	if (g_dbus_message_to_gerror (priv->message, error)) {
		g_dbus_error_strip_remote_error (*error);
		return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
gboolean
eas_gdbus_call (struct eas_gdbus_client *client, const gchar *object,
		const gchar *interface, const gchar *method,
		EasProgressFn progress_fn, gpointer progress_data,
		const gchar *in_params, const gchar *out_params,
		GCancellable *cancellable, GError **error, ...)
{
	GDBusMessage *message;
	struct _eas_call_data call;
	GMainContext *ctxt;
	GVariant *v = NULL;
	va_list ap;
	gboolean success;
	guint cancel_handler_id;
	guint32 serial = 0;

	va_start (ap, error);

	message = g_dbus_message_new_method_call (EAS_SERVICE_NAME, object,
						  interface, method);

	v = g_variant_new_va (in_params, NULL, &ap);
	g_dbus_message_set_body (message, v);

	call.cancelled = FALSE;
	call.result = NULL;
	ctxt = g_main_context_new ();
	call.loop = g_main_loop_new (ctxt, FALSE);

	g_main_context_push_thread_default (ctxt);

	g_dbus_connection_send_message_with_reply (client->connection,
						   message,
						   G_DBUS_SEND_MESSAGE_FLAGS_NONE,
						   1000000,
						   &serial,
						   cancellable,
						   _call_done,
						   (gpointer) &call);
	g_object_unref (message);

	if (cancellable)
		cancel_handler_id = g_cancellable_connect (cancellable,
							  G_CALLBACK (_call_cancel),
							  (gpointer) &call, NULL);

	/* Ignore error; it's not the end of the world if progress info
	   is lost, and it should never happen anyway */
	if (progress_fn)
		eas_client_add_progress_info_to_table (client, serial, progress_fn,
						       progress_data, NULL);

	g_main_loop_run (call.loop);

	if (cancellable)
		g_cancellable_disconnect (cancellable, cancel_handler_id);

	success = eas_gdbus_call_finish (client, call.result, call.cancelled ? serial : 0,
					 out_params, &ap, error);

	if (serial && progress_fn) {
		EasProgressCallbackInfo *cbinfo;

		g_mutex_lock (client->progress_lock);
		cbinfo = g_hash_table_lookup (client->progress_fns_table,
					      GUINT_TO_POINTER (serial));
		if (cbinfo && cbinfo->calling) {
			g_debug ("Progress for call %u is running; wait for it to complete",
				 serial);
			g_hash_table_steal (client->progress_fns_table,
					    GUINT_TO_POINTER (serial));
			do {
				g_cond_wait (client->progress_cond, client->progress_lock);
			} while (cbinfo->calling);
			g_free (cbinfo);
		} else if (cbinfo) {
			g_hash_table_remove (client->progress_fns_table,
					     GUINT_TO_POINTER (serial));
		}
		g_mutex_unlock (client->progress_lock);
	}

	va_end (ap);

	g_main_context_pop_thread_default (ctxt);
	g_main_context_unref (ctxt);
	g_main_loop_unref (call.loop);
	g_object_unref (call.result);

	return success;
}
Ejemplo n.º 21
0
/**
 * fu_util_install_internal:
 **/
static gboolean
fu_util_install_internal (FuUtilPrivate *priv, const gchar *id,
			  const gchar *filename, GError **error)
{
	GVariant *body;
	GVariantBuilder builder;
	gint retval;
	gint fd;
	_cleanup_object_unref_ GDBusMessage *request = NULL;
	_cleanup_object_unref_ GUnixFDList *fd_list = NULL;

	/* set options */
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
	g_variant_builder_add (&builder, "{sv}",
			       "reason", g_variant_new_string ("user-action"));
	g_variant_builder_add (&builder, "{sv}",
			       "filename", g_variant_new_string (filename));
	if (priv->flags & FU_PROVIDER_UPDATE_FLAG_OFFLINE) {
		g_variant_builder_add (&builder, "{sv}",
				       "offline", g_variant_new_boolean (TRUE));
	}
	if (priv->flags & FU_PROVIDER_UPDATE_FLAG_ALLOW_OLDER) {
		g_variant_builder_add (&builder, "{sv}",
				       "allow-older", g_variant_new_boolean (TRUE));
	}
	if (priv->flags & FU_PROVIDER_UPDATE_FLAG_ALLOW_REINSTALL) {
		g_variant_builder_add (&builder, "{sv}",
				       "allow-reinstall", g_variant_new_boolean (TRUE));
	}

	/* open file */
	fd = open (filename, O_RDONLY);
	if (fd < 0) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INVALID_FILE,
			     "failed to open %s",
			     filename);
		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,
						  "Install");
	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 ("(sha{sv})", id, fd > -1 ? 0 : -1, &builder);
	g_dbus_message_set_body (request, body);
	g_dbus_connection_send_message_with_reply (priv->conn,
						   request,
						   G_DBUS_SEND_MESSAGE_FLAGS_NONE,
						   -1,
						   NULL,
						   NULL,
						   fu_util_update_cb,
						   priv);
	g_main_loop_run (priv->loop);
	if (priv->message == NULL) {
		g_dbus_error_strip_remote_error (priv->error);
		g_propagate_error (error, priv->error);
		return FALSE;
	}
	if (g_dbus_message_to_gerror (priv->message, error)) {
		g_dbus_error_strip_remote_error (*error);
		return FALSE;
	}
	/* TRANSLATORS: update completed, no errors */
	g_print ("%s\n", _("Done!"));
	return TRUE;
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
0
static void
gdkevent_dispatcher (GdkEvent *event,
                     gpointer  data)
{
	GDBusMessage *message;
	GError *error = NULL;

	message = g_dbus_message_new_method_call(NULL, "/",
	                                         "org.perfkit.Agent.GdkEvent",
	                                         "Event");

	switch (event->type) {
   case GDK_TOUCH_BEGIN:
   case GDK_TOUCH_END:
   case GDK_TOUCH_UPDATE:
   case GDK_TOUCH_CANCEL:
	case GDK_NOTHING:
		break;
	case GDK_DELETE:
		gdkevent_handle_any(event, connection);
		break;
	case GDK_DESTROY:
		gdkevent_handle_destroy(event, connection);
		break;
	case GDK_EXPOSE:
		gdkevent_handle_expose(event, message, connection);
		break;
	case GDK_MOTION_NOTIFY:
		gdkevent_handle_motion_notfiy(event, connection);
		break;
	case GDK_BUTTON_PRESS:
	case GDK_2BUTTON_PRESS:
	case GDK_3BUTTON_PRESS:
	case GDK_BUTTON_RELEASE:
		gdkevent_handle_button(event, connection);
		break;
	case GDK_KEY_PRESS:
	case GDK_KEY_RELEASE:
		gdkevent_handle_key(event, connection);
		break;
	case GDK_ENTER_NOTIFY:
	case GDK_LEAVE_NOTIFY:
		gdkevent_handle_crossing(event, connection);
		break;
	case GDK_FOCUS_CHANGE:
		gdkevent_handle_focus(event, connection);
		break;
	case GDK_CONFIGURE:
		gdkevent_handle_configure(event, connection);
		break;
	case GDK_MAP:
	case GDK_UNMAP:
		gdkevent_handle_any(event, connection);
		break;
	case GDK_PROPERTY_NOTIFY:
	case GDK_SELECTION_CLEAR:
	case GDK_SELECTION_REQUEST:
	case GDK_SELECTION_NOTIFY:
	case GDK_PROXIMITY_IN:
	case GDK_PROXIMITY_OUT:
	case GDK_DRAG_ENTER:
	case GDK_DRAG_LEAVE:
	case GDK_DRAG_MOTION:
	case GDK_DRAG_STATUS:
	case GDK_DROP_START:
	case GDK_DROP_FINISHED:
	case GDK_CLIENT_EVENT:
	case GDK_VISIBILITY_NOTIFY:
#if !GTK_CHECK_VERSION(2, 91, 0)
	case GDK_NO_EXPOSE:
#endif
	case GDK_SCROLL:
	case GDK_WINDOW_STATE:
	case GDK_SETTING:
	case GDK_OWNER_CHANGE:
	case GDK_GRAB_BROKEN:
	case GDK_DAMAGE:
	case GDK_EVENT_LAST:
	default:
		/*
		 * TODO: Handle more of these specificaly.
		 */
		gdkevent_handle_any(event, connection);
		break;
	}

	if (!g_dbus_connection_send_message(connection, message,
	                                    G_DBUS_SEND_MESSAGE_FLAGS_NONE,
	                                    NULL, &error)) {
		CRITICAL(Gdk, "Error sending message: %s", error->message);
		g_error_free(error);
	}

	gtk_main_do_event(event);
}
Ejemplo n.º 24
0
gboolean
gtk_file_chooser_native_portal_show (GtkFileChooserNative *self)
{
  FilechooserPortalData *data;
  GtkWindow *transient_for;
  GDBusConnection *connection;
  char *parent_window_str;
  GDBusMessage *message;
  GVariantBuilder opt_builder;
  GtkFileChooserAction action;
  gboolean multiple;
  const char *method_name;

  if (!gtk_should_use_portal ())
    return FALSE;

  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (connection == NULL)
    return FALSE;

  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self));
  multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (self));

  if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
    method_name = "OpenFile";
  else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
    method_name = "SaveFile";
  else
    {
      g_warning ("GTK_FILE_CHOOSER_ACTION_%s is not supported by GtkFileChooserNativePortal", action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ? "SELECT_FOLDER" : "CREATE_FOLDER");
      return FALSE;
    }

  data = g_new0 (FilechooserPortalData, 1);
  data->self = g_object_ref (self);
  data->connection = connection;

  message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop",
                                            "/org/freedesktop/portal/desktop",
                                            "org.freedesktop.portal.FileChooser",
                                            method_name);

  parent_window_str = NULL;
  transient_for = gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG (self));
  if (transient_for != NULL && gtk_widget_is_visible (GTK_WIDGET (transient_for)))
    {
      GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (transient_for));
#ifdef GDK_WINDOWING_X11
      if (GDK_IS_X11_WINDOW(window))
        parent_window_str = g_strdup_printf ("x11:%x", (guint32)gdk_x11_window_get_xid (window));
#endif
    }

  if (gtk_native_dialog_get_modal (GTK_NATIVE_DIALOG (self)))
    data->modal = TRUE;

  if (data->modal && transient_for != NULL)
    {
      data->grab_widget = gtk_invisible_new_for_screen (gtk_widget_get_screen (GTK_WIDGET (transient_for)));
      gtk_grab_add (GTK_WIDGET (data->grab_widget));
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
  g_variant_builder_add (&opt_builder, "{sv}", "multiple",
                         g_variant_new_boolean (multiple));
  if (self->accept_label)
    g_variant_builder_add (&opt_builder, "{sv}", "accept_label",
                           g_variant_new_string (self->accept_label));
  if (self->cancel_label)
    g_variant_builder_add (&opt_builder, "{sv}", "cancel_label",
                           g_variant_new_string (self->cancel_label));
  g_variant_builder_add (&opt_builder, "{sv}", "modal",
                         g_variant_new_boolean (data->modal));
  g_variant_builder_add (&opt_builder, "{sv}", "filters", get_filters (GTK_FILE_CHOOSER (self)));
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_name)
    g_variant_builder_add (&opt_builder, "{sv}", "current_name",
                           g_variant_new_string (GTK_FILE_CHOOSER_NATIVE (self)->current_name));
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_folder)
    {
      gchar *path;

      path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_folder);
      g_variant_builder_add (&opt_builder, "{sv}", "current_folder",
                             g_variant_new_bytestring (path));
      g_free (path);
    }
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_file)
    {
      gchar *path;

      path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_file);
      g_variant_builder_add (&opt_builder, "{sv}", "current_file",
                             g_variant_new_bytestring (path));
      g_free (path);
    }

  if (GTK_FILE_CHOOSER_NATIVE (self)->choices)
    g_variant_builder_add (&opt_builder, "{sv}", "choices",
                           serialize_choices (GTK_FILE_CHOOSER_NATIVE (self)));

  g_dbus_message_set_body (message,
                           g_variant_new ("(ss@a{sv})",
                                          parent_window_str ? parent_window_str : "",
                                          gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (self)),
                                          g_variant_builder_end (&opt_builder)));
  g_free (parent_window_str);

  g_dbus_connection_send_message_with_reply (data->connection,
                                             message,
                                             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                             G_MAXINT,
                                             NULL,
                                             NULL,
                                             open_file_msg_cb,
                                             data);

  g_object_unref (message);

  self->mode_data = data;
  return TRUE;
}
Ejemplo n.º 25
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;
}
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;
}
Ejemplo n.º 27
0
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;
}