diff options
author | Giovanni Campagna <gcampagna@src.gnome.org> | 2013-06-02 19:51:02 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2013-06-14 11:17:55 +0200 |
commit | 3b8ff4e37fce0b8edaede5e876a1d16a12d07b08 (patch) | |
tree | d5509df97159b02b7948deb7d6cb3cb6428a3c36 | |
parent | 051a0d80f37c54337bd10f52dddaf7b703e03231 (diff) | |
download | gvfs-3b8ff4e37fce0b8edaede5e876a1d16a12d07b08.tar.gz |
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
(cherry picked from commit bf50158cb58d1d22d6ece145d1eabd790b30798f)
-rw-r--r-- | client/gdaemonfile.c | 85 |
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 * |