summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2013-06-02 19:51:02 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2013-06-13 21:04:42 +0200
commitbf50158cb58d1d22d6ece145d1eabd790b30798f (patch)
treeb616542f50a575d808d07de9477125068d0a6239
parent5235e39b054e7574493c50bf60dce874f040bd6c (diff)
GDaemonFile: fix relative path handling to account for mount_prefix
If two files have two different origins (say, one from g_mount_get_root() and one from g_file_new_for_uri()), the mount_spec they use could expose a different mount_prefix, even if the represent the same URI and network object. This in particular fixes the handling of shadow mounts for dav (which rewrites the mount_spec during mount to find the right prefix) https://bugzilla.gnome.org/show_bug.cgi?id=696279
-rw-r--r--client/gdaemonfile.c85
1 files changed, 69 insertions, 16 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index ebde8c58..25cb3cd0 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -327,13 +327,32 @@ g_daemon_file_prefix_matches (GFile *parent,
GDaemonFile *descendant_daemon = G_DAEMON_FILE (descendant);
const char *remainder;
- if (descendant_daemon->mount_spec != parent_daemon->mount_spec)
- return FALSE;
-
- remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
- if (remainder != NULL && *remainder == '/')
- return TRUE;
- return FALSE;
+ if (descendant_daemon->mount_spec == parent_daemon->mount_spec)
+ {
+ remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
+ if (remainder != NULL && *remainder == '/')
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* If descendant was created with g_file_new_for_uri(), it's
+ mount_prefix is /, but parent might have a different mount_prefix,
+ for example if obtained by g_mount_get_root()
+ */
+ char *full_path;
+ gboolean ok;
+
+ full_path = g_build_path ("/", descendant_daemon->mount_spec->mount_prefix,
+ descendant_daemon->path, NULL);
+ ok = g_mount_spec_match_with_path (parent_daemon->mount_spec,
+ descendant_daemon->mount_spec,
+ full_path);
+
+ g_free (full_path);
+ return ok;
+ }
}
static char *
@@ -342,16 +361,50 @@ g_daemon_file_get_relative_path (GFile *parent,
{
GDaemonFile *parent_daemon = G_DAEMON_FILE (parent);
GDaemonFile *descendant_daemon = G_DAEMON_FILE (descendant);
- const char *remainder;
- if (descendant_daemon->mount_spec != parent_daemon->mount_spec)
- return NULL;
-
- remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
-
- if (remainder != NULL && *remainder == '/')
- return g_strdup (remainder + 1);
- return NULL;
+ if (descendant_daemon->mount_spec == parent_daemon->mount_spec)
+ {
+ const char *remainder;
+
+ remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
+
+ if (remainder != NULL && *remainder == '/')
+ return g_strdup (remainder + 1);
+ else
+ return NULL;
+ }
+ else
+ {
+ char *full_path_descendant;
+ char *full_path_parent;
+ char *ret;
+ const char *remainder;
+ gboolean ok;
+
+ full_path_descendant = g_build_path ("/", descendant_daemon->mount_spec->mount_prefix,
+ descendant_daemon->path, NULL);
+
+ if (!g_mount_spec_match_with_path (parent_daemon->mount_spec,
+ descendant_daemon->mount_spec,
+ full_path_descendant))
+ {
+ g_free (full_path_descendant);
+ return NULL;
+ }
+
+ full_path_parent = g_build_path ("/", parent_daemon->mount_spec->mount_prefix,
+ parent_daemon->path, NULL);
+
+ remainder = match_prefix (full_path_descendant, full_path_parent);
+ if (remainder == NULL || *remainder != '/')
+ ret = g_strdup (remainder + 1);
+ else
+ ret = NULL;
+
+ g_free (full_path_parent);
+ g_free (full_path_descendant);
+ return ret;
+ }
}
static GFile *