X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgunixvolume.c;h=981f703b8d0bbbdf7ab436bbc384c501d5c2e31c;hb=925913d8dd8f4f283265fb7b2e17fc3da4d06b3e;hp=93036c387c7e4a3080d3c1662cdfe2a55a4a5dde;hpb=a2ca589703273fca80cb126430a8b058aba3eb52;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c index 93036c3..981f703 100644 --- a/gio/gunixvolume.c +++ b/gio/gunixvolume.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -13,35 +15,48 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: Alexander Larsson + * David Zeuthen */ -#include +#include "config.h" #include +#include +#include #include -#include "gunixvolumemonitor.h" #include "gunixvolume.h" -#include "gunixdrive.h" -#include "gvolumeprivate.h" -#include "gvolumemonitor.h" +#include "gunixmount.h" +#include "gunixmounts.h" #include "gthemedicon.h" +#include "gvolume.h" +#include "gvolumemonitor.h" +#include "gtask.h" +#include "gioerror.h" #include "glibintl.h" +/* for BUFSIZ */ +#include -#include "gioalias.h" struct _GUnixVolume { GObject parent; - GUnixDrive *drive; /* owned by volume monitor */ + GVolumeMonitor *volume_monitor; + GUnixMount *mount; /* owned by volume monitor */ + + char *device_path; + char *mount_path; + gboolean can_eject; + + char *identifier; + char *identifier_type; + char *name; - char *icon; - char *mountpoint; + GIcon *icon; + GIcon *symbolic_icon; }; static void g_unix_volume_volume_iface_init (GVolumeIface *iface); @@ -51,7 +66,6 @@ G_DEFINE_TYPE_WITH_CODE (GUnixVolume, g_unix_volume, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, g_unix_volume_volume_iface_init)) - static void g_unix_volume_finalize (GObject *object) { @@ -59,16 +73,21 @@ g_unix_volume_finalize (GObject *object) volume = G_UNIX_VOLUME (object); - if (volume->drive) - _g_unix_drive_unset_volume (volume->drive, volume); - - g_assert (volume->drive == NULL); - g_free (volume->name); - g_free (volume->icon); - g_free (volume->mountpoint); + if (volume->volume_monitor != NULL) + g_object_unref (volume->volume_monitor); + + if (volume->mount) + _g_unix_mount_unset_volume (volume->mount, volume); - if (G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize) - (*G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize) (object); + g_object_unref (volume->icon); + g_object_unref (volume->symbolic_icon); + g_free (volume->name); + g_free (volume->mount_path); + g_free (volume->device_path); + g_free (volume->identifier); + g_free (volume->identifier_type); + + G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize (object); } static void @@ -84,225 +103,329 @@ g_unix_volume_init (GUnixVolume *unix_volume) { } -static char * -get_filesystem_volume_name (const char *fs_type) -{ - /* TODO: add translation table from gnome-vfs */ - return g_strdup_printf (_("%s volume"), fs_type); -} - -static char * -type_to_icon (GUnixMountType type) -{ - const char *icon_name = NULL; - - switch (type) - { - case G_UNIX_MOUNT_TYPE_HD: - icon_name = "drive-harddisk"; - break; - case G_UNIX_MOUNT_TYPE_FLOPPY: - case G_UNIX_MOUNT_TYPE_ZIP: - case G_UNIX_MOUNT_TYPE_JAZ: - icon_name = "media-floppy"; - break; - case G_UNIX_MOUNT_TYPE_CDROM: - icon_name = "media-optical"; - break; - case G_UNIX_MOUNT_TYPE_NFS: - /* TODO: Would like a better icon here... */ - icon_name = "drive-harddisk"; - break; - case G_UNIX_MOUNT_TYPE_MEMSTICK: - icon_name = "media-flash"; - break; - case G_UNIX_MOUNT_TYPE_CAMERA: - icon_name = "camera-photo"; - break; - case G_UNIX_MOUNT_TYPE_IPOD: - icon_name = "multimedia-player"; - break; - case G_UNIX_MOUNT_TYPE_UNKNOWN: - default: - icon_name = "drive-harddisk"; - break; - } - return g_strdup (icon_name); -} - GUnixVolume * -_g_unix_volume_new (GUnixMount *mount, - GUnixDrive *drive) +_g_unix_volume_new (GVolumeMonitor *volume_monitor, + GUnixMountPoint *mountpoint) { GUnixVolume *volume; - GUnixMountType type; - const char *mount_path; - char *volume_name; - mount_path = g_unix_mount_get_mount_path (mount); - - /* No drive for volume. Ignore internal things */ - if (drive == NULL && g_unix_mount_is_system_internal (mount)) + if (!(g_unix_mount_point_is_user_mountable (mountpoint) || + g_str_has_prefix (g_unix_mount_point_get_device_path (mountpoint), "/vol/")) || + g_unix_mount_point_is_loopback (mountpoint)) return NULL; volume = g_object_new (G_TYPE_UNIX_VOLUME, NULL); - volume->drive = drive; - if (drive) - _g_unix_drive_set_volume (drive, volume); - volume->mountpoint = g_strdup (mount_path); + volume->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL; + volume->mount_path = g_strdup (g_unix_mount_point_get_mount_path (mountpoint)); + volume->device_path = g_strdup (g_unix_mount_point_get_device_path (mountpoint)); + volume->can_eject = g_unix_mount_point_guess_can_eject (mountpoint); - type = g_unix_mount_guess_type (mount); - - volume->icon = type_to_icon (type); - - volume_name = NULL; - if (mount_path) + volume->name = g_unix_mount_point_guess_name (mountpoint); + volume->icon = g_unix_mount_point_guess_icon (mountpoint); + volume->symbolic_icon = g_unix_mount_point_guess_symbolic_icon (mountpoint); + + + if (strcmp (g_unix_mount_point_get_fs_type (mountpoint), "nfs") == 0) { - if (strcmp (mount_path, "/") == 0) - volume_name = g_strdup (_("Filesystem root")); - else - volume_name = g_filename_display_basename (mount_path); + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT); + volume->identifier = g_strdup (volume->device_path); } - - if (volume_name == NULL) + else if (g_str_has_prefix (volume->device_path, "LABEL=")) { - if (g_unix_mount_get_fs_type (mount) != NULL) - volume_name = g_strdup (get_filesystem_volume_name (g_unix_mount_get_fs_type (mount))); + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL); + volume->identifier = g_strdup (volume->device_path + 6); + } + else if (g_str_has_prefix (volume->device_path, "UUID=")) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID); + volume->identifier = g_strdup (volume->device_path + 5); + } + else if (g_path_is_absolute (volume->device_path)) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); + volume->identifier = g_strdup (volume->device_path); } - if (volume_name == NULL) - /* TODO: Use volume size as name? */ - volume_name = g_strdup (_("Unknown volume")); - - volume->name = volume_name; - return volume; } void -_g_unix_volume_unmounted (GUnixVolume *volume) +_g_unix_volume_disconnected (GUnixVolume *volume) { - if (volume->drive) + if (volume->mount) { - _g_unix_drive_unset_volume (volume->drive, volume); - volume->drive = NULL; - g_signal_emit_by_name (volume, "changed"); + _g_unix_mount_unset_volume (volume->mount, volume); + volume->mount = NULL; } } void -_g_unix_volume_unset_drive (GUnixVolume *volume, - GUnixDrive *drive) +_g_unix_volume_set_mount (GUnixVolume *volume, + GUnixMount *mount) +{ + if (volume->mount == mount) + return; + + if (volume->mount) + _g_unix_mount_unset_volume (volume->mount, volume); + + volume->mount = mount; + + /* TODO: Emit changed in idle to avoid locking issues */ + g_signal_emit_by_name (volume, "changed"); + if (volume->volume_monitor != NULL) + g_signal_emit_by_name (volume->volume_monitor, "volume-changed", volume); +} + +void +_g_unix_volume_unset_mount (GUnixVolume *volume, + GUnixMount *mount) { - if (volume->drive == drive) + if (volume->mount == mount) { - volume->drive = NULL; + volume->mount = NULL; /* TODO: Emit changed in idle to avoid locking issues */ g_signal_emit_by_name (volume, "changed"); + if (volume->volume_monitor != NULL) + g_signal_emit_by_name (volume->volume_monitor, "volume-changed", volume); } } -static GFile * -g_unix_volume_get_root (GVolume *volume) +static GIcon * +g_unix_volume_get_icon (GVolume *volume) { GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); - - return g_file_new_for_path (unix_volume->mountpoint); + return g_object_ref (unix_volume->icon); } static GIcon * -g_unix_volume_get_icon (GVolume *volume) +g_unix_volume_get_symbolic_icon (GVolume *volume) { GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); - - return g_themed_icon_new (unix_volume->icon); + return g_object_ref (unix_volume->symbolic_icon); } static char * g_unix_volume_get_name (GVolume *volume) { GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); - return g_strdup (unix_volume->name); } -gboolean -_g_unix_volume_has_mountpoint (GUnixVolume *volume, - const char *mountpoint) +static char * +g_unix_volume_get_uuid (GVolume *volume) +{ + return NULL; +} + +static gboolean +g_unix_volume_can_mount (GVolume *volume) { - return strcmp (volume->mountpoint, mountpoint) == 0; + return TRUE; +} + +static gboolean +g_unix_volume_can_eject (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + return unix_volume->can_eject; +} + +static gboolean +g_unix_volume_should_automount (GVolume *volume) +{ + /* We automount all local volumes because we don't even + * make the internal stuff visible + */ + return TRUE; } static GDrive * g_unix_volume_get_drive (GVolume *volume) { + return NULL; +} + +static GMount * +g_unix_volume_get_mount (GVolume *volume) +{ GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); - if (unix_volume->drive) - return G_DRIVE (g_object_ref (unix_volume->drive)); - + if (unix_volume->mount != NULL) + return g_object_ref (unix_volume->mount); + return NULL; } -static gboolean -g_unix_volume_can_unmount (GVolume *volume) + +gboolean +_g_unix_volume_has_mount_path (GUnixVolume *volume, + const char *mount_path) { - /* TODO */ - return FALSE; + return strcmp (volume->mount_path, mount_path) == 0; } -static gboolean -g_unix_volume_can_eject (GVolume *volume) +static void +eject_mount_done (GObject *source, + GAsyncResult *result, + gpointer user_data) { - /* TODO */ - return FALSE; + GSubprocess *subprocess = G_SUBPROCESS (source); + GTask *task = user_data; + GError *error = NULL; + gchar *stderr_str; + + if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error)) + { + g_task_return_error (task, error); + g_error_free (error); + } + else /* successful communication */ + { + if (!g_subprocess_get_successful (subprocess)) + /* ...but bad exit code */ + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str); + else + /* ...and successful exit code */ + g_task_return_boolean (task, TRUE); + + g_free (stderr_str); + } + + g_object_unref (task); } static void -g_unix_volume_unmount (GVolume *volume, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +eject_mount_do (GVolume *volume, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const gchar * const *argv) { - /* TODO */ + GSubprocess *subprocess; + GError *error = NULL; + GTask *task; + + task = g_task_new (volume, cancellable, callback, user_data); + + if (g_task_return_error_if_cancelled (task)) + { + g_object_unref (task); + return; + } + + subprocess = g_subprocess_newv (argv, G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE, &error); + g_assert_no_error (error); + + g_subprocess_communicate_utf8_async (subprocess, NULL, + g_task_get_cancellable (task), + eject_mount_done, task); +} + +static void +g_unix_volume_mount (GVolume *volume, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + const gchar *argv[] = { "mount", NULL, NULL }; + + if (unix_volume->mount_path != NULL) + argv[1] = unix_volume->mount_path; + else + argv[1] = unix_volume->device_path; + + eject_mount_do (volume, cancellable, callback, user_data, argv); } static gboolean -g_unix_volume_unmount_finish (GVolume *volume, - GAsyncResult *result, - GError **error) +g_unix_volume_mount_finish (GVolume *volume, + GAsyncResult *result, + GError **error) { - return TRUE; + g_return_val_if_fail (g_task_is_valid (result, volume), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); } static void -g_unix_volume_eject (GVolume *volume, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +g_unix_volume_eject (GVolume *volume, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - /* TODO */ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + const gchar *argv[] = { "eject", NULL, NULL }; + + argv[1] = unix_volume->device_path; + + eject_mount_do (volume, cancellable, callback, user_data, argv); } static gboolean -g_unix_volume_eject_finish (GVolume *volume, - GAsyncResult *result, - GError **error) +g_unix_volume_eject_finish (GVolume *volume, + GAsyncResult *result, + GError **error) { - return TRUE; + g_return_val_if_fail (g_task_is_valid (result, volume), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gchar * +g_unix_volume_get_identifier (GVolume *volume, + const gchar *kind) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + + if (unix_volume->identifier_type != NULL && + strcmp (kind, unix_volume->identifier_type) == 0) + return g_strdup (unix_volume->identifier); + + return NULL; +} + +static gchar ** +g_unix_volume_enumerate_identifiers (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + gchar **res; + + if (unix_volume->identifier_type) + { + res = g_new (gchar *, 2); + res[0] = g_strdup (unix_volume->identifier_type); + res[1] = NULL; + } + else + { + res = g_new (gchar *, 1); + res[0] = NULL; + } + + return res; } static void g_unix_volume_volume_iface_init (GVolumeIface *iface) { - iface->get_root = g_unix_volume_get_root; iface->get_name = g_unix_volume_get_name; iface->get_icon = g_unix_volume_get_icon; + iface->get_symbolic_icon = g_unix_volume_get_symbolic_icon; + iface->get_uuid = g_unix_volume_get_uuid; iface->get_drive = g_unix_volume_get_drive; - iface->can_unmount = g_unix_volume_can_unmount; + iface->get_mount = g_unix_volume_get_mount; + iface->can_mount = g_unix_volume_can_mount; iface->can_eject = g_unix_volume_can_eject; - iface->unmount = g_unix_volume_unmount; - iface->unmount_finish = g_unix_volume_unmount_finish; + iface->should_automount = g_unix_volume_should_automount; + iface->mount_fn = g_unix_volume_mount; + iface->mount_finish = g_unix_volume_mount_finish; iface->eject = g_unix_volume_eject; iface->eject_finish = g_unix_volume_eject_finish; + iface->get_identifier = g_unix_volume_get_identifier; + iface->enumerate_identifiers = g_unix_volume_enumerate_identifiers; }