<commit_before>/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* gvfs - extensions for gio
 *
 * Copyright (C) 2006-2012 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>

#ifdef HAVE_KEYRING
#include <gnome-keyring.h>
#endif

#include "gvfsudisks2drive.h"
#include "gvfsudisks2volume.h"
#include "gvfsudisks2mount.h"
#include "gvfsudisks2utils.h"

typedef struct _GVfsUDisks2VolumeClass GVfsUDisks2VolumeClass;

struct _GVfsUDisks2VolumeClass
{
  GObjectClass parent_class;
};

struct MountData;
typedef struct MountData MountData;

static void mount_cancel_pending_op (MountData *data);

struct _GVfsUDisks2Volume
{
  GObject parent;

  GVfsUDisks2VolumeMonitor *monitor; /* owned by volume monitor */
  GVfsUDisks2Mount         *mount;   /* owned by volume monitor */
  GVfsUDisks2Drive         *drive;   /* owned by volume monitor */

  /* If TRUE, the volume was discovered at coldplug time */
  gboolean coldplug;

  /* exactly one of these are set */
  UDisksBlock *block;
  GUnixMountPoint *mount_point;

  /* set in update_volume() */
  GIcon *icon;
  GFile *activation_root;
  gchar *name;
  gchar *sort_key;
  gchar *device_file;
  dev_t dev;
  gchar *uuid;
  gboolean can_mount;
  gboolean should_automount;

  /* If a mount operation is in progress, then pending_mount_op is != NULL. This
   * is used to cancel the operation to make possible authentication dialogs go
   * away.
   */
  MountData *mount_pending_op;
};

static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);

static void on_block_changed (GObject    *object,
                              GParamSpec *pspec,
                              gpointer    user_data);

static void on_udisks_client_changed (UDisksClient *client,
                                      gpointer      user_data);

G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Volume, gvfs_udisks2_volume, G_TYPE_OBJECT, 0,
                        G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, gvfs_udisks2_volume_volume_iface_init))

static void
gvfs_udisks2_volume_finalize (GObject *object)
{
  GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (object);

  g_signal_handlers_disconnect_by_func (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                        G_CALLBACK (on_udisks_client_changed),
                                        volume);

  if (volume->mount != NULL)
    {
      gvfs_udisks2_mount_unset_volume (volume->mount, volume);
    }

  if (volume->drive != NULL)
    {
      gvfs_udisks2_drive_unset_volume (volume->drive, volume);
    }

  if (volume->block != NULL)
    {
      g_signal_handlers_disconnect_by_func (volume->block, G_CALLBACK (on_block_changed), volume);
      g_object_unref (volume->block);
    }

  if (volume->mount_point != NULL)
    g_unix_mount_point_free (volume->mount_point);

  if (volume->icon != NULL)
    g_object_unref (volume->icon);
  if (volume->activation_root != NULL)
    g_object_unref (volume->activation_root);

  g_free (volume->name);
  g_free (volume->sort_key);
  g_free (volume->device_file);
  g_free (volume->uuid);

  G_OBJECT_CLASS (gvfs_udisks2_volume_parent_class)->finalize (object);
}

static void
gvfs_udisks2_volume_class_init (GVfsUDisks2VolumeClass *klass)
{
  GObjectClass *gobject_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = gvfs_udisks2_volume_finalize;
}

static void
gvfs_udisks2_volume_init (GVfsUDisks2Volume *volume)
{
}

static void
emit_changed (GVfsUDisks2Volume *volume)
{
  g_signal_emit_by_name (volume, "changed");
  g_signal_emit_by_name (volume->monitor, "volume-changed", volume);
}

static void
apply_options_from_fstab (GVfsUDisks2Volume *volume,
                          const gchar       *fstab_options)
{
  gchar *name;
  gchar *icon_name;

  name = gvfs_udisks2_utils_lookup_fstab_options_value (fstab_options, "x-gvfs-name=");
  if (name != NULL)
    {
      g_free (volume->name);
      volume->name = name;
    }

  icon_name = gvfs_udisks2_utils_lookup_fstab_options_value (fstab_options, "x-gvfs-icon=");
  if (icon_name != NULL)
    {
      volume->icon = g_themed_icon_new_with_default_fallbacks (icon_name);
      g_free (icon_name);
    }
}

static gboolean
update_volume (GVfsUDisks2Volume *volume)
{
  gboolean changed;
  gboolean old_can_mount;
  gboolean old_should_automount;
  gchar *old_name;
  gchar *old_device_file;
  dev_t old_dev;
  GIcon *old_icon;
  UDisksDrive *udisks_drive;
  gchar *s;

  /* ---------------------------------------------------------------------------------------------------- */
  /* save old values */

  old_can_mount = volume->can_mount;
  old_should_automount = volume->should_automount;
  old_name = g_strdup (volume->name);
  old_device_file = g_strdup (volume->device_file);
  old_dev = volume->dev;
  old_icon = volume->icon != NULL ? g_object_ref (volume->icon) : NULL;

  /* ---------------------------------------------------------------------------------------------------- */
  /* reset */

  volume->can_mount = volume->should_automount = FALSE;
  g_free (volume->name); volume->name = NULL;
  g_free (volume->device_file); volume->device_file = NULL;
  volume->dev = 0;
  g_clear_object (&volume->icon);

  /* ---------------------------------------------------------------------------------------------------- */
  /* in with the new */

  if (volume->block != NULL)
    {
      const gchar *hint;
      UDisksBlock *block;
      UDisksBlock *cleartext_block;
      GVariantIter iter;
      const gchar *configuration_type;
      GVariant *configuration_value;
      UDisksLoop *loop = NULL;

      loop = udisks_client_get_loop_for_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                               volume->block);

      /* If unlocked, use the values from the unlocked block device for presentation */
      cleartext_block = udisks_client_get_cleartext_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                           volume->block);
      if (cleartext_block != NULL)
        block = cleartext_block;
      else
        block = volume->block;

      volume->dev = udisks_block_get_device_number (block);
      volume->device_file = udisks_block_dup_device (block);

      if (strlen (udisks_block_get_id_label (block)) > 0)
        {
          volume->name = g_strdup (udisks_block_get_id_label (block));
        }
      else if (g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0)
        {
          s = udisks_client_get_size_for_display (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                  udisks_block_get_size (volume->block), FALSE, FALSE);
          /* Translators: This is used for encrypted volumes.
           *              The first %s is the formatted size (e.g. "42.0 MB").
           */
          volume->name = g_strdup_printf (_("%s Encrypted"), s);
          g_free (s);
        }
      else
        {
          guint64 size = udisks_block_get_size (block);
          if (size > 0)
            {
              s = udisks_client_get_size_for_display (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                      size, FALSE, FALSE);
              /* Translators: This is used for volume with no filesystem label.
               *              The first %s is the formatted size (e.g. "42.0 MB").
               */
              volume->name = g_strdup_printf (_("%s Volume"), s);
              g_free (s);
            }
        }

      udisks_drive = udisks_client_get_drive_for_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                        volume->block);
      if (udisks_drive != NULL)
        {
          gchar *drive_desc;
          GIcon *drive_icon;
          gchar *media_desc;
          GIcon *media_icon;

          udisks_client_get_drive_info (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                        udisks_drive,
                                        NULL, /* drive_name */
                                        &drive_desc,
                                        &drive_icon,
                                        &media_desc,
                                        &media_icon);
          if (media_desc == NULL)
            {
              media_desc = drive_desc;
              drive_desc = NULL;
            }
          if (media_icon == NULL)
            {
              media_icon = drive_icon;
              drive_icon = NULL;
            }

          /* Override name for blank and audio discs */
          if (udisks_drive_get_optical_blank (udisks_drive))
            {
              g_free (volume->name);
              volume->name = g_strdup (media_desc);
            }
          else if (volume->activation_root != NULL && g_file_has_uri_scheme (volume->activation_root, "cdda"))
            {
              g_free (volume->name);
              volume->name = g_strdup (_("Audio Disc"));
            }

          volume->icon = media_icon != NULL ? g_object_ref (media_icon) : NULL;

          /* use media_desc if we haven't figured out a name yet (applies to e.g.
           * /dev/fd0 since its size is 0)
           */
          if (volume->name == NULL)
            {
              volume->name = media_desc;
              media_desc = NULL;
            }

          g_free (media_desc);
          if (media_icon != NULL)
            g_object_unref (media_icon);

          /* Only automount drives attached to the same seat as we're running on
           */
          if (gvfs_udisks2_utils_is_drive_on_our_seat (udisks_drive))
            {
              /* Only automount filesystems from drives of known types/interconnects:
               *
               *  - USB
               *  - Firewire
               *  - sdio
               *  - optical discs
               *
               * The mantra here is "be careful" - we really don't want to
               * automount filesystems from all devices in a SAN etc - We
               * REALLY need to be CAREFUL here.
               *
               * Fortunately udisks provides a property just for this.
               */
              if (udisks_block_get_hint_auto (volume->block))
                {
                  gboolean just_plugged_in = FALSE;
                  /* Also, if a volume (partition) appear _much later_ than when media was inserted it
                   * can only be because the media was repartitioned. We don't want to automount
                   * such volumes. So only mark volumes appearing just after their drive.
                   *
                   * There's a catch here - if the volume was discovered at coldplug-time (typically
                   * when the user desktop session started), we can't use this heuristic
                   */
                  if (g_get_real_time () - udisks_drive_get_time_media_detected (udisks_drive) < 5 * G_USEC_PER_SEC)
                    just_plugged_in = TRUE;
                  if (volume->coldplug || just_plugged_in)
                    volume->should_automount = TRUE;
                }
            }
          g_object_unref (udisks_drive);
        }

      /* Also automount loop devices set up by the user himself - e.g. via the
       * udisks interfaces or the gnome-disk-image-mounter(1) command
       */
      if (loop != NULL)
        {
          if (udisks_loop_get_setup_by_uid (loop) == getuid ())
            {
              volume->should_automount = TRUE;
            }
        }

      /* Use hints, if available */
      hint = udisks_block_get_hint_name (volume->block);
      if (hint != NULL && strlen (hint) > 0)
        {
          g_free (volume->name);
          volume->name = g_strdup (hint);
        }
      hint = udisks_block_get_hint_icon_name (volume->block);
      if (hint != NULL && strlen (hint) > 0)
        {
          g_clear_object (&volume->icon);
          volume->icon = g_themed_icon_new_with_default_fallbacks (hint);
        }

      /* Use x-gvfs-name=The%20Name and x-gvfs-icon=foo-name, if available */
      g_variant_iter_init (&iter, udisks_block_get_configuration (block));
      while (g_variant_iter_next (&iter, "(&s@a{sv})", &configuration_type, &configuration_value))
        {
          if (g_strcmp0 (configuration_type, "fstab") == 0)
            {
              const gchar *fstab_options;
              if (g_variant_lookup (configuration_value, "opts", "^&ay", &fstab_options))
                apply_options_from_fstab (volume, fstab_options);
            }
          g_variant_unref (configuration_value);
        }

      /* Add an emblem, depending on whether the encrypted volume is locked or unlocked */
      if (g_strcmp0 (udisks_block_get_id_type (volume->block), "crypto_LUKS") == 0 && volume->icon != NULL)
        {
          GEmblem *emblem;
          GIcon *padlock;
          GIcon *emblemed_icon;
          if (cleartext_block != NULL)
            padlock = g_themed_icon_new ("changes-allow");
          else
            padlock = g_themed_icon_new ("changes-prevent");
          emblem = g_emblem_new_with_origin (padlock, G_EMBLEM_ORIGIN_DEVICE);
          emblemed_icon = g_emblemed_icon_new (volume->icon, emblem);
          g_object_unref (padlock);
          g_object_unref (emblem);

          g_object_unref (volume->icon);
          volume->icon = emblemed_icon;
        }

      g_clear_object (&cleartext_block);
      g_clear_object (&loop);
    }
  else
    {
      apply_options_from_fstab (volume, g_unix_mount_point_get_options (volume->mount_point));
      if (volume->name == NULL)
        volume->name = g_unix_mount_point_guess_name (volume->mount_point);
      if (volume->icon == NULL)
        volume->icon = gvfs_udisks2_utils_icon_from_fs_type (g_unix_mount_point_get_fs_type (volume->mount_point));
    }

  if (volume->mount == NULL)<commit_msg>udisks2: ensure that encrypted loop devices also get padlock emblem<commit_after>/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* gvfs - extensions for gio
 *
 * Copyright (C) 2006-2012 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>

#ifdef HAVE_KEYRING
#include <gnome-keyring.h>
#endif

#include "gvfsudisks2drive.h"
#include "gvfsudisks2volume.h"
#include "gvfsudisks2mount.h"
#include "gvfsudisks2utils.h"

typedef struct _GVfsUDisks2VolumeClass GVfsUDisks2VolumeClass;

struct _GVfsUDisks2VolumeClass
{
  GObjectClass parent_class;
};

struct MountData;
typedef struct MountData MountData;

static void mount_cancel_pending_op (MountData *data);

struct _GVfsUDisks2Volume
{
  GObject parent;

  GVfsUDisks2VolumeMonitor *monitor; /* owned by volume monitor */
  GVfsUDisks2Mount         *mount;   /* owned by volume monitor */
  GVfsUDisks2Drive         *drive;   /* owned by volume monitor */

  /* If TRUE, the volume was discovered at coldplug time */
  gboolean coldplug;

  /* exactly one of these are set */
  UDisksBlock *block;
  GUnixMountPoint *mount_point;

  /* set in update_volume() */
  GIcon *icon;
  GFile *activation_root;
  gchar *name;
  gchar *sort_key;
  gchar *device_file;
  dev_t dev;
  gchar *uuid;
  gboolean can_mount;
  gboolean should_automount;

  /* If a mount operation is in progress, then pending_mount_op is != NULL. This
   * is used to cancel the operation to make possible authentication dialogs go
   * away.
   */
  MountData *mount_pending_op;
};

static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);

static void on_block_changed (GObject    *object,
                              GParamSpec *pspec,
                              gpointer    user_data);

static void on_udisks_client_changed (UDisksClient *client,
                                      gpointer      user_data);

G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Volume, gvfs_udisks2_volume, G_TYPE_OBJECT, 0,
                        G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, gvfs_udisks2_volume_volume_iface_init))

static void
gvfs_udisks2_volume_finalize (GObject *object)
{
  GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (object);

  g_signal_handlers_disconnect_by_func (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                        G_CALLBACK (on_udisks_client_changed),
                                        volume);

  if (volume->mount != NULL)
    {
      gvfs_udisks2_mount_unset_volume (volume->mount, volume);
    }

  if (volume->drive != NULL)
    {
      gvfs_udisks2_drive_unset_volume (volume->drive, volume);
    }

  if (volume->block != NULL)
    {
      g_signal_handlers_disconnect_by_func (volume->block, G_CALLBACK (on_block_changed), volume);
      g_object_unref (volume->block);
    }

  if (volume->mount_point != NULL)
    g_unix_mount_point_free (volume->mount_point);

  if (volume->icon != NULL)
    g_object_unref (volume->icon);
  if (volume->activation_root != NULL)
    g_object_unref (volume->activation_root);

  g_free (volume->name);
  g_free (volume->sort_key);
  g_free (volume->device_file);
  g_free (volume->uuid);

  G_OBJECT_CLASS (gvfs_udisks2_volume_parent_class)->finalize (object);
}

static void
gvfs_udisks2_volume_class_init (GVfsUDisks2VolumeClass *klass)
{
  GObjectClass *gobject_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = gvfs_udisks2_volume_finalize;
}

static void
gvfs_udisks2_volume_init (GVfsUDisks2Volume *volume)
{
}

static void
emit_changed (GVfsUDisks2Volume *volume)
{
  g_signal_emit_by_name (volume, "changed");
  g_signal_emit_by_name (volume->monitor, "volume-changed", volume);
}

static void
apply_options_from_fstab (GVfsUDisks2Volume *volume,
                          const gchar       *fstab_options)
{
  gchar *name;
  gchar *icon_name;

  name = gvfs_udisks2_utils_lookup_fstab_options_value (fstab_options, "x-gvfs-name=");
  if (name != NULL)
    {
      g_free (volume->name);
      volume->name = name;
    }

  icon_name = gvfs_udisks2_utils_lookup_fstab_options_value (fstab_options, "x-gvfs-icon=");
  if (icon_name != NULL)
    {
      volume->icon = g_themed_icon_new_with_default_fallbacks (icon_name);
      g_free (icon_name);
    }
}

static gboolean
update_volume (GVfsUDisks2Volume *volume)
{
  gboolean changed;
  gboolean old_can_mount;
  gboolean old_should_automount;
  gchar *old_name;
  gchar *old_device_file;
  dev_t old_dev;
  GIcon *old_icon;
  UDisksDrive *udisks_drive;
  gchar *s;

  /* ---------------------------------------------------------------------------------------------------- */
  /* save old values */

  old_can_mount = volume->can_mount;
  old_should_automount = volume->should_automount;
  old_name = g_strdup (volume->name);
  old_device_file = g_strdup (volume->device_file);
  old_dev = volume->dev;
  old_icon = volume->icon != NULL ? g_object_ref (volume->icon) : NULL;

  /* ---------------------------------------------------------------------------------------------------- */
  /* reset */

  volume->can_mount = volume->should_automount = FALSE;
  g_free (volume->name); volume->name = NULL;
  g_free (volume->device_file); volume->device_file = NULL;
  volume->dev = 0;
  g_clear_object (&volume->icon);

  /* ---------------------------------------------------------------------------------------------------- */
  /* in with the new */

  if (volume->block != NULL)
    {
      const gchar *hint;
      UDisksBlock *block;
      UDisksBlock *cleartext_block;
      GVariantIter iter;
      const gchar *configuration_type;
      GVariant *configuration_value;
      UDisksLoop *loop = NULL;

      loop = udisks_client_get_loop_for_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                               volume->block);

      /* If unlocked, use the values from the unlocked block device for presentation */
      cleartext_block = udisks_client_get_cleartext_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                           volume->block);
      if (cleartext_block != NULL)
        block = cleartext_block;
      else
        block = volume->block;

      volume->dev = udisks_block_get_device_number (block);
      volume->device_file = udisks_block_dup_device (block);

      if (strlen (udisks_block_get_id_label (block)) > 0)
        {
          volume->name = g_strdup (udisks_block_get_id_label (block));
        }
      else if (g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0)
        {
          s = udisks_client_get_size_for_display (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                  udisks_block_get_size (volume->block), FALSE, FALSE);
          /* Translators: This is used for encrypted volumes.
           *              The first %s is the formatted size (e.g. "42.0 MB").
           */
          volume->name = g_strdup_printf (_("%s Encrypted"), s);
          g_free (s);
        }
      else
        {
          guint64 size = udisks_block_get_size (block);
          if (size > 0)
            {
              s = udisks_client_get_size_for_display (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                      size, FALSE, FALSE);
              /* Translators: This is used for volume with no filesystem label.
               *              The first %s is the formatted size (e.g. "42.0 MB").
               */
              volume->name = g_strdup_printf (_("%s Volume"), s);
              g_free (s);
            }
        }

      udisks_drive = udisks_client_get_drive_for_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                                        volume->block);
      if (udisks_drive != NULL)
        {
          gchar *drive_desc;
          GIcon *drive_icon;
          gchar *media_desc;
          GIcon *media_icon;

          udisks_client_get_drive_info (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
                                        udisks_drive,
                                        NULL, /* drive_name */
                                        &drive_desc,
                                        &drive_icon,
                                        &media_desc,
                                        &media_icon);
          if (media_desc == NULL)
            {
              media_desc = drive_desc;
              drive_desc = NULL;
            }
          if (media_icon == NULL)
            {
              media_icon = drive_icon;
              drive_icon = NULL;
            }

          /* Override name for blank and audio discs */
          if (udisks_drive_get_optical_blank (udisks_drive))
            {
              g_free (volume->name);
              volume->name = g_strdup (media_desc);
            }
          else if (volume->activation_root != NULL && g_file_has_uri_scheme (volume->activation_root, "cdda"))
            {
              g_free (volume->name);
              volume->name = g_strdup (_("Audio Disc"));
            }

          volume->icon = media_icon != NULL ? g_object_ref (media_icon) : NULL;

          /* use media_desc if we haven't figured out a name yet (applies to e.g.
           * /dev/fd0 since its size is 0)
           */
          if (volume->name == NULL)
            {
              volume->name = media_desc;
              media_desc = NULL;
            }

          g_free (media_desc);
          if (media_icon != NULL)
            g_object_unref (media_icon);

          /* Only automount drives attached to the same seat as we're running on
           */
          if (gvfs_udisks2_utils_is_drive_on_our_seat (udisks_drive))
            {
              /* Only automount filesystems from drives of known types/interconnects:
               *
               *  - USB
               *  - Firewire
               *  - sdio
               *  - optical discs
               *
               * The mantra here is "be careful" - we really don't want to
               * automount filesystems from all devices in a SAN etc - We
               * REALLY need to be CAREFUL here.
               *
               * Fortunately udisks provides a property just for this.
               */
              if (udisks_block_get_hint_auto (volume->block))
                {
                  gboolean just_plugged_in = FALSE;
                  /* Also, if a volume (partition) appear _much later_ than when media was inserted it
                   * can only be because the media was repartitioned. We don't want to automount
                   * such volumes. So only mark volumes appearing just after their drive.
                   *
                   * There's a catch here - if the volume was discovered at coldplug-time (typically
                   * when the user desktop session started), we can't use this heuristic
                   */
                  if (g_get_real_time () - udisks_drive_get_time_media_detected (udisks_drive) < 5 * G_USEC_PER_SEC)
                    just_plugged_in = TRUE;
                  if (volume->coldplug || just_plugged_in)
                    volume->should_automount = TRUE;
                }
            }
          g_object_unref (udisks_drive);
        }

      /* Also automount loop devices set up by the user himself - e.g. via the
       * udisks interfaces or the gnome-disk-image-mounter(1) command
       */
      if (loop != NULL)
        {
          if (udisks_loop_get_setup_by_uid (loop) == getuid ())
            {
              volume->should_automount = TRUE;
            }
        }

      /* Use hints, if available */
      hint = udisks_block_get_hint_name (volume->block);
      if (hint != NULL && strlen (hint) > 0)
        {
          g_free (volume->name);
          volume->name = g_strdup (hint);
        }
      hint = udisks_block_get_hint_icon_name (volume->block);
      if (hint != NULL && strlen (hint) > 0)
        {
          g_clear_object (&volume->icon);
          volume->icon = g_themed_icon_new_with_default_fallbacks (hint);
        }

      /* Use x-gvfs-name=The%20Name and x-gvfs-icon=foo-name, if available */
      g_variant_iter_init (&iter, udisks_block_get_configuration (block));
      while (g_variant_iter_next (&iter, "(&s@a{sv})", &configuration_type, &configuration_value))
        {
          if (g_strcmp0 (configuration_type, "fstab") == 0)
            {
              const gchar *fstab_options;
              if (g_variant_lookup (configuration_value, "opts", "^&ay", &fstab_options))
                apply_options_from_fstab (volume, fstab_options);
            }
          g_variant_unref (configuration_value);
        }

      /* Add an emblem, depending on whether the encrypted volume is locked or unlocked */
      if (g_strcmp0 (udisks_block_get_id_type (volume->block), "crypto_LUKS") == 0)
        {
          GEmblem *emblem;
          GIcon *padlock;
          GIcon *emblemed_icon;

          if (volume->icon == NULL)
            volume->icon = g_themed_icon_new ("drive-removable-media");

          if (cleartext_block != NULL)
            padlock = g_themed_icon_new ("changes-allow");
          else
            padlock = g_themed_icon_new ("changes-prevent");
          emblem = g_emblem_new_with_origin (padlock, G_EMBLEM_ORIGIN_DEVICE);
          emblemed_icon = g_emblemed_icon_new (volume->icon, emblem);
          g_object_unref (padlock);
          g_object_unref (emblem);

          g_object_unref (volume->icon);
          volume->icon = emblemed_icon;
        }

      g_clear_object (&cleartext_block);
      g_clear_object (&loop);
    }
  else
    {
      apply_options_from_fstab (volume, g_unix_mount_point_get_options (volume->mount_point));
      if (volume->name == NULL)
        volume->name = g_unix_mount_point_guess_name (volume->mount_point);
      if (volume->icon == NULL)
        volume->icon = gvfs_udisks2_utils_icon_from_fs_type (g_unix_mount_point_get_fs_type (volume->mount_point));
    }

  if (volume->mount == NULL)
{'fraction_non_alphanumeric': 0.11059554012551742, 'fraction_numerical': 0.006108959807717986, 'mean_word_length': 2.029938302821887, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 210, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7570792', 'n_tokens_mistral': 9358, 'n_tokens_neox': 8914, 'n_words': 2140}