summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build7
-rw-r--r--meson_options.txt1
-rw-r--r--monitor/gdu/gdu-volume-monitor-daemon.c45
-rw-r--r--monitor/gdu/gdu.monitor5
-rw-r--r--monitor/gdu/ggdudrive.c1244
-rw-r--r--monitor/gdu/ggdudrive.h69
-rw-r--r--monitor/gdu/ggdumount.c1475
-rw-r--r--monitor/gdu/ggdumount.h64
-rw-r--r--monitor/gdu/ggduvolume.c1884
-rw-r--r--monitor/gdu/ggduvolume.h87
-rw-r--r--monitor/gdu/ggduvolumemonitor.c1812
-rw-r--r--monitor/gdu/ggduvolumemonitor.h67
-rw-r--r--monitor/gdu/gvfs-gdu-volume-monitor.service.in7
-rw-r--r--monitor/gdu/meson.build76
-rw-r--r--monitor/gdu/org.gtk.vfs.GduVolumeMonitor.service.in4
-rw-r--r--monitor/meson.build4
-rw-r--r--po/POTFILES.in4
-rw-r--r--test/meson.build4
18 files changed, 0 insertions, 6859 deletions
diff --git a/meson.build b/meson.build
index 2b6b3506..5b836c66 100644
--- a/meson.build
+++ b/meson.build
@@ -330,12 +330,6 @@ if enable_fuse
endif
config_h.set('HAVE_FUSE', enable_fuse)
-# *** Check for gnome-disk-utility ***
-enable_gdu = get_option('gdu')
-if enable_gdu
- gdu_dep = dependency('gdu', version: '>= 3.0.2')
-endif
-
# *** Check for udisks2 ***
enable_udisks2 = get_option('udisks2')
if enable_udisks2
@@ -522,7 +516,6 @@ output += ' afp: ' + enable_afp.to_string() + '\n'
output += ' archive: ' + enable_archive.to_string() + '\n'
output += ' cdda: ' + enable_cdda.to_string() + '\n'
output += ' dnssd: ' + enable_dnssd.to_string() + '\n'
-output += ' gdu: ' + enable_gdu.to_string() + '\n'
output += ' goa: ' + enable_goa.to_string() + '\n'
output += ' google: ' + enable_google.to_string() + '\n'
output += ' gphoto2: ' + enable_gphoto2.to_string() + '\n'
diff --git a/meson_options.txt b/meson_options.txt
index 66e2ade8..e4006dbe 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -7,7 +7,6 @@ option('afp', type: 'boolean', value: true, description: 'build with afp backend
option('archive', type: 'boolean', value: true, description: 'build with archive backend')
option('cdda', type: 'boolean', value: true, description: 'build with cdda backend')
option('dnssd', type: 'boolean', value: true, description: 'build with dnssd backend')
-option('gdu', type: 'boolean', value: false, description: 'build with gdu volume monitor')
option('goa', type: 'boolean', value: true, description: 'build with goa volume monitor')
option('google', type: 'boolean', value: true, description: 'build with google backend')
option('gphoto2', type: 'boolean', value: true, description: 'build with gphoto2 backend and volume monitor')
diff --git a/monitor/gdu/gdu-volume-monitor-daemon.c b/monitor/gdu/gdu-volume-monitor-daemon.c
deleted file mode 100644
index d2e87a7d..00000000
--- a/monitor/gdu/gdu-volume-monitor-daemon.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include <config.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-
-#include <gvfsproxyvolumemonitordaemon.h>
-
-#include "ggduvolumemonitor.h"
-
-int
-main (int argc, char *argv[])
-{
- g_vfs_proxy_volume_monitor_daemon_init ();
-
- g_set_application_name (_("GVfs GDU Volume Monitor"));
-
- return g_vfs_proxy_volume_monitor_daemon_main (argc,
- argv,
- "org.gtk.vfs.GduVolumeMonitor",
- G_TYPE_GDU_VOLUME_MONITOR);
-}
diff --git a/monitor/gdu/gdu.monitor b/monitor/gdu/gdu.monitor
deleted file mode 100644
index 25bf4131..00000000
--- a/monitor/gdu/gdu.monitor
+++ /dev/null
@@ -1,5 +0,0 @@
-[RemoteVolumeMonitor]
-Name=GProxyVolumeMonitorGdu
-DBusName=org.gtk.vfs.GduVolumeMonitor
-IsNative=true
-NativePriority=3
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
deleted file mode 100644
index aafd26c0..00000000
--- a/monitor/gdu/ggdudrive.c
+++ /dev/null
@@ -1,1244 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include <config.h>
-
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-
-#include "ggduvolumemonitor.h"
-#include "ggdudrive.h"
-#include "ggduvolume.h"
-
-struct _GGduDrive {
- GObject parent;
-
- GVolumeMonitor *volume_monitor; /* owned by volume monitor */
- GList *volumes; /* entries in list are owned by volume_monitor */
-
- GduPresentable *presentable;
-
- /* the following members need to be set upon construction */
- GIcon *icon;
- gchar *name;
- gchar *device_file;
- dev_t dev;
- gboolean is_media_removable;
- gboolean has_media;
- gboolean can_eject;
- gboolean can_poll_for_media;
- gboolean is_media_check_automatic;
-
- GDriveStartStopType start_stop_type;
- gboolean can_start;
- gboolean can_start_degraded;
- gboolean can_stop;
-};
-
-static void g_gdu_drive_drive_iface_init (GDriveIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GGduDrive, g_gdu_drive, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (G_TYPE_DRIVE,
- g_gdu_drive_drive_iface_init))
-
-static void presentable_changed (GduPresentable *presentable,
- GGduDrive *drive);
-
-static void presentable_job_changed (GduPresentable *presentable,
- GGduDrive *drive);
-
-static void
-g_gdu_drive_finalize (GObject *object)
-{
- GList *l;
- GGduDrive *drive;
-
- drive = G_GDU_DRIVE (object);
-
- for (l = drive->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- g_gdu_volume_unset_drive (volume, drive);
- }
-
- if (drive->presentable != NULL)
- {
- g_signal_handlers_disconnect_by_func (drive->presentable, presentable_changed, drive);
- g_signal_handlers_disconnect_by_func (drive->presentable, presentable_job_changed, drive);
- g_object_unref (drive->presentable);
- }
-
- if (drive->icon != NULL)
- g_object_unref (drive->icon);
- g_free (drive->name);
- g_free (drive->device_file);
-
- if (G_OBJECT_CLASS (g_gdu_drive_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_gdu_drive_parent_class)->finalize) (object);
-}
-
-static void
-g_gdu_drive_class_init (GGduDriveClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_gdu_drive_finalize;
-}
-
-static void
-g_gdu_drive_init (GGduDrive *gdu_drive)
-{
-}
-
-static void
-emit_changed (GGduDrive *drive)
-{
- g_signal_emit_by_name (drive, "changed");
- g_signal_emit_by_name (drive->volume_monitor, "drive_changed", drive);
-}
-
-static gboolean
-update_drive (GGduDrive *drive)
-{
- GduDevice *device;
- gboolean changed;
- GIcon *old_icon;
- gchar *old_name;
- gchar *old_device_file;
- dev_t old_dev;
- gboolean old_is_media_removable;
- gboolean old_has_media;
- gboolean old_can_eject;
- gboolean old_can_start;
- gboolean old_can_start_degraded;
- gboolean old_can_stop;
- gboolean old_start_stop_type;
- gboolean old_is_media_check_automatic;
- gboolean old_can_poll_for_media;
-
- /* save old values */
- old_is_media_removable = drive->is_media_removable;
- old_has_media = drive->has_media;
- old_can_eject = drive->can_eject;
- old_can_start = drive->can_start;
- old_can_start_degraded = drive->can_start_degraded;
- old_can_stop = drive->can_stop;
- old_start_stop_type = drive->start_stop_type;
- old_can_poll_for_media = drive->can_poll_for_media;
- old_is_media_check_automatic = drive->is_media_check_automatic;
-
- old_name = g_strdup (drive->name);
- old_device_file = g_strdup (drive->device_file);
- old_dev = drive->dev;
- old_icon = drive->icon != NULL ? g_object_ref (drive->icon) : NULL;
-
- /* in with the new */
- device = gdu_presentable_get_device (drive->presentable);
-
- if (drive->icon != NULL)
- g_object_unref (drive->icon);
- drive->icon = gdu_presentable_get_icon (drive->presentable);
-
- g_free (drive->name);
- if (_is_pc_floppy_drive (device))
- drive->name = g_strdup (_("Floppy Drive"));
- else
- drive->name = gdu_presentable_get_name (drive->presentable);
-
- /* It's perfectly fine to not have a GduDevice - for example, this is the case for non-running
- * MD RAID arrays as well as LVM2 Volume Group "drives"
- */
- if (device == NULL)
- {
- g_free (drive->device_file);
- drive->dev = 0;
- drive->device_file = NULL;
- drive->is_media_removable = FALSE;
- drive->has_media = TRUE;
- drive->can_eject = FALSE;
- drive->can_poll_for_media = FALSE;
- }
- else
- {
- g_free (drive->device_file);
- drive->dev = gdu_device_get_dev (device);
- drive->device_file = g_strdup (gdu_device_get_device_file (device));
- drive->is_media_removable = gdu_device_is_removable (device);
- drive->has_media = gdu_device_is_media_available (device);
- /* All drives with removable media are ejectable
- *
- * See http://bugzilla.gnome.org/show_bug.cgi?id=576587 for why we want this.
- *
- * See also below where we e.g. set can_eject to TRUE for non-removable drives.
- */
- drive->can_eject = ((gdu_device_drive_get_is_media_ejectable (device) || gdu_device_is_removable (device)) &&
- gdu_device_is_media_available (device) && ! _is_pc_floppy_drive (device)) ||
- gdu_device_drive_get_requires_eject (device);
- drive->is_media_check_automatic = gdu_device_is_media_change_detected (device);
- drive->can_poll_for_media = gdu_device_is_removable (device);
- }
-
- /* determine start/stop type */
- drive->can_stop = FALSE;
- drive->can_start = FALSE;
- drive->can_start_degraded = FALSE;
- drive->start_stop_type = G_DRIVE_START_STOP_TYPE_UNKNOWN;
- if (gdu_drive_is_activatable (GDU_DRIVE (drive->presentable)))
- {
- gboolean can_activate;
- gboolean degraded;
-
- can_activate = gdu_drive_can_activate (GDU_DRIVE (drive->presentable), &degraded);
-
- drive->can_stop = gdu_drive_can_deactivate (GDU_DRIVE (drive->presentable));
- drive->can_start = can_activate && !degraded;
- drive->can_start_degraded = can_activate && degraded;
- drive->start_stop_type = G_DRIVE_START_STOP_TYPE_MULTIDISK;
- }
- else if (device != NULL && gdu_device_drive_get_can_detach (device))
- {
- /* Ideally, for non-ejectable devices (e.g. non-cdrom, non-zip)
- * such as USB sticks we'd display "Eject" instead of "Shutdown"
- * since it is more familiar and the common case. The way this
- * should work is that after the Eject() method returns we call
- * Detach() - see eject_cb() below.
- *
- * (Note that it's not enough to just call Detach() since some
- * devices, such as the Kindle, only works with Eject(). So we
- * call them both in order).
- *
- * We actually used to do this (and that's why eject_cb() still
- * has this code) but some systems use internal USB devices for
- * e.g. SD card readers. If we were to detach these then the
- * user would have to power-cycle the system to get the device
- * back. See http://bugs.freedesktop.org/show_bug.cgi?id=24343
- * for more details.
- *
- * In the future, if we know for sure that a port is external
- * (like, from DMI data) we can go back to doing this. For now
- * the user will get all the options...
- */
- drive->can_stop = TRUE;
- drive->can_start = FALSE;
- drive->can_start_degraded = FALSE;
- drive->start_stop_type = G_DRIVE_START_STOP_TYPE_SHUTDOWN;
- }
-
- if (device != NULL)
- g_object_unref (device);
-
- /* Never use empty/blank names (#582772) */
- if (drive->name == NULL || strlen (drive->name) == 0)
- {
- if (drive->device_file != NULL)
- drive->name = g_strdup_printf (_("Unnamed Drive (%s)"), drive->device_file);
- else
- drive->name = g_strdup (_("Unnamed Drive"));
- }
-
- /* compute whether something changed */
- changed = !((old_is_media_removable == drive->is_media_removable) &&
- (old_has_media == drive->has_media) &&
- (old_can_eject == drive->can_eject) &&
- (old_can_start == drive->can_start) &&
- (old_can_start_degraded == drive->can_start_degraded) &&
- (old_can_stop == drive->can_stop) &&
- (old_start_stop_type == drive->start_stop_type) &&
- (old_is_media_check_automatic == drive->is_media_check_automatic) &&
- (old_can_poll_for_media == drive->can_poll_for_media) &&
- (g_strcmp0 (old_name, drive->name) == 0) &&
- (g_strcmp0 (old_device_file, drive->device_file) == 0) &&
- (old_dev == drive->dev) &&
- g_icon_equal (old_icon, drive->icon)
- );
-
- /* free old values */
- g_free (old_name);
- g_free (old_device_file);
- if (old_icon != NULL)
- g_object_unref (old_icon);
-
- /*g_debug ("in update_drive(); has_media=%d changed=%d", drive->has_media, changed);*/
-
- return changed;
-}
-
-static void
-presentable_changed (GduPresentable *presentable,
- GGduDrive *drive)
-{
- /*g_debug ("drive: presentable_changed: %p: %s", drive, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_drive (drive))
- emit_changed (drive);
-}
-
-static void
-presentable_job_changed (GduPresentable *presentable,
- GGduDrive *drive)
-{
- /*g_debug ("drive: presentable_job_changed: %p: %s", drive, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_drive (drive))
- emit_changed (drive);
-}
-
-GGduDrive *
-g_gdu_drive_new (GVolumeMonitor *volume_monitor,
- GduPresentable *presentable)
-{
- GGduDrive *drive;
-
- drive = g_object_new (G_TYPE_GDU_DRIVE, NULL);
- drive->volume_monitor = volume_monitor;
- g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(drive->volume_monitor));
-
- drive->presentable = g_object_ref (presentable);
-
- g_signal_connect (drive->presentable, "changed", G_CALLBACK (presentable_changed), drive);
- g_signal_connect (drive->presentable, "job-changed", G_CALLBACK (presentable_job_changed), drive);
-
- update_drive (drive);
-
- return drive;
-}
-
-void
-g_gdu_drive_disconnected (GGduDrive *drive)
-{
- GList *l, *volumes;
-
- volumes = drive->volumes;
- drive->volumes = NULL;
-
- for (l = volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- g_gdu_volume_unset_drive (volume, drive);
- }
-
- g_list_free (volumes);
-}
-
-void
-g_gdu_drive_set_volume (GGduDrive *drive,
- GGduVolume *volume)
-{
- if (g_list_find (drive->volumes, volume) == NULL)
- {
- drive->volumes = g_list_prepend (drive->volumes, volume);
- emit_changed (drive);
- }
-}
-
-void
-g_gdu_drive_unset_volume (GGduDrive *drive,
- GGduVolume *volume)
-{
- GList *l;
-
- l = g_list_find (drive->volumes, volume);
- if (l != NULL)
- {
- drive->volumes = g_list_delete_link (drive->volumes, l);
- emit_changed (drive);
- }
-}
-
-static GIcon *
-g_gdu_drive_get_icon (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->icon != NULL ? g_object_ref (drive->icon) : NULL;
-}
-
-static char *
-g_gdu_drive_get_name (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return g_strdup (drive->name);
-}
-
-static GList *
-g_gdu_drive_get_volumes (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GList *l;
-
- l = g_list_copy (drive->volumes);
- g_list_foreach (l, (GFunc) g_object_ref, NULL);
-
- return l;
-}
-
-static gboolean
-g_gdu_drive_has_volumes (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- gboolean res;
-
- res = drive->volumes != NULL;
-
- return res;
-}
-
-static gboolean
-g_gdu_drive_is_media_removable (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->is_media_removable;
-}
-
-static gboolean
-g_gdu_drive_has_media (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->has_media;
-}
-
-static gboolean
-g_gdu_drive_is_media_check_automatic (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->is_media_check_automatic;
-}
-
-static gboolean
-g_gdu_drive_can_eject (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->can_eject;
-}
-
-static gboolean
-g_gdu_drive_can_poll_for_media (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->can_poll_for_media;
-}
-
-static gboolean
-g_gdu_drive_can_start (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->can_start;
-}
-
-static gboolean
-g_gdu_drive_can_start_degraded (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->can_start_degraded;
-}
-
-static gboolean
-g_gdu_drive_can_stop (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->can_stop;
-}
-
-static GDriveStartStopType
-g_gdu_drive_get_start_stop_type (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- return drive->start_stop_type;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef void (*UnmountsMountsFunc) (GDrive *drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- gpointer on_all_unmounted_data);
-
-typedef struct {
- GDrive *drive;
- GAsyncReadyCallback callback;
- gpointer user_data;
- GMountOperation *mount_operation;
- GCancellable *cancellable;
- GMountUnmountFlags flags;
-
- GList *pending_mounts;
-
- UnmountsMountsFunc on_all_unmounted;
- gpointer on_all_unmounted_data;
-} UnmountMountsOp;
-
-static void
-free_unmount_mounts_op (UnmountMountsOp *data)
-{
- GList *l;
-
- for (l = data->pending_mounts; l != NULL; l = l->next)
- {
- GMount *mount = l->data;
- g_object_unref (mount);
- }
- g_list_free (data->pending_mounts);
-}
-
-static void
-unmount_mounts_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data);
-
-static void
-unmount_mounts_do (UnmountMountsOp *data)
-{
- if (data->pending_mounts == NULL)
- {
-
- /*g_warning ("all pending mounts done");*/
- data->on_all_unmounted (data->drive,
- data->cancellable,
- data->callback,
- data->user_data,
- data->on_all_unmounted_data);
-
- g_object_unref (data->drive);
- g_free (data);
- }
- else
- {
- GMount *mount;
-
- mount = data->pending_mounts->data;
- data->pending_mounts = g_list_remove (data->pending_mounts, mount);
-
- /*g_warning ("unmounting %p", mount);*/
-
- g_mount_unmount_with_operation (mount,
- data->flags,
- data->mount_operation,
- data->cancellable,
- unmount_mounts_cb,
- data);
- }
-}
-
-static void
-unmount_mounts_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- UnmountMountsOp *data = user_data;
- GMount *mount = G_MOUNT (source_object);
- GSimpleAsyncResult *simple;
- GError *error = NULL;
-
- if (!g_mount_unmount_with_operation_finish (mount, res, &error))
- {
- /* make the error dialog more targeted to the drive.. unless the user has already seen a dialog */
- if (error->code != G_IO_ERROR_FAILED_HANDLED)
- {
- g_error_free (error);
- error = g_error_new (G_IO_ERROR, G_IO_ERROR_BUSY,
- _("Failed to eject medium; one or more volumes on the medium are busy."));
- }
-
- /* unmount failed; need to fail the whole eject operation */
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
- data->callback,
- data->user_data,
- error);
- g_error_free (error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- free_unmount_mounts_op (data);
- }
- else
- {
-
- /*g_warning ("successfully unmounted %p", mount);*/
-
- /* move on to the next mount.. */
- unmount_mounts_do (data);
- }
-
- g_object_unref (mount);
-}
-
-static void
-unmount_mounts (GGduDrive *drive,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- UnmountsMountsFunc on_all_unmounted,
- gpointer on_all_unmounted_data)
-{
- GMount *mount;
- UnmountMountsOp *data;
- GList *l;
-
- data = g_new0 (UnmountMountsOp, 1);
- data->drive = g_object_ref (drive);
- data->mount_operation = mount_operation;
- data->cancellable = cancellable;
- data->callback = callback;
- data->user_data = user_data;
- data->flags = flags;
- data->on_all_unmounted = on_all_unmounted;
- data->on_all_unmounted_data = on_all_unmounted_data;
-
- for (l = drive->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- mount = g_volume_get_mount (G_VOLUME (volume));
- if (mount != NULL && g_mount_can_unmount (mount))
- data->pending_mounts = g_list_prepend (data->pending_mounts, g_object_ref (mount));
- }
-
- unmount_mounts_do (data);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-detach_after_eject_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
- /* Don't return an error here - this is because some devices, such as
- * the Kindle, can do Eject() but not Detach() e.g. the STOP UNIT
- * command or any other part of Detach() may fail.
- */
- if (error != NULL)
- {
- g_warning ("Detach() after Eject() failed with: %s", error->message);
- g_error_free (error);
- }
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-eject_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
- GGduDrive *drive;
- gboolean drive_detachable;
-
- drive = G_GDU_DRIVE (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
- drive_detachable = drive->can_stop == FALSE && drive->start_stop_type == G_DRIVE_START_STOP_TYPE_SHUTDOWN;
-
- if (error != NULL && error->code == G_IO_ERROR_FAILED &&
- drive_detachable && ! drive->has_media && drive->is_media_removable)
- {
- /* Silently drop the error if there's no media in drive and we're still trying to detach it (see below) */
- g_error_free (error);
- error = NULL;
- }
-
- if (error != NULL)
- {
- g_simple_async_result_set_from_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- g_error_free (error);
- goto out;
- }
-
- if (drive_detachable)
- {
- /* If device is not ejectable but it is detachable and we don't support stop(),
- * then also run Detach() after Eject() - see update_drive() for details for why...
- */
- gdu_device_op_drive_detach (device, detach_after_eject_cb, simple);
- }
- else
- {
- /* otherwise we are done */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
- g_object_unref (drive);
-
- out:
- ;
-}
-
-static void
-g_gdu_drive_eject_on_all_unmounted (GDrive *_drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- gpointer on_all_unmounted_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GSimpleAsyncResult *simple;
- GduDevice *device;
-
- device = gdu_presentable_get_device (drive->presentable);
- if (device == NULL)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (drive),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Drive is activatable and not running");
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- else
- {
- simple = g_simple_async_result_new (G_OBJECT (drive),
- callback,
- user_data,
- NULL);
-
- gdu_device_op_drive_eject (device, eject_cb, simple);
- }
-}
-
-static void
-g_gdu_drive_eject_with_operation (GDrive *_drive,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
-
- /* first we need to go through all the volumes and unmount their assoicated mounts (if any) */
- unmount_mounts (drive,
- flags,
- mount_operation,
- cancellable,
- callback,
- user_data,
- g_gdu_drive_eject_on_all_unmounted,
- NULL);
-}
-
-static gboolean
-g_gdu_drive_eject_with_operation_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
-}
-
-static void
-g_gdu_drive_eject (GDrive *drive,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_gdu_drive_eject_with_operation (drive, flags, NULL, cancellable, callback, user_data);
-}
-
-static gboolean
-g_gdu_drive_eject_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return g_gdu_drive_eject_with_operation_finish (drive, result, error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-stop_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
- if (error != NULL)
- {
- g_simple_async_result_set_from_error (simple, error);
- g_error_free (error);
- }
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-drive_deactivate_cb (GduDrive *drive,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
- if (error != NULL)
- {
- g_simple_async_result_set_from_error (simple, error);
- g_error_free (error);
- }
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-g_gdu_drive_stop_on_all_unmounted (GDrive *_drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- gpointer on_all_unmounted_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GSimpleAsyncResult *simple;
- GduDevice *device;
-
- simple = g_simple_async_result_new (G_OBJECT (drive),
- callback,
- user_data,
- NULL);
-
- switch (drive->start_stop_type)
- {
- case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
- device = gdu_presentable_get_device (drive->presentable);
- if (device == NULL)
- {
- g_simple_async_result_set_error (simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Cannot detach: drive has no GduDevice object");
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- else
- {
- gdu_device_op_drive_detach (device, stop_cb, simple);
- g_object_unref (device);
- }
- break;
-
- case G_DRIVE_START_STOP_TYPE_MULTIDISK:
- gdu_drive_deactivate (GDU_DRIVE (drive->presentable), drive_deactivate_cb, simple);
- break;
-
- default:
- g_simple_async_result_set_error (simple,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "start_stop_type %d not supported",
- drive->start_stop_type);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- break;
- }
-}
-
-static void
-g_gdu_drive_stop (GDrive *_drive,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
-
- /* first we need to go through all the volumes and unmount their assoicated mounts (if any) */
- unmount_mounts (drive,
- flags,
- mount_operation,
- cancellable,
- callback,
- user_data,
- g_gdu_drive_stop_on_all_unmounted,
- NULL);
-}
-
-static gboolean
-g_gdu_drive_stop_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-start_cb (GduDrive *drive,
- gchar *assembled_drive_object_path,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
- if (error != NULL)
- {
- g_simple_async_result_set_error (simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Failed activating drive: %s",
- error->message);
- g_error_free (error);
- }
- else
- {
- g_free (assembled_drive_object_path);
- }
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-typedef struct
-{
- GGduDrive *drive;
- GSimpleAsyncResult *simple;
-
- GMountOperation *start_operation;
- gulong start_operation_reply_handler_id;
-} StartOpData;
-
-static void
-start_operation_reply (GMountOperation *op,
- GMountOperationResult result,
- gpointer user_data)
-{
- StartOpData *data = user_data;
- gint choice;
-
- /* we got what we wanted; don't listen to any other signals from the start operation */
- if (data->start_operation_reply_handler_id != 0)
- {
- g_signal_handler_disconnect (data->start_operation, data->start_operation_reply_handler_id);
- data->start_operation_reply_handler_id = 0;
- }
-
- if (result != G_MOUNT_OPERATION_HANDLED)
- {
- if (result == G_MOUNT_OPERATION_ABORTED)
- {
- /* The user aborted the operation so consider it "handled" */
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "Start operation dialog aborted (user should never see this error since "
- "it is G_IO_ERROR_FAILED_HANDLED)");
- }
- else
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Expected G_MOUNT_OPERATION_HANDLED but got %d", result);
- }
- g_simple_async_result_complete (data->simple);
- goto out;
- }
-
- /* handle the user pressing cancel */
- choice = g_mount_operation_get_choice (data->start_operation);
- if (choice == 1)
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "User refused to start degraded array (user should never see this error since "
- "it is G_IO_ERROR_FAILED_HANDLED)");
- g_simple_async_result_complete (data->simple);
- goto out;
- }
-
- gdu_drive_activate (GDU_DRIVE (data->drive->presentable), start_cb, g_object_ref (data->simple));
-
- out:
- g_object_unref (data->drive);
- g_object_unref (data->start_operation);
- g_object_unref (data->simple);
- g_free (data);
-}
-
-static void
-g_gdu_drive_start (GDrive *_drive,
- GDriveStartFlags flags,
- GMountOperation *start_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GSimpleAsyncResult *simple;
- gboolean degraded;
-
- /* TODO: handle GCancellable */
-
- if (!gdu_drive_can_activate (GDU_DRIVE (drive->presentable), &degraded))
- goto not_supported;
-
- if (start_operation == NULL && degraded)
- goto refuse_degraded_without_confirmation;
-
- simple = g_simple_async_result_new (G_OBJECT (drive),
- callback,
- user_data,
- NULL);
-
- if (degraded)
- {
- const gchar *message;
- const gchar *choices[3];
- StartOpData *data;
-
- message = _("Start drive in degraded mode?\n"
- "Starting a drive in degraded mode means that "
- "the drive is no longer tolerant to failures. "
- "Data on the drive may be irrevocably lost if a "
- "component fails.");
-
- choices[0] = _("Start Anyway");
- choices[1] = _("Cancel");
- choices[2] = NULL;
-
- data = g_new0 (StartOpData, 1);
- data->drive = g_object_ref (drive);
- data->simple = simple;
- data->start_operation = g_object_ref (start_operation);
- data->start_operation_reply_handler_id = g_signal_connect (start_operation,
- "reply",
- G_CALLBACK (start_operation_reply),
- data);
-
- g_signal_emit_by_name (start_operation,
- "ask-question",
- message,
- choices);
- }
- else
- {
- gdu_drive_activate (GDU_DRIVE (drive->presentable), start_cb, simple);
- }
-
- return;
-
- not_supported:
- simple = g_simple_async_result_new_error (G_OBJECT (drive),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "Starting drive with start_stop_type %d is not supported",
- drive->start_stop_type);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- return;
-
- refuse_degraded_without_confirmation:
- simple = g_simple_async_result_new_error (G_OBJECT (drive),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Refusing to start degraded multidisk drive without user confirmation");
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
-
-}
-
-static gboolean
-g_gdu_drive_start_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-poll_media_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
- if (error != NULL)
- {
- /* We could handle PolicyKit integration here but this action is allowed by default
- * and this won't be needed when porting to PolicyKit 1.0 anyway
- */
- g_simple_async_result_set_from_error (simple, error);
- g_error_free (error);
- }
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-g_gdu_drive_poll_for_media (GDrive *_drive,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GSimpleAsyncResult *simple;
- GduDevice *device;
-
- device = gdu_presentable_get_device (drive->presentable);
- if (device == NULL)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (drive),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Device is not active");
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- else
- {
- simple = g_simple_async_result_new (G_OBJECT (drive),
- callback,
- user_data,
- NULL);
-
- gdu_device_op_drive_poll_media (device, poll_media_cb, simple);
- g_object_unref (device);
- }
-}
-
-static gboolean
-g_gdu_drive_poll_for_media_finish (GDrive *drive,
- GAsyncResult *result,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static char *
-g_gdu_drive_get_identifier (GDrive *_drive,
- const char *kind)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- gchar *id;
-
- id = NULL;
-
- if (drive->device_file != NULL)
- {
- if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
- id = g_strdup (drive->device_file);
- }
-
- return id;
-}
-
-static char **
-g_gdu_drive_enumerate_identifiers (GDrive *_drive)
-{
- GGduDrive *drive = G_GDU_DRIVE (_drive);
- GPtrArray *p;
-
- p = g_ptr_array_new ();
- if (drive->device_file != NULL)
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
- g_ptr_array_add (p, NULL);
-
- return (gchar **) g_ptr_array_free (p, FALSE);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-g_gdu_drive_drive_iface_init (GDriveIface *iface)
-{
- iface->get_name = g_gdu_drive_get_name;
- iface->get_icon = g_gdu_drive_get_icon;
- iface->has_volumes = g_gdu_drive_has_volumes;
- iface->get_volumes = g_gdu_drive_get_volumes;
- iface->is_media_removable = g_gdu_drive_is_media_removable;
- iface->has_media = g_gdu_drive_has_media;
- iface->is_media_check_automatic = g_gdu_drive_is_media_check_automatic;
- iface->can_eject = g_gdu_drive_can_eject;
- iface->can_poll_for_media = g_gdu_drive_can_poll_for_media;
- iface->eject = g_gdu_drive_eject;
- iface->eject_finish = g_gdu_drive_eject_finish;
- iface->eject_with_operation = g_gdu_drive_eject_with_operation;
- iface->eject_with_operation_finish = g_gdu_drive_eject_with_operation_finish;
- iface->poll_for_media = g_gdu_drive_poll_for_media;
- iface->poll_for_media_finish = g_gdu_drive_poll_for_media_finish;
- iface->get_identifier = g_gdu_drive_get_identifier;
- iface->enumerate_identifiers = g_gdu_drive_enumerate_identifiers;
-
- iface->get_start_stop_type = g_gdu_drive_get_start_stop_type;
- iface->can_start = g_gdu_drive_can_start;
- iface->can_start_degraded = g_gdu_drive_can_start_degraded;
- iface->can_stop = g_gdu_drive_can_stop;
- iface->start = g_gdu_drive_start;
- iface->start_finish = g_gdu_drive_start_finish;
- iface->stop = g_gdu_drive_stop;
- iface->stop_finish = g_gdu_drive_stop_finish;
-}
-
-gboolean
-g_gdu_drive_has_dev (GGduDrive *drive,
- dev_t dev)
-{
- return drive->dev == dev;
-}
-
-gboolean
-g_gdu_drive_has_presentable (GGduDrive *drive,
- GduPresentable *presentable)
-{
- return g_strcmp0 (gdu_presentable_get_id (drive->presentable), gdu_presentable_get_id (presentable)) == 0;
-}
-
-time_t
-g_gdu_drive_get_time_of_last_media_insertion (GGduDrive *drive)
-{
- GduDevice *device;
- time_t ret;
-
- ret = 0;
- device = gdu_presentable_get_device (drive->presentable);
- if (device != NULL) {
- ret = gdu_device_get_media_detection_time (device);
- g_object_unref (device);
- }
- return ret;
-}
-
-GduPresentable *
-g_gdu_drive_get_presentable (GGduDrive *drive)
-{
- return drive->presentable;
-}
diff --git a/monitor/gdu/ggdudrive.h b/monitor/gdu/ggdudrive.h
deleted file mode 100644
index 784d9ca7..00000000
--- a/monitor/gdu/ggdudrive.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#ifndef __G_GDU_DRIVE_H__
-#define __G_GDU_DRIVE_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include "ggduvolumemonitor.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_GDU_DRIVE (g_gdu_drive_get_type ())
-#define G_GDU_DRIVE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_GDU_DRIVE, GGduDrive))
-#define G_GDU_DRIVE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_GDU_DRIVE, GGduDriveClass))
-#define G_IS_GDU_DRIVE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_GDU_DRIVE))
-#define G_IS_GDU_DRIVE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_GDU_DRIVE))
-
-typedef struct _GGduDriveClass GGduDriveClass;
-
-struct _GGduDriveClass {
- GObjectClass parent_class;
-};
-
-GType g_gdu_drive_get_type (void) G_GNUC_CONST;
-
-GGduDrive *g_gdu_drive_new (GVolumeMonitor *volume_monitor,
- GduPresentable *presentable);
-void g_gdu_drive_set_volume (GGduDrive *drive,
- GGduVolume *volume);
-void g_gdu_drive_unset_volume (GGduDrive *drive,
- GGduVolume *volume);
-void g_gdu_drive_disconnected (GGduDrive *drive);
-gboolean g_gdu_drive_has_dev (GGduDrive *drive,
- dev_t dev);
-time_t g_gdu_drive_get_time_of_last_media_insertion (GGduDrive *drive);
-
-gboolean g_gdu_drive_has_presentable (GGduDrive *drive,
- GduPresentable *presentable);
-
-GduPresentable *g_gdu_drive_get_presentable (GGduDrive *drive);
-
-
-char * _drive_get_icon (GduDevice *d);
-
-G_END_DECLS
-
-#endif /* __G_GDU_DRIVE_H__ */
diff --git a/monitor/gdu/ggdumount.c b/monitor/gdu/ggdumount.c
deleted file mode 100644
index eca04c03..00000000
--- a/monitor/gdu/ggdumount.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include <config.h>
-
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-
-#include <gvfsmountinfo.h>
-
-#ifdef HAVE_GUDEV
-#include <gudev/gudev.h>
-#endif
-
-#include "ggduvolumemonitor.h"
-#include "ggdumount.h"
-#include "ggduvolume.h"
-
-struct _GGduMount
-{
- GObject parent;
-
- GVolumeMonitor *volume_monitor; /* owned by volume monitor */
- GGduVolume *volume; /* owned by volume monitor */
-
- /* the following members need to be set upon construction */
- GFile *root;
- GIcon *icon;
- gchar *name;
- gchar *uuid;
- gchar *device_file;
- gchar *mount_path;
- gboolean can_unmount;
-
- gchar *mount_entry_name;
- GIcon *mount_entry_icon;
-
- gboolean is_burn_mount;
-
- GIcon *autorun_icon;
- gboolean searched_for_autorun;
-
- gchar *xdg_volume_info_name;
- GIcon *xdg_volume_info_icon;
- gboolean searched_for_xdg_volume_info;
-
- gchar *bdmv_volume_info_name;
- GIcon *bdmv_volume_info_icon;
- gboolean searched_for_bdmv_volume_info;
-};
-
-static gboolean update_mount (GGduMount *mount);
-
-static void g_gdu_mount_mount_iface_init (GMountIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GGduMount, g_gdu_mount, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
- g_gdu_mount_mount_iface_init))
-
-static void
-volume_changed (GVolume *volume,
- gpointer user_data);
-
-static void
-g_gdu_mount_finalize (GObject *object)
-{
- GGduMount *mount;
-
- mount = G_GDU_MOUNT (object);
-
- if (mount->volume != NULL)
- {
- g_signal_handlers_disconnect_by_func (mount->volume, volume_changed, mount);
- g_gdu_volume_unset_mount (mount->volume, mount);
- }
-
- if (mount->root != NULL)
- g_object_unref (mount->root);
- if (mount->icon != NULL)
- g_object_unref (mount->icon);
- g_free (mount->name);
- g_free (mount->uuid);
- g_free (mount->device_file);
- g_free (mount->mount_path);
-
- g_free (mount->mount_entry_name);
- if (mount->mount_entry_icon != NULL)
- g_object_unref (mount->mount_entry_icon);
-
- if (mount->autorun_icon != NULL)
- g_object_unref (mount->autorun_icon);
-
- g_free (mount->xdg_volume_info_name);
- if (mount->xdg_volume_info_icon != NULL)
- g_object_unref (mount->xdg_volume_info_icon);
-
- if (G_OBJECT_CLASS (g_gdu_mount_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_gdu_mount_parent_class)->finalize) (object);
-}
-
-static void
-g_gdu_mount_class_init (GGduMountClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_gdu_mount_finalize;
-}
-
-static void
-g_gdu_mount_init (GGduMount *mount)
-{
-}
-
-static void
-emit_changed (GGduMount *mount)
-{
- g_signal_emit_by_name (mount, "changed");
- g_signal_emit_by_name (mount->volume_monitor, "mount_changed", mount);
-}
-
-static void
-got_autorun_info_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GGduMount *mount = G_GDU_MOUNT (user_data);
-
- mount->autorun_icon = g_vfs_mount_info_query_autorun_info_finish (G_FILE (source_object),
- res,
- NULL);
-
- if (update_mount (mount))
- emit_changed (mount);
-
- g_object_unref (mount);
-}
-
-static void
-got_xdg_volume_info_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GGduMount *mount = G_GDU_MOUNT (user_data);
-
- mount->xdg_volume_info_icon = g_vfs_mount_info_query_xdg_volume_info_finish (G_FILE (source_object),
- res,
- &(mount->xdg_volume_info_name),
- NULL);
- if (update_mount (mount))
- emit_changed (mount);
-
- g_object_unref (mount);
-}
-
-static void
-got_bdmv_volume_info_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GGduMount *mount = G_GDU_MOUNT (user_data);
-
- mount->bdmv_volume_info_icon = g_vfs_mount_info_query_bdmv_volume_info_finish (G_FILE (source_object),
- res,
- &(mount->bdmv_volume_info_name),
- NULL);
- if (update_mount (mount))
- emit_changed (mount);
-
- g_object_unref (mount);
-}
-
-static gboolean
-update_mount (GGduMount *mount)
-{
- gboolean changed;
- gboolean old_can_unmount;
- gchar *old_name;
- GIcon *old_icon;
-
- /* save old values */
- old_can_unmount = mount->can_unmount;
- old_name = g_strdup (mount->name);
- old_icon = mount->icon != NULL ? g_object_ref (mount->icon) : NULL;
-
- /* in with the new */
- if (mount->volume != NULL)
- {
- mount->can_unmount = TRUE;
-
- if (mount->icon != NULL)
- g_object_unref (mount->icon);
-
- /* order of preference: bdmv, xdg, autorun, probed */
- if (mount->bdmv_volume_info_icon != NULL)
- mount->icon = g_object_ref (mount->bdmv_volume_info_icon);
- else if (mount->xdg_volume_info_icon != NULL)
- mount->icon = g_object_ref (mount->xdg_volume_info_icon);
- else if (mount->autorun_icon != NULL)
- mount->icon = g_object_ref (mount->autorun_icon);
- else
- mount->icon = g_volume_get_icon (G_VOLUME (mount->volume));
-
- g_free (mount->name);
-
- /* order of preference : bdmv, xdg, probed */
- if (mount->bdmv_volume_info_name != NULL)
- mount->name = g_strdup (mount->bdmv_volume_info_name);
- else if (mount->xdg_volume_info_name != NULL)
- mount->name = g_strdup (mount->xdg_volume_info_name);
- else
- mount->name = g_volume_get_name (G_VOLUME (mount->volume));
- }
- else
- {
- mount->can_unmount = TRUE;
-
- if (mount->icon != NULL)
- g_object_unref (mount->icon);
-
- /* order of preference: bdmv, xdg, autorun, probed */
- if (mount->bdmv_volume_info_icon != NULL)
- mount->icon = g_object_ref (mount->bdmv_volume_info_icon);
- else if (mount->xdg_volume_info_icon != NULL)
- mount->icon = g_object_ref (mount->xdg_volume_info_icon);
- else if (mount->autorun_icon != NULL)
- mount->icon = g_object_ref (mount->autorun_icon);
- else
- mount->icon = mount->mount_entry_icon != NULL ? g_object_ref (mount->mount_entry_icon) : NULL;
-
- g_free (mount->name);
-
- /* order of preference : bdmv, xdg, probed */
- if (mount->bdmv_volume_info_name != NULL)
- mount->name = g_strdup (mount->bdmv_volume_info_name);
- else if (mount->xdg_volume_info_name != NULL)
- mount->name = g_strdup (mount->xdg_volume_info_name);
- else
- mount->name = g_strdup (mount->mount_entry_name);
- }
-
- /* compute whether something changed */
- changed = !((old_can_unmount == mount->can_unmount) &&
- (g_strcmp0 (old_name, mount->name) == 0) &&
- g_icon_equal (old_icon, mount->icon)
- );
-
- /* free old values */
- g_free (old_name);
- if (old_icon != NULL)
- g_object_unref (old_icon);
-
- /*g_debug ("in update_mount(), changed=%d", changed);*/
-
- /* search for BDMV */
- if (!mount->searched_for_bdmv_volume_info)
- {
- mount->searched_for_bdmv_volume_info = TRUE;
- g_vfs_mount_info_query_bdmv_volume_info (mount->root,
- NULL,
- got_bdmv_volume_info_cb,
- g_object_ref (mount));
- }
-
- /* search for .xdg-volume-info */
- if (!mount->searched_for_xdg_volume_info)
- {
- mount->searched_for_xdg_volume_info = TRUE;
- g_vfs_mount_info_query_xdg_volume_info (mount->root,
- NULL,
- got_xdg_volume_info_cb,
- g_object_ref (mount));
- }
-
- /* search for autorun.inf */
- if (!mount->searched_for_autorun)
- {
- mount->searched_for_autorun = TRUE;
- g_vfs_mount_info_query_autorun_info (mount->root,
- NULL,
- got_autorun_info_cb,
- g_object_ref (mount));
- }
-
- return changed;
-}
-
-static void
-volume_changed (GVolume *volume,
- gpointer user_data)
-{
- GGduMount *mount = G_GDU_MOUNT (user_data);
-
- if (update_mount (mount))
- emit_changed (mount);
-}
-
-GGduMount *
-g_gdu_mount_new (GVolumeMonitor *volume_monitor,
- GUnixMountEntry *mount_entry,
- GGduVolume *volume)
-{
- GGduMount *mount;
-
- mount = NULL;
-
- /* Ignore internal mounts unless there's a volume */
- if (volume == NULL && (mount_entry != NULL && !g_unix_mount_guess_should_display (mount_entry)))
- goto out;
-
- mount = g_object_new (G_TYPE_GDU_MOUNT, NULL);
- mount->volume_monitor = volume_monitor;
- g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(mount->volume_monitor));
-
- if (mount_entry != NULL)
- {
- /* No ref on GUnixMountEntry so save values for later use */
- mount->mount_entry_name = g_unix_mount_guess_name (mount_entry);
- mount->mount_entry_icon = g_unix_mount_guess_icon (mount_entry);
- mount->device_file = g_strdup (g_unix_mount_get_device_path (mount_entry));
- mount->mount_path = g_strdup (g_unix_mount_get_mount_path (mount_entry));
- mount->root = g_file_new_for_path (mount->mount_path);
- }
- else
- {
- /* burn:/// mount (the only mounts we support with mount_entry == NULL) */
- mount->device_file = NULL;
- mount->mount_path = NULL;
- mount->root = g_file_new_for_uri ("burn:///");
- mount->is_burn_mount = TRUE;
- }
-
- /* need to set the volume only when the mount is fully constructed */
- mount->volume = volume;
- if (mount->volume != NULL)
- {
- g_gdu_volume_set_mount (volume, mount);
- /* this is for piggy backing on the name and icon of the associated volume */
- g_signal_connect (mount->volume, "changed", G_CALLBACK (volume_changed), mount);
- }
-
- update_mount (mount);
-
- out:
-
- return mount;
-}
-
-void
-g_gdu_mount_unmounted (GGduMount *mount)
-{
- if (mount->volume != NULL)
- {
- g_gdu_volume_unset_mount (mount->volume, mount);
- g_signal_handlers_disconnect_by_func (mount->volume, volume_changed, mount);
- mount->volume = NULL;
- emit_changed (mount);
- }
-}
-
-void
-g_gdu_mount_unset_volume (GGduMount *mount,
- GGduVolume *volume)
-{
- if (mount->volume == volume)
- {
- g_signal_handlers_disconnect_by_func (mount->volume, volume_changed, mount);
- mount->volume = NULL;
- emit_changed (mount);
- }
-}
-
-static GFile *
-g_gdu_mount_get_root (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return mount->root != NULL ? g_object_ref (mount->root) : NULL;
-}
-
-static GIcon *
-g_gdu_mount_get_icon (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return mount->icon != NULL ? g_object_ref (mount->icon) : NULL;
-}
-
-static gchar *
-g_gdu_mount_get_uuid (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return g_strdup (mount->uuid);
-}
-
-static gchar *
-g_gdu_mount_get_name (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return g_strdup (mount->name);
-}
-
-gboolean
-g_gdu_mount_has_uuid (GGduMount *_mount,
- const gchar *uuid)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return g_strcmp0 (mount->uuid, uuid) == 0;
-}
-
-gboolean
-g_gdu_mount_has_mount_path (GGduMount *_mount,
- const gchar *mount_path)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return g_strcmp0 (mount->mount_path, mount_path) == 0;
-}
-
-static GDrive *
-g_gdu_mount_get_drive (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- GDrive *drive;
-
- drive = NULL;
- if (mount->volume != NULL)
- drive = g_volume_get_drive (G_VOLUME (mount->volume));
-
- return drive;
-}
-
-static GVolume *
-g_gdu_mount_get_volume (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- GVolume *volume;
-
- volume = NULL;
- if (mount->volume)
- volume = G_VOLUME (g_object_ref (mount->volume));
-
- return volume;
-}
-
-static gboolean
-g_gdu_mount_can_unmount (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- return mount->can_unmount;
-}
-
-static gboolean
-g_gdu_mount_can_eject (GMount *_mount)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- GDrive *drive;
- gboolean can_eject;
-
- can_eject = FALSE;
- if (mount->volume != NULL)
- {
- drive = g_volume_get_drive (G_VOLUME (mount->volume));
- if (drive != NULL)
- can_eject = g_drive_can_eject (drive);
- }
-
- return can_eject;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef struct {
- GMount *mount;
-
- gchar **argv;
-
- GAsyncReadyCallback callback;
- gpointer user_data;
- GCancellable *cancellable;
-
- int error_fd;
- GIOChannel *error_channel;
- guint error_channel_source_id;
- GString *error_string;
-
-} BinUnmountData;
-
-static gboolean bin_unmount_attempt (BinUnmountData *data);
-
-static void
-bin_unmount_cb (GPid pid, gint status, gpointer user_data)
-{
- BinUnmountData *data = user_data;
- GSimpleAsyncResult *simple;
-
- g_spawn_close_pid (pid);
-
- if (WEXITSTATUS (status) != 0)
- {
- GError *error;
- gint error_code;
-
- error_code = G_IO_ERROR_FAILED;
- /* we may want to add more strstr() checks here depending on what unmount helper is being used etc... */
- if (data->error_string->str != NULL && strstr (data->error_string->str, "is busy") != NULL)
- error_code = G_IO_ERROR_BUSY;
-
- error = g_error_new_literal (G_IO_ERROR,
- error_code,
- data->error_string->str);
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- error);
- g_error_free (error);
- }
- else
- {
- simple = g_simple_async_result_new (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- NULL);
- }
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- g_source_remove (data->error_channel_source_id);
- g_io_channel_unref (data->error_channel);
- g_string_free (data->error_string, TRUE);
- close (data->error_fd);
- g_strfreev (data->argv);
- g_free (data);
-}
-
-static gboolean
-bin_unmount_read_error (GIOChannel *channel,
- GIOCondition condition,
- gpointer user_data)
-{
- BinUnmountData *data = user_data;
- gchar buf[BUFSIZ];
- gsize bytes_read;
- GError *error;
- GIOStatus status;
-
- error = NULL;
-read:
- status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
- if (status == G_IO_STATUS_NORMAL)
- {
- g_string_append_len (data->error_string, buf, bytes_read);
- if (bytes_read == sizeof (buf))
- goto read;
- }
- else if (status == G_IO_STATUS_EOF)
- g_string_append_len (data->error_string, buf, bytes_read);
- else if (status == G_IO_STATUS_ERROR)
- {
- if (data->error_string->len > 0)
- g_string_append (data->error_string, "\n");
-
- g_string_append (data->error_string, error->message);
- g_error_free (error);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-bin_unmount_attempt (BinUnmountData *data)
-{
- GPid child_pid;
- GError *error;
-
- error = NULL;
- if (!g_spawn_async_with_pipes (NULL, /* working dir */
- data->argv,
- NULL, /* envp */
- G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
- NULL, /* child_setup */
- NULL, /* user_data for child_setup */
- &child_pid,
- NULL, /* standard_input */
- NULL, /* standard_output */
- &(data->error_fd),
- &error)) {
- g_assert (error != NULL);
- goto handle_error;
- }
-
- data->error_string = g_string_new ("");
-
- data->error_channel = g_io_channel_unix_new (data->error_fd);
- g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
- if (error != NULL)
- goto handle_error;
-
- data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, bin_unmount_read_error, data);
- g_child_watch_add (child_pid, bin_unmount_cb, data);
-
-handle_error:
-
- if (error != NULL)
- {
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- if (data->error_string != NULL)
- g_string_free (data->error_string, TRUE);
-
- if (data->error_channel != NULL)
- g_io_channel_unref (data->error_channel);
-
- g_error_free (error);
- g_free (data);
- }
-
- return FALSE;
-}
-
-static void
-bin_unmount_do (GMount *mount,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- char **argv)
-{
- BinUnmountData *data;
-
- data = g_new0 (BinUnmountData, 1);
- data->mount = mount;
- data->callback = callback;
- data->user_data = user_data;
- data->cancellable = cancellable;
- data->argv = g_strdupv (argv);
-
- bin_unmount_attempt (data);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static GArray *
-_get_busy_processes (GduDevice *device)
-{
- GArray *processes;
- GList *open_files, *l;
-
- processes = g_array_new (FALSE, FALSE, sizeof (GPid));
-
- open_files = gdu_device_filesystem_list_open_files_sync (device, NULL);
- for (l = open_files; l != NULL; l = l->next)
- {
- GduProcess *gdup = GDU_PROCESS (l->data);
- GPid pid = gdu_process_get_id (gdup);
- g_array_append_val (processes, pid);
- }
- g_list_foreach (open_files, (GFunc) g_object_unref, NULL);
- g_list_free (open_files);
-
- return processes;
-}
-
-typedef struct
-{
- gint ref_count;
-
- GGduMount *mount;
- GMountUnmountFlags flags;
- GduDevice *device;
-
- GAsyncReadyCallback callback;
- gpointer user_data;
-
- GCancellable *cancellable;
- GMountOperation *mount_operation;
-
- gulong cancelled_handler_id;
- gulong mount_op_reply_handler_id;
- guint retry_unmount_timer_id;
-
- gboolean completed;
-} _GduUnmountData;
-
-static _GduUnmountData *
-_gdu_unmount_data_ref (_GduUnmountData *data)
-{
- g_atomic_int_inc (&data->ref_count);
- return data;
-}
-
-static void
-_gdu_unmount_data_unref (_GduUnmountData *data)
-{
- if (!g_atomic_int_dec_and_test (&data->ref_count))
- return;
-
- if (data->cancelled_handler_id > 0)
- g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
- if (data->mount_op_reply_handler_id > 0)
- {
- /* make the operation dialog go away */
- g_signal_emit_by_name (data->mount_operation, "aborted");
- g_signal_handler_disconnect (data->mount_operation, data->mount_op_reply_handler_id);
- }
- if (data->retry_unmount_timer_id > 0)
- {
- g_source_remove (data->retry_unmount_timer_id);
- }
-
- g_object_unref (data->mount);
- if (data->cancellable != NULL)
- g_object_unref (data->cancellable);
- if (data->mount_operation != NULL)
- g_object_unref (data->mount_operation);
- g_object_unref (data->device);
-
- g_free (data);
-}
-
-static void
-_gdu_unmount_luks_lock_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- _GduUnmountData *data = user_data;
- GSimpleAsyncResult *simple;
-
- if (error != NULL)
- {
- /* translate to GduError to GIOError */
- if (error->domain == GDU_ERROR && error->code == GDU_ERROR_BUSY)
- error->code = G_IO_ERROR_BUSY;
- else
- error->code = G_IO_ERROR_FAILED;
- error->domain = G_IO_ERROR;
-
- if (!data->completed)
- {
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- error);
- g_error_free (error);
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- goto out;
- }
-
- /* we're done */
- if (!data->completed)
- {
- simple = g_simple_async_result_new (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- NULL);
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
-
- out:
- /* release the ref taken when calling gdu_device_op_luks_lock() */
- _gdu_unmount_data_unref (data);
-}
-
-static void _gdu_unmount_attempt (_GduUnmountData *data,
- gboolean force_unmount);
-
-static void
-_gdu_unmount_on_mount_op_reply (GMountOperation *mount_operation,
- GMountOperationResult result,
- gpointer user_data)
-{
- _GduUnmountData *data = user_data;
- GSimpleAsyncResult *simple;
- gint choice;
-
- /* disconnect the signal handler */
- g_warn_if_fail (data->mount_op_reply_handler_id != 0);
- g_signal_handler_disconnect (data->mount_operation,
- data->mount_op_reply_handler_id);
- data->mount_op_reply_handler_id = 0;
-
- choice = g_mount_operation_get_choice (mount_operation);
-
- if (result == G_MOUNT_OPERATION_ABORTED ||
- (result == G_MOUNT_OPERATION_HANDLED && choice == 1))
- {
- /* don't show an error dialog here */
- if (!data->completed)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "GMountOperation aborted (user should never see this "
- "error since it is G_IO_ERROR_FAILED_HANDLED)");
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- }
- else if (result == G_MOUNT_OPERATION_HANDLED)
- {
- /* user chose force unmount => try again with force_unmount==TRUE */
-
- _gdu_unmount_attempt (data, TRUE);
- }
- else
- {
- /* result == G_MOUNT_OPERATION_UNHANDLED => GMountOperation instance doesn't
- * support :show-processes signal
- */
- if (!data->completed)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_BUSY,
- _("One or more programs are preventing the unmount operation."));
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- }
-}
-
-static gboolean
-_gdu_unmount_on_retry_unmount_timer (gpointer user_data)
-{
- _GduUnmountData *data = user_data;
-
- /* we're removing the timeout */
- data->retry_unmount_timer_id = 0;
-
- if (data->completed)
- goto out;
-
- /* timeout expired => try again */
- _gdu_unmount_attempt (data, FALSE);
-
- out:
- return FALSE;
-}
-
-
-static void
-_gdu_unmount_cb (GduDevice *device,
- GError *error,
- gpointer user_data)
-{
- _GduUnmountData *data = user_data;
- GSimpleAsyncResult *simple;
-
- if (error != NULL)
- {
- /* translate to GduError to GIOError */
- if (error->domain == GDU_ERROR && error->code == GDU_ERROR_BUSY)
- error->code = G_IO_ERROR_BUSY;
- else
- error->code = G_IO_ERROR_FAILED;
- error->domain = G_IO_ERROR;
-
- /* if the user passed in a GMountOperation, then do the GMountOperation::show-processes dance ... */
- if (error->code == G_IO_ERROR_BUSY && data->mount_operation != NULL)
- {
- GArray *processes;
-
- /* TODO: might be better to do this Async - punt on this until gdu uses GCancellable... */
- processes = _get_busy_processes (device);
-
- if (processes != NULL && processes->len > 0)
- {
- const gchar *choices[3] = {NULL, NULL, NULL};
- const gchar *message;
-
- if (data->mount_op_reply_handler_id == 0)
- {
- data->mount_op_reply_handler_id = g_signal_connect (data->mount_operation,
- "reply",
- G_CALLBACK (_gdu_unmount_on_mount_op_reply),
- data);
- }
- choices[0] = _("Unmount Anyway");
- choices[1] = _("Cancel");
- message = _("Volume is busy\n"
- "One or more applications are keeping the volume busy.");
- g_signal_emit_by_name (data->mount_operation,
- "show-processes",
- message,
- processes,
- choices);
-
- /* set up a timer to try unmounting every two seconds - this will also
- * update the list of busy processes
- */
- if (data->retry_unmount_timer_id == 0)
- {
- data->retry_unmount_timer_id = g_timeout_add_seconds (2,
- _gdu_unmount_on_retry_unmount_timer,
- data);
- }
- goto out;
- }
- else
- {
- if (processes != NULL)
- g_array_unref (processes);
- /* falls through to reporting an error */
- }
- }
-
- /* otherwise, just report the error */
-
- if (!data->completed)
- {
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- error);
- g_error_free (error);
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- goto out;
- }
-
- /* success! if we unmounted a cleartext device, also tear down the crypto mapping */
- if (gdu_device_is_luks_cleartext (device))
- {
- const gchar *luks_cleartext_slave_object_path;
- GduDevice *luks_cleartext_slave;
- GduPool *pool;
-
- luks_cleartext_slave_object_path = gdu_device_luks_cleartext_get_slave (data->device);
- if (luks_cleartext_slave_object_path == NULL)
- {
- if (!data->completed)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- /* Translators: can't get block device with unencrypted data to unmount */
- _("Cannot get LUKS cleartext slave"));
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- goto out;
- }
-
- pool = gdu_device_get_pool (device);
- luks_cleartext_slave = gdu_pool_get_by_object_path (pool, luks_cleartext_slave_object_path);
- g_object_unref (pool);
-
- if (luks_cleartext_slave == NULL)
- {
- if (!data->completed)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- /* Translators: can't get block device with unencrypted data from path */
- _("Cannot get LUKS cleartext slave from path “%s”"),
- luks_cleartext_slave_object_path);
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- goto out;
- }
-
- /* take an extra ref on data since we may complete before the callback */
- gdu_device_op_luks_lock (luks_cleartext_slave,
- _gdu_unmount_luks_lock_cb,
- _gdu_unmount_data_ref (data));
-
- g_object_unref (luks_cleartext_slave);
- goto out;
- }
-
- /* not a cleartext device => we're done */
- if (!data->completed)
- {
- simple = g_simple_async_result_new (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- NULL);
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
-
- out:
- /* release the ref taken when calling gdu_device_op_filesystem_unmount() */
- _gdu_unmount_data_unref (data);
-}
-
-static void
-_gdu_unmount_attempt (_GduUnmountData *data,
- gboolean force_unmount)
-{
- /* TODO: honor force_unmount */
-
- /* take an extra ref on data since we may complete before the callback */
- gdu_device_op_filesystem_unmount (data->device, _gdu_unmount_cb, _gdu_unmount_data_ref (data));
-}
-
-
-static void
-_gdu_unmount_on_cancelled (GMount *mount,
- gpointer user_data)
-{
- _GduUnmountData *data = user_data;
-
- if (!data->completed)
- {
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new_error (G_OBJECT (data->mount),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- data->completed = TRUE;
- _gdu_unmount_data_unref (data);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
-}
-
-static void
-_gdu_unmount_do (GGduMount *mount,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- GduDevice *device)
-{
- _GduUnmountData *data;
-
- data = g_new0 (_GduUnmountData, 1);
- data->ref_count = 1;
- data->mount = g_object_ref (mount);
- data->flags = flags;
- data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
- data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
- data->callback = callback;
- data->user_data = user_data;
- data->device = g_object_ref (device);
-
- /* operation may be cancelled at any time */
- if (data->cancellable != NULL)
- {
- data->cancelled_handler_id = g_signal_connect (data->cancellable,
- "cancelled",
- G_CALLBACK (_gdu_unmount_on_cancelled),
- data);
- }
-
- /* attempt to unmount */
- _gdu_unmount_attempt (data, FALSE);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-g_gdu_mount_unmount_with_operation (GMount *_mount,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- GduPresentable *gdu_volume;
-
- /* emit the ::mount-pre-unmount signal */
- g_signal_emit_by_name (mount->volume_monitor, "mount-pre-unmount", mount);
-
- gdu_volume = NULL;
- if (mount->volume != NULL)
- gdu_volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
-
- if (mount->volume == NULL || gdu_volume == NULL)
- {
- gchar *argv[] = {"umount", NULL, NULL};
-
- /* TODO: honor flags */
-
- if (mount->mount_path != NULL)
- argv[1] = mount->mount_path;
- else
- argv[1] = mount->device_file;
-
- bin_unmount_do (_mount, cancellable, callback, user_data, argv);
- }
- else if (gdu_volume != NULL)
- {
- if (mount->is_burn_mount)
- {
- /* burn mounts are really never mounted so complete successfully immediately */
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new (G_OBJECT (mount),
- callback,
- user_data,
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
- else
- {
- GduDevice *device;
- device = gdu_presentable_get_device (gdu_volume);
- _gdu_unmount_do (mount, flags, mount_operation, cancellable, callback, user_data, device);
- g_object_unref (device);
- }
- }
- else
- {
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new_error (G_OBJECT (mount),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Operation not supported by backend"));
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
-}
-
-static gboolean
-g_gdu_mount_unmount_with_operation_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
-}
-
-static void
-g_gdu_mount_unmount (GMount *mount,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_gdu_mount_unmount_with_operation (mount, flags, NULL, cancellable, callback, user_data);
-}
-
-static gboolean
-g_gdu_mount_unmount_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return g_gdu_mount_unmount_with_operation_finish (mount, result, error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef struct {
- GObject *object;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} EjectWrapperOp;
-
-static void
-eject_wrapper_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- EjectWrapperOp *data = user_data;
- data->callback (data->object, res, data->user_data);
- g_object_unref (data->object);
- g_free (data);
-}
-
-static void
-g_gdu_mount_eject_with_operation (GMount *mount,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduMount *gdu_mount = G_GDU_MOUNT (mount);
- GDrive *drive;
-
- drive = NULL;
- if (gdu_mount->volume != NULL)
- drive = g_volume_get_drive (G_VOLUME (gdu_mount->volume));
-
- if (drive != NULL)
- {
- EjectWrapperOp *data;
- data = g_new0 (EjectWrapperOp, 1);
- data->object = g_object_ref (mount);
- data->callback = callback;
- data->user_data = user_data;
- g_drive_eject_with_operation (drive, flags, mount_operation, cancellable, eject_wrapper_callback, data);
- g_object_unref (drive);
- }
- else
- {
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new_error (G_OBJECT (mount),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Operation not supported by backend"));
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
-
-}
-
-static gboolean
-g_gdu_mount_eject_with_operation_finish (GMount *_mount,
- GAsyncResult *result,
- GError **error)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- GDrive *drive;
- gboolean res;
-
- res = TRUE;
-
- drive = NULL;
- if (mount->volume != NULL)
- drive = g_volume_get_drive (G_VOLUME (mount->volume));
-
- if (drive != NULL)
- {
- res = g_drive_eject_with_operation_finish (drive, result, error);
- g_object_unref (drive);
- }
- else
- {
- g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
- res = FALSE;
- }
-
- return res;
-}
-
-static void
-g_gdu_mount_eject (GMount *mount,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_gdu_mount_eject_with_operation (mount, flags, NULL, cancellable, callback, user_data);
-}
-
-static gboolean
-g_gdu_mount_eject_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return g_gdu_mount_eject_with_operation_finish (mount, result, error);
-}
-
-/* TODO: handle force_rescan */
-static gchar **
-g_gdu_mount_guess_content_type_sync (GMount *_mount,
- gboolean force_rescan,
- GCancellable *cancellable,
- GError **error)
-{
- GGduMount *mount = G_GDU_MOUNT (_mount);
- const gchar *disc_type;
- char **x_content_types;
- GPtrArray *p;
- gchar **result;
- GduDevice *device;
- guint n;
-
- p = g_ptr_array_new ();
-
- device = NULL;
- if (mount->volume != NULL)
- {
- GduPresentable *presentable;
- presentable = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
- if (presentable != NULL)
- device = gdu_presentable_get_device (presentable);
- }
-
- /* doesn't make sense to probe blank discs - look at the disc type instead */
- if (device != NULL && gdu_device_optical_disc_get_is_blank (device))
- {
- disc_type = gdu_device_drive_get_media (device);
- if (disc_type != NULL)
- {
- if (g_str_has_prefix (disc_type, "optical_dvd"))
- g_ptr_array_add (p, g_strdup ("x-content/blank-dvd"));
- else if (g_str_has_prefix (disc_type, "optical_hddvd"))
- g_ptr_array_add (p, g_strdup ("x-content/blank-hddvd"));
- else if (g_str_has_prefix (disc_type, "optical_bd"))
- g_ptr_array_add (p, g_strdup ("x-content/blank-bd"));
- else
- g_ptr_array_add (p, g_strdup ("x-content/blank-cd")); /* assume CD */
- }
- }
- else
- {
- /* sniff content type */
- x_content_types = g_content_type_guess_for_tree (mount->root);
- if (x_content_types != NULL)
- {
- for (n = 0; x_content_types[n] != NULL; n++)
- g_ptr_array_add (p, g_strdup (x_content_types[n]));
- g_strfreev (x_content_types);
- }
- }
-
-#ifdef HAVE_GUDEV
- /* Check if its bootable */
- if (device != NULL)
- {
- const gchar *device_file;
-
- device_file = gdu_device_get_device_file (device);
- if (device_file != NULL)
- {
- GUdevClient *client;
- GUdevDevice *gudev_device;
- const gchar *subsystems[] = {"block", NULL};
-
- client = g_udev_client_new (subsystems);
- gudev_device = g_udev_client_query_by_device_file (client, device_file);
- if (gudev_device != NULL)
- {
- const gchar *boot_sys_id;
-
- boot_sys_id = g_udev_device_get_property (gudev_device,
- "ID_FS_BOOT_SYSTEM_ID");
- if (boot_sys_id != NULL ||
- g_udev_device_get_property_as_boolean (gudev_device,
- "OSINFO_BOOTABLE"))
- g_ptr_array_add (p, g_strdup ("x-content/bootable-media"));
-
- g_object_unref (gudev_device);
- }
-
- g_object_unref (client);
- }
- }
-#endif
-
- if (p->len == 0)
- {
- result = NULL;
- g_ptr_array_free (p, TRUE);
- }
- else
- {
- g_ptr_array_add (p, NULL);
- result = (char **) g_ptr_array_free (p, FALSE);
- }
-
- if (device != NULL)
- g_object_unref (device);
-
- return result;
-}
-
-/* since we're an out-of-process volume monitor we'll just do this sync */
-static void
-g_gdu_mount_guess_content_type (GMount *mount,
- gboolean force_rescan,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
-
- /* TODO: handle force_rescan */
- simple = g_simple_async_result_new (G_OBJECT (mount),
- callback,
- user_data,
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static gchar **
-g_gdu_mount_guess_content_type_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return g_gdu_mount_guess_content_type_sync (mount, FALSE, NULL, error);
-}
-
-static void
-g_gdu_mount_mount_iface_init (GMountIface *iface)
-{
- iface->get_root = g_gdu_mount_get_root;
- iface->get_name = g_gdu_mount_get_name;
- iface->get_icon = g_gdu_mount_get_icon;
- iface->get_uuid = g_gdu_mount_get_uuid;
- iface->get_drive = g_gdu_mount_get_drive;
- iface->get_volume = g_gdu_mount_get_volume;
- iface->can_unmount = g_gdu_mount_can_unmount;
- iface->can_eject = g_gdu_mount_can_eject;
- iface->unmount = g_gdu_mount_unmount;
- iface->unmount_finish = g_gdu_mount_unmount_finish;
- iface->unmount_with_operation = g_gdu_mount_unmount_with_operation;
- iface->unmount_with_operation_finish = g_gdu_mount_unmount_with_operation_finish;
- iface->eject = g_gdu_mount_eject;
- iface->eject_finish = g_gdu_mount_eject_finish;
- iface->eject_with_operation = g_gdu_mount_eject_with_operation;
- iface->eject_with_operation_finish = g_gdu_mount_eject_with_operation_finish;
- iface->guess_content_type = g_gdu_mount_guess_content_type;
- iface->guess_content_type_finish = g_gdu_mount_guess_content_type_finish;
- iface->guess_content_type_sync = g_gdu_mount_guess_content_type_sync;
-}
-
-gboolean
-g_gdu_mount_has_volume (GGduMount *mount,
- GGduVolume *volume)
-{
- return mount->volume == volume;
-}
diff --git a/monitor/gdu/ggdumount.h b/monitor/gdu/ggdumount.h
deleted file mode 100644
index 875ba4cb..00000000
--- a/monitor/gdu/ggdumount.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#ifndef __G_GDU_MOUNT_H__
-#define __G_GDU_MOUNT_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include "ggduvolumemonitor.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_GDU_MOUNT (g_gdu_mount_get_type ())
-#define G_GDU_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_GDU_MOUNT, GGduMount))
-#define G_GDU_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_GDU_MOUNT, GGduMountClass))
-#define G_IS_GDU_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_GDU_MOUNT))
-#define G_IS_GDU_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_GDU_MOUNT))
-
-typedef struct _GGduMountClass GGduMountClass;
-
-struct _GGduMountClass {
- GObjectClass parent_class;
-};
-
-GType g_gdu_mount_get_type (void) G_GNUC_CONST;
-
-GGduMount * g_gdu_mount_new (GVolumeMonitor *volume_monitor,
- GUnixMountEntry *mount_entry,
- GGduVolume *volume);
-gboolean g_gdu_mount_has_mount_path (GGduMount *mount,
- const gchar *mount_path);
-gboolean g_gdu_mount_has_uuid (GGduMount *mount,
- const gchar *uuid);
-void g_gdu_mount_unset_volume (GGduMount *mount,
- GGduVolume *volume);
-void g_gdu_mount_unmounted (GGduMount *mount);
-
-gboolean g_gdu_mount_has_volume (GGduMount *mount,
- GGduVolume *volume);
-
-G_END_DECLS
-
-#endif /* __G_GDU_MOUNT_H__ */
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
deleted file mode 100644
index cf42a928..00000000
--- a/monitor/gdu/ggduvolume.c
+++ /dev/null
@@ -1,1884 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#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>
-
-#include "ggdudrive.h"
-#include "ggduvolume.h"
-#include "ggdumount.h"
-
-/* for BUFSIZ */
-#include <stdio.h>
-
-typedef struct MountOpData MountOpData;
-
-static void cancel_pending_mount_op (MountOpData *data);
-
-static void g_gdu_volume_mount_unix_mount_point (GGduVolume *volume,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-struct _GGduVolume
-{
- GObject parent;
-
- GVolumeMonitor *volume_monitor; /* owned by volume monitor */
- GGduMount *mount; /* owned by volume monitor */
- GGduDrive *drive; /* owned by volume monitor */
-
- /* only set if constructed via new() */
- GduVolume *gdu_volume;
-
- /* only set if constructed via new_for_unix_mount_point() */
- GUnixMountPoint *unix_mount_point;
-
- /* if the volume is encrypted, this is != NULL when unlocked */
- GduVolume *cleartext_gdu_volume;
-
- /* 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.
- */
- MountOpData *pending_mount_op;
-
- /* the following members need to be set upon construction, see constructors and update_volume() */
- GIcon *icon;
- GFile *activation_root;
- gchar *name;
- gchar *device_file;
- dev_t dev;
- gchar *uuid;
- gboolean can_mount;
- gboolean should_automount;
-};
-
-static void g_gdu_volume_volume_iface_init (GVolumeIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GGduVolume, g_gdu_volume, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME,
- g_gdu_volume_volume_iface_init))
-
-static void gdu_volume_changed (GduPresentable *presentable,
- GGduVolume *volume);
-static void gdu_volume_job_changed (GduPresentable *presentable,
- GGduVolume *volume);
-
-static void gdu_cleartext_volume_removed (GduPresentable *presentable,
- GGduVolume *volume);
-static void gdu_cleartext_volume_changed (GduPresentable *presentable,
- GGduVolume *volume);
-static void gdu_cleartext_volume_job_changed (GduPresentable *presentable,
- GGduVolume *volume);
-
-static void mount_with_mount_operation (MountOpData *data);
-
-static gboolean
-g_gdu_drive_device_is_flash(GduDevice *drive_device)
-{
- const gchar *drive_media;
-
- if (drive_device == NULL)
- return FALSE;
-
- drive_media = gdu_device_drive_get_media (drive_device);
- return g_str_has_prefix (drive_media, "flash");
-}
-
-static void
-g_gdu_volume_finalize (GObject *object)
-{
- GGduVolume *volume;
-
- volume = G_GDU_VOLUME (object);
-
- if (volume->mount != NULL)
- g_gdu_mount_unset_volume (volume->mount, volume);
-
- if (volume->drive != NULL)
- g_gdu_drive_unset_volume (volume->drive, volume);
-
- if (volume->gdu_volume != NULL)
- {
- g_signal_handlers_disconnect_by_func (volume->gdu_volume, gdu_volume_changed, volume);
- g_signal_handlers_disconnect_by_func (volume->gdu_volume, gdu_volume_job_changed, volume);
- g_object_unref (volume->gdu_volume);
- }
-
- if (volume->unix_mount_point != NULL)
- {
- g_unix_mount_point_free (volume->unix_mount_point);
- }
-
- if (volume->cleartext_gdu_volume != NULL)
- {
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_removed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_changed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_job_changed, volume);
- g_object_unref (volume->cleartext_gdu_volume);
- }
-
- 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->device_file);
- g_free (volume->uuid);
-
- if (G_OBJECT_CLASS (g_gdu_volume_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_gdu_volume_parent_class)->finalize) (object);
-}
-
-static void
-g_gdu_volume_class_init (GGduVolumeClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_gdu_volume_finalize;
-}
-
-static void
-g_gdu_volume_init (GGduVolume *gdu_volume)
-{
-}
-
-static void
-emit_changed (GGduVolume *volume)
-{
- g_signal_emit_by_name (volume, "changed");
- g_signal_emit_by_name (volume->volume_monitor, "volume_changed", volume);
-}
-
-static gboolean
-update_volume (GGduVolume *volume)
-{
- GduDevice *device;
- GduPool *pool = NULL;
- time_t now;
- gboolean changed;
- gboolean old_can_mount;
- gboolean old_should_automount;
- gchar *old_name;
- gchar *old_device_file;
- dev_t old_dev;
- GIcon *old_icon;
- gboolean keep_cleartext_volume;
-
- /* 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;
-
- /* ---------------------------------------------------------------------------------------------------- */
-
- /* if the volume is a fstab mount point, get the data from there */
- if (volume->unix_mount_point != NULL)
- {
- struct stat_buf;
-
- volume->can_mount = TRUE;
- volume->should_automount = FALSE;
-
- g_free (volume->device_file);
- volume->device_file = g_strdup (g_unix_mount_point_get_device_path (volume->unix_mount_point));
- volume->dev = 0;
-
- if (volume->icon != NULL)
- g_object_unref (volume->icon);
- if (g_strcmp0 (g_unix_mount_point_get_fs_type (volume->unix_mount_point), "nfs") == 0)
- volume->icon = g_themed_icon_new_with_default_fallbacks ("folder-remote");
- else
- volume->icon = g_unix_mount_point_guess_icon (volume->unix_mount_point);
-
- g_free (volume->name);
- volume->name = g_unix_mount_point_guess_name (volume->unix_mount_point);
-
- //volume->can_eject = g_unix_mount_point_guess_can_eject (volume->unix_mount_point);
-
- goto update_done;
- }
-
- /* in with the new */
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
- if (device != NULL)
- pool = gdu_device_get_pool (device);
-
- keep_cleartext_volume = FALSE;
- if (device != NULL && gdu_device_is_luks (device))
- {
- const gchar *holder_objpath;
-
- holder_objpath = gdu_device_luks_get_holder (device);
- if (holder_objpath != NULL && g_strcmp0 (holder_objpath, "/") != 0)
- {
- GduDevice *cleartext_device;
-
- cleartext_device = gdu_pool_get_by_object_path (pool, holder_objpath);
- if (cleartext_device != NULL)
- {
- GduVolume *cleartext_gdu_volume;
-
- cleartext_gdu_volume = GDU_VOLUME (gdu_pool_get_volume_by_device (pool, cleartext_device));
- if (cleartext_gdu_volume != volume->cleartext_gdu_volume)
- {
- if (volume->cleartext_gdu_volume != NULL)
- {
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_removed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_changed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_job_changed, volume);
- g_object_unref (volume->cleartext_gdu_volume);
- }
-
- volume->cleartext_gdu_volume = g_object_ref (cleartext_gdu_volume);
- g_signal_connect (volume->cleartext_gdu_volume, "removed", G_CALLBACK (gdu_cleartext_volume_removed), volume);
- g_signal_connect (volume->cleartext_gdu_volume, "changed", G_CALLBACK (gdu_cleartext_volume_changed), volume);
- g_signal_connect (volume->cleartext_gdu_volume, "job-changed", G_CALLBACK (gdu_cleartext_volume_job_changed), volume);
- }
- g_object_unref (cleartext_gdu_volume);
-
- g_object_unref (cleartext_device);
-
- keep_cleartext_volume = TRUE;
- }
- }
- }
-
- if (!keep_cleartext_volume)
- {
- if (volume->cleartext_gdu_volume != NULL)
- {
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_removed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_changed, volume);
- g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_job_changed, volume);
- g_object_unref (volume->cleartext_gdu_volume);
- volume->cleartext_gdu_volume = NULL;
- }
- }
-
-
- /* Use data from cleartext LUKS volume if it is unlocked */
- if (volume->cleartext_gdu_volume != NULL)
- {
- GduDevice *luks_cleartext_volume_device;
-
- luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
-
- if (volume->icon != NULL)
- g_object_unref (volume->icon);
- volume->icon = gdu_presentable_get_icon (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
-
- g_free (volume->name);
- volume->name = gdu_presentable_get_name (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
-
- g_free (volume->device_file);
- if (luks_cleartext_volume_device != NULL)
- {
- volume->device_file = g_strdup (gdu_device_get_device_file (luks_cleartext_volume_device));
- volume->dev = gdu_device_get_dev (luks_cleartext_volume_device);
- }
- else
- {
- volume->device_file = NULL;
- volume->dev = 0;
- }
-
- volume->can_mount = TRUE;
-
- volume->should_automount = FALSE;
-
- if (luks_cleartext_volume_device != NULL)
- g_object_unref (luks_cleartext_volume_device);
- }
- else
- {
- gchar *activation_uri;
-
- if (volume->icon != NULL)
- g_object_unref (volume->icon);
- volume->icon = gdu_presentable_get_icon (GDU_PRESENTABLE (volume->gdu_volume));
-
- g_free (volume->name);
- if (_is_pc_floppy_drive (device))
- volume->name = g_strdup (_("Floppy Disk"));
- else
- volume->name = gdu_presentable_get_name (GDU_PRESENTABLE (volume->gdu_volume));
-
- /* special case the name and icon for audio discs */
- activation_uri = volume->activation_root != NULL ? g_file_get_uri (volume->activation_root) : NULL;
- if (activation_uri != NULL && g_str_has_prefix (activation_uri, "cdda://"))
- {
- if (volume->icon != NULL)
- g_object_unref (volume->icon);
- volume->icon = g_themed_icon_new_with_default_fallbacks ("media-optical-audio");
- g_free (volume->name);
- volume->name = g_strdup (_("Audio Disc"));
- }
-
- g_free (volume->device_file);
- if (device != NULL)
- {
- volume->device_file = g_strdup (gdu_device_get_device_file (device));
- volume->dev = gdu_device_get_dev (device);
- }
- else
- {
- volume->device_file = NULL;
- volume->dev = 0;
- }
-
- volume->can_mount = TRUE;
-
- /* 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 fs'es from all devices in a SAN etc - We REALLY
- * need to be CAREFUL here.
- *
- * Sidebar: Actually, a surprisingly large number of admins like
- * to log into GNOME as root (thus having all polkit
- * authorizations) and if weren't careful we'd
- * automount all mountable devices from the box. See
- * the enterprise distro bug trackers for details.
- */
- volume->should_automount = FALSE;
- if (volume->drive != NULL)
- {
- GduPresentable *drive_presentable;
- drive_presentable = g_gdu_drive_get_presentable (volume->drive);
- if (drive_presentable != NULL)
- {
- GduDevice *drive_device;
- drive_device = gdu_presentable_get_device (drive_presentable);
- if (drive_device != NULL)
- {
- if (gdu_device_is_drive (drive_device))
- {
- const gchar *connection_interface;
-
- connection_interface = gdu_device_drive_get_connection_interface (drive_device);
-
- if (g_strcmp0 (connection_interface, "usb") == 0 ||
- g_strcmp0 (connection_interface, "firewire") == 0 ||
- g_strcmp0 (connection_interface, "sdio") == 0 ||
- g_gdu_drive_device_is_flash (drive_device) ||
- gdu_device_is_optical_disc (drive_device))
- {
- volume->should_automount = TRUE;
- }
- }
- g_object_unref (drive_device);
- }
- }
-
- /* 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.
- */
- now = time (NULL);
- if (now - g_gdu_drive_get_time_of_last_media_insertion (volume->drive) > 5)
- volume->should_automount = FALSE;
- }
-
- /* Respect the presentation hint for whether the volume should be automounted - normally
- * nopolicy is only FALSE for "physical" devices - e.g. only "physical" devices will
- * be set to be automounted.
- */
- if (device != NULL && gdu_device_get_presentation_nopolicy (device))
- volume->should_automount = FALSE;
-
- g_free (activation_uri);
- }
-
- /* if there's an automount hint, use it */
- if (device != NULL)
- {
- if (g_strcmp0 (gdu_device_get_automount_hint (device), "always") == 0)
- volume->should_automount = TRUE;
- else if (g_strcmp0 (gdu_device_get_automount_hint (device), "never") == 0)
- volume->should_automount = FALSE;
- }
-
- if (pool != NULL)
- g_object_unref (pool);
- if (device != NULL)
- g_object_unref (device);
-
- /* ---------------------------------------------------------------------------------------------------- */
-
- update_done:
-
- /* compute whether something changed */
- changed = !((old_can_mount == volume->can_mount) &&
- (old_should_automount == volume->should_automount) &&
- (g_strcmp0 (old_name, volume->name) == 0) &&
- (g_strcmp0 (old_device_file, volume->device_file) == 0) &&
- (old_dev == volume->dev) &&
- g_icon_equal (old_icon, volume->icon)
- );
-
- /* free old values */
- g_free (old_name);
- g_free (old_device_file);
- if (old_icon != NULL)
- g_object_unref (old_icon);
-
- /*g_debug ("in update_volume(), changed=%d", changed);*/
-
- return changed;
-}
-
-static void
-gdu_volume_changed (GduPresentable *presentable,
- GGduVolume *volume)
-{
- /*g_debug ("volume: presentable_changed: %p: %s", volume, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_volume (volume))
- emit_changed (volume);
-}
-
-static void
-gdu_volume_job_changed (GduPresentable *presentable,
- GGduVolume *volume)
-{
- /*g_debug ("volume: presentable_job_changed %p: %s", volume, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_volume (volume))
- emit_changed (volume);
-}
-
-static void
-gdu_cleartext_volume_removed (GduPresentable *presentable,
- GGduVolume *volume)
-{
- /*g_debug ("cleartext volume: presentable_removed: %p: %s", volume, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_volume (volume))
- emit_changed (volume);
-}
-
-static void
-gdu_cleartext_volume_changed (GduPresentable *presentable,
- GGduVolume *volume)
-{
- /*g_debug ("cleartext volume: presentable_changed: %p: %s", volume, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_volume (volume))
- emit_changed (volume);
-}
-
-static void
-gdu_cleartext_volume_job_changed (GduPresentable *presentable,
- GGduVolume *volume)
-{
- /*g_debug ("cleartext volume: presentable_job_changed %p: %s", volume, gdu_presentable_get_id (GDU_PRESENTABLE (presentable)));*/
- if (update_volume (volume))
- emit_changed (volume);
-}
-
-GGduVolume *
-g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor *volume_monitor,
- GUnixMountPoint *unix_mount_point)
-{
- GGduVolume *volume;
-
- volume = g_object_new (G_TYPE_GDU_VOLUME, NULL);
- volume->volume_monitor = volume_monitor;
- g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(volume->volume_monitor));
-
- volume->unix_mount_point = unix_mount_point;
-
- update_volume (volume);
-
- return volume;
-}
-
-GGduVolume *
-g_gdu_volume_new (GVolumeMonitor *volume_monitor,
- GduVolume *gdu_volume,
- GGduDrive *drive,
- GFile *activation_root)
-{
- GGduVolume *volume;
-
- volume = g_object_new (G_TYPE_GDU_VOLUME, NULL);
- volume->volume_monitor = volume_monitor;
- g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(volume->volume_monitor));
-
- volume->gdu_volume = g_object_ref (gdu_volume);
- volume->activation_root = activation_root != NULL ? g_object_ref (activation_root) : NULL;
-
- g_signal_connect (volume->gdu_volume, "changed", G_CALLBACK (gdu_volume_changed), volume);
- g_signal_connect (volume->gdu_volume, "job-changed", G_CALLBACK (gdu_volume_job_changed), volume);
-
- volume->drive = drive;
- if (drive != NULL)
- g_gdu_drive_set_volume (drive, volume);
-
- update_volume (volume);
-
- return volume;
-}
-
-void
-g_gdu_volume_removed (GGduVolume *volume)
-{
- if (volume->pending_mount_op != NULL)
- cancel_pending_mount_op (volume->pending_mount_op);
-
- if (volume->mount != NULL)
- {
- g_gdu_mount_unset_volume (volume->mount, volume);
- volume->mount = NULL;
- }
-
- if (volume->drive != NULL)
- {
- g_gdu_drive_unset_volume (volume->drive, volume);
- volume->drive = NULL;
- }
-}
-
-void
-g_gdu_volume_set_mount (GGduVolume *volume,
- GGduMount *mount)
-{
- if (volume->mount != mount)
- {
-
- if (volume->mount != NULL)
- g_gdu_mount_unset_volume (volume->mount, volume);
-
- volume->mount = mount;
-
- emit_changed (volume);
- }
-}
-
-void
-g_gdu_volume_unset_mount (GGduVolume *volume,
- GGduMount *mount)
-{
- if (volume->mount == mount)
- {
- volume->mount = NULL;
- emit_changed (volume);
- }
-}
-
-void
-g_gdu_volume_set_drive (GGduVolume *volume,
- GGduDrive *drive)
-{
- if (volume->drive != drive)
- {
- if (volume->drive != NULL)
- g_gdu_drive_unset_volume (volume->drive, volume);
-
- volume->drive = drive;
-
- emit_changed (volume);
- }
-}
-
-void
-g_gdu_volume_unset_drive (GGduVolume *volume,
- GGduDrive *drive)
-{
- if (volume->drive == drive)
- {
- volume->drive = NULL;
- emit_changed (volume);
- }
-}
-
-static GIcon *
-g_gdu_volume_get_icon (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return volume->icon != NULL ? g_object_ref (volume->icon) : NULL;
-}
-
-static char *
-g_gdu_volume_get_name (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return g_strdup (volume->name);
-}
-
-static char *
-g_gdu_volume_get_uuid (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return g_strdup (volume->uuid);
-}
-
-static gboolean
-g_gdu_volume_can_mount (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return volume->can_mount;
-}
-
-static gboolean
-g_gdu_volume_can_eject (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- gboolean can_eject;
-
- can_eject = FALSE;
- if (volume->drive != NULL)
- can_eject = g_drive_can_eject (G_DRIVE (volume->drive));
-
- return can_eject;
-}
-
-static gboolean
-g_gdu_volume_should_automount (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return volume->should_automount;
-}
-
-static GDrive *
-g_gdu_volume_get_drive (GVolume *volume)
-{
- GGduVolume *gdu_volume = G_GDU_VOLUME (volume);
- GDrive *drive;
-
- drive = NULL;
- if (gdu_volume->drive != NULL)
- drive = g_object_ref (gdu_volume->drive);
-
- return drive;
-}
-
-static GMount *
-g_gdu_volume_get_mount (GVolume *volume)
-{
- GGduVolume *gdu_volume = G_GDU_VOLUME (volume);
- GMount *mount;
-
- mount = NULL;
- if (gdu_volume->mount != NULL)
- mount = g_object_ref (gdu_volume->mount);
-
- return mount;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gchar **
-get_mount_options (GduDevice *device,
- gboolean allow_user_interaction)
-{
- GPtrArray *p;
-
- p = g_ptr_array_new ();
-
- /* one day we might read this from user settings */
- if (g_strcmp0 (gdu_device_id_get_usage (device), "filesystem") == 0 &&
- g_strcmp0 (gdu_device_id_get_type (device), "vfat") == 0)
- {
- g_ptr_array_add (p, g_strdup ("flush"));
- }
-
- if (!allow_user_interaction)
- {
- g_ptr_array_add (p, g_strdup ("auth_no_user_interaction"));
- }
-
- g_ptr_array_add (p, NULL);
-
- return (gchar **) g_ptr_array_free (p, FALSE);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-struct MountOpData
-{
- GGduVolume *volume;
- GduDevice *device_to_mount;
- GSimpleAsyncResult *simple;
- GCancellable *cancellable;
- gulong cancelled_handler_id;
-
- GMountOperation *mount_operation;
- gulong mount_operation_reply_handler_id;
-
- gboolean is_cancelled;
-};
-
-static void
-mount_op_data_unref (MountOpData *data)
-{
- g_object_unref (data->volume);
- if (data->device_to_mount != NULL)
- g_object_unref (data->device_to_mount);
- g_object_unref (data->simple);
- if (data->cancelled_handler_id != 0)
- g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
- if (data->cancellable != NULL)
- g_object_unref (data->cancellable);
- if (data->mount_operation_reply_handler_id != 0)
- g_signal_handler_disconnect (data->mount_operation, data->mount_operation_reply_handler_id);
- if (data->mount_operation != NULL)
- g_object_unref (data->mount_operation);
- g_free (data);
-}
-
-static void
-cancel_pending_mount_op (MountOpData *data)
-{
- /* we are no longer pending */
- data->volume->pending_mount_op = NULL;
-
- data->is_cancelled = TRUE;
-
- /* send an ::aborted signal to make the dialog go away */
- if (data->mount_operation != NULL)
- g_signal_emit_by_name (data->mount_operation, "aborted");
-
- /* complete the operation (sends reply to caller) */
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "Operation was cancelled");
- g_simple_async_result_complete (data->simple);
-}
-
-static void
-mount_cb (GduDevice *device,
- gchar *mount_point,
- GError *error,
- gpointer user_data)
-{
- MountOpData *data = user_data;
-
- /* if we've already aborted due to device removal / cancellation, just bail out */
- if (data->is_cancelled)
- goto bailout;
-
- if (error != NULL)
- {
- /* be quiet if the DeviceKit-disks daemon is inhibited */
- if (error->code == GDU_ERROR_INHIBITED)
- {
- error->domain = G_IO_ERROR;
- error->code = G_IO_ERROR_FAILED_HANDLED;
- }
- g_simple_async_result_set_from_error (data->simple, error);
- g_error_free (error);
- }
- else
- {
- g_free (mount_point);
- }
-
- g_simple_async_result_complete (data->simple);
-
- bailout:
- data->volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
-
-}
-
-static void
-mount_cleartext_device (MountOpData *data,
- const gchar *object_path_of_cleartext_device)
-{
- GduPool *pool;
-
- /* if we've already aborted due to device removal / cancellation, just bail out */
- if (data->is_cancelled)
- {
- mount_op_data_unref (data);
- goto bailout;
- }
-
- pool = gdu_presentable_get_pool (GDU_PRESENTABLE (data->volume->gdu_volume));
-
- data->device_to_mount = gdu_pool_get_by_object_path (pool, object_path_of_cleartext_device);
- if (data->device_to_mount == NULL)
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Successfully unlocked encrypted volume but cleartext device does not exist");
- g_simple_async_result_complete (data->simple);
- data->volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
- }
- else
- {
- gchar **mount_options;
- mount_options = get_mount_options (data->device_to_mount, data->mount_operation != NULL);
- gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
- g_strfreev (mount_options);
- }
-
- g_object_unref (pool);
-
- bailout:
- ;
-}
-
-static void
-unlock_from_keyring_cb (GduDevice *device,
- char *object_path_of_cleartext_device,
- GError *error,
- gpointer user_data)
-{
- MountOpData *data = user_data;
-
- /* if we've already aborted due to device removal / cancellation, just bail out */
- if (data->is_cancelled)
- {
- mount_op_data_unref (data);
- goto bailout;
- }
-
- if (error != NULL)
- {
- /*g_debug ("keyring password didn't work: %s", error->message);*/
-
- /* The password we retrieved from the keyring didn't work. So go ahead and prompt
- * the user.
- */
- mount_with_mount_operation (data);
-
- g_error_free (error);
- }
- else
- {
- mount_cleartext_device (data, object_path_of_cleartext_device);
- g_free (object_path_of_cleartext_device);
- }
-
- bailout:
- ;
-}
-
-static void
-unlock_cb (GduDevice *device,
- gchar *object_path_of_cleartext_device,
- GError *error,
- gpointer user_data)
-{
- MountOpData *data = user_data;
-
- /* if we've already aborted due to device removal / cancellation, just bail out */
- if (data->is_cancelled)
- {
- mount_op_data_unref (data);
- goto bailout;
- }
-
- if (error != NULL)
- {
- /* be quiet if the daemon is inhibited */
- if (error->code == GDU_ERROR_INHIBITED)
- {
- error->domain = G_IO_ERROR;
- error->code = G_IO_ERROR_FAILED_HANDLED;
- }
- g_simple_async_result_set_from_error (data->simple, error);
- g_error_free (error);
- g_simple_async_result_complete (data->simple);
- data->volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
- }
- else
- {
- GPasswordSave password_save;
- const gchar *password;
-
- password_save = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (device), "password-save"));
- password = g_object_get_data (G_OBJECT (device), "password");
-
- if (password != NULL)
- {
- switch (password_save)
- {
- case G_PASSWORD_SAVE_FOR_SESSION:
- gdu_util_save_secret (device, password, TRUE);
- break;
-
- case G_PASSWORD_SAVE_PERMANENTLY:
- gdu_util_save_secret (device, password, FALSE);
- break;
-
- default:
- /* do nothing */
- break;
- }
- }
-
- /* now we have a cleartext device; update the GVolume details to show that */
- if (update_volume (data->volume))
- emit_changed (data->volume);
-
- mount_cleartext_device (data, object_path_of_cleartext_device);
- g_free (object_path_of_cleartext_device);
- }
-
- bailout:
-
- /* scrub the password */
- g_object_set_data (G_OBJECT (device), "password-save", NULL);
- g_object_set_data (G_OBJECT (device), "password", NULL);
-}
-
-static void
-scrub_n_free_string (char *password)
-{
- memset (password, '\0', strlen (password));
- g_free (password);
-}
-
-static void
-mount_operation_reply (GMountOperation *mount_operation,
- GMountOperationResult result,
- gpointer user_data)
-{
- MountOpData *data = user_data;
- GduDevice *device;
- const gchar *password;
-
- /* if we've already aborted due to device removal, just bail out */
- if (data->is_cancelled)
- {
- mount_op_data_unref (data);
- goto out;
- }
-
- /* we got what we wanted; don't listen to any other signals from the mount operation */
- if (data->mount_operation_reply_handler_id != 0)
- {
- g_signal_handler_disconnect (data->mount_operation, data->mount_operation_reply_handler_id);
- data->mount_operation_reply_handler_id = 0;
- }
-
- if (result != G_MOUNT_OPERATION_HANDLED)
- {
- if (result == G_MOUNT_OPERATION_ABORTED)
- {
- /* The user aborted the operation so consider it "handled" */
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "Password dialog aborted (user should never see this error since it is G_IO_ERROR_FAILED_HANDLED)");
- }
- else
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED,
- "Expected G_MOUNT_OPERATION_HANDLED but got %d", result);
- }
- g_simple_async_result_complete (data->simple);
- data->volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
- goto out;
- }
-
- password = g_mount_operation_get_password (mount_operation);
-
- device = gdu_presentable_get_device (GDU_PRESENTABLE (data->volume->gdu_volume));
-
- g_object_set_data (G_OBJECT (device),
- "password-save",
- GINT_TO_POINTER (g_mount_operation_get_password_save (mount_operation)));
- g_object_set_data_full (G_OBJECT (device),
- "password",
- g_strdup (password),
- (GDestroyNotify) scrub_n_free_string);
-
- gdu_device_op_luks_unlock (device, password, unlock_cb, data);
-
- g_object_unref (device);
-
- out:
- ;
-}
-
-static void
-mount_with_mount_operation (MountOpData *data)
-{
- gchar *message;
- gchar *drive_name;
- GduPresentable *toplevel;
- GduDevice *device;
-
- device = NULL;
- drive_name = NULL;
- message = NULL;
- toplevel = NULL;
-
- /* if we've already aborted due to device removal, just bail out */
- if (data->is_cancelled)
- {
- mount_op_data_unref (data);
- goto out;
- }
-
- if (data->mount_operation == NULL)
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Password required to access the encrypted data");
- g_simple_async_result_complete (data->simple);
- data->volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
- goto out;
- }
-
- device = gdu_presentable_get_device (GDU_PRESENTABLE (data->volume->gdu_volume));
-
- toplevel = gdu_presentable_get_enclosing_presentable (GDU_PRESENTABLE (data->volume->gdu_volume));
- /* handle logical partitions enclosed by an extented partition */
- if (GDU_IS_VOLUME (toplevel))
- {
- GduPresentable *temp;
- temp = toplevel;
- toplevel = gdu_presentable_get_enclosing_presentable (toplevel);
- g_object_unref (temp);
- if (!GDU_IS_DRIVE (toplevel))
- {
- g_object_unref (toplevel);
- toplevel = NULL;
- }
- }
-
- if (toplevel != NULL)
- drive_name = gdu_presentable_get_name (toplevel);
-
- if (drive_name != NULL)
- {
- if (gdu_device_is_partition (device))
- {
- message = g_strdup_printf (_("Enter a password to unlock the volume\n"
- "The device “%s” contains encrypted data on partition %d."),
- drive_name,
- gdu_device_partition_get_number (device));
- }
- else
- {
- message = g_strdup_printf (_("Enter a password to unlock the volume\n"
- "The device “%s” contains encrypted data."),
- drive_name);
- }
- }
- else
- {
- message = g_strdup_printf (_("Enter a password to unlock the volume\n"
- "The device %s contains encrypted data."),
- gdu_device_get_device_file (device));
- }
-
- data->mount_operation_reply_handler_id = g_signal_connect (data->mount_operation,
- "reply",
- G_CALLBACK (mount_operation_reply),
- data);
-
- g_signal_emit_by_name (data->mount_operation,
- "ask-password",
- message,
- NULL,
- NULL,
- G_ASK_PASSWORD_NEED_PASSWORD |
- G_ASK_PASSWORD_SAVING_SUPPORTED);
-
- out:
- g_free (drive_name);
- g_free (message);
- if (device != NULL)
- g_object_unref (device);
- if (toplevel != NULL)
- g_object_unref (toplevel);
-}
-
-static void
-cancelled_cb (GCancellable *cancellable,
- GGduVolume *volume)
-{
- if (volume->pending_mount_op != NULL)
- {
- cancel_pending_mount_op (volume->pending_mount_op);
- }
-}
-
-static void
-g_gdu_volume_mount (GVolume *_volume,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- GSimpleAsyncResult *simple;
- GduDevice *device;
- GduPool *pool;
- const gchar *usage;
- const gchar *type;
- MountOpData *data;
-
- pool = NULL;
- device = NULL;
-
- /* for fstab mounts, call the native mount command */
- if (volume->unix_mount_point != NULL)
- {
- g_gdu_volume_mount_unix_mount_point (volume,
- flags,
- mount_operation,
- cancellable,
- callback,
- user_data);
- goto out;
- }
-
- if (volume->pending_mount_op != NULL)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (volume),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "A mount operation is already pending");
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
-
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
-
- if (device == NULL)
- {
- simple = g_simple_async_result_new_error (G_OBJECT (volume),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Underlying device missing");
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
-
- pool = gdu_device_get_pool (device);
-
- /* Makes no sense to mount
- *
- * - blank discs since these already have a burn:/// mount
- * - other things that are already mounted
- *
- * Unfortunately Nautilus will try to do this anyway. For now, just return success for
- * such requests.
- */
- if (gdu_device_optical_disc_get_is_blank (device) || gdu_device_is_mounted (device))
- {
- simple = g_simple_async_result_new (G_OBJECT (volume),
- callback,
- user_data,
- g_gdu_volume_mount);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
-
- data = g_new0 (MountOpData, 1);
-
- data->volume = g_object_ref (volume);
-
- data->simple = g_simple_async_result_new (G_OBJECT (volume),
- callback,
- user_data,
- g_gdu_volume_mount);
-
- data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-
- data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
-
- if (data->cancellable != NULL)
- data->cancelled_handler_id = g_signal_connect (data->cancellable, "cancelled", G_CALLBACK (cancelled_cb), volume);
-
- volume->pending_mount_op = data;
-
- /* if the device is already unlocked, just attempt to mount it */
- if (volume->cleartext_gdu_volume != NULL)
- {
- GduDevice *luks_cleartext_volume_device;
- const gchar *object_path_of_cleartext_device;
-
- luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
-
- if (luks_cleartext_volume_device != NULL)
- {
- object_path_of_cleartext_device = gdu_device_get_object_path (luks_cleartext_volume_device);
-
- mount_cleartext_device (data, object_path_of_cleartext_device);
-
- g_object_unref (luks_cleartext_volume_device);
- }
- goto out;
- }
-
- usage = gdu_device_id_get_usage (device);
- type = gdu_device_id_get_type (device);
- if (g_strcmp0 (usage, "crypto") == 0 && g_strcmp0 (type, "crypto_LUKS") == 0)
- {
- gchar *password;
-
- /* if we have the secret in the keyring, try with that first */
- password = gdu_util_get_secret (device);
- if (password != NULL)
- {
- gdu_device_op_luks_unlock (device, password, unlock_from_keyring_cb, data);
-
- scrub_n_free_string (password);
- goto out;
- }
-
- /* don't put up a password dialog if the daemon is inhibited */
- if (gdu_pool_is_daemon_inhibited (pool))
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED_HANDLED,
- "Daemon is currently inhibited");
- g_simple_async_result_complete (data->simple);
- volume->pending_mount_op = NULL;
- mount_op_data_unref (data);
- goto out;
- }
-
- mount_with_mount_operation (data);
- }
- else
- {
- gchar **mount_options;
- data->device_to_mount = g_object_ref (device);
- mount_options = get_mount_options (data->device_to_mount, data->mount_operation != NULL);
- gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
- g_strfreev (mount_options);
- }
-
- out:
- if (pool != NULL)
- g_object_unref (pool);
- if (device != NULL)
- g_object_unref (device);
-}
-
-static gboolean
-g_gdu_volume_mount_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- //g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_gdu_volume_mount);
-
- return !g_simple_async_result_propagate_error (simple, error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef struct {
- GGduVolume *volume;
- GAsyncReadyCallback callback;
- gpointer user_data;
- GCancellable *cancellable;
- int error_fd;
- GIOChannel *error_channel;
- guint error_channel_source_id;
- GString *error_string;
-
- guint wait_for_mount_timeout_id;
- gulong wait_for_mount_changed_signal_handler_id;
-} MountPointOp;
-
-static void
-mount_point_op_free (MountPointOp *data)
-{
- if (data->error_channel_source_id > 0)
- g_source_remove (data->error_channel_source_id);
- if (data->error_channel != NULL)
- g_io_channel_unref (data->error_channel);
- if (data->error_string != NULL)
- g_string_free (data->error_string, TRUE);
- if (data->error_fd > 0)
- close (data->error_fd);
- g_free (data);
-}
-
-static void
-mount_point_op_changed_cb (GVolume *volume,
- gpointer user_data)
-{
- MountPointOp *data = user_data;
- GSimpleAsyncResult *simple;
-
- /* keep waiting if the mount hasn't appeared */
- if (data->volume->mount == NULL)
- goto out;
-
- simple = g_simple_async_result_new (G_OBJECT (data->volume),
- data->callback,
- data->user_data,
- NULL);
- /* complete in idle to make sure the mount is added before we return */
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
-
- g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
- g_source_remove (data->wait_for_mount_timeout_id);
-
- mount_point_op_free (data);
-
- out:
- ;
-}
-
-static gboolean
-mount_point_op_never_appeared_cb (gpointer user_data)
-{
- MountPointOp *data = user_data;
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new_error (G_OBJECT (data->volume),
- data->callback,
- data->user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Timeout waiting for mount to appear");
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
- g_source_remove (data->wait_for_mount_timeout_id);
-
- mount_point_op_free (data);
-
- return FALSE;
-}
-
-static void
-mount_point_op_cb (GPid pid, gint status, gpointer user_data)
-{
- MountPointOp *data = user_data;
- GSimpleAsyncResult *simple;
-
- g_spawn_close_pid (pid);
-
- if (WEXITSTATUS (status) != 0)
- {
- GError *error;
- error = g_error_new_literal (G_IO_ERROR,
- G_IO_ERROR_FAILED,
- data->error_string->str);
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
- data->callback,
- data->user_data,
- error);
- g_error_free (error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- mount_point_op_free (data);
- }
- else
- {
- /* wait for the GMount to appear - this is to honor this requirement
- *
- * "If the mount operation succeeded, g_volume_get_mount() on
- * volume is guaranteed to return the mount right after calling
- * this function; there's no need to listen for the
- * 'mount-added' signal on GVolumeMonitor."
- *
- * So we set up a signal handler waiting for it to appear. We also set up
- * a timer for handling the case when it never appears.
- */
- if (data->volume->mount == NULL)
- {
- /* no need to ref, GSimpleAsyncResult has a ref on data->volume */
- data->wait_for_mount_timeout_id = g_timeout_add (5 * 1000,
- mount_point_op_never_appeared_cb,
- data);
- data->wait_for_mount_changed_signal_handler_id = g_signal_connect (data->volume,
- "changed",
- G_CALLBACK (mount_point_op_changed_cb),
- data);
- }
- else
- {
- /* have the mount already, finish up */
- simple = g_simple_async_result_new (G_OBJECT (data->volume),
- data->callback,
- data->user_data,
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- mount_point_op_free (data);
- }
- }
-}
-
-static gboolean
-mount_point_op_read_error (GIOChannel *channel,
- GIOCondition condition,
- gpointer user_data)
-{
- MountPointOp *data = user_data;
- gchar buf[BUFSIZ];
- gsize bytes_read;
- GError *error;
- GIOStatus status;
-
- error = NULL;
-read:
- status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
- if (status == G_IO_STATUS_NORMAL)
- {
- g_string_append_len (data->error_string, buf, bytes_read);
- if (bytes_read == sizeof (buf))
- goto read;
- }
- else if (status == G_IO_STATUS_EOF)
- {
- g_string_append_len (data->error_string, buf, bytes_read);
- }
- else if (status == G_IO_STATUS_ERROR)
- {
- if (data->error_string->len > 0)
- g_string_append (data->error_string, "\n");
-
- g_string_append (data->error_string, error->message);
- g_error_free (error);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-g_gdu_volume_mount_unix_mount_point (GGduVolume *volume,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MountPointOp *data;
- GPid child_pid;
- GError *error;
- const gchar *argv[] = {"mount", NULL, NULL};
-
- argv[1] = g_unix_mount_point_get_mount_path (volume->unix_mount_point);
-
- data = g_new0 (MountPointOp, 1);
- data->volume = volume;
- data->callback = callback;
- data->user_data = user_data;
- data->cancellable = cancellable;
-
- error = NULL;
- if (!g_spawn_async_with_pipes (NULL, /* working dir */
- (gchar **) argv,
- NULL, /* envp */
- G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
- NULL, /* child_setup */
- NULL, /* user_data for child_setup */
- &child_pid,
- NULL, /* standard_input */
- NULL, /* standard_output */
- &(data->error_fd),
- &error))
- {
- g_assert (error != NULL);
- goto handle_error;
- }
-
- data->error_string = g_string_new ("");
-
- data->error_channel = g_io_channel_unix_new (data->error_fd);
- g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
- if (error != NULL)
- goto handle_error;
-
- data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, mount_point_op_read_error, data);
- g_child_watch_add (child_pid, mount_point_op_cb, data);
-
-handle_error:
- if (error != NULL)
- {
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
- data->callback,
- data->user_data,
- error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- mount_point_op_free (data);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef struct {
- GObject *object;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} EjectWrapperOp;
-
-static void
-eject_wrapper_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- EjectWrapperOp *data = user_data;
- data->callback (data->object, res, data->user_data);
- g_object_unref (data->object);
- g_free (data);
-}
-
-static void
-g_gdu_volume_eject_with_operation (GVolume *volume,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GGduVolume *gdu_volume = G_GDU_VOLUME (volume);
- GGduDrive *drive;
-
- drive = NULL;
- if (gdu_volume->drive != NULL)
- drive = g_object_ref (gdu_volume->drive);
-
- if (drive != NULL)
- {
- EjectWrapperOp *data;
- data = g_new0 (EjectWrapperOp, 1);
- data->object = g_object_ref (volume);
- data->callback = callback;
- data->user_data = user_data;
- g_drive_eject_with_operation (G_DRIVE (drive), flags, mount_operation, cancellable, eject_wrapper_callback, data);
- g_object_unref (drive);
- }
- else
- {
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new_error (G_OBJECT (volume),
- callback,
- user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Operation not supported by backend"));
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
-}
-
-static gboolean
-g_gdu_volume_eject_with_operation_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
-{
- GGduVolume *gdu_volume = G_GDU_VOLUME (volume);
- gboolean res;
-
- res = TRUE;
- if (gdu_volume->drive != NULL)
- {
- res = g_drive_eject_with_operation_finish (G_DRIVE (gdu_volume->drive), result, error);
- }
- else
- {
- g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
- res = FALSE;
- }
-
- return res;
-}
-
-static void
-g_gdu_volume_eject (GVolume *volume,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_gdu_volume_eject_with_operation (volume, flags, NULL, cancellable, callback, user_data);
-}
-
-static gboolean
-g_gdu_volume_eject_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
-{
- return g_gdu_volume_eject_with_operation_finish (volume, result, error);
-}
-
-static char *
-g_gdu_volume_get_identifier (GVolume *_volume,
- const char *kind)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- GduDevice *device;
- const gchar *label;
- const gchar *uuid;
- gchar *id;
-
- id = NULL;
-
- if (volume->gdu_volume != NULL)
- {
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
-
- if (device != NULL)
- {
- label = gdu_device_id_get_label (device);
- uuid = gdu_device_id_get_uuid (device);
-
- g_object_unref (device);
-
- if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
- id = g_strdup (volume->device_file);
- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
- id = strlen (label) > 0 ? g_strdup (label) : NULL;
- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
- id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
- }
- }
-
- return id;
-}
-
-static char **
-g_gdu_volume_enumerate_identifiers (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- GduDevice *device;
- GPtrArray *p;
- const gchar *label;
- const gchar *uuid;
-
- p = g_ptr_array_new ();
- label = NULL;
-
- if (volume->gdu_volume != NULL)
- {
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
-
- if (device != NULL)
- {
- label = gdu_device_id_get_label (device);
- uuid = gdu_device_id_get_uuid (device);
- g_object_unref (device);
-
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
- if (strlen (label) > 0)
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
- if (strlen (uuid) > 0)
- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
- }
- }
-
- g_ptr_array_add (p, NULL);
-
- return (gchar **) g_ptr_array_free (p, FALSE);
-}
-
-static GFile *
-g_gdu_volume_get_activation_root (GVolume *_volume)
-{
- GGduVolume *volume = G_GDU_VOLUME (_volume);
- return volume->activation_root != NULL ? g_object_ref (volume->activation_root) : NULL;
-}
-
-static void
-g_gdu_volume_volume_iface_init (GVolumeIface *iface)
-{
- iface->get_name = g_gdu_volume_get_name;
- iface->get_icon = g_gdu_volume_get_icon;
- iface->get_uuid = g_gdu_volume_get_uuid;
- iface->get_drive = g_gdu_volume_get_drive;
- iface->get_mount = g_gdu_volume_get_mount;
- iface->can_mount = g_gdu_volume_can_mount;
- iface->can_eject = g_gdu_volume_can_eject;
- iface->should_automount = g_gdu_volume_should_automount;
- iface->mount_fn = g_gdu_volume_mount;
- iface->mount_finish = g_gdu_volume_mount_finish;
- iface->eject = g_gdu_volume_eject;
- iface->eject_finish = g_gdu_volume_eject_finish;
- iface->eject_with_operation = g_gdu_volume_eject_with_operation;
- iface->eject_with_operation_finish = g_gdu_volume_eject_with_operation_finish;
- iface->get_identifier = g_gdu_volume_get_identifier;
- iface->enumerate_identifiers = g_gdu_volume_enumerate_identifiers;
- iface->get_activation_root = g_gdu_volume_get_activation_root;
-}
-
-gboolean
-g_gdu_volume_has_dev (GGduVolume *volume,
- dev_t dev)
-{
- dev_t _dev;
-
- _dev = volume->dev;
-
- if (volume->cleartext_gdu_volume != NULL)
- {
- GduDevice *luks_cleartext_volume_device;
- luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
- if (luks_cleartext_volume_device != NULL)
- {
- _dev = gdu_device_get_dev (luks_cleartext_volume_device);
- g_object_unref (luks_cleartext_volume_device);
- }
- }
-
- return _dev == dev;
-}
-
-gboolean
-g_gdu_volume_has_device_file (GGduVolume *volume,
- const gchar *device_file)
-{
- const gchar *_device_file;
-
- _device_file = volume->device_file;
-
- if (volume->cleartext_gdu_volume != NULL)
- {
- GduDevice *luks_cleartext_volume_device;
- luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
- if (luks_cleartext_volume_device != NULL)
- {
- _device_file = gdu_device_get_device_file (luks_cleartext_volume_device);
- g_object_unref (luks_cleartext_volume_device);
- }
- }
-
- return g_strcmp0 (_device_file, device_file) == 0;
-}
-
-
-gboolean
-g_gdu_volume_has_mount_path (GGduVolume *volume,
- const char *mount_path)
-{
- GduDevice *device;
- GduPresentable *presentable;
- gboolean ret;
-
- ret = FALSE;
-
- presentable = g_gdu_volume_get_presentable_with_cleartext (volume);
- if (presentable != NULL)
- {
- device = gdu_presentable_get_device (presentable);
- if (device != NULL)
- {
- ret = g_strcmp0 (gdu_device_get_mount_path (device), mount_path) == 0;
- g_object_unref (device);
- }
- }
-
- return ret;
-}
-
-gboolean
-g_gdu_volume_has_uuid (GGduVolume *volume,
- const char *uuid)
-{
- const gchar *_uuid;
-
- _uuid = volume->uuid;
-
- if (volume->cleartext_gdu_volume != NULL)
- {
- GduDevice *luks_cleartext_volume_device;
- luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume));
- if (luks_cleartext_volume_device != NULL)
- {
- _uuid = gdu_device_id_get_uuid (luks_cleartext_volume_device);
- g_object_unref (luks_cleartext_volume_device);
- }
- }
-
- return g_strcmp0 (_uuid, uuid) == 0;
-}
-
-GduPresentable *
-g_gdu_volume_get_presentable (GGduVolume *volume)
-{
- return GDU_PRESENTABLE (volume->gdu_volume);
-}
-
-GduPresentable *
-g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume)
-{
- GduVolume *ret;
-
- ret = volume->cleartext_gdu_volume;
- if (ret == NULL)
- ret = volume->gdu_volume;
-
- return GDU_PRESENTABLE (ret);
-}
-
-GUnixMountPoint *
-g_gdu_volume_get_unix_mount_point (GGduVolume *volume)
-{
- return volume->unix_mount_point;
-}
-
-gboolean
-g_gdu_volume_has_presentable (GGduVolume *volume,
- GduPresentable *presentable)
-{
- return volume->gdu_volume != NULL &&
- g_strcmp0 (gdu_presentable_get_id (GDU_PRESENTABLE (volume->gdu_volume)),
- gdu_presentable_get_id (presentable)) == 0;
-}
diff --git a/monitor/gdu/ggduvolume.h b/monitor/gdu/ggduvolume.h
deleted file mode 100644
index 3f037429..00000000
--- a/monitor/gdu/ggduvolume.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#ifndef __G_GDU_VOLUME_H__
-#define __G_GDU_VOLUME_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include "ggduvolumemonitor.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_GDU_VOLUME (g_gdu_volume_get_type ())
-#define G_GDU_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_GDU_VOLUME, GGduVolume))
-#define G_GDU_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_GDU_VOLUME, GGduVolumeClass))
-#define G_IS_GDU_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_GDU_VOLUME))
-#define G_IS_GDU_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_GDU_VOLUME))
-
-typedef struct _GGduVolumeClass GGduVolumeClass;
-
-struct _GGduVolumeClass {
- GObjectClass parent_class;
-};
-
-GType g_gdu_volume_get_type (void) G_GNUC_CONST;
-
-GGduVolume *g_gdu_volume_new (GVolumeMonitor *volume_monitor,
- GduVolume *gdu_volume,
- GGduDrive *drive,
- GFile *activation_root);
-
-GGduVolume *g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor *volume_monitor,
- GUnixMountPoint *unix_mount_point);
-
-void g_gdu_volume_set_mount (GGduVolume *volume,
- GGduMount *mount);
-void g_gdu_volume_unset_mount (GGduVolume *volume,
- GGduMount *mount);
-
-void g_gdu_volume_set_drive (GGduVolume *volume,
- GGduDrive *drive);
-void g_gdu_volume_unset_drive (GGduVolume *volume,
- GGduDrive *drive);
-
-void g_gdu_volume_removed (GGduVolume *volume);
-
-gboolean g_gdu_volume_has_mount_path (GGduVolume *volume,
- const char *mount_path);
-gboolean g_gdu_volume_has_uuid (GGduVolume *volume,
- const char *uuid);
-gboolean g_gdu_volume_has_device_file (GGduVolume *volume,
- const gchar *device_file);
-gboolean g_gdu_volume_has_dev (GGduVolume *volume,
- dev_t dev);
-gboolean g_gdu_volume_has_presentable (GGduVolume *volume,
- GduPresentable *presentable);
-
-GduPresentable *g_gdu_volume_get_presentable (GGduVolume *volume);
-
-GduPresentable *g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume);
-
-GUnixMountPoint *g_gdu_volume_get_unix_mount_point (GGduVolume *volume);
-
-G_END_DECLS
-
-#endif /* __G_GDU_VOLUME_H__ */
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
deleted file mode 100644
index 1ecf4181..00000000
--- a/monitor/gdu/ggduvolumemonitor.c
+++ /dev/null
@@ -1,1812 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#include <config.h>
-
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-
-#include "ggduvolumemonitor.h"
-#include "ggdumount.h"
-#include "ggduvolume.h"
-#include "ggdudrive.h"
-
-static GGduVolumeMonitor *the_volume_monitor = NULL;
-
-struct _GGduVolumeMonitor {
- GNativeVolumeMonitor parent;
-
- GUnixMountMonitor *mount_monitor;
-
- GduPool *pool;
-
- GList *last_optical_disc_devices;
- GList *last_mountpoints;
- GList *last_mounts;
-
- GList *drives;
- GList *volumes;
- GList *fstab_volumes;
- GList *mounts;
-
- /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */
- GList *disc_volumes;
- GList *disc_mounts;
-
-};
-
-static void mountpoints_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data);
-static void mounts_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data);
-
-static void presentable_added (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data);
-static void presentable_removed (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data);
-
-static void update_all (GGduVolumeMonitor *monitor,
- gboolean emit_changes);
-
-static void update_drives (GGduVolumeMonitor *monitor,
- GList **added_drives,
- GList **removed_drives);
-static void update_volumes (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes);
-static void update_fstab_volumes (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes);
-static void update_mounts (GGduVolumeMonitor *monitor,
- GList **added_mounts,
- GList **removed_mounts);
-static void update_discs (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes,
- GList **added_mounts,
- GList **removed_mounts);
-
-
-G_DEFINE_TYPE (GGduVolumeMonitor, g_gdu_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR)
-
-static void
-list_free (GList *objects)
-{
- g_list_foreach (objects, (GFunc)g_object_unref, NULL);
- g_list_free (objects);
-}
-
-static void
-g_gdu_volume_monitor_dispose (GObject *object)
-{
- the_volume_monitor = NULL;
-
- if (G_OBJECT_CLASS (g_gdu_volume_monitor_parent_class)->dispose)
- (*G_OBJECT_CLASS (g_gdu_volume_monitor_parent_class)->dispose) (object);
-}
-
-static void
-g_gdu_volume_monitor_finalize (GObject *object)
-{
- GGduVolumeMonitor *monitor;
-
- monitor = G_GDU_VOLUME_MONITOR (object);
-
- g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mountpoints_changed, monitor);
- g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mounts_changed, monitor);
- g_signal_handlers_disconnect_by_func (monitor->mount_monitor, presentable_added, monitor);
- g_signal_handlers_disconnect_by_func (monitor->mount_monitor, presentable_removed, monitor);
-
- g_object_unref (monitor->mount_monitor);
-
- g_clear_object (&monitor->pool);
-
- list_free (monitor->last_optical_disc_devices);
- list_free (monitor->last_mountpoints);
- g_list_foreach (monitor->last_mounts,
- (GFunc)g_unix_mount_free, NULL);
- g_list_free (monitor->last_mounts);
-
- list_free (monitor->drives);
- list_free (monitor->fstab_volumes);
- list_free (monitor->volumes);
- list_free (monitor->mounts);
-
- list_free (monitor->disc_volumes);
- list_free (monitor->disc_mounts);
-
- if (G_OBJECT_CLASS (g_gdu_volume_monitor_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_gdu_volume_monitor_parent_class)->finalize) (object);
-}
-
-static GList *
-get_mounts (GVolumeMonitor *volume_monitor)
-{
- GGduVolumeMonitor *monitor;
- GList *l, *ll;
-
- monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
-
- l = g_list_copy (monitor->mounts);
- ll = g_list_copy (monitor->disc_mounts);
- l = g_list_concat (l, ll);
-
- g_list_foreach (l, (GFunc)g_object_ref, NULL);
-
- return l;
-}
-
-static GList *
-get_volumes (GVolumeMonitor *volume_monitor)
-{
- GGduVolumeMonitor *monitor;
- GList *l, *ll;
-
- monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
-
- l = g_list_copy (monitor->volumes);
- ll = g_list_copy (monitor->fstab_volumes);
- l = g_list_concat (l, ll);
- ll = g_list_copy (monitor->disc_volumes);
- l = g_list_concat (l, ll);
-
- g_list_foreach (l, (GFunc)g_object_ref, NULL);
-
- return l;
-}
-
-static GList *
-get_connected_drives (GVolumeMonitor *volume_monitor)
-{
- GGduVolumeMonitor *monitor;
- GList *l;
-
- monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
-
- l = g_list_copy (monitor->drives);
- g_list_foreach (l, (GFunc)g_object_ref, NULL);
-
- return l;
-}
-
-static GVolume *
-get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
-{
- GGduVolumeMonitor *monitor;
- GGduVolume *volume;
- GList *l;
-
- monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
-
- volume = NULL;
-
- for (l = monitor->volumes; l != NULL; l = l->next)
- {
- volume = l->data;
- if (g_gdu_volume_has_uuid (volume, uuid))
- goto found;
- }
-
- for (l = monitor->fstab_volumes; l != NULL; l = l->next)
- {
- volume = l->data;
- if (g_gdu_volume_has_uuid (volume, uuid))
- goto found;
- }
-
- for (l = monitor->disc_volumes; l != NULL; l = l->next)
- {
- volume = l->data;
- if (g_gdu_volume_has_uuid (volume, uuid))
- goto found;
- }
-
- return NULL;
-
- found:
-
- g_object_ref (volume);
-
- return (GVolume *)volume;
-}
-
-static GMount *
-get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
-{
- GGduVolumeMonitor *monitor;
- GGduMount *mount;
- GList *l;
-
- monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
-
- mount = NULL;
-
- for (l = monitor->mounts; l != NULL; l = l->next)
- {
- mount = l->data;
- if (g_gdu_mount_has_uuid (mount, uuid))
- goto found;
- }
-
- for (l = monitor->disc_mounts; l != NULL; l = l->next)
- {
- mount = l->data;
- if (g_gdu_mount_has_uuid (mount, uuid))
- goto found;
- }
-
- return NULL;
-
- found:
-
- g_object_ref (mount);
-
- return (GMount *)mount;
-}
-
-static GMount *
-get_mount_for_mount_path (const char *mount_path,
- GCancellable *cancellable)
-{
- GMount *mount;
- GGduMount *gdu_mount;
- GGduVolumeMonitor *volume_monitor;
-
- if (the_volume_monitor == NULL)
- {
- /* Dammit, no monitor is set up.. so we have to create one, find
- * what the user asks for and throw it away again.
- *
- * What a waste - especially considering that there's IO
- * involved in doing this: connect to the system message bus;
- * IPC to DeviceKit-disks etc etc
- */
- volume_monitor = G_GDU_VOLUME_MONITOR (g_gdu_volume_monitor_new ());
- }
- else
- {
- volume_monitor = g_object_ref (the_volume_monitor);
- }
-
- mount = NULL;
-
- /* creation of the volume monitor might actually fail */
- if (volume_monitor != NULL)
- {
- GList *l;
-
- for (l = volume_monitor->mounts; l != NULL; l = l->next)
- {
- gdu_mount = l->data;
-
- if (g_gdu_mount_has_mount_path (gdu_mount, mount_path))
- {
- mount = g_object_ref (gdu_mount);
- break;
- }
- }
- }
-
- g_object_unref (volume_monitor);
-
- return (GMount *) mount;
-}
-
-static void
-mountpoints_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- update_all (monitor, TRUE);
-}
-
-static void
-mounts_changed (GUnixMountMonitor *mount_monitor,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- update_all (monitor, TRUE);
-}
-
-static void
-presentable_added (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- /*g_debug ("presentable_added %p: %s", presentable, gdu_presentable_get_id (presentable));*/
-
- update_all (monitor, TRUE);
-}
-
-static void
-presentable_removed (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- /*g_debug ("presentable_removed %p: %s", presentable, gdu_presentable_get_id (presentable));*/
-
- update_all (monitor, TRUE);
-}
-
-static void
-presentable_changed (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- /*g_debug ("presentable_changed %p: %s", presentable, gdu_presentable_get_id (presentable));*/
-
- update_all (monitor, TRUE);
-}
-
-static void
-presentable_job_changed (GduPool *pool,
- GduPresentable *presentable,
- gpointer user_data)
-{
- GGduVolumeMonitor *monitor = G_GDU_VOLUME_MONITOR (user_data);
-
- /*g_debug ("presentable_job_changed %p: %s", presentable, gdu_presentable_get_id (presentable));*/
-
- update_all (monitor, TRUE);
-}
-
-static GObject *
-g_gdu_volume_monitor_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
-{
- GObject *object;
- GGduVolumeMonitor *monitor;
- GGduVolumeMonitorClass *klass;
- GObjectClass *parent_class;
-
- if (the_volume_monitor != NULL)
- {
- object = g_object_ref (the_volume_monitor);
- return object;
- }
-
- /*g_warning ("creating gdu vm");*/
-
- object = NULL;
-
- /* Invoke parent constructor. */
- klass = G_GDU_VOLUME_MONITOR_CLASS (g_type_class_peek (G_TYPE_GDU_VOLUME_MONITOR));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
- object = parent_class->constructor (type,
- n_construct_properties,
- construct_properties);
-
- monitor = G_GDU_VOLUME_MONITOR (object);
-
- monitor->mount_monitor = g_unix_mount_monitor_get ();
-
- g_signal_connect (monitor->mount_monitor,
- "mounts_changed",
- G_CALLBACK (mounts_changed),
- monitor);
-
- g_signal_connect (monitor->mount_monitor,
- "mountpoints_changed",
- G_CALLBACK (mountpoints_changed),
- monitor);
-
- monitor->pool = gdu_pool_new ();
-
- if (monitor->pool != NULL)
- {
- g_signal_connect (monitor->pool,
- "presentable_added",
- G_CALLBACK (presentable_added),
- monitor);
-
- g_signal_connect (monitor->pool,
- "presentable_removed",
- G_CALLBACK (presentable_removed),
- monitor);
-
- g_signal_connect (monitor->pool,
- "presentable_changed",
- G_CALLBACK (presentable_changed),
- monitor);
-
- g_signal_connect (monitor->pool,
- "presentable_job_changed",
- G_CALLBACK (presentable_job_changed),
- monitor);
- }
-
- update_all (monitor, FALSE);
-
- the_volume_monitor = monitor;
-
- return object;
-}
-
-static void
-g_gdu_volume_monitor_init (GGduVolumeMonitor *monitor)
-{
-}
-
-static gboolean
-is_supported (void)
-{
- /* TODO: return FALSE if DeviceKit-disks is not available */
- return TRUE;
-}
-
-static void
-g_gdu_volume_monitor_class_init (GGduVolumeMonitorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
- GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass);
-
- gobject_class->constructor = g_gdu_volume_monitor_constructor;
- gobject_class->finalize = g_gdu_volume_monitor_finalize;
- gobject_class->dispose = g_gdu_volume_monitor_dispose;
-
- monitor_class->get_mounts = get_mounts;
- monitor_class->get_volumes = get_volumes;
- monitor_class->get_connected_drives = get_connected_drives;
- monitor_class->get_volume_for_uuid = get_volume_for_uuid;
- monitor_class->get_mount_for_uuid = get_mount_for_uuid;
- monitor_class->is_supported = is_supported;
-
- native_class->get_mount_for_mount_path = get_mount_for_mount_path;
-}
-
-/**
- * g_gdu_volume_monitor_new:
- *
- * Returns: a new #GVolumeMonitor.
- **/
-GVolumeMonitor *
-g_gdu_volume_monitor_new (void)
-{
- GGduVolumeMonitor *monitor;
-
- monitor = g_object_new (G_TYPE_GDU_VOLUME_MONITOR, NULL);
-
- return G_VOLUME_MONITOR (monitor);
-}
-
-static void
-diff_sorted_lists (GList *list1,
- GList *list2,
- GCompareFunc compare,
- GList **added,
- GList **removed)
-{
- int order;
-
- *added = *removed = NULL;
-
- while (list1 != NULL &&
- list2 != NULL)
- {
- order = (*compare) (list1->data, list2->data);
- if (order < 0)
- {
- *removed = g_list_prepend (*removed, list1->data);
- list1 = list1->next;
- }
- else if (order > 0)
- {
- *added = g_list_prepend (*added, list2->data);
- list2 = list2->next;
- }
- else
- { /* same item */
- list1 = list1->next;
- list2 = list2->next;
- }
- }
-
- while (list1 != NULL)
- {
- *removed = g_list_prepend (*removed, list1->data);
- list1 = list1->next;
- }
- while (list2 != NULL)
- {
- *added = g_list_prepend (*added, list2->data);
- list2 = list2->next;
- }
-}
-
-static GGduVolume *
-find_volume_for_mount_path (GGduVolumeMonitor *monitor,
- const char *mount_path)
-{
- GList *l;
- GGduVolume *found;
-
- found = NULL;
-
- for (l = monitor->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- if (g_gdu_volume_has_mount_path (volume, mount_path))
- {
- found = volume;
- goto out;
- }
- }
-
- for (l = monitor->fstab_volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- if (g_gdu_volume_has_mount_path (volume, mount_path))
- {
- found = volume;
- goto out;
- }
- }
-
- out:
- return found;
-}
-
-static GGduVolume *
-find_volume_for_unix_mount_point (GGduVolumeMonitor *monitor,
- GUnixMountPoint *unix_mount_point)
-{
- GList *l;
- GGduVolume *found;
-
- found = NULL;
- for (l = monitor->fstab_volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = l->data;
- GUnixMountPoint *volume_mount_point;
-
- volume_mount_point = g_gdu_volume_get_unix_mount_point (volume);
- if (g_unix_mount_point_compare (unix_mount_point, volume_mount_point) == 0)
- {
- found = volume;
- goto out;
- }
- }
-
- out:
- return found;
-}
-
-static GGduMount *
-find_mount_by_mount_path (GGduVolumeMonitor *monitor,
- const char *mount_path)
-{
- GList *l;
-
- for (l = monitor->mounts; l != NULL; l = l->next)
- {
- GGduMount *mount = l->data;
-
- if (g_gdu_mount_has_mount_path (mount, mount_path))
- return mount;
- }
-
- return NULL;
-}
-
-/* TODO: move to gio */
-static gboolean
-_g_unix_mount_point_guess_should_display (GUnixMountPoint *mount_point)
-{
- const char *mount_path;
-
- mount_path = g_unix_mount_point_get_mount_path (mount_point);
-
- /* Never display internal mountpoints */
- if (g_unix_is_mount_path_system_internal (mount_path))
- return FALSE;
-
- /* Hide mounts within a dot path, suppose it was a purpose to hide this mount */
- if (g_strstr_len (mount_path, -1, "/.") != NULL)
- return FALSE;
-
- /* Only display things in /media (which are generally user mountable)
- and home dir (fuse stuff) */
- if (g_str_has_prefix (mount_path, "/media/"))
- return TRUE;
-
- if (g_str_has_prefix (mount_path, g_get_home_dir ()))
- return TRUE;
-
- return FALSE;
-}
-
-static GUnixMountPoint *
-get_mount_point_for_device (GduDevice *d, GList *fstab_mount_points)
-{
- GList *l;
- const gchar *device_file;
- const gchar *mount_path;
- GUnixMountPoint *ret;
-
- ret = NULL;
-
- mount_path = gdu_device_get_mount_path (d);
-
- device_file = gdu_device_get_device_file (d);
-
- for (l = fstab_mount_points; l != NULL; l = l->next)
- {
- GUnixMountPoint *mount_point = l->data;
- const gchar *fstab_device_file;
- const gchar *fstab_mount_path;
-
- fstab_mount_path = g_unix_mount_point_get_mount_path (mount_point);
- if (g_strcmp0 (mount_path, fstab_mount_path) == 0)
- {
- ret = mount_point;
- goto out;
- }
-
- fstab_device_file = g_unix_mount_point_get_device_path (mount_point);
- if (g_str_has_prefix (fstab_device_file, "LABEL="))
- {
- if (g_strcmp0 (fstab_device_file + 6, gdu_device_id_get_label (d)) == 0)
- {
- ret = mount_point;
- goto out;
- }
- }
- else if (g_str_has_prefix (fstab_device_file, "UUID="))
- {
- if (g_ascii_strcasecmp (fstab_device_file + 5, gdu_device_id_get_uuid (d)) == 0)
- {
- ret = mount_point;
- goto out;
- }
- }
- else
- {
- char resolved_fstab_device_file[PATH_MAX];
-
- /* handle symlinks such as /dev/disk/by-uuid/47C2-1994 */
- if (realpath (fstab_device_file, resolved_fstab_device_file) != NULL &&
- g_strcmp0 (resolved_fstab_device_file, device_file) == 0)
- {
- ret = mount_point;
- goto out;
- }
- }
- }
-
- out:
- return ret;
-}
-
-static gboolean
-should_mount_be_ignored (GduPool *pool, GduDevice *d)
-{
- gboolean ret;
- const gchar *mount_path;
- GUnixMountEntry *mount_entry;
-
- ret = FALSE;
-
- if (gdu_device_get_presentation_hide (d))
- {
- ret = TRUE;
- goto out;
- }
-
- mount_path = gdu_device_get_mount_path (d);
- if (mount_path == NULL || strlen (mount_path) == 0)
- goto out;
-
- mount_entry = g_unix_mount_at (mount_path, NULL);
- if (mount_entry != NULL)
- {
- if (!g_unix_mount_guess_should_display (mount_entry))
- {
- ret = TRUE;
- }
- g_unix_mount_free (mount_entry);
- }
-
- out:
- return ret;
-}
-
-gboolean
-_is_pc_floppy_drive (GduDevice *device)
-{
- gboolean ret;
- gchar **drive_media_compat;
- const gchar *drive_connection_interface;
-
- ret = FALSE;
-
- if (device != NULL)
- {
- drive_media_compat = gdu_device_drive_get_media_compatibility (device);
- drive_connection_interface = gdu_device_drive_get_connection_interface (device);
-
- if (g_strcmp0 (drive_connection_interface, "platform") == 0 &&
- (drive_media_compat != NULL &&
- g_strv_length (drive_media_compat) > 0 &&
- g_strcmp0 (drive_media_compat[0], "floppy") == 0))
- {
- ret = TRUE;
- }
- }
-
- return ret;
-}
-
-static gboolean
-should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_points)
-{
- GduDevice *device;
- gboolean ret;
- const gchar *usage;
- const gchar *type;
-
- ret = TRUE;
-
- device = gdu_presentable_get_device (GDU_PRESENTABLE (volume));
- if (device == NULL)
- goto out;
-
- if (gdu_device_get_presentation_hide (device))
- goto out;
-
- usage = gdu_device_id_get_usage (device);
- type = gdu_device_id_get_type (device);
-
- if (_is_pc_floppy_drive (device) || g_strcmp0 (usage, "filesystem") == 0)
- {
- GUnixMountPoint *mount_point;
-
- /* don't ignore volumes with a mountable filesystem unless
- *
- * - volume is referenced in /etc/fstab and deemed to be ignored
- *
- * - volume is mounted and should_mount_be_ignored() deems it should be ignored
- *
- * - volume is a cleartext LUKS device as the cryptotext LUKS volume will morph
- * into the cleartext volume when unlocked (see ggduvolume.c)
- */
-
- if (gdu_device_is_luks_cleartext (device))
- goto out;
-
- mount_point = get_mount_point_for_device (device, fstab_mount_points);
- if (mount_point != NULL && !_g_unix_mount_point_guess_should_display (mount_point))
- goto out;
-
- if (gdu_device_is_mounted (device))
- {
- ret = should_mount_be_ignored (pool, device);
- goto out;
- }
-
- ret = FALSE;
-
- }
- else if (g_strcmp0 (usage, "crypto") == 0 && g_strcmp0 (type, "crypto_LUKS") == 0)
- {
- /* don't ignore LUKS volumes */
- ret = FALSE;
- }
-
- out:
-
- if (device != NULL)
- g_object_unref (device);
- return ret;
-}
-
-static gboolean
-should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
-{
- GduDevice *device;
- gboolean ignored;
- gboolean have_volumes;
- gboolean all_volumes_are_ignored;
- GList *enclosed;
- GList *l;
-
- ignored = FALSE;
- enclosed = NULL;
-
- device = gdu_presentable_get_device (GDU_PRESENTABLE (d));
-
- /* If there is no GduDevice for a drive, then ignore it unless
- * we know how to start it (e.g. RAID arrays, Volume Groups)
- */
- if (device == NULL)
- {
- if (!gdu_drive_is_activatable (d))
- {
- ignored = TRUE;
- goto out;
- }
- }
-
- if (device != NULL && gdu_device_get_presentation_hide (device)) {
- ignored = TRUE;
- goto out;
- }
-
- have_volumes = FALSE;
- all_volumes_are_ignored = TRUE;
-
- /* never ignore a drive if it has volumes that we don't want to ignore */
- enclosed = gdu_pool_get_enclosed_presentables (pool, GDU_PRESENTABLE (d));
- for (l = enclosed; l != NULL && all_volumes_are_ignored; l = l->next)
- {
- GduPresentable *enclosed_presentable = GDU_PRESENTABLE (l->data);
-
- /* There might be other presentables that GduVolume objects; for example GduVolumeHole */
- if (GDU_IS_VOLUME (enclosed_presentable))
- {
- GduVolume *volume = GDU_VOLUME (enclosed_presentable);
- GduDevice *volume_device;
-
- have_volumes = TRUE;
-
- if (!should_volume_be_ignored (pool, volume, fstab_mount_points))
- {
- all_volumes_are_ignored = FALSE;
- break;
- }
-
- /* The volume may be an extended partition - we need to check all logical
- * partitions as well (#597041)
- */
- volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume));
- if (volume_device != NULL)
- {
- if (g_strcmp0 (gdu_device_partition_get_scheme (volume_device), "mbr") == 0)
- {
- gint type;
-
- type = strtol (gdu_device_partition_get_type (volume_device), NULL, 0);
- if (type == 0x05 || type == 0x0f || type == 0x85)
- {
- GList *enclosed_logical;
- GList *ll;
-
- enclosed_logical = gdu_pool_get_enclosed_presentables (pool, GDU_PRESENTABLE (volume));
- for (ll = enclosed_logical; ll != NULL && all_volumes_are_ignored; ll = ll->next)
- {
- GduPresentable *enclosed_logical_presentable = GDU_PRESENTABLE (ll->data);
-
- if (GDU_IS_VOLUME (enclosed_logical_presentable))
- {
- if (!should_volume_be_ignored (pool,
- GDU_VOLUME (enclosed_logical_presentable),
- fstab_mount_points))
- {
- all_volumes_are_ignored = FALSE;
- }
- }
- }
- g_list_foreach (enclosed_logical, (GFunc) g_object_unref, NULL);
- g_list_free (enclosed_logical);
- }
- }
- g_object_unref (volume_device);
- }
- }
- }
-
- /* we ignore a drive if
- *
- * a) no volumes are available AND media is available; OR
- *
- * b) the volumes of the drive are all ignored
- */
- if (device != NULL)
- {
- if (!have_volumes)
- {
- if (gdu_device_is_media_available (device))
- ignored = TRUE;
- }
- else
- {
- if (all_volumes_are_ignored)
- ignored = TRUE;
- }
-
- /* special case for audio and blank discs: don't ignore the drive since we'll create
- * a cdda:// or burn:// mount for the drive
- */
- if (gdu_device_is_optical_disc (device) && (gdu_device_optical_disc_get_num_audio_tracks (device) > 0 ||
- gdu_device_optical_disc_get_is_blank (device)))
- {
- ignored = FALSE;
- }
- }
-
- out:
- g_list_foreach (enclosed, (GFunc) g_object_unref, NULL);
- g_list_free (enclosed);
-
- if (device != NULL)
- g_object_unref (device);
-
- return ignored;
-}
-
-static void
-list_emit (GGduVolumeMonitor *monitor,
- const char *monitor_signal,
- const char *object_signal,
- GList *objects)
-{
- GList *l;
-
- for (l = objects; l != NULL; l = l->next)
- {
- g_signal_emit_by_name (monitor, monitor_signal, l->data);
- if (object_signal)
- g_signal_emit_by_name (l->data, object_signal);
- }
-}
-
-static void
-update_all (GGduVolumeMonitor *monitor,
- gboolean emit_changes)
-{
- GList *added_drives, *removed_drives;
- GList *added_volumes, *removed_volumes;
- GList *added_mounts, *removed_mounts;
-
- added_drives = NULL;
- removed_drives = NULL;
- added_volumes = NULL;
- removed_volumes = NULL;
- added_mounts = NULL;
- removed_mounts = NULL;
-
- update_drives (monitor, &added_drives, &removed_drives);
- update_volumes (monitor, &added_volumes, &removed_volumes);
- update_fstab_volumes (monitor, &added_volumes, &removed_volumes);
- update_mounts (monitor, &added_mounts, &removed_mounts);
- update_discs (monitor,
- &added_volumes, &removed_volumes,
- &added_mounts, &removed_mounts);
-
- if (emit_changes)
- {
- list_emit (monitor,
- "drive_disconnected", NULL,
- removed_drives);
- list_emit (monitor,
- "drive_connected", NULL,
- added_drives);
-
- list_emit (monitor,
- "volume_removed", "removed",
- removed_volumes);
- list_emit (monitor,
- "volume_added", NULL,
- added_volumes);
-
- list_emit (monitor,
- "mount_removed", "unmounted",
- removed_mounts);
- list_emit (monitor,
- "mount_added", NULL,
- added_mounts);
- }
-
- list_free (removed_drives);
- list_free (added_drives);
- list_free (removed_volumes);
- list_free (added_volumes);
- list_free (removed_mounts);
- list_free (added_mounts);
-}
-
-static GGduMount *
-find_disc_mount_for_volume (GGduVolumeMonitor *monitor,
- GGduVolume *volume)
-{
- GList *l;
-
- for (l = monitor->disc_mounts; l != NULL; l = l->next)
- {
- GGduMount *mount = G_GDU_MOUNT (l->data);
-
- if (g_gdu_mount_has_volume (mount, volume))
- return mount;
- }
-
- return NULL;
-}
-
-static GGduVolume *
-find_disc_volume_for_device_file (GGduVolumeMonitor *monitor,
- const gchar *device_file)
-{
- GList *l;
- GGduVolume *ret;
- struct stat stat_buf;
-
- ret = NULL;
-
- if (stat (device_file, &stat_buf) == 0)
- {
- for (l = monitor->disc_volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
- if (g_gdu_volume_has_dev (volume, stat_buf.st_rdev))
- {
- ret = volume;
- goto out;
- }
- }
- }
-
- for (l = monitor->disc_volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
-
- if (g_gdu_volume_has_device_file (volume, device_file))
- {
- ret = volume;
- goto out;
- }
- }
-
- out:
- return ret;
-}
-
-static GGduVolume *
-find_volume_for_device_file (GGduVolumeMonitor *monitor,
- const gchar *device_file)
-{
- GList *l;
- GGduVolume *ret;
- struct stat stat_buf;
-
- ret = NULL;
-
- if (stat (device_file, &stat_buf) == 0)
- {
- for (l = monitor->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
- if (g_gdu_volume_has_dev (volume, stat_buf.st_rdev))
- {
- ret = volume;
- goto out;
- }
- }
- }
-
- for (l = monitor->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
-
- if (g_gdu_volume_has_device_file (volume, device_file))
- {
- ret = volume;
- goto out;
- }
- }
-
- ret = NULL;
- for (l = monitor->fstab_volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
-
- if (g_gdu_volume_has_device_file (volume, device_file))
- {
- ret = volume;
- goto out;
- }
- }
-
- out:
- return ret;
-}
-
-static GGduVolume *
-find_volume_for_presentable (GGduVolumeMonitor *monitor,
- GduPresentable *presentable)
-{
- GList *l;
-
- for (l = monitor->volumes; l != NULL; l = l->next)
- {
- GGduVolume *volume = G_GDU_VOLUME (l->data);
-
- if (g_gdu_volume_has_presentable (volume, presentable))
- return volume;
- }
-
- return NULL;
-}
-
-static GGduDrive *
-find_drive_by_device_file (GGduVolumeMonitor *monitor,
- const gchar *device_file)
-{
- GList *l;
- struct stat stat_buf;
-
- if (stat (device_file, &stat_buf) != 0)
- {
- g_warning ("%s:%s: Error statting %s: %m", G_STRLOC, G_STRFUNC, device_file);
- return NULL;
- }
-
- for (l = monitor->drives; l != NULL; l = l->next)
- {
- GGduDrive *drive = G_GDU_DRIVE (l->data);
-
- if (g_gdu_drive_has_dev (drive, stat_buf.st_rdev))
- return drive;
- }
-
- return NULL;
-}
-
-static GGduDrive *
-find_drive_by_presentable (GGduVolumeMonitor *monitor,
- GduPresentable *presentable)
-{
- GList *l;
-
- for (l = monitor->drives; l != NULL; l = l->next)
- {
- GGduDrive *drive = G_GDU_DRIVE (l->data);
-
- if (g_gdu_drive_has_presentable (drive, presentable))
- return drive;
- }
-
- return NULL;
-}
-
-static void
-update_drives (GGduVolumeMonitor *monitor,
- GList **added_drives,
- GList **removed_drives)
-{
- GList *cur_drives;
- GList *new_drives;
- GList *removed, *added;
- GList *l, *ll;
- GGduDrive *drive;
- GList *fstab_mount_points;
-
- if (monitor->pool == NULL)
- return;
-
- fstab_mount_points = g_unix_mount_points_get (NULL);
-
- cur_drives = NULL;
- for (l = monitor->drives; l != NULL; l = l->next)
- cur_drives = g_list_prepend (cur_drives, g_gdu_drive_get_presentable (G_GDU_DRIVE (l->data)));
-
- /* remove devices we want to ignore - we do it here so we get to reevaluate
- * on the next update whether they should still be ignored
- */
- new_drives = gdu_pool_get_presentables (monitor->pool);
- for (l = new_drives; l != NULL; l = ll)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- ll = l->next;
- if (!GDU_IS_DRIVE (p) || should_drive_be_ignored (monitor->pool, GDU_DRIVE (p), fstab_mount_points))
- {
- g_object_unref (p);
- new_drives = g_list_delete_link (new_drives, l);
- }
- }
-
- cur_drives = g_list_sort (cur_drives, (GCompareFunc) gdu_presentable_compare);
- new_drives = g_list_sort (new_drives, (GCompareFunc) gdu_presentable_compare);
- diff_sorted_lists (cur_drives,
- new_drives, (GCompareFunc) gdu_presentable_compare,
- &added, &removed);
-
- for (l = removed; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
-
- drive = find_drive_by_presentable (monitor, p);
- if (drive != NULL)
- {
- /*g_debug ("removing drive %s", gdu_presentable_get_id (p));*/
- g_gdu_drive_disconnected (drive);
- monitor->drives = g_list_remove (monitor->drives, drive);
- *removed_drives = g_list_prepend (*removed_drives, drive);
- }
- }
-
- for (l = added; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
-
- drive = find_drive_by_presentable (monitor, p);
- if (drive == NULL)
- {
- /*g_debug ("adding drive %s", gdu_presentable_get_id (p));*/
- drive = g_gdu_drive_new (G_VOLUME_MONITOR (monitor), p);
- if (drive != NULL)
- {
- monitor->drives = g_list_prepend (monitor->drives, drive);
- *added_drives = g_list_prepend (*added_drives, g_object_ref (drive));
- }
- }
- }
-
- g_list_free (added);
- g_list_free (removed);
-
- g_list_free (cur_drives);
-
- g_list_foreach (new_drives, (GFunc) g_object_unref, NULL);
- g_list_free (new_drives);
-
- g_list_foreach (fstab_mount_points, (GFunc) g_unix_mount_point_free, NULL);
- g_list_free (fstab_mount_points);
-}
-
-static void
-update_volumes (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes)
-{
- GList *cur_volumes;
- GList *new_volumes;
- GList *removed, *added;
- GList *l, *ll;
- GGduVolume *volume;
- GGduDrive *drive;
- GList *fstab_mount_points;
-
- if (monitor->pool == NULL)
- return;
-
- fstab_mount_points = g_unix_mount_points_get (NULL);
-
- cur_volumes = NULL;
- for (l = monitor->volumes; l != NULL; l = l->next)
- cur_volumes = g_list_prepend (cur_volumes, g_gdu_volume_get_presentable (G_GDU_VOLUME (l->data)));
-
- /* remove devices we want to ignore - we do it here so we get to reevaluate
- * on the next update whether they should still be ignored
- */
- new_volumes = gdu_pool_get_presentables (monitor->pool);
- for (l = new_volumes; l != NULL; l = ll)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- ll = l->next;
- if (!GDU_IS_VOLUME (p) || should_volume_be_ignored (monitor->pool, GDU_VOLUME (p), fstab_mount_points))
- {
- g_object_unref (p);
- new_volumes = g_list_delete_link (new_volumes, l);
- }
- }
-
- cur_volumes = g_list_sort (cur_volumes, (GCompareFunc) gdu_presentable_compare);
- new_volumes = g_list_sort (new_volumes, (GCompareFunc) gdu_presentable_compare);
- diff_sorted_lists (cur_volumes,
- new_volumes, (GCompareFunc) gdu_presentable_compare,
- &added, &removed);
-
- for (l = removed; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
-
- volume = find_volume_for_presentable (monitor, p);
- if (volume != NULL)
- {
- /*g_debug ("removing volume %s", gdu_device_get_device_file (d));*/
- g_gdu_volume_removed (volume);
- monitor->volumes = g_list_remove (monitor->volumes, volume);
- *removed_volumes = g_list_prepend (*removed_volumes, volume);
- }
- }
-
- for (l = added; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- GduDevice *d;
-
- volume = NULL;
- d = gdu_presentable_get_device (p);
-
- if (d != NULL)
- volume = find_volume_for_device_file (monitor, gdu_device_get_device_file (d));
-
- if (volume == NULL)
- {
- GduDrive *gdu_drive;
-
- drive = NULL;
- gdu_drive = gdu_volume_get_drive (GDU_VOLUME (p));
- if (gdu_drive != NULL)
- {
- drive = find_drive_by_presentable (monitor, GDU_PRESENTABLE (gdu_drive));
- g_object_unref (gdu_drive);
- }
-
- volume = g_gdu_volume_new (G_VOLUME_MONITOR (monitor),
- GDU_VOLUME (p),
- drive,
- NULL);
- if (volume != NULL)
- {
- monitor->volumes = g_list_prepend (monitor->volumes, volume);
- *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
- }
- }
-
- if (d != NULL)
- g_object_unref (d);
- }
-
- g_list_free (added);
- g_list_free (removed);
-
- g_list_foreach (new_volumes, (GFunc) g_object_unref, NULL);
- g_list_free (new_volumes);
-
- g_list_free (cur_volumes);
-
- g_list_foreach (fstab_mount_points, (GFunc) g_unix_mount_point_free, NULL);
- g_list_free (fstab_mount_points);
-}
-
-static void
-update_fstab_volumes (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes)
-{
- GList *fstab_mount_points;
- GList *cur_fstab_mount_points;
- GList *new_fstab_mount_points;
- GList *removed, *added;
- GList *l;
- GGduVolume *volume;
-
- fstab_mount_points = g_unix_mount_points_get (NULL);
-
- cur_fstab_mount_points = NULL;
- for (l = monitor->fstab_volumes; l != NULL; l = l->next)
- cur_fstab_mount_points = g_list_prepend (cur_fstab_mount_points, g_gdu_volume_get_unix_mount_point (G_GDU_VOLUME (l->data)));
-
- new_fstab_mount_points = NULL;
- for (l = fstab_mount_points; l != NULL; l = l->next)
- {
- GUnixMountPoint *mount_point = l->data;
- const gchar *device_file;
-
- /* only show user mountable mount points */
- if (!g_unix_mount_point_is_user_mountable (mount_point))
- continue;
-
- /* only show stuff that can be mounted in user-visible locations */
- if (!_g_unix_mount_point_guess_should_display (mount_point))
- continue;
-
- /* ignore mount point if the device doesn't exist or is handled by DeviceKit-disks */
- device_file = g_unix_mount_point_get_device_path (mount_point);
- if (g_str_has_prefix (device_file, "/dev/"))
- {
- gchar resolved_path[PATH_MAX];
- GduDevice *device = NULL;
-
- /* doesn't exist */
- if (realpath (device_file, resolved_path) == NULL)
- continue;
-
- /* is handled by DKD */
- if (monitor->pool != NULL)
- device = gdu_pool_get_by_device_file (monitor->pool, resolved_path);
- if (device != NULL)
- {
- g_object_unref (device);
- continue;
- }
- }
-
- new_fstab_mount_points = g_list_prepend (new_fstab_mount_points, mount_point);
- }
-
- diff_sorted_lists (cur_fstab_mount_points,
- new_fstab_mount_points, (GCompareFunc) g_unix_mount_point_compare,
- &added, &removed);
-
- for (l = removed; l != NULL; l = l->next)
- {
- GUnixMountPoint *mount_point = l->data;
- volume = find_volume_for_unix_mount_point (monitor, mount_point);
- if (volume != NULL)
- {
- g_gdu_volume_removed (volume);
- monitor->fstab_volumes = g_list_remove (monitor->fstab_volumes, volume);
- *removed_volumes = g_list_prepend (*removed_volumes, volume);
- /*g_debug ("removed volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
- }
- }
-
- for (l = added; l != NULL; l = l->next)
- {
- GUnixMountPoint *mount_point = l->data;
-
- volume = g_gdu_volume_new_for_unix_mount_point (G_VOLUME_MONITOR (monitor), mount_point);
- if (volume != NULL)
- {
- /* steal mount_point since g_gdu_volume_new_for_unix_mount_point() takes ownership of it */
- fstab_mount_points = g_list_remove (fstab_mount_points, mount_point);
- monitor->fstab_volumes = g_list_prepend (monitor->fstab_volumes, volume);
- *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
- /*g_debug ("added volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
- }
- else
- {
- g_unix_mount_point_free (mount_point);
- }
- }
-
- g_list_free (added);
- g_list_free (removed);
-
- g_list_free (cur_fstab_mount_points);
-
- g_list_foreach (fstab_mount_points, (GFunc) g_unix_mount_point_free, NULL);
- g_list_free (fstab_mount_points);
-}
-
-static gboolean
-unix_mount_is_cleartext (GGduVolumeMonitor *monitor,
- GUnixMountEntry *mount_entry)
-{
- const char *device_file;
- const char *mount_path;
- GGduVolume *volume;
- GduPresentable *presentable;
-
- device_file = g_unix_mount_get_device_path (mount_entry);
- mount_path = g_unix_mount_get_mount_path (mount_entry);
- volume = find_volume_for_device_file (monitor, device_file);
- if (volume == NULL)
- volume = find_volume_for_mount_path (monitor, mount_path);
-
- if (volume != NULL)
- {
- presentable = g_gdu_volume_get_presentable_with_cleartext (volume);
- return presentable != NULL;
- }
-
- return FALSE;
-}
-
-static void
-update_mounts (GGduVolumeMonitor *monitor,
- GList **added_mounts,
- GList **removed_mounts)
-{
- GList *new_mounts;
- GList *removed, *added;
- GList *l, *ll;
- GGduMount *mount;
- GGduVolume *volume;
- const char *device_file;
- const char *mount_path;
-
- new_mounts = g_unix_mounts_get (NULL);
-
- /* remove mounts we want to ignore - we do it here so we get to reevaluate
- * on the next update whether they should still be ignored
- */
- for (l = new_mounts; l != NULL; l = ll)
- {
- GUnixMountEntry *mount_entry = l->data;
- ll = l->next;
-
- /* since we always show crypto volumes, we should also never ignore their mounts */
- /* keep in sync with should_mount_be_ignored() */
- if (!g_unix_mount_guess_should_display (mount_entry) &&
- !unix_mount_is_cleartext (monitor, mount_entry))
- {
- g_unix_mount_free (mount_entry);
- new_mounts = g_list_delete_link (new_mounts, l);
- }
- }
-
- new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare);
-
- diff_sorted_lists (monitor->last_mounts,
- new_mounts, (GCompareFunc) g_unix_mount_compare,
- &added, &removed);
-
- for (l = removed; l != NULL; l = l->next)
- {
- GUnixMountEntry *mount_entry = l->data;
-
- mount = find_mount_by_mount_path (monitor, g_unix_mount_get_mount_path (mount_entry));
- if (mount)
- {
- /*g_debug ("removing mount %s", g_unix_mount_get_device_path (mount_entry));*/
- g_gdu_mount_unmounted (mount);
- monitor->mounts = g_list_remove (monitor->mounts, mount);
-
- *removed_mounts = g_list_prepend (*removed_mounts, mount);
- }
- }
-
- for (l = added; l != NULL; l = l->next)
- {
- GUnixMountEntry *mount_entry = l->data;
-
- device_file = g_unix_mount_get_device_path (mount_entry);
- mount_path = g_unix_mount_get_mount_path (mount_entry);
- volume = find_volume_for_device_file (monitor, device_file);
- if (volume == NULL)
- volume = find_volume_for_mount_path (monitor, mount_path);
-
- /*g_debug ("adding mount %s (vol %p) (device %s, mount_path %s)", g_unix_mount_get_device_path (mount_entry), volume, device_file, mount_path);*/
- mount = g_gdu_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume);
- if (mount)
- {
- monitor->mounts = g_list_prepend (monitor->mounts, mount);
- *added_mounts = g_list_prepend (*added_mounts, g_object_ref (mount));
- }
- }
-
- g_list_free (added);
- g_list_free (removed);
- g_list_foreach (monitor->last_mounts,
- (GFunc)g_unix_mount_free, NULL);
- g_list_free (monitor->last_mounts);
- monitor->last_mounts = new_mounts;
-}
-
-static void
-update_discs (GGduVolumeMonitor *monitor,
- GList **added_volumes,
- GList **removed_volumes,
- GList **added_mounts,
- GList **removed_mounts)
-{
- GList *cur_discs;
- GList *new_discs;
- GList *removed, *added;
- GList *l, *ll;
- GGduDrive *drive = NULL;
- GGduVolume *volume;
- GGduMount *mount;
-
- /* we also need to generate GVolume + GMount objects for
- *
- * - optical discs that have audio
- * - optical discs that are blank
- *
- */
-
- if (monitor->pool == NULL)
- return;
-
- cur_discs = NULL;
- for (l = monitor->disc_volumes; l != NULL; l = l->next)
- cur_discs = g_list_prepend (cur_discs, g_gdu_volume_get_presentable (G_GDU_VOLUME (l->data)));
-
- new_discs = gdu_pool_get_presentables (monitor->pool);
- for (l = new_discs; l != NULL; l = ll)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- GduDevice *d;
- gboolean ignore;
-
- ll = l->next;
- ignore = TRUE;
-
- /* filter out everything but discs that are blank or has audio */
- d = gdu_presentable_get_device (p);
- if (GDU_IS_VOLUME (p) && d != NULL && gdu_device_is_optical_disc (d))
- {
- if (gdu_device_optical_disc_get_num_audio_tracks (d) > 0 || gdu_device_optical_disc_get_is_blank (d))
- ignore = FALSE;
- }
-
- if (ignore)
- {
- g_object_unref (p);
- new_discs = g_list_delete_link (new_discs, l);
- }
-
- if (d != NULL)
- g_object_unref (d);
- }
-
- cur_discs = g_list_sort (cur_discs, (GCompareFunc) gdu_presentable_compare);
- new_discs = g_list_sort (new_discs, (GCompareFunc) gdu_presentable_compare);
- diff_sorted_lists (cur_discs, new_discs, (GCompareFunc) gdu_presentable_compare, &added, &removed);
-
- for (l = removed; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- GduDevice *d;
-
- volume = NULL;
- mount = NULL;
- d = gdu_presentable_get_device (p);
-
- if (d != NULL)
- {
- volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d));
- mount = find_disc_mount_for_volume (monitor, volume);
- }
-
- if (mount != NULL)
- {
- /*g_debug ("removing disc mount %s", gdu_device_get_device_file (d));*/
- g_gdu_mount_unmounted (mount);
- monitor->disc_mounts = g_list_remove (monitor->disc_mounts, mount);
- *removed_mounts = g_list_prepend (*removed_mounts, mount);
- }
-
- if (volume != NULL)
- {
- /*g_debug ("removing disc volume %s", gdu_device_get_device_file (d));*/
- g_gdu_volume_removed (volume);
- monitor->disc_volumes = g_list_remove (monitor->disc_volumes, volume);
- *removed_volumes = g_list_prepend (*removed_volumes, volume);
- }
-
- if (d != NULL)
- g_object_unref (d);
- }
-
- for (l = added; l != NULL; l = l->next)
- {
- GduPresentable *p = GDU_PRESENTABLE (l->data);
- GduDevice *d;
- gboolean is_blank;
-
- volume = NULL;
- is_blank = TRUE;
- d = gdu_presentable_get_device (p);
-
- if (d != NULL)
- {
- is_blank = gdu_device_optical_disc_get_is_blank (d);
- volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d));
- }
-
- if (volume == NULL)
- {
- GduPresentable *toplevel_drive;
-
- toplevel_drive = gdu_presentable_get_enclosing_presentable (p);
- /* handle logical partitions enclosed by an extented partition */
- if (GDU_IS_VOLUME (toplevel_drive))
- {
- GduPresentable *temp;
- temp = toplevel_drive;
- toplevel_drive = gdu_presentable_get_enclosing_presentable (toplevel_drive);
- g_object_unref (temp);
- }
-
- if (toplevel_drive != NULL)
- {
- if (GDU_IS_DRIVE (toplevel_drive))
- {
- GduDevice *toplevel_drive_device;
-
- drive = NULL;
- toplevel_drive_device = gdu_presentable_get_device (toplevel_drive);
- if (toplevel_drive_device != NULL)
- {
- drive = find_drive_by_device_file (monitor, gdu_device_get_device_file (toplevel_drive_device));
- /*g_debug ("adding volume %s (drive %s)",
- gdu_device_get_device_file (d),
- gdu_device_get_device_file (toplevel_device));*/
- g_object_unref (toplevel_drive_device);
- }
- }
- g_object_unref (toplevel_drive);
- }
- else
- {
- drive = NULL;
- /*g_debug ("adding volume %s (no drive)", gdu_device_get_device_file (d));*/
- }
-
- mount = NULL;
- if (is_blank)
- {
- volume = g_gdu_volume_new (G_VOLUME_MONITOR (monitor),
- GDU_VOLUME (p),
- drive,
- NULL);
- mount = g_gdu_mount_new (G_VOLUME_MONITOR (monitor),
- NULL,
- volume);
- }
- else
- {
- gchar *uri;
- gchar *device_basename;
- GFile *activation_root;
-
- /* the gvfsd-cdda backend uses URI's like these */
- device_basename = g_path_get_basename (gdu_device_get_device_file (d));
- uri = g_strdup_printf ("cdda://%s", device_basename);
- activation_root = g_file_new_for_uri (uri);
- g_free (device_basename);
- g_free (uri);
-
- volume = g_gdu_volume_new (G_VOLUME_MONITOR (monitor),
- GDU_VOLUME (p),
- drive,
- activation_root);
-
- g_object_unref (activation_root);
- }
-
- if (volume != NULL)
- {
- monitor->disc_volumes = g_list_prepend (monitor->disc_volumes, volume);
- *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
-
- if (mount != NULL)
- {
- monitor->disc_mounts = g_list_prepend (monitor->disc_mounts, mount);
- *added_mounts = g_list_prepend (*added_mounts, g_object_ref (mount));
- }
- }
- }
-
- if (d != NULL)
- g_object_unref (d);
- }
-
- g_list_free (added);
- g_list_free (removed);
-
- g_list_foreach (new_discs, (GFunc) g_object_unref, NULL);
- g_list_free (new_discs);
-
- g_list_free (cur_discs);
-}
diff --git a/monitor/gdu/ggduvolumemonitor.h b/monitor/gdu/ggduvolumemonitor.h
deleted file mode 100644
index 74a978a1..00000000
--- a/monitor/gdu/ggduvolumemonitor.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* gvfs - extensions for gio
- *
- * Copyright (C) 2006-2009 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#ifndef __G_GDU_VOLUME_MONITOR_H__
-#define __G_GDU_VOLUME_MONITOR_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-#include <gio/gunixmounts.h>
-
-/* for dev_t */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <gdu/gdu.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_GDU_VOLUME_MONITOR (g_gdu_volume_monitor_get_type ())
-#define G_GDU_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_GDU_VOLUME_MONITOR, GGduVolumeMonitor))
-#define G_GDU_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_GDU_VOLUME_MONITOR, GGduVolumeMonitorClass))
-#define G_IS_GDU_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_GDU_VOLUME_MONITOR))
-#define G_IS_GDU_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_GDU_VOLUME_MONITOR))
-
-typedef struct _GGduVolumeMonitor GGduVolumeMonitor;
-typedef struct _GGduVolumeMonitorClass GGduVolumeMonitorClass;
-
-/* Forward definitions */
-typedef struct _GGduDrive GGduDrive;
-typedef struct _GGduVolume GGduVolume;
-typedef struct _GGduMount GGduMount;
-
-struct _GGduVolumeMonitorClass {
- GNativeVolumeMonitorClass parent_class;
-
-};
-
-GType g_gdu_volume_monitor_get_type (void) G_GNUC_CONST;
-
-GVolumeMonitor *g_gdu_volume_monitor_new (void);
-
-gboolean _is_pc_floppy_drive (GduDevice *device);
-
-G_END_DECLS
-
-#endif /* __G_GDU_VOLUME_MONITOR_H__ */
diff --git a/monitor/gdu/gvfs-gdu-volume-monitor.service.in b/monitor/gdu/gvfs-gdu-volume-monitor.service.in
deleted file mode 100644
index f25309db..00000000
--- a/monitor/gdu/gvfs-gdu-volume-monitor.service.in
+++ /dev/null
@@ -1,7 +0,0 @@
-[Unit]
-Description=Virtual filesystem service - GNOME Disk Utility monitor
-
-[Service]
-ExecStart=@libexecdir@/gvfs-gdu-volume-monitor
-Type=dbus
-BusName=org.gtk.vfs.GduVolumeMonitor
diff --git a/monitor/gdu/meson.build b/monitor/gdu/meson.build
deleted file mode 100644
index 0850d112..00000000
--- a/monitor/gdu/meson.build
+++ /dev/null
@@ -1,76 +0,0 @@
-gdu_monitor = files('gdu.monitor')
-
-install_data(
- gdu_monitor,
- install_dir: gvfs_remote_volume_monitors_dir
-)
-
-dbus_service = gvfs_namespace + '.GduVolumeMonitor'
-dbus_exec = 'gvfs-gdu-volume-monitor'
-dbus_systemd_service = ''
-
-if install_systemd_user_unit_dir
- service = dbus_exec + '.service'
-
- configure_file(
- input: service + '.in',
- output: service,
- install: true,
- install_dir: systemd_user_unit_dir,
- configuration: service_conf
- )
-
- dbus_systemd_service = 'SystemdService=' + service
-endif
-
-dbus_service_conf = configuration_data()
-dbus_service_conf.set('service', dbus_service)
-dbus_service_conf.set('exec', join_paths(gvfs_libexecdir, dbus_exec))
-dbus_service_conf.set('systemd_service', dbus_systemd_service)
-
-gdu_service = configure_file(
- input: dbus_service_in,
- output: dbus_service + '.service',
- install: true,
- install_dir: dbus_service_dir,
- configuration: dbus_service_conf
-)
-
-sources = files(
- 'gdu-volume-monitor-daemon.c',
- 'ggdudrive.c',
- 'ggdumount.c',
- 'ggduvolume.c',
- 'ggduvolumemonitor.c'
-)
-
-deps = [
- gdu_dep,
- gio_unix_dep,
- glib_dep,
- gobject_dep,
- libgvfscommon_monitor_dep,
- libgvfsproxyvolumemonitordaemon_noin_dep
-]
-
-if enable_gudev
- deps += gudev_dep
-endif
-
-cflags = [
- '-DG_LOG_DOMAIN="GVFS-Gdu"',
- '-DGDU_API_IS_SUBJECT_TO_CHANGE',
- '-DGIO_MODULE_DIR="@0@"'.format(gio_module_dir),
- '-DGVFS_LOCALEDIR="@0@"'.format(gvfs_localedir)
-]
-
-executable(
- 'gvfs-gdu-volume-monitor',
- sources,
- include_directories: top_inc,
- dependencies: deps,
- c_args: cflags,
- install: true,
- install_rpath: gvfs_rpath,
- install_dir: gvfs_libexecdir
-)
diff --git a/monitor/gdu/org.gtk.vfs.GduVolumeMonitor.service.in b/monitor/gdu/org.gtk.vfs.GduVolumeMonitor.service.in
deleted file mode 100644
index be73c456..00000000
--- a/monitor/gdu/org.gtk.vfs.GduVolumeMonitor.service.in
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.gtk.vfs.GduVolumeMonitor
-Exec=@libexecdir@/gvfs-gdu-volume-monitor
-SystemdService=gvfs-gdu-volume-monitor.service
diff --git a/monitor/meson.build b/monitor/meson.build
index b6aa8de5..f841bdce 100644
--- a/monitor/meson.build
+++ b/monitor/meson.build
@@ -1,9 +1,5 @@
subdir('proxy')
-if enable_gdu
- subdir('gdu')
-endif
-
if enable_udisks2
subdir('udisks2')
endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index da379209..7a870755 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -90,10 +90,6 @@ daemon/mount.c
daemon/org.gtk.vfs.file-operations.policy.in.in
metadata/meta-daemon.c
monitor/afc/afcvolume.c
-monitor/gdu/gdu-volume-monitor-daemon.c
-monitor/gdu/ggdudrive.c
-monitor/gdu/ggdumount.c
-monitor/gdu/ggduvolume.c
monitor/goa/goavolume.c
monitor/gphoto2/ggphoto2volume.c
monitor/gphoto2/ggphoto2volumemonitor.c
diff --git a/test/meson.build b/test/meson.build
index b6e23ddb..53c3c979 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -41,10 +41,6 @@ if enable_installed_tests
test_data += [afc_monitor, afc_service]
endif
- if enable_gdu
- test_data += [gdu_monitor, gdu_service]
- endif
-
if enable_gphoto2
test_data += [gphoto2_monitor, gphoto2_service]
endif