[gvfs] afp: implement basic file replace
- From: Christian Kellner <gicmo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: implement basic file replace
- Date: Thu, 25 Aug 2011 19:25:09 +0000 (UTC)
commit 0d52e171cf8c64dd7715fb6e8600ed767e3e75cf
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date: Sun Jul 10 23:00:56 2011 +0200
afp: implement basic file replace
daemon/gvfsafpconnection.h | 2 +
daemon/gvfsbackendafp.c | 614 +++++++++++++++++++++++++++-----------------
2 files changed, 380 insertions(+), 236 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
index 0c13cdb..f1bcda5 100644
--- a/daemon/gvfsafpconnection.h
+++ b/daemon/gvfsafpconnection.h
@@ -142,6 +142,7 @@ typedef enum
AFP_COMMAND_RENAME = 28,
AFP_COMMAND_WRITE = 33,
AFP_COMMAND_GET_FILE_DIR_PARMS = 34,
+ AFP_COMMAND_EXCHANGE_FILES = 42,
AFP_COMMAND_READ_EXT = 60,
AFP_COMMAND_WRITE_EXT = 61,
AFP_COMMAND_ENUMERATE_EXT = 66,
@@ -164,6 +165,7 @@ typedef enum
AFP_RESULT_OBJECT_NOT_FOUND = -5018,
AFP_RESULT_PARAM_ERR = -5019,
AFP_RESULT_USER_NOT_AUTH = -5023,
+ AFP_RESULT_CALL_NOT_SUPPORTED = -5024,
AFP_RESULT_OBJECT_TYPE_ERR = -5025,
AFP_RESULT_TOO_MANY_FILES_OPEN = -5026,
AFP_RESULT_CANT_RENAME = -5028,
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 65c3d8b..e0c74a9 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -128,10 +128,22 @@ put_pathname (GVfsAfpCommand *comm, const char *filename)
g_vfs_afp_name_unref (pathname);
}
+typedef enum
+{
+ AFP_HANDLE_TYPE_READ_FILE,
+ AFP_HANDLE_TYPE_CREATE_FILE,
+ AFP_HANDLE_TYPE_REPLACE_FILE,
+ AFP_HANDLE_TYPE_APPEND_TO_FILE
+} AfpHandleType;
+
typedef struct
{
+ AfpHandleType type;
gint16 fork_refnum;
gint64 offset;
+
+ char *filename;
+ char *tmp_filename;
} AfpHandle;
static AfpHandle *
@@ -148,6 +160,8 @@ afp_handle_new (gint16 fork_refnum)
static void
afp_handle_free (AfpHandle *afp_handle)
{
+ g_free (afp_handle->filename);
+
g_slice_free (AfpHandle, afp_handle);
}
@@ -274,6 +288,267 @@ static void fill_info (GVfsBackendAfp *afp_backend,
}
}
+typedef void (*OpenForkCallback) (GVfsJob *job,
+ AfpHandle *afp_handle);
+
+static void
+open_fork_cb (GVfsAfpConnection *afp_connection,
+ GVfsAfpReply *reply,
+ GError *error,
+ gpointer user_data)
+{
+ GVfsJob *job = G_VFS_JOB (user_data);
+
+ AfpResultCode res_code;
+ guint16 file_bitmap;
+ gint16 fork_refnum;
+ AfpHandle *afp_handle;
+
+ OpenForkCallback cb;
+
+ if (!reply)
+ {
+ g_vfs_job_failed_from_error (job, error);
+ return;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ g_object_unref (reply);
+
+ switch (res_code)
+ {
+ case AFP_RESULT_ACCESS_DENIED:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Access denied"));
+ break;
+ case AFP_RESULT_OBJECT_NOT_FOUND:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("File doesn't exist"));
+ break;
+ case AFP_RESULT_OBJECT_TYPE_ERR:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE,
+ _("File is a directory"));
+ break;
+ case AFP_RESULT_TOO_MANY_FILES_OPEN:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_TOO_MANY_OPEN_FILES,
+ _("Too many files open"));
+ break;
+ default:
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ break;
+ }
+ return;
+ }
+
+ g_vfs_afp_reply_read_uint16 (reply, &file_bitmap);
+ g_vfs_afp_reply_read_int16 (reply, &fork_refnum);
+
+ g_object_unref (reply);
+
+ afp_handle = afp_handle_new (fork_refnum);
+
+ cb = g_object_get_data (G_OBJECT (job), "OpenForkCallback");
+ cb (job, afp_handle);
+}
+
+static void
+open_fork (GVfsBackendAfp *afp_backend,
+ GVfsJob *job,
+ const char *filename,
+ guint16 access_mode,
+ OpenForkCallback cb)
+{
+ GVfsAfpCommand *comm;
+
+ if (is_root (filename))
+ {
+ g_vfs_job_failed_literal (job, G_IO_ERROR,
+ G_IO_ERROR_NOT_REGULAR_FILE,
+ _("File is a directory"));
+ return;
+ }
+
+ comm = g_vfs_afp_command_new (AFP_COMMAND_OPEN_FORK);
+ /* data fork */
+ g_vfs_afp_command_put_byte (comm, 0);
+
+ /* Volume ID */
+ g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
+ /* Directory ID */
+ g_vfs_afp_command_put_uint32 (comm, 2);
+
+ /* Bitmap */
+ g_vfs_afp_command_put_uint16 (comm, 0);
+
+ /* AccessMode */
+ g_vfs_afp_command_put_uint16 (comm, access_mode);
+
+ /* Pathname */
+ put_pathname (comm, filename);
+
+ g_object_set_data (G_OBJECT (job), "OpenForkCallback", cb);
+
+ g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
+ open_fork_cb,
+ G_VFS_JOB (job)->cancellable, job);
+ g_object_unref (comm);
+
+ return;
+}
+
+typedef void (*CloseForkCallback) (GVfsJob *job);
+
+static void
+close_fork_cb (GVfsAfpConnection *afp_connection,
+ GVfsAfpReply *reply,
+ GError *error,
+ gpointer user_data)
+{
+ GVfsJob *job = G_VFS_JOB (user_data);
+
+ AfpResultCode res_code;
+ CloseForkCallback cb;
+
+ if (!reply)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ return;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ g_object_unref (reply);
+
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ return;
+ }
+
+ cb = g_object_get_data (G_OBJECT (job), "CloseForkCallback");
+ if (cb != NULL)
+ cb (job);
+ else
+ g_vfs_job_succeeded (job);
+}
+
+static void
+close_fork (GVfsBackendAfp *afp_backend,
+ GVfsJob *job,
+ AfpHandle *afp_handle,
+ CloseForkCallback cb)
+{
+ GVfsAfpCommand *comm;
+
+ comm = g_vfs_afp_command_new (AFP_COMMAND_CLOSE_FORK);
+ /* pad byte */
+ g_vfs_afp_command_put_byte (comm, 0);
+
+ /* OForkRefNum */
+ g_vfs_afp_command_put_int16 (comm, afp_handle->fork_refnum);
+
+ g_object_set_data (G_OBJECT (job), "CloseForkCallback", cb);
+
+ g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
+ close_fork_cb, G_VFS_JOB (job)->cancellable,
+ job);
+ g_object_unref (comm);
+
+ afp_handle_free (afp_handle);
+}
+
+typedef void (*CreateFileCallback) (GVfsJob *job);
+
+static void
+create_file_cb (GVfsAfpConnection *afp_connection,
+ GVfsAfpReply *reply,
+ GError *error,
+ gpointer user_data)
+{
+ GVfsJob *job = G_VFS_JOB (user_data);
+
+ AfpResultCode res_code;
+ CreateFileCallback cb;
+
+ if (!reply)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ return;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ g_object_unref (reply);
+
+ switch (res_code)
+ {
+ case AFP_RESULT_ACCESS_DENIED:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Access denied"));
+ break;
+ case AFP_RESULT_DISK_FULL:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
+ _("Not enough space on volume"));
+ break;
+ case AFP_RESULT_FILE_BUSY:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_EXISTS,
+ _("Target file is open"));
+ break;
+ case AFP_RESULT_OBJECT_EXISTS:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_EXISTS,
+ _("Target file already exists"));
+ break;
+ case AFP_RESULT_OBJECT_NOT_FOUND:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("Ancestor directory doesn't exist"));
+ break;
+ case AFP_RESULT_VOL_LOCKED:
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Volume is read-only"));
+ break;
+ default:
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ break;
+ }
+ return;
+ }
+
+ cb = g_object_get_data (G_OBJECT (job), "CreateFileCallback");
+ cb (job);
+}
+
+static void
+create_file (GVfsBackendAfp *afp_backend,
+ GVfsJob *job,
+ const char *filename,
+ gboolean hard_create,
+ CreateFileCallback cb)
+{
+ GVfsAfpCommand *comm;
+
+ comm = g_vfs_afp_command_new (AFP_COMMAND_CREATE_FILE);
+ /* soft/hard create */
+ g_vfs_afp_command_put_byte (comm, hard_create ? 0x80 : 0x00);
+ /* Volume ID */
+ g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
+ /* Directory ID 2 == / */
+ g_vfs_afp_command_put_uint32 (comm, 2);
+
+ /* Pathname */
+ put_pathname (comm, filename);
+
+ g_object_set_data (G_OBJECT (job), "CreateFileCallback", cb);
+
+ g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm, create_file_cb,
+ job->cancellable, job);
+ g_object_unref (comm);
+}
+
static void
rename_cb (GVfsAfpConnection *afp_connection,
GVfsAfpReply *reply,
@@ -785,7 +1060,7 @@ read_ext_cb (GVfsAfpConnection *afp_connection,
g_vfs_job_succeeded (G_VFS_JOB (job));
}
-
+
static gboolean
try_read (GVfsBackend *backend,
GVfsJobRead *job,
@@ -820,35 +1095,42 @@ try_read (GVfsBackend *backend,
}
static void
-close_write_cb (GVfsAfpConnection *afp_connection,
- GVfsAfpReply *reply,
- GError *error,
- gpointer user_data)
+close_replace_exchange_files_cb (GVfsAfpConnection *afp_connection,
+ GVfsAfpReply *reply,
+ GError *error,
+ gpointer user_data)
{
GVfsJobCloseWrite *job = G_VFS_JOB_CLOSE_WRITE (user_data);
- AfpHandle *afp_handle = (AfpHandle *)job->handle;
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (job->backend);
AfpResultCode res_code;
-
+
if (!reply)
{
- afp_handle_free (afp_handle);
g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
return;
}
res_code = g_vfs_afp_reply_get_result_code (reply);
- g_object_unref (reply);
-
if (res_code != AFP_RESULT_NO_ERROR)
{
- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Got error code: %d from server"), res_code);
+ g_object_unref (reply);
+
+ switch (res_code)
+ {
+ case AFP_RESULT_ACCESS_DENIED:
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Access denied"));
+ break;
+ default:
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ break;
+ }
+ return;
}
- else
- g_vfs_job_succeeded (G_VFS_JOB (job));
- afp_handle_free (afp_handle);
+ close_fork (afp_backend, G_VFS_JOB (job), (AfpHandle *)job->handle, NULL);
}
static gboolean
@@ -859,53 +1141,35 @@ try_close_write (GVfsBackend *backend,
GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
AfpHandle *afp_handle = (AfpHandle *)handle;
- GVfsAfpCommand *comm;
-
- comm = g_vfs_afp_command_new (AFP_COMMAND_CLOSE_FORK);
- /* pad byte */
- g_vfs_afp_command_put_byte (comm, 0);
-
- /* OForkRefNum */
- g_vfs_afp_command_put_int16 (comm, afp_handle->fork_refnum);
-
- g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
- close_write_cb, G_VFS_JOB (job)->cancellable,
- job);
- g_object_unref (comm);
-
- return TRUE;
-}
+ if (afp_handle->type == AFP_HANDLE_TYPE_REPLACE_FILE)
+ {
+ GVfsAfpCommand *comm;
-static void
-close_read_cb (GVfsAfpConnection *afp_connection,
- GVfsAfpReply *reply,
- GError *error,
- gpointer user_data)
-{
- GVfsJobCloseRead *job = G_VFS_JOB_CLOSE_READ (user_data);
- AfpHandle *afp_handle = (AfpHandle *)job->handle;
+ comm = g_vfs_afp_command_new (AFP_COMMAND_EXCHANGE_FILES);
+ /* pad byte */
+ g_vfs_afp_command_put_byte (comm, 0);
- AfpResultCode res_code;
-
- if (!reply)
- {
- afp_handle_free (afp_handle);
- g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
- return;
- }
+ /* Volume ID */
+ g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
+ /* SourceDirectory ID 2 == / */
+ g_vfs_afp_command_put_uint32 (comm, 2);
+ /* DestDirectory ID 2 == / */
+ g_vfs_afp_command_put_uint32 (comm, 2);
- res_code = g_vfs_afp_reply_get_result_code (reply);
- g_object_unref (reply);
+ /* SourcePath */
+ put_pathname (comm, afp_handle->filename);
+ /* DestPath */
+ put_pathname (comm, afp_handle->tmp_filename);
- if (res_code != AFP_RESULT_NO_ERROR)
- {
- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Got error from server"));
+ g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
+ close_replace_exchange_files_cb,
+ G_VFS_JOB (job)->cancellable, job);
+ g_object_unref (comm);
}
else
- g_vfs_job_succeeded (G_VFS_JOB (job));
-
- afp_handle_free (afp_handle);
+ close_fork (afp_backend, G_VFS_JOB (job), afp_handle, NULL);
+
+ return TRUE;
}
static gboolean
@@ -916,132 +1180,69 @@ try_close_read (GVfsBackend *backend,
GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
AfpHandle *afp_handle = (AfpHandle *)handle;
- GVfsAfpCommand *comm;
-
- comm = g_vfs_afp_command_new (AFP_COMMAND_CLOSE_FORK);
- /* pad byte */
- g_vfs_afp_command_put_byte (comm, 0);
-
- /* OForkRefNum */
- g_vfs_afp_command_put_int16 (comm, afp_handle->fork_refnum);
-
- g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
- close_read_cb, G_VFS_JOB (job)->cancellable,
- job);
- g_object_unref (comm);
+ close_fork (afp_backend, G_VFS_JOB (job), afp_handle, NULL);
return TRUE;
}
-typedef void (*OpenForkCallback) (GVfsJob *job,
- AfpHandle *afp_handle);
-
static void
-open_fork_cb (GVfsAfpConnection *afp_connection,
- GVfsAfpReply *reply,
- GError *error,
- gpointer user_data)
+replace_open_fork_cb (GVfsJob *job,
+ AfpHandle *afp_handle)
{
- GVfsJob *job = G_VFS_JOB (user_data);
-
- AfpResultCode res_code;
- guint16 file_bitmap;
- gint16 fork_refnum;
- AfpHandle *afp_handle;
-
- OpenForkCallback cb;
-
- if (!reply)
- {
- g_vfs_job_failed_from_error (job, error);
- return;
- }
-
- res_code = g_vfs_afp_reply_get_result_code (reply);
- if (res_code != AFP_RESULT_NO_ERROR)
- {
- g_object_unref (reply);
-
- switch (res_code)
- {
- case AFP_RESULT_ACCESS_DENIED:
- g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- _("Access denied"));
- break;
- case AFP_RESULT_OBJECT_NOT_FOUND:
- g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
- _("File doesn't exist"));
- break;
- case AFP_RESULT_OBJECT_TYPE_ERR:
- g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE,
- _("File is a directory"));
- break;
- case AFP_RESULT_TOO_MANY_FILES_OPEN:
- g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_TOO_MANY_OPEN_FILES,
- _("Too many files open"));
- break;
- default:
- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Got error code: %d from server"), res_code);
- break;
- }
- return;
- }
-
- g_vfs_afp_reply_read_uint16 (reply, &file_bitmap);
- g_vfs_afp_reply_read_int16 (reply, &fork_refnum);
+ GVfsJobOpenForWrite *write_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
- g_object_unref (reply);
+ afp_handle->type = AFP_HANDLE_TYPE_REPLACE_FILE;
+ afp_handle->filename = g_strdup (write_job->filename);
+ afp_handle->tmp_filename = g_strdup (g_object_get_data (G_OBJECT (job), "TempFilename"));
- afp_handle = afp_handle_new (fork_refnum);
+ g_vfs_job_open_for_write_set_handle (write_job, (GVfsBackendHandle) afp_handle);
+ g_vfs_job_open_for_write_set_can_seek (write_job, TRUE);
+ g_vfs_job_open_for_write_set_initial_offset (write_job, 0);
- cb = g_object_get_data (G_OBJECT (job), "OpenForkCallback");
- cb (job, afp_handle);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
}
static void
-open_fork (GVfsBackendAfp *afp_backend,
- GVfsJob *job,
- const char *filename,
- guint16 access_mode,
- OpenForkCallback cb)
+replace_cb (GVfsJob *job)
{
- GVfsAfpCommand *comm;
-
- if (is_root (filename))
- {
- g_vfs_job_failed_literal (job, G_IO_ERROR,
- G_IO_ERROR_NOT_REGULAR_FILE,
- _("File is a directory"));
- return;
- }
-
- comm = g_vfs_afp_command_new (AFP_COMMAND_OPEN_FORK);
- /* data fork */
- g_vfs_afp_command_put_byte (comm, 0);
+ GVfsJobOpenForWrite *owjob = G_VFS_JOB_OPEN_FOR_WRITE (job);
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (owjob->backend);
- /* Volume ID */
- g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
- /* Directory ID */
- g_vfs_afp_command_put_uint32 (comm, 2);
-
- /* Bitmap */
- g_vfs_afp_command_put_uint16 (comm, 0);
+ guint16 access_mode;
+ char *tmp_filename;
- /* AccessMode */
- g_vfs_afp_command_put_uint16 (comm, access_mode);
+ access_mode = AFP_ACCESS_MODE_WRITE_BIT;
+ tmp_filename = g_object_get_data (G_OBJECT (job), "TempFilename");
+ open_fork (afp_backend, job, tmp_filename, access_mode,
+ replace_open_fork_cb);
+}
- /* Pathname */
- put_pathname (comm, filename);
+static gboolean
+try_replace (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
- g_object_set_data (G_OBJECT (job), "OpenForkCallback", cb);
+ char *tmp_filename;
- g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
- open_fork_cb,
- G_VFS_JOB (job)->cancellable, job);
- g_object_unref (comm);
+ if (make_backup)
+ {
+ /* FIXME: implement! */
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_CANT_CREATE_BACKUP,
+ _("backups not supported yet"));
+ return TRUE;
+ }
- return;
+ tmp_filename = g_strdup_printf ("%s.tmp", filename);
+ g_object_set_data_full (G_OBJECT (job), "TempFilename", tmp_filename, g_free);
+ create_file (afp_backend, G_VFS_JOB (job), tmp_filename, TRUE, replace_cb);
+
+ return TRUE;
}
static void
@@ -1050,6 +1251,8 @@ create_open_fork_cb (GVfsJob *job,
{
GVfsJobOpenForWrite *write_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
+ afp_handle->type = AFP_HANDLE_TYPE_CREATE_FILE;
+
g_vfs_job_open_for_write_set_handle (write_job, (GVfsBackendHandle) afp_handle);
g_vfs_job_open_for_write_set_can_seek (write_job, TRUE);
g_vfs_job_open_for_write_set_initial_offset (write_job, 0);
@@ -1058,67 +1261,18 @@ create_open_fork_cb (GVfsJob *job,
}
static void
-create_cb (GVfsAfpConnection *afp_connection,
- GVfsAfpReply *reply,
- GError *error,
- gpointer user_data)
+create_cb (GVfsJob *job)
{
- GVfsJobOpenForWrite *job = G_VFS_JOB_OPEN_FOR_WRITE (user_data);
- GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (job->backend);
+ GVfsJobOpenForWrite *owjob = G_VFS_JOB_OPEN_FOR_WRITE (job);
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (owjob->backend);
- AfpResultCode res_code;
guint16 access_mode;
-
- if (!reply)
- {
- g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
- return;
- }
-
- res_code = g_vfs_afp_reply_get_result_code (reply);
- if (res_code != AFP_RESULT_NO_ERROR)
- {
- g_object_unref (reply);
-
- switch (res_code)
- {
- case AFP_RESULT_ACCESS_DENIED:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- _("Access denied"));
- break;
- case AFP_RESULT_DISK_FULL:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NO_SPACE,
- _("Not enough space on volume"));
- break;
- case AFP_RESULT_FILE_BUSY:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS,
- _("Target file is open"));
- break;
- case AFP_RESULT_OBJECT_EXISTS:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS,
- _("Target file already exists"));
- break;
- case AFP_RESULT_OBJECT_NOT_FOUND:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
- _("Ancestor directory doesn't exist"));
- break;
- case AFP_RESULT_VOL_LOCKED:
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- _("Volume is read-only"));
- break;
- default:
- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Got error code: %d from server"), res_code);
- break;
- }
- return;
- }
access_mode = AFP_ACCESS_MODE_WRITE_BIT;
- open_fork (afp_backend, G_VFS_JOB (job), job->filename, access_mode,
+ open_fork (afp_backend, job, owjob->filename, access_mode,
create_open_fork_cb);
}
-
+
static gboolean
try_create (GVfsBackend *backend,
GVfsJobOpenForWrite *job,
@@ -1127,31 +1281,18 @@ try_create (GVfsBackend *backend,
{
GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
- GVfsAfpCommand *comm;
-
- comm = g_vfs_afp_command_new (AFP_COMMAND_CREATE_FILE);
- /* soft create */
- 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);
-
- /* Pathname */
- put_pathname (comm, filename);
-
- g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm, create_cb,
- G_VFS_JOB (job)->cancellable, job);
- g_object_unref (comm);
+ create_file (afp_backend, G_VFS_JOB (job), filename, FALSE, create_cb);
return TRUE;
}
static void
-open_for_read_cb (GVfsJob *job,
- AfpHandle *afp_handle)
+read_open_fork_cb (GVfsJob *job,
+ AfpHandle *afp_handle)
{
GVfsJobOpenForRead *read_job = G_VFS_JOB_OPEN_FOR_READ (job);
+
+ afp_handle->type = AFP_HANDLE_TYPE_READ_FILE;
g_vfs_job_open_for_read_set_handle (read_job, (GVfsBackendHandle) afp_handle);
g_vfs_job_open_for_read_set_can_seek (read_job, TRUE);
@@ -1169,7 +1310,7 @@ try_open_for_read (GVfsBackend *backend,
access_mode = AFP_ACCESS_MODE_READ_BIT;
- open_fork (afp_backend, G_VFS_JOB (job), filename, access_mode, open_for_read_cb);
+ open_fork (afp_backend, G_VFS_JOB (job), filename, access_mode, read_open_fork_cb);
return TRUE;
}
@@ -1787,6 +1928,7 @@ g_vfs_backend_afp_class_init (GVfsBackendAfpClass *klass)
backend_class->try_read = try_read;
backend_class->try_seek_on_read = try_seek_on_read;
backend_class->try_create = try_create;
+ backend_class->try_replace = try_replace;
backend_class->try_write = try_write;
backend_class->try_close_write = try_close_write;
backend_class->try_delete = try_delete;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]