diff options
author | Alexander Larsson <alexl@src.gnome.org> | 2007-09-13 11:25:55 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2007-09-13 11:25:55 +0000 |
commit | 2e6f0c31af7c2b1262db3e84654c1c2ed082a18a (patch) | |
tree | 21eec64a5d41bfbb087289d533d90cfab6b6b0df | |
parent | 5950303721316b204dd2e98323e3696dcc59c328 (diff) | |
download | gvfs-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.c | 4 | ||||
-rw-r--r-- | common/gmountoperationdbus.c | 30 | ||||
-rw-r--r-- | common/gmountoperationdbus.h | 4 | ||||
-rw-r--r-- | common/gmountspec.c | 20 | ||||
-rw-r--r-- | common/gmountspec.h | 4 | ||||
-rw-r--r-- | daemon/.gitignore | 1 | ||||
-rw-r--r-- | daemon/Makefile.am | 13 | ||||
-rw-r--r-- | daemon/gvfsbackendsmb.c | 39 | ||||
-rw-r--r-- | daemon/gvfsbackendsmb.h | 5 | ||||
-rw-r--r-- | daemon/main.c | 3 | ||||
-rw-r--r-- | daemon/mount.c | 126 | ||||
-rw-r--r-- | daemon/mount.h | 24 | ||||
-rw-r--r-- | daemon/mounttracker.c | 129 | ||||
-rw-r--r-- | daemon/smb.c | 129 | ||||
-rw-r--r-- | daemon/smb.mount.in | 4 | ||||
-rw-r--r-- | gio/gmountoperation.c | 15 |
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 |