[gvfs] GDaemonFile: fix relative path handling to account for mount_prefix



commit bf50158cb58d1d22d6ece145d1eabd790b30798f
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Jun 2 19:51:02 2013 +0200

    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

 client/gdaemonfile.c |   85 ++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 69 insertions(+), 16 deletions(-)
---
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index ebde8c5..25cb3cd 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 *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]