diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2011-11-22 23:46:10 +0100 |
---|---|---|
committer | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2012-01-22 09:47:27 +0100 |
commit | a1af02aee5d076e042502569d59d350d03839baf (patch) | |
tree | 00471f8f5b65cc020f08d656fea13e1d37703a6c | |
parent | 35cf2feab74059065b23073b8bb3bcd8a3786bbf (diff) | |
download | gvfs-a1af02aee5d076e042502569d59d350d03839baf.tar.gz |
afp: Add support for making backups when server has support for FPExchangeFiles
Instead of deleting the temporary file after doing the FPExchangeFiles call we
rename the temporary file to "~filename" since it holds the old contents of the
file.
-rw-r--r-- | daemon/gvfsbackendafp.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c index 796863a9..d35ee7a6 100644 --- a/daemon/gvfsbackendafp.c +++ b/daemon/gvfsbackendafp.c @@ -194,9 +194,11 @@ typedef struct /* Used if type == AFP_HANDLE_TYPE_REPLACE_FILE_DIRECT */ gint64 size; - + + /* Used if type == AFP_HANDLE_TYPE_REPLACE_FILE_TEMP */ char *filename; char *tmp_filename; + gboolean make_backup; } AfpHandle; static AfpHandle * @@ -2676,20 +2678,49 @@ close_replace_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, g g_object_unref (info); } - + static void -close_replace_close_fork_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +close_replace_delete_backup_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object); AfpHandle *afp_handle = (AfpHandle *)user_data; - /* Delete temporary file */ - delete (afp_backend, afp_handle->tmp_filename, NULL, NULL, NULL); + char *backup_name; + + /* We ignore all errors and just try to rename the temporary file anyway */ + backup_name = g_strconcat (afp_handle->filename, "~", NULL); + move_and_rename (afp_backend, afp_handle->tmp_filename, backup_name, NULL, + NULL, NULL); afp_handle_free (afp_handle); } static void +close_replace_close_fork_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object); + AfpHandle *afp_handle = (AfpHandle *)user_data; + + if (afp_handle->make_backup) + { + char *backup_name = g_strconcat (afp_handle->filename, "~", NULL); + + /* Delete old backup */ + delete (afp_backend, backup_name, NULL, close_replace_delete_backup_cb, + afp_handle); + g_free (backup_name); + } + + else + { + /* Delete temporary file */ + delete (afp_backend, afp_handle->tmp_filename, NULL, NULL, NULL); + + afp_handle_free (afp_handle); + } +} + +static void close_replace_exchange_files_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object); @@ -2710,7 +2741,7 @@ close_replace_exchange_files_cb (GObject *source_object, GAsyncResult *res, gpoi return; } - /* Close fork and remove the temporary file even if the exchange failed */ + /* Close fork and remove/rename the temporary file even if the exchange failed */ close_fork (afp_backend, afp_handle->fork_refnum, G_VFS_JOB (job)->cancellable, close_replace_close_fork_cb, job->handle); @@ -3029,6 +3060,7 @@ replace_open_fork_cb (GObject *source_object, GAsyncResult *res, gpointer user_d afp_handle->type = AFP_HANDLE_TYPE_REPLACE_FILE_TEMP; afp_handle->filename = g_strdup (job->filename); afp_handle->tmp_filename = g_strdup (tmp_filename); + afp_handle->make_backup = job->make_backup; } else afp_handle->type = AFP_HANDLE_TYPE_REPLACE_FILE_DIRECT; @@ -3060,9 +3092,19 @@ replace_create_tmp_file_cb (GObject *source_object, GAsyncResult *res, gpointer * so we try to write directly to the file */ else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) { - g_object_set_data (G_OBJECT (job), "TempFilename", NULL); - open_fork (afp_backend, job->filename, AFP_ACCESS_MODE_WRITE_BIT, 0, - G_VFS_JOB (job)->cancellable, replace_open_fork_cb, job); + /* FIXME: We don't support making backups when we can't use FPExchangeFiles */ + if (job->make_backup) + { + g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("backups not supported")); + } + else + { + g_object_set_data (G_OBJECT (job), "TempFilename", NULL); + open_fork (afp_backend, job->filename, AFP_ACCESS_MODE_WRITE_BIT, 0, + G_VFS_JOB (job)->cancellable, replace_open_fork_cb, job); + } } else @@ -3145,8 +3187,18 @@ replace_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, gpointe { if (afp_backend->vol_attrs_bitmap & AFP_VOLUME_ATTRIBUTES_BITMAP_NO_EXCHANGE_FILES) { - open_fork (afp_backend, job->filename, AFP_ACCESS_MODE_WRITE_BIT, 0, - G_VFS_JOB (job)->cancellable, replace_open_fork_cb, job); + /* FIXME: We don't support making backups when we can't use FPExchangeFiles */ + if (job->make_backup) + { + g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("backups not supported")); + } + else + { + open_fork (afp_backend, job->filename, AFP_ACCESS_MODE_WRITE_BIT, 0, + G_VFS_JOB (job)->cancellable, replace_open_fork_cb, job); + } } else replace_create_tmp_file (afp_backend, job); @@ -3165,15 +3217,6 @@ try_replace (GVfsBackend *backend, { GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend); - 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; - } - get_filedir_parms (afp_backend, filename, AFP_FILE_BITMAP_MOD_DATE_BIT, 0, G_VFS_JOB (job)->cancellable, replace_get_filedir_parms_cb, job); |