summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/gdaemonfile.c23
-rw-r--r--common/gmountoperationdbus.c85
-rw-r--r--common/gmountoperationdbus.h3
-rw-r--r--common/gmountsource.c278
-rw-r--r--common/gmountsource.h19
-rw-r--r--common/gvfsdaemonprotocol.h3
-rw-r--r--daemon/daemon-main.c98
-rw-r--r--daemon/daemon-main.h2
-rw-r--r--daemon/gvfsbackend.h6
-rw-r--r--daemon/gvfsbackendsmb.c6
-rw-r--r--daemon/gvfsbackendsmbbrowse.c8
-rw-r--r--daemon/gvfsbackendtest.c3
-rw-r--r--daemon/gvfsdaemon.c100
-rw-r--r--daemon/gvfsdaemon.h5
-rw-r--r--daemon/gvfsjobmount.c52
-rw-r--r--daemon/gvfsjobmount.h4
-rw-r--r--daemon/main.c4
-rw-r--r--daemon/mount.c227
-rw-r--r--daemon/mount.h10
-rw-r--r--daemon/mounttracker.c119
-rw-r--r--daemon/smb-browse.mount.in2
-rw-r--r--daemon/smb.mount.in2
-rwxr-xr-xgio/test-gio.c4
23 files changed, 480 insertions, 583 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 05cdaf8f..b710487e 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -913,7 +913,8 @@ mount_reply (DBusMessage *reply,
g_simple_async_result_complete (res);
g_object_unref (data->file);
- g_object_unref (data->mount_operation);
+ if (data->mount_operation)
+ g_object_unref (data->mount_operation);
g_free (data);
}
@@ -927,19 +928,26 @@ g_daemon_file_mount_for_location (GFile *location,
DBusMessage *message;
GMountSpec *spec;
GMountSource *mount_source;
+ DBusMessageIter iter;
MountData *data;
daemon_file = G_DAEMON_FILE (location);
-
- spec = g_mount_spec_copy (daemon_file->mount_spec);
- g_mount_spec_set_mount_prefix (spec, daemon_file->path);
- mount_source = g_mount_operation_dbus_wrap (mount_operation, spec);
- g_mount_spec_unref (spec);
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_MOUNT_LOCATION);
+
+ spec = g_mount_spec_copy (daemon_file->mount_spec);
+ g_mount_spec_set_mount_prefix (spec, daemon_file->path);
+ dbus_message_iter_init_append (message, &iter);
+ g_mount_spec_to_dbus (&iter, spec);
+ g_mount_spec_unref (spec);
+
+ if (mount_operation)
+ mount_source = g_mount_operation_dbus_wrap (mount_operation);
+ else
+ mount_source = g_mount_source_new_dummy ();
g_mount_source_to_dbus (mount_source, message);
g_object_unref (mount_source);
@@ -947,7 +955,8 @@ g_daemon_file_mount_for_location (GFile *location,
data->callback = callback;
data->user_data = user_data;
data->file = g_object_ref (location);
- data->mount_operation = g_object_ref (mount_operation);
+ if (mount_operation)
+ data->mount_operation = g_object_ref (mount_operation);
_g_dbus_connection_call_async (NULL, message, -1,
mount_reply, data);
diff --git a/common/gmountoperationdbus.c b/common/gmountoperationdbus.c
index f6aba91e..4956c07d 100644
--- a/common/gmountoperationdbus.c
+++ b/common/gmountoperationdbus.c
@@ -17,7 +17,6 @@ typedef struct
char *obj_path;
char *dbus_id;
DBusConnection *connection;
- GMountSpec *mount_spec;
} GMountOperationDBus;
static DBusHandlerResult mount_op_message_function (DBusConnection *connection,
@@ -29,10 +28,6 @@ static void mount_op_ask_password (GMountOperationDBus *op_d
DBusMessage *message);
static void mount_op_ask_question (GMountOperationDBus *op_dbus,
DBusMessage *message);
-static void mount_op_done (GMountOperationDBus *op_dbus,
- DBusMessage *message);
-static void mount_op_get_mount_spec (GMountOperationDBus *op_dbus,
- DBusMessage *message);
static void
g_mount_operation_dbus_free (GMountOperationDBus *op_dbus)
@@ -45,13 +40,11 @@ g_mount_operation_dbus_free (GMountOperationDBus *op_dbus)
}
g_free (op_dbus->dbus_id);
g_free (op_dbus->obj_path);
- g_mount_spec_unref (op_dbus->mount_spec);
g_free (op_dbus);
}
GMountSource *
-g_mount_operation_dbus_wrap (GMountOperation *op,
- GMountSpec *spec)
+g_mount_operation_dbus_wrap (GMountOperation *op)
{
GMountOperationDBus *op_dbus;
static int mount_id = 0;
@@ -63,7 +56,6 @@ g_mount_operation_dbus_wrap (GMountOperation *op,
op_dbus = g_new0 (GMountOperationDBus, 1);
op_dbus->op = op;
- op_dbus->mount_spec = g_mount_spec_ref (spec);
op_dbus->connection = dbus_bus_get (DBUS_BUS_SESSION, NULL);
op_dbus->obj_path = g_strdup_printf ("/org/gtk/gvfs/mountop/%d", mount_id++);
if (op_dbus->connection)
@@ -79,7 +71,7 @@ g_mount_operation_dbus_wrap (GMountOperation *op,
g_object_set_data_full (G_OBJECT (op), "dbus-op",
op_dbus, (GDestroyNotify)g_mount_operation_dbus_free);
- return g_mount_source_new_dbus (op_dbus->dbus_id, op_dbus->obj_path, spec);
+ return g_mount_source_new (op_dbus->dbus_id, op_dbus->obj_path);
}
/**
@@ -112,14 +104,6 @@ mount_op_message_function (DBusConnection *connection,
G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
"askQuestion"))
mount_op_ask_question (op_dbus, message);
- else if (dbus_message_is_method_call (message,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "done"))
- mount_op_done (op_dbus, message);
- else if (dbus_message_is_method_call (message,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "getMountSpec"))
- mount_op_get_mount_spec (op_dbus, message);
else
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -127,22 +111,6 @@ mount_op_message_function (DBusConnection *connection,
}
static void
-mount_op_get_mount_spec (GMountOperationDBus *op_dbus,
- DBusMessage *message)
-{
- DBusMessage *reply;
- DBusMessageIter iter;
-
- reply = dbus_message_new_method_return (message);
-
- dbus_message_iter_init_append (reply, &iter);
- g_mount_spec_to_dbus (&iter, op_dbus->mount_spec);
-
- if (!dbus_connection_send (op_dbus->connection, reply, NULL))
- _g_dbus_oom ();
-}
-
-static void
mount_op_send_reply (GMountOperationDBus *op_dbus,
DBusMessage *reply)
{
@@ -332,52 +300,3 @@ mount_op_ask_question (GMountOperationDBus *op_dbus,
dbus_free_string_array (choices);
}
-
-static void
-mount_op_done (GMountOperationDBus *op_dbus,
- DBusMessage *message)
-{
- const char *domain, *error_message;
- dbus_bool_t success;
- DBusMessageIter iter;
- DBusError derror;
- guint32 code;
- GError *error;
-
- dbus_message_iter_init (message, &iter);
-
- dbus_error_init (&derror);
- if (!_g_dbus_message_iter_get_args (&iter,
- &derror,
- DBUS_TYPE_BOOLEAN, &success,
- 0))
- {
- g_warning ("Can't get mountDone args: %s\n", derror.message);
- dbus_error_free (&derror);
- return;
- }
-
- error = NULL;
- if (!success)
- {
- if (_g_dbus_message_iter_get_args (&iter,
- &derror,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_UINT32, &code,
- DBUS_TYPE_STRING, &error_message,
- 0))
- error = g_error_new_literal (g_quark_from_string (domain),
- code, error_message);
- else
- {
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't parse mount error: %s", derror.message);
- dbus_error_free (&derror);
- }
- }
-
- g_signal_emit_by_name (op_dbus->op, "done", success, error);
-
- if (error)
- g_error_free (error);
-}
diff --git a/common/gmountoperationdbus.h b/common/gmountoperationdbus.h
index c4a14192..16c842b9 100644
--- a/common/gmountoperationdbus.h
+++ b/common/gmountoperationdbus.h
@@ -10,8 +10,7 @@
G_BEGIN_DECLS
-GMountSource *g_mount_operation_dbus_wrap (GMountOperation *op,
- GMountSpec *spec);
+GMountSource *g_mount_operation_dbus_wrap (GMountOperation *op);
G_END_DECLS
diff --git a/common/gmountsource.c b/common/gmountsource.c
index b5cec491..c4a6fbee 100644
--- a/common/gmountsource.c
+++ b/common/gmountsource.c
@@ -9,10 +9,8 @@ struct _GMountSource
{
GObject parent_instance;
- GMountSpec *mount_spec;
char *dbus_id;
char *obj_path;
- gboolean is_automount;
};
G_DEFINE_TYPE (GMountSource, g_mount_source, G_TYPE_OBJECT);
@@ -26,8 +24,6 @@ g_mount_source_finalize (GObject *object)
g_free (source->dbus_id);
g_free (source->obj_path);
- if (source->mount_spec)
- g_mount_spec_unref (source->mount_spec);
if (G_OBJECT_CLASS (g_mount_source_parent_class)->finalize)
(*G_OBJECT_CLASS (g_mount_source_parent_class)->finalize) (object);
@@ -44,60 +40,49 @@ g_mount_source_class_init (GMountSourceClass *klass)
static void
g_mount_source_init (GMountSource *mount_source)
{
- mount_source->is_automount = FALSE;
}
-void
-g_mount_source_set_is_automount (GMountSource *source,
- gboolean is_automount)
+GMountSource *
+g_mount_source_new (const char *dbus_id,
+ const char *obj_path)
{
- source->is_automount = is_automount;
-}
+ GMountSource *source;
-gboolean
-g_mount_source_get_is_automount (GMountSource *source)
-{
- return source->is_automount;
+ source = g_object_new (G_TYPE_MOUNT_SOURCE, NULL);
+
+ source->dbus_id = g_strdup (dbus_id);
+ source->obj_path = g_strdup (obj_path);
+
+ return source;
}
GMountSource *
-g_mount_source_new_dbus (const char *dbus_id,
- const char *obj_path,
- GMountSpec *spec)
+g_mount_source_new_dummy (void)
{
GMountSource *source;
source = g_object_new (G_TYPE_MOUNT_SOURCE, NULL);
-
- source->dbus_id = g_strdup (dbus_id);
- source->obj_path = g_strdup (obj_path);
- if (spec)
- source->mount_spec = g_mount_spec_ref (spec);
+
+ source->dbus_id = g_strdup ("");
+ source->obj_path = g_strdup ("/");
return source;
}
+
void
g_mount_source_to_dbus (GMountSource *source,
DBusMessage *message)
{
- dbus_bool_t automount;
- DBusMessageIter iter;
-
g_assert (source->dbus_id != NULL);
g_assert (source->obj_path != NULL);
- g_assert (source->mount_spec != NULL);
- automount = source->is_automount;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, &source->dbus_id,
DBUS_TYPE_OBJECT_PATH, &source->obj_path,
- DBUS_TYPE_BOOLEAN, &automount,
0))
_g_dbus_oom ();
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus (&iter, source->mount_spec);
}
const char *
@@ -112,237 +97,6 @@ g_mount_source_get_obj_path (GMountSource *mount_source)
return mount_source->obj_path;
}
-GMountSource *
-g_mount_source_new_null (GMountSpec *spec)
-{
- GMountSource *source;
-
- source = g_object_new (G_TYPE_MOUNT_SOURCE, NULL);
-
- source->mount_spec = g_mount_spec_ref (spec);
-
- return source;
-}
-
-static DBusMessage *
-send_sync_and_unref (DBusMessage *message,
- GError **error)
-{
- DBusError derror;
- DBusConnection *connection;
- DBusMessage *reply;
-
- dbus_error_init (&derror);
- connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
- if (connection == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't open dbus connection");
- dbus_message_unref (message);
- return NULL;
- }
-
- reply = dbus_connection_send_with_reply_and_block (connection, message, 4000, &derror);
- dbus_connection_unref (connection);
- dbus_message_unref (message);
- if (reply == NULL)
- {
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- return NULL;
- }
-
- return reply;
-}
-
-static void
-send_noreply_and_unref (DBusMessage *message)
-{
- DBusError derror;
- DBusConnection *connection;
-
- dbus_message_set_no_reply (message, TRUE);
-
- dbus_error_init (&derror);
- connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
- if (connection == NULL)
- {
- g_warning ("Can't get dbus connection");
- return;
- }
-
- dbus_connection_send (connection, message, NULL);
- dbus_message_unref (message);
- dbus_connection_unref (connection);
-}
-
-void
-g_mount_source_done (GMountSource *source)
-{
- dbus_bool_t succeeded_dbus = TRUE;
- DBusMessage *message;
-
- /* Fail gracefully if no source specified */
- if (source == NULL)
- return;
-
- if (source->dbus_id == NULL)
- return;
-
- message = dbus_message_new_method_call (source->dbus_id,
- source->obj_path,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "done");
- _g_dbus_message_append_args (message,
- DBUS_TYPE_BOOLEAN, &succeeded_dbus,
- 0);
-
- send_noreply_and_unref (message);
-}
-
-void
-g_mount_source_failed (GMountSource *source,
- GError *error)
-{
- dbus_bool_t succeeded_dbus = FALSE;
- DBusMessage *message;
- const char *domain;
- guint32 code;
-
- /* Fail gracefully if no source specified */
- if (source == NULL)
- return;
-
- if (source->dbus_id == NULL)
- {
- g_print ("Error mounting: %s\n", error->message);
- return;
- }
-
- message = dbus_message_new_method_call (source->dbus_id,
- source->obj_path,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "done");
-
- domain = g_quark_to_string (error->domain);
- code = error->code;
- _g_dbus_message_append_args (message,
- DBUS_TYPE_BOOLEAN, &succeeded_dbus,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_UINT32, &code,
- DBUS_TYPE_STRING, &error->message,
- 0);
-
- send_noreply_and_unref (message);
-}
-
-GMountSpec *
-g_mount_source_request_mount_spec (GMountSource *source,
- GError **error)
-{
- DBusMessage *message, *reply;
- DBusMessageIter iter;
-
- if (source->mount_spec)
- return source->mount_spec;
-
- g_assert (source->dbus_id != NULL || source->obj_path != NULL);
-
- message =
- dbus_message_new_method_call (source->dbus_id,
- source->obj_path,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "getMountSpec");
-
- reply = send_sync_and_unref (message, error);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init (reply, &iter);
- source->mount_spec = g_mount_spec_from_dbus (&iter);
- dbus_message_unref (reply);
- if (source->mount_spec == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "No mount spec gotten from mount source");
- return NULL;
- }
-
- return source->mount_spec;
-}
-
-typedef struct {
- GMountSource *source;
- RequestMountSpecCallback callback;
- gpointer user_data;
-} RequestMountSpecData;
-
-static void
-request_mount_spec_reply (DBusMessage *reply,
- GError *error,
- gpointer _data)
-{
- DBusMessageIter iter;
- RequestMountSpecData *data = _data;
-
- if (reply == NULL)
- {
- data->callback (data->source, NULL, error, data->user_data);
- goto out;
- }
-
- dbus_message_iter_init (reply, &iter);
- data->source->mount_spec = g_mount_spec_from_dbus (&iter);
-
- if (data->source->mount_spec == NULL)
- {
- error = NULL;
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "No mount spec gotten from mount source");
- data->callback (data->source, NULL, error, data->user_data);
- g_error_free (error);
- goto out;
- }
-
- data->callback (data->source, data->source->mount_spec, NULL, data->user_data);
-
- out:
- g_object_unref (data->source);
- g_free (data);
-}
-
-void
-g_mount_source_request_mount_spec_async (GMountSource *source,
- RequestMountSpecCallback callback,
- gpointer user_data)
-{
- RequestMountSpecData *data;
- DBusMessage *message;
-
- if (source->mount_spec)
- {
- callback (source, source->mount_spec, NULL, user_data);
- return;
- }
-
- g_assert (source->dbus_id != NULL || source->obj_path != NULL);
-
- message = dbus_message_new_method_call (source->dbus_id,
- source->obj_path,
- G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
- "getMountSpec");
-
-
- data = g_new (RequestMountSpecData, 1);
- data->source = g_object_ref (source);
- data->callback = callback;
- data->user_data = user_data;
-
- _g_dbus_connection_call_async (NULL, message, -1,
- request_mount_spec_reply, data);
- dbus_message_unref (message);
-}
-
typedef struct {
GMutex *mutex;
GCond *cond;
@@ -419,7 +173,7 @@ g_mount_source_ask_password (GMountSource *source,
*user_out = NULL;
*domain_out = NULL;
- if (source->dbus_id == NULL)
+ if (source->dbus_id[0] == 0)
return FALSE;
if (message_string == NULL)
diff --git a/common/gmountsource.h b/common/gmountsource.h
index 8d374eda..cff5e915 100644
--- a/common/gmountsource.h
+++ b/common/gmountsource.h
@@ -27,26 +27,13 @@ typedef void (*RequestMountSpecCallback) (GMountSource *source,
GError *error,
gpointer data);
-
GType g_mount_source_get_type (void) G_GNUC_CONST;
-GMountSource *g_mount_source_new_dbus (const char *dbus_id,
- const char *obj_path,
- GMountSpec *spec);
-GMountSource *g_mount_source_new_null (GMountSpec *spec);
+GMountSource *g_mount_source_new (const char *dbus_id,
+ const char *obj_path);
+GMountSource *g_mount_source_new_dummy (void);
void g_mount_source_to_dbus (GMountSource *source,
DBusMessage *message);
-GMountSpec * g_mount_source_request_mount_spec (GMountSource *source,
- GError **error);
-void g_mount_source_request_mount_spec_async (GMountSource *source,
- RequestMountSpecCallback callback,
- gpointer data);
-void g_mount_source_done (GMountSource *source);
-void g_mount_source_failed (GMountSource *source,
- GError *error);
-void g_mount_source_set_is_automount (GMountSource *source,
- gboolean is_automount);
-gboolean g_mount_source_get_is_automount (GMountSource *source);
gboolean g_mount_source_ask_password (GMountSource *mount_source,
const char *message,
const char *initial_user,
diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h
index bcaa4923..a4bfc784 100644
--- a/common/gvfsdaemonprotocol.h
+++ b/common/gvfsdaemonprotocol.h
@@ -40,6 +40,9 @@ G_BEGIN_DECLS
#define G_VFS_DBUS_MOUNT_OPERATION_INTERFACE "org.gtk.vfs.MountOperation"
+#define G_VFS_DBUS_SPAWNER_INTERFACE "org.gtk.vfs.Spawner"
+#define G_VFS_DBUS_OP_SPAWNED "Spawned"
+
typedef struct {
guint32 command;
guint32 seq_nr;
diff --git a/daemon/daemon-main.c b/daemon/daemon-main.c
index 47127a71..89eebd9e 100644
--- a/daemon/daemon-main.c
+++ b/daemon/daemon-main.c
@@ -9,8 +9,14 @@
#include "daemon-main.h"
#include <glib/gi18n.h>
#include <gvfsdaemon.h>
+#include <gvfsdaemonprotocol.h>
#include <gvfsbackend.h>
+static char *spawner_id = NULL;
+static char *spawner_path = NULL;
+
+
+
void
daemon_init (void)
{
@@ -31,25 +37,59 @@ daemon_init (void)
}
}
-GMountSource *
+static void
+send_spawned (DBusConnection *connection, gboolean succeeded, char *error_message)
+{
+ DBusMessage *message;
+ dbus_bool_t dbus_succeeded;
+
+ if (error_message == NULL)
+ error_message = "";
+
+ if (spawner_id == NULL || spawner_path == NULL)
+ {
+ if (!succeeded)
+ g_print ("Error: %s\n", error_message);
+ return;
+ }
+
+ message = dbus_message_new_method_call (spawner_id,
+ spawner_path,
+ G_VFS_DBUS_SPAWNER_INTERFACE,
+ "spawned");
+ dbus_message_set_no_reply (message, TRUE);
+
+ dbus_succeeded = succeeded;
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_BOOLEAN, &dbus_succeeded,
+ DBUS_TYPE_STRING, &error_message,
+ DBUS_TYPE_INVALID))
+ _g_dbus_oom ();
+
+ dbus_connection_send (connection, message, NULL);
+ /* Make sure the message is sent */
+ dbus_connection_flush (connection);
+}
+
+GMountSpec *
daemon_parse_args (int argc, char *argv[], const char *default_type)
{
- GMountSource *mount_source;
+ GMountSpec *mount_spec;
- mount_source = NULL;
- if (argc > 1 && strcmp (argv[1], "--dbus") == 0)
+ mount_spec = NULL;
+ if (argc > 1 && strcmp (argv[1], "--spawner") == 0)
{
if (argc < 4)
{
- g_printerr ("Usage: %s --dbus dbus-id object_path\n", argv[0]);
+ g_printerr ("Usage: %s --spawner dbus-id object_path\n", argv[0]);
exit (1);
}
-
- mount_source = g_mount_source_new_dbus (argv[2], argv[3], NULL);
+
+ spawner_id = argv[2];
+ spawner_path = argv[3];
}
else if (argc > 1 || default_type != NULL)
{
- GMountSpec *mount_spec;
gboolean found_type;
int i;
@@ -83,12 +123,9 @@ daemon_parse_args (int argc, char *argv[], const char *default_type)
g_printerr ("Usage: %s key=value key=value ...\n", argv[0]);
exit (1);
}
-
- mount_source = g_mount_source_new_null (mount_spec);
- g_mount_spec_unref (mount_spec);
}
- return mount_source;
+ return mount_spec;
}
void
@@ -105,12 +142,22 @@ daemon_main (int argc,
GMainLoop *loop;
GVfsDaemon *daemon;
DBusError derror;
+ GMountSpec *mount_spec;
GMountSource *mount_source;
GError *error;
int res;
const char *type;
- mount_source = daemon_parse_args (argc, argv, default_type);
+ dbus_error_init (&derror);
+ connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+ if (connection == NULL)
+ {
+ g_printerr (_("Error connecting dbus: %s\n"), derror.message);
+ dbus_error_free (&derror);
+ exit (1);
+ }
+
+ mount_spec = daemon_parse_args (argc, argv, default_type);
va_start (var_args, first_type_name);
@@ -128,14 +175,6 @@ daemon_main (int argc,
error = NULL;
if (mountable_name)
{
- dbus_error_init (&derror);
- connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
- if (connection == NULL)
- {
- g_printerr (_("Error connecting dbus: %s\n"), derror.message);
- dbus_error_free (&derror);
- exit (1);
- }
res = dbus_bus_request_name (connection,
mountable_name,
@@ -148,7 +187,9 @@ daemon_main (int argc,
else
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("mountpoint for %s already running"), mountable_name);
- g_mount_source_failed (mount_source, error);
+
+ send_spawned (connection, FALSE, error->message);
+ g_error_free (error);
exit (1);
}
}
@@ -156,23 +197,24 @@ daemon_main (int argc,
daemon = g_vfs_daemon_new (FALSE, FALSE);
if (daemon == NULL)
{
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("error starting mount daemon"));
- g_mount_source_failed (mount_source, error);
+ send_spawned (connection, FALSE, _("error starting mount daemon"));
exit (1);
}
g_vfs_daemon_set_max_threads (daemon, max_job_threads);
- if (mount_source)
+ send_spawned (connection, TRUE, NULL);
+
+ if (mount_spec)
{
- g_vfs_daemon_initiate_mount (daemon, mount_source);
+ mount_source = g_mount_source_new_dummy ();
+ g_vfs_daemon_initiate_mount (daemon, mount_spec, mount_source, FALSE, NULL);
+ g_mount_spec_unref (mount_spec);
g_object_unref (mount_source);
}
loop = g_main_loop_new (NULL, FALSE);
- g_print ("Entering mainloop\n");
g_main_loop_run (loop);
}
diff --git a/daemon/daemon-main.h b/daemon/daemon-main.h
index 4c0eec13..4be60a57 100644
--- a/daemon/daemon-main.h
+++ b/daemon/daemon-main.h
@@ -6,7 +6,7 @@
G_BEGIN_DECLS
void daemon_init (void);
-GMountSource *daemon_parse_args (int argc,
+GMountSpec *daemon_parse_args (int argc,
char *argv[],
const char *default_type);
void daemon_main (int argc,
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index 4a2a65d1..8dc90443 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -61,11 +61,13 @@ struct _GVfsBackendClass
void (*mount) (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source);
+ GMountSource *mount_source,
+ gboolean is_automount);
gboolean (*try_mount) (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source);
+ GMountSource *mount_source,
+ gboolean is_automount);
void (*open_for_read) (GVfsBackend *backend,
GVfsJobOpenForRead *job,
const char *filename);
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
index 03a1ade1..fcdc2bfe 100644
--- a/daemon/gvfsbackendsmb.c
+++ b/daemon/gvfsbackendsmb.c
@@ -384,7 +384,8 @@ static void
do_mount (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source)
+ GMountSource *mount_source,
+ gboolean is_automount)
{
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
SMBCCTX *smb_context;
@@ -496,7 +497,8 @@ static gboolean
try_mount (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source)
+ GMountSource *mount_source,
+ gboolean is_automount)
{
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
const char *server, *share, *user, *domain;
diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c
index 9847fb5e..4c2d0cd1 100644
--- a/daemon/gvfsbackendsmbbrowse.c
+++ b/daemon/gvfsbackendsmbbrowse.c
@@ -470,7 +470,8 @@ static void
do_mount (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source)
+ GMountSource *mount_source,
+ gboolean is_automount)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
SMBCCTX *smb_context;
@@ -556,7 +557,8 @@ static gboolean
try_mount (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source)
+ GMountSource *mount_source,
+ gboolean is_automount)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
const char *server;
@@ -581,7 +583,7 @@ try_mount (GVfsBackend *backend,
user = g_mount_spec_get (mount_spec, "user");
domain = g_mount_spec_get (mount_spec, "domain");
- if (g_mount_source_get_is_automount (mount_source) &&
+ if (is_automount &&
((user != NULL) || (domain != NULL)))
{
g_vfs_job_failed (G_VFS_JOB (job),
diff --git a/daemon/gvfsbackendtest.c b/daemon/gvfsbackendtest.c
index 3e20616d..c3bd54fe 100644
--- a/daemon/gvfsbackendtest.c
+++ b/daemon/gvfsbackendtest.c
@@ -51,7 +51,8 @@ static gboolean
try_mount (GVfsBackend *backend,
GVfsJobMount *job,
GMountSpec *mount_spec,
- GMountSource *mount_source)
+ GMountSource *mount_source,
+ gboolean is_automount)
{
g_vfs_job_succeeded (G_VFS_JOB (job));
return TRUE;
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index 0aabb86b..80eab2bf 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -187,8 +187,6 @@ g_vfs_daemon_new (gboolean main_daemon, gboolean replace)
unsigned int flags;
int ret;
- g_print ("main_daemon: %d, replace %d\n", main_daemon, replace);
-
dbus_error_init (&error);
conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
if (!conn)
@@ -212,7 +210,6 @@ g_vfs_daemon_new (gboolean main_daemon, gboolean replace)
if (replace)
flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
- g_print ("requesting name\n");
ret = dbus_bus_request_name (conn, G_VFS_DBUS_DAEMON_NAME, flags, &error);
if (ret == -1)
{
@@ -788,35 +785,34 @@ daemon_start_mount (GVfsDaemon *daemon,
dbus_message_iter_init (message, &iter);
+ reply = NULL;
mount_spec = NULL;
dbus_error_init (&derror);
- if (!_g_dbus_message_iter_get_args (&iter, &derror,
- DBUS_TYPE_STRING, &dbus_id,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_BOOLEAN, &automount,
- 0))
+ if ((mount_spec = g_mount_spec_from_dbus (&iter)) == NULL)
+ reply = dbus_message_new_error (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "Error in mount spec");
+ else if (!_g_dbus_message_iter_get_args (&iter, &derror,
+ DBUS_TYPE_BOOLEAN, &automount,
+ DBUS_TYPE_STRING, &dbus_id,
+ DBUS_TYPE_OBJECT_PATH, &obj_path,
+ 0))
{
reply = dbus_message_new_error (message, derror.name, derror.message);
dbus_error_free (&derror);
}
- else if ((mount_spec = g_mount_spec_from_dbus (&iter)) == NULL)
- reply = dbus_message_new_error (message,
- DBUS_ERROR_INVALID_ARGS,
- "Error in mount spec");
- else
- reply = dbus_message_new_method_return (message);
-
- dbus_connection_send (connection, reply, NULL);
- dbus_message_unref (reply);
- if (mount_spec)
+ if (reply)
{
- mount_source = g_mount_source_new_dbus (dbus_id, obj_path, mount_spec);
- g_mount_source_set_is_automount (mount_source, automount);
- g_mount_spec_unref (mount_spec);
-
- g_vfs_daemon_initiate_mount (daemon, mount_source);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ }
+ else
+ {
+ mount_source = g_mount_source_new (dbus_id, obj_path);
+ g_vfs_daemon_initiate_mount (daemon, mount_spec, mount_source, automount, message);
g_object_unref (mount_source);
+ g_mount_spec_unref (mount_spec);
}
}
@@ -829,8 +825,6 @@ daemon_message_func (DBusConnection *conn,
RegisteredPath *registered_path;
const char *path;
- g_print ("daemon_message_func\n");
-
path = dbus_message_get_path (message);
if (path == NULL)
path = "";
@@ -931,25 +925,20 @@ peer_to_peer_filter_func (DBusConnection *conn,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-static void
-mount_got_spec (GMountSource *mount_source,
- GMountSpec *mount_spec,
- GError *error,
- gpointer data)
+void
+g_vfs_daemon_initiate_mount (GVfsDaemon *daemon,
+ GMountSpec *mount_spec,
+ GMountSource *mount_source,
+ gboolean is_automount,
+ DBusMessage *request)
{
- GVfsDaemon *daemon = data;
const char *type;
GType backend_type;
char *obj_path;
GVfsJob *job;
GVfsBackend *backend;
- GError *io_error;
-
- if (mount_spec == NULL)
- {
- g_mount_source_failed (mount_source, error);
- return;
- }
+ DBusConnection *conn;
+ DBusMessage *reply;
type = g_mount_spec_get_type (mount_spec);
@@ -959,11 +948,23 @@ mount_got_spec (GMountSource *mount_source,
if (backend_type == G_TYPE_INVALID)
{
- io_error = NULL;
- g_set_error (&io_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Unsupported mount type");
- g_mount_source_failed (mount_source, io_error);
- g_error_free (io_error);
+ if (request)
+ {
+ reply = _dbus_message_new_gerror (request,
+ G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Invalid backend type"));
+
+ /* Queues reply (threadsafely), actually sends it in mainloop */
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (conn)
+ {
+ dbus_connection_send (conn, reply, NULL);
+ dbus_message_unref (reply);
+ dbus_connection_unref (conn);
+ }
+ }
+ else
+ g_warning ("Error mounting: invalid backend type\n");
return;
}
@@ -976,17 +977,6 @@ mount_got_spec (GMountSource *mount_source,
g_vfs_daemon_add_job_source (daemon, G_VFS_JOB_SOURCE (backend));
g_object_unref (backend);
- job = g_vfs_job_mount_new (mount_spec, mount_source, backend);
+ job = g_vfs_job_mount_new (mount_spec, mount_source, is_automount, request, backend);
g_vfs_daemon_queue_job (daemon, job);
-
- g_object_unref (mount_source);
-}
-
-void
-g_vfs_daemon_initiate_mount (GVfsDaemon *daemon,
- GMountSource *mount_source)
-{
- g_object_ref (mount_source);
- g_mount_source_request_mount_spec_async (mount_source,
- mount_got_spec, daemon);
}
diff --git a/daemon/gvfsdaemon.h b/daemon/gvfsdaemon.h
index 61fb7af0..b74d7767 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -44,7 +44,10 @@ void g_vfs_daemon_register_path (GVfsDaemon *daemon,
void g_vfs_daemon_unregister_path (GVfsDaemon *daemon,
const char *obj_path);
void g_vfs_daemon_initiate_mount (GVfsDaemon *daemon,
- GMountSource *mount_source);
+ GMountSpec *mount_spec,
+ GMountSource *mount_source,
+ gboolean is_automount,
+ DBusMessage *request);
G_END_DECLS
diff --git a/daemon/gvfsjobmount.c b/daemon/gvfsjobmount.c
index d1b1527d..76b51e0e 100644
--- a/daemon/gvfsjobmount.c
+++ b/daemon/gvfsjobmount.c
@@ -52,6 +52,8 @@ g_vfs_job_mount_init (GVfsJobMount *job)
GVfsJob *
g_vfs_job_mount_new (GMountSpec *spec,
GMountSource *source,
+ gboolean is_automount,
+ DBusMessage *request,
GVfsBackend *backend)
{
GVfsJobMount *job;
@@ -61,7 +63,10 @@ g_vfs_job_mount_new (GMountSpec *spec,
job->mount_spec = g_mount_spec_ref (spec);
job->mount_source = g_object_ref (source);
+ job->is_automount = is_automount;
job->backend = backend;
+ if (request)
+ job->request = dbus_message_ref (request);
return G_VFS_JOB (job);
}
@@ -75,7 +80,8 @@ run (GVfsJob *job)
class->mount (op_job->backend,
op_job,
op_job->mount_spec,
- op_job->mount_source);
+ op_job->mount_source,
+ op_job->is_automount);
}
static gboolean
@@ -90,16 +96,32 @@ try (GVfsJob *job)
return class->try_mount (op_job->backend,
op_job,
op_job->mount_spec,
- op_job->mount_source);
+ op_job->mount_source,
+ op_job->is_automount);
}
static void
mount_failed (GVfsJobMount *op_job, GError *error)
{
+ DBusConnection *conn;
+ DBusMessage *reply;
GVfsBackend *backend;
-
+
+ if (op_job->request)
+ {
+ reply = _dbus_message_new_from_gerror (op_job->request, error);
+
+ /* Queues reply (threadsafely), actually sends it in mainloop */
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (conn)
+ {
+ dbus_connection_send (conn, reply, NULL);
+ dbus_message_unref (reply);
+ dbus_connection_unref (conn);
+ }
+ }
+
backend = g_object_ref (op_job->backend);
- g_mount_source_failed (op_job->mount_source, error);
g_vfs_job_emit_finished (G_VFS_JOB (op_job));
/* Remove failed backend from daemon */
@@ -108,19 +130,33 @@ mount_failed (GVfsJobMount *op_job, GError *error)
}
static void
-register_mount_callback (DBusMessage *reply,
+register_mount_callback (DBusMessage *mount_reply,
GError *error,
gpointer user_data)
{
GVfsJobMount *op_job = G_VFS_JOB_MOUNT (user_data);
+ DBusConnection *conn;
+ DBusMessage *reply;
- g_print ("register_mount_callback, reply: %p, error: %p\n", reply, error);
+ g_print ("register_mount_callback, mount_reply: %p, error: %p\n", mount_reply, error);
- if (reply == NULL)
+ if (mount_reply == NULL)
mount_failed (op_job, error);
else
{
- g_mount_source_done (op_job->mount_source);
+ if (op_job->request)
+ {
+ reply = dbus_message_new_method_return (op_job->request);
+ /* Queues reply (threadsafely), actually sends it in mainloop */
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (conn)
+ {
+ dbus_connection_send (conn, reply, NULL);
+ dbus_message_unref (reply);
+ dbus_connection_unref (conn);
+ }
+ }
+
g_vfs_job_emit_finished (G_VFS_JOB (op_job));
}
}
diff --git a/daemon/gvfsjobmount.h b/daemon/gvfsjobmount.h
index bf41e2c7..03706d6d 100644
--- a/daemon/gvfsjobmount.h
+++ b/daemon/gvfsjobmount.h
@@ -22,8 +22,10 @@ struct _GVfsJobMount
GVfsJob parent_instance;
GVfsBackend *backend;
+ gboolean is_automount;
GMountSpec *mount_spec;
GMountSource *mount_source;
+ DBusMessage *request;
};
struct _GVfsJobMountClass
@@ -35,6 +37,8 @@ GType g_vfs_job_mount_get_type (void) G_GNUC_CONST;
GVfsJob *g_vfs_job_mount_new (GMountSpec *spec,
GMountSource *source,
+ gboolean is_automount,
+ DBusMessage *request,
GVfsBackend *backend);
G_END_DECLS
diff --git a/daemon/main.c b/daemon/main.c
index 4b1013c9..20c96abf 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -23,6 +23,8 @@ main (int argc, char *argv[])
{ NULL }
};
+ g_thread_init (NULL);
+
g_set_application_name (_("GVFS Daemon"));
context = g_option_context_new (_(""));
@@ -41,8 +43,6 @@ main (int argc, char *argv[])
dbus_threads_init_default ();
- g_thread_init (NULL);
-
g_type_init ();
daemon = g_vfs_daemon_new (TRUE, replace);
diff --git a/daemon/mount.c b/daemon/mount.c
index edd18f34..1e038a95 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -102,94 +102,91 @@ lookup_mountable (GMountSpec *spec)
return find_mountable (type);
}
+typedef struct {
+ Mountable *mountable;
+ dbus_bool_t automount;
+ GMountSource *source;
+ GMountSpec *mount_spec;
+ MountCallback callback;
+ gpointer user_data;
+ char *obj_path;
+ gboolean spawned;
+} MountData;
+
+static void spawn_mount (MountData *data);
+
static void
-exec_mount (Mountable *mountable,
- GMountSource *source)
+mount_data_free (MountData *data)
{
- char *exec;
- GError *error;
+ g_object_unref (data->source);
+ g_mount_spec_unref (data->mount_spec);
+ g_free (data->obj_path);
- error = NULL;
- if (mountable->exec == NULL)
- {
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No exec key defined for mountpoint");
- g_mount_source_failed (source, error);
- g_error_free (error);
- }
- else
- {
- exec = g_strconcat (mountable->exec, " ", g_mount_source_get_dbus_id (source), " ", g_mount_source_get_obj_path (source), NULL);
- if (!g_spawn_command_line_async (exec, &error))
- {
- g_mount_source_failed (source, error);
- g_error_free (error);
- }
- g_free (exec);
- }
+ g_free (data);
+}
+
+static void
+mount_finish (MountData *data, GError *error)
+{
+ data->callback (data->mountable, error, data->user_data);
+ mount_data_free (data);
}
static void
dbus_mount_reply (DBusPendingCall *pending,
- void *user_data)
+ void *_data)
{
- GMountSource *source = user_data;
- Mountable *mountable;
DBusMessage *reply;
GError *error;
+ MountData *data = _data;
- mountable = g_object_get_data (G_OBJECT (source), "mountable");
-
reply = dbus_pending_call_steal_reply (pending);
dbus_pending_call_unref (pending);
- if (dbus_message_is_error (reply, DBUS_ERROR_NAME_HAS_NO_OWNER) ||
- dbus_message_is_error (reply, DBUS_ERROR_SERVICE_UNKNOWN))
- exec_mount (mountable, source);
+ if ((dbus_message_is_error (reply, DBUS_ERROR_NAME_HAS_NO_OWNER) ||
+ dbus_message_is_error (reply, DBUS_ERROR_SERVICE_UNKNOWN)) &&
+ !data->spawned)
+ spawn_mount (data);
else
{
error = NULL;
if (_g_error_from_message (reply, &error))
{
- g_mount_source_failed (source, error);
+ mount_finish (data, error);
g_error_free (error);
}
+ else
+ mount_finish (data, NULL);
}
dbus_message_unref (reply);
}
-void
-mountable_mount (Mountable *mountable,
- GMountSource *source)
+static void
+mountable_mount_with_name (MountData *data,
+ const char *dbus_name)
{
DBusConnection *conn;
DBusMessage *message;
DBusPendingCall *pending;
GError *error = NULL;
-
- if (mountable->dbus_name == NULL)
- {
- exec_mount (mountable, source);
- return;
- }
+ DBusMessageIter iter;
conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
- if (conn == NULL)
- {
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection");
- g_mount_source_failed (source, error);
- g_error_free (error);
- return;
- }
-
- message = dbus_message_new_method_call (mountable->dbus_name,
+ message = dbus_message_new_method_call (dbus_name,
G_VFS_DBUS_MOUNTABLE_PATH,
G_VFS_DBUS_MOUNTABLE_INTERFACE,
"mount");
- g_mount_source_to_dbus (source, message);
+ dbus_message_iter_init_append (message, &iter);
+ g_mount_spec_to_dbus (&iter, data->mount_spec);
+
+ _g_dbus_message_append_args (message,
+ DBUS_TYPE_BOOLEAN, &data->automount,
+ 0);
+
+ g_mount_source_to_dbus (data->source, message);
+
if (!dbus_connection_send_with_reply (conn, message,
&pending,
2000))
@@ -203,16 +200,134 @@ mountable_mount (Mountable *mountable,
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error while getting peer-to-peer dbus connection: %s",
"Connection is closed");
- g_mount_source_failed (source, error);
+ mount_finish (data, error);
g_error_free (error);
return;
}
-
- g_object_set_data (G_OBJECT (source), "mountable", mountable);
if (!dbus_pending_call_set_notify (pending,
dbus_mount_reply,
- g_object_ref (source),
- g_object_unref))
+ data, NULL))
_g_dbus_oom ();
}
+
+static void
+spawn_mount_unregister_function (DBusConnection *connection,
+ void *user_data)
+{
+}
+
+static DBusHandlerResult
+spawn_mount_message_function (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ MountData *data = user_data;
+ GError *error = NULL;
+ dbus_bool_t succeeded;
+ char *error_message;
+
+ if (dbus_message_is_method_call (message,
+ G_VFS_DBUS_SPAWNER_INTERFACE,
+ "spawned"))
+ {
+ dbus_connection_unregister_object_path (connection, data->obj_path);
+
+ if (!dbus_message_get_args (message, NULL,
+ DBUS_TYPE_BOOLEAN, &succeeded,
+ DBUS_TYPE_STRING, &error_message,
+ DBUS_TYPE_INVALID))
+ {
+ g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Invalid arguments from spawned child"));
+ mount_finish (data, error);
+ g_error_free (error);
+ }
+ else if (!succeeded)
+ {
+ g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, error_message);
+ mount_finish (data, error);
+ g_error_free (error);
+ }
+ else
+ mountable_mount_with_name (data, dbus_message_get_sender (message));
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void
+spawn_mount (MountData *data)
+{
+ char *exec;
+ GError *error;
+ DBusConnection *connection;
+ static int mount_id = 0;
+ DBusObjectPathVTable spawn_vtable = {
+ spawn_mount_unregister_function,
+ spawn_mount_message_function
+ };
+
+ data->spawned = TRUE;
+
+ error = NULL;
+ if (data->mountable->exec == NULL)
+ {
+ g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No exec key defined for mountpoint");
+ mount_finish (data, error);
+ g_error_free (error);
+ }
+ else
+ {
+ data->obj_path = g_strdup_printf ("/org/gtk/gvfs/exec_spaw/%d", mount_id++);
+
+ connection = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (!dbus_connection_register_object_path (connection,
+ data->obj_path,
+ &spawn_vtable,
+ data))
+ _g_dbus_oom ();
+
+ exec = g_strconcat (data->mountable->exec, " --spawner ", dbus_bus_get_unique_name (connection), " ", data->obj_path, NULL);
+
+ if (!g_spawn_command_line_async (exec, &error))
+ {
+ dbus_connection_unregister_object_path (connection, data->obj_path);
+ mount_finish (data, error);
+ g_error_free (error);
+ }
+
+ /* TODO: Add a timeout here to detect spawned app crashing */
+
+ dbus_connection_unref (connection);
+ g_free (exec);
+ }
+}
+
+void
+mountable_mount (Mountable *mountable,
+ GMountSpec *mount_spec,
+ GMountSource *source,
+ gboolean automount,
+ MountCallback callback,
+ gpointer user_data)
+{
+ MountData *data;
+
+ data = g_new0 (MountData, 1);
+ data->automount = automount;
+ data->mountable = mountable;
+ data->source = g_object_ref (source);
+ data->mount_spec = g_mount_spec_ref (mount_spec);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ if (mountable->dbus_name == NULL)
+ spawn_mount (data);
+ else
+ mountable_mount_with_name (data, mountable->dbus_name);
+
+}
diff --git a/daemon/mount.h b/daemon/mount.h
index aa4ce5fe..95c9df2c 100644
--- a/daemon/mount.h
+++ b/daemon/mount.h
@@ -9,11 +9,19 @@ G_BEGIN_DECLS
typedef struct _Mountable Mountable;
+typedef void (*MountCallback) (Mountable *mountable,
+ GError *error,
+ gpointer user_data);
+
void mount_init (void);
Mountable *lookup_mountable (GMountSpec *spec);
gboolean mountable_is_automount (Mountable *mountable);
void mountable_mount (Mountable *mountable,
- GMountSource *source);
+ GMountSpec *mount_spec,
+ GMountSource *source,
+ gboolean automount,
+ MountCallback callback,
+ gpointer user_data);
G_END_DECLS
diff --git a/daemon/mounttracker.c b/daemon/mounttracker.c
index de5af3f8..50050ce0 100644
--- a/daemon/mounttracker.c
+++ b/daemon/mounttracker.c
@@ -241,15 +241,14 @@ typedef struct {
} AutoMountData;
static void
-automount_done (GMountOperation *op,
- gboolean succeeded,
- GError *error,
+automount_done (Mountable *mountable,
+ GError *error,
gpointer _data)
{
DBusMessage *reply;
AutoMountData *data = _data;
- if (!succeeded)
+ if (error)
{
reply = _dbus_message_new_gerror (data->message,
G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED,
@@ -262,8 +261,6 @@ automount_done (GMountOperation *op,
data->message,
FALSE);
- g_object_unref (op);
-
dbus_connection_unref (data->connection);
dbus_message_unref (data->message);
g_free (data);
@@ -285,25 +282,20 @@ maybe_automount (GMountTracker *tracker,
if (mountable != NULL && do_automount &&
mountable_is_automount (mountable))
{
- GMountOperation *op;
AutoMountData *data;
GMountSource *mount_source;
g_print ("automounting...\n");
- op = g_mount_operation_new ();
- mount_source = g_mount_operation_dbus_wrap (op, spec);
- g_mount_source_set_is_automount (mount_source, TRUE);
+ mount_source = g_mount_source_new_dummy ();
data = g_new0 (AutoMountData, 1);
data->tracker = tracker;
data->message = dbus_message_ref (message);
data->connection = dbus_connection_ref (connection);
- g_signal_connect (op, "done", (GCallback)automount_done, data);
- mountable_mount (mountable, mount_source);
+ mountable_mount (mountable, spec, mount_source, TRUE, automount_done, data);
g_object_unref (mount_source);
-
}
else
{
@@ -331,6 +323,8 @@ lookup_mount (GMountTracker *tracker,
dbus_message_iter_init (message, &iter);
spec = g_mount_spec_from_dbus (&iter);
+ g_print ("lookup_mount\n");
+
reply = NULL;
if (spec != NULL)
{
@@ -418,6 +412,36 @@ list_mounts (GMountTracker *tracker,
}
static void
+mount_location_done (Mountable *mountable,
+ GError *error,
+ gpointer user_data)
+{
+ DBusMessage *message, *reply;
+ DBusConnection *conn;
+
+ message = user_data;
+
+ if (error)
+ reply = _dbus_message_new_from_gerror (message, error);
+ else
+ reply = dbus_message_new_method_return (message);
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ _g_dbus_oom ();
+
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (conn)
+ {
+ dbus_connection_send (conn, reply, NULL);
+ dbus_connection_unref (conn);
+ }
+
+ dbus_message_unref (reply);
+}
+
+static void
mount_location (GMountTracker *tracker,
DBusConnection *connection,
DBusMessage *message)
@@ -428,65 +452,62 @@ mount_location (GMountTracker *tracker,
GMountSpec *spec;
const char *obj_path, *dbus_id;
Mountable *mountable;
- dbus_bool_t automount;
dbus_message_iter_init (message, &iter);
mountable = NULL;
spec = NULL;
reply = NULL;
- dbus_error_init (&derror);
- if (_g_dbus_message_iter_get_args (&iter,
- &derror,
- DBUS_TYPE_STRING, &dbus_id,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_BOOLEAN, &automount,
- 0))
+
+ spec = g_mount_spec_from_dbus (&iter);
+ if (spec == NULL)
+ reply = dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+ else
{
- spec = g_mount_spec_from_dbus (&iter);
- if (spec != NULL)
+ dbus_error_init (&derror);
+ if (!_g_dbus_message_iter_get_args (&iter,
+ &derror,
+ DBUS_TYPE_STRING, &dbus_id,
+ DBUS_TYPE_OBJECT_PATH, &obj_path,
+ 0))
+ {
+ reply = dbus_message_new_error (message, derror.name, derror.message);
+ dbus_error_free (&derror);
+ }
+ else
{
VFSMount *mount;
mount = match_vfs_mount (tracker, spec);
+
if (mount != NULL)
- {
- reply = _dbus_message_new_gerror (message,
- G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED,
- _("Location is already mounted"));
- }
+ reply = _dbus_message_new_gerror (message,
+ G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED,
+ _("Location is already mounted"));
else
{
mountable = lookup_mountable (spec);
-
+
if (mountable == NULL)
- {
- reply = _dbus_message_new_gerror (message,
- G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED,
- _("Location is not mountable"));
- }
+ reply = _dbus_message_new_gerror (message,
+ G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED,
+ _("Location is not mountable"));
}
}
- else
- reply = dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments");
- }
- else
- {
- reply = dbus_message_new_error (message, derror.name, derror.message);
- dbus_error_free (&derror);
}
- if (reply == NULL)
- _g_dbus_oom ();
-
if (reply)
dbus_connection_send (connection, reply, NULL);
-
- if (mountable)
+ else
{
GMountSource *source;
- source = g_mount_source_new_dbus (dbus_id, obj_path, spec);
- mountable_mount (mountable, source);
+
+ source = g_mount_source_new (dbus_id, obj_path);
+ mountable_mount (mountable,
+ spec,
+ source,
+ FALSE,
+ mount_location_done, dbus_message_ref (message));
g_object_unref (source);
}
diff --git a/daemon/smb-browse.mount.in b/daemon/smb-browse.mount.in
index 6ef77a68..39a791f0 100644
--- a/daemon/smb-browse.mount.in
+++ b/daemon/smb-browse.mount.in
@@ -1,6 +1,6 @@
[Mount]
Type=smb-network;smb-server
-Exec=@libexecdir@/gvfs-daemon-smb-browse --dbus
+Exec=@libexecdir@/gvfs-daemon-smb-browse
DBusName=org.gtk.vfs.mountpoint.smb_browse
AutoMount=true
diff --git a/daemon/smb.mount.in b/daemon/smb.mount.in
index f78c61ef..cce2dc77 100644
--- a/daemon/smb.mount.in
+++ b/daemon/smb.mount.in
@@ -1,4 +1,4 @@
[Mount]
Type=smb-share
-Exec=@libexecdir@/gvfs-daemon-smb --dbus
+Exec=@libexecdir@/gvfs-daemon-smb
AutoMount=false
diff --git a/gio/test-gio.c b/gio/test-gio.c
index 688b50cd..fabb4a16 100755
--- a/gio/test-gio.c
+++ b/gio/test-gio.c
@@ -581,11 +581,11 @@ main (int argc, char *argv[])
}
file = g_file_get_for_path ("/tmp");
- if (0) test_sync ("test:///etc/passwd", FALSE);
+ if (1) test_sync ("test:///etc/passwd", FALSE);
if (0) test_async ("test:///etc/passwd", TRUE);
if (0) test_out ();
- if (1) test_get_content ();
+ if (0) test_get_content ();
g_print ("Starting mainloop\n");