Esempio n. 1
0
static void take_inhibit_cb(GObject *source_object,
                            GAsyncResult *res,
                            gpointer user_data)
{
    GVariant *result = NULL;
    GError *error = NULL;
    GUnixFDList *fd_list;
    gint32 fd_index = 0;
    Context *context = (Context *)user_data;

    result = g_dbus_proxy_call_with_unix_fd_list_finish(context->proxy,
                                                        &fd_list,
                                                        res,
                                                        &error);
    if (!result) {
        log_warn("Error taking lid inhibitor lock: %s", error->message);
        g_error_free(error);
        return;
    }

    g_variant_get(result, "(h)", &fd_index);
    context->state.lid_inhibit_fd = g_unix_fd_list_get(fd_list, fd_index, &error);
    if (context->state.lid_inhibit_fd == -1) {
        log_warn("Error getting file descriptor for lid inhibitor lock: %s",
                 error->message);
        g_error_free(error);
    }
    g_variant_unref(result);
    g_object_unref(fd_list);
}
static void
inhibit_done (GObject      *source,
              GAsyncResult *result,
              gpointer      user_data)
{
    GDBusProxy *sd_proxy = G_DBUS_PROXY (source);
    NMSleepMonitor *self = user_data;
    GError *error = NULL;
    GVariant *res;
    GUnixFDList *fd_list;

    res = g_dbus_proxy_call_with_unix_fd_list_finish (sd_proxy, &fd_list, result, &error);
    if (!res) {
        g_dbus_error_strip_remote_error (error);
        nm_log_warn (LOGD_SUSPEND, "Inhibit failed: %s", error->message);
        g_error_free (error);
    } else {
        if (!fd_list || g_unix_fd_list_get_length (fd_list) != 1)
            nm_log_warn (LOGD_SUSPEND, "Didn't get a single fd back");

        self->inhibit_fd = g_unix_fd_list_get (fd_list, 0, NULL);

        nm_log_dbg (LOGD_SUSPEND, "Inhibitor fd is %d", self->inhibit_fd);
        g_object_unref (fd_list);
        g_variant_unref (res);
    }
}
Esempio n. 3
0
static GInputStream *
g_vfs_icon_load (GLoadableIcon  *icon,
                 int            size,
                 char          **type,
                 GCancellable   *cancellable,
                 GError        **error)
{
  GVfsIcon *vfs_icon = G_VFS_ICON (icon);
  GVfsDBusMount *proxy;
  gboolean res;
  gboolean can_seek;
  GUnixFDList *fd_list;
  int fd;
  GVariant *fd_id_val = NULL;
  GError *local_error = NULL;

  proxy = create_proxy_for_icon (vfs_icon, cancellable, error);
  if (proxy == NULL)
    return NULL;

  res = gvfs_dbus_mount_call_open_icon_for_read_sync (proxy,
                                                      vfs_icon->icon_id,
                                                      NULL,
                                                      &fd_id_val,
                                                      &can_seek,
                                                      &fd_list,
                                                      cancellable,
                                                      &local_error);
  
  if (! res)
    {
      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
      _g_propagate_error_stripped (error, local_error);
    }

  g_object_unref (proxy);

  if (! res)
    return NULL;
  
  if (fd_list == NULL || fd_id_val == NULL ||
      g_unix_fd_list_get_length (fd_list) != 1 ||
      (fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_id_val), NULL)) == -1)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Didn't get stream file descriptor"));
      return NULL;
    }

  g_variant_unref (fd_id_val);
  g_object_unref (fd_list);
  
  return G_INPUT_STREAM (g_daemon_file_input_stream_new (fd, can_seek));
}
static gboolean
fu_plugin_thunderbolt_power_bolt_force_power (FuPlugin *plugin,
					      GError **error)
{
	FuPluginData *data = fu_plugin_get_data (plugin);
	g_autoptr(GDBusConnection) connection = NULL;
	g_autoptr(GDBusProxy) proxy = NULL;
	g_autoptr(GUnixFDList) fds = NULL;
	g_autoptr(GVariant) val = NULL;
	GVariant *input;

	input = g_variant_new ("(ss)",
				"fwupd",   /* who */
				"");       /* flags */

	connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
	if (connection == NULL)
		return FALSE;

	proxy = g_dbus_proxy_new_sync (connection,
					G_DBUS_PROXY_FLAGS_NONE,
					NULL,
					BOLT_DBUS_SERVICE,
					BOLT_DBUS_PATH,
					BOLT_DBUS_INTERFACE,
					NULL,
					error);
	if (proxy == NULL)
		return FALSE;

	val = g_dbus_proxy_call_with_unix_fd_list_sync (proxy,
							"ForcePower",
							input,
							G_DBUS_CALL_FLAGS_NONE,
							-1,
							NULL,
							&fds,
							NULL,
							error);

	if (val == NULL)
		return FALSE;

	if (g_unix_fd_list_get_length (fds) != 1) {
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
				"invalid number of file descriptors returned: %d",
				g_unix_fd_list_get_length (fds));
		return FALSE;
	}
	data->bolt_fd = g_unix_fd_list_get (fds, 0, NULL);

	return TRUE;
}
Esempio n. 5
0
static VALUE
unixfdlist_get(VALUE self, VALUE index)
{
        GError *error = NULL;
        gint fd;

        fd = g_unix_fd_list_get(_SELF(self), RVAL2GINT(index), &error);
        if (fd == -1)
                rbgio_raise_error(error);

        /* TODO: This fd must be closed properly.  How do we deal with that? */
        return FD2RVAL(fd);
}
Esempio n. 6
0
static void
set_running_settings (OfficeRunner *run,
		      gboolean      running)
{
	if (running) {
		GVariant *ret;
		GUnixFDList *fd_list;
		gint idx;
		GError *error = NULL;

		if (run->lid_switch_fd != -1) {
			g_debug ("Already blocked");
			return;
		}
		g_debug ("Blocking lid action");

		ret = g_dbus_connection_call_with_unix_fd_list_sync (run->connection,
								     LOGIND_DBUS_NAME,
								     LOGIND_DBUS_PATH,
								     LOGIND_DBUS_INTERFACE,
								     "Inhibit",
								     g_variant_new ("(ssss)", "handle-lid-switch", g_get_user_name(), _("Office Runner is running"), "block"),
								     NULL,
								     G_DBUS_CALL_FLAGS_NONE,
								     -1,
								     NULL,
								     &fd_list,
								     NULL,
								     &error);

		if (ret == NULL)
			g_error ("Failed to inhibit: %s", error->message);
		g_variant_get (ret, "(h)", &idx);
		run->lid_switch_fd = g_unix_fd_list_get (fd_list, idx, NULL);

		g_object_unref (fd_list);
		g_variant_unref (ret);
	} else {
		if (run->lid_switch_fd != -1) {
			close (run->lid_switch_fd);
			run->lid_switch_fd = -1;

			g_debug ("Unblocking lid action");
		} else {
			g_debug ("Already released the blocking inhibitor");
		}
	}
}
/* 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;
}
Esempio n. 8
0
static void
open_icon_read_cb (GVfsDBusMount *proxy,
                   GAsyncResult *res,
                   gpointer user_data)
{
  AsyncPathCall *data = user_data;
  GError *error = NULL;
  gboolean can_seek;
  GUnixFDList *fd_list;
  int fd;
  GVariant *fd_id_val;
  guint fd_id;
  GFileInputStream *stream;

  if (! gvfs_dbus_mount_call_open_icon_for_read_finish (proxy, &fd_id_val, &can_seek, &fd_list, res, &error))
    {
      _g_simple_async_result_take_error_stripped (data->result, error);
      goto out;
    }

  fd_id = g_variant_get_handle (fd_id_val);
  g_variant_unref (fd_id_val);

  if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1 ||
      (fd = g_unix_fd_list_get (fd_list, fd_id, NULL)) == -1)
    {
      g_simple_async_result_set_error (data->result,
                                       G_IO_ERROR, G_IO_ERROR_FAILED,
                                       _("Couldn't get stream file descriptor"));
    }
  else
    {
      stream = g_daemon_file_input_stream_new (fd, can_seek);
      g_simple_async_result_set_op_res_gpointer (data->result, stream, g_object_unref);
      g_object_unref (fd_list);
    }

out:
  _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
  _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
  async_path_call_free (data);
}
Esempio n. 9
0
static gboolean
handle_trash_file (XdpTrash *object,
                   GDBusMethodInvocation *invocation,
                   GUnixFDList *fd_list,
                   GVariant *arg_fd)
{
  Request *request = request_from_invocation (invocation);
  int idx, fd;
  guint result;

  REQUEST_AUTOLOCK (request);

  g_variant_get (arg_fd, "h", &idx);
  fd = g_unix_fd_list_get (fd_list, idx, NULL);

  result = trash_file (request->app_info, request->sender, fd);

  xdp_trash_complete_trash_file (object, invocation, NULL, result);

  return TRUE;
}
Esempio n. 10
0
/**
 * udisks_daemon_util_inhibit_system_sync:
 * @reason: A human readable explanation of why the system is being inhibited.
 *
 * Tries to inhibit the system.
 *
 * Right now only
 * <ulink url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">systemd</ulink>
 * inhibitors are supported but other inhibitors can be added in the future.
 *
 * Returns: A cookie that can be used with udisks_daemon_util_uninhibit_system_sync().
 */
UDisksInhibitCookie *
udisks_daemon_util_inhibit_system_sync (const gchar  *reason)
{
#ifdef HAVE_LIBSYSTEMD_LOGIN
  UDisksInhibitCookie *ret = NULL;
  GDBusConnection *connection = NULL;
  GVariant *value = NULL;
  GUnixFDList *fd_list = NULL;
  gint32 index = -1;
  GError *error = NULL;

  g_return_val_if_fail (reason != NULL, NULL);

  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
  if (connection == NULL)
    {
      udisks_error ("Error getting system bus: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      goto out;
    }

  value = g_dbus_connection_call_with_unix_fd_list_sync (connection,
                                                         "org.freedesktop.login1",
                                                         "/org/freedesktop/login1",
                                                         "org.freedesktop.login1.Manager",
                                                         "Inhibit",
                                                         g_variant_new ("(ssss)",
                                                                        "sleep:shutdown:idle", /* what */
                                                                        "Disk Manager",        /* who */
                                                                        reason,                /* why */
                                                                        "block"),              /* mode */
                                                         G_VARIANT_TYPE ("(h)"),
                                                         G_DBUS_CALL_FLAGS_NONE,
                                                         -1,       /* default timeout */
                                                         NULL,     /* fd_list */
                                                         &fd_list, /* out_fd_list */
                                                         NULL, /* GCancellable */
                                                         &error);
  if (value == NULL)
    {
      udisks_error ("Error inhibiting: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      goto out;
    }

  g_variant_get (value, "(h)", &index);
  g_assert (index >= 0 && index < g_unix_fd_list_get_length (fd_list));

  ret = g_new0 (UDisksInhibitCookie, 1);
  ret->magic = 0xdeadbeef;
  ret->fd = g_unix_fd_list_get (fd_list, index, &error);
  if (ret->fd == -1)
    {
      udisks_error ("Error getting fd: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      g_free (ret);
      ret = NULL;
      goto out;
    }

 out:
  if (value != NULL)
    g_variant_unref (value);
  g_clear_object (&fd_list);
  g_clear_object (&connection);
  return ret;
#else
  /* non-systemd: just return a dummy pointer */
  g_return_val_if_fail (reason != NULL, NULL);
  return (UDisksInhibitCookie* ) &udisks_daemon_util_inhibit_system_sync;
#endif
}
Esempio n. 11
0
/* runs in thread dedicated to handling @invocation */
static gboolean
handle_loop_setup (StoragedManager          *object,
                   GDBusMethodInvocation    *invocation,
                   GUnixFDList              *fd_list,
                   GVariant                 *fd_index,
                   GVariant                 *options)
{
  StoragedLinuxManager *manager = STORAGED_LINUX_MANAGER (object);
  GError *error;
  gint fd_num;
  gint fd = -1;
  gchar proc_path[64];
  gchar path[8192];
  ssize_t path_len;
  gint loop_fd = -1;
  gint loop_control_fd = -1;
  gint allocated_loop_number = -1;
  gchar *loop_device = NULL;
  struct loop_info64 li64;
  StoragedObject *loop_object = NULL;
  gboolean option_read_only = FALSE;
  gboolean option_no_part_scan = FALSE;
  guint64 option_offset = 0;
  guint64 option_size = 0;
  uid_t caller_uid;
  struct stat fd_statbuf;
  gboolean fd_statbuf_valid = FALSE;
  WaitForLoopData wait_data;

  /* we need the uid of the caller for the loop file */
  error = NULL;
  if (!storaged_daemon_util_get_caller_uid_sync (manager->daemon, invocation, NULL /* GCancellable */, &caller_uid, NULL, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      goto out;
    }

  /* Check if the user is authorized to create a loop device */
  if (!storaged_daemon_util_check_authorization_sync (manager->daemon,
                                                      NULL,
                                                      "org.storaged.Storaged.loop-setup",
                                                      options,
                                                      /* Translators: Shown in authentication dialog when the user
                                                       * requests setting up a loop device.
                                                       */
                                                      N_("Authentication is required to set up a loop device"),
                                                      invocation))
    goto out;

  fd_num = g_variant_get_handle (fd_index);
  if (fd_list == NULL || fd_num >= g_unix_fd_list_get_length (fd_list))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Expected to use fd at index %d, but message has only %d fds",
                                             fd_num,
                                             fd_list == NULL ? 0 : g_unix_fd_list_get_length (fd_list));
      goto out;
    }
  error = NULL;
  fd = g_unix_fd_list_get (fd_list, fd_num, &error);
  if (fd == -1)
    {
      g_prefix_error (&error, "Error getting file descriptor %d from message: ", fd_num);
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  snprintf (proc_path, sizeof (proc_path), "/proc/%d/fd/%d", getpid (), fd);
  path_len = readlink (proc_path, path, sizeof (path) - 1);
  if (path_len < 1)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Error determing path: %m");
      goto out;
    }
  path[path_len] = '\0';

  g_variant_lookup (options, "read-only", "b", &option_read_only);
  g_variant_lookup (options, "offset", "t", &option_offset);
  g_variant_lookup (options, "size", "t", &option_size);
  g_variant_lookup (options, "no-part-scan", "b", &option_no_part_scan);

  /* it's not a problem if fstat fails... for example, this can happen if the user
   * passes a fd to a file on the GVfs fuse mount
   */
  if (fstat (fd, &fd_statbuf) == 0)
    fd_statbuf_valid = TRUE;

  /* serialize access to /dev/loop-control */
  g_mutex_lock (&(manager->lock));

  loop_control_fd = open ("/dev/loop-control", O_RDWR);
  if (loop_control_fd == -1)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Error opening /dev/loop-control: %m");
      g_mutex_unlock (&(manager->lock));
      goto out;
    }

  allocated_loop_number = ioctl (loop_control_fd, LOOP_CTL_GET_FREE);
  if (allocated_loop_number < 0)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Error allocating free loop device: %m");
      g_mutex_unlock (&(manager->lock));
      goto out;
    }

  loop_device = g_strdup_printf ("/dev/loop%d", allocated_loop_number);
  loop_fd = open (loop_device, option_read_only ? O_RDONLY : O_RDWR);
  if (loop_fd == -1)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Cannot open %s: %m", loop_device);
      g_mutex_unlock (&(manager->lock));
      goto out;
    }

  /* update the loop file - need to do this before getting the uevent for the device  */
  storaged_state_add_loop (storaged_daemon_get_state (manager->daemon),
                           loop_device,
                           path,
                           fd_statbuf_valid ? fd_statbuf.st_dev : 0,
                           caller_uid);

  memset (&li64, '\0', sizeof (li64));
  strncpy ((char *) li64.lo_file_name, path, LO_NAME_SIZE - 1);
  if (option_read_only)
    li64.lo_flags |= LO_FLAGS_READ_ONLY;
  if (!option_no_part_scan)
    li64.lo_flags |= 8; /* Use LO_FLAGS_PARTSCAN when 3.2 has been out for a while */
  li64.lo_offset = option_offset;
  li64.lo_sizelimit = option_size;
  if (ioctl (loop_fd, LOOP_SET_FD, fd) < 0 || ioctl (loop_fd, LOOP_SET_STATUS64, &li64) < 0)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             STORAGED_ERROR,
                                             STORAGED_ERROR_FAILED,
                                             "Error setting up loop device %s: %m",
                                             loop_device);
      g_mutex_unlock (&(manager->lock));
      goto out;
    }
  g_mutex_unlock (&(manager->lock));

  /* Determine the resulting object */
  error = NULL;
  wait_data.loop_device = loop_device;
  wait_data.path = path;
  loop_object = storaged_daemon_wait_for_object_sync (manager->daemon,
                                                    wait_for_loop_object,
                                                    &wait_data,
                                                    NULL,
                                                    10, /* timeout_seconds */
                                                    &error);
  if (loop_object == NULL)
    {
      g_prefix_error (&error,
                      "Error waiting for loop object after creating %s",
                      loop_device);
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  storaged_notice ("Set up loop device %s (backed by %s)",
                   loop_device,
                   path);

  storaged_manager_complete_loop_setup (object,
                                        invocation,
                                        NULL, /* fd_list */
                                        g_dbus_object_get_object_path (G_DBUS_OBJECT (loop_object)));

 out:
  if (loop_object != NULL)
    g_object_unref (loop_object);
  g_free (loop_device);
  if (loop_control_fd != -1)
    close (loop_control_fd);
  if (loop_fd != -1)
    close (loop_fd);
  if (fd != -1)
    close (fd);
  return TRUE; /* returning TRUE means that we handled the method invocation */
}