From 193575c1bee1e3d57bda2884a0e9a72f9ffcaebb Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Sun, 31 May 2020 15:56:23 +0200 Subject: extract: Remove Storage After the removal of mediaartlocal, this is useless now. It can also cause some lock-ups if gvfs is missing --- libmediaart/Makefile.am | 4 +- libmediaart/extract.c | 19 +- libmediaart/meson.build | 1 - libmediaart/storage.c | 1100 ----------------------------------------------- libmediaart/storage.h | 118 ----- 5 files changed, 2 insertions(+), 1240 deletions(-) delete mode 100644 libmediaart/storage.c delete mode 100644 libmediaart/storage.h diff --git a/libmediaart/Makefile.am b/libmediaart/Makefile.am index baea0d3..42a270b 100644 --- a/libmediaart/Makefile.am +++ b/libmediaart/Makefile.am @@ -21,9 +21,7 @@ libmediaart_sources = \ cache.h \ extract.c \ extract.h \ - extractgeneric.h \ - storage.c \ - storage.h + extractgeneric.h libmediaartinclude_HEADERS = \ mediaart.h \ diff --git a/libmediaart/extract.c b/libmediaart/extract.c index 4ff61bb..d505285 100644 --- a/libmediaart/extract.c +++ b/libmediaart/extract.c @@ -28,7 +28,6 @@ #include #include "extractgeneric.h" -#include "storage.h" #include "extract.h" #include "cache.h" @@ -69,7 +68,6 @@ typedef struct { gboolean disable_requests; GHashTable *media_art_cache; - Storage *storage; } MediaArtProcessPrivate; static const gchar *media_art_type_name[MEDIA_ART_TYPE_COUNT] = { @@ -123,10 +121,6 @@ media_art_process_finalize (GObject *object) process = MEDIA_ART_PROCESS (object); private = media_art_process_get_instance_private (process); - if (private->storage) { - g_object_unref (private->storage); - } - if (private->media_art_cache) { g_hash_table_unref (private->media_art_cache); } @@ -159,16 +153,6 @@ media_art_process_initable_init (GInitable *initable, (GDestroyNotify) g_free, NULL); - private->storage = storage_new (); - if (!private->storage) { - g_critical ("Could not start storage module for removable media detection"); - g_set_error_literal (error, - media_art_error_quark (), - MEDIA_ART_ERROR_NO_STORAGE, - _("Could not initialize storage module")); - return FALSE; - } - /* Returns 0 if already exists, so we don't check if directory * existed before, it's an additional stat() call we just * don't need. @@ -215,8 +199,7 @@ media_art_process_init (MediaArtProcess *thumbnailer) * * Initialize a GObject for processing and extracting media art. * - * This function initializes cache hash tables, backend plugins, - * and storage modules used for removable devices. + * This function initializes cache hash tables and backend plugins, * * Returns: A new #MediaArtProcess object on success or %NULL if * @error is set. This object must be freed using g_object_unref(). diff --git a/libmediaart/meson.build b/libmediaart/meson.build index 265a9ab..4f15513 100644 --- a/libmediaart/meson.build +++ b/libmediaart/meson.build @@ -13,7 +13,6 @@ libmediaart_introspection_sources = [ libmediaart_sources = [ 'cache.c', 'extract.c', - 'storage.c' ] if image_library_name == 'gdk-pixbuf-2.0' diff --git a/libmediaart/storage.c b/libmediaart/storage.c deleted file mode 100644 index 36213d7..0000000 --- a/libmediaart/storage.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Copyright (C) 2008, Nokia - * - * 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.1 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. - */ - -#include "config.h" - -#include - -#include -#include - -#include "storage.h" -#include "marshal.h" - -/** - * SECTION:storage - * @short_description: Removable storage and mount point convenience API - * @include: libmediaart/mediaart.h - * - * This API is a convenience to to be able to keep track of volumes - * which are mounted and also the type of removable media available. - * The API is built upon the top of GIO's #GMount, #GDrive and #GVolume API. - **/ - -#define STORAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_STORAGE, StoragePrivate)) - -typedef struct { - GVolumeMonitor *volume_monitor; - - GNode *mounts; - GHashTable *mounts_by_uuid; - GHashTable *unmount_watchdogs; -} StoragePrivate; - -typedef struct { - gchar *mount_point; - gchar *uuid; - guint unmount_timer_id; - guint removable : 1; - guint optical : 1; -} MountInfo; - -typedef struct { - const gchar *path; - GNode *node; -} TraverseData; - -typedef struct { - GSList *roots; - StorageType type; - gboolean exact_match; -} GetRoots; - -typedef struct { - Storage *storage; - GMount *mount; -} UnmountCheckData; - -static void storage_finalize (GObject *object); -static gboolean mount_info_free (GNode *node, - gpointer user_data); -static void mount_node_free (GNode *node); -static gboolean mounts_setup (Storage *storage); -static void mount_added_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data); -static void mount_removed_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data); -static void mount_pre_removed_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data); - -enum { - MOUNT_POINT_ADDED, - MOUNT_POINT_REMOVED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE (Storage, storage, G_TYPE_OBJECT); - -static void -storage_class_init (StorageClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = storage_finalize; - - signals[MOUNT_POINT_ADDED] = - g_signal_new ("mount-point-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - media_art_marshal_VOID__STRING_STRING_STRING_BOOLEAN_BOOLEAN, - G_TYPE_NONE, - 5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - - signals[MOUNT_POINT_REMOVED] = - g_signal_new ("mount-point-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - media_art_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_STRING); - - g_type_class_add_private (object_class, sizeof (StoragePrivate)); -} - -static void -storage_init (Storage *storage) -{ - StoragePrivate *priv; - - priv = STORAGE_GET_PRIVATE (storage); - - priv->mounts = g_node_new (NULL); - - priv->mounts_by_uuid = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify) g_free, - NULL); - priv->unmount_watchdogs = g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) g_source_remove); - - priv->volume_monitor = g_volume_monitor_get (); - - /* Volume and property notification callbacks */ - g_signal_connect_object (priv->volume_monitor, "mount-removed", - G_CALLBACK (mount_removed_cb), storage, 0); - g_signal_connect_object (priv->volume_monitor, "mount-pre-unmount", - G_CALLBACK (mount_pre_removed_cb), storage, 0); - g_signal_connect_object (priv->volume_monitor, "mount-added", - G_CALLBACK (mount_added_cb), storage, 0); - - /* Get all mounts and set them up */ - if (!mounts_setup (storage)) { - return; - } -} - -static void -storage_finalize (GObject *object) -{ - StoragePrivate *priv; - - priv = STORAGE_GET_PRIVATE (object); - - g_hash_table_destroy (priv->unmount_watchdogs); - - if (priv->mounts_by_uuid) { - g_hash_table_unref (priv->mounts_by_uuid); - } - - if (priv->mounts) { - mount_node_free (priv->mounts); - } - - if (priv->volume_monitor) { - g_object_unref (priv->volume_monitor); - } - - (G_OBJECT_CLASS (storage_parent_class)->finalize) (object); -} - -static void -mount_node_free (GNode *node) -{ - g_node_traverse (node, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - mount_info_free, - NULL); - - g_node_destroy (node); -} - -static gboolean -mount_node_traverse_func (GNode *node, - gpointer user_data) -{ - TraverseData *data; - MountInfo *info; - - if (!node->data) { - /* Root node */ - return FALSE; - } - - data = user_data; - info = node->data; - - if (g_str_has_prefix (data->path, info->mount_point)) { - data->node = node; - return TRUE; - } - - return FALSE; -} - -static GNode * -mount_node_find (GNode *root, - const gchar *path) -{ - TraverseData data = { path, NULL }; - - g_node_traverse (root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - mount_node_traverse_func, - &data); - - return data.node; -} - -static gboolean -mount_info_free (GNode *node, - gpointer user_data) -{ - MountInfo *info; - - info = node->data; - - if (info) { - g_free (info->mount_point); - g_free (info->uuid); - - g_slice_free (MountInfo, info); - } - - return FALSE; -} - -static MountInfo * -mount_info_find (GNode *root, - const gchar *path) -{ - GNode *node; - - node = mount_node_find (root, path); - return (node) ? node->data : NULL; -} - -static StorageType -mount_info_get_type (MountInfo *info) -{ - StorageType mount_type = 0; - - if (info->removable) { - mount_type |= STORAGE_REMOVABLE; - } - - if (info->optical) { - mount_type |= STORAGE_OPTICAL; - } - - return mount_type; -} - -static gchar * -mount_point_normalize (const gchar *mount_point) -{ - gchar *mp; - - /* Normalize all mount points to have a / at the end */ - if (g_str_has_suffix (mount_point, G_DIR_SEPARATOR_S)) { - mp = g_strdup (mount_point); - } else { - mp = g_strconcat (mount_point, G_DIR_SEPARATOR_S, NULL); - } - - return mp; -} - -static GNode * -mount_add_hierarchy (GNode *root, - const gchar *uuid, - const gchar *mount_point, - gboolean removable, - gboolean optical) -{ - MountInfo *info; - GNode *node; - gchar *mp; - - mp = mount_point_normalize (mount_point); - node = mount_node_find (root, mp); - - if (!node) { - node = root; - } - - info = g_slice_new (MountInfo); - info->mount_point = mp; - info->uuid = g_strdup (uuid); - info->removable = removable; - info->optical = optical; - - return g_node_append_data (node, info); -} - -static void -mount_add_new (Storage *storage, - const gchar *uuid, - const gchar *mount_point, - const gchar *mount_name, - gboolean removable_device, - gboolean optical_disc) -{ - StoragePrivate *priv; - GNode *node; - - priv = STORAGE_GET_PRIVATE (storage); - - node = mount_add_hierarchy (priv->mounts, uuid, mount_point, removable_device, optical_disc); - g_hash_table_insert (priv->mounts_by_uuid, g_strdup (uuid), node); - - g_signal_emit (storage, - signals[MOUNT_POINT_ADDED], - 0, - uuid, - mount_point, - mount_name, - removable_device, - optical_disc, - NULL); -} - -static gchar * -mount_guess_content_type (GMount *mount, - gboolean *is_optical, - gboolean *is_multimedia, - gboolean *is_blank) -{ - gchar *content_type = NULL; - gchar **guess_type; - - *is_optical = FALSE; - *is_multimedia = FALSE; - *is_blank = FALSE; - - /* This function has 2 purposes: - * - * 1. Detect if we are using optical media - * 2. Detect if we are video or music, we can't index those types - * - * We try to determine the content type because we don't want - * to store Volume information in about DVDs and media - * which has no real data for us to mine. - * - * Generally, if is_multimedia is TRUE then we end up ignoring - * the media. - */ - guess_type = g_mount_guess_content_type_sync (mount, TRUE, NULL, NULL); - - if (guess_type) { - gint i = 0; - - while (!content_type && guess_type[i]) { - if (!g_strcmp0 (guess_type[i], "x-content/image-picturecd")) { - /* Images */ - content_type = g_strdup (guess_type[i]); - } else if (!g_strcmp0 (guess_type[i], "x-content/video-bluray") || - !g_strcmp0 (guess_type[i], "x-content/video-dvd") || - !g_strcmp0 (guess_type[i], "x-content/video-hddvd") || - !g_strcmp0 (guess_type[i], "x-content/video-svcd") || - !g_strcmp0 (guess_type[i], "x-content/video-vcd")) { - /* Videos */ - *is_multimedia = TRUE; - content_type = g_strdup (guess_type[i]); - } else if (!g_strcmp0 (guess_type[i], "x-content/audio-cdda") || - !g_strcmp0 (guess_type[i], "x-content/audio-dvd") || - !g_strcmp0 (guess_type[i], "x-content/audio-player")) { - /* Audios */ - *is_multimedia = TRUE; - content_type = g_strdup (guess_type[i]); - } else if (!g_strcmp0 (guess_type[i], "x-content/blank-bd") || - !g_strcmp0 (guess_type[i], "x-content/blank-cd") || - !g_strcmp0 (guess_type[i], "x-content/blank-dvd") || - !g_strcmp0 (guess_type[i], "x-content/blank-hddvd")) { - /* Blank */ - *is_blank = TRUE; - content_type = g_strdup (guess_type[i]); - } else if (!g_strcmp0 (guess_type[i], "x-content/software") || - !g_strcmp0 (guess_type[i], "x-content/unix-software") || - !g_strcmp0 (guess_type[i], "x-content/win32-software")) { - /* NOTE: This one is a guess, can we - * have this content type on - * none-optical mount points? - */ - content_type = g_strdup (guess_type[i]); - } else { - /* else, keep on with the next guess, if any */ - i++; - } - } - - /* If we didn't have an exact match on possible guessed content types, - * then use the first one returned (best guess always first) if any */ - if (!content_type && guess_type[0]) { - content_type = g_strdup (guess_type[0]); - } - - g_strfreev (guess_type); - } - - if (content_type) { - if (strstr (content_type, "vcd") || - strstr (content_type, "cdda") || - strstr (content_type, "dvd") || - strstr (content_type, "bluray")) { - *is_optical = TRUE; - } - } else { - GUnixMountEntry *entry; - gchar *mount_path; - GFile *mount_root; - - /* No content type was guessed, try to find out - * at least whether it's an optical media or not - */ - mount_root = g_mount_get_root (mount); - mount_path = g_file_get_path (mount_root); - - /* FIXME: Try to assume we have a unix mount :( - * EEK, once in a while, I have to write crack, oh well - */ - if (mount_path && - (entry = g_unix_mount_at (mount_path, NULL)) != NULL) { - const gchar *filesystem_type; - gchar *device_path = NULL; - GVolume *volume; - - volume = g_mount_get_volume (mount); - filesystem_type = g_unix_mount_get_fs_type (entry); - g_debug (" Using filesystem type:'%s'", - filesystem_type); - - /* Volume may be NULL */ - if (volume) { - device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); - g_debug (" Using device path:'%s'", - device_path); - g_object_unref (volume); - } - - /* NOTE: This code was taken from guess_mount_type() - * in GIO's gunixmounts.c and adapted purely for - * guessing optical media. We don't use the guessing - * code for other types such as MEMSTICKS, ZIPs, - * IPODs, etc. - * - * This code may need updating over time since it is - * very situational depending on how distributions - * mount their devices and how devices are named in - * /dev. - */ - if (strcmp (filesystem_type, "udf") == 0 || - strcmp (filesystem_type, "iso9660") == 0 || - strcmp (filesystem_type, "cd9660") == 0 || - (device_path && - (g_str_has_prefix (device_path, "/dev/cdrom") || - g_str_has_prefix (device_path, "/dev/acd") || - g_str_has_prefix (device_path, "/dev/cd")))) { - *is_optical = TRUE; - } else if (device_path && - g_str_has_prefix (device_path, "/vol/")) { - const gchar *name; - - name = mount_path + strlen ("/"); - - if (g_str_has_prefix (name, "cdrom")) { - *is_optical = TRUE; - } - } else { - gchar *basename = g_path_get_basename (mount_path); - - if (g_str_has_prefix (basename, "cdr") || - g_str_has_prefix (basename, "cdwriter") || - g_str_has_prefix (basename, "burn") || - g_str_has_prefix (basename, "dvdr")) { - *is_optical = TRUE; - } - - g_free (basename); - } - - g_free (device_path); - g_free (mount_path); - g_unix_mount_free (entry); - } else { - g_debug (" No GUnixMountEntry found, needed for detecting if optical media... :("); - g_free (mount_path); - } - - g_object_unref (mount_root); - } - - return content_type; -} - -static void -mount_add (Storage *storage, - GMount *mount) -{ - StoragePrivate *priv; - GFile *root; - GVolume *volume; - gchar *mount_name, *mount_path, *uuid; - gboolean is_optical = FALSE; - gboolean is_removable = FALSE; - - /* Get mount name */ - mount_name = g_mount_get_name (mount); - - /* Get root path of the mount */ - root = g_mount_get_root (mount); - mount_path = g_file_get_path (root); - - g_debug ("Found '%s' mounted on path '%s'", - mount_name, - mount_path); - - /* Do not process shadowed mounts! */ - if (g_mount_is_shadowed (mount)) { - g_debug (" Skipping shadowed mount '%s'", mount_name); - g_object_unref (root); - g_free (mount_path); - g_free (mount_name); - return; - } - - priv = STORAGE_GET_PRIVATE (storage); - - /* fstab partitions may not have corresponding - * GVolumes, so volume may be NULL */ - volume = g_mount_get_volume (mount); - if (volume) { - /* GMount with GVolume */ - - /* Try to get UUID from the Volume. - * Note that g_volume_get_uuid() is NOT equivalent */ - uuid = g_volume_get_identifier (volume, - G_VOLUME_IDENTIFIER_KIND_UUID); - if (!uuid) { - gchar *content_type; - gboolean is_multimedia; - gboolean is_blank; - - /* Optical discs usually won't have UUID in the GVolume */ - content_type = mount_guess_content_type (mount, &is_optical, &is_multimedia, &is_blank); - is_removable = TRUE; - - /* We don't index content which is video, music or blank */ - if (!is_multimedia && !is_blank) { - uuid = g_compute_checksum_for_string (G_CHECKSUM_MD5, - mount_name, - -1); - g_debug (" No UUID, generated:'%s' (based on mount name)", uuid); - g_debug (" Assuming GVolume has removable media, if wrong report a bug! " - "content type is '%s'", - content_type); - } else { - g_debug (" Being ignored because mount with volume is music/video/blank " - "(content type:%s, optical:%s, multimedia:%s, blank:%s)", - content_type, - is_optical ? "yes" : "no", - is_multimedia ? "yes" : "no", - is_blank ? "yes" : "no"); - } - - g_free (content_type); - } else { - /* Any other removable media will have UUID in the - * GVolume. Note that this also may include some - * partitions in the machine which have GVolumes - * associated to the GMounts. We also check a drive - * exists to be sure the device is local. */ - GDrive *drive; - - drive = g_volume_get_drive (volume); - - if (drive) { - /* We can't mount/unmount system volumes, so tag - * them as non removable. */ - is_removable = g_volume_can_mount (volume); - g_debug (" Found mount with volume and drive which %s be mounted: " - "Assuming it's %s removable, if wrong report a bug!", - is_removable ? "can" : "cannot", - is_removable ? "" : "not"); - g_object_unref (drive); - } else { - /* Note: not sure when this can happen... */ - g_debug (" Mount with volume but no drive, " - "assuming not a removable device, " - "if wrong report a bug!"); - is_removable = FALSE; - } - } - - g_object_unref (volume); - } else { - /* GMount without GVolume. - * Note: Never found a case where this g_mount_get_uuid() returns - * non-NULL... :-) */ - uuid = g_mount_get_uuid (mount); - if (!uuid) { - if (mount_path) { - gchar *content_type; - gboolean is_multimedia; - gboolean is_blank; - - content_type = mount_guess_content_type (mount, &is_optical, &is_multimedia, &is_blank); - - /* Note: for GMounts without GVolume, is_blank should NOT be considered, - * as it may give unwanted results... */ - if (!is_multimedia) { - uuid = g_compute_checksum_for_string (G_CHECKSUM_MD5, - mount_path, - -1); - g_debug (" No UUID, generated:'%s' (based on mount path)", uuid); - } else { - g_debug (" Being ignored because mount is music/video " - "(content type:%s, optical:%s, multimedia:%s)", - content_type, - is_optical ? "yes" : "no", - is_multimedia ? "yes" : "no"); - } - - g_free (content_type); - } else { - g_debug (" Being ignored because mount has no GVolume (i.e. not user mountable) " - "and has no mount root path available"); - } - } - } - - /* If we got something to be used as UUID, then add the mount - * to the Storage */ - if (uuid && mount_path && !g_hash_table_lookup (priv->mounts_by_uuid, uuid)) { - g_debug (" Adding mount point with UUID: '%s', removable: %s, optical: %s, path: '%s'", - uuid, - is_removable ? "yes" : "no", - is_optical ? "yes" : "no", - mount_path); - mount_add_new (storage, uuid, mount_path, mount_name, is_removable, is_optical); - } else { - g_debug (" Skipping mount point with UUID: '%s', path: '%s', already managed: '%s'", - uuid ? uuid : "none", - mount_path ? mount_path : "none", - (uuid && g_hash_table_lookup (priv->mounts_by_uuid, uuid)) ? "yes" : "no"); - } - - g_free (mount_name); - g_free (mount_path); - g_free (uuid); - g_object_unref (root); -} - -static gboolean -mounts_setup (Storage *storage) -{ - StoragePrivate *priv; - GList *mounts, *lm; - - priv = STORAGE_GET_PRIVATE (storage); - - mounts = g_volume_monitor_get_mounts (priv->volume_monitor); - - if (!mounts) { - g_debug ("No mounts found to iterate"); - return TRUE; - } - - /* Iterate over all available mounts and add them. - * Note that GVolumeMonitor shows only those mounts which are - * actually mounted. */ - for (lm = mounts; lm; lm = g_list_next (lm)) { - mount_add (storage, lm->data); - g_object_unref (lm->data); - } - - g_list_free (mounts); - - return TRUE; -} - -static void -mount_added_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data) -{ - mount_add (user_data, mount); -} - -static void -mount_remove (Storage *storage, - GMount *mount) -{ - StoragePrivate *priv; - MountInfo *info; - GNode *node; - GFile *file; - gchar *name; - gchar *mount_point; - gchar *mp; - - priv = STORAGE_GET_PRIVATE (storage); - - file = g_mount_get_root (mount); - mount_point = g_file_get_path (file); - name = g_mount_get_name (mount); - - mp = mount_point_normalize (mount_point); - node = mount_node_find (priv->mounts, mp); - g_free (mp); - - if (node) { - info = node->data; - - g_debug ("Mount:'%s' with UUID:'%s' now unmounted from:'%s'", - name, - info->uuid, - mount_point); - - g_signal_emit (storage, signals[MOUNT_POINT_REMOVED], 0, info->uuid, mount_point, NULL); - - g_hash_table_remove (priv->mounts_by_uuid, info->uuid); - mount_node_free (node); - } else { - g_debug ("Mount:'%s' now unmounted from:'%s' (was not tracked)", - name, - mount_point); - } - - g_free (name); - g_free (mount_point); - g_object_unref (file); -} - -static void -mount_removed_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data) -{ - Storage *storage; - StoragePrivate *priv; - - storage = user_data; - priv = STORAGE_GET_PRIVATE (storage); - - mount_remove (storage, mount); - - /* Unmount suceeded, remove the pending check */ - g_hash_table_remove (priv->unmount_watchdogs, mount); -} - -static gboolean -unmount_failed_cb (gpointer user_data) -{ - UnmountCheckData *data = user_data; - StoragePrivate *priv; - - /* If this timeout gets to be executed, this is due - * to a pre-unmount signal with no corresponding - * unmount in a timely fashion, we assume this is - * due to an error, and add back the still mounted - * path. - */ - priv = STORAGE_GET_PRIVATE (data->storage); - - g_warning ("Unmount operation failed, adding back mount point..."); - - mount_add (data->storage, data->mount); - - g_hash_table_remove (priv->unmount_watchdogs, data->mount); - return FALSE; -} - -static void -mount_pre_removed_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data) -{ - Storage *storage; - StoragePrivate *priv; - UnmountCheckData *data; - guint id; - - storage = user_data; - priv = STORAGE_GET_PRIVATE (storage); - - mount_remove (storage, mount); - - /* Add check for failed unmounts */ - data = g_new (UnmountCheckData, 1); - data->storage = storage; - data->mount = mount; - - id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE + 10, 3, - unmount_failed_cb, - data, (GDestroyNotify) g_free); - g_hash_table_insert (priv->unmount_watchdogs, data->mount, - GUINT_TO_POINTER (id)); -} - -/** - * storage_new: - * - * Creates a new instance of #Storage. - * - * Returns: The newly created #Storage. - * - * Since: 0.2.0 - **/ -Storage * -storage_new (void) -{ - return g_object_new (TYPE_STORAGE, NULL); -} - -static void -get_mount_point_by_uuid_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - GetRoots *gr; - GNode *node; - MountInfo *info; - StorageType mount_type; - - gr = user_data; - node = value; - info = node->data; - mount_type = mount_info_get_type (info); - - /* is mount of the type we're looking for? */ - if ((gr->exact_match && mount_type == gr->type) || - (!gr->exact_match && (mount_type & gr->type))) { - gchar *normalized_mount_point; - gint len; - - normalized_mount_point = g_strdup (info->mount_point); - len = strlen (normalized_mount_point); - - /* Don't include trailing slashes */ - if (len > 2 && normalized_mount_point[len - 1] == G_DIR_SEPARATOR) { - normalized_mount_point[len - 1] = '\0'; - } - - gr->roots = g_slist_prepend (gr->roots, normalized_mount_point); - } -} - -/** - * storage_get_device_roots: - * @storage: A #Storage - * @type: A #StorageType - * @exact_match: if all devices should exactly match the types - * - * Returns: (transfer full) (element-type utf8): a #GSList of strings - * containing the root directories for devices with @type based on - * @exact_match. Each element must be freed using g_free() and the - * list itself through g_slist_free(). - * - * Since: 0.2.0 - **/ -GSList * -storage_get_device_roots (Storage *storage, - StorageType type, - gboolean exact_match) -{ - StoragePrivate *priv; - GetRoots gr; - - g_return_val_if_fail (IS_STORAGE (storage), NULL); - - priv = STORAGE_GET_PRIVATE (storage); - - gr.roots = NULL; - gr.type = type; - gr.exact_match = exact_match; - - g_hash_table_foreach (priv->mounts_by_uuid, - get_mount_point_by_uuid_foreach, - &gr); - - return gr.roots; -} - -/** - * storage_get_device_uuids: - * @storage: A #Storage - * @type: A #StorageType - * @exact_match: if all devices should exactly match the types - * - * Returns: (transfer full) (element-type utf8): a #GSList of - * strings containing the UUID for devices with @type based - * on @exact_match. Each element must be freed using g_free() - * and the list itself through g_slist_free(). - * - * Since: 0.2.0 - **/ -GSList * -storage_get_device_uuids (Storage *storage, - StorageType type, - gboolean exact_match) -{ - StoragePrivate *priv; - GHashTableIter iter; - gpointer key, value; - GSList *uuids; - - g_return_val_if_fail (IS_STORAGE (storage), NULL); - - priv = STORAGE_GET_PRIVATE (storage); - - uuids = NULL; - - g_hash_table_iter_init (&iter, priv->mounts_by_uuid); - - while (g_hash_table_iter_next (&iter, &key, &value)) { - const gchar *uuid; - GNode *node; - MountInfo *info; - StorageType mount_type; - - uuid = key; - node = value; - info = node->data; - - mount_type = mount_info_get_type (info); - - /* is mount of the type we're looking for? */ - if ((exact_match && mount_type == type) || - (!exact_match && (mount_type & type))) { - uuids = g_slist_prepend (uuids, g_strdup (uuid)); - } - } - - return uuids; -} - -/** - * storage_get_mount_point_for_uuid: - * @storage: A #Storage - * @uuid: A string pointer to the UUID for the %GVolume. - * - * Returns: The mount point for @uuid, this should not be freed. - * - * Since: 0.2.0 - **/ -const gchar * -storage_get_mount_point_for_uuid (Storage *storage, - const gchar *uuid) -{ - StoragePrivate *priv; - GNode *node; - MountInfo *info; - - g_return_val_if_fail (IS_STORAGE (storage), NULL); - g_return_val_if_fail (uuid != NULL, NULL); - - priv = STORAGE_GET_PRIVATE (storage); - - node = g_hash_table_lookup (priv->mounts_by_uuid, uuid); - - if (!node) { - return NULL; - } - - info = node->data; - - return info->mount_point; -} - -/** - * storage_get_type_for_uuid: - * @storage: A #Storage - * @uuid: A string pointer to the UUID for the %GVolume. - * - * Returns: The type flags for @uuid. - * - * Since: 0.2.0 - **/ -StorageType -storage_get_type_for_uuid (Storage *storage, - const gchar *uuid) -{ - StoragePrivate *priv; - GNode *node; - StorageType type = 0; - - g_return_val_if_fail (IS_STORAGE (storage), 0); - g_return_val_if_fail (uuid != NULL, 0); - - priv = STORAGE_GET_PRIVATE (storage); - - node = g_hash_table_lookup (priv->mounts_by_uuid, uuid); - - if (node) { - MountInfo *info; - - info = node->data; - - if (info->removable) { - type |= STORAGE_REMOVABLE; - } - if (info->optical) { - type |= STORAGE_OPTICAL; - } - } - - return type; -} - -/** - * storage_get_uuid_for_file: - * @storage: A #Storage - * @file: a file - * - * Returns the UUID of the removable device for @file - * - * Returns: Returns the UUID of the removable device for @file, this - * should not be freed. - * - * Since: 0.2.0 - **/ -const gchar * -storage_get_uuid_for_file (Storage *storage, - GFile *file) -{ - StoragePrivate *priv; - gchar *path; - MountInfo *info; - - g_return_val_if_fail (IS_STORAGE (storage), FALSE); - - path = g_file_get_path (file); - - if (!path) { - return NULL; - } - - /* Normalize all paths to have a / at the end */ - if (!g_str_has_suffix (path, G_DIR_SEPARATOR_S)) { - gchar *norm_path; - - norm_path = g_strconcat (path, G_DIR_SEPARATOR_S, NULL); - g_free (path); - path = norm_path; - } - - priv = STORAGE_GET_PRIVATE (storage); - - info = mount_info_find (priv->mounts, path); - - if (!info) { - g_free (path); - return NULL; - } - - /* g_debug ("Mount for path '%s' is '%s' (UUID:'%s')", */ - /* path, info->mount_point, info->uuid); */ - - g_free (path); - - return info->uuid; -} - diff --git a/libmediaart/storage.h b/libmediaart/storage.h deleted file mode 100644 index e4678ad..0000000 --- a/libmediaart/storage.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2008, Nokia - * - * 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.1 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. - */ - -#ifndef __LIBMEDIAART_STORAGE_H__ -#define __LIBMEDIAART_STORAGE_H__ - -#include -#include - -#if !defined (__LIBMEDIAART_INSIDE__) && !defined (LIBMEDIAART_COMPILATION) -#error "Only must be included directly." -#endif - -G_BEGIN_DECLS - -/** - * StorageType: - * @STORAGE_REMOVABLE: Storage is a removable media - * @STORAGE_OPTICAL: Storage is an optical disc - * - * Flags specifying properties of the type of storage. - * - * Since: 0.2.0 - */ -typedef enum { - STORAGE_REMOVABLE = 1 << 0, - STORAGE_OPTICAL = 1 << 1 -} StorageType; - -/** - * STORAGE_TYPE_IS_REMOVABLE: - * @type: Mask of StorageType flags - * - * Check if the given storage type is marked as being removable media. - * - * Returns: %TRUE if the storage is marked as removable media, %FALSE otherwise - * - * Since: 0.2.0 - */ -#define STORAGE_TYPE_IS_REMOVABLE(type) ((type & STORAGE_REMOVABLE) ? TRUE : FALSE) - -/** - * STORAGE_TYPE_IS_OPTICAL: - * @type: Mask of StorageType flags - * - * Check if the given storage type is marked as being optical disc - * - * Returns: %TRUE if the storage is marked as optical disc, %FALSE otherwise - * - * Since: 0.2.0 - */ -#define STORAGE_TYPE_IS_OPTICAL(type) ((type & STORAGE_OPTICAL) ? TRUE : FALSE) - - -#define TYPE_STORAGE (storage_get_type ()) -#define STORAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_STORAGE, Storage)) -#define STORAGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TYPE_STORAGE, StorageClass)) -#define IS_STORAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_STORAGE)) -#define IS_STORAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_STORAGE)) -#define STORAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_STORAGE, StorageClass)) - -typedef struct _Storage Storage; -typedef struct _StorageClass StorageClass; - -/** - * Storage: - * @parent: parent object - * - * A storage API for using mount points and devices - **/ -struct _Storage { - GObject parent; -}; - -/** - * StorageClass: - * @parent_class: parent object class - * - * A storage class for #Storage. - **/ -struct _StorageClass { - GObjectClass parent_class; -}; - -GType storage_get_type (void) G_GNUC_CONST; -Storage * storage_new (void); -GSList * storage_get_device_roots (Storage *storage, - StorageType type, - gboolean exact_match); -GSList * storage_get_device_uuids (Storage *storage, - StorageType type, - gboolean exact_match); -const gchar *storage_get_mount_point_for_uuid (Storage *storage, - const gchar *uuid); -StorageType storage_get_type_for_uuid (Storage *storage, - const gchar *uuid); -const gchar *storage_get_uuid_for_file (Storage *storage, - GFile *file); - -G_END_DECLS - -#endif /* __LIBMEDIAART_STORAGE_H__ */ -- cgit v1.2.1