summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2008-12-12 07:42:32 +0000
committerRyan Lortie <ryanl@src.gnome.org>2008-12-12 07:42:32 +0000
commit5eec790d20e0e4e30af57e82147f0c211b89a472 (patch)
tree05fc029685fcb794b2c6f67994c06d86a94c66c2
parent1394c3a853596f9a08275e49f8b70f2a4174738f (diff)
downloadgvfs-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--ChangeLog7
-rw-r--r--daemon/gvfsbackendtrash.c65
-rw-r--r--daemon/trashlib/trashitem.c60
-rw-r--r--daemon/trashlib/trashitem.h3
4 files changed, 112 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 35a20db1..12f054ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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_ */