summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@src.gnome.org>2007-09-13 11:25:55 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-09-13 11:25:55 +0000
commit2e6f0c31af7c2b1262db3e84654c1c2ed082a18a (patch)
tree21eec64a5d41bfbb087289d533d90cfab6b6b0df
parent5950303721316b204dd2e98323e3696dcc59c328 (diff)
downloadgvfs-2e6f0c31af7c2b1262db3e84654c1c2ed082a18a.tar.gz
More work on mounting. Automount of smb now works (test).
Original git commit by Alexander Larsson <alex@greebo.(none)> at 1170415025 +0100 svn path=/trunk/; revision=296
-rw-r--r--client/gvfsimpldaemon.c4
-rw-r--r--common/gmountoperationdbus.c30
-rw-r--r--common/gmountoperationdbus.h4
-rw-r--r--common/gmountspec.c20
-rw-r--r--common/gmountspec.h4
-rw-r--r--daemon/.gitignore1
-rw-r--r--daemon/Makefile.am13
-rw-r--r--daemon/gvfsbackendsmb.c39
-rw-r--r--daemon/gvfsbackendsmb.h5
-rw-r--r--daemon/main.c3
-rw-r--r--daemon/mount.c126
-rw-r--r--daemon/mount.h24
-rw-r--r--daemon/mounttracker.c129
-rw-r--r--daemon/smb.c129
-rw-r--r--daemon/smb.mount.in4
-rw-r--r--gio/gmountoperation.c15
16 files changed, 491 insertions, 59 deletions
diff --git a/client/gvfsimpldaemon.c b/client/gvfsimpldaemon.c
index d795cb1e..c75f461b 100644
--- a/client/gvfsimpldaemon.c
+++ b/client/gvfsimpldaemon.c
@@ -76,7 +76,7 @@ get_mountspec_from_uri (GDecodedUri *uri,
{
spec = g_mount_spec_new ("smb-share");
- g_mount_spec_add_item (spec, "server", uri->host);
+ g_mount_spec_set (spec, "server", uri->host);
share = uri->path + 1;
share_end = strchr (share, '/');
@@ -86,7 +86,7 @@ get_mountspec_from_uri (GDecodedUri *uri,
else
tmp = g_strdup (share);
- g_mount_spec_add_item (spec, "share", tmp);
+ g_mount_spec_set (spec, "share", tmp);
g_free (tmp);
if (share_end)
diff --git a/common/gmountoperationdbus.c b/common/gmountoperationdbus.c
index fd968993..79b689ad 100644
--- a/common/gmountoperationdbus.c
+++ b/common/gmountoperationdbus.c
@@ -21,6 +21,8 @@ static void mount_op_ask_question (GMountOperationDBus *op,
DBusMessage *message);
static void mount_op_done (GMountOperationDBus *op,
DBusMessage *message);
+static void mount_op_get_mount_spec (GMountOperationDBus *op,
+ DBusMessage *message);
static void
g_mount_operation_dbus_finalize (GObject *object)
@@ -67,9 +69,14 @@ g_mount_operation_dbus_init (GMountOperationDBus *operation)
}
GMountOperationDBus *
-g_mount_operation_dbus_new (void)
+g_mount_operation_dbus_new (GMountSpec *spec)
{
- return g_object_new (G_TYPE_MOUNT_OPERATION_DBUS, NULL);
+ GMountOperationDBus *op;
+
+ op = g_object_new (G_TYPE_MOUNT_OPERATION_DBUS, NULL);
+ op->mount_spec = g_mount_spec_ref (spec);
+
+ return op;
}
@@ -107,12 +114,31 @@ mount_op_message_function (DBusConnection *connection,
G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
"done"))
mount_op_done (op, message);
+ else if (dbus_message_is_method_call (message,
+ G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
+ "getMountSpec"))
+ mount_op_get_mount_spec (op, message);
else
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
return DBUS_HANDLER_RESULT_HANDLED;
}
+static void
+mount_op_get_mount_spec (GMountOperationDBus *op,
+ 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->mount_spec);
+
+ if (!dbus_connection_send (op->connection, reply, NULL))
+ _g_dbus_oom ();
+}
static void
mount_op_send_reply (GMountOperationDBus *op,
diff --git a/common/gmountoperationdbus.h b/common/gmountoperationdbus.h
index 986552e4..dce774fc 100644
--- a/common/gmountoperationdbus.h
+++ b/common/gmountoperationdbus.h
@@ -5,6 +5,7 @@
#include <glib-object.h>
#include <gio/gmountoperation.h>
+#include <gmountspec.h>
#include <dbus/dbus.h>
G_BEGIN_DECLS
@@ -25,6 +26,7 @@ struct _GMountOperationDBus
char *obj_path;
DBusConnection *connection;
+ GMountSpec *mount_spec;
};
struct _GMountOperationDBusClass
@@ -34,7 +36,7 @@ struct _GMountOperationDBusClass
GType g_mount_operation_dbus_get_type (void) G_GNUC_CONST;
-GMountOperationDBus * g_mount_operation_dbus_new (void);
+GMountOperationDBus * g_mount_operation_dbus_new (GMountSpec *spec);
G_END_DECLS
diff --git a/common/gmountspec.c b/common/gmountspec.c
index 5c657677..f77fe597 100644
--- a/common/gmountspec.c
+++ b/common/gmountspec.c
@@ -27,7 +27,7 @@ g_mount_spec_new (const char *type)
spec->items = g_array_new (FALSE, TRUE, sizeof (GMountSpecItem));
if (type != NULL)
- g_mount_spec_add_item (spec, "type", type);
+ g_mount_spec_set (spec, "type", type);
return spec;
}
@@ -47,9 +47,9 @@ add_item (GMountSpec *spec,
void
-g_mount_spec_add_item (GMountSpec *spec,
- const char *key,
- const char *value)
+g_mount_spec_set (GMountSpec *spec,
+ const char *key,
+ const char *value)
{
add_item (spec, key, g_strdup (value));
g_array_sort (spec->items, item_compare);
@@ -253,7 +253,8 @@ g_mount_spec_match (GMountSpec *mount,
}
const char *
-g_mount_spec_get_type (GMountSpec *spec)
+g_mount_spec_get (GMountSpec *spec,
+ const char *key)
{
int i;
@@ -261,9 +262,16 @@ g_mount_spec_get_type (GMountSpec *spec)
{
GMountSpecItem *item = &g_array_index (spec->items, GMountSpecItem, i);
- if (strcmp (item->key, "type") == 0)
+ if (strcmp (item->key, key) == 0)
return item->value;
}
return NULL;
}
+
+const char *
+g_mount_spec_get_type (GMountSpec *spec)
+{
+ return g_mount_spec_get (spec, "type");
+}
+
diff --git a/common/gmountspec.h b/common/gmountspec.h
index 842d7632..210ce035 100644
--- a/common/gmountspec.h
+++ b/common/gmountspec.h
@@ -44,7 +44,7 @@ void g_mount_spec_to_dbus (DBusMessageIter *iter,
void g_mount_spec_to_dbus_with_path (DBusMessageIter *iter,
GMountSpec *spec,
const char *path);
-void g_mount_spec_add_item (GMountSpec *spec,
+void g_mount_spec_set (GMountSpec *spec,
const char *key,
const char *value);
gboolean g_mount_spec_match (GMountSpec *mount,
@@ -52,6 +52,8 @@ gboolean g_mount_spec_match (GMountSpec *mount,
gboolean g_mount_spec_match_with_path (GMountSpec *mount,
GMountSpec *spec,
const char *path);
+const char *g_mount_spec_get (GMountSpec *spec,
+ const char *key);
const char *g_mount_spec_get_type (GMountSpec *spec);
G_END_DECLS
diff --git a/daemon/.gitignore b/daemon/.gitignore
index 40dc437f..39a04a7d 100644
--- a/daemon/.gitignore
+++ b/daemon/.gitignore
@@ -10,3 +10,4 @@ gvfs-daemon
gvfs-daemon-smb
gvfs-daemon-test
*.service
+*.mount
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 97d95782..21446e20 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -6,7 +6,7 @@ INCLUDES = \
-I$(top_builddir) \
$(GLIB_CFLAGS) $(DBUS_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \
- -DMOUNTPOINT_DIR=\"$(sysconfdir)/gvfs/mounts/\" \
+ -DMOUNTABLE_DIR=\"$(sysconfdir)/gvfs/mounts/\" \
-DG_DISABLE_DEPRECATED
noinst_LTLIBRARIES=libdaemon.la
@@ -25,15 +25,21 @@ servicedir = $(DBUS_SERVICE_DIR)
service_in_files = gvfs-daemon.service.in
service_DATA = gvfs-daemon.service
+%.mount: %.mount.in ../config.log
+ sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+mountdir = $(sysconfdir)/gvfs/mounts
+mount_in_files = smb.mount.in
+mount_DATA = smb.mount
+
EXTRA_DIST = gvfs-daemon.service.in
DISTCLEANFILES = gvfs-daemon.service
-libexec_PROGRAMS=gvfs-daemon
+libexec_PROGRAMS=gvfs-daemon gvfs-daemon-smb
noinst_PROGRAMS = \
gvfs-daemon-test \
- gvfs-daemon-smb \
$(NULL)
libdaemon_la_SOURCES = \
@@ -56,6 +62,7 @@ libdaemon_la_SOURCES = \
gvfs_daemon_SOURCES = \
mounttracker.c mounttracker.h \
+ mount.c mount.h \
main.c
gvfs_daemon_LDADD = $(libraries)
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
index d6e40708..1df8f942 100644
--- a/daemon/gvfsbackendsmb.c
+++ b/daemon/gvfsbackendsmb.c
@@ -247,8 +247,8 @@ create_smb_uri (const char *server,
}
GVfsBackendSmb *
-g_vfs_backend_smb_new (const char *server,
- const char *share)
+g_vfs_backend_smb_new (GMountSpec *spec,
+ GError **error)
{
GVfsBackendSmb *backend;
GVfsBackend *_backend;
@@ -256,12 +256,32 @@ g_vfs_backend_smb_new (const char *server,
int res;
char *uri;
struct stat st;
+ const char *server;
+ const char *share;
g_assert (smb_backend == NULL);
+
+ server = g_mount_spec_get (spec, "server");
+ share = g_mount_spec_get (spec, "share");
+
+ if (server == NULL ||
+ share == NULL)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
+ _("Invalid mount spec"));
+ return NULL;
+ }
+
+
+
smb_context = smbc_new_context ();
if (smb_context == NULL)
- return NULL;
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
+ "Failed to allocate smb context");
+ return NULL;
+ }
smb_context->debug = 0;
smb_context->callbacks.auth_fn = auth_callback;
@@ -286,7 +306,8 @@ g_vfs_backend_smb_new (const char *server,
if (!smbc_init_context (smb_context))
{
- g_print ("init context failed\n");
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
+ "Failed to initialize smb context");
smbc_free_context (smb_context, FALSE);
return NULL;
}
@@ -300,10 +321,10 @@ g_vfs_backend_smb_new (const char *server,
_backend = G_VFS_BACKEND (backend);
_backend->display_name = g_strdup_printf ("%s on %s", share, server);
_backend->mount_spec = g_mount_spec_new ("smb-share");
- g_mount_spec_add_item (_backend->mount_spec,
- "share", share);
- g_mount_spec_add_item (_backend->mount_spec,
- "server", server);
+ g_mount_spec_set (_backend->mount_spec,
+ "share", share);
+ g_mount_spec_set (_backend->mount_spec,
+ "server", server);
smb_backend = backend;
backend->smb_context = smb_context;
@@ -313,6 +334,8 @@ g_vfs_backend_smb_new (const char *server,
g_free (uri);
if (res != 0)
{
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
+ "Failed to mount smb share");
g_object_unref (backend);
return NULL;
}
diff --git a/daemon/gvfsbackendsmb.h b/daemon/gvfsbackendsmb.h
index f11c5d28..17eaa72c 100644
--- a/daemon/gvfsbackendsmb.h
+++ b/daemon/gvfsbackendsmb.h
@@ -2,6 +2,7 @@
#define __G_VFS_BACKEND_SMB_H__
#include <gvfsbackend.h>
+#include <gmountspec.h>
#include <libsmbclient.h>
@@ -41,8 +42,8 @@ struct _GVfsBackendSmbClass
GType g_vfs_backend_smb_get_type (void) G_GNUC_CONST;
-GVfsBackendSmb *g_vfs_backend_smb_new (const char *server,
- const char *share);
+GVfsBackendSmb *g_vfs_backend_smb_new (GMountSpec *mount_spec,
+ GError **error);
G_END_DECLS
diff --git a/daemon/main.c b/daemon/main.c
index 987b1ad3..bb128c87 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -8,6 +8,7 @@
#include "gvfsbackendtest.h"
#include <gvfsdaemonprotocol.h>
#include "mounttracker.h"
+#include "mount.h"
int
main (int argc, char *argv[])
@@ -46,6 +47,8 @@ main (int argc, char *argv[])
if (daemon == NULL)
return 1;
+ mount_init ();
+
g_mount_tracker_new ();
loop = g_main_loop_new (NULL, FALSE);
diff --git a/daemon/mount.c b/daemon/mount.c
new file mode 100644
index 00000000..eeab0583
--- /dev/null
+++ b/daemon/mount.c
@@ -0,0 +1,126 @@
+#include <config.h>
+
+#include <string.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <glib/gi18n.h>
+#include "mount.h"
+#include "gmountoperationdbus.h"
+
+struct _Mountable {
+ char *type;
+ char *exec;
+ gboolean automount;
+};
+
+static GList *mountables;
+
+void
+mount_init (void)
+{
+ GDir *dir;
+ char *mount_dir, *path;
+ const char *filename;
+ GKeyFile *keyfile;
+ char *type, *exec;
+ Mountable *mountable;
+ gboolean automount;
+
+ mount_dir = MOUNTABLE_DIR;
+ dir = g_dir_open (mount_dir, 0, NULL);
+
+ if (dir)
+ {
+ while ((filename = g_dir_read_name (dir)) != NULL)
+ {
+ path = g_build_filename (mount_dir, filename, NULL);
+
+ keyfile = g_key_file_new ();
+ if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL))
+ {
+ type = g_key_file_get_string (keyfile, "Mount", "Type", NULL);
+ exec = g_key_file_get_string (keyfile, "Mount", "Exec", NULL);
+ automount = g_key_file_get_boolean (keyfile, "Mount", "AutoMount", NULL);
+ if (type != NULL && exec != NULL)
+ {
+ mountable = g_new0 (Mountable, 1);
+ mountable->type = g_strdup (type);
+ mountable->exec = g_strdup (exec);
+ mountable->automount = automount;
+
+ mountables = g_list_prepend (mountables, mountable);
+ }
+ g_free (type);
+ g_free (exec);
+ }
+ g_key_file_free (keyfile);
+ g_free (path);
+ }
+ }
+}
+
+gboolean
+mountable_is_automount (Mountable *mountable)
+{
+ return mountable->automount;
+}
+
+static Mountable *
+find_mountable (const char *type)
+{
+ GList *l;
+
+ for (l = mountables; l != NULL; l = l->next)
+ {
+ Mountable *mountable = l->data;
+
+ if (strcmp (mountable->type, type) == 0)
+ return mountable;
+ }
+
+ return NULL;
+}
+
+Mountable *
+lookup_mountable (GMountSpec *spec)
+{
+ const char *type;
+
+ type = g_mount_spec_get_type (spec);
+ if (type == NULL)
+ return NULL;
+
+ return find_mountable (type);
+}
+
+GMountOperation *
+mountable_mount (Mountable *mountable,
+ GMountSpec *spec,
+ GError **error)
+{
+ DBusConnection *conn;
+ const char *id;
+ char *exec;
+ gboolean res;
+ GMountOperationDBus *op;
+
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ id = dbus_bus_get_unique_name (conn);
+ dbus_connection_unref (conn);
+
+ op = g_mount_operation_dbus_new (spec);
+
+ exec = g_strconcat (mountable->exec, " ", id, " ", op->obj_path, NULL);
+
+ res = g_spawn_command_line_async (exec, error);
+ g_free (exec);
+
+ if (!res)
+ {
+ g_object_unref (op);
+ return NULL;
+ }
+
+ return G_MOUNT_OPERATION (op);
+}
diff --git a/daemon/mount.h b/daemon/mount.h
new file mode 100644
index 00000000..19a54e70
--- /dev/null
+++ b/daemon/mount.h
@@ -0,0 +1,24 @@
+#ifndef __MOUNT_H__
+#define __MOUNT_H__
+
+#include <glib-object.h>
+#include <gio/gmountoperation.h>
+#include <gmountspec.h>
+
+G_BEGIN_DECLS
+
+typedef struct _Mountable Mountable;
+
+void mount_init (void);
+Mountable * lookup_mountable (GMountSpec *spec);
+gboolean mountable_is_automount (Mountable *mountable);
+GMountOperation *mountable_mount (Mountable *mountable,
+ GMountSpec *spec,
+ GError **error);
+
+
+
+G_END_DECLS
+
+#endif /* __MOUNT_H__ */
+
diff --git a/daemon/mounttracker.c b/daemon/mounttracker.c
index fd5aca7a..ccfeba84 100644
--- a/daemon/mounttracker.c
+++ b/daemon/mounttracker.c
@@ -14,6 +14,7 @@
#include "gmountspec.h"
#include "gvfsdaemonprotocol.h"
#include <gio/gvfserror.h>
+#include <mount.h>
typedef struct {
char *key;
@@ -39,6 +40,11 @@ struct _GMountTracker
GList *mounts;
};
+static void lookup_mount (GMountTracker *tracker,
+ DBusConnection *connection,
+ DBusMessage *message,
+ gboolean do_automount);
+
G_DEFINE_TYPE (GMountTracker, g_mount_tracker, G_TYPE_OBJECT);
static VFSMount *
@@ -223,32 +229,129 @@ register_mount (GMountTracker *tracker,
dbus_connection_send (connection, reply, NULL);
}
+typedef struct {
+ DBusMessage *message;
+ DBusConnection *connection;
+ GMountTracker *tracker;
+} AutoMountData;
+
+static void
+automount_done (GMountOperation *op,
+ gboolean succeeded,
+ GError *error,
+ gpointer _data)
+{
+ DBusMessage *reply;
+ AutoMountData *data = _data;
+
+ if (!succeeded)
+ {
+ GError *mount_error = NULL;
+ g_set_error (&mount_error, G_VFS_ERROR, G_VFS_ERROR_NOT_MOUNTED,
+ _("Automount failed: %s"), error->message);
+ reply = _dbus_message_new_error_from_gerror (data->message, mount_error);
+ g_error_free (mount_error);
+ dbus_connection_send (data->connection, reply, NULL);
+ }
+ else
+ lookup_mount (data->tracker,
+ data->connection,
+ data->message,
+ FALSE);
+
+ g_object_unref (op);
+
+
+ dbus_connection_unref (data->connection);
+ dbus_message_unref (data->message);
+ g_free (data);
+}
+
+static DBusMessage *
+maybe_automount (GMountTracker *tracker,
+ GMountSpec *spec,
+ DBusMessage *message,
+ DBusConnection *connection,
+ gboolean do_automount)
+{
+ Mountable *mountable;
+ DBusMessage *reply;
+ GError *error;
+
+ mountable = lookup_mountable (spec);
+
+ g_print ("mountable: %p, do-automount: %d, is_automount: %d\n",
+ mountable, do_automount,
+ mountable_is_automount (mountable));
+
+ reply = NULL;
+
+ if (mountable != NULL && do_automount &&
+ mountable_is_automount (mountable))
+ {
+ GMountOperation *op;
+ GError *mount_error;
+
+ g_print ("automounting...\n");
+
+ mount_error = NULL;
+ op = mountable_mount (mountable, spec, &error);
+ g_print ("op = %p\n", op);
+
+ if (op == NULL)
+ {
+ error = NULL;
+ g_set_error (&error, G_VFS_ERROR, G_VFS_ERROR_NOT_MOUNTED,
+ _("Error automounting location: %s"), mount_error->message);
+ reply = _dbus_message_new_error_from_gerror (message, error);
+ g_error_free (mount_error);
+ g_error_free (error);
+ }
+ else
+ {
+ AutoMountData *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);
+ }
+ }
+ else
+ {
+ error = NULL;
+ g_set_error (&error, G_VFS_ERROR, G_VFS_ERROR_NOT_MOUNTED,
+ (mountable == NULL) ?
+ _("Location is not mountable") :
+ _("Location is not mounted"));
+ reply = _dbus_message_new_error_from_gerror (message, error);
+ g_error_free (error);
+ }
+
+ return reply;
+}
+
static void
lookup_mount (GMountTracker *tracker,
DBusConnection *connection,
- DBusMessage *message)
+ DBusMessage *message,
+ gboolean do_automount)
{
VFSMount *mount;
DBusMessage *reply;
DBusMessageIter iter;
GMountSpec *spec;
- GError *error;
dbus_message_iter_init (message, &iter);
spec = g_mount_spec_from_dbus (&iter);
+ reply = NULL;
if (spec != NULL)
{
mount = match_vfs_mount (tracker, spec);
if (mount == NULL)
- {
- error = NULL;
- g_set_error (&error, G_VFS_ERROR, G_VFS_ERROR_NOT_MOUNTED,
- _("Location is not mounted"));
- reply = _dbus_message_new_error_from_gerror (message, error);
- g_error_free (error);
- }
+ reply = maybe_automount (tracker, spec, message, connection, do_automount);
else
{
reply = dbus_message_new_method_return (message);
@@ -266,11 +369,9 @@ lookup_mount (GMountTracker *tracker,
DBUS_ERROR_INVALID_ARGS,
"Invalid arguments");
- if (reply == NULL)
- _g_dbus_oom ();
-
g_mount_spec_unref (spec);
- dbus_connection_send (connection, reply, NULL);
+ if (reply != NULL)
+ dbus_connection_send (connection, reply, NULL);
}
static void
@@ -347,7 +448,7 @@ dbus_message_function (DBusConnection *connection,
else if (dbus_message_is_method_call (message,
G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT))
- lookup_mount (tracker, connection, message);
+ lookup_mount (tracker, connection, message, TRUE);
else if (dbus_message_is_method_call (message,
G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
"listMounts"))
diff --git a/daemon/smb.c b/daemon/smb.c
index 5f3c6416..a6ca1abc 100644
--- a/daemon/smb.c
+++ b/daemon/smb.c
@@ -1,49 +1,152 @@
#include <config.h>
#include <stdlib.h>
+#include <string.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus-gmain.h>
#include "gvfsdaemon.h"
+#include "gdbusutils.h"
#include "gvfsbackendsmb.h"
#include <gvfsdaemonprotocol.h>
+static DBusConnection *connection;
+
+static void
+send_done (const char *dbus_id,
+ const char *obj_path,
+ gboolean succeeded, GError *error)
+{
+ dbus_bool_t succeeded_dbus = succeeded;
+ const char *domain;
+ DBusMessage *message;
+ guint32 code;
+
+ if (dbus_id == NULL)
+ return;
+
+ message =
+ dbus_message_new_method_call (dbus_id,
+ obj_path,
+ G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
+ "done");
+
+ if (succeeded)
+ _g_dbus_message_append_args (message,
+ DBUS_TYPE_BOOLEAN, &succeeded_dbus,
+ 0);
+ else
+ {
+ 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);
+ }
+
+ dbus_connection_send_with_reply_and_block (connection, message, 2000, NULL);
+}
+
int
main (int argc, char *argv[])
{
GMainLoop *loop;
GVfsDaemon *daemon;
GVfsBackendSmb *backend;
- const char *server, *share;
+ const char *dbus_id, *obj_path;
+ DBusMessage *message, *reply;
+ DBusMessageIter iter;
+ DBusError derror;
+ GMountSpec *mount_spec;
+ GError *error;
+
+ g_thread_init (NULL);
- if (argc < 3)
+ g_type_init ();
+
+ dbus_error_init (&derror);
+ connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+ if (connection == NULL)
{
- g_print ("Args: server share\n");
- return 0;
+ g_print ("Error connecting dbus: %s\n", derror.message);
+ dbus_error_free (&derror);
+ return 1;
}
- server = argv[1];
- share = argv[2];
-
- g_thread_init (NULL);
+ dbus_id = NULL;
+ obj_path = NULL;
+ if (strcmp (argv[1], "--mount") == 0)
+ {
+ if (argc < 4)
+ {
+ g_print ("Args: --mount dbus-id object_path\n");
+ return 1;
+ }
+
+ dbus_id = argv[2];
+ obj_path = argv[3];
- g_type_init ();
+ message =
+ dbus_message_new_method_call (dbus_id,
+ obj_path,
+ G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
+ "getMountSpec");
+
+ reply = dbus_connection_send_with_reply_and_block (connection, message, 2000, &derror);
+ dbus_message_unref (message);
+ if (reply == NULL)
+ {
+ g_print ("Error requesting mount spec: %s\n", derror.message);
+ dbus_error_free (&derror);
+ return 1;
+ }
+ dbus_message_iter_init (reply, &iter);
+ mount_spec = g_mount_spec_from_dbus (&iter);
+ dbus_message_unref (reply);
+ }
+ else
+ {
+ if (argc < 3)
+ {
+ g_print ("Args: server share\n");
+
+ return 1;
+ }
+ mount_spec = g_mount_spec_new ("smb-share");
+ g_mount_spec_set (mount_spec, "server", argv[1]);
+ g_mount_spec_set (mount_spec, "share", argv[2]);
+ }
+
+ error = NULL;
+
daemon = g_vfs_daemon_new (FALSE, FALSE);
if (daemon == NULL)
- return 1;
-
- backend = g_vfs_backend_smb_new (server, share);
+ {
+ g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_IO,
+ "error starting mount daemon");
+ send_done (dbus_id, obj_path, FALSE, error);
+ return 1;
+ }
+ backend = g_vfs_backend_smb_new (mount_spec, &error);
if (backend == NULL)
{
- g_print ("Failed instantiating backend\n");
+ send_done (dbus_id, obj_path, FALSE, error);
return 1;
}
g_vfs_backend_register_with_daemon (G_VFS_BACKEND (backend), daemon);
g_object_unref (backend);
+
+ /* TODO: Verify registration succeeded? */
+
+ send_done (dbus_id, obj_path, TRUE, error);
loop = g_main_loop_new (NULL, FALSE);
diff --git a/daemon/smb.mount.in b/daemon/smb.mount.in
new file mode 100644
index 00000000..00ddf1ae
--- /dev/null
+++ b/daemon/smb.mount.in
@@ -0,0 +1,4 @@
+[Mount]
+Type=smb-share
+Exec=@libexecdir@/gvfs-daemon-smb --mount
+AutoMount=true
diff --git a/gio/gmountoperation.c b/gio/gmountoperation.c
index f60b6d9c..3b090ddb 100644
--- a/gio/gmountoperation.c
+++ b/gio/gmountoperation.c
@@ -109,7 +109,7 @@ g_mount_operation_class_init (GMountOperationClass *klass)
G_STRUCT_OFFSET (GMountOperationClass, ask_question),
boolean_handled_accumulator, NULL,
_gvfs_marshal_BOOLEAN__STRING_POINTER,
- G_TYPE_NONE, 2,
+ G_TYPE_BOOLEAN, 2,
G_TYPE_STRING, G_TYPE_POINTER);
signals[REPLY] =
@@ -118,9 +118,9 @@ g_mount_operation_class_init (GMountOperationClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GMountOperationClass, reply),
NULL, NULL,
- _gvfs_marshal_VOID__BOOLEAN_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_BOOLEAN, G_TYPE_POINTER);
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
signals[DONE] =
g_signal_new (I_("done"),
@@ -128,9 +128,10 @@ g_mount_operation_class_init (GMountOperationClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GMountOperationClass, done),
NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
+ _gvfs_marshal_VOID__BOOLEAN_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_BOOLEAN,
+ G_TYPE_POINTER);
}
static void