[gvfs] afp: fix renaming of files/directories outside of the root directory



commit c1aa8a97f866eca06927cd2bb45a40724b006089
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Tue Aug 2 22:31:39 2011 +0200

    afp: fix renaming of files/directories outside of the root directory
    
    we now first query for the file's/directory's parent dir id which we then use
    in the FPRename command

 daemon/gvfsbackendafp.c |   77 +++++++++++++++++++++++++++++++++-------------
 1 files changed, 55 insertions(+), 22 deletions(-)
---
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 6523e3e..0a30a68 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -264,6 +264,14 @@ static void fill_info (GVfsBackendAfp *afp_backend,
       g_file_info_set_is_hidden (info, TRUE);
   }
 
+  if (bitmap & AFP_FILEDIR_BITMAP_PARENT_DIR_ID_BIT)
+  {
+    guint32 parent_dir_id;
+
+    g_vfs_afp_reply_read_uint32 (reply, &parent_dir_id);
+    g_file_info_set_attribute_uint32 (info, "afp::parent-dir-id", parent_dir_id);
+  }
+  
   if (bitmap & AFP_FILEDIR_BITMAP_CREATE_DATE_BIT)
   {
     gint32 create_date;
@@ -1184,47 +1192,72 @@ rename_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
   g_vfs_job_succeeded (G_VFS_JOB (job));
 }
 
-static gboolean
-try_set_display_name (GVfsBackend *backend,
-                      GVfsJobSetDisplayName *job,
-                      const char *filename,
-                      const char *display_name)
+static void
+set_display_name_get_filedir_parms_cb (GObject      *source_object,
+                                       GAsyncResult *res,
+                                       gpointer      user_data)
 {
-  GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
+  GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object);
+  GVfsJobSetDisplayName *job = G_VFS_JOB_SET_DISPLAY_NAME (user_data);
+
+  GFileInfo *info;
+  GError *err = NULL;
 
+  guint32 dir_id;
   GVfsAfpCommand *comm;
-  char *dirname, *newname;
-  
-  if (is_root (filename))
+  char *basename;
+
+  info = get_filedir_parms_finish (afp_backend, res, &err);
+  if (!info)
   {
-    g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME,
-                              _("Can't rename volume"));
-    return TRUE;
+    g_vfs_job_failed_from_error (G_VFS_JOB (job), err);
+    g_error_free (err);
+    return;
   }
 
+  dir_id = g_file_info_get_attribute_uint32 (info, "afp::parent-dir-id");
+  g_object_unref (info);
+
   comm = g_vfs_afp_command_new (AFP_COMMAND_RENAME);
   /* pad byte */
   g_vfs_afp_command_put_byte (comm, 0);
   /* Volume ID */
   g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
-  /* Directory ID 2 == / */
-  g_vfs_afp_command_put_uint32 (comm, 2);
+  /* Directory ID */
+  g_vfs_afp_command_put_uint32 (comm, dir_id);
 
   /* Pathname */
-  put_pathname (comm, filename);
+  basename = g_path_get_basename (job->filename);
+  put_pathname (comm, basename);
+  g_free (basename);
 
   /* NewName */
-  dirname = g_path_get_dirname (filename);
-  newname = g_build_filename (dirname, display_name, NULL);
-  put_pathname (comm, newname);
-
-  g_free (dirname);
-  g_free (newname);
+  put_pathname (comm, job->display_name);
 
   g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, rename_cb,
-                                      G_VFS_JOB (job)->cancellable, job);
+                                     G_VFS_JOB (job)->cancellable, job);
   g_object_unref (comm);
+}
+  
+static gboolean
+try_set_display_name (GVfsBackend *backend,
+                      GVfsJobSetDisplayName *job,
+                      const char *filename,
+                      const char *display_name)
+{
+  GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
+  
+  if (is_root (filename))
+  {
+    g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME,
+                              _("Can't rename volume"));
+    return TRUE;
+  }
 
+  get_filedir_parms (afp_backend, filename, AFP_FILEDIR_BITMAP_PARENT_DIR_ID_BIT,
+                     AFP_FILEDIR_BITMAP_PARENT_DIR_ID_BIT,
+                     G_VFS_JOB (job)->cancellable,
+                     set_display_name_get_filedir_parms_cb, job);
   return TRUE;
 }
 



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