Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1758)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2008-04-29  David Zeuthen  <davidz@redhat.com>
+
+	* client/gdaemonvfs.c: (g_daemon_vfs_get_file_for_path):
+	* client/gvfsfusedaemon.c: (vfs_listxattr), (vfs_getxattr),
+	(vfs_removexattr), (vfs_setxattr): Map FUSE POSIX paths to
+	proper gio uri's (#530654)
+
 2008-04-22  Benjamin Otte  <otte@gnome.org>
 
 	* */*.[ch]: get rid of modelines
Index: client/gvfsfusedaemon.c
===================================================================
--- client/gvfsfusedaemon.c	(revision 1758)
+++ client/gvfsfusedaemon.c	(working copy)
@@ -1,3 +1,4 @@
+
 /* GIO - GLib Input, Output and Streaming Library
  * 
  * Copyright (C) 2006-2007 Red Hat, Inc.
@@ -34,6 +35,7 @@
 #include <string.h>
 #include <errno.h>
 #include <signal.h>
+#include <attr/xattr.h>
 
 #include <dbus/dbus.h>
 
@@ -2117,6 +2119,90 @@
   g_object_unref (gvfs);
 }
 
+static int
+vfs_listxattr (const char *path, char *list, size_t size)
+{
+  int res;
+  const char attr[] = "user.gio.uri";
+
+  debug_print ("vfs_listxattr: %s\n", path);
+
+  /* Right now we only support a single attribute, user.gio.uri, which contains
+   * the GIO uri of the file. For example, for the POSIX path
+   *
+   *  /home/davidz/.gvfs/gphoto2 mount on usb%3A001,006/MUSIC/Nephew/09. USADSB.mp3
+   *
+   * user.gio.uri will contain
+   *
+   *  gphoto2://[usb:001,006]/MUSIC/Nephew/09. USADSB.mp3
+   */
+
+  if (list == NULL && size == 0)
+    return sizeof attr + 1;
+
+  if (size < strlen (attr) + 1)
+    return -ERANGE;
+
+  g_utf8_strncpy (list, attr, size);
+  res = sizeof attr + 1;
+  return res;
+}
+
+static int
+vfs_getxattr (const char *path, const char *name, char *value, size_t size)
+{
+  int res;
+  GFile *f;
+  char *uri;
+
+  debug_print ("vfs_getxattr: %s\n", path);
+
+  if (strcmp (name, "user.gio.uri") == 0)
+    {
+      if (value == NULL && size == 0)
+              return PATH_MAX;
+
+      f = file_from_full_path (path);
+      if (f == NULL)
+        {
+          res = -EINVAL;
+        }
+      else
+        {
+          uri = g_file_get_uri (f);
+          if (size < strlen (uri))
+            {
+              res = -ERANGE;
+            }
+          else
+            {
+              g_utf8_strncpy (value, uri, size);
+              res = strlen (value);
+            }
+          g_free (uri);
+          g_object_unref (f);
+        }
+    }
+  else
+    {
+      res = -ENOATTR;
+    }
+
+  return res;
+}
+
+static int
+vfs_removexattr (const char *path, const char *name)
+{
+        return -EPERM;
+}
+
+static int
+vfs_setxattr (const char *path, const char *name, const char *value, size_t size, int flags)
+{
+        return -EPERM;
+}
+
 static struct fuse_operations vfs_oper =
 {
   .init        = vfs_init,
@@ -2150,6 +2236,11 @@
   .utimens     = vfs_utimens,
   .chmod       = vfs_chmod,
 
+  .setxattr    = vfs_setxattr,
+  .getxattr    = vfs_getxattr,
+  .listxattr   = vfs_listxattr,
+  .removexattr = vfs_removexattr,
+
 #if 0
   .chown       = vfs_chown,
   .setxattr    = vfs_setxattr,
Index: client/gdaemonvfs.c
===================================================================
--- client/gdaemonvfs.c	(revision 1758)
+++ client/gdaemonvfs.c	(working copy)
@@ -340,8 +340,22 @@
 g_daemon_vfs_get_file_for_path (GVfs       *vfs,
 				const char *path)
 {
-  /* TODO: detect fuse paths and convert to daemon vfs GFiles */
-  
+  /* detect fuse paths and convert to daemon vfs GFiles */
+  if (strstr (path, ".gvfs") != NULL)
+    {
+      char buf[PATH_MAX];
+      ssize_t len;
+
+      /* the 'user.gio.uri' xattr is provided by the gvfs fuse
+       * daemon, see gvfsfusedaemon.c:vfs_getxattr().
+       */
+      len = getxattr (path, "user.gio.uri", buf, sizeof buf - 1);
+      if (len != -1 && len < sizeof buf - 1)
+        {
+          buf[len] = '\0';
+          return g_vfs_get_file_for_uri (vfs, buf);
+        }
+    }
   return g_vfs_get_file_for_path (G_DAEMON_VFS (vfs)->wrapped_vfs, path);
 }
 
