[gvfs/wip/rishi/goa: 8/8] foo



commit 694f58cc4b3f38f0c5fd4bf0f3a013df8be1bb80
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Aug 31 17:28:23 2015 +0200

    foo

 client/gdaemonfile.c       |   30 +-
 daemon/gvfsbackendgoogle.c | 2001 ++++++++++++++++++--------------------------
 2 files changed, 833 insertions(+), 1198 deletions(-)
---
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index de2a033..9866857 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -2337,27 +2337,17 @@ g_daemon_file_get_child_for_display_name (GFile        *file,
 
   if (mount_info && mount_info->prefered_filename_encoding)
     {
-      if (g_strcmp0 (mount_info->prefered_filename_encoding, "google-drive") == 0)
+      basename = g_convert (display_name, -1,
+                            mount_info->prefered_filename_encoding,
+                            "UTF-8",
+                            NULL, NULL,
+                            NULL);
+      if (basename == NULL)
         {
-          if (g_str_has_prefix (display_name, "_"))
-            basename = g_strconcat ("_", display_name, NULL);
-          else
-            basename = g_strdup (display_name);
-        }
-      else
-        {
-          basename = g_convert (display_name, -1,
-                                mount_info->prefered_filename_encoding,
-                                "UTF-8",
-                                NULL, NULL,
-                                NULL);
-          if (basename == NULL)
-            {
-              g_set_error (error, G_IO_ERROR,
-                           G_IO_ERROR_INVALID_FILENAME,
-                           _("Invalid filename %s"), display_name);
-              return NULL;
-            }
+          g_set_error (error, G_IO_ERROR,
+                       G_IO_ERROR_INVALID_FILENAME,
+                       _("Invalid filename %s"), display_name);
+          return NULL;
         }
 
       child = g_file_get_child (file, basename);
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index 0e6c89c..a5bd8cc 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -95,7 +95,8 @@ typedef struct
 
 static GDataEntry *resolve_dir (GVfsBackendGoogle  *self,
                                 const gchar        *filename,
-                                gchar             **out_basename);
+                                gchar             **out_basename,
+                                GError            **error);
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -151,287 +152,28 @@ entries_in_folder_equal (gconstpointer a, gconstpointer b)
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-insert_lookaside (GVfsBackendGoogle *self,
-                  const gchar       *parent_id,
-                  const gchar       *basename,
-                  const gchar       *id)
-{
-  gchar *key;
-
-  key = g_build_filename (parent_id, basename, NULL);
-  g_hash_table_insert (self->lookaside, g_strdup (key), g_strdup (id));
-  g_free (key);
-}
-
-static const gchar *
-lookup_lookaside (GVfsBackendGoogle *self,
-                  const gchar       *parent_id,
-                  const gchar       *basename)
-{
-  const gchar *id;
-  gchar *key;
-
-  key = g_build_filename (parent_id, basename, NULL);
-  id = g_hash_table_lookup (self->lookaside, key);
-  g_free (key);
-  return id;
-}
-
-static gchar *
-resolve_filename (GVfsBackendGoogle *self,
-                  const gchar       *filename)
-{
-  const gchar *id;
-  gchar *basename = NULL;
-  gchar *parent_id = NULL;
-  gchar *parent_path = NULL;
-  gchar *resolved_parent_path = NULL;
-  gchar *ret_val = NULL;
-
-  if (g_strcmp0 (filename, "/") == 0)
-    {
-      ret_val = g_strdup ("/");
-      goto out;
-    }
-
-  parent_path = g_path_get_dirname (filename);
-  resolved_parent_path = resolve_filename (self, parent_path);
-  if (resolved_parent_path == NULL)
-    goto out;
-
-  parent_id = g_path_get_basename (resolved_parent_path);
-  basename = g_path_get_basename (filename);
-  id = lookup_lookaside (self, parent_id, basename);
-  if (id == NULL)
-    goto out;
-
-  ret_val = g_build_filename (resolved_parent_path, id, NULL);
-
- out:
-  g_free (parent_id);
-  g_free (parent_path);
-  g_free (resolved_parent_path);
-  return ret_val;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gchar *
-escape_id (const gchar *id)
-{
-  return g_strconcat ("_", id, NULL);
-}
-
-static gchar *
-escape_filename (const gchar *filename)
-{
-  GString *escaped_filename;
-  gboolean separator_added = FALSE;
-  gchar *basename = NULL;
-  gchar *dirname = NULL;
-  gsize len;
-
-  len = strlen (filename);
-  escaped_filename = g_string_sized_new (len);
-  basename = g_path_get_basename (filename);
-  dirname = g_path_get_dirname (filename);
-
-  while (g_strcmp0 (basename, dirname) != 0)
-    {
-      gchar *escaped_basename;
-      gchar *tmp = NULL;
-
-      escaped_basename = escape_id (basename);
-      g_string_prepend (escaped_filename, escaped_basename);
-      g_string_prepend_c (escaped_filename, G_DIR_SEPARATOR);
-      separator_added = TRUE;
-      g_free (escaped_basename);
-
-      g_free (basename);
-      basename = g_path_get_basename (dirname);
-
-      tmp = dirname;
-      dirname = g_path_get_dirname (dirname);
-      g_free (tmp);
-    }
-
-  if (!separator_added)
-    g_string_prepend_c (escaped_filename, G_DIR_SEPARATOR);
-
-  g_free (basename);
-  g_free (dirname);
-  return g_string_free (escaped_filename, FALSE);
-}
-
-/* Takes a filename as supplied by the application and returns a value
- * that is either:
- * (a) guaranteed to be made up of persistent, server-defined IDs, or
- * (b) can be used to look-up such a persistent filename through the
- *     lookaside cache
- */
-static gchar *
-unescape_filename (GVfsBackendGoogle *self,
-                   const gchar       *filename,
-                   gboolean          *out_is_volatile)
-{
-  GString *unescaped_filename;
-  gboolean is_volatile;
-  gboolean separator_added = FALSE;
-  gchar *basename = NULL;
-  gchar *dirname = NULL;
-  gsize len;
-
-  /* If a path is in the lookaside cache then it is volatile, even if
-   * it looks like /_id10/_id2, and we don't perform the usual
-   * unescaping operation. See the copy job for an explanation.
-   */
-  if (g_hash_table_lookup (self->lookaside, filename) != NULL)
-    {
-      is_volatile = TRUE;
-      unescaped_filename = g_string_new (filename);
-      goto out;
-    }
-  else
-    {
-      is_volatile = FALSE;
-    }
-
-  len = strlen (filename);
-  unescaped_filename = g_string_sized_new (len);
-  basename = g_path_get_basename (filename);
-  dirname = g_path_get_dirname (filename);
-
-  while (g_strcmp0 (basename, dirname) != 0)
-    {
-      const gchar *unescaped_basename;
-      gchar *tmp = NULL;
-
-      if (g_str_has_prefix (basename, "_"))
-        {
-          unescaped_basename = basename + 1;
-          if (g_str_has_prefix (basename, "__"))
-            is_volatile = TRUE;
-        }
-      else
-        {
-          unescaped_basename = basename;
-          is_volatile = TRUE;
-        }
-
-      g_string_prepend (unescaped_filename, unescaped_basename);
-      g_string_prepend_c (unescaped_filename, G_DIR_SEPARATOR);
-      separator_added = TRUE;
-
-      g_free (basename);
-      basename = g_path_get_basename (dirname);
-
-      tmp = dirname;
-      dirname = g_path_get_dirname (dirname);
-      g_free (tmp);
-    }
-
-  if (!separator_added)
-    g_string_prepend_c (unescaped_filename, G_DIR_SEPARATOR);
-
- out:
-  if (out_is_volatile != NULL)
-    *out_is_volatile = is_volatile;
-  g_free (basename);
-  g_free (dirname);
-  return g_string_free (unescaped_filename, FALSE);
-}
-
-/* Specifically meant for differentiating between /_id10/_id2 and
- * /_id10/foo when creating a file or directory, and mapping the
- * dirname to the real dirname if it was found to be volatile. The
- * filename will always be volatile. See the copy job for an
- * explanation.
- *
- * Knowing the difference is important because if it is /_id10/_id2
- * then the title or display-name of the new file has to be taken from
- * the original entry corresponding to _id2. Otherwise it should be
- * foo.
- */
-static gchar *
-unescape_basename_and_map_dirname (GVfsBackendGoogle *self,
-                                   const gchar       *filename,
-                                   gboolean          *out_is_display_name)
-{
-  gboolean is_dirname_volatile;
-  gboolean is_display_name = FALSE;
-  const gchar *unescaped_basename;
-  gchar *basename = NULL;
-  gchar *dirname = NULL;
-  gchar *ret_val = NULL;
-  gchar *unescaped_dirname = NULL;
-
-  basename = g_path_get_basename (filename);
-  if (g_str_has_prefix (basename, "_"))
-    {
-      unescaped_basename = basename + 1;
-      if (g_str_has_prefix (basename, "__"))
-        is_display_name = TRUE;
-    }
-  else
-    {
-      unescaped_basename = basename;
-      is_display_name = TRUE;
-    }
-
-  dirname = g_path_get_dirname (filename);
-  unescaped_dirname = unescape_filename (self, dirname, &is_dirname_volatile);
-  if (is_dirname_volatile)
-    {
-      const gchar *real_dirname;
-
-      real_dirname = g_hash_table_lookup (self->lookaside, unescaped_dirname);
-      if (real_dirname == NULL)
-        goto out;
-
-      g_free (unescaped_dirname);
-      unescaped_dirname = g_strdup (real_dirname);
-    }
-
-  ret_val = g_build_filename (unescaped_dirname, unescaped_basename, NULL);
-
-  if (out_is_display_name != NULL)
-    *out_is_display_name = is_display_name;
-
- out:
-  g_free (unescaped_dirname);
-  g_free (dirname);
-  g_free (basename);
-  return ret_val;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
 emit_event_internal (GVfsMonitor       *monitor,
                      const gchar       *filename,
                      GFileMonitorEvent  event)
 {
   const gchar *monitored_path;
-  gchar *escaped_filename;
-  gchar *parent;
+  gchar *parent_path;
 
   monitored_path = g_object_get_data (G_OBJECT (monitor), "g-vfs-backend-google-path");
-  escaped_filename = escape_filename (filename);
-  parent = g_path_get_dirname (filename);
+  parent_path = g_path_get_dirname (filename);
 
-  if (g_strcmp0 (parent, monitored_path) == 0)
+  if (g_strcmp0 (parent_path, monitored_path) == 0)
     {
-      g_debug ("  emit event %d on parent directory for %s\n", event, escaped_filename);
-      g_vfs_monitor_emit_event (monitor, event, escaped_filename, NULL);
+      g_debug ("  emit event %d on parent directory for %s\n", event, filename);
+      g_vfs_monitor_emit_event (monitor, event, filename, NULL);
     }
   else if (g_strcmp0 (filename, monitored_path) == 0)
     {
-      g_debug ("  emit event %d on file %s\n", event, escaped_filename);
-      g_vfs_monitor_emit_event (monitor, event, escaped_filename, NULL);
+      g_debug ("  emit event %d on file %s\n", event, filename);
+      g_vfs_monitor_emit_event (monitor, event, filename, NULL);
     }
 
-  g_free (escaped_filename);
-  g_free (parent);
+  g_free (parent_path);
 }
 
 static void
@@ -570,13 +312,8 @@ build_file_info (GVfsBackendGoogle      *self,
 
   if (is_symlink)
     {
-      gchar *escaped_filename = NULL;
-
       file_type = G_FILE_TYPE_SYMBOLIC_LINK;
-
-      escaped_filename = escape_filename (filename);
-      g_file_info_set_symlink_target (info, escaped_filename);
-      g_free (escaped_filename);
+      g_file_info_set_symlink_target (info, filename);
     }
 
   if (content_type != NULL)
@@ -626,14 +363,9 @@ build_file_info (GVfsBackendGoogle      *self,
   g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE, id);
 
   if (is_symlink)
-    {
-      name = symlink_name;
-    }
+    name = symlink_name;
   else
-    {
-      escaped_name = escape_id (id);
-      name = escaped_name;
-    }
+    name = id;
 
   g_file_info_set_name (info, name);
 
@@ -747,12 +479,18 @@ get_parent_id (GDataEntry *entry)
 static gchar *
 get_entry_path (GVfsBackendGoogle *self, GDataEntry *entry)
 {
-  GString *path;
+  GString *path = NULL;
   const gchar *base_id;
   const gchar *root_id;
   gchar *id = NULL;
   gchar *ret_val = NULL;
 
+  if (entry == self->root)
+    {
+      ret_val = g_strdup ("/");
+      goto out;
+    }
+
   base_id = gdata_entry_get_id (entry);
   path = g_string_new (base_id);
   g_string_prepend_c (path, '/');
@@ -783,12 +521,12 @@ get_entry_path (GVfsBackendGoogle *self, GDataEntry *entry)
       id = get_parent_id (parent_entry);
     }
 
-
   ret_val = g_strdup (path->str);
 
  out:
   g_free (id);
-  g_string_free (path, TRUE);
+  if (path != NULL)
+    g_string_free (path, TRUE);
   return ret_val;
 }
 
@@ -977,6 +715,7 @@ resolve (GVfsBackendGoogle  *self,
 {
   GDataEntry *parent;
   GDataEntry *ret_val = NULL;
+  GError *local_error;
   gchar *basename = NULL;
 
   if (g_strcmp0 (filename, "/") == 0)
@@ -985,10 +724,11 @@ resolve (GVfsBackendGoogle  *self,
       goto out;
     }
 
-  parent = resolve_dir (self, filename, &basename);
-  if (parent == NULL)
+  local_error = NULL;
+  parent = resolve_dir (self, filename, &basename, &local_error);
+  if (local_error != NULL)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, _("The file is not a directory"));
+      g_propagate_error (error, local_error);
       goto out;
     }
 
@@ -1007,32 +747,46 @@ resolve (GVfsBackendGoogle  *self,
 static GDataEntry *
 resolve_dir (GVfsBackendGoogle  *self,
              const gchar        *filename,
-             gchar             **out_basename)
+             gchar             **out_basename,
+             GError            **error)
 {
   GDataEntry *parent;
+  GDataEntry *ret_val = NULL;
+  GError *local_error;
   gboolean is_folder;
   gchar *basename = NULL;
   gchar *parent_path = NULL;
 
   basename = g_path_get_basename (filename);
+  parent_path = g_path_get_dirname (filename);
+
+  local_error = NULL;
+  parent = resolve (self, parent_path, &local_error);
+  if (local_error != NULL)
+    {
+      g_propagate_error (error, local_error);
+      goto out;
+    }
+
+  is_folder_or_root (self, parent_path, parent, &is_folder, NULL);
+  if (!is_folder)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, _("The file is not a directory"));
+      goto out;
+    }
+
   if (out_basename != NULL)
     {
       *out_basename = basename;
       basename = NULL;
     }
 
-  parent_path = g_path_get_dirname (filename);
-  parent = resolve (self, parent_path, NULL);
-  if (parent != NULL)
-    {
-      is_folder_or_root (self, parent_path, parent, &is_folder, NULL);
-      if (!is_folder)
-        parent = NULL;
-    }
+  ret_val = parent;
 
+ out:
   g_free (basename);
   g_free (parent_path);
-  return parent;
+  return ret_val;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -1141,165 +895,165 @@ g_vfs_backend_google_copy (GVfsBackend           *_self,
                            GFileProgressCallback  progress_callback,
                            gpointer               progress_callback_data)
 {
-  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
-  GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
-  GDataDocumentsEntry *new_entry = NULL;
-  GDataDocumentsFolder *destination_parent;
-  GDataEntry *source_entry;
-  GError *error;
-  gboolean is_folder;
-  gboolean destination_is_root;
-  gboolean is_volatile_source;
-  const gchar *real_destination_parent_path;
-  const gchar *real_parent_path;
-  const gchar *real_source;
-  gchar *destination_parent_id = NULL;
-  gchar *destination_parent_path = NULL;
-  gchar *path = NULL;
-  gchar *source_id = NULL;
-  gchar *unescaped_destination = NULL;
-  gchar *unescaped_source = NULL;
-
-  /* The destination is always volatile. It will look like /_id1/_id2
-   * -> /_id10/_id2, whereas in reality it will be /_id1/_id2 ->
-   * /_id10/_id20. This will confuse our escaping logic when
-   * /_id10/_id2 is passed to a any subsequent job, and make it think
-   * that it is a non-volatile path. Hence, we add /_id10/_id2 to the
-   * lookaside cache at the end of the copy so that subsequent jobs
-   * can recognize it as a volatile path.
-   */
-
-  g_rec_mutex_lock (&self->mutex);
-  unescaped_destination = unescape_basename_and_map_dirname (self, destination, NULL);
-  unescaped_source = unescape_filename (self, source, &is_volatile_source);
-  g_debug ("+ copy: %s (%s, %d) -> %s (%s, 1)\n",
-           source,
-           unescaped_source,
-           is_volatile_source,
-           destination,
-           unescaped_destination);
-  source = unescaped_source;
-
-  if (unescaped_destination == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
-
-  if (flags & G_FILE_COPY_BACKUP)
-    {
-      /* Return G_IO_ERROR_NOT_SUPPORTED instead of
-       * G_IO_ERROR_CANT_CREATE_BACKUP to proceed with the GIO
-       * fallback copy.
-       */
-      g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Operation not 
supported");
-      goto out;
-    }
-
-  if (is_volatile_source)
-    {
-      real_source = g_hash_table_lookup (self->lookaside, source);
-      if (real_source == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      source = real_source;
-    }
-
-  source_id = g_path_get_basename (source);
-  source_entry = g_hash_table_lookup (self->entries, source_id);
-
-  destination_parent_path = g_path_get_dirname (unescaped_destination);
-  real_destination_parent_path = g_hash_table_lookup (self->lookaside, destination_parent_path);
-  if (real_destination_parent_path != NULL)
-    {
-      g_free (destination_parent_path);
-      destination_parent_path = g_strdup (real_destination_parent_path);
-    }
-
-  is_folder_or_root (self, destination_parent_path, NULL, NULL, &destination_is_root);
-  if (destination_is_root)
-    {
-      destination_parent = GDATA_DOCUMENTS_FOLDER (self->root);
-    }
-  else
-    {
-      destination_parent_id = g_path_get_basename (destination_parent_path);
-      destination_parent = g_hash_table_lookup (self->entries, destination_parent_id);
-    }
-
-  if (source_entry == NULL || destination_parent == NULL)
-    {
-      error = NULL;
-      rebuild_entries (self, cancellable, &error);
-      if (error != NULL)
-        {
-          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-          g_error_free (error);
-          goto out;
-        }
-    }
-
-  source_entry = g_hash_table_lookup (self->entries, source_id);
-
-  if (!destination_is_root && destination_parent == NULL)
-    destination_parent = g_hash_table_lookup (self->entries, destination_parent_id);
-
-  if (source_entry == NULL || destination_parent == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
-
-  is_folder_or_root (self, source, source_entry, &is_folder, NULL);
-  if (is_folder)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_WOULD_RECURSE,
-                        _("Can't recursively copy directory"));
-      goto out;
-    }
-
-  error = NULL;
-  new_entry = gdata_documents_service_add_entry_to_folder (self->service,
-                                                           GDATA_DOCUMENTS_ENTRY (source_entry),
-                                                           destination_parent,
-                                                           cancellable,
-                                                           &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  insert_entry (self, GDATA_ENTRY (new_entry));
-
-  path = get_entry_path (self, GDATA_ENTRY (new_entry));
-  if (path != NULL)
-    {
-      g_debug ("  insert lookaside: %s -> %s\n", destination, path);
-      g_hash_table_insert (self->lookaside, g_strdup (destination), g_strdup (path));
-      g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path);
-    }
-
-  self->entries_stale = TRUE;
-
-  g_vfs_job_succeeded (G_VFS_JOB (job));
-
- out:
-  g_clear_object (&new_entry);
-  g_free (path);
-  g_free (destination_parent_id);
-  g_free (destination_parent_path);
-  g_free (source_id);
-  g_free (unescaped_source);
-  g_free (unescaped_destination);
-  g_debug ("- copy\n");
-  g_rec_mutex_unlock (&self->mutex);
+ /*  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); */
+ /*  GCancellable *cancellable = G_VFS_JOB (job)->cancellable; */
+ /*  GDataDocumentsEntry *new_entry = NULL; */
+ /*  GDataDocumentsFolder *destination_parent; */
+ /*  GDataEntry *source_entry; */
+ /*  GError *error; */
+ /*  gboolean is_folder; */
+ /*  gboolean destination_is_root; */
+ /*  gboolean is_volatile_source; */
+ /*  const gchar *real_destination_parent_path; */
+ /*  const gchar *real_parent_path; */
+ /*  const gchar *real_source; */
+ /*  gchar *destination_parent_id = NULL; */
+ /*  gchar *destination_parent_path = NULL; */
+ /*  gchar *path = NULL; */
+ /*  gchar *source_id = NULL; */
+ /*  gchar *unescaped_destination = NULL; */
+ /*  gchar *unescaped_source = NULL; */
+
+ /*  /\* The destination is always volatile. It will look like /_id1/_id2 */
+ /*   * -> /_id10/_id2, whereas in reality it will be /_id1/_id2 -> */
+ /*   * /_id10/_id20. This will confuse our escaping logic when */
+ /*   * /_id10/_id2 is passed to a any subsequent job, and make it think */
+ /*   * that it is a non-volatile path. Hence, we add /_id10/_id2 to the */
+ /*   * lookaside cache at the end of the copy so that subsequent jobs */
+ /*   * can recognize it as a volatile path. */
+ /*   *\/ */
+
+ /*  g_rec_mutex_lock (&self->mutex); */
+ /*  unescaped_destination = unescape_basename_and_map_dirname (self, destination, NULL); */
+ /*  unescaped_source = unescape_filename (self, source, &is_volatile_source); */
+ /*  g_debug ("+ copy: %s (%s, %d) -> %s (%s, 1)\n", */
+ /*           source, */
+ /*           unescaped_source, */
+ /*           is_volatile_source, */
+ /*           destination, */
+ /*           unescaped_destination); */
+ /*  source = unescaped_source; */
+
+ /*  if (unescaped_destination == NULL) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (flags & G_FILE_COPY_BACKUP) */
+ /*    { */
+ /*      /\* Return G_IO_ERROR_NOT_SUPPORTED instead of */
+ /*       * G_IO_ERROR_CANT_CREATE_BACKUP to proceed with the GIO */
+ /*       * fallback copy. */
+ /*       *\/ */
+ /*      g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Operation not 
supported"); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (is_volatile_source) */
+ /*    { */
+ /*      real_source = g_hash_table_lookup (self->lookaside, source); */
+ /*      if (real_source == NULL) */
+ /*        { */
+ /*          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*          goto out; */
+ /*        } */
+
+ /*      source = real_source; */
+ /*    } */
+
+ /*  source_id = g_path_get_basename (source); */
+ /*  source_entry = g_hash_table_lookup (self->entries, source_id); */
+
+ /*  destination_parent_path = g_path_get_dirname (unescaped_destination); */
+ /*  real_destination_parent_path = g_hash_table_lookup (self->lookaside, destination_parent_path); */
+ /*  if (real_destination_parent_path != NULL) */
+ /*    { */
+ /*      g_free (destination_parent_path); */
+ /*      destination_parent_path = g_strdup (real_destination_parent_path); */
+ /*    } */
+
+ /*  is_folder_or_root (self, destination_parent_path, NULL, NULL, &destination_is_root); */
+ /*  if (destination_is_root) */
+ /*    { */
+ /*      destination_parent = GDATA_DOCUMENTS_FOLDER (self->root); */
+ /*    } */
+ /*  else */
+ /*    { */
+ /*      destination_parent_id = g_path_get_basename (destination_parent_path); */
+ /*      destination_parent = g_hash_table_lookup (self->entries, destination_parent_id); */
+ /*    } */
+
+ /*  if (source_entry == NULL || destination_parent == NULL) */
+ /*    { */
+ /*      error = NULL; */
+ /*      rebuild_entries (self, cancellable, &error); */
+ /*      if (error != NULL) */
+ /*        { */
+ /*          g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*          g_error_free (error); */
+ /*          goto out; */
+ /*        } */
+ /*    } */
+
+ /*  source_entry = g_hash_table_lookup (self->entries, source_id); */
+
+ /*  if (!destination_is_root && destination_parent == NULL) */
+ /*    destination_parent = g_hash_table_lookup (self->entries, destination_parent_id); */
+
+ /*  if (source_entry == NULL || destination_parent == NULL) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  is_folder_or_root (self, source, source_entry, &is_folder, NULL); */
+ /*  if (is_folder) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                        G_IO_ERROR, */
+ /*                        G_IO_ERROR_WOULD_RECURSE, */
+ /*                        _("Can't recursively copy directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  error = NULL; */
+ /*  new_entry = gdata_documents_service_add_entry_to_folder (self->service, */
+ /*                                                           GDATA_DOCUMENTS_ENTRY (source_entry), */
+ /*                                                           destination_parent, */
+ /*                                                           cancellable, */
+ /*                                                           &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  insert_entry (self, GDATA_ENTRY (new_entry)); */
+
+ /*  path = get_entry_path (self, GDATA_ENTRY (new_entry)); */
+ /*  if (path != NULL) */
+ /*    { */
+ /*      g_debug ("  insert lookaside: %s -> %s\n", destination, path); */
+ /*      g_hash_table_insert (self->lookaside, g_strdup (destination), g_strdup (path)); */
+ /*      g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path); */
+ /*    } */
+
+ /*  self->entries_stale = TRUE; */
+
+ /*  g_vfs_job_succeeded (G_VFS_JOB (job)); */
+
+ /* out: */
+ /*  g_clear_object (&new_entry); */
+ /*  g_free (path); */
+ /*  g_free (destination_parent_id); */
+ /*  g_free (destination_parent_path); */
+ /*  g_free (source_id); */
+ /*  g_free (unescaped_source); */
+ /*  g_free (unescaped_destination); */
+ /*  g_debug ("- copy\n"); */
+ /*  g_rec_mutex_unlock (&self->mutex); */
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -1319,12 +1073,10 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
   gboolean is_root;
   gboolean is_volatile;
   gchar *id = NULL;
-  gchar *unescaped_filename = NULL;
+  gchar *entry_path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ create_dir_monitor: %s (%s, %d)\n", filename, unescaped_filename, is_volatile);
-  filename = unescaped_filename;
+  g_debug ("+ create_dir_monitor: %s\n", filename);
 
   if (flags & G_FILE_MONITOR_SEND_MOVED)
     {
@@ -1332,25 +1084,8 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
       goto out;
     }
 
-  if (is_volatile)
-    {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, filename);
-      if (real_filename == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      filename = real_filename;
-    }
-
-  id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, id);
-  is_folder_or_root (self, filename, entry, NULL, &is_root);
-
-  if (entry == NULL && !is_root)
+  entry = resolve (self, filename, NULL);
+  if (entry == NULL)
     {
       error = NULL;
       rebuild_entries (self, cancellable, &error);
@@ -1361,15 +1096,20 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, id);
-      if (entry == NULL)
+      error = NULL;
+      entry = resolve (self, filename, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
     }
 
-  is_folder_or_root (self, filename, entry, &is_folder, NULL);
+  entry_path = get_entry_path (self, entry);
+  g_debug ("  entry-path: %s\n", entry_path);
+
+  is_folder_or_root (self, entry_path, entry, &is_folder, NULL);
   if (!is_folder)
     {
       g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, _("The file is not a 
directory"));
@@ -1377,7 +1117,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
     }
 
   monitor = g_vfs_monitor_new (_self);
-  g_object_set_data_full (G_OBJECT (monitor), "g-vfs-backend-google-path", g_strdup (filename), g_free);
+  g_object_set_data_full (G_OBJECT (monitor), "g-vfs-backend-google-path", g_strdup (entry_path), g_free);
   g_hash_table_add (self->monitors, monitor);
   g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_hash_table_remove, self->monitors);
   g_vfs_job_create_monitor_set_monitor (job, monitor);
@@ -1385,8 +1125,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
 
  out:
   g_clear_object (&monitor);
-  g_free (id);
-  g_free (unescaped_filename);
+  g_free (entry_path);
   g_debug ("- create_dir_monitor\n");
   g_rec_mutex_unlock (&self->mutex);
   return TRUE;
@@ -1404,44 +1143,12 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
   GDataAuthorizationDomain *auth_domain;
   GDataEntry *entry;
   GError *error;
-  gboolean is_root;
-  gboolean is_volatile;
-  gchar *path = NULL;
-  gchar *id = NULL;
-  gchar *unescaped_filename = NULL;
+  gchar *entry_path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ delete: %s (%s, %d)\n", filename, unescaped_filename, is_volatile);
-  filename = unescaped_filename;
-
-  if (is_volatile)
-    {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, filename);
-      if (real_filename == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      filename = real_filename;
-    }
-
-  is_folder_or_root (self, filename, NULL, NULL, &is_root);
-  if (is_root)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_NOT_SUPPORTED,
-                        _("Can not delete the root directory"));
-      goto out;
-    }
-
-  id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, id);
+  g_debug ("+ delete: %s\n", filename);
 
+  entry = resolve (self, filename, NULL);
   if (entry == NULL)
     {
       error = NULL;
@@ -1453,16 +1160,29 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, id);
-      if (entry == NULL)
+      error = NULL;
+      entry = resolve (self, filename, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
     }
 
+  entry_path = get_entry_path (self, entry);
+  g_debug ("  entry-path: %s\n", entry_path);
+
+  if (entry == self->root)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR,
+                        G_IO_ERROR_NOT_SUPPORTED,
+                        _("Can not delete the root directory"));
+      goto out;
+    }
+
   auth_domain = gdata_documents_service_get_primary_authorization_domain ();
-  path = get_entry_path (self, entry);
 
   error = NULL;
   gdata_service_delete_entry (GDATA_SERVICE (self->service), auth_domain, entry, cancellable, &error);
@@ -1474,15 +1194,13 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
     }
 
   remove_entry (self, entry);
-  if (path != NULL)
-    g_hash_table_foreach (self->monitors, emit_delete_event, (gpointer) path);
+  if (entry_path != NULL)
+    g_hash_table_foreach (self->monitors, emit_delete_event, (gpointer) entry_path);
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
-  g_free (path);
-  g_free (id);
-  g_free (unescaped_filename);
+  g_free (entry_path);
   g_debug ("- delete\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -1512,27 +1230,12 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
   GDataEntry *entry;
   GError *error;
   GHashTableIter iter;
+  gboolean is_folder;
   gboolean is_volatile;
-  gchar *unescaped_filename = NULL;
+  gchar *entry_path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ enumerate: %s (%s, %d)\n", filename, unescaped_filename, is_volatile);
-  filename = unescaped_filename;
-
-  if (is_volatile)
-    {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, filename);
-      if (real_filename == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      filename = real_filename;
-    }
+  g_debug ("+ enumerate: %s\n", filename);
 
   if (self->entries_stale_timeout == 0)
     {
@@ -1555,6 +1258,25 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
         }
     }
 
+  error = NULL;
+  entry = resolve (self, filename, &error);
+  if (error != NULL)
+    {
+      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+      g_error_free (error);
+      goto out;
+    }
+
+  entry_path = get_entry_path (self, entry);
+  g_debug ("  entry-path: %s\n", entry_path);
+
+  is_folder_or_root (self, entry_path, entry, &is_folder, NULL);
+  if (!is_folder)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,_("The file is not a 
directory"));
+      goto out;
+    }
+
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
   g_hash_table_iter_init (&iter, self->entries);
@@ -1568,7 +1290,7 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
           gchar *parent_path;
 
           parent_path = g_path_get_dirname (path);
-          if (g_strcmp0 (filename, parent_path) == 0)
+          if (g_strcmp0 (entry_path, parent_path) == 0)
             {
               GFileInfo *info;
 
@@ -1587,7 +1309,7 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
   g_vfs_job_enumerate_done (job);
 
  out:
-  g_free (unescaped_filename);
+  g_free (entry_path);
   g_debug ("- enumerate\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -1603,32 +1325,20 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
   GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
   GDataDocumentsEntry *new_entry = NULL;
   GDataDocumentsFolder *folder = NULL;
-  GDataDocumentsFolder *parent;
+  GDataEntry *existing_entry;
+  GDataEntry *parent;
   GDataEntry *source_entry = NULL;
   GError *error;
-  gboolean is_display_name;
-  gboolean is_root;
-  gboolean needs_rebuild = FALSE;
-  const gchar *real_parent_path;
-  gchar *parent_id = NULL;
+  const gchar *summary;
+  const gchar *title;
+  gchar *entry_path = NULL;
+  gchar *basename = NULL;
   gchar *parent_path = NULL;
-  gchar *path = NULL;
-  gchar *source_id = NULL;
-  gchar *title = NULL;
-  gchar *unescaped_filename = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_basename_and_map_dirname (self, filename, &is_display_name);
-  g_debug ("+ make_directory: %s (%s, %d)\n", filename, unescaped_filename, is_display_name);
-
-  if (unescaped_filename == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
+  g_debug ("+ make_directory: %s\n", filename);
 
-  is_folder_or_root (self, unescaped_filename, NULL, NULL, &is_root);
-  if (is_root)
+  if (g_strcmp0 (filename, "/") == 0)
     {
       g_vfs_job_failed (G_VFS_JOB (job),
                         G_IO_ERROR,
@@ -1637,34 +1347,21 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
       goto out;
     }
 
-  parent_path = g_path_get_dirname (unescaped_filename);
-  is_folder_or_root (self, parent_path, NULL, NULL, &is_root);
-  if (is_root)
-    {
-      parent = GDATA_DOCUMENTS_FOLDER (self->root);
-    }
-  else
-    {
-      parent_id = g_path_get_basename (parent_path);
-      parent = g_hash_table_lookup (self->entries, parent_id);
-      if (parent == NULL)
-        needs_rebuild = TRUE;
-    }
-
-  if (is_display_name)
-    {
-      title = g_path_get_basename (unescaped_filename);
-    }
-  else
+  error = NULL;
+  parent = resolve_dir (self, filename, &basename, &error);
+  if (error != NULL)
     {
-      source_id = g_path_get_basename (unescaped_filename);
-      source_entry = g_hash_table_lookup (self->entries, source_id);
-      if (source_entry == NULL)
-        needs_rebuild = TRUE;
-    }
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY))
+        {
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
+          goto out;
+        }
+      else
+        {
+          g_error_free (error);
+        }
 
-  if (needs_rebuild)
-    {
       error = NULL;
       rebuild_entries (self, cancellable, &error);
       if (error != NULL)
@@ -1673,37 +1370,47 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
           g_error_free (error);
           goto out;
         }
-    }
 
-  if (!is_root && parent == NULL)
-    {
-      parent = g_hash_table_lookup (self->entries, parent_id);
-      if (parent == NULL)
+      error = NULL;
+      parent = resolve_dir (self, filename, &basename, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
     }
 
-  if (!is_display_name)
+  parent_path = get_entry_path (self, parent);
+  g_debug ("  parent path: %s\n", parent_path);
+
+  existing_entry = resolve_child (self, parent, basename);
+  if (existing_entry != NULL)
     {
-      source_entry = g_hash_table_lookup (self->entries, source_id);
-      if (source_entry == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
+      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already exists"));
+      goto out;
+    }
 
-      title = g_strdup (gdata_entry_get_title (source_entry));
+  source_entry = g_hash_table_lookup (self->entries, basename);
+  if (source_entry == NULL)
+    {
+      title = basename;
+      summary = NULL;
+    }
+  else
+    {
+      title = gdata_entry_get_title (source_entry);
+      summary = gdata_entry_get_summary (source_entry);
     }
 
   folder = gdata_documents_folder_new (NULL);
   gdata_entry_set_title (GDATA_ENTRY (folder), title);
+  gdata_entry_set_summary (GDATA_ENTRY (folder), summary);
 
   error = NULL;
   new_entry = gdata_documents_service_add_entry_to_folder (self->service,
                                                            GDATA_DOCUMENTS_ENTRY (folder),
-                                                           parent,
+                                                           GDATA_DOCUMENTS_FOLDER (parent),
                                                            cancellable,
                                                            &error);
   if (error != NULL)
@@ -1715,27 +1422,20 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
 
   insert_entry (self, GDATA_ENTRY (new_entry));
 
-  path = get_entry_path (self, GDATA_ENTRY (new_entry));
-  if (path != NULL)
-    {
-      g_debug ("  insert lookaside: %s -> %s\n", filename, path);
-      g_hash_table_insert (self->lookaside, g_strdup (filename), g_strdup (path));
-      g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path);
-    }
+  entry_path = get_entry_path (self, GDATA_ENTRY (new_entry));
+  g_debug ("  new entry path: %s\n", entry_path);
 
-  self->entries_stale = TRUE;
+  if (entry_path != NULL)
+    g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) entry_path);
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
   g_clear_object (&new_entry);
   g_clear_object (&folder);
-  g_free (source_id);
-  g_free (parent_id);
+  g_free (basename);
+  g_free (entry_path);
   g_free (parent_path);
-  g_free (path);
-  g_free (title);
-  g_free (unescaped_filename);
   g_debug ("- make_directory\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -1880,287 +1580,287 @@ g_vfs_backend_google_push (GVfsBackend           *_self,
                            GFileProgressCallback  progress_callback,
                            gpointer               progress_callback_data)
 {
-  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
-  GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
-  GDataDocumentsDocument *document = NULL;
-  GDataDocumentsDocument *new_document = NULL;
-  GDataDocumentsFolder *parent = NULL;
-  GDataEntry *entry;
-  GDataUploadStream *ostream = NULL;
-  GError *error;
-  GFile *local_file = NULL;
-  GFileInputStream *istream = NULL;
-  GFileInfo *info = NULL;
-  gboolean is_display_name;
-  gboolean is_root;
-  gboolean needs_overwrite = FALSE;
-  const gchar *content_type;
-  const gchar *title;
-  gchar *basename = NULL;
-  gchar *parent_id = NULL;
-  gchar *parent_path = NULL;
-  gchar *path = NULL;
-  gchar *unescaped_destination = NULL;
-
-  /* The destination is always volatile. It will look like /foo/bar
-   * -> /_id1/bar, whereas in reality it will be /foo/bar ->
-   * /_id1/_id2.
-   */
-
-  g_rec_mutex_lock (&self->mutex);
-  unescaped_destination = unescape_basename_and_map_dirname (self, destination, &is_display_name);
-  g_debug ("+ push: %s -> %s (%s, %d)\n", local_path, destination, unescaped_destination, is_display_name);
-
-  if (unescaped_destination == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
-
-  if (flags & G_FILE_COPY_BACKUP)
-    {
-      /* Return G_IO_ERROR_NOT_SUPPORTED instead of
-       * G_IO_ERROR_CANT_CREATE_BACKUP to proceed with the GIO
-       * fallback copy.
-       */
-      g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Operation not 
supported");
-      goto out;
-    }
-
-  local_file = g_file_new_for_path (local_path);
-
-  error = NULL;
-  info = g_file_query_info (local_file,
-                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
-                            G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
-                            G_FILE_ATTRIBUTE_STANDARD_TYPE,
-                            G_FILE_QUERY_INFO_NONE,
-                            cancellable,
-                            &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_WOULD_RECURSE,
-                        _("Can't recursively copy directory"));
-      goto out;
-    }
-
-  basename = g_path_get_basename (unescaped_destination);
-
-  if (!is_display_name)
-    {
-      const gchar *destination_id = basename;
-
-      /* This is almost a pathological case. In reality, clients like
-       * file managers won't use an ID as the destination
-       * basename. They will use an escaped version of the source
-       * basename. That means this code path is unlikely to be hit
-       * when recursively pushing a folder.
-       *
-       * Therefore, in order to keep things simple, we unconditionally
-       * refresh the cache.
-       */
-      error = NULL;
-      rebuild_entries (self, cancellable, &error);
-      if (error != NULL)
-        {
-          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-          goto out;
-        }
-
-      entry = g_hash_table_lookup (self->entries, destination_id);
-      if (entry != NULL)
-        {
-          if (flags & G_FILE_COPY_OVERWRITE)
-            {
-              if (GDATA_IS_DOCUMENTS_FOLDER (entry))
-                {
-                  /* At this point, the source can never be a
-                   * directory. So we can ignore the issue of copying
-                   * a directory over another
-                   * (ie. G_IO_ERROR_WOULD_MERGE).
-                   */
-                  g_vfs_job_failed (G_VFS_JOB (job),
-                                    G_IO_ERROR,
-                                    G_IO_ERROR_IS_DIRECTORY,
-                                    _("Can't copy file over directory"));
-                  goto out;
-                }
-
-              needs_overwrite = TRUE;
-            }
-          else
-            {
-              g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already 
exists"));
-              goto out;
-            }
-        }
-      else
-        {
-          /* The basename looks like an ID but that ID doesn't
-           * exist. This is fishy. Probably caused by not using
-           * g_file_get_child_for_display_name to create the
-           * destination path.
-           */
-          g_vfs_job_failed (G_VFS_JOB (job),
-                            G_IO_ERROR,
-                            G_IO_ERROR_INVALID_FILENAME,
-                            _("Invalid filename %s"),
-                            destination);
-          goto out;
-        }
-    }
-
-  g_debug ("  will overwrite: %d\n", needs_overwrite);
-
-  error = NULL;
-  istream = g_file_read (local_file, cancellable, &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  content_type = g_file_info_get_content_type (info);
-
-  if (needs_overwrite)
-    {
-      document = g_object_ref (entry);
-      title = gdata_entry_get_title (entry);
-
-      error = NULL;
-      ostream = gdata_documents_service_update_document (self->service,
-                                                         document,
-                                                         title,
-                                                         content_type,
-                                                         cancellable,
-                                                         &error);
-    }
-  else
-    {
-      parent_path = g_path_get_dirname (unescaped_destination);
-
-      is_folder_or_root (self, parent_path, NULL, NULL, &is_root);
-      if (!is_root)
-        {
-          parent_id = g_path_get_basename (parent_path);
-          parent = g_hash_table_lookup (self->entries, parent_id);
-
-          if (parent == NULL)
-            {
-              error = NULL;
-              rebuild_entries (self, cancellable, &error);
-              if (error != NULL)
-                {
-                  g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-                  g_error_free (error);
-                  goto out;
-                }
-
-              parent = g_hash_table_lookup (self->entries, parent_id);
-              if (parent == NULL)
-                {
-                  g_vfs_job_failed (G_VFS_JOB (job),
-                                    G_IO_ERROR,
-                                    G_IO_ERROR_NOT_FOUND,
-                                    _("No such file or directory"));
-                  goto out;
-                }
-            }
-        }
-
-      document = gdata_documents_document_new (NULL);
-      title = basename;
-      gdata_entry_set_title (GDATA_ENTRY (document), title);
-
-      error = NULL;
-      ostream = gdata_documents_service_upload_document (self->service,
-                                                         document,
-                                                         title,
-                                                         content_type,
-                                                         parent,
-                                                         cancellable,
-                                                         &error);
-    }
-
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  error = NULL;
-  g_output_stream_splice (G_OUTPUT_STREAM (ostream),
-                          G_INPUT_STREAM (istream),
-                          G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
-                          cancellable,
-                          &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  error = NULL;
-  new_document = gdata_documents_service_finish_upload (self->service, ostream, &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  insert_entry (self, GDATA_ENTRY (new_document));
-
-  path = get_entry_path (self, GDATA_ENTRY (new_document));
-  if (path != NULL)
-    {
-      g_debug ("  insert lookaside: %s -> %s\n", destination, path);
-      g_hash_table_insert (self->lookaside, g_strdup (destination), g_strdup (path));
-      g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path);
-    }
-
-  self->entries_stale = TRUE;
-
-  if (remove_source)
-    {
-      error = NULL;
-      g_file_delete (local_file, cancellable, &error);
-      if (error != NULL)
-        {
-          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-          g_error_free (error);
-          goto out;
-        }
-    }
-
-  g_vfs_job_succeeded (G_VFS_JOB (job));
-
- out:
-  g_clear_object (&document);
-  g_clear_object (&info);
-  g_clear_object (&istream);
-  g_clear_object (&local_file);
-  g_clear_object (&new_document);
-  g_clear_object (&ostream);
-  g_free (basename);
-  g_free (parent_id);
-  g_free (parent_path);
-  g_free (path);
-  g_free (unescaped_destination);
-  g_debug ("- push\n");
-  g_rec_mutex_unlock (&self->mutex);
+ /*  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); */
+ /*  GCancellable *cancellable = G_VFS_JOB (job)->cancellable; */
+ /*  GDataDocumentsDocument *document = NULL; */
+ /*  GDataDocumentsDocument *new_document = NULL; */
+ /*  GDataDocumentsFolder *parent = NULL; */
+ /*  GDataEntry *entry; */
+ /*  GDataUploadStream *ostream = NULL; */
+ /*  GError *error; */
+ /*  GFile *local_file = NULL; */
+ /*  GFileInputStream *istream = NULL; */
+ /*  GFileInfo *info = NULL; */
+ /*  gboolean is_display_name; */
+ /*  gboolean is_root; */
+ /*  gboolean needs_overwrite = FALSE; */
+ /*  const gchar *content_type; */
+ /*  const gchar *title; */
+ /*  gchar *basename = NULL; */
+ /*  gchar *parent_id = NULL; */
+ /*  gchar *parent_path = NULL; */
+ /*  gchar *path = NULL; */
+ /*  gchar *unescaped_destination = NULL; */
+
+ /*  /\* The destination is always volatile. It will look like /foo/bar */
+ /*   * -> /_id1/bar, whereas in reality it will be /foo/bar -> */
+ /*   * /_id1/_id2. */
+ /*   *\/ */
+
+ /*  g_rec_mutex_lock (&self->mutex); */
+ /*  unescaped_destination = unescape_basename_and_map_dirname (self, destination, &is_display_name); */
+ /*  g_debug ("+ push: %s -> %s (%s, %d)\n", local_path, destination, unescaped_destination, 
is_display_name); */
+
+ /*  if (unescaped_destination == NULL) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (flags & G_FILE_COPY_BACKUP) */
+ /*    { */
+ /*      /\* Return G_IO_ERROR_NOT_SUPPORTED instead of */
+ /*       * G_IO_ERROR_CANT_CREATE_BACKUP to proceed with the GIO */
+ /*       * fallback copy. */
+ /*       *\/ */
+ /*      g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Operation not 
supported"); */
+ /*      goto out; */
+ /*    } */
+
+ /*  local_file = g_file_new_for_path (local_path); */
+
+ /*  error = NULL; */
+ /*  info = g_file_query_info (local_file, */
+ /*                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE"," */
+ /*                            G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME"," */
+ /*                            G_FILE_ATTRIBUTE_STANDARD_TYPE, */
+ /*                            G_FILE_QUERY_INFO_NONE, */
+ /*                            cancellable, */
+ /*                            &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                        G_IO_ERROR, */
+ /*                        G_IO_ERROR_WOULD_RECURSE, */
+ /*                        _("Can't recursively copy directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  basename = g_path_get_basename (unescaped_destination); */
+
+ /*  if (!is_display_name) */
+ /*    { */
+ /*      const gchar *destination_id = basename; */
+
+ /*      /\* This is almost a pathological case. In reality, clients like */
+ /*       * file managers won't use an ID as the destination */
+ /*       * basename. They will use an escaped version of the source */
+ /*       * basename. That means this code path is unlikely to be hit */
+ /*       * when recursively pushing a folder. */
+ /*       * */
+ /*       * Therefore, in order to keep things simple, we unconditionally */
+ /*       * refresh the cache. */
+ /*       *\/ */
+ /*      error = NULL; */
+ /*      rebuild_entries (self, cancellable, &error); */
+ /*      if (error != NULL) */
+ /*        { */
+ /*          g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*          goto out; */
+ /*        } */
+
+ /*      entry = g_hash_table_lookup (self->entries, destination_id); */
+ /*      if (entry != NULL) */
+ /*        { */
+ /*          if (flags & G_FILE_COPY_OVERWRITE) */
+ /*            { */
+ /*              if (GDATA_IS_DOCUMENTS_FOLDER (entry)) */
+ /*                { */
+ /*                  /\* At this point, the source can never be a */
+ /*                   * directory. So we can ignore the issue of copying */
+ /*                   * a directory over another */
+ /*                   * (ie. G_IO_ERROR_WOULD_MERGE). */
+ /*                   *\/ */
+ /*                  g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                                    G_IO_ERROR, */
+ /*                                    G_IO_ERROR_IS_DIRECTORY, */
+ /*                                    _("Can't copy file over directory")); */
+ /*                  goto out; */
+ /*                } */
+
+ /*              needs_overwrite = TRUE; */
+ /*            } */
+ /*          else */
+ /*            { */
+ /*              g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already 
exists")); */
+ /*              goto out; */
+ /*            } */
+ /*        } */
+ /*      else */
+ /*        { */
+ /*          /\* The basename looks like an ID but that ID doesn't */
+ /*           * exist. This is fishy. Probably caused by not using */
+ /*           * g_file_get_child_for_display_name to create the */
+ /*           * destination path. */
+ /*           *\/ */
+ /*          g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                            G_IO_ERROR, */
+ /*                            G_IO_ERROR_INVALID_FILENAME, */
+ /*                            _("Invalid filename %s"), */
+ /*                            destination); */
+ /*          goto out; */
+ /*        } */
+ /*    } */
+
+ /*  g_debug ("  will overwrite: %d\n", needs_overwrite); */
+
+ /*  error = NULL; */
+ /*  istream = g_file_read (local_file, cancellable, &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  content_type = g_file_info_get_content_type (info); */
+
+ /*  if (needs_overwrite) */
+ /*    { */
+ /*      document = g_object_ref (entry); */
+ /*      title = gdata_entry_get_title (entry); */
+
+ /*      error = NULL; */
+ /*      ostream = gdata_documents_service_update_document (self->service, */
+ /*                                                         document, */
+ /*                                                         title, */
+ /*                                                         content_type, */
+ /*                                                         cancellable, */
+ /*                                                         &error); */
+ /*    } */
+ /*  else */
+ /*    { */
+ /*      parent_path = g_path_get_dirname (unescaped_destination); */
+
+ /*      is_folder_or_root (self, parent_path, NULL, NULL, &is_root); */
+ /*      if (!is_root) */
+ /*        { */
+ /*          parent_id = g_path_get_basename (parent_path); */
+ /*          parent = g_hash_table_lookup (self->entries, parent_id); */
+
+ /*          if (parent == NULL) */
+ /*            { */
+ /*              error = NULL; */
+ /*              rebuild_entries (self, cancellable, &error); */
+ /*              if (error != NULL) */
+ /*                { */
+ /*                  g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*                  g_error_free (error); */
+ /*                  goto out; */
+ /*                } */
+
+ /*              parent = g_hash_table_lookup (self->entries, parent_id); */
+ /*              if (parent == NULL) */
+ /*                { */
+ /*                  g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                                    G_IO_ERROR, */
+ /*                                    G_IO_ERROR_NOT_FOUND, */
+ /*                                    _("No such file or directory")); */
+ /*                  goto out; */
+ /*                } */
+ /*            } */
+ /*        } */
+
+ /*      document = gdata_documents_document_new (NULL); */
+ /*      title = basename; */
+ /*      gdata_entry_set_title (GDATA_ENTRY (document), title); */
+
+ /*      error = NULL; */
+ /*      ostream = gdata_documents_service_upload_document (self->service, */
+ /*                                                         document, */
+ /*                                                         title, */
+ /*                                                         content_type, */
+ /*                                                         parent, */
+ /*                                                         cancellable, */
+ /*                                                         &error); */
+ /*    } */
+
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  error = NULL; */
+ /*  g_output_stream_splice (G_OUTPUT_STREAM (ostream), */
+ /*                          G_INPUT_STREAM (istream), */
+ /*                          G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, */
+ /*                          cancellable, */
+ /*                          &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  error = NULL; */
+ /*  new_document = gdata_documents_service_finish_upload (self->service, ostream, &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  insert_entry (self, GDATA_ENTRY (new_document)); */
+
+ /*  path = get_entry_path (self, GDATA_ENTRY (new_document)); */
+ /*  if (path != NULL) */
+ /*    { */
+ /*      g_debug ("  insert lookaside: %s -> %s\n", destination, path); */
+ /*      g_hash_table_insert (self->lookaside, g_strdup (destination), g_strdup (path)); */
+ /*      g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path); */
+ /*    } */
+
+ /*  self->entries_stale = TRUE; */
+
+ /*  if (remove_source) */
+ /*    { */
+ /*      error = NULL; */
+ /*      g_file_delete (local_file, cancellable, &error); */
+ /*      if (error != NULL) */
+ /*        { */
+ /*          g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*          g_error_free (error); */
+ /*          goto out; */
+ /*        } */
+ /*    } */
+
+ /*  g_vfs_job_succeeded (G_VFS_JOB (job)); */
+
+ /* out: */
+ /*  g_clear_object (&document); */
+ /*  g_clear_object (&info); */
+ /*  g_clear_object (&istream); */
+ /*  g_clear_object (&local_file); */
+ /*  g_clear_object (&new_document); */
+ /*  g_clear_object (&ostream); */
+ /*  g_free (basename); */
+ /*  g_free (parent_id); */
+ /*  g_free (parent_path); */
+ /*  g_free (path); */
+ /*  g_free (unescaped_destination); */
+ /*  g_debug ("- push\n"); */
+ /*  g_rec_mutex_unlock (&self->mutex); */
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -2204,57 +1904,50 @@ g_vfs_backend_google_query_info (GVfsBackend           *_self,
   GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
   GDataEntry *entry;
   GError *error;
-  gboolean is_root;
   gboolean is_symlink = FALSE;
   gboolean is_volatile;
-  gchar *id = NULL;
+  gchar *entry_path = NULL;
   gchar *symlink_name = NULL;
-  gchar *unescaped_filename = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ query_info: %s (%s, %d), %d\n", filename, unescaped_filename, is_volatile, flags);
-  filename = unescaped_filename;
+  g_debug ("+ query_info: %s, %d\n", filename, flags);
 
-  if (is_volatile)
+  entry = resolve (self, filename, NULL);
+  if (entry == NULL)
     {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, filename);
-      if (real_filename == NULL)
+      error = NULL;
+      rebuild_entries (self, cancellable, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
 
-      filename = real_filename;
-      if ((flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) != 0)
-        {
-          is_symlink = TRUE;
-          symlink_name = g_path_get_basename (filename);
-        }
-    }
-
-  id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, id);
-  is_folder_or_root (self, filename, entry, NULL, &is_root);
-
-  if (entry == NULL && !is_root)
-    {
       error = NULL;
-      rebuild_entries (self, cancellable, &error);
+      entry = resolve (self, filename, &error);
       if (error != NULL)
         {
           g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
           g_error_free (error);
           goto out;
         }
+    }
 
-      entry = g_hash_table_lookup (self->entries, id);
+  entry_path = get_entry_path (self, entry);
+  if (g_strcmp0 (entry_path, filename) != 0) /* volatile */
+    {
+      if ((flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) != 0)
+        {
+          is_symlink = TRUE;
+          symlink_name = g_path_get_basename (filename);
+        }
     }
 
+  g_debug ("  entry-path: %s (%d)\n", entry_path, is_symlink);
+
   error = NULL;
-  build_file_info (self, filename, entry, info, matcher, is_symlink, symlink_name, &error);
+  build_file_info (self, entry_path, entry, info, matcher, is_symlink, symlink_name, &error);
   if (error != NULL)
     {
       g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
@@ -2265,9 +1958,8 @@ g_vfs_backend_google_query_info (GVfsBackend           *_self,
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
-  g_free (id);
+  g_free (entry_path);
   g_free (symlink_name);
-  g_free (unescaped_filename);
   g_debug ("- query_info\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -2368,41 +2060,13 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
   GInputStream *stream;
   GError *error;
   gboolean is_folder;
-  gboolean is_root;
-  gboolean is_volatile;
   gchar *content_type = NULL;
-  gchar *id = NULL;
-  gchar *unescaped_filename = NULL;
+  gchar *entry_path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ open_for_read: %s (%s, %d)\n", filename, unescaped_filename, is_volatile);
-  filename = unescaped_filename;
-
-  if (is_volatile)
-    {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, filename);
-      if (real_filename == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      filename = real_filename;
-    }
-
-  id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, id);
-
-  is_folder_or_root (self, filename, entry, NULL, &is_root);
-  if (is_root)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, _("Can't open directory"));
-      goto out;
-    }
+  g_debug ("+ open_for_read: %s\n", filename);
 
+  entry = resolve (self, filename, NULL);
   if (entry == NULL)
     {
       error = NULL;
@@ -2414,15 +2078,20 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, id);
-      if (entry == NULL)
+      error = NULL;
+      entry = resolve (self, filename, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
     }
 
-  is_folder_or_root (self, filename, entry, &is_folder, NULL);
+  entry_path = get_entry_path (self, entry);
+  g_debug ("  entry-path: %s\n", entry_path);
+
+  is_folder_or_root (self, entry_path, entry, &is_folder, NULL);
   if (is_folder)
     {
       g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, _("Can't open directory"));
@@ -2487,8 +2156,7 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
 
  out:
   g_free (content_type);
-  g_free (id);
-  g_free (unescaped_filename);
+  g_free (entry_path);
   g_debug ("- open_for_read\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -2623,44 +2291,12 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
   GDataEntry *entry;
   GDataEntry *new_entry = NULL;
   GError *error;
-  gboolean is_root;
-  gboolean is_volatile;
-  gchar *escaped_filename = NULL;
-  gchar *id = NULL;
-  gchar *unescaped_filename = NULL;
+  gchar *entry_path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_filename (self, filename, &is_volatile);
-  g_debug ("+ set_display_name: %s (%s, %d), %s\n", filename, unescaped_filename, is_volatile, display_name);
-  filename = unescaped_filename;
-
-  if (is_volatile)
-    {
-      const gchar *real_filename;
-
-      real_filename = g_hash_table_lookup (self->lookaside, unescaped_filename);
-      if (real_filename == NULL)
-        {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-          goto out;
-        }
-
-      filename = real_filename;
-    }
-
-  is_folder_or_root (self, filename, NULL, NULL, &is_root);
-  if (is_root)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_NOT_SUPPORTED,
-                        _("Can not rename the root directory"));
-      goto out;
-    }
-
-  id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, id);
+  g_debug ("+ set_display_name: %s, %s\n", filename, display_name);
 
+  entry = resolve (self, filename, NULL);
   if (entry == NULL)
     {
       error = NULL;
@@ -2672,14 +2308,28 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, id);
-      if (entry == NULL)
+      error = NULL;
+      entry = resolve (self, filename, &error);
+      if (error != NULL)
         {
-          g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
+          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+          g_error_free (error);
           goto out;
         }
     }
 
+  entry_path = get_entry_path (self, entry);
+  g_debug ("  entry-path: %s\n", entry_path);
+
+  if (entry == self->root)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR,
+                        G_IO_ERROR_NOT_SUPPORTED,
+                        _("Can not rename the root directory"));
+      goto out;
+    }
+
   gdata_entry_set_title (entry, display_name);
   auth_domain = gdata_documents_service_get_primary_authorization_domain ();
 
@@ -2695,22 +2345,19 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
   remove_entry (self, entry);
   insert_entry (self, new_entry);
 
-  g_hash_table_foreach (self->monitors, emit_attribute_changed_event, (gpointer) filename);
+  g_hash_table_foreach (self->monitors, emit_attribute_changed_event, (gpointer) entry_path);
 
-  /* escaped_filename might not be the same as the initial filename
-   * that was passed to this operation. The former is guaranteed to be
+  /* entry_path might not be the same as the initial filename that was
+   * passed to this operation. The former is guaranteed to be
    * non-volatile, while the latter is not.
    */
-  escaped_filename = escape_filename (filename);
-  g_debug ("  set new path: %s\n", escaped_filename);
-  g_vfs_job_set_display_name_set_new_path (job, escaped_filename);
+  g_debug ("  set new path: %s\n", entry_path);
+  g_vfs_job_set_display_name_set_new_path (job, entry_path);
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
   g_clear_object (&new_entry);
-  g_free (id);
-  g_free (escaped_filename);
-  g_free (unescaped_filename);
+  g_free (entry_path);
   g_debug ("- set_display_name\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -2723,49 +2370,49 @@ g_vfs_backend_google_create (GVfsBackend         *_self,
                              const gchar         *filename,
                              GFileCreateFlags     flags)
 {
-  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
-  GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
-  GDataDocumentsDocument *new_document;
-  GError *error;
-  gboolean is_root;
-  gchar *unescaped_filename = NULL;
-
-  g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_basename_and_map_dirname (self, filename, NULL);
-  g_debug ("+ create: %s (%s, 1)\n", filename, unescaped_filename);
-
-  if (unescaped_filename == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
-
-  is_folder_or_root (self, unescaped_filename, NULL, NULL, &is_root);
-  if (is_root)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_NOT_SUPPORTED,
-                        _("Can not create root directory"));
-      goto out;
-    }
-
-  error = NULL;
-  new_document = create_document (self, filename, unescaped_filename, cancellable, &error);
-  if (error != NULL)
-    {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
-    }
-
-  g_vfs_job_open_for_write_set_handle (job, new_document);
-  g_vfs_job_succeeded (G_VFS_JOB (job));
-
- out:
-  g_free (unescaped_filename);
-  g_debug ("- create\n");
-  g_rec_mutex_unlock (&self->mutex);
+ /*  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); */
+ /*  GCancellable *cancellable = G_VFS_JOB (job)->cancellable; */
+ /*  GDataDocumentsDocument *new_document; */
+ /*  GError *error; */
+ /*  gboolean is_root; */
+ /*  gchar *unescaped_filename = NULL; */
+
+ /*  g_rec_mutex_lock (&self->mutex); */
+ /*  unescaped_filename = unescape_basename_and_map_dirname (self, filename, NULL); */
+ /*  g_debug ("+ create: %s (%s, 1)\n", filename, unescaped_filename); */
+
+ /*  if (unescaped_filename == NULL) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  is_folder_or_root (self, unescaped_filename, NULL, NULL, &is_root); */
+ /*  if (is_root) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                        G_IO_ERROR, */
+ /*                        G_IO_ERROR_NOT_SUPPORTED, */
+ /*                        _("Can not create root directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  error = NULL; */
+ /*  new_document = create_document (self, filename, unescaped_filename, cancellable, &error); */
+ /*  if (error != NULL) */
+ /*    { */
+ /*      g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*      g_error_free (error); */
+ /*      goto out; */
+ /*    } */
+
+ /*  g_vfs_job_open_for_write_set_handle (job, new_document); */
+ /*  g_vfs_job_succeeded (G_VFS_JOB (job)); */
+
+ /* out: */
+ /*  g_free (unescaped_filename); */
+ /*  g_debug ("- create\n"); */
+ /*  g_rec_mutex_unlock (&self->mutex); */
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -2778,116 +2425,116 @@ g_vfs_backend_google_replace (GVfsBackend         *_self,
                               gboolean             make_backup,
                               GFileCreateFlags     flags)
 {
-  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
-  GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
-  GDataUploadStream *stream;
-  GError *error;
-  GVfsBackendHandle handle;
-  gboolean is_display_name;
-  gboolean is_root;
-  gchar *content_type = NULL;
-  gchar *id = NULL;
-  gchar *unescaped_filename = NULL;
-
-  g_rec_mutex_lock (&self->mutex);
-  unescaped_filename = unescape_basename_and_map_dirname (self, filename, &is_display_name);
-  g_debug ("+ replace: %s (%s, %d)\n", filename, unescaped_filename, is_display_name);
-
-  if (unescaped_filename == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
-      goto out;
-    }
-
-  is_folder_or_root (self, unescaped_filename, NULL, NULL, &is_root);
-  if (is_root)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_NOT_SUPPORTED,
-                        _("Can not create root directory"));
-      goto out;
-    }
-
-  if (make_backup)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_CANT_CREATE_BACKUP,
-                        _("Backup file creation failed"));
-      goto out;
-    }
-
-  if (is_display_name)
-    {
-      GDataDocumentsDocument *new_document;
-
-      error = NULL;
-      new_document = create_document (self, filename, unescaped_filename, cancellable, &error);
-      if (error != NULL)
-        {
-          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-          g_error_free (error);
-          goto out;
-        }
-
-      handle = new_document;
-    }
-  else
-    {
-      GDataEntry *entry;
-      const gchar *title;
-
-      id = g_path_get_basename (unescaped_filename);
-      entry = g_hash_table_lookup (self->entries, id);
-
-      if (entry == NULL)
-        {
-          error = NULL;
-          rebuild_entries (self, cancellable, &error);
-          if (error != NULL)
-            {
-              g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-              g_error_free (error);
-              goto out;
-            }
-
-          entry = g_hash_table_lookup (self->entries, id);
-          if (entry == NULL)
-            {
-              g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory"));
-              goto out;
-            }
-        }
-
-      title = gdata_entry_get_title (entry);
-      content_type = get_content_type_from_entry (entry);
-
-      error = NULL;
-      stream = gdata_documents_service_update_document (self->service,
-                                                        GDATA_DOCUMENTS_DOCUMENT (entry),
-                                                        title,
-                                                        content_type,
-                                                        cancellable,
-                                                        &error);
-      if (error != NULL)
-        {
-          g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-          g_error_free (error);
-          goto out;
-        }
-
-      handle = stream;
-    }
-
-  g_vfs_job_open_for_write_set_handle (job, handle);
-  g_vfs_job_succeeded (G_VFS_JOB (job));
-
- out:
-  g_free (content_type);
-  g_free (unescaped_filename);
-  g_debug ("- replace\n");
-  g_rec_mutex_unlock (&self->mutex);
+ /*  GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); */
+ /*  GCancellable *cancellable = G_VFS_JOB (job)->cancellable; */
+ /*  GDataUploadStream *stream; */
+ /*  GError *error; */
+ /*  GVfsBackendHandle handle; */
+ /*  gboolean is_display_name; */
+ /*  gboolean is_root; */
+ /*  gchar *content_type = NULL; */
+ /*  gchar *id = NULL; */
+ /*  gchar *unescaped_filename = NULL; */
+
+ /*  g_rec_mutex_lock (&self->mutex); */
+ /*  unescaped_filename = unescape_basename_and_map_dirname (self, filename, &is_display_name); */
+ /*  g_debug ("+ replace: %s (%s, %d)\n", filename, unescaped_filename, is_display_name); */
+
+ /*  if (unescaped_filename == NULL) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  is_folder_or_root (self, unescaped_filename, NULL, NULL, &is_root); */
+ /*  if (is_root) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                        G_IO_ERROR, */
+ /*                        G_IO_ERROR_NOT_SUPPORTED, */
+ /*                        _("Can not create root directory")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (make_backup) */
+ /*    { */
+ /*      g_vfs_job_failed (G_VFS_JOB (job), */
+ /*                        G_IO_ERROR, */
+ /*                        G_IO_ERROR_CANT_CREATE_BACKUP, */
+ /*                        _("Backup file creation failed")); */
+ /*      goto out; */
+ /*    } */
+
+ /*  if (is_display_name) */
+ /*    { */
+ /*      GDataDocumentsDocument *new_document; */
+
+ /*      error = NULL; */
+ /*      new_document = create_document (self, filename, unescaped_filename, cancellable, &error); */
+ /*      if (error != NULL) */
+ /*        { */
+ /*          g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*          g_error_free (error); */
+ /*          goto out; */
+ /*        } */
+
+ /*      handle = new_document; */
+ /*    } */
+ /*  else */
+ /*    { */
+ /*      GDataEntry *entry; */
+ /*      const gchar *title; */
+
+ /*      id = g_path_get_basename (unescaped_filename); */
+ /*      entry = g_hash_table_lookup (self->entries, id); */
+
+ /*      if (entry == NULL) */
+ /*        { */
+ /*          error = NULL; */
+ /*          rebuild_entries (self, cancellable, &error); */
+ /*          if (error != NULL) */
+ /*            { */
+ /*              g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*              g_error_free (error); */
+ /*              goto out; */
+ /*            } */
+
+ /*          entry = g_hash_table_lookup (self->entries, id); */
+ /*          if (entry == NULL) */
+ /*            { */
+ /*              g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or 
directory")); */
+ /*              goto out; */
+ /*            } */
+ /*        } */
+
+ /*      title = gdata_entry_get_title (entry); */
+ /*      content_type = get_content_type_from_entry (entry); */
+
+ /*      error = NULL; */
+ /*      stream = gdata_documents_service_update_document (self->service, */
+ /*                                                        GDATA_DOCUMENTS_DOCUMENT (entry), */
+ /*                                                        title, */
+ /*                                                        content_type, */
+ /*                                                        cancellable, */
+ /*                                                        &error); */
+ /*      if (error != NULL) */
+ /*        { */
+ /*          g_vfs_job_failed_from_error (G_VFS_JOB (job), error); */
+ /*          g_error_free (error); */
+ /*          goto out; */
+ /*        } */
+
+ /*      handle = stream; */
+ /*    } */
+
+ /*  g_vfs_job_open_for_write_set_handle (job, handle); */
+ /*  g_vfs_job_succeeded (G_VFS_JOB (job)); */
+
+ /* out: */
+ /*  g_free (content_type); */
+ /*  g_free (unescaped_filename); */
+ /*  g_debug ("- replace\n"); */
+ /*  g_rec_mutex_unlock (&self->mutex); */
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -3076,8 +2723,8 @@ g_vfs_backend_google_class_init (GVfsBackendGoogleClass * klass)
 
   backend_class->try_close_read = g_vfs_backend_google_close_read;
   backend_class->close_write = g_vfs_backend_google_close_write;
-  backend_class->copy = g_vfs_backend_google_copy;
-  backend_class->create = g_vfs_backend_google_create;
+  //backend_class->copy = g_vfs_backend_google_copy;
+  //backend_class->create = g_vfs_backend_google_create;
   backend_class->try_create_dir_monitor = g_vfs_backend_google_create_dir_monitor;
   backend_class->delete = g_vfs_backend_google_delete;
   backend_class->enumerate = g_vfs_backend_google_enumerate;
@@ -3093,15 +2740,13 @@ g_vfs_backend_google_class_init (GVfsBackendGoogleClass * klass)
   backend_class->seek_on_read = g_vfs_backend_google_seek_on_read;
   backend_class->set_display_name = g_vfs_backend_google_set_display_name;
   backend_class->try_read = g_vfs_backend_google_read;
-  backend_class->replace = g_vfs_backend_google_replace;
+  //backend_class->replace = g_vfs_backend_google_replace;
   backend_class->write = g_vfs_backend_google_write;
 }
 
 static void
 g_vfs_backend_google_init (GVfsBackendGoogle *self)
 {
-  g_vfs_backend_set_prefered_filename_encoding (G_VFS_BACKEND (self), "google-drive");
-
   self->entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   self->dir_entries = g_hash_table_new_full (entries_in_folder_hash,
                                              entries_in_folder_equal,


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