[gvfs/tracker-metadata: 2/4] metadata: Add a way to map tree item back to real path
- From: Tomas Bzatek <tbzatek src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/tracker-metadata: 2/4] metadata: Add a way to map tree item back to real path
- Date: Tue, 14 Dec 2010 17:04:09 +0000 (UTC)
commit 8c24a00dfef7471d570ef255f93fea1c7d3766a3
Author: Tomas Bzatek <tbzatek redhat com>
Date: Tue Dec 14 17:18:41 2010 +0100
metadata: Add a way to map tree item back to real path
We need to have a way to reverse-map tree file name to a real path.
This however works properly only when a device is mounted. We don't
maintain database of UUIDs/labels nor metadata files have a path in
the header either.
metadata/metatree.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++-
metadata/metatree.h | 2 +
2 files changed, 152 insertions(+), 2 deletions(-)
---
diff --git a/metadata/metatree.c b/metadata/metatree.c
index 3a1c12b..c2ddf6f 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -2800,6 +2800,55 @@ get_tree_from_udev (MetaLookupCache *cache,
return res;
}
+
+static char *
+get_device_file_from_udev (const char *treename)
+{
+ struct udev_device *dev;
+ struct udev_enumerate *enumerator;
+ struct udev_list_entry *entry;
+ char *device_file;
+
+ G_LOCK (udev);
+
+ if (udev == NULL)
+ udev = udev_new ();
+
+ device_file = NULL;
+
+ /* Can't get device by UUID directly, hence use enumerator */
+ enumerator = udev_enumerate_new (udev);
+ if (g_str_has_prefix (treename, "uuid-"))
+ udev_enumerate_add_match_property (enumerator, "ID_FS_UUID_ENC", treename + 5);
+ else
+ if (g_str_has_prefix (treename, "label-"))
+ udev_enumerate_add_match_property (enumerator, "ID_FS_LABEL_ENC", treename + 6);
+ else
+ goto out;
+
+ if (udev_enumerate_scan_devices (enumerator))
+ goto out;
+
+ entry = udev_enumerate_get_list_entry (enumerator);
+ while (entry)
+ {
+ dev = udev_device_new_from_syspath (udev, udev_list_entry_get_name (entry));
+ device_file = g_strdup (udev_device_get_property_value (dev, "DEVNAME"));
+
+ udev_device_unref (dev);
+ if (device_file)
+ break;
+
+ entry = udev_list_entry_get_next (entry);
+ }
+
+out:
+ udev_enumerate_unref (enumerator);
+ G_UNLOCK (udev);
+
+ return device_file;
+}
+
#endif
static const char *
@@ -2825,6 +2874,8 @@ get_tree_for_device (MetaLookupCache *cache,
typedef struct {
char *mountpoint;
char *root;
+ char *device;
+ gboolean outside_root;
} MountinfoEntry;
static gboolean mountinfo_initialized = FALSE;
@@ -2920,6 +2971,7 @@ parse_mountinfo (const char *contents)
const char *line;
const char *line_root;
const char *line_mountpoint;
+ const char *line_device;
a = g_array_new (TRUE, TRUE, sizeof (MountinfoEntry));
@@ -2943,16 +2995,39 @@ parse_mountinfo (const char *contents)
/* mountpoint */
line = strchr (line+1, ' ');
line_mountpoint = line + 1;
+ if (line)
+ {
+ /* mount options */
+ line = strchr (line+1, ' ');
+ if (line)
+ {
+ /* dash */
+ line = strchr (line+1, ' ');
+ if (line)
+ {
+ /* fstype */
+ line = strchr (line+1, ' ');
+ if (line)
+ {
+ /* device */
+ line = strchr (line+1, ' ');
+ line_device = line + 1;
+ }
+ }
+ }
+ }
}
}
}
- if (line_mountpoint && !(line_root[0] == '/' && line_root[1] == ' '))
+ if (line_mountpoint)
{
MountinfoEntry new_entry;
new_entry.mountpoint = mountinfo_unescape (line_mountpoint);
new_entry.root = mountinfo_unescape (line_root);
+ new_entry.device = mountinfo_unescape (line_device);
+ new_entry.outside_root = !(line_root[0] == '/' && line_root[1] == ' ');
g_array_append_val (a, new_entry);
}
@@ -3037,7 +3112,8 @@ find_mountinfo_root_for_mountpoint (const char *mountpoint)
{
for (i = 0; mountinfo_roots[i].mountpoint != NULL; i++)
{
- if (strcmp (mountinfo_roots[i].mountpoint, mountpoint) == 0)
+ if (mountinfo_roots[i].outside_root &&
+ strcmp (mountinfo_roots[i].mountpoint, mountpoint) == 0)
{
res = g_strdup (mountinfo_roots[i].root);
break;
@@ -3050,6 +3126,35 @@ find_mountinfo_root_for_mountpoint (const char *mountpoint)
return res;
}
+static char *
+find_mountinfo_root_for_device_file (const char *device_file)
+{
+ char *res;
+ int i;
+
+ res = NULL;
+
+ G_LOCK (mountinfo);
+
+ update_mountinfo ();
+
+ if (mountinfo_roots)
+ {
+ for (i = 0; mountinfo_roots[i].mountpoint != NULL; i++)
+ {
+ if (strcmp (mountinfo_roots[i].device, device_file) == 0)
+ {
+ res = g_strdup (mountinfo_roots[i].mountpoint);
+ break;
+ }
+ }
+ }
+
+ G_UNLOCK (mountinfo);
+
+ return res;
+}
+
#endif
@@ -3343,3 +3448,46 @@ meta_lookup_cache_lookup_path (MetaLookupCache *cache,
g_free (prefix);
return NULL;
}
+
+char *
+meta_tree_get_real_path (MetaTree *tree,
+ const char *path)
+{
+ const char *treefile;
+ char *metadata_dir;
+ char *filename;
+ char *device_file;
+ char *mount_path;
+ char *real_path;
+
+ treefile = meta_tree_get_filename (tree);
+
+ if (treefile == NULL)
+ return NULL;
+
+ real_path = NULL;
+ filename = NULL;
+
+ metadata_dir = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), "gvfs-metadata", G_DIR_SEPARATOR_S, NULL);
+ if (path_has_prefix (treefile, metadata_dir))
+ filename = g_strdup (treefile + strlen (metadata_dir));
+ g_free (metadata_dir);
+
+ if (g_strcmp0 ("root", filename) == 0)
+ mount_path = g_strdup ("/");
+ else
+ if (g_strcmp0 ("home", filename) == 0)
+ mount_path = g_strdup (g_get_home_dir());
+ else
+ {
+ device_file = get_device_file_from_udev (filename);
+ mount_path = find_mountinfo_root_for_device_file (device_file);
+ g_free (device_file);
+ }
+
+ if (mount_path)
+ real_path = g_build_filename (mount_path, path, NULL);
+ g_free (mount_path);
+
+ return real_path;
+}
diff --git a/metadata/metatree.h b/metadata/metatree.h
index 40b4457..da77d6c 100644
--- a/metadata/metatree.h
+++ b/metadata/metatree.h
@@ -65,6 +65,8 @@ MetaTree * meta_tree_ref (MetaTree *tree);
void meta_tree_unref (MetaTree *tree);
void meta_tree_refresh (MetaTree *tree);
const char *meta_tree_get_filename (MetaTree *tree);
+char * meta_tree_get_real_path (MetaTree *tree,
+ const char *path);
gboolean meta_tree_exists (MetaTree *tree);
MetaKeyType meta_tree_lookup_key_type (MetaTree *tree,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]