diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index 9e055c2..8a1ae74 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -1939,50 +1939,71 @@ progress_callback_message (DBusConnection *connection, return DBUS_HANDLER_RESULT_HANDLED; } + static gboolean g_daemon_file_copy (GFile *source, - GFile *destination, - GFileCopyFlags flags, - GCancellable *cancellable, - GFileProgressCallback progress_callback, - gpointer progress_callback_data, - GError **error) + GFile *destination, + GFileCopyFlags flags, + 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; struct ProgressCallbackData data; + gboolean source_is_daemon; + gboolean dest_is_daemon; + gboolean can_copy; + gboolean can_upload; + gboolean can_download; - if (!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; - } + local_path = NULL; + can_copy = can_upload = can_download = FALSE; + source_is_daemon = G_IS_DAEMON_FILE (source); + dest_is_daemon = G_IS_DAEMON_FILE (destination); - if (G_IS_DAEMON_FILE (source)) + if (source_is_daemon && dest_is_daemon) { - daemon_source = G_DAEMON_FILE (source); - local_path = NULL; + can_copy = TRUE; } - else + else if (dest_is_daemon && !source_is_daemon) { - daemon_source = NULL; local_path = g_file_get_path (source); - 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 (local_path) + can_upload = TRUE; } - - if (progress_callback) + else if (source_is_daemon && !dest_is_daemon) + { + local_path = g_file_get_path (destination); + + if (local_path) + can_download = TRUE; + } + else { + /* This will cause the fallback code to be involved */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Copy not supported"); + return FALSE; + } + + + if (can_copy == FALSE && 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); dbus_obj_path = obj_path; } @@ -1998,29 +2019,40 @@ g_daemon_file_copy (GFile *source, flags_dbus = flags; - if (daemon_source) + if (can_copy) { 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); + 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); } - else + else if (can_upload) { 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); - } - + 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); + } + else if (can_download) + { + reply = do_sync_2_path_call (source, NULL, + G_VFS_DBUS_MOUNT_OP_DOWNLOAD, + 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); g_free (obj_path); if (reply == NULL) diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h index aa41f98..26d0622 100644 --- a/common/gvfsdaemonprotocol.h +++ b/common/gvfsdaemonprotocol.h @@ -43,6 +43,7 @@ G_BEGIN_DECLS #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_DOWNLOAD "Download" #define G_VFS_DBUS_MOUNT_OP_MOVE "Move" #define G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE "SetAttribute" #define G_VFS_DBUS_MOUNT_OP_QUERY_SETTABLE_ATTRIBUTES "QuerySettableAttributes" diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 9a5be5b..8681a69 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -135,6 +135,7 @@ libdaemon_la_SOURCES = \ gvfsjobdelete.c gvfsjobdelete.h \ gvfsjobcopy.c gvfsjobcopy.h \ gvfsjobupload.c gvfsjobupload.h \ + gvfsjobdownload.c gvfsjobdownload.h \ gvfsjobmove.c gvfsjobmove.h \ gvfsjobmakedirectory.c gvfsjobmakedirectory.h \ gvfsjobmakesymlink.c gvfsjobmakesymlink.h \ diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c index ddce08c..205661b 100644 --- a/daemon/gvfsbackend.c +++ b/daemon/gvfsbackend.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -538,6 +539,10 @@ backend_dbus_handler (DBusConnection *connection, job = g_vfs_job_upload_new (connection, message, backend); else if (dbus_message_is_method_call (message, G_VFS_DBUS_MOUNT_INTERFACE, + G_VFS_DBUS_MOUNT_OP_DOWNLOAD)) + job = g_vfs_job_download_new (connection, message, backend); + else if (dbus_message_is_method_call (message, + G_VFS_DBUS_MOUNT_INTERFACE, G_VFS_DBUS_MOUNT_OP_MOVE)) job = g_vfs_job_move_new (connection, message, backend); else if (dbus_message_is_method_call (message, diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h index d8c7867..599220e 100644 --- a/daemon/gvfsbackend.h +++ b/daemon/gvfsbackend.h @@ -65,6 +65,7 @@ typedef struct _GVfsJobMakeDirectory GVfsJobMakeDirectory; typedef struct _GVfsJobMakeSymlink GVfsJobMakeSymlink; typedef struct _GVfsJobCopy GVfsJobCopy; typedef struct _GVfsJobUpload GVfsJobUpload; +typedef struct _GVfsJobDownload GVfsJobDownload; typedef struct _GVfsJobMove GVfsJobMove; typedef struct _GVfsJobSetAttribute GVfsJobSetAttribute; typedef struct _GVfsJobQueryAttributes GVfsJobQueryAttributes; @@ -297,6 +298,20 @@ struct _GVfsBackendClass GFileCopyFlags flags, GFileProgressCallback progress_callback, gpointer progress_callback_data); + void (*download) (GVfsBackend *backend, + GVfsJobDownload *job, + const char *source, + const char *local_destination, + GFileCopyFlags flags, + GFileProgressCallback progress_callback, + gpointer progress_callback_data); + gboolean (*try_download) (GVfsBackend *backend, + GVfsJobDownload *job, + const char *source, + const char *local_destination, + GFileCopyFlags flags, + GFileProgressCallback progress_callback, + gpointer progress_callback_data); void (*upload) (GVfsBackend *backend, GVfsJobUpload *job, const char *destination, diff --git a/daemon/gvfsbackendhttp.c b/daemon/gvfsbackendhttp.c index 7e91a05..1d46924 100644 --- a/daemon/gvfsbackendhttp.c +++ b/daemon/gvfsbackendhttp.c @@ -1,5 +1,5 @@ /* GIO - GLib Input, Output and Streaming Library - * + * * Copyright (C) 2008 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -81,7 +81,7 @@ g_vfs_backend_http_init (GVfsBackendHttp *backend) { const char *debug; - g_vfs_backend_set_user_visible (G_VFS_BACKEND (backend), FALSE); + g_vfs_backend_set_user_visible (G_VFS_BACKEND (backend), FALSE); backend->session = soup_session_sync_new_with_options ("user-agent", "gvfs/" VERSION, @@ -214,7 +214,7 @@ http_error_code_from_status (guint status) case SOUP_STATUS_NOT_FOUND: case SOUP_STATUS_GONE: - return G_IO_ERROR_NOT_FOUND; + return G_IO_ERROR_NOT_FOUND; case SOUP_STATUS_GATEWAY_TIMEOUT: return G_IO_ERROR_TIMED_OUT; @@ -229,6 +229,11 @@ g_vfs_job_failed_from_http_status (GVfsJob *job, guint status_code, const char * { switch (status_code) { + case SOUP_STATUS_CANCELLED: + g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + break; + case SOUP_STATUS_NOT_FOUND: g_vfs_job_failed_literal (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, message); @@ -263,7 +268,7 @@ http_backend_queue_message (GVfsBackend *backend, { GVfsBackendHttp *op_backend = G_VFS_BACKEND_HTTP (backend); - soup_session_queue_message (op_backend->session_async, msg, + soup_session_queue_message (op_backend->session_async, msg, callback, user_data); } /* ************************************************************************* */ @@ -310,9 +315,9 @@ try_mount (GVfsBackend *backend, real_mount_spec->mount_prefix = g_mount_spec_canonicalize_path (path); g_free (path); } - + g_vfs_backend_set_mount_spec (backend, real_mount_spec); - + op_backend->mount_base = uri; g_vfs_job_succeeded (G_VFS_JOB (job)); @@ -331,7 +336,7 @@ open_for_read_ready (GObject *source_object, gboolean can_seek; GError *error; - stream = G_INPUT_STREAM (source_object); + stream = G_INPUT_STREAM (source_object); error = NULL; job = G_VFS_JOB (user_data); @@ -356,7 +361,7 @@ open_for_read_ready (GObject *source_object, g_vfs_job_succeeded (job); } -static gboolean +static gboolean try_open_for_read (GVfsBackend *backend, GVfsJobOpenForRead *job, const char *filename) @@ -393,7 +398,7 @@ read_ready (GObject *source_object, GError *error; gssize nread; - stream = G_INPUT_STREAM (source_object); + stream = G_INPUT_STREAM (source_object); error = NULL; job = G_VFS_JOB (user_data); @@ -498,7 +503,7 @@ close_read_ready (GObject *source_object, g_object_unref (stream); } -static gboolean +static gboolean try_close_read (GVfsBackend *backend, GVfsJobCloseRead *job, GVfsBackendHandle handle) @@ -547,7 +552,7 @@ query_info_ready (SoupSession *session, g_print ("basename:%s\n", basename); /* read http/1.1 rfc, until then we copy the local files - * behaviour */ + * behaviour */ if (basename != NULL && g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) @@ -572,7 +577,7 @@ query_info_ready (SoupSession *session, char *edit_name = g_filename_display_name (basename); g_file_info_set_edit_name (info, edit_name); g_free (edit_name); - } + } g_free (basename); @@ -647,16 +652,217 @@ try_query_info (GVfsBackend *backend, return TRUE; } +typedef struct { + + GVfsJobDownload *job; + GFileCopyFlags flags; + const char *destination; + + SoupSession *session; + + GOutputStream *out; + + GFileProgressCallback progress_callback; + gpointer progress_callback_data; + + goffset total_size; + goffset data_read; + + GError *error; + GCancellable *cancellable; + +} DownloadData; + +static void +download_got_headers (SoupMessage *msg, + gpointer user_data) +{ + DownloadData *data = user_data; + GFileOutputStream *out; + GFile *file; + const char *text; + + if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) + return; + + file = g_file_new_for_path (data->destination); + + if (data->flags & G_FILE_COPY_OVERWRITE) + { + out = g_file_replace (file, + NULL, + data->flags & G_FILE_COPY_BACKUP, + 0, + data->cancellable, + &data->error); + } + else + { + out = g_file_create (file, + 0, + data->cancellable, + &data->error); + } + + g_object_unref (file); + + if (out == NULL) + { + soup_session_cancel_message (data->session, msg, SOUP_STATUS_CANCELLED); + return; + } + + data->out = G_OUTPUT_STREAM (out); + + if (data->progress_callback == NULL) + return; + + text = soup_message_headers_get (msg->response_headers, + "Content-Length"); + if (text) + { + char *endptr = NULL; + + data->total_size = g_ascii_strtoull (text, &endptr, 10); + + if (endptr == text) + data->total_size = -1; + } + +} + +static void +download_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data) +{ + DownloadData *data = user_data; + gsize bytes_written = 0; + gboolean res; + + res = g_output_stream_write_all (data->out, + chunk->data, + chunk->length, + &bytes_written, + data->cancellable, + &data->error); + + if (res == FALSE) + { + soup_session_cancel_message (data->session, msg, SOUP_STATUS_CANCELLED); + return; + } + + if (data->progress_callback) + { + data->data_read += bytes_written; + data->progress_callback (data->data_read, data->total_size, + data->progress_callback_data); + } +} + +static void +download_got_body (SoupMessage *msg, + gpointer user_data) +{ + DownloadData *data = user_data; + gboolean res; + + res = g_output_stream_close (data->out, data->cancellable, &data->error); + + if (res == FALSE) + soup_session_cancel_message (data->session, msg, SOUP_STATUS_CANCELLED); + + g_object_unref (data->out); + data->out = NULL; +} + +static void +download_finished (SoupMessage *msg, + gpointer user_data) +{ + DownloadData *data = user_data; + + /* In an error case the message will get cancelled + * and the got_body function not be called so we + * free the output stream here .. */ + + if (data->out != NULL) + { + g_output_stream_close (data->out, data->cancellable, NULL); + g_object_unref (data->out); + } + +} + +static void +do_download (GVfsBackend *backend, + GVfsJobDownload *job, + const char *source, + const char *local_destination, + GFileCopyFlags flags, + GFileProgressCallback progress_callback, + gpointer progress_callback_data) +{ + DownloadData data; + SoupMessage *msg; + SoupURI *uri; + guint status; + + uri = http_backend_uri_for_filename (backend, source, FALSE); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + soup_uri_free (uri); + + soup_message_body_set_accumulate (msg->response_body, FALSE); + + g_signal_connect (msg, "got_headers", + G_CALLBACK (download_got_headers), &data); + + g_signal_connect (msg, "got_chunk", + G_CALLBACK (download_got_chunk), &data); + + g_signal_connect (msg, "got_body", + G_CALLBACK (download_got_body), &data); + + g_signal_connect (msg, "finished", + G_CALLBACK (download_finished), &data); + + memset (&data, 0, sizeof (data)); + + data.job = job; + data.flags = flags; + data.cancellable = G_VFS_JOB (job)->cancellable; + data.destination = local_destination; + data.session = G_VFS_BACKEND_HTTP (backend)->session; + data.progress_callback_data = progress_callback_data; + data.progress_callback = progress_callback; + data.total_size = -1; + + status = http_backend_send_message (backend, msg); + + if (! SOUP_STATUS_IS_SUCCESSFUL (status)) + { + if (data.error != NULL) + { + g_vfs_job_failed_from_error (G_VFS_JOB (job), data.error); + g_error_free (data.error); + } + else + g_vfs_job_failed_from_http_status (G_VFS_JOB (job), status, msg->reason_phrase); + } + else + g_vfs_job_succeeded (G_VFS_JOB (job)); + + g_object_unref (msg); +} static void g_vfs_backend_http_class_init (GVfsBackendHttpClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GVfsBackendClass *backend_class; - + gobject_class->finalize = g_vfs_backend_http_finalize; - backend_class = G_VFS_BACKEND_CLASS (klass); + backend_class = G_VFS_BACKEND_CLASS (klass); backend_class->try_mount = try_mount; backend_class->try_open_for_read = try_open_for_read; @@ -665,4 +871,5 @@ g_vfs_backend_http_class_init (GVfsBackendHttpClass *klass) backend_class->try_close_read = try_close_read; backend_class->try_query_info = try_query_info; + backend_class->download = do_download; } diff --git a/daemon/gvfsjobdownload.c b/daemon/gvfsjobdownload.c new file mode 100644 index 0000000..6828e5e --- /dev/null +++ b/daemon/gvfsjobdownload.c @@ -0,0 +1,211 @@ +/* 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 + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "gvfsjobdownload.h" +#include "gdbusutils.h" +#include "gvfsdaemonprotocol.h" + +G_DEFINE_TYPE (GVfsJobDownload, g_vfs_job_download, 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_download_finalize (GObject *object) +{ + GVfsJobDownload *job; + + job = G_VFS_JOB_DOWNLOAD (object); + + g_free (job->local_destination); + g_free (job->source); + g_free (job->callback_obj_path); + + if (G_OBJECT_CLASS (g_vfs_job_download_parent_class)->finalize) + (*G_OBJECT_CLASS (g_vfs_job_download_parent_class)->finalize) (object); +} + +static void +g_vfs_job_download_class_init (GVfsJobDownloadClass *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_download_finalize; + job_class->run = run; + job_class->try = try; + job_dbus_class->create_reply = create_reply; +} + +static void +g_vfs_job_download_init (GVfsJobDownload *job) +{ +} + +GVfsJob * +g_vfs_job_download_new (DBusConnection *connection, + DBusMessage *message, + GVfsBackend *backend) +{ + GVfsJobDownload *job; + DBusMessage *reply; + DBusError derror; + int path1_len, path2_len; + const char *path1_data, *path2_data, *callback_obj_path; + dbus_uint32_t flags; + + 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, + 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_DOWNLOAD, + "message", message, + "connection", connection, + NULL); + + job->source = g_strndup (path1_data, path1_len); + job->local_destination = g_strndup (path2_data, path2_len); + job->backend = backend; + job->flags = flags; + 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); + GVfsJobDownload *op_job = G_VFS_JOB_DOWNLOAD (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, ¤t_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) +{ + GVfsJobDownload *op_job = G_VFS_JOB_DOWNLOAD (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->download == NULL) + { + g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported by backend")); + return; + } + + class->download (op_job->backend, + op_job, + op_job->source, + op_job->local_destination, + op_job->flags, + progress_callback, + job); +} + +static gboolean +try (GVfsJob *job) +{ + GVfsJobDownload *op_job = G_VFS_JOB_DOWNLOAD (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->try_download == NULL) + return FALSE; + + return class->try_download (op_job->backend, + op_job, + op_job->source, + op_job->local_destination, + op_job->flags, + 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/gvfsjobdownload.h b/daemon/gvfsjobdownload.h new file mode 100644 index 0000000..a92bb94 --- /dev/null +++ b/daemon/gvfsjobdownload.h @@ -0,0 +1,66 @@ +/* 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 + */ + +#ifndef __G_VFS_JOB_DOWNLOAD_H__ +#define __G_VFS_JOB_DOWNLOAD_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define G_VFS_TYPE_JOB_DOWNLOAD (g_vfs_job_download_get_type ()) +#define G_VFS_JOB_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_DOWNLOAD, GVfsJobDownload)) +#define G_VFS_JOB_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_DOWNLOAD, GVfsJobDownloadClass)) +#define G_VFS_IS_JOB_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_DOWNLOAD)) +#define G_VFS_IS_JOB_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_DOWNLOAD)) +#define G_VFS_JOB_DOWNLOAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_DOWNLOAD, GVfsJobDownloadClass)) + +typedef struct _GVfsJobDownloadClass GVfsJobDownloadClass; + +struct _GVfsJobDownload +{ + GVfsJobDBus parent_instance; + + GVfsBackend *backend; + char *source; + char *local_destination; + GFileCopyFlags flags; + char *callback_obj_path; +}; + +struct _GVfsJobDownloadClass +{ + GVfsJobDBusClass parent_class; +}; + +GType g_vfs_job_download_get_type (void) G_GNUC_CONST; + +GVfsJob *g_vfs_job_download_new (DBusConnection *connection, + DBusMessage *message, + GVfsBackend *backend); + +G_END_DECLS + +#endif /* __G_VFS_JOB_DOWNLOAD_H__ */