summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--client/gdaemonvolume.c69
-rw-r--r--common/gvfsdaemonprotocol.h2
-rw-r--r--daemon/Makefile.am1
-rw-r--r--daemon/gvfsbackend.c30
-rw-r--r--daemon/gvfsbackend.h8
-rw-r--r--daemon/gvfsjobunmount.c166
-rw-r--r--daemon/gvfsjobunmount.h62
8 files changed, 329 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 6b43abfa..add2a1ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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__ */