[gvfs] afp: add copy_file function wrapping FPCopyFile



commit e70e80d574505dbfeb89e31269cc00d8866bf122
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Mon Aug 22 00:30:08 2011 +0200

    afp: add copy_file function wrapping FPCopyFile

 daemon/gvfsafpconnection.h |    2 +
 daemon/gvfsbackendafp.c    |  128 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 1 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
index 44cfb09..f5cde13 100644
--- a/daemon/gvfsafpconnection.h
+++ b/daemon/gvfsafpconnection.h
@@ -191,6 +191,7 @@ enum
 typedef enum
 {
   AFP_COMMAND_CLOSE_FORK         = 4,
+  AFP_COMMAND_COPY_FILE          = 5,
   AFP_COMMAND_CREATE_DIR         = 6,
   AFP_COMMAND_CREATE_FILE        = 7,
   AFP_COMMAND_DELETE             = 8,
@@ -227,6 +228,7 @@ typedef enum
   AFP_RESULT_AUTH_CONTINUE        = -5001,
   AFP_RESULT_BAD_UAM              = -5002,
   AFP_RESULT_CANT_MOVE            = -5005,
+  AFP_RESULT_DENY_CONFLICT        = -5006,
   AFP_RESULT_DIR_NOT_EMPTY        = -5007,
   AFP_RESULT_DISK_FULL            = -5008,
   AFP_RESULT_EOF_ERR              = -5009,
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 8f0afc0..f4a80c3 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -1517,10 +1517,136 @@ move_and_rename_finish (GVfsBackendAfp *afp_backend,
   return TRUE;
 }
 
+static void
+copy_file_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+  GVfsAfpReply *reply;
+  GError *err = NULL;
+
+  AfpResultCode res_code;
+
+  reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
+  if (!reply)
+  {
+    g_simple_async_result_take_error (simple, err);
+    goto done;
+  }
+
+  res_code = g_vfs_afp_reply_get_result_code (reply);
+  g_object_unref (reply);
+
+  if (res_code != AFP_RESULT_NO_ERROR)
+  {
+    switch (res_code)
+    {
+      case AFP_RESULT_ACCESS_DENIED:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                                         _("Permission denied"));
+        break;
+      case AFP_RESULT_CALL_NOT_SUPPORTED:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                                         _("Server doesn't support the FPCopyFile operation"));
+        break;
+      case AFP_RESULT_DENY_CONFLICT:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                         _("Couldn't open source file as Read/DenyWrite"));
+        break;
+      case AFP_RESULT_DISK_FULL:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
+                                         _("Not enough space on volume"));
+        break;
+      case AFP_RESULT_OBJECT_EXISTS:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_EXISTS,
+                                         _("Target file already exists"));
+        break;
+      case AFP_RESULT_OBJECT_NOT_FOUND:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                                         _("Source file and/or destination directory doesn't exist"));
+        break;
+      case AFP_RESULT_OBJECT_TYPE_ERR:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
+                                         _("Source file is a directory"));
+        break;
+      default:
+        g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                         _("Got error code: %d from server"), res_code);
+        break;
+    }
+  }
+        
+done:
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+static void
+copy_file (GVfsBackendAfp     *afp_backend,
+           const char         *source,
+           const char         *destination,
+           GCancellable       *cancellable,
+           GAsyncReadyCallback callback,
+           gpointer            user_data)
+{
+  GVfsAfpCommand *comm;
+  char *dirname, *basename;
+  GSimpleAsyncResult *simple;
+
+  comm = g_vfs_afp_command_new (AFP_COMMAND_COPY_FILE);
+  /* pad byte */
+  g_vfs_afp_command_put_byte (comm, 0);
+
+  /* VolumeID */
+  g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
+
+  /* SourceDirectoryID 2 == / */
+  g_vfs_afp_command_put_uint32 (comm, 2);
+  /* DestDirectoryID 2 == / */
+  g_vfs_afp_command_put_uint32 (comm, 2);
+
+  /* SourcePathname */
+  put_pathname (comm, source);
+
+  /* DestPathname */
+  dirname = g_path_get_dirname (destination);
+  put_pathname (comm, dirname);
+  g_free (dirname);
+
+  /* NewName */
+  basename = g_path_get_basename (destination);
+  put_pathname (comm, basename);
+  g_free (basename);
+
+  simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
+                                      user_data, copy_file);
+
+  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
+                                     copy_file_cb, cancellable, simple);
+  g_object_unref (comm);
+}
+
+static gboolean
+copy_file_finish (GVfsBackendAfp *afp_backend, GAsyncResult *res, GError **error)
+{
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (afp_backend),
+                                                        copy_file),
+                        FALSE);
+
+  simple = (GSimpleAsyncResult *)res;
+  
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
+  return TRUE;
+}
+
 /*
  * Backend code
  */
-
 static void
 move_move_and_rename_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {



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