diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | client/gdaemonvolume.c | 69 | ||||
-rw-r--r-- | common/gvfsdaemonprotocol.h | 2 | ||||
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/gvfsbackend.c | 30 | ||||
-rw-r--r-- | daemon/gvfsbackend.h | 8 | ||||
-rw-r--r-- | daemon/gvfsjobunmount.c | 166 | ||||
-rw-r--r-- | daemon/gvfsjobunmount.h | 62 |
8 files changed, 329 insertions, 25 deletions
@@ -1,5 +1,21 @@ 2007-11-14 Alexander Larsson <alexl@redhat.com> + * common/gvfsdaemonprotocol.h: + Add unmount operation and + unregister mount mounttracker call + + * client/gdaemonvolume.c: + Implement client side of unmount + + * daemon/Makefile.am: + * daemon/gvfsjobunmount.[ch]: Added. + Add unmount job type + + * daemon/gvfsbackend.[ch]: + Implement unmount + +2007-11-14 Alexander Larsson <alexl@redhat.com> + * common/gdbusutils.c: Handle NULL callback in _g_dbus_connection_call_async diff --git a/client/gdaemonvolume.c b/client/gdaemonvolume.c index 891bed36..b54f3683 100644 --- a/client/gdaemonvolume.c +++ b/client/gdaemonvolume.c @@ -26,10 +26,13 @@ #include <glib.h> #include <glib/gi18n-lib.h> +#include <gio/gthemedicon.h> +#include <gio/gsimpleasyncresult.h> #include "gdaemonvolumemonitor.h" #include "gdaemonvolume.h" +#include "gvfsdaemondbus.h" #include "gdaemonfile.h" -#include "gio/gthemedicon.h" +#include "gvfsdaemonprotocol.h" struct _GDaemonVolume { GObject parent; @@ -114,57 +117,75 @@ g_daemon_volume_get_name (GVolume *volume) static GDrive * g_daemon_volume_get_drive (GVolume *volume) { - /* TODO */ - return NULL; } static gboolean g_daemon_volume_can_unmount (GVolume *volume) { - /* TODO */ return TRUE; } static gboolean g_daemon_volume_can_eject (GVolume *volume) { - /* TODO */ return FALSE; } static void -g_daemon_volume_unmount (GVolume *volume, - GAsyncReadyCallback callback, - gpointer user_data) +unmount_reply (DBusMessage *reply, + DBusConnection *connection, + GError *io_error, + gpointer _data) { - /* TODO */ -} + GSimpleAsyncResult *result = _data; -static gboolean -g_daemon_volume_unmount_finish (GVolume *volume, - GAsyncResult *result, - GError **error) -{ - return TRUE; + if (io_error != NULL) + g_simple_async_result_set_from_error (result, io_error); + + g_simple_async_result_complete (result); + g_object_unref (result); } static void -g_daemon_volume_eject (GVolume *volume, - GAsyncReadyCallback callback, - gpointer user_data) +g_daemon_volume_unmount (GVolume *volume, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - /* TODO */ + GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume); + DBusMessage *message; + GMountInfo *mount_info; + GSimpleAsyncResult *res; + + mount_info = daemon_volume->mount_info; + + message = + dbus_message_new_method_call (mount_info->dbus_id, + mount_info->object_path, + G_VFS_DBUS_MOUNT_INTERFACE, + G_VFS_DBUS_MOUNT_OP_UNMOUNT); + + res = g_simple_async_result_new (G_OBJECT (volume), + callback, user_data, + g_daemon_volume_unmount); + + _g_vfs_daemon_call_async (message, + unmount_reply, res, + cancellable); + + dbus_message_unref (message); } static gboolean -g_daemon_volume_eject_finish (GVolume *volume, - GAsyncResult *result, - GError **error) +g_daemon_volume_unmount_finish (GVolume *volume, + GAsyncResult *result, + GError **error) { return TRUE; } + static void g_daemon_volume_volume_iface_init (GVolumeIface *iface) { @@ -176,6 +197,4 @@ g_daemon_volume_volume_iface_init (GVolumeIface *iface) iface->can_eject = g_daemon_volume_can_eject; iface->unmount = g_daemon_volume_unmount; iface->unmount_finish = g_daemon_volume_unmount_finish; - iface->eject = g_daemon_volume_eject; - iface->eject_finish = g_daemon_volume_eject_finish; } diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h index 600870f0..eef045ea 100644 --- a/common/gvfsdaemonprotocol.h +++ b/common/gvfsdaemonprotocol.h @@ -15,6 +15,7 @@ G_BEGIN_DECLS #define G_VFS_DBUS_MOUNTTRACKER_OP_MOUNT_LOCATION "mountLocation" #define G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTS "listMounts" #define G_VFS_DBUS_MOUNTTRACKER_OP_REGISTER_MOUNT "registerMount" +#define G_VFS_DBUS_MOUNTTRACKER_OP_UNREGISTER_MOUNT "unregisterMount" #define G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNT_TYPES "listMountTypes" #define G_VFS_DBUS_MOUNTTRACKER_OP_REGISTER_FUSE "registerFuse" #define G_VFS_DBUS_MOUNTTRACKER_SIGNAL_MOUNTED "mounted" @@ -23,6 +24,7 @@ G_BEGIN_DECLS /* Each mount (there might be several in a daemon) implements one of these interfaces for standard i/o operations */ #define G_VFS_DBUS_MOUNT_INTERFACE "org.gtk.vfs.Mount" +#define G_VFS_DBUS_MOUNT_OP_UNMOUNT "Unmount" #define G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ "OpenForRead" #define G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE "OpenForWrite" #define G_VFS_DBUS_MOUNT_OP_QUERY_INFO "QueryInfo" diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 8e86e2cf..9ec1cb76 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -63,6 +63,7 @@ libdaemon_la_SOURCES = \ gvfsjobsource.c gvfsjobsource.h \ gvfsjobdbus.c gvfsjobdbus.h \ gvfsjobmount.c gvfsjobmount.h \ + gvfsjobunmount.c gvfsjobunmount.h \ gvfsjobmountmountable.c gvfsjobmountmountable.h \ gvfsjobopenforread.c gvfsjobopenforread.h \ gvfsjobread.c gvfsjobread.h \ diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c index e2d4aab2..579a32cb 100644 --- a/daemon/gvfsbackend.c +++ b/daemon/gvfsbackend.c @@ -347,6 +347,10 @@ backend_dbus_handler (DBusConnection *connection, if (dbus_message_is_method_call (message, G_VFS_DBUS_MOUNT_INTERFACE, + G_VFS_DBUS_MOUNT_OP_UNMOUNT)) + job = g_vfs_job_unmount_new (connection, message, backend); + else if (dbus_message_is_method_call (message, + G_VFS_DBUS_MOUNT_INTERFACE, G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ)) job = g_vfs_job_open_for_read_new (connection, message, backend); else if (dbus_message_is_method_call (message, @@ -463,3 +467,29 @@ g_vfs_backend_register_mount (GVfsBackend *backend, callback, user_data); dbus_message_unref (message); } + +void +g_vfs_backend_unregister_mount (GVfsBackend *backend, + GAsyncDBusCallback callback, + gpointer user_data) +{ + DBusMessage *message; + DBusMessageIter iter; + dbus_bool_t user_visible; + + message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME, + G_VFS_DBUS_MOUNTTRACKER_PATH, + G_VFS_DBUS_MOUNTTRACKER_INTERFACE, + G_VFS_DBUS_MOUNTTRACKER_OP_UNREGISTER_MOUNT); + if (message == NULL) + _g_dbus_oom (); + + if (!dbus_message_append_args (message, + DBUS_TYPE_OBJECT_PATH, &backend->priv->object_path, + 0)) + _g_dbus_oom (); + + _g_dbus_connection_call_async (NULL, message, -1, + callback, user_data); + dbus_message_unref (message); +} diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h index 2cad7cbc..60ead913 100644 --- a/daemon/gvfsbackend.h +++ b/daemon/gvfsbackend.h @@ -45,6 +45,7 @@ typedef struct _GVfsBackendPrivate GVfsBackendPrivate; typedef struct _GVfsBackendClass GVfsBackendClass; typedef struct _GVfsJobMount GVfsJobMount; +typedef struct _GVfsJobUnmount GVfsJobUnmount; typedef struct _GVfsJobMountMountable GVfsJobMountMountable; typedef struct _GVfsJobOpenForRead GVfsJobOpenForRead; typedef struct _GVfsJobSeekRead GVfsJobSeekRead; @@ -91,6 +92,10 @@ struct _GVfsBackendClass * A NULL here means operation not supported */ + void (*unmount) (GVfsBackend *backend, + GVfsJobUnmount *job); + gboolean (*try_unmount) (GVfsBackend *backend, + GVfsJobUnmount *job); void (*mount) (GVfsBackend *backend, GVfsJobMount *job, GMountSpec *mount_spec, @@ -350,6 +355,9 @@ void g_vfs_backend_set_mount_spec (GVfsBackend *ba void g_vfs_backend_register_mount (GVfsBackend *backend, GAsyncDBusCallback callback, gpointer user_data); +void g_vfs_backend_unregister_mount (GVfsBackend *backend, + GAsyncDBusCallback callback, + gpointer user_data); const char *g_vfs_backend_get_backend_type (GVfsBackend *backend); const char *g_vfs_backend_get_display_name (GVfsBackend *backend); const char *g_vfs_backend_get_icon_name (GVfsBackend *backend); diff --git a/daemon/gvfsjobunmount.c b/daemon/gvfsjobunmount.c new file mode 100644 index 00000000..5731e3d3 --- /dev/null +++ b/daemon/gvfsjobunmount.c @@ -0,0 +1,166 @@ +/* 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 <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 "gvfsjobunmount.h" +#include "gdbusutils.h" +#include "gvfsdaemonprotocol.h" + +G_DEFINE_TYPE (GVfsJobUnmount, g_vfs_job_unmount, G_VFS_TYPE_JOB_DBUS); + +static void run (GVfsJob *job); +static gboolean try (GVfsJob *job); +static void send_reply (GVfsJob *job); +static DBusMessage *create_reply (GVfsJob *job, + DBusConnection *connection, + DBusMessage *message); + +static void +g_vfs_job_unmount_finalize (GObject *object) +{ + GVfsJobUnmount *job; + + job = G_VFS_JOB_UNMOUNT (object); + + if (G_OBJECT_CLASS (g_vfs_job_unmount_parent_class)->finalize) + (*G_OBJECT_CLASS (g_vfs_job_unmount_parent_class)->finalize) (object); +} + +static void +g_vfs_job_unmount_class_init (GVfsJobUnmountClass *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_unmount_finalize; + job_class->run = run; + job_class->try = try; + job_class->send_reply = send_reply; + + job_dbus_class->create_reply = create_reply; + +} + +static void +g_vfs_job_unmount_init (GVfsJobUnmount *job) +{ +} + +GVfsJob * +g_vfs_job_unmount_new (DBusConnection *connection, + DBusMessage *message, + GVfsBackend *backend) +{ + GVfsJobUnmount *job; + + g_print ("g_vfs_job_unmount_new request: %p\n", message); + + job = g_object_new (G_VFS_TYPE_JOB_UNMOUNT, + "message", message, + "connection", connection, + NULL); + + job->backend = backend; + + return G_VFS_JOB (job); +} + +static void +run (GVfsJob *job) +{ + GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->unmount == NULL) + { + g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported by backend")); + return; + } + + class->unmount (op_job->backend, + op_job); +} + +static gboolean +try (GVfsJob *job) +{ + GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->try_unmount == NULL) + return FALSE; + + return class->try_unmount (op_job->backend, + op_job); +} + +static void +unregister_mount_callback (DBusMessage *unmount_reply, + GError *error, + gpointer user_data) +{ + GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (user_data); + + g_print ("unregister_mount_callback, unmount_reply: %p, error: %p\n", unmount_reply, error); + + (*G_VFS_JOB_CLASS (g_vfs_job_unmount_parent_class)->send_reply) (G_VFS_JOB (op_job)); + + /* Unlink job source from daemon */ + g_vfs_job_source_closed (G_VFS_JOB_SOURCE (op_job->backend)); +} + +/* Might be called on an i/o thread */ +static void +send_reply (GVfsJob *job) +{ + GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job); + + g_print ("send_reply, failed: %d\n", job->failed); + + g_vfs_backend_unregister_mount (op_job->backend, + unregister_mount_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/gvfsjobunmount.h b/daemon/gvfsjobunmount.h new file mode 100644 index 00000000..77076412 --- /dev/null +++ b/daemon/gvfsjobunmount.h @@ -0,0 +1,62 @@ +/* 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_UNMOUNT_H__ +#define __G_VFS_JOB_UNMOUNT_H__ + +#include <gio/gfileinfo.h> +#include <gvfsjob.h> +#include <gvfsjobdbus.h> +#include <gvfsbackend.h> + +G_BEGIN_DECLS + +#define G_VFS_TYPE_JOB_UNMOUNT (g_vfs_job_unmount_get_type ()) +#define G_VFS_JOB_UNMOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_UNMOUNT, GVfsJobUnmount)) +#define G_VFS_JOB_UNMOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_UNMOUNT, GVfsJobUnmountClass)) +#define G_VFS_IS_JOB_UNMOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_UNMOUNT)) +#define G_VFS_IS_JOB_UNMOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_UNMOUNT)) +#define G_VFS_JOB_UNMOUNT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_UNMOUNT, GVfsJobUnmountClass)) + +typedef struct _GVfsJobUnmountClass GVfsJobUnmountClass; + +struct _GVfsJobUnmount +{ + GVfsJobDBus parent_instance; + + GVfsBackend *backend; +}; + +struct _GVfsJobUnmountClass +{ + GVfsJobDBusClass parent_class; +}; + +GType g_vfs_job_unmount_get_type (void) G_GNUC_CONST; + +GVfsJob *g_vfs_job_unmount_new (DBusConnection *connection, + DBusMessage *request, + GVfsBackend *backend); + +G_END_DECLS + +#endif /* __G_VFS_JOB_UNMOUNT_H__ */ |