summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--client/gdaemonfile.c53
-rw-r--r--common/gmountoperationdbus.c27
-rw-r--r--common/gmountsource.c186
-rw-r--r--common/gmountsource.h2
-rw-r--r--daemon/gvfsbackendcomputer.c62
-rw-r--r--daemon/gvfsjobmountmountable.c36
-rw-r--r--daemon/gvfsjobmountmountable.h4
-rw-r--r--programs/gvfs-mount.c6
9 files changed, 314 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index 051ccd83..47f7903b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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