diff options
author | Ondrej Holy <oholy@redhat.com> | 2018-04-13 14:26:33 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2018-04-17 12:57:06 +0200 |
commit | 1db029df72bcd50dd877d388c2e0934d8ed3d321 (patch) | |
tree | 522e5ba698c663a8d85cdfeb4bdb03bd4049e091 | |
parent | 5e2ff6885240f929f067322707e45aa64c23107f (diff) | |
download | gvfs-1db029df72bcd50dd877d388c2e0934d8ed3d321.tar.gz |
Remove libgdu support
libgdu has been removed in 2011 and is superseded by libudisks2, so
there is no need to have gdu volume monitor in the tree.
-rw-r--r-- | meson.build | 7 | ||||
-rw-r--r-- | meson_options.txt | 1 | ||||
-rw-r--r-- | monitor/gdu/gdu-volume-monitor-daemon.c | 45 | ||||
-rw-r--r-- | monitor/gdu/gdu.monitor | 5 | ||||
-rw-r--r-- | monitor/gdu/ggdudrive.c | 1244 | ||||
-rw-r--r-- | monitor/gdu/ggdudrive.h | 69 | ||||
-rw-r--r-- | monitor/gdu/ggdumount.c | 1475 | ||||
-rw-r--r-- | monitor/gdu/ggdumount.h | 64 | ||||
-rw-r--r-- | monitor/gdu/ggduvolume.c | 1884 | ||||
-rw-r--r-- | monitor/gdu/ggduvolume.h | 87 | ||||
-rw-r--r-- | monitor/gdu/ggduvolumemonitor.c | 1812 | ||||
-rw-r--r-- | monitor/gdu/ggduvolumemonitor.h | 67 | ||||
-rw-r--r-- | monitor/gdu/gvfs-gdu-volume-monitor.service.in | 7 | ||||
-rw-r--r-- | monitor/gdu/meson.build | 76 | ||||
-rw-r--r-- | monitor/gdu/org.gtk.vfs.GduVolumeMonitor.service.in | 4 | ||||
-rw-r--r-- | monitor/meson.build | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 4 | ||||
-rw-r--r-- | test/meson.build | 4 |
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), °raded); - - 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), °raded)) - 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 |