diff options
author | Alexander Larsson <alexl@redhat.com> | 2008-01-09 14:49:05 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2008-01-09 14:49:05 +0000 |
commit | 23730c607ca8ae5a6f8d84d623e7b21bdd5bd1c3 (patch) | |
tree | 1f4c6e149a351d32ba92a9ba71c6856ce771d81e | |
parent | ca250f832f62324f0bef8fab968d681d03a84a57 (diff) | |
download | gvfs-23730c607ca8ae5a6f8d84d623e7b21bdd5bd1c3.tar.gz |
Add g_mount_source_get_operation() that lets you handle a remote
2008-01-09 Alexander Larsson <alexl@redhat.com>
* common/gmountsource.[ch]:
Add g_mount_source_get_operation() that lets
you handle a remote GMountSource as if it
was a GMountOperation.
* common/gmountoperationdbus.c:
* programs/gvfs-mount.c:
Update to new GMountOperation APIs
* client/gdaemonfile.c:
* daemon/gvfsjobmountmountable.[ch]:
Also let you return target by uri, as not all
targets are from gvfs.
* daemon/gvfsbackendcomputer.c:
Initial cut at mount_mountable
svn path=/trunk/; revision=1085
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | client/gdaemonfile.c | 53 | ||||
-rw-r--r-- | common/gmountoperationdbus.c | 27 | ||||
-rw-r--r-- | common/gmountsource.c | 186 | ||||
-rw-r--r-- | common/gmountsource.h | 2 | ||||
-rw-r--r-- | daemon/gvfsbackendcomputer.c | 62 | ||||
-rw-r--r-- | daemon/gvfsjobmountmountable.c | 36 | ||||
-rw-r--r-- | daemon/gvfsjobmountmountable.h | 4 | ||||
-rw-r--r-- | programs/gvfs-mount.c | 6 |
9 files changed, 314 insertions, 81 deletions
@@ -1,5 +1,24 @@ 2008-01-09 Alexander Larsson <alexl@redhat.com> + * common/gmountsource.[ch]: + Add g_mount_source_get_operation() that lets + you handle a remote GMountSource as if it + was a GMountOperation. + + * common/gmountoperationdbus.c: + * programs/gvfs-mount.c: + Update to new GMountOperation APIs + + * client/gdaemonfile.c: + * daemon/gvfsjobmountmountable.[ch]: + Also let you return target by uri, as not all + targets are from gvfs. + + * daemon/gvfsbackendcomputer.c: + Initial cut at mount_mountable + +2008-01-09 Alexander Larsson <alexl@redhat.com> + * client/gdaemonvfs.c (_g_daemon_vfs_get_mount_info_sync): Better error return on not mounted. diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index 9ba5b2b6..ebf24b92 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -1198,15 +1198,14 @@ mount_mountable_async_cb (DBusMessage *reply, char *path; DBusMessageIter iter; GFile *file; - dbus_bool_t must_mount_location; + dbus_bool_t must_mount_location, is_uri; path = NULL; - + dbus_message_iter_init (reply, &iter); - mount_spec = g_mount_spec_from_dbus (&iter); - if (mount_spec == NULL || - !_g_dbus_message_iter_get_args (&iter, NULL, + if (!_g_dbus_message_iter_get_args (&iter, NULL, + DBUS_TYPE_BOOLEAN, &is_uri, G_DBUS_TYPE_CSTRING, &path, DBUS_TYPE_BOOLEAN, &must_mount_location, 0)) @@ -1215,26 +1214,44 @@ mount_mountable_async_cb (DBusMessage *reply, G_IO_ERROR, G_IO_ERROR_FAILED, _("Invalid return value from call")); g_simple_async_result_complete (result); + + return; + } + + if (is_uri) + { + file = g_file_new_for_uri (path); } else { + mount_spec = g_mount_spec_from_dbus (&iter); + if (mount_spec == NULL) + { + g_simple_async_result_set_error (result, + G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid return value from call")); + g_simple_async_result_complete (result); + return; + } + file = g_daemon_file_new (mount_spec, path); g_mount_spec_unref (mount_spec); - g_free (path); - g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref); + } + + g_free (path); + g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref); - if (must_mount_location) - { - g_file_mount_enclosing_volume (file, - mount_operation, - cancellable, - mount_mountable_location_mounted_cb, - g_object_ref (result)); - - } - else - g_simple_async_result_complete (result); + if (must_mount_location) + { + g_file_mount_enclosing_volume (file, + mount_operation, + cancellable, + mount_mountable_location_mounted_cb, + g_object_ref (result)); + } + else + g_simple_async_result_complete (result); } static void diff --git a/common/gmountoperationdbus.c b/common/gmountoperationdbus.c index 1f46ab04..ea44f534 100644 --- a/common/gmountoperationdbus.c +++ b/common/gmountoperationdbus.c @@ -156,18 +156,20 @@ mount_op_send_reply (GMountOperationDBus *op_dbus, static void ask_password_reply (GMountOperation *op, - gboolean abort, + GMountOperationResult result, gpointer data) { DBusMessage *reply = data; const char *username, *password, *domain; dbus_bool_t anonymous; guint32 password_save; - dbus_bool_t handled = TRUE; - dbus_bool_t abort_dbus = abort; + dbus_bool_t handled, abort_dbus; GMountOperationDBus *op_dbus; op_dbus = g_object_get_data (G_OBJECT (op), "dbus-op"); + + handled = (result != G_MOUNT_OPERATION_UNHANDLED); + abort_dbus = (result == G_MOUNT_OPERATION_ABORTED); password = g_mount_operation_get_password (op); if (password == NULL) @@ -238,31 +240,24 @@ mount_op_ask_password (GMountOperationDBus *op_dbus, message_string, default_user, default_domain, - flags, - &res); - - if (!res) - { - _g_dbus_message_append_args (reply, - DBUS_TYPE_BOOLEAN, &handled, - 0); - mount_op_send_reply (op_dbus, reply); - } + flags); } static void ask_question_reply (GMountOperation *op, - gboolean abort, + GMountOperationResult result, gpointer data) { DBusMessage *reply = data; guint32 choice; - dbus_bool_t handled = TRUE; - dbus_bool_t abort_dbus = abort; + dbus_bool_t handled, abort_dbus; GMountOperationDBus *op_dbus; op_dbus = g_object_get_data (G_OBJECT (op), "dbus-op"); + handled = (result != G_MOUNT_OPERATION_UNHANDLED); + abort_dbus = (result == G_MOUNT_OPERATION_ABORTED); + choice = g_mount_operation_get_choice (op); _g_dbus_message_append_args (reply, diff --git a/common/gmountsource.c b/common/gmountsource.c index afbfcabb..0ee8c243 100644 --- a/common/gmountsource.c +++ b/common/gmountsource.c @@ -119,15 +119,23 @@ g_mount_source_get_obj_path (GMountSource *mount_source) return mount_source->obj_path; } -typedef struct { +typedef struct AskPasswordData AskPasswordData; + +struct AskPasswordData { + void (*callback)(AskPasswordData *data); + /* For sync calls */ GMutex *mutex; GCond *cond; + /* For async calls */ + GMountOperation *op; + + /* results: */ gboolean handled; gboolean aborted; char *password; char *username; char *domain; -} AskPasswordData; +} ; static void ask_password_reply (DBusMessage *reply, @@ -140,6 +148,7 @@ ask_password_reply (DBusMessage *reply, const char *password, *username, *domain; DBusMessageIter iter; + data->handled = TRUE; if (reply == NULL) { data->aborted = TRUE; @@ -170,36 +179,40 @@ ask_password_reply (DBusMessage *reply, } } - /* Wake up sync call thread */ - g_mutex_lock (data->mutex); - g_cond_signal (data->cond); - g_mutex_unlock (data->mutex); + data->callback (data); } -gboolean -g_mount_source_ask_password (GMountSource *source, - const char *message_string, - const char *default_user, - const char *default_domain, - GAskPasswordFlags flags, - gboolean *aborted, - char **password_out, - char **user_out, - char **domain_out) +static gboolean +password_non_handled_in_idle (gpointer _data) +{ + AskPasswordData *data = _data; + + data->callback (data); + return FALSE; +} + +static void +g_mount_source_ask_password_async (GMountSource *source, + const char *message_string, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags, + AskPasswordData *data) { DBusMessage *message; guint32 flags_as_int; - AskPasswordData data = {NULL}; - if (password_out) - *password_out = NULL; - if (user_out) - *user_out = NULL; - if (domain_out) - *domain_out = NULL; - + /* If no dbus id specified, reply that we weren't handled */ if (source->dbus_id[0] == 0) - return FALSE; + { + data->handled = FALSE; + + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + password_non_handled_in_idle, + data, + NULL); + return; + } if (message_string == NULL) message_string = ""; @@ -222,15 +235,55 @@ g_mount_source_ask_password (GMountSource *source, DBUS_TYPE_UINT32, &flags_as_int, 0); + /* 30 minute timeout */ + _g_dbus_connection_call_async (NULL, message, 1000 * 60 * 30, + ask_password_reply, data); + dbus_message_unref (message); +} + + +static void +ask_password_reply_sync (AskPasswordData *data) +{ + /* Wake up sync call thread */ + g_mutex_lock (data->mutex); + g_cond_signal (data->cond); + g_mutex_unlock (data->mutex); +} + +gboolean +g_mount_source_ask_password (GMountSource *source, + const char *message_string, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags, + gboolean *aborted, + char **password_out, + char **user_out, + char **domain_out) +{ + AskPasswordData data = {NULL}; + + if (password_out) + *password_out = NULL; + if (user_out) + *user_out = NULL; + if (domain_out) + *domain_out = NULL; + data.mutex = g_mutex_new (); data.cond = g_cond_new (); + data.callback = ask_password_reply_sync; g_mutex_lock (data.mutex); - /* 30 minute timeout */ - _g_dbus_connection_call_async (NULL, message, 1000 * 60 * 30, - ask_password_reply, &data); - dbus_message_unref (message); + + g_mount_source_ask_password_async (source, + message_string, + default_user, + default_domain, + flags, + &data); g_cond_wait(data.cond, data.mutex); g_mutex_unlock (data.mutex); @@ -242,11 +295,86 @@ g_mount_source_ask_password (GMountSource *source, *aborted = data.aborted; if (password_out) *password_out = data.password; + else + g_free (data.password); if (user_out) *user_out = data.username; + else + g_free (data.username); if (domain_out) *domain_out = data.domain; + else + g_free (data.domain); return data.handled; } +static void +ask_password_reply_async (AskPasswordData *data) +{ + GMountOperationResult result; + + if (!data->handled) + result = G_MOUNT_OPERATION_UNHANDLED; + else if (data->aborted) + result = G_MOUNT_OPERATION_ABORTED; + else + { + result = G_MOUNT_OPERATION_HANDLED; + + if (data->password) + g_mount_operation_set_password (data->op, + data->password); + if (data->username) + g_mount_operation_set_username (data->op, + data->username); + if (data->domain) + g_mount_operation_set_domain (data->op, + data->domain); + } + + g_mount_operation_reply (data->op, result); + + g_object_unref (data->op); + g_free (data); +} + +static gboolean +op_ask_password (GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags, + GMountSource *mount_source) +{ + AskPasswordData *data; + + data = g_new0 (AskPasswordData, 1); + data->callback = ask_password_reply_async; + data->op = g_object_ref (op); + + g_mount_source_ask_password_async (mount_source, + message, + default_user, + default_domain, + flags, + data); + return TRUE; +} + + +GMountOperation * +g_mount_source_get_operation (GMountSource *mount_source) +{ + GMountOperation *op; + + op = g_mount_operation_new (); + g_object_set_data_full (G_OBJECT (op), "source", + g_object_ref (mount_source), + g_object_unref); + + + g_signal_connect (op, "ask_password", (GCallback)op_ask_password, mount_source); + + return op; +} diff --git a/common/gmountsource.h b/common/gmountsource.h index 395d33a8..f1075970 100644 --- a/common/gmountsource.h +++ b/common/gmountsource.h @@ -68,6 +68,8 @@ gboolean g_mount_source_ask_password (GMountSource const char * g_mount_source_get_dbus_id (GMountSource *mount_source); const char * g_mount_source_get_obj_path (GMountSource *mount_source); +GMountOperation *g_mount_source_get_operation (GMountSource *mount_source); + G_END_DECLS #endif /* __G_MOUNT_SOURCE_H__ */ diff --git a/daemon/gvfsbackendcomputer.c b/daemon/gvfsbackendcomputer.c index 90cf7fb8..bb3cd40c 100644 --- a/daemon/gvfsbackendcomputer.c +++ b/daemon/gvfsbackendcomputer.c @@ -48,6 +48,7 @@ #include "gvfsjobclosewrite.h" #include "gvfsjobseekwrite.h" #include "gvfsjobsetdisplayname.h" +#include "gvfsjobmountmountable.h" #include "gvfsjobqueryinfo.h" #include "gvfsjobdelete.h" #include "gvfsjobqueryfsinfo.h" @@ -718,6 +719,51 @@ try_create_dir_monitor (GVfsBackend *backend, return TRUE; } +static void +mount_volume_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GVfsJobMountMountable *job = user_data; + GError *error; + GMount *mount; + GVolume *volume; + GFile *root; + char *uri; + + volume = G_VOLUME (source_object); + + /* TODO: We're leaking the GMountOperation here */ + + error = NULL; + if (g_volume_mount_finish (volume, res, &error)) + { + mount = g_volume_get_mount (volume); + + if (mount) + { + root = g_mount_get_root (mount); + uri = g_file_get_uri (root); + g_vfs_job_mount_mountable_set_target_uri (job, + uri, + FALSE); + g_free (uri); + g_object_unref (root); + g_object_unref (mount); + g_vfs_job_succeeded (G_VFS_JOB (job)); + } + else + g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Can't find mount for mounted volume")); + } + else + { + g_vfs_job_failed_from_error (G_VFS_JOB (job), error); + g_error_free (error); + } +} + static gboolean try_mount_mountable (GVfsBackend *backend, GVfsJobMountMountable *job, @@ -725,6 +771,7 @@ try_mount_mountable (GVfsBackend *backend, GMountSource *mount_source) { ComputerFile *file; + GMountOperation *mount_op; file = lookup (G_VFS_BACKEND_COMPUTER (backend), G_VFS_JOB (job), filename); @@ -735,22 +782,22 @@ try_mount_mountable (GVfsBackend *backend, _("Can't open directory")); else if (file != NULL) { -#if 0 if (file->volume) { - /* TODO: Implement */ + mount_op = g_mount_source_get_operation (mount_source); g_volume_mount (file->volume, - GMountOperation *mount_operation, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); + mount_op, + G_VFS_JOB (job)->cancellable, + mount_volume_cb, + job); } +#if 0 else if (file->drive) { /* TODO: Poll for media? */ } - else #endif + else { g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, @@ -788,4 +835,5 @@ g_vfs_backend_computer_class_init (GVfsBackendComputerClass *klass) backend_class->try_query_info = try_query_info; backend_class->try_enumerate = try_enumerate; backend_class->try_create_dir_monitor = try_create_dir_monitor; + backend_class->try_mount_mountable = try_mount_mountable; } diff --git a/daemon/gvfsjobmountmountable.c b/daemon/gvfsjobmountmountable.c index 1af2823d..a83c04a3 100644 --- a/daemon/gvfsjobmountmountable.c +++ b/daemon/gvfsjobmountmountable.c @@ -135,6 +135,15 @@ g_vfs_job_mount_mountable_set_target (GVfsJobMountMountable *job, job->must_mount_location = must_mount_location; } +void +g_vfs_job_mount_mountable_set_target_uri (GVfsJobMountMountable *job, + const char *uri, + gboolean must_mount_location) +{ + job->target_uri = g_strdup (uri); + job->must_mount_location = must_mount_location; +} + static void run (GVfsJob *job) { @@ -178,17 +187,30 @@ create_reply (GVfsJob *job, GVfsJobMountMountable *op_job = G_VFS_JOB_MOUNT_MOUNTABLE (job); DBusMessage *reply; DBusMessageIter iter; - dbus_bool_t must_mount; + dbus_bool_t must_mount, is_uri; reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &iter); - g_mount_spec_to_dbus (&iter, op_job->mount_spec); must_mount = op_job->must_mount_location; - _g_dbus_message_append_args (reply, - G_DBUS_TYPE_CSTRING, &op_job->target_filename, - DBUS_TYPE_BOOLEAN, &must_mount, - 0); + is_uri = op_job->target_uri != NULL; + if (is_uri) + { + _g_dbus_message_append_args (reply, + DBUS_TYPE_BOOLEAN, &is_uri, + G_DBUS_TYPE_CSTRING, &op_job->target_uri, + DBUS_TYPE_BOOLEAN, &must_mount, + 0); + } + else + { + _g_dbus_message_append_args (reply, + DBUS_TYPE_BOOLEAN, &is_uri, + G_DBUS_TYPE_CSTRING, &op_job->target_filename, + DBUS_TYPE_BOOLEAN, &must_mount, + 0); + dbus_message_iter_init_append (reply, &iter); + g_mount_spec_to_dbus (&iter, op_job->mount_spec); + } return reply; } diff --git a/daemon/gvfsjobmountmountable.h b/daemon/gvfsjobmountmountable.h index 87e95085..70968bf0 100644 --- a/daemon/gvfsjobmountmountable.h +++ b/daemon/gvfsjobmountmountable.h @@ -47,6 +47,7 @@ struct _GVfsJobMountMountable char *filename; GMountSource *mount_source; + char *target_uri; char *target_filename; GMountSpec *mount_spec; gboolean must_mount_location; @@ -66,6 +67,9 @@ void g_vfs_job_mount_mountable_set_target (GVfsJobMountMountable *job, GMountSpec *mount_spec, const char *filename, gboolean must_mount_location); +void g_vfs_job_mount_mountable_set_target_uri (GVfsJobMountMountable *job, + const char *uri, + gboolean must_mount_location); G_END_DECLS diff --git a/programs/gvfs-mount.c b/programs/gvfs-mount.c index 43a0459f..aa1d56bc 100644 --- a/programs/gvfs-mount.c +++ b/programs/gvfs-mount.c @@ -65,7 +65,7 @@ prompt_for (const char *prompt, const char *default_value) return g_strdup (data); } -static gboolean +static void ask_password_cb (GMountOperation *op, const char *message, const char *default_user, @@ -96,9 +96,7 @@ ask_password_cb (GMountOperation *op, g_free (s); } - g_mount_operation_reply (op, FALSE); - - return TRUE; + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); } static void |