diff options
author | Ryan Lortie <desrt@desrt.ca> | 2008-12-12 07:42:32 +0000 |
---|---|---|
committer | Ryan Lortie <ryanl@src.gnome.org> | 2008-12-12 07:42:32 +0000 |
commit | 5eec790d20e0e4e30af57e82147f0c211b89a472 (patch) | |
tree | 05fc029685fcb794b2c6f67994c06d86a94c66c2 | |
parent | 1394c3a853596f9a08275e49f8b70f2a4174738f (diff) | |
download | gvfs-5eec790d20e0e4e30af57e82147f0c211b89a472.tar.gz |
Implement pull support on trash backend.
2008-12-11 Ryan Lortie <desrt@desrt.ca>
Implement pull support on trash backend.
* daemon/trashlib/trashitem.[ch]: add support for restoring items
* daemon/gvfsbackendtrash.c: implement pull
svn path=/trunk/; revision=2133
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | daemon/gvfsbackendtrash.c | 65 | ||||
-rw-r--r-- | daemon/trashlib/trashitem.c | 60 | ||||
-rw-r--r-- | daemon/trashlib/trashitem.h | 3 |
4 files changed, 112 insertions, 23 deletions
@@ -1,5 +1,12 @@ 2008-12-11 Ryan Lortie <desrt@desrt.ca> + Implement pull support on trash backend. + + * daemon/trashlib/trashitem.[ch]: add support for restoring items + * daemon/gvfsbackendtrash.c: implement pull + +2008-12-11 Ryan Lortie <desrt@desrt.ca> + New trash:/ backend. * daemon/trashlib: implementation of the reader side of the fd.o diff --git a/daemon/gvfsbackendtrash.c b/daemon/gvfsbackendtrash.c index b4b5916a..be674716 100644 --- a/daemon/gvfsbackendtrash.c +++ b/daemon/gvfsbackendtrash.c @@ -367,6 +367,70 @@ trash_backend_delete (GVfsBackend *vfs_backend, return TRUE; } +static gboolean +trash_backend_pull (GVfsBackend *vfs_backend, + GVfsJobPull *job, + const gchar *source, + const gchar *local_path, + GFileCopyFlags flags, + gboolean remove_source, + GFileProgressCallback progress_callback, + gpointer progress_callback_data) +{ + GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); + GError *error = NULL; + + if (source[1] == '\0') + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Can't pull trash")); + else + { + gboolean is_toplevel; + TrashItem *item; + GFile *real; + + real = trash_backend_get_file (backend, source, &item, + &is_toplevel, &error); + + if (real) + { + if (remove_source && !is_toplevel) + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, + _("Items in the trash may not be modified")); + + else + { + GFile *destination; + gboolean it_worked; + + destination = g_file_new_for_path (local_path); + + if (remove_source) + it_worked = trash_item_restore (item, destination, &error); + else + it_worked = g_file_copy (real, destination, flags, + NULL, NULL, NULL, &error); + + g_object_unref (destination); + + if (it_worked) + { + g_vfs_job_succeeded (G_VFS_JOB (job)); + + return TRUE; + } + } + + trash_item_unref (item); + } + + } + + g_vfs_job_failed_from_error (G_VFS_JOB (job), error); + + return TRUE; +} + static void trash_backend_add_info (TrashItem *item, GFileInfo *info, @@ -717,6 +781,7 @@ g_vfs_backend_trash_class_init (GVfsBackendTrashClass *class) backend_class->try_query_fs_info = trash_backend_query_fs_info; backend_class->try_enumerate = trash_backend_enumerate; backend_class->try_delete = trash_backend_delete; + backend_class->try_pull = trash_backend_pull; backend_class->try_create_dir_monitor = trash_backend_create_dir_monitor; backend_class->try_create_file_monitor = trash_backend_create_file_monitor; } diff --git a/daemon/trashlib/trashitem.c b/daemon/trashlib/trashitem.c index dc01a929..5e32850c 100644 --- a/daemon/trashlib/trashitem.c +++ b/daemon/trashlib/trashitem.c @@ -479,30 +479,9 @@ trash_item_delete (TrashItem *item, g_sprintf (buffer, "%u", unique + i); temp_name = g_file_get_child (expunged, buffer); - if (g_file_move (item->file, temp_name, - G_FILE_COPY_OVERWRITE | - G_FILE_COPY_NOFOLLOW_SYMLINKS | - G_FILE_COPY_NO_FALLBACK_FOR_MOVE, - NULL, NULL, NULL, NULL)) + /* "restore" the item into the expunged folder */ + if (trash_item_restore (item, temp_name, NULL)) { - g_static_rw_lock_writer_lock (&item->root->lock); - g_hash_table_remove (item->root->item_table, item->escaped_name); - g_static_rw_lock_writer_unlock (&item->root->lock); - - { - GFile *trashinfo; - gchar *basename; - gchar *relname; - - basename = g_file_get_basename (item->file); - relname = g_strdup_printf ("../../info/%s.trashinfo", basename); - trashinfo = g_file_resolve_relative_path (item->file, relname); - g_free (basename); - g_free (relname); - - g_file_delete (trashinfo, NULL, NULL); - } - trash_expunge (expunged); success = TRUE; } @@ -520,3 +499,38 @@ trash_item_delete (TrashItem *item, return success; } + +gboolean +trash_item_restore (TrashItem *item, + GFile *dest, + GError **error) +{ + if (g_file_move (item->file, dest, + G_FILE_COPY_OVERWRITE | + G_FILE_COPY_NOFOLLOW_SYMLINKS | + G_FILE_COPY_NO_FALLBACK_FOR_MOVE, + NULL, NULL, NULL, NULL)) + { + g_static_rw_lock_writer_lock (&item->root->lock); + g_hash_table_remove (item->root->item_table, item->escaped_name); + g_static_rw_lock_writer_unlock (&item->root->lock); + + { + GFile *trashinfo; + gchar *basename; + gchar *relname; + + basename = g_file_get_basename (item->file); + relname = g_strdup_printf ("../../info/%s.trashinfo", basename); + trashinfo = g_file_resolve_relative_path (item->file, relname); + g_free (basename); + g_free (relname); + + g_file_delete (trashinfo, NULL, NULL); + } + + return TRUE; + } + + return FALSE; +} diff --git a/daemon/trashlib/trashitem.h b/daemon/trashlib/trashitem.h index 785ef8aa..0fe0938e 100644 --- a/daemon/trashlib/trashitem.h +++ b/daemon/trashlib/trashitem.h @@ -52,5 +52,8 @@ GFile *trash_item_get_file (TrashItem *item); /* delete a trash item (safe while holding a reference to it) */ gboolean trash_item_delete (TrashItem *item, GError **error); +gboolean trash_item_restore (TrashItem *item, + GFile *dest, + GError **error); #endif /* _trashitem_h_ */ |