summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kellner <gicmo@src.gnome.org>2008-09-01 21:22:15 +0000
committerChristian Kellner <gicmo@src.gnome.org>2008-09-01 21:22:15 +0000
commit178eb46a36ceb9a1b4aa6e9fba2e3b72d52e5754 (patch)
tree33da89988c49acbe85b8e20d09b33e547c0c3c15
parent7afb8438c184839e43f81341578e8c6c40d5883f (diff)
downloadgvfs-178eb46a36ceb9a1b4aa6e9fba2e3b72d52e5754.tar.gz
Add Push and Pull. Remove Upload. (#550100)
svn path=/trunk/; revision=1922
-rw-r--r--ChangeLog34
-rw-r--r--client/gdaemonfile.c192
-rw-r--r--common/gvfsdaemonprotocol.h3
-rw-r--r--daemon/Makefile.am3
-rw-r--r--daemon/gvfsbackend.c11
-rw-r--r--daemon/gvfsbackend.h51
-rw-r--r--daemon/gvfsbackendburn.c27
-rw-r--r--daemon/gvfsbackendtrash.c81
-rw-r--r--daemon/gvfsjobpull.c217
-rw-r--r--daemon/gvfsjobpull.h67
-rw-r--r--daemon/gvfsjobpush.c (renamed from daemon/gvfsjobupload.c)92
-rw-r--r--daemon/gvfsjobpush.h (renamed from daemon/gvfsjobupload.h)35
12 files changed, 636 insertions, 177 deletions
diff --git a/ChangeLog b/ChangeLog
index fa832850..335a24ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,39 @@
2008-09-01 Christian Kellner <gicmo@gnome.org>
+ * daemon/gvfsjobpull.c:
+ * daemon/gvfsjobpull.h:
+ New daemon method to pull files from daemons to the local
+ file system.
+
+ * daemon/gvfsjobpush.c:
+ * daemon/gvfsjobpush.h:
+ New daemon method to push local files to daemons. (Replaces
+ Upload)
+
+ * daemon/gvfsjobupload.c:
+ * daemon/gvfsjobupload.h:
+ Replaced by Push.
+
+ * common/gvfsdaemonprotocol.h:
+ * daemon/Makefile.am:
+ * daemon/gvfsbackend.c:
+ * daemon/gvfsbackend.h:
+ Add Push and Pull. Remove Upload.
+
+ * client/gdaemonfile.c:
+ New transfer logic. In case of move try push/pull (with
+ remove_source set to TRUE) first then fallback. In case of copy
+ try push/pull first then fallback. Use the same logic for
+ both cases.
+
+ * daemon/gvfsbackendburn.c:
+ Port Upload to Push.
+
+ * daemon/gvfsbackendtrash.c:
+ Implement the Pull method. That should fix bug #529971
+
+2008-09-01 Christian Kellner <gicmo@gnome.org>
+
* monitor/hal/ghalvolume.c: (do_update_from_hal):
Use g_format_size_for_display for consistency.
Patch from Christian Persch <chpe@gnome.org>
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 87cc0c1a..1aab47f3 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -1940,47 +1940,52 @@ progress_callback_message (DBusConnection *connection,
}
static gboolean
-g_daemon_file_copy (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
+file_transfer (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
{
- GDaemonFile *daemon_source;
DBusMessage *reply;
- char *local_path;
char *obj_path, *dbus_obj_path;
dbus_uint32_t flags_dbus;
+ dbus_bool_t dbus_remove_source;
struct ProgressCallbackData data;
-
- if (!G_IS_DAEMON_FILE (destination))
+ char *local_path = NULL;
+ gboolean source_is_daemon;
+ gboolean dest_is_daemon;
+ gboolean native_transfer;
+
+ native_transfer = FALSE;
+ source_is_daemon = G_IS_DAEMON_FILE (source);
+ dest_is_daemon = G_IS_DAEMON_FILE (destination);
+
+ if (source_is_daemon && dest_is_daemon)
+ native_transfer = TRUE;
+ else if (dest_is_daemon && !source_is_daemon)
+ local_path = g_file_get_path (source);
+ else if (source_is_daemon && !dest_is_daemon)
+ local_path = g_file_get_path (destination);
+ else
{
- /* Fall back to default move */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Move not supported");
+ /* Fall back to default copy/move */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Operation not supported");
return FALSE;
}
- if (G_IS_DAEMON_FILE (source))
+ if (!native_transfer && local_path == NULL)
{
- daemon_source = G_DAEMON_FILE (source);
- local_path = NULL;
- }
- else
- {
- daemon_source = NULL;
- local_path = g_file_get_path (source);
+ /* This will cause the fallback code to be involved */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported, files on different mounts"));
+ return FALSE;
- if (local_path == NULL)
- {
- /* This will cause the fallback code to be involved */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Operation not supported, files on different mounts"));
- return FALSE;
- }
}
-
+
if (progress_callback)
{
obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path);
@@ -1997,30 +2002,52 @@ g_daemon_file_copy (GFile *source,
data.progress_callback_data = progress_callback_data;
flags_dbus = flags;
-
- if (daemon_source)
+ dbus_remove_source = remove_source;
+
+ if (native_transfer == TRUE)
+ {
+ const char *method_string;
+
+ if (remove_source == FALSE)
+ method_string = G_VFS_DBUS_MOUNT_OP_COPY;
+ else
+ method_string = G_VFS_DBUS_MOUNT_OP_MOVE;
+
+ reply = do_sync_2_path_call (source, destination,
+ method_string,
+ obj_path, progress_callback_message, &data,
+ NULL, cancellable, error,
+ DBUS_TYPE_UINT32, &flags_dbus,
+ DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
+ 0);
+ }
+ else if (dest_is_daemon == TRUE)
{
- reply = do_sync_2_path_call (source, destination,
- G_VFS_DBUS_MOUNT_OP_COPY,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- 0);
+ reply = do_sync_2_path_call (destination, NULL,
+ G_VFS_DBUS_MOUNT_OP_PUSH,
+ obj_path, progress_callback_message, &data,
+ NULL, cancellable, error,
+ G_DBUS_TYPE_CSTRING, &local_path,
+ DBUS_TYPE_UINT32, &flags_dbus,
+ DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
+ DBUS_TYPE_BOOLEAN, &dbus_remove_source,
+ 0);
}
else
{
- reply = do_sync_2_path_call (destination, NULL,
- G_VFS_DBUS_MOUNT_OP_UPLOAD,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- G_DBUS_TYPE_CSTRING, &local_path,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- 0);
- g_free (local_path);
+ reply = do_sync_2_path_call (source, NULL,
+ G_VFS_DBUS_MOUNT_OP_PULL,
+ obj_path, progress_callback_message, &data,
+ NULL, cancellable, error,
+ G_DBUS_TYPE_CSTRING, &local_path,
+ DBUS_TYPE_UINT32, &flags_dbus,
+ DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
+ DBUS_TYPE_BOOLEAN, &dbus_remove_source,
+ 0);
+
}
+ g_free (local_path);
g_free (obj_path);
if (reply == NULL)
@@ -2031,7 +2058,7 @@ g_daemon_file_copy (GFile *source,
}
static gboolean
-g_daemon_file_move (GFile *source,
+g_daemon_file_copy (GFile *source,
GFile *destination,
GFileCopyFlags flags,
GCancellable *cancellable,
@@ -2039,50 +2066,41 @@ g_daemon_file_move (GFile *source,
gpointer progress_callback_data,
GError **error)
{
- DBusMessage *reply;
- char *obj_path, *dbus_obj_path;
- dbus_uint32_t flags_dbus;
- struct ProgressCallbackData data;
-
- if (!G_IS_DAEMON_FILE (source) ||
- !G_IS_DAEMON_FILE (destination))
- {
- /* Fall back to default move */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Move not supported");
- return FALSE;
- }
-
- if (progress_callback)
- {
- obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path);
- dbus_obj_path = obj_path;
- }
- else
- {
- obj_path = NULL;
- /* Can't pass NULL obj path as arg */
- dbus_obj_path = "/org/gtk/vfs/void";
- }
+ gboolean result;
- data.progress_callback = progress_callback;
- data.progress_callback_data = progress_callback_data;
+ result = file_transfer (source,
+ destination,
+ flags,
+ FALSE,
+ cancellable,
+ progress_callback,
+ progress_callback_data,
+ error);
- flags_dbus = flags;
- reply = do_sync_2_path_call (source, destination,
- G_VFS_DBUS_MOUNT_OP_MOVE,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- 0);
+ return result;
+}
- g_free (obj_path);
+static gboolean
+g_daemon_file_move (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
+{
+ gboolean result;
- if (reply == NULL)
- return FALSE;
+ result = file_transfer (source,
+ destination,
+ flags,
+ TRUE,
+ cancellable,
+ progress_callback,
+ progress_callback_data,
+ error);
- dbus_message_unref (reply);
- return TRUE;
+ return result;
}
static GFileMonitor*
diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h
index aa41f981..0e73c52e 100644
--- a/common/gvfsdaemonprotocol.h
+++ b/common/gvfsdaemonprotocol.h
@@ -42,8 +42,9 @@ G_BEGIN_DECLS
#define G_VFS_DBUS_MOUNT_OP_MAKE_DIRECTORY "MakeDirectory"
#define G_VFS_DBUS_MOUNT_OP_MAKE_SYMBOLIC_LINK "MakeSymbolicLink"
#define G_VFS_DBUS_MOUNT_OP_COPY "Copy"
-#define G_VFS_DBUS_MOUNT_OP_UPLOAD "Upload"
#define G_VFS_DBUS_MOUNT_OP_MOVE "Move"
+#define G_VFS_DBUS_MOUNT_OP_PUSH "Push"
+#define G_VFS_DBUS_MOUNT_OP_PULL "Pull"
#define G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE "SetAttribute"
#define G_VFS_DBUS_MOUNT_OP_QUERY_SETTABLE_ATTRIBUTES "QuerySettableAttributes"
#define G_VFS_DBUS_MOUNT_OP_QUERY_WRITABLE_NAMESPACES "QueryWritableNamespaces"
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 9a5be5ba..57e03080 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -134,8 +134,9 @@ libdaemon_la_SOURCES = \
gvfsjobtrash.c gvfsjobtrash.h \
gvfsjobdelete.c gvfsjobdelete.h \
gvfsjobcopy.c gvfsjobcopy.h \
- gvfsjobupload.c gvfsjobupload.h \
gvfsjobmove.c gvfsjobmove.h \
+ gvfsjobpush.c gvfsjobpush.h \
+ gvfsjobpull.c gvfsjobpull.h \
gvfsjobmakedirectory.c gvfsjobmakedirectory.h \
gvfsjobmakesymlink.c gvfsjobmakesymlink.h \
gvfsjobsetattribute.c gvfsjobsetattribute.h \
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index ddce08cc..4e6e9a53 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -48,9 +48,10 @@
#include <gvfsjobmakedirectory.h>
#include <gvfsjobmakesymlink.h>
#include <gvfsjobcreatemonitor.h>
-#include <gvfsjobupload.h>
#include <gvfsjobcopy.h>
#include <gvfsjobmove.h>
+#include <gvfsjobpush.h>
+#include <gvfsjobpull.h>
#include <gvfsjobsetattribute.h>
#include <gvfsjobqueryattributes.h>
#include <gdbusutils.h>
@@ -534,8 +535,12 @@ backend_dbus_handler (DBusConnection *connection,
job = g_vfs_job_copy_new (connection, message, backend);
else if (dbus_message_is_method_call (message,
G_VFS_DBUS_MOUNT_INTERFACE,
- G_VFS_DBUS_MOUNT_OP_UPLOAD))
- job = g_vfs_job_upload_new (connection, message, backend);
+ G_VFS_DBUS_MOUNT_OP_PUSH))
+ job = g_vfs_job_push_new (connection, message, backend);
+ else if (dbus_message_is_method_call (message,
+ G_VFS_DBUS_MOUNT_INTERFACE,
+ G_VFS_DBUS_MOUNT_OP_PULL))
+ job = g_vfs_job_pull_new (connection, message, backend);
else if (dbus_message_is_method_call (message,
G_VFS_DBUS_MOUNT_INTERFACE,
G_VFS_DBUS_MOUNT_OP_MOVE))
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index d8c78675..e47f3680 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -64,8 +64,9 @@ typedef struct _GVfsJobDelete GVfsJobDelete;
typedef struct _GVfsJobMakeDirectory GVfsJobMakeDirectory;
typedef struct _GVfsJobMakeSymlink GVfsJobMakeSymlink;
typedef struct _GVfsJobCopy GVfsJobCopy;
-typedef struct _GVfsJobUpload GVfsJobUpload;
typedef struct _GVfsJobMove GVfsJobMove;
+typedef struct _GVfsJobPush GVfsJobPush;
+typedef struct _GVfsJobPull GVfsJobPull;
typedef struct _GVfsJobSetAttribute GVfsJobSetAttribute;
typedef struct _GVfsJobQueryAttributes GVfsJobQueryAttributes;
typedef struct _GVfsJobCreateMonitor GVfsJobCreateMonitor;
@@ -297,21 +298,7 @@ struct _GVfsBackendClass
GFileCopyFlags flags,
GFileProgressCallback progress_callback,
gpointer progress_callback_data);
- void (*upload) (GVfsBackend *backend,
- GVfsJobUpload *job,
- const char *destination,
- const char *local_path,
- GFileCopyFlags flags,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data);
- gboolean (*try_upload) (GVfsBackend *backend,
- GVfsJobUpload *job,
- const char *destination,
- const char *local_path,
- GFileCopyFlags flags,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data);
- void (*move) (GVfsBackend *backend,
+ void (*move) (GVfsBackend *backend,
GVfsJobMove *job,
const char *source,
const char *destination,
@@ -325,6 +312,38 @@ struct _GVfsBackendClass
GFileCopyFlags flags,
GFileProgressCallback progress_callback,
gpointer progress_callback_data);
+ void (*push) (GVfsBackend *backend,
+ GVfsJobPush *job,
+ const char *destination,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data);
+ gboolean (*try_push) (GVfsBackend *backend,
+ GVfsJobPush *job,
+ const char *destination,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data);
+ void (*pull) (GVfsBackend *backend,
+ GVfsJobPull *job,
+ const char *source,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data);
+ gboolean (*try_pull) (GVfsBackend *backend,
+ GVfsJobPull *job,
+ const char *source,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data);
void (*set_attribute) (GVfsBackend *backend,
GVfsJobSetAttribute *set_attribute,
const char *filename,
diff --git a/daemon/gvfsbackendburn.c b/daemon/gvfsbackendburn.c
index 38904a21..e9ed3da5 100644
--- a/daemon/gvfsbackendburn.c
+++ b/daemon/gvfsbackendburn.c
@@ -809,18 +809,27 @@ try_set_display_name (GVfsBackend *backend,
}
static gboolean
-try_upload (GVfsBackend *backend,
- GVfsJobUpload *job,
- const char *destination,
- const char *local_path,
- GFileCopyFlags flags,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data)
+try_push (GVfsBackend *backend,
+ GVfsJobPush *job,
+ const char *destination,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data)
{
VirtualNode *file, *dir;
struct stat stat_buf;
char *dirname, *basename;
-
+
+ if (remove_source)
+ {
+ /* Fallback to copy & delete for now, fix that up later */
+ g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported by backend"));
+ return TRUE;
+ }
+
if (g_stat (local_path, &stat_buf) == -1)
{
int errsv = errno;
@@ -959,7 +968,7 @@ g_vfs_backend_burn_class_init (GVfsBackendBurnClass *klass)
backend_class->try_create_dir_monitor = try_create_dir_monitor;
backend_class->try_make_directory = try_make_directory;
backend_class->try_set_display_name = try_set_display_name;
- backend_class->try_upload = try_upload;
+ backend_class->try_push = try_push;
backend_class->try_delete = try_delete;
backend_class->read = do_read;
backend_class->seek_on_read = do_seek_on_read;
diff --git a/daemon/gvfsbackendtrash.c b/daemon/gvfsbackendtrash.c
index 5c854a36..0b99e21b 100644
--- a/daemon/gvfsbackendtrash.c
+++ b/daemon/gvfsbackendtrash.c
@@ -1761,6 +1761,86 @@ do_create_file_monitor (GVfsBackend *backend,
}
static void
+do_pull (GVfsBackend *backend,
+ GVfsJobPull *job,
+ const char *filename,
+ const char *local_destination,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data)
+{
+ GFile *dst_file;
+ GFile *src_file;
+ char *trashdir, *topdir, *relative_path, *trashfile;
+ char *src_path;
+ gboolean res;
+ GError *error = NULL;
+
+ res = decode_path (filename, &trashdir, &trashfile, &relative_path, &topdir);
+
+ if (res == FALSE)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_IS_DIRECTORY,
+ _("Can't open directory"));
+ return;
+ }
+
+ dst_file = g_file_new_for_path (local_destination);
+
+ src_path = g_build_filename (trashdir, "files", trashfile, relative_path, NULL);
+ src_file = g_file_new_for_path (src_path);
+
+ if (remove_source)
+ res = g_file_move (src_file,
+ dst_file,
+ flags,
+ G_VFS_JOB (job)->cancellable,
+ progress_callback,
+ progress_callback_data,
+ &error);
+ else
+ res = g_file_copy (src_file,
+ dst_file,
+ flags,
+ G_VFS_JOB (job)->cancellable,
+ progress_callback,
+ progress_callback_data,
+ &error);
+
+ if (res == FALSE)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+ else
+ {
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ if (relative_path == NULL)
+ {
+ char *info_filename, *info_path;
+
+ info_filename = g_strconcat (trashfile, ".trashinfo", NULL);
+ info_path = g_build_filename (trashdir, "info", info_filename, NULL);
+ g_free (info_filename);
+ g_unlink (info_path);
+ g_free (info_path);
+ }
+ }
+
+ g_object_unref (src_file);
+ g_object_unref (dst_file);
+
+ g_free (trashdir);
+ g_free (trashfile);
+ g_free (relative_path);
+ g_free (topdir);
+}
+
+
+static void
g_vfs_backend_trash_class_init (GVfsBackendTrashClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -1778,4 +1858,5 @@ g_vfs_backend_trash_class_init (GVfsBackendTrashClass *klass)
backend_class->delete = do_delete;
backend_class->create_dir_monitor = do_create_dir_monitor;
backend_class->create_file_monitor = do_create_file_monitor;
+ backend_class->pull = do_pull;
}
diff --git a/daemon/gvfsjobpull.c b/daemon/gvfsjobpull.c
new file mode 100644
index 00000000..2eb12e4d
--- /dev/null
+++ b/daemon/gvfsjobpull.c
@@ -0,0 +1,217 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <strings.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <glib/gi18n.h>
+#include "gvfsjobpull.h"
+#include "gdbusutils.h"
+#include "gvfsdaemonprotocol.h"
+
+G_DEFINE_TYPE (GVfsJobPull, g_vfs_job_pull, G_VFS_TYPE_JOB_DBUS)
+
+static void run (GVfsJob *job);
+static gboolean try (GVfsJob *job);
+static DBusMessage *create_reply (GVfsJob *job,
+ DBusConnection *connection,
+ DBusMessage *message);
+
+static void
+g_vfs_job_pull_finalize (GObject *object)
+{
+ GVfsJobPull *job;
+
+ job = G_VFS_JOB_PULL (object);
+
+ g_free (job->local_path);
+ g_free (job->source);
+ g_free (job->callback_obj_path);
+
+ if (G_OBJECT_CLASS (g_vfs_job_pull_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_vfs_job_pull_parent_class)->finalize) (object);
+}
+
+static void
+g_vfs_job_pull_class_init (GVfsJobPullClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
+ GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
+
+ gobject_class->finalize = g_vfs_job_pull_finalize;
+ job_class->run = run;
+ job_class->try = try;
+ job_dbus_class->create_reply = create_reply;
+}
+
+static void
+g_vfs_job_pull_init (GVfsJobPull *job)
+{
+}
+
+GVfsJob *
+g_vfs_job_pull_new (DBusConnection *connection,
+ DBusMessage *message,
+ GVfsBackend *backend)
+{
+ GVfsJobPull *job;
+ DBusMessage *reply;
+ DBusError derror;
+ int path1_len, path2_len;
+ const char *path1_data, *path2_data, *callback_obj_path;
+ dbus_uint32_t flags;
+ dbus_bool_t remove_source;
+
+ dbus_error_init (&derror);
+ if (!dbus_message_get_args (message, &derror,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &path1_data, &path1_len,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &path2_data, &path2_len,
+ DBUS_TYPE_UINT32, &flags,
+ DBUS_TYPE_OBJECT_PATH, &callback_obj_path,
+ DBUS_TYPE_BOOLEAN, &remove_source,
+ 0))
+ {
+ reply = dbus_message_new_error (message,
+ derror.name,
+ derror.message);
+ dbus_error_free (&derror);
+
+ dbus_connection_send (connection, reply, NULL);
+ return NULL;
+ }
+
+ job = g_object_new (G_VFS_TYPE_JOB_PULL,
+ "message", message,
+ "connection", connection,
+ NULL);
+
+ job->source = g_strndup (path1_data, path1_len);
+ job->local_path = g_strndup (path2_data, path2_len);
+ job->backend = backend;
+ job->flags = flags;
+ job->remove_source = remove_source;
+ g_print ("Remove Source: %s\n", remove_source ? "true" : "false");
+ if (strcmp (callback_obj_path, "/org/gtk/vfs/void") != 0)
+ job->callback_obj_path = g_strdup (callback_obj_path);
+
+ return G_VFS_JOB (job);
+}
+
+static void
+progress_callback (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
+{
+ GVfsJob *job = G_VFS_JOB (user_data);
+ GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);
+ GVfsJobPull *op_job = G_VFS_JOB_PULL (job);
+ dbus_uint64_t current_dbus, total_dbus;
+ DBusMessage *message;
+
+ g_print ("progress_callback %d/%d\n", (int)current_num_bytes, (int)total_num_bytes);
+
+ if (op_job->callback_obj_path == NULL)
+ return;
+
+ message =
+ dbus_message_new_method_call (dbus_message_get_sender (dbus_job->message),
+ op_job->callback_obj_path,
+ G_VFS_DBUS_PROGRESS_INTERFACE,
+ G_VFS_DBUS_PROGRESS_OP_PROGRESS);
+ dbus_message_set_no_reply (message, TRUE);
+
+ current_dbus = current_num_bytes;
+ total_dbus = total_num_bytes;
+ dbus_message_append_args (message,
+ DBUS_TYPE_UINT64, &current_dbus,
+ DBUS_TYPE_UINT64, &total_dbus,
+ 0);
+
+ /* Queues reply (threadsafely), actually sends it in mainloop */
+ dbus_connection_send (dbus_job->connection, message, NULL);
+ dbus_message_unref (message);
+}
+
+static void
+run (GVfsJob *job)
+{
+ GVfsJobPull *op_job = G_VFS_JOB_PULL (job);
+ GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
+
+ if (class->pull == NULL)
+ {
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported by backend"));
+ return;
+ }
+
+ class->pull (op_job->backend,
+ op_job,
+ op_job->source,
+ op_job->local_path,
+ op_job->flags,
+ op_job->remove_source,
+ progress_callback,
+ job);
+}
+
+static gboolean
+try (GVfsJob *job)
+{
+ GVfsJobPull *op_job = G_VFS_JOB_PULL (job);
+ GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
+
+ if (class->try_pull == NULL)
+ return FALSE;
+
+ return class->try_pull (op_job->backend,
+ op_job,
+ op_job->source,
+ op_job->local_path,
+ op_job->flags,
+ op_job->remove_source,
+ progress_callback,
+ job);
+}
+
+/* Might be called on an i/o thread */
+static DBusMessage *
+create_reply (GVfsJob *job,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return (message);
+
+ return reply;
+}
diff --git a/daemon/gvfsjobpull.h b/daemon/gvfsjobpull.h
new file mode 100644
index 00000000..bb080878
--- /dev/null
+++ b/daemon/gvfsjobpull.h
@@ -0,0 +1,67 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_VFS_JOB_PULL_H__
+#define __G_VFS_JOB_PULL_H__
+
+#include <gio/gio.h>
+#include <gvfsjob.h>
+#include <gvfsjobdbus.h>
+#include <gvfsbackend.h>
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_JOB_PULL (g_vfs_job_pull_get_type ())
+#define G_VFS_JOB_PULL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_PULL, GVfsJobPull))
+#define G_VFS_JOB_PULL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_PULL, GVfsJobPullClass))
+#define G_VFS_IS_JOB_PULL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_PULL))
+#define G_VFS_IS_JOB_PULL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_PULL))
+#define G_VFS_JOB_PULL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_PULL, GVfsJobPullClass))
+
+typedef struct _GVfsJobPullClass GVfsJobPullClass;
+
+struct _GVfsJobPull
+{
+ GVfsJobDBus parent_instance;
+
+ GVfsBackend *backend;
+ char *source;
+ char *local_path;
+ GFileCopyFlags flags;
+ char *callback_obj_path;
+ gboolean remove_source;
+};
+
+struct _GVfsJobPullClass
+{
+ GVfsJobDBusClass parent_class;
+};
+
+GType g_vfs_job_pull_get_type (void) G_GNUC_CONST;
+
+GVfsJob *g_vfs_job_pull_new (DBusConnection *connection,
+ DBusMessage *message,
+ GVfsBackend *backend);
+
+G_END_DECLS
+
+#endif /* __G_VFS_JOB_PULL_H__ */
diff --git a/daemon/gvfsjobupload.c b/daemon/gvfsjobpush.c
index 642643c2..c24b9d80 100644
--- a/daemon/gvfsjobupload.c
+++ b/daemon/gvfsjobpush.c
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -31,11 +31,11 @@
#include <glib.h>
#include <dbus/dbus.h>
#include <glib/gi18n.h>
-#include "gvfsjobupload.h"
+#include "gvfsjobpush.h"
#include "gdbusutils.h"
#include "gvfsdaemonprotocol.h"
-G_DEFINE_TYPE (GVfsJobUpload, g_vfs_job_upload, G_VFS_TYPE_JOB_DBUS)
+G_DEFINE_TYPE (GVfsJobPush, g_vfs_job_push, G_VFS_TYPE_JOB_DBUS)
static void run (GVfsJob *job);
static gboolean try (GVfsJob *job);
@@ -44,58 +44,60 @@ static DBusMessage *create_reply (GVfsJob *job,
DBusMessage *message);
static void
-g_vfs_job_upload_finalize (GObject *object)
+g_vfs_job_push_finalize (GObject *object)
{
- GVfsJobUpload *job;
+ GVfsJobPush *job;
+
+ job = G_VFS_JOB_PUSH (object);
- job = G_VFS_JOB_UPLOAD (object);
-
g_free (job->local_path);
g_free (job->destination);
g_free (job->callback_obj_path);
-
- if (G_OBJECT_CLASS (g_vfs_job_upload_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_vfs_job_upload_parent_class)->finalize) (object);
+
+ if (G_OBJECT_CLASS (g_vfs_job_push_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_vfs_job_push_parent_class)->finalize) (object);
}
static void
-g_vfs_job_upload_class_init (GVfsJobUploadClass *klass)
+g_vfs_job_push_class_init (GVfsJobPushClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
-
- gobject_class->finalize = g_vfs_job_upload_finalize;
+
+ gobject_class->finalize = g_vfs_job_push_finalize;
job_class->run = run;
job_class->try = try;
job_dbus_class->create_reply = create_reply;
}
static void
-g_vfs_job_upload_init (GVfsJobUpload *job)
+g_vfs_job_push_init (GVfsJobPush *job)
{
}
GVfsJob *
-g_vfs_job_upload_new (DBusConnection *connection,
+g_vfs_job_push_new (DBusConnection *connection,
DBusMessage *message,
GVfsBackend *backend)
{
- GVfsJobUpload *job;
+ GVfsJobPush *job;
DBusMessage *reply;
DBusError derror;
int path1_len, path2_len;
const char *path1_data, *path2_data, *callback_obj_path;
dbus_uint32_t flags;
-
+ dbus_bool_t remove_source;
+
dbus_error_init (&derror);
- if (!dbus_message_get_args (message, &derror,
+ if (!dbus_message_get_args (message, &derror,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
&path1_data, &path1_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
&path2_data, &path2_len,
DBUS_TYPE_UINT32, &flags,
DBUS_TYPE_OBJECT_PATH, &callback_obj_path,
+ DBUS_TYPE_BOOLEAN, &remove_source,
0))
{
reply = dbus_message_new_error (message,
@@ -107,7 +109,7 @@ g_vfs_job_upload_new (DBusConnection *connection,
return NULL;
}
- job = g_object_new (G_VFS_TYPE_JOB_UPLOAD,
+ job = g_object_new (G_VFS_TYPE_JOB_PUSH,
"message", message,
"connection", connection,
NULL);
@@ -116,9 +118,11 @@ g_vfs_job_upload_new (DBusConnection *connection,
job->local_path = g_strndup (path2_data, path2_len);
job->backend = backend;
job->flags = flags;
+ job->remove_source = remove_source;
+ g_print ("Remove Source: %s\n", remove_source ? "true" : "false");
if (strcmp (callback_obj_path, "/org/gtk/vfs/void") != 0)
job->callback_obj_path = g_strdup (callback_obj_path);
-
+
return G_VFS_JOB (job);
}
@@ -129,7 +133,7 @@ progress_callback (goffset current_num_bytes,
{
GVfsJob *job = G_VFS_JOB (user_data);
GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);
- GVfsJobUpload *op_job = G_VFS_JOB_UPLOAD (job);
+ GVfsJobPush *op_job = G_VFS_JOB_PUSH (job);
dbus_uint64_t current_dbus, total_dbus;
DBusMessage *message;
@@ -137,7 +141,7 @@ progress_callback (goffset current_num_bytes,
if (op_job->callback_obj_path == NULL)
return;
-
+
message =
dbus_message_new_method_call (dbus_message_get_sender (dbus_job->message),
op_job->callback_obj_path,
@@ -160,41 +164,43 @@ progress_callback (goffset current_num_bytes,
static void
run (GVfsJob *job)
{
- GVfsJobUpload *op_job = G_VFS_JOB_UPLOAD (job);
+ GVfsJobPush *op_job = G_VFS_JOB_PUSH (job);
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
- if (class->upload == NULL)
+ if (class->push == NULL)
{
g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Operation not supported by backend"));
return;
}
-
- class->upload (op_job->backend,
- op_job,
- op_job->destination,
- op_job->local_path,
- op_job->flags,
- progress_callback,
- job);
+
+ class->push (op_job->backend,
+ op_job,
+ op_job->destination,
+ op_job->local_path,
+ op_job->flags,
+ op_job->remove_source,
+ progress_callback,
+ job);
}
static gboolean
try (GVfsJob *job)
{
- GVfsJobUpload *op_job = G_VFS_JOB_UPLOAD (job);
+ GVfsJobPush *op_job = G_VFS_JOB_PUSH (job);
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
- if (class->try_upload == NULL)
+ if (class->try_push == NULL)
return FALSE;
-
- return class->try_upload (op_job->backend,
- op_job,
- op_job->destination,
- op_job->local_path,
- op_job->flags,
- progress_callback,
- job);
+
+ return class->try_push (op_job->backend,
+ op_job,
+ op_job->destination,
+ op_job->local_path,
+ op_job->flags,
+ op_job->remove_source,
+ progress_callback,
+ job);
}
/* Might be called on an i/o thread */
@@ -206,6 +212,6 @@ create_reply (GVfsJob *job,
DBusMessage *reply;
reply = dbus_message_new_method_return (message);
-
+
return reply;
}
diff --git a/daemon/gvfsjobupload.h b/daemon/gvfsjobpush.h
index f72510d2..c7aabcba 100644
--- a/daemon/gvfsjobupload.h
+++ b/daemon/gvfsjobpush.h
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -20,8 +20,8 @@
* Author: Alexander Larsson <alexl@redhat.com>
*/
-#ifndef __G_VFS_JOB_UPLOAD_H__
-#define __G_VFS_JOB_UPLOAD_H__
+#ifndef __G_VFS_JOB_PUSH_H__
+#define __G_VFS_JOB_PUSH_H__
#include <gio/gio.h>
#include <gvfsjob.h>
@@ -30,16 +30,16 @@
G_BEGIN_DECLS
-#define G_VFS_TYPE_JOB_UPLOAD (g_vfs_job_upload_get_type ())
-#define G_VFS_JOB_UPLOAD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_UPLOAD, GVfsJobUpload))
-#define G_VFS_JOB_UPLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_UPLOAD, GVfsJobUploadClass))
-#define G_VFS_IS_JOB_UPLOAD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_UPLOAD))
-#define G_VFS_IS_JOB_UPLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_UPLOAD))
-#define G_VFS_JOB_UPLOAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_UPLOAD, GVfsJobUploadClass))
+#define G_VFS_TYPE_JOB_PUSH (g_vfs_job_push_get_type ())
+#define G_VFS_JOB_PUSH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_PUSH, GVfsJobPush))
+#define G_VFS_JOB_PUSH_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_PUSH, GVfsJobPushClass))
+#define G_VFS_IS_JOB_PUSH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_PUSH))
+#define G_VFS_IS_JOB_PUSH_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_PUSH))
+#define G_VFS_JOB_PUSH_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_PUSH, GVfsJobPushClass))
-typedef struct _GVfsJobUploadClass GVfsJobUploadClass;
+typedef struct _GVfsJobPushClass GVfsJobPushClass;
-struct _GVfsJobUpload
+struct _GVfsJobPush
{
GVfsJobDBus parent_instance;
@@ -48,19 +48,20 @@ struct _GVfsJobUpload
char *local_path;
GFileCopyFlags flags;
char *callback_obj_path;
+ gboolean remove_source;
};
-struct _GVfsJobUploadClass
+struct _GVfsJobPushClass
{
GVfsJobDBusClass parent_class;
};
-GType g_vfs_job_upload_get_type (void) G_GNUC_CONST;
+GType g_vfs_job_push_get_type (void) G_GNUC_CONST;
-GVfsJob *g_vfs_job_upload_new (DBusConnection *connection,
- DBusMessage *message,
- GVfsBackend *backend);
+GVfsJob *g_vfs_job_push_new (DBusConnection *connection,
+ DBusMessage *message,
+ GVfsBackend *backend);
G_END_DECLS
-#endif /* __G_VFS_JOB_UPLOAD_H__ */
+#endif /* __G_VFS_JOB_PUSH_H__ */