summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@src.gnome.org>2007-09-13 10:35:50 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-09-13 10:35:50 +0000
commit4311de34b4e46bdca9c650f235fb0ab015a0847f (patch)
tree37d40e4966a2d7b2eac5122e944ba6b673910e97 /daemon
parent47f200386b742183ea7a131ef45236e47984be59 (diff)
downloadgvfs-4311de34b4e46bdca9c650f235fb0ab015a0847f.tar.gz
Initial work on the new way to track mountpoints.
Daemon side only. Original git commit by Alexander Larsson <alex@greebo.(none)> at 1165492556 +0100 svn path=/trunk/; revision=219
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile.am19
-rw-r--r--daemon/gvfsbackend.c163
-rw-r--r--daemon/gvfsbackend.h19
-rw-r--r--daemon/gvfsbackendtest.c6
-rw-r--r--daemon/gvfsdaemon.c432
-rw-r--r--daemon/gvfsdaemon.h18
-rw-r--r--daemon/gvfsdaemonprotocol.h5
-rw-r--r--daemon/gvfsdaemonutils.c21
-rw-r--r--daemon/gvfsdaemonutils.h26
-rw-r--r--daemon/gvfsjob.c30
-rw-r--r--daemon/gvfsjob.h21
-rw-r--r--daemon/gvfsjobcloseread.c4
-rw-r--r--daemon/gvfsjobcloseread.h2
-rw-r--r--daemon/gvfsjobdbus.c162
-rw-r--r--daemon/gvfsjobdbus.h46
-rw-r--r--daemon/gvfsjobopenforread.c6
-rw-r--r--daemon/gvfsjobopenforread.h2
-rw-r--r--daemon/gvfsjobread.c6
-rw-r--r--daemon/gvfsjobread.h2
-rw-r--r--daemon/gvfsjobseekread.c6
-rw-r--r--daemon/gvfsjobseekread.h2
-rw-r--r--daemon/gvfsjobsource.c108
-rw-r--r--daemon/gvfsjobsource.h43
-rw-r--r--daemon/gvfsmountpoint.c61
-rw-r--r--daemon/gvfsmountpoint.h22
-rw-r--r--daemon/gvfsreadchannel.c46
-rw-r--r--daemon/gvfsreadchannel.h2
-rw-r--r--daemon/main.c60
28 files changed, 1018 insertions, 322 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 58c85066..aafefa66 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -7,27 +7,42 @@ INCLUDES = \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED
+noinst_LTLIBRARIES=libdaemon.la
+
libraries = \
$(top_builddir)/gvfs/libgvfs.la \
+ libdaemon.la \
$(GLIB_LIBS) $(DBUS_LIBS)
+
noinst_PROGRAMS = \
gvfs-daemon \
+ gvfs-daemon-test \
$(NULL)
-gvfs_daemon_SOURCES = \
+libdaemon_la_SOURCES = \
gvfsdaemon.c gvfsdaemon.h \
gvfsbackend.c gvfsbackend.h \
- gvfsbackendtest.c gvfsbackendtest.h \
gvfsreadchannel.c gvfsreadchannel.h \
gvfsdaemonutils.c gvfsdaemonutils.h \
+ gvfsmountpoint.c gvfsmountpoint.h \
gvfsjob.c gvfsjob.h \
+ gvfsjobsource.c gvfsjobsource.h \
gvfsjobdbus.c gvfsjobdbus.h \
gvfsjobopenforread.c gvfsjobopenforread.h \
gvfsjobread.c gvfsjobread.h \
gvfsjobseekread.c gvfsjobseekread.h \
gvfsjobcloseread.c gvfsjobcloseread.h \
dbus-gmain.h dbus-gmain.c \
+ $(NULL)
+
+gvfs_daemon_SOURCES = \
main.c
gvfs_daemon_LDADD = $(libraries)
+
+gvfs_daemon_test_SOURCES = \
+ gvfsbackendtest.c gvfsbackendtest.h \
+ test.c
+
+gvfs_daemon_test_LDADD = $(libraries)
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index ddf8bce4..ed9216db 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -9,8 +9,34 @@
#include <dbus/dbus.h>
#include <glib/gi18n.h>
#include "gvfsbackend.h"
-
-G_DEFINE_TYPE (GVfsBackend, g_vfs_backend, G_TYPE_OBJECT);
+#include "gvfsjobsource.h"
+#include "gvfsdaemonprotocol.h"
+#include <gvfsjobopenforread.h>
+
+enum {
+ PROP_0,
+ PROP_MOUNTPOINT
+};
+
+/* TODO: Real P_() */
+#define P_(_x) (_x)
+
+static void g_vfs_backend_job_source_iface_init (GVfsJobSourceIface *iface);
+static void g_vfs_backend_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void g_vfs_backend_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void g_vfs_backend_reset (GVfsJobSource *job_source);
+
+G_DEFINE_TYPE_WITH_CODE (GVfsBackend, g_vfs_backend, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VFS_JOB_SOURCE,
+ g_vfs_backend_job_source_iface_init))
+
+volatile gint mountpoint_counter = 0;
static void
g_vfs_backend_finalize (GObject *object)
@@ -19,35 +45,86 @@ g_vfs_backend_finalize (GObject *object)
backend = G_VFS_BACKEND (object);
+ if (backend->mountpoint)
+ g_vfs_mountpoint_free (backend->mountpoint);
+
+ g_free (backend->mountpoint_path);
+
if (G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize)
(*G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) (object);
}
static void
+g_vfs_backend_job_source_iface_init (GVfsJobSourceIface *iface)
+{
+ iface->reset = g_vfs_backend_reset;
+}
+
+static void
g_vfs_backend_class_init (GVfsBackendClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = g_vfs_backend_finalize;
+ gobject_class->set_property = g_vfs_backend_set_property;
+ gobject_class->get_property = g_vfs_backend_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_MOUNTPOINT,
+ g_param_spec_pointer ("mountpoint",
+ P_("Mountpoint"),
+ P_("The mountpoint this backend handles."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+
}
static void
g_vfs_backend_init (GVfsBackend *backend)
{
+ int id;
+
+ id = g_atomic_int_exchange_and_add (&mountpoint_counter, 1);
+ backend->mountpoint_path = g_strdup_printf ("/org/gtk/vfs/mountpoint/%d", id);
}
-void
-g_vfs_backend_set_mountpoint (GVfsBackend *backend,
- const char *mountpoint)
+static void
+g_vfs_backend_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- g_free (backend->mountpoint);
- backend->mountpoint = g_strdup (mountpoint);
+ GVfsBackend *backend = G_VFS_BACKEND (object);
+
+ switch (prop_id)
+ {
+ case PROP_MOUNTPOINT:
+ backend->mountpoint = g_vfs_mountpoint_copy (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
-const char *
-g_vfs_backend_get_mountpoint (GVfsBackend *backend)
+static void
+g_vfs_backend_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- return backend->mountpoint;
+ GVfsBackend *backend = G_VFS_BACKEND (object);
+
+ switch (prop_id)
+ {
+ case PROP_MOUNTPOINT:
+ g_value_set_pointer (value, backend->mountpoint);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
gboolean
@@ -103,3 +180,69 @@ g_vfs_backend_seek_on_read (GVfsBackend *backend,
return class->seek_on_read (backend, job, handle,
offset, type);
}
+
+static DBusHandlerResult
+backend_dbus_handler (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ GVfsBackend *backend = user_data;
+ GVfsJob *job;
+
+ job = NULL;
+
+ if (dbus_message_is_method_call (message,
+ G_VFS_DBUS_DAEMON_INTERFACE,
+ G_VFS_DBUS_OP_OPEN_FOR_READ))
+ job = g_vfs_job_open_for_read_new (connection, message, backend);
+
+ if (job)
+ {
+ g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), job);
+ g_object_unref (job);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void
+signal_mountpoint (GVfsBackend *backend)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter;
+ DBusConnection *bus;
+
+ signal = dbus_message_new_signal (backend->mountpoint_path,
+ G_VFS_DBUS_MOUNTPOINT_INTERFACE,
+ G_VFS_DBUS_ANNOUNCE_MOUNTPOINT);
+
+ dbus_message_iter_init_append (signal, &iter);
+
+ g_vfs_mountpoint_to_dbus (backend->mountpoint, &iter);
+
+ bus = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (bus)
+ {
+ dbus_connection_send (bus, signal, NULL);
+ dbus_connection_unref (bus);
+ }
+
+ dbus_message_unref (signal);
+}
+
+static void
+g_vfs_backend_reset (GVfsJobSource *job_source)
+{
+ signal_mountpoint (G_VFS_BACKEND (job_source));
+}
+
+void
+g_vfs_backend_register_with_daemon (GVfsBackend *backend,
+ GVfsDaemon *daemon)
+{
+ g_vfs_daemon_add_job_source (daemon, G_VFS_JOB_SOURCE (backend));
+ g_vfs_daemon_register_path (daemon, backend->mountpoint_path,
+ backend_dbus_handler, backend);
+ signal_mountpoint (backend);
+}
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index a0cfc590..1e7c4b46 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -4,6 +4,8 @@
#include <gvfs/gvfstypes.h>
#include <gvfsdaemon.h>
#include <gvfsjob.h>
+#include <dbus/dbus.h>
+#include <gvfsmountpoint.h>
G_BEGIN_DECLS
@@ -14,15 +16,21 @@ G_BEGIN_DECLS
#define G_IS_VFS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_BACKEND))
#define G_VFS_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_BACKEND, GVfsBackendClass))
-/* GVfsBackend defined in gvfsdaemon.h to fix circular defines */
+typedef struct _GVfsBackend GVfsBackend;
typedef struct _GVfsBackendClass GVfsBackendClass;
+typedef struct _GVfsJobOpenForRead GVfsJobOpenForRead;
+typedef struct _GVfsJobSeekRead GVfsJobSeekRead;
+typedef struct _GVfsJobCloseRead GVfsJobCloseRead;
+typedef struct _GVfsJobRead GVfsJobRead;
+
typedef gpointer GVfsBackendHandle;
struct _GVfsBackend
{
GObject parent_instance;
- char *mountpoint;
+ GVfsMountpoint *mountpoint;
+ char *mountpoint_path;
};
struct _GVfsBackendClass
@@ -59,10 +67,6 @@ struct _GVfsBackendClass
GType g_vfs_backend_get_type (void) G_GNUC_CONST;
-void g_vfs_backend_set_mountpoint (GVfsBackend *backend,
- const char *mountpoint);
-const char *g_vfs_backend_get_mountpoint (GVfsBackend *backend);
-
gboolean g_vfs_backend_open_for_read (GVfsBackend *backend,
GVfsJobOpenForRead *job,
char *filename);
@@ -80,6 +84,9 @@ gboolean g_vfs_backend_seek_on_read (GVfsBackend *backend,
goffset offset,
GSeekType type);
+void g_vfs_backend_register_with_daemon (GVfsBackend *backend,
+ GVfsDaemon *daemon);
+
G_END_DECLS
#endif /* __G_VFS_BACKEND_H__ */
diff --git a/daemon/gvfsbackendtest.c b/daemon/gvfsbackendtest.c
index 3ce5a6c9..877ce74c 100644
--- a/daemon/gvfsbackendtest.c
+++ b/daemon/gvfsbackendtest.c
@@ -32,15 +32,17 @@ g_vfs_backend_test_finalize (GObject *object)
static void
g_vfs_backend_test_init (GVfsBackendTest *backend)
{
- g_vfs_backend_set_mountpoint (G_VFS_BACKEND (backend), "foo://");
}
GVfsBackendTest *
g_vfs_backend_test_new (void)
{
GVfsBackendTest *backend;
+ GVfsMountpoint mountpoint = { "foo", "", "", -1, "" };
+
backend = g_object_new (G_TYPE_VFS_BACKEND_TEST,
- NULL);
+ "mountpoint", &mountpoint,
+ NULL);
return backend;
}
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index 2faa364e..2fc08dbf 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -1,9 +1,10 @@
#include <config.h>
-#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <unistd.h>
+#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n.h>
@@ -20,16 +21,24 @@ enum {
PROP_0,
};
+typedef struct {
+ char *path;
+ DBusObjectPathMessageFunction callback;
+ gpointer data;
+} RegisteredPath;
+
struct _GVfsDaemonPrivate
{
- GHashTable *backends; /* bus_name -> backend */
-
- GMutex *lock; /* protects the parts that are accessed by multiple threads */
-
- GQueue *pending_jobs;
- GQueue *jobs; /* protected by lock */
- guint queued_job_start; /* protected by lock */
- GList *read_channels; /* protected by lock */
+ GMutex *lock;
+ gboolean main_daemon;
+
+ DBusConnection *session_bus;
+ GHashTable *registered_paths;
+ GQueue *new_pending_jobs;
+ GQueue *pending_jobs; /* Only accessed from main thread */
+ GQueue *jobs;
+ guint queued_job_start;
+ GList *job_sources;
};
typedef struct {
@@ -52,22 +61,19 @@ static void g_vfs_daemon_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
-static void daemon_unregistered_func (DBusConnection *conn,
- gpointer data);
static DBusHandlerResult daemon_message_func (DBusConnection *conn,
DBusMessage *message,
gpointer data);
-static DBusHandlerResult daemon_filter_func (DBusConnection *conn,
+static DBusHandlerResult peer_to_peer_filter_func (DBusConnection *conn,
DBusMessage *message,
gpointer data);
-static void start_or_queue_job (GVfsDaemon *daemon,
- GVfsJob *job);
-static DBusObjectPathVTable daemon_vtable = {
- daemon_unregistered_func,
- daemon_message_func,
- NULL
-};
+static void
+registered_path_free (RegisteredPath *data)
+{
+ g_free (data->path);
+ g_free (data);
+}
static void
g_vfs_daemon_finalize (GObject *object)
@@ -80,8 +86,9 @@ g_vfs_daemon_finalize (GObject *object)
g_assert (daemon->priv->pending_jobs->head == NULL);
g_queue_free (daemon->priv->jobs);
g_queue_free (daemon->priv->pending_jobs);
+ g_queue_free (daemon->priv->new_pending_jobs);
- g_hash_table_destroy (daemon->priv->backends);
+ g_hash_table_destroy (daemon->priv->registered_paths);
g_mutex_free (daemon->priv->lock);
if (G_OBJECT_CLASS (g_vfs_daemon_parent_class)->finalize)
@@ -107,12 +114,19 @@ g_vfs_daemon_init (GVfsDaemon *daemon)
G_TYPE_VFS_DAEMON,
GVfsDaemonPrivate);
daemon->priv->lock = g_mutex_new ();
+ daemon->priv->session_bus = dbus_bus_get (DBUS_BUS_SESSION, NULL);
daemon->priv->jobs = g_queue_new ();
daemon->priv->pending_jobs = g_queue_new ();
- daemon->priv->backends = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_object_unref);
+ daemon->priv->new_pending_jobs = g_queue_new ();
+ daemon->priv->registered_paths =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify)registered_path_free);
+
+ if (!dbus_connection_add_filter (daemon->priv->session_bus,
+ daemon_message_func, daemon, NULL))
+ g_error ("Not enough memory to add filter");
}
static void
@@ -152,55 +166,169 @@ g_vfs_daemon_get_property (GObject *object,
}
GVfsDaemon *
-g_vfs_daemon_new (void)
+g_vfs_daemon_new (gboolean main_daemon, gboolean replace)
{
GVfsDaemon *daemon;
+ DBusConnection *conn;
+ DBusError error;
+ 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)
+ {
+ g_printerr ("Failed to connect to the D-BUS daemon: %s\n",
+ error.message);
+
+ dbus_error_free (&error);
+ return NULL;
+ }
+
+ dbus_bus_add_match (conn,
+ "sender='org.freedesktop.DBus',"
+ "interface='org.freedesktop.DBus',"
+ "member='NameOwnerChanged'",
+ &error);
+ if (dbus_error_is_set (&error))
+ {
+ g_printerr ("Failed to connect to add dbus match: %s\n",
+ error.message);
+ dbus_error_free (&error);
+ return NULL;
+ }
+
+ dbus_connection_setup_with_g_main (conn, NULL);
+
daemon = g_object_new (G_TYPE_VFS_DAEMON, NULL);
+ daemon->priv->main_daemon = main_daemon;
+
+ /* Request name only after we've installed the message filter */
+ if (main_daemon)
+ {
+ flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_DO_NOT_QUEUE;
+ 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)
+ {
+ g_printerr ("Failed to acquire daemon name: %s", error.message);
+ dbus_error_free (&error);
+
+ g_object_unref (daemon);
+ daemon = NULL;
+ }
+ else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
+ {
+ g_printerr ("VFS daemon already running, exiting.\n");
+ g_object_unref (daemon);
+ daemon = NULL;
+ }
+ else if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ {
+ g_printerr ("Not primary owner of the service, exiting.\n");
+ g_object_unref (daemon);
+ daemon = NULL;
+ }
+ }
+
+ dbus_connection_unref (conn);
+
return daemon;
}
-gboolean
-g_vfs_daemon_add_backend (GVfsDaemon *daemon,
- GVfsBackend *backend)
+static void
+job_source_new_job_callback (GVfsJobSource *job_source,
+ GVfsJob *job,
+ GVfsDaemon *daemon)
{
- DBusConnection *conn;
- const char *mountpoint;
- char *bus_name;
- int ret;
- DBusError error;
+ g_vfs_daemon_queue_job (daemon, job);
+}
- mountpoint = g_vfs_backend_get_mountpoint (backend);
+static void
+job_source_closed_callback (GVfsJobSource *job_source,
+ GVfsDaemon *daemon)
+{
+ g_mutex_lock (daemon->priv->lock);
+
+ daemon->priv->job_sources = g_list_remove (daemon->priv->job_sources,
+ job_source);
+
+ g_signal_handlers_disconnect_by_func (job_source,
+ (GCallback)job_source_new_job_callback,
+ daemon);
+ g_signal_handlers_disconnect_by_func (job_source,
+ (GCallback)job_source_closed_callback,
+ daemon);
- g_assert (g_hash_table_lookup (daemon->priv->backends, mountpoint) == NULL);
+ g_object_unref (job_source);
+
+ g_mutex_unlock (daemon->priv->lock);
+}
- conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
- if (conn == NULL)
+void
+g_vfs_daemon_add_job_source (GVfsDaemon *daemon,
+ GVfsJobSource *job_source)
+{
+ g_print ("Added new job source %p (%s)\n", job_source, g_type_name_from_instance ((gpointer)job_source));
+
+ g_mutex_lock (daemon->priv->lock);
+
+ g_object_ref (job_source);
+ daemon->priv->job_sources = g_list_append (daemon->priv->job_sources,
+ job_source);
+ g_signal_connect (job_source, "new_job",
+ (GCallback)job_source_new_job_callback, daemon);
+ g_signal_connect (job_source, "closed",
+ (GCallback)job_source_closed_callback, daemon);
+
+ g_mutex_unlock (daemon->priv->lock);
+}
+
+gboolean
+g_vfs_daemon_register_path (GVfsDaemon *daemon,
+ const char *path,
+ DBusObjectPathMessageFunction callback,
+ gpointer user_data)
+{
+ RegisteredPath *data;
+
+ if (g_hash_table_lookup (daemon->priv->registered_paths, path) != NULL)
return FALSE;
- bus_name = _g_dbus_bus_name_from_mountpoint (mountpoint);
- g_print ("bus_name: %s, mountpoint: %s\n", bus_name, mountpoint);
- dbus_error_init (&error);
- ret = dbus_bus_request_name (conn, bus_name, 0, &error);
- if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
- {
- g_printerr ("Failed to acquire vfs-daemon service: %s", error.message);
- dbus_error_free (&error);
- return FALSE;
- }
+ data = g_new0 (RegisteredPath, 1);
+ data->path = g_strdup (path);
+ data->callback = callback;
+ data->data = user_data;
- if (!dbus_connection_register_object_path (conn,
- G_VFS_DBUS_DAEMON_PATH,
- &daemon_vtable,
- daemon))
- g_error ("Failed to register object with D-BUS (oom).\n");
+ g_hash_table_insert (daemon->priv->registered_paths, data->path, data);
- g_hash_table_insert (daemon->priv->backends,
- bus_name,
- g_object_ref (backend));
return TRUE;
}
+static void
+g_queue_move_items (GQueue *to, GQueue *from)
+{
+ GList *ignore;
+ if (from->head != NULL)
+ {
+ if (to->head == NULL)
+ to->head = from->head;
+ else
+ ignore = g_list_concat (to->tail, from->head);
+ to->tail = from->tail;
+ to->length += from->length;
+
+ from->head = NULL;
+ from->tail = NULL;
+ from->length = 0;
+ }
+}
+
static gboolean
start_jobs_at_idle (gpointer data)
{
@@ -210,6 +338,8 @@ start_jobs_at_idle (gpointer data)
g_mutex_lock (daemon->priv->lock);
daemon->priv->queued_job_start = 0;
+ g_queue_move_items (daemon->priv->pending_jobs,
+ daemon->priv->new_pending_jobs);
g_mutex_unlock (daemon->priv->lock);
l = daemon->priv->pending_jobs->head;
@@ -227,35 +357,13 @@ start_jobs_at_idle (gpointer data)
return FALSE;
}
-/* Called with lock held */
-static void
-queue_start_jobs_at_idle (GVfsDaemon *daemon)
-{
- if (daemon->priv->queued_job_start == 0)
- daemon->priv->queued_job_start = g_idle_add (start_jobs_at_idle, daemon);
-}
-
+/* NOTE: Might be emitted on a thread */
static void
-handle_new_job_callback (GVfsReadChannel *channel,
- GVfsJob *job,
+job_new_source_callback (GVfsJob *job,
+ GVfsJobSource *job_source,
GVfsDaemon *daemon)
{
- g_print ("handle_new_job_callback() job=%p daemon=%p\n", job, daemon);
- g_object_ref (job);
- start_or_queue_job (daemon, job);
-}
-
-static void
-handle_read_channel_closed_callback (GVfsReadChannel *channel,
- GVfsDaemon *daemon)
-{
- g_mutex_lock (daemon->priv->lock);
-
- daemon->priv->read_channels = g_list_remove (daemon->priv->read_channels, channel);
- g_signal_handlers_disconnect_by_func (channel, (GCallback)handle_new_job_callback, daemon);
- g_object_unref (channel);
-
- g_mutex_unlock (daemon->priv->lock);
+ g_vfs_daemon_add_job_source (daemon, job_source);
}
/* NOTE: Might be emitted on a thread */
@@ -263,50 +371,47 @@ static void
job_finished_callback (GVfsJob *job,
GVfsDaemon *daemon)
{
+
+ g_signal_handlers_disconnect_by_func (job,
+ (GCallback)job_new_source_callback,
+ daemon);
+ g_signal_handlers_disconnect_by_func (job,
+ (GCallback)job_finished_callback,
+ daemon);
+
g_mutex_lock (daemon->priv->lock);
g_queue_remove (daemon->priv->jobs, job);
- queue_start_jobs_at_idle (daemon);
-
- if (G_IS_VFS_JOB_OPEN_FOR_READ (job))
- {
- GVfsJobOpenForRead *open_job = G_VFS_JOB_OPEN_FOR_READ (job);
- GVfsReadChannel *channel;
-
- channel = g_vfs_job_open_for_read_steal_channel (open_job);
-
- if (channel)
- {
- g_print ("Got new read channel %p for daemon %p\n", channel, daemon);
- daemon->priv->read_channels = g_list_append (daemon->priv->read_channels,
- channel);
- g_signal_connect (channel, "new_job", (GCallback)handle_new_job_callback, daemon);
- g_signal_connect (channel, "closed", (GCallback)handle_read_channel_closed_callback, daemon);
- }
- }
-
+ if (daemon->priv->queued_job_start == 0)
+ daemon->priv->queued_job_start = g_idle_add (start_jobs_at_idle, daemon);
+
g_mutex_unlock (daemon->priv->lock);
g_object_unref (job);
}
-static void
-start_or_queue_job (GVfsDaemon *daemon,
- GVfsJob *job)
+void
+g_vfs_daemon_queue_job (GVfsDaemon *daemon,
+ GVfsJob *job)
{
- g_assert (job->backend != NULL);
+ g_print ("Queued new job %p (%s)\n", job, g_type_name_from_instance ((gpointer)job));
+
+ g_object_ref (job);
+ g_signal_connect (job, "finished", (GCallback)job_finished_callback, daemon);
+ g_signal_connect (job, "new_source", (GCallback)job_new_source_callback, daemon);
g_mutex_lock (daemon->priv->lock);
g_queue_push_tail (daemon->priv->jobs, job);
g_mutex_unlock (daemon->priv->lock);
- g_signal_connect (job, "finished", (GCallback)job_finished_callback, daemon);
/* Can we start the job immediately */
if (!g_vfs_job_start (job))
{
/* Didn't start, queue as pending */
- g_queue_push_tail (daemon->priv->pending_jobs, job);
+ g_mutex_lock (daemon->priv->lock);
+ g_queue_push_tail (daemon->priv->new_pending_jobs, job);
+ g_mutex_unlock (daemon->priv->lock);
}
}
@@ -328,7 +433,7 @@ new_connection_data_free (void *memory)
static void
daemon_peer_connection_setup (GVfsDaemon *daemon,
- DBusConnection *dbus_conn,
+ DBusConnection *dbus_conn,
NewConnectionData *data)
{
/* We wait until we have the extra fd */
@@ -344,11 +449,8 @@ daemon_peer_connection_setup (GVfsDaemon *daemon,
}
dbus_connection_setup_with_g_main (dbus_conn, NULL);
- if (!dbus_connection_add_filter (dbus_conn, daemon_filter_func, daemon, NULL) ||
- !dbus_connection_register_object_path (dbus_conn,
- G_VFS_DBUS_DAEMON_PATH,
- &daemon_vtable,
- daemon))
+ if (!dbus_connection_add_filter (dbus_conn, peer_to_peer_filter_func, daemon, NULL) ||
+ !dbus_connection_add_filter (dbus_conn, daemon_message_func, daemon, NULL))
{
g_warning (_("Failed to accept client: %s"), _("object registration failed"));
dbus_connection_unref (dbus_conn);
@@ -598,20 +700,6 @@ accept_new_fd_client (GIOChannel *channel,
}
static void
-append_mountpoint_cb (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- DBusMessageIter *array_iter = user_data;
- GVfsBackend *backend = value;
- char *mountpoint = backend->mountpoint;
-
- if (!dbus_message_iter_append_basic (array_iter,
- DBUS_TYPE_STRING, &mountpoint))
- g_error ("Can't allocate dbus message");
-}
-
-static void
daemon_handle_get_connection (DBusConnection *conn,
DBusMessage *message,
GVfsDaemon *daemon)
@@ -625,7 +713,6 @@ daemon_handle_get_connection (DBusConnection *conn,
GIOChannel *channel;
char *socket_dir;
int fd;
- DBusMessageIter iter, array_iter;
generate_addresses (&address1, &address2, &socket_dir);
@@ -679,21 +766,6 @@ daemon_handle_get_connection (DBusConnection *conn,
DBUS_TYPE_STRING, &address2,
DBUS_TYPE_INVALID))
g_error ("Can't allocate dbus message\n");
-
- dbus_message_iter_init_append (reply, &iter);
-
- if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING,
- &array_iter))
- g_error ("Can't allocate dbus message\n");
-
-
- g_hash_table_foreach (daemon->priv->backends,
- append_mountpoint_cb,
- &array_iter);
-
- if (!dbus_message_iter_close_container (&iter, &array_iter))
- g_error ("Can't allocate dbus message\n");
dbus_connection_send (conn, reply, NULL);
@@ -715,22 +787,51 @@ daemon_handle_get_connection (DBusConnection *conn,
}
}
-
-static void
-daemon_unregistered_func (DBusConnection *conn,
- gpointer data)
-{
-}
-
static DBusHandlerResult
daemon_message_func (DBusConnection *conn,
DBusMessage *message,
gpointer data)
{
GVfsDaemon *daemon = data;
- GVfsBackend *backend;
- const char *dest;
GVfsJob *job;
+ RegisteredPath *registered_path;
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
+ {
+ char *name, *from, *to;
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &from,
+ DBUS_TYPE_STRING, &to,
+ DBUS_TYPE_INVALID))
+ {
+ const char *my_name = dbus_bus_get_unique_name (conn);
+
+ g_print ("NameOwnerChanged %s %s->%s (my name: %s)\n", name, from, to, my_name);
+
+ if (strcmp (name, G_VFS_DBUS_DAEMON_NAME) == 0)
+ {
+ /* Someone else got the name (i.e. someone used --replace), exit */
+ if (daemon->priv->main_daemon &&
+ strcmp (to, my_name) != 0)
+ exit (1);
+
+ if (*to != 0)
+ {
+ GList *l;
+
+ /* New owner, tell all backends to re-register */
+ g_mutex_lock (daemon->priv->lock);
+ for (l = daemon->priv->job_sources; l != NULL; l = l->next)
+ {
+ GVfsJobSource *source = l->data;
+ g_vfs_job_source_reset (source);
+ }
+ g_mutex_unlock (daemon->priv->lock);
+ }
+ }
+ }
+ }
job = NULL;
if (dbus_message_is_method_call (message,
@@ -780,32 +881,21 @@ daemon_message_func (DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
-
- backend = NULL;
- dest = dbus_message_get_destination (message);
- if (dest != NULL)
- backend = g_hash_table_lookup (daemon->priv->backends,
- dest);
- if (backend == NULL)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (dbus_message_is_method_call (message,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_OPEN_FOR_READ))
- job = g_vfs_job_open_for_read_new (conn, message, backend);
+ registered_path = g_hash_table_lookup (daemon->priv->registered_paths,
+ dbus_message_get_path (message));
+ if (registered_path)
+ return registered_path->callback (conn, message, registered_path->data);
else
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (job)
- start_or_queue_job (daemon, job);
-
- return DBUS_HANDLER_RESULT_HANDLED;
}
+
+/* Only called for peer-to-peer connections */
static DBusHandlerResult
-daemon_filter_func (DBusConnection *conn,
- DBusMessage *message,
- gpointer data)
+peer_to_peer_filter_func (DBusConnection *conn,
+ DBusMessage *message,
+ gpointer data)
{
if (dbus_message_is_signal (message,
DBUS_INTERFACE_LOCAL,
diff --git a/daemon/gvfsdaemon.h b/daemon/gvfsdaemon.h
index 7440d381..405f2332 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -2,6 +2,8 @@
#define __G_VFS_DAEMON_H__
#include <glib-object.h>
+#include <gvfsjobsource.h>
+#include <dbus/dbus.h>
G_BEGIN_DECLS
@@ -16,9 +18,6 @@ typedef struct _GVfsDaemon GVfsDaemon;
typedef struct _GVfsDaemonClass GVfsDaemonClass;
typedef struct _GVfsDaemonPrivate GVfsDaemonPrivate;
-/* Placed here to fix circular ref problems in headers */
-typedef struct _GVfsBackend GVfsBackend;
-
struct _GVfsDaemon
{
GObject parent_instance;
@@ -36,9 +35,16 @@ struct _GVfsDaemonClass
GType g_vfs_daemon_get_type (void) G_GNUC_CONST;
-GVfsDaemon *g_vfs_daemon_new (void);
-gboolean g_vfs_daemon_add_backend (GVfsDaemon *daemon,
- GVfsBackend *backend);
+GVfsDaemon *g_vfs_daemon_new (gboolean main_daemon,
+ gboolean replace);
+void g_vfs_daemon_add_job_source (GVfsDaemon *daemon,
+ GVfsJobSource *job_source);
+void g_vfs_daemon_queue_job (GVfsDaemon *daemon,
+ GVfsJob *job);
+gboolean g_vfs_daemon_register_path (GVfsDaemon *daemon,
+ const char *path,
+ DBusObjectPathMessageFunction callback,
+ gpointer user_data);
G_END_DECLS
diff --git a/daemon/gvfsdaemonprotocol.h b/daemon/gvfsdaemonprotocol.h
index ef3879a8..a265c5fb 100644
--- a/daemon/gvfsdaemonprotocol.h
+++ b/daemon/gvfsdaemonprotocol.h
@@ -3,6 +3,11 @@
G_BEGIN_DECLS
+#define G_VFS_DBUS_DAEMON_NAME "org.gtk.vfs.Daemon"
+
+#define G_VFS_DBUS_MOUNTPOINT_INTERFACE "org.gtk.vfs.Mountpoint"
+#define G_VFS_DBUS_ANNOUNCE_MOUNTPOINT "AnnounceMountpoint"
+
#define G_VFS_DBUS_MOUNTPOINT_NAME "org.gtk.vfs.mount."
#define G_VFS_DBUS_ERROR_SOCKET_FAILED "org.gtk.vfs.Error.SocketFailed"
diff --git a/daemon/gvfsdaemonutils.c b/daemon/gvfsdaemonutils.c
index 68dd5825..d8b62853 100644
--- a/daemon/gvfsdaemonutils.c
+++ b/daemon/gvfsdaemonutils.c
@@ -265,3 +265,24 @@ g_error_to_daemon_reply (GError *error, guint32 seq_nr, gsize *len_out)
return buffer;
}
+gboolean
+_g_dbus_message_iter_append_filename (DBusMessageIter *iter, const char *filename)
+{
+ DBusMessageIter array;
+
+ if (!dbus_message_iter_open_container (iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_BYTE_AS_STRING,
+ &array))
+ return FALSE;
+
+ if (!dbus_message_iter_append_fixed_array (&array,
+ DBUS_TYPE_BYTE,
+ &filename, strlen (filename)))
+ return FALSE;
+
+ if (!dbus_message_iter_close_container (iter, &array))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/daemon/gvfsdaemonutils.h b/daemon/gvfsdaemonutils.h
index 16b27bd9..507d3e28 100644
--- a/daemon/gvfsdaemonutils.h
+++ b/daemon/gvfsdaemonutils.h
@@ -6,18 +6,20 @@
G_BEGIN_DECLS
-DBusMessage *dbus_message_new_error_from_gerror (DBusMessage *message,
- GError *error);
-void dbus_connection_add_fd_send_fd (DBusConnection *connection,
- int extra_fd);
-gboolean dbus_connection_send_fd (DBusConnection *connection,
- int fd,
- int *fd_id,
- GError **error);
-char * g_error_to_daemon_reply (GError *error,
- guint32 seq_nr,
- gsize *len_out);
-char * _g_dbus_bus_name_from_mountpoint (const char *mountpoint);
+DBusMessage *dbus_message_new_error_from_gerror (DBusMessage *message,
+ GError *error);
+void dbus_connection_add_fd_send_fd (DBusConnection *connection,
+ int extra_fd);
+gboolean dbus_connection_send_fd (DBusConnection *connection,
+ int fd,
+ int *fd_id,
+ GError **error);
+char * g_error_to_daemon_reply (GError *error,
+ guint32 seq_nr,
+ gsize *len_out);
+char * _g_dbus_bus_name_from_mountpoint (const char *mountpoint);
+gboolean _g_dbus_message_iter_append_filename (DBusMessageIter *iter,
+ const char *filename);
G_END_DECLS
diff --git a/daemon/gvfsjob.c b/daemon/gvfsjob.c
index 6207773b..36db2578 100644
--- a/daemon/gvfsjob.c
+++ b/daemon/gvfsjob.c
@@ -9,7 +9,6 @@
#include <dbus/dbus.h>
#include <glib/gi18n.h>
#include "gvfsjob.h"
-#include "gvfsbackend.h"
G_DEFINE_TYPE (GVfsJob, g_vfs_job, G_TYPE_OBJECT);
@@ -18,7 +17,6 @@ G_DEFINE_TYPE (GVfsJob, g_vfs_job, G_TYPE_OBJECT);
enum {
PROP_0,
- PROP_BACKEND,
};
enum {
@@ -28,6 +26,11 @@ enum {
LAST_SIGNAL
};
+struct _GVfsJobPrivate
+{
+ int dummy;
+};
+
static guint signals[LAST_SIGNAL] = { 0 };
static void g_vfs_job_get_property (GObject *object,
@@ -57,6 +60,8 @@ static void
g_vfs_job_class_init (GVfsJobClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GVfsJobPrivate));
gobject_class->finalize = g_vfs_job_finalize;
gobject_class->set_property = g_vfs_job_set_property;
@@ -86,20 +91,13 @@ g_vfs_job_class_init (GVfsJobClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
-
- g_object_class_install_property (gobject_class,
- PROP_BACKEND,
- g_param_spec_object ("backend",
- P_("VFS Backend"),
- P_("The implementation for this job operartion."),
- G_TYPE_VFS_BACKEND,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
}
static void
g_vfs_job_init (GVfsJob *job)
{
+ job->priv = G_TYPE_INSTANCE_GET_PRIVATE (job, G_TYPE_VFS_JOB, GVfsJobPrivate);
+
}
static void
@@ -108,13 +106,8 @@ g_vfs_job_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GVfsJob *job = G_VFS_JOB (object);
-
switch (prop_id)
{
- case PROP_BACKEND:
- job->backend = g_value_get_object (value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -127,13 +120,8 @@ g_vfs_job_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- GVfsJob *job = G_VFS_JOB (object);
-
switch (prop_id)
{
- case PROP_BACKEND:
- g_value_set_object (value, job->backend);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/daemon/gvfsjob.h b/daemon/gvfsjob.h
index b9cc4702..6eb1fbfc 100644
--- a/daemon/gvfsjob.h
+++ b/daemon/gvfsjob.h
@@ -2,7 +2,6 @@
#define __G_VFS_JOB_H__
#include <glib-object.h>
-#include <gvfsdaemon.h>
G_BEGIN_DECLS
@@ -13,26 +12,26 @@ G_BEGIN_DECLS
#define G_IS_VFS_JOB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB))
#define G_VFS_JOB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB, GVfsJobClass))
-typedef struct _GVfsJob GVfsJob;
-typedef struct _GVfsJobClass GVfsJobClass;
+typedef struct _GVfsJob GVfsJob;
+typedef struct _GVfsJobPrivate GVfsJobPrivate;
+typedef struct _GVfsJobClass GVfsJobClass;
-/* Define these here to avoid circular includes */
-typedef struct _GVfsJobOpenForRead GVfsJobOpenForRead;
-typedef struct _GVfsJobCloseRead GVfsJobCloseRead;
-typedef struct _GVfsJobRead GVfsJobRead;
-typedef struct _GVfsJobSeekRead GVfsJobSeekRead;
+/* Defined here to avoid circular includes */
+typedef struct _GVfsJobSource GVfsJobSource;
struct _GVfsJob
{
GObject parent_instance;
-
- GVfsBackend *backend;
+
+ /* TODO: Move stuff to private */
gpointer backend_data;
guint failed : 1;
guint cancelled : 1;
guint sending_reply : 1;
guint finished : 1;
GError *error;
+
+ GVfsJobPrivate *priv;
};
struct _GVfsJobClass
@@ -42,6 +41,8 @@ struct _GVfsJobClass
/* signals */
void (*cancelled) (GVfsJob *job);
void (*send_reply) (GVfsJob *job);
+ void (*new_source) (GVfsJob *job,
+ GVfsJobSource *job_source);
void (*finished) (GVfsJob *job);
/* vtable */
diff --git a/daemon/gvfsjobcloseread.c b/daemon/gvfsjobcloseread.c
index 28aeddc2..4ea7904a 100644
--- a/daemon/gvfsjobcloseread.c
+++ b/daemon/gvfsjobcloseread.c
@@ -53,10 +53,10 @@ g_vfs_job_close_read_new (GVfsReadChannel *channel,
GVfsJobCloseRead *job;
job = g_object_new (G_TYPE_VFS_JOB_CLOSE_READ,
- "backend", backend,
NULL);
job->channel = g_object_ref (channel);
+ job->backend = backend;
job->handle = handle;
return G_VFS_JOB (job);
@@ -81,7 +81,7 @@ start (GVfsJob *job)
{
GVfsJobCloseRead *op_job = G_VFS_JOB_CLOSE_READ (job);
- return g_vfs_backend_close_read (job->backend,
+ return g_vfs_backend_close_read (op_job->backend,
op_job,
op_job->handle);
}
diff --git a/daemon/gvfsjobcloseread.h b/daemon/gvfsjobcloseread.h
index 5333c006..f7725593 100644
--- a/daemon/gvfsjobcloseread.h
+++ b/daemon/gvfsjobcloseread.h
@@ -14,7 +14,6 @@ G_BEGIN_DECLS
#define G_IS_VFS_JOB_CLOSE_READ_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB_CLOSE_READ))
#define G_VFS_JOB_CLOSE_READ_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB_CLOSE_READ, GVfsJobCloseReadClass))
-/* GVfsJobCloseRead declared in gvfsjob.h */
typedef struct _GVfsJobCloseReadClass GVfsJobCloseReadClass;
struct _GVfsJobCloseRead
@@ -22,6 +21,7 @@ struct _GVfsJobCloseRead
GVfsJob parent_instance;
GVfsReadChannel *channel;
+ GVfsBackend *backend;
GVfsBackendHandle handle;
};
diff --git a/daemon/gvfsjobdbus.c b/daemon/gvfsjobdbus.c
new file mode 100644
index 00000000..d693f346
--- /dev/null
+++ b/daemon/gvfsjobdbus.c
@@ -0,0 +1,162 @@
+#include <config.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <glib/gi18n.h>
+#include "gvfsjobdbus.h"
+#include "gvfsdaemonutils.h"
+
+G_DEFINE_TYPE (GVfsJobDBus, g_vfs_job_dbus, G_TYPE_VFS_JOB);
+
+/* TODO: Real P_() */
+#define P_(_x) (_x)
+
+enum {
+ PROP_0,
+ PROP_MESSAGE,
+ PROP_CONNECTION,
+};
+
+static void send_reply (GVfsJob *job);
+static void g_vfs_job_dbus_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void g_vfs_job_dbus_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void
+g_vfs_job_dbus_finalize (GObject *object)
+{
+ GVfsJobDBus *job;
+
+ job = G_VFS_JOB_DBUS (object);
+
+ if (job->message)
+ dbus_message_unref (job->message);
+
+ if (job->connection)
+ dbus_connection_unref (job->connection);
+
+ if (G_OBJECT_CLASS (g_vfs_job_dbus_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_vfs_job_dbus_parent_class)->finalize) (object);
+}
+
+static void
+g_vfs_job_dbus_class_init (GVfsJobDBusClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
+
+ gobject_class->finalize = g_vfs_job_dbus_finalize;
+ gobject_class->set_property = g_vfs_job_dbus_set_property;
+ gobject_class->get_property = g_vfs_job_dbus_get_property;
+
+ job_class->send_reply = send_reply;
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_pointer ("connection",
+ P_("VFS Backend"),
+ P_("The implementation for this job operartion."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+ g_object_class_install_property (gobject_class,
+ PROP_MESSAGE,
+ g_param_spec_pointer ("message",
+ P_("VFS Backend"),
+ P_("The implementation for this job operartion."),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+}
+
+static void
+g_vfs_job_dbus_init (GVfsJobDBus *job)
+{
+}
+
+static void
+g_vfs_job_dbus_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GVfsJobDBus *job = G_VFS_JOB_DBUS (object);
+
+ switch (prop_id)
+ {
+ case PROP_MESSAGE:
+ job->message = dbus_message_ref (g_value_get_pointer (value));
+ break;
+ case PROP_CONNECTION:
+ job->connection = dbus_connection_ref (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_vfs_job_dbus_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GVfsJobDBus *job = G_VFS_JOB_DBUS (object);
+
+ switch (prop_id)
+ {
+ case PROP_MESSAGE:
+ g_value_set_pointer (value, job->message);
+ break;
+ case PROP_CONNECTION:
+ g_value_set_pointer (value, job->connection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* Might be called on an i/o thread */
+static void
+send_reply (GVfsJob *job)
+{
+ GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job);
+ DBusMessage *reply;
+ GVfsJobDBusClass *class;
+
+ g_print ("send_reply, failed=%d (%s)\n", job->failed, job->failed?job->error->message:"");
+
+ class = G_VFS_JOB_DBUS_GET_CLASS (job);
+
+ if (job->failed)
+ reply = dbus_message_new_error_from_gerror (dbus_job->message, job->error);
+ else
+ reply = class->create_reply (job, dbus_job->connection, dbus_job->message);
+
+ g_assert (reply != NULL);
+
+ /* Queues reply (threadsafely), actually sends it in mainloop */
+ dbus_connection_send (dbus_job->connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ g_vfs_job_emit_finished (job);
+}
+
+gboolean
+g_vfs_job_dbus_is_serial (GVfsJobDBus *job_dbus,
+ DBusConnection *connection,
+ dbus_uint32_t serial)
+{
+ return job_dbus->connection == connection &&
+ dbus_message_get_serial (job_dbus->message) == serial;
+}
diff --git a/daemon/gvfsjobdbus.h b/daemon/gvfsjobdbus.h
new file mode 100644
index 00000000..78d68d84
--- /dev/null
+++ b/daemon/gvfsjobdbus.h
@@ -0,0 +1,46 @@
+#ifndef __G_VFS_JOB_DBUS_H__
+#define __G_VFS_JOB_DBUS_H__
+
+#include <dbus/dbus.h>
+#include <gvfsjob.h>
+#include <gvfsbackend.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_VFS_JOB_DBUS (g_vfs_job_dbus_get_type ())
+#define G_VFS_JOB_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_VFS_JOB_DBUS, GVfsJobDBus))
+#define G_VFS_JOB_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_VFS_JOB_DBUS, GVfsJobDBusClass))
+#define G_IS_VFS_JOB_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VFS_JOB_DBUS))
+#define G_IS_VFS_JOB_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB_DBUS))
+#define G_VFS_JOB_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB_DBUS, GVfsJobDBusClass))
+
+typedef struct _GVfsJobDBus GVfsJobDBus;
+typedef struct _GVfsJobDBusClass GVfsJobDBusClass;
+
+struct _GVfsJobDBus
+{
+ GVfsJob parent_instance;
+
+ DBusConnection *connection;
+ DBusMessage *message;
+};
+
+struct _GVfsJobDBusClass
+{
+ GVfsJobClass parent_class;
+
+ /* Might be called on an i/o thread */
+ DBusMessage * (*create_reply) (GVfsJob *job,
+ DBusConnection *connection,
+ DBusMessage *message);
+};
+
+GType g_vfs_job_dbus_get_type (void) G_GNUC_CONST;
+
+gboolean g_vfs_job_dbus_is_serial (GVfsJobDBus *job_dbus,
+ DBusConnection *connection,
+ dbus_uint32_t serial);
+
+G_END_DECLS
+
+#endif /* __G_VFS_JOB_DBUS_H__ */
diff --git a/daemon/gvfsjobopenforread.c b/daemon/gvfsjobopenforread.c
index 6eec8d9f..baff8aea 100644
--- a/daemon/gvfsjobopenforread.c
+++ b/daemon/gvfsjobopenforread.c
@@ -81,12 +81,12 @@ g_vfs_job_open_for_read_new (DBusConnection *connection,
}
job = g_object_new (G_TYPE_VFS_JOB_OPEN_FOR_READ,
- "backend", backend,
"message", message,
"connection", connection,
NULL);
job->filename = g_strndup (path_data, path_len);
+ job->backend = backend;
return G_VFS_JOB (job);
}
@@ -96,7 +96,7 @@ start (GVfsJob *job)
{
GVfsJobOpenForRead *op_job = G_VFS_JOB_OPEN_FOR_READ (job);
- return g_vfs_backend_open_for_read (job->backend,
+ return g_vfs_backend_open_for_read (op_job->backend,
op_job,
op_job->filename);
}
@@ -133,7 +133,7 @@ create_reply (GVfsJob *job,
g_assert (open_job->backend_handle != NULL);
error = NULL;
- channel = g_vfs_read_channel_new (job->backend, &error);
+ channel = g_vfs_read_channel_new (open_job->backend, &error);
if (channel == NULL)
{
reply = dbus_message_new_error_from_gerror (message, error);
diff --git a/daemon/gvfsjobopenforread.h b/daemon/gvfsjobopenforread.h
index b301bb5c..4be12bcc 100644
--- a/daemon/gvfsjobopenforread.h
+++ b/daemon/gvfsjobopenforread.h
@@ -15,7 +15,6 @@ G_BEGIN_DECLS
#define G_IS_VFS_JOB_OPEN_FOR_READ_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB_OPEN_FOR_READ))
#define G_VFS_JOB_OPEN_FOR_READ_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB_OPEN_FOR_READ, GVfsJobOpenForReadClass))
-/* GVfsJobOpenForRead declared in gvfsjob.h */
typedef struct _GVfsJobOpenForReadClass GVfsJobOpenForReadClass;
struct _GVfsJobOpenForRead
@@ -23,6 +22,7 @@ struct _GVfsJobOpenForRead
GVfsJobDBus parent_instance;
char *filename;
+ GVfsBackend *backend;
GVfsBackendHandle backend_handle;
gboolean can_seek;
GVfsReadChannel *read_channel;
diff --git a/daemon/gvfsjobread.c b/daemon/gvfsjobread.c
index 84cbe277..e8f45df6 100644
--- a/daemon/gvfsjobread.c
+++ b/daemon/gvfsjobread.c
@@ -56,9 +56,9 @@ g_vfs_job_read_new (GVfsReadChannel *channel,
GVfsJobRead *job;
job = g_object_new (G_TYPE_VFS_JOB_READ,
- "backend", backend,
NULL);
-
+
+ job->backend = backend;
job->channel = g_object_ref (channel);
job->handle = handle;
job->buffer = g_malloc (bytes_requested);
@@ -89,7 +89,7 @@ start (GVfsJob *job)
{
GVfsJobRead *op_job = G_VFS_JOB_READ (job);
- return g_vfs_backend_read (job->backend,
+ return g_vfs_backend_read (op_job->backend,
op_job,
op_job->handle,
op_job->buffer,
diff --git a/daemon/gvfsjobread.h b/daemon/gvfsjobread.h
index f7cda3e8..ea084428 100644
--- a/daemon/gvfsjobread.h
+++ b/daemon/gvfsjobread.h
@@ -14,7 +14,6 @@ G_BEGIN_DECLS
#define G_IS_VFS_JOB_READ_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB_READ))
#define G_VFS_JOB_READ_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB_READ, GVfsJobReadClass))
-/* GVfsJobRead declared in gvfsjob.h */
typedef struct _GVfsJobReadClass GVfsJobReadClass;
struct _GVfsJobRead
@@ -22,6 +21,7 @@ struct _GVfsJobRead
GVfsJob parent_instance;
GVfsReadChannel *channel;
+ GVfsBackend *backend;
GVfsBackendHandle handle;
gsize bytes_requested;
char *buffer;
diff --git a/daemon/gvfsjobseekread.c b/daemon/gvfsjobseekread.c
index d3678b31..0e898cf1 100644
--- a/daemon/gvfsjobseekread.c
+++ b/daemon/gvfsjobseekread.c
@@ -55,9 +55,9 @@ g_vfs_job_seek_read_new (GVfsReadChannel *channel,
GVfsJobSeekRead *job;
job = g_object_new (G_TYPE_VFS_JOB_SEEK_READ,
- "backend", backend,
NULL);
-
+
+ job->backend = backend;
job->channel = g_object_ref (channel);
job->handle = handle;
job->requested_offset = offset;
@@ -88,7 +88,7 @@ start (GVfsJob *job)
{
GVfsJobSeekRead *op_job = G_VFS_JOB_SEEK_READ (job);
- return g_vfs_backend_seek_on_read (job->backend,
+ return g_vfs_backend_seek_on_read (op_job->backend,
op_job,
op_job->handle,
op_job->requested_offset,
diff --git a/daemon/gvfsjobseekread.h b/daemon/gvfsjobseekread.h
index be11be53..15f5bc64 100644
--- a/daemon/gvfsjobseekread.h
+++ b/daemon/gvfsjobseekread.h
@@ -14,7 +14,6 @@ G_BEGIN_DECLS
#define G_IS_VFS_JOB_SEEK_READ_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS_JOB_SEEK_READ))
#define G_VFS_JOB_SEEK_READ_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS_JOB_SEEK_READ, GVfsJobSeekReadClass))
-/* GVfsJobSeekRead declared in gvfsjob.h */
typedef struct _GVfsJobSeekReadClass GVfsJobSeekReadClass;
struct _GVfsJobSeekRead
@@ -22,6 +21,7 @@ struct _GVfsJobSeekRead
GVfsJob parent_instance;
GVfsReadChannel *channel;
+ GVfsBackend *backend;
GVfsBackendHandle handle;
GSeekType seek_type;
goffset requested_offset;
diff --git a/daemon/gvfsjobsource.c b/daemon/gvfsjobsource.c
new file mode 100644
index 00000000..86fef8ea
--- /dev/null
+++ b/daemon/gvfsjobsource.c
@@ -0,0 +1,108 @@
+#include <config.h>
+#include "gvfsjobsource.h"
+
+static void g_vfs_job_source_base_init (gpointer g_class);
+
+enum {
+ NEW_JOB,
+ CLOSED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+g_vfs_job_source_get_type (void)
+{
+ static GType vfs_job_source_type = 0;
+
+ if (! vfs_job_source_type)
+ {
+ static const GTypeInfo vfs_job_source_info =
+ {
+ sizeof (GVfsJobSourceIface), /* class_size */
+ g_vfs_job_source_base_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ vfs_job_source_type =
+ g_type_register_static (G_TYPE_INTERFACE, "GVfsJobSource",
+ &vfs_job_source_info, 0);
+
+ g_type_interface_add_prerequisite (vfs_job_source_type, G_TYPE_OBJECT);
+ }
+
+ return vfs_job_source_type;
+}
+
+
+static void
+g_vfs_job_source_base_init (gpointer g_class)
+{
+ static gboolean initialized = FALSE;
+
+ if (! initialized)
+ {
+ initialized = TRUE;
+
+ signals[NEW_JOB] =
+ g_signal_new ("new_job",
+ G_TYPE_VFS_JOB_SOURCE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVfsJobSourceIface, new_job),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_VFS_JOB);
+
+ signals[CLOSED] =
+ g_signal_new ("closed",
+ G_TYPE_VFS_JOB_SOURCE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVfsJobSourceIface, closed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ }
+}
+
+/*
+gboolean
+g_vfs_job_source_is_native (GVfsJobSource *vfs_job_source)
+{
+ GVfsJobSourceIface *iface;
+
+ iface = G_VFS_JOB_SOURCE_GET_IFACE (vfs_job_source);
+
+ return (* iface->is_native) (vfs_job_source);
+}
+*/
+
+void
+g_vfs_job_source_new_job (GVfsJobSource *job_source,
+ GVfsJob *job)
+{
+ g_signal_emit (job_source, signals[NEW_JOB], 0, job);
+}
+
+void
+g_vfs_job_source_closed (GVfsJobSource *job_source)
+{
+ g_signal_emit (job_source, signals[CLOSED], 0);
+}
+
+void
+g_vfs_job_source_reset (GVfsJobSource *job_source)
+{
+ GVfsJobSourceIface *iface;
+
+ iface = G_VFS_JOB_SOURCE_GET_IFACE (job_source);
+
+ if (iface->reset)
+ (* iface->reset) (job_source);
+}
diff --git a/daemon/gvfsjobsource.h b/daemon/gvfsjobsource.h
new file mode 100644
index 00000000..41696787
--- /dev/null
+++ b/daemon/gvfsjobsource.h
@@ -0,0 +1,43 @@
+#ifndef __G_VFS_JOB_SOURCE_H__
+#define __G_VFS_JOB_SOURCE_H__
+
+#include <glib-object.h>
+#include <gvfsjob.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_VFS_JOB_SOURCE (g_vfs_job_source_get_type ())
+#define G_VFS_JOB_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_VFS_JOB_SOURCE, GVfsJobSource))
+#define G_IS_VFS_JOB_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_VFS_JOB_SOURCE))
+#define G_VFS_JOB_SOURCE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_VFS_JOB_SOURCE, GVfsJobSourceIface))
+
+/* GVfsJobSource defined in gvfsjob.h */
+typedef struct _GVfsJobSourceIface GVfsJobSourceIface;
+
+struct _GVfsJobSourceIface
+{
+ GTypeInterface g_iface;
+
+ /* Virtual Table: */
+
+ void (*reset) (GVfsJobSource *source);
+
+ /* Signals: */
+
+ void (*new_job) (GVfsJobSource *source,
+ GVfsJob *job);
+ void (*closed) (GVfsJobSource *source);
+
+};
+
+GType g_vfs_job_source_get_type (void) G_GNUC_CONST;
+
+void g_vfs_job_source_new_job (GVfsJobSource *job_source,
+ GVfsJob *job);
+void g_vfs_job_source_closed (GVfsJobSource *job_source);
+void g_vfs_job_source_reset (GVfsJobSource *job_source);
+
+
+G_END_DECLS
+
+#endif /* __G_VFS_JOB_SOURCE_H__ */
diff --git a/daemon/gvfsmountpoint.c b/daemon/gvfsmountpoint.c
new file mode 100644
index 00000000..1ac35dc7
--- /dev/null
+++ b/daemon/gvfsmountpoint.c
@@ -0,0 +1,61 @@
+#include <config.h>
+#include <gvfsmountpoint.h>
+#include <gvfsdaemonutils.h>
+
+GVfsMountpoint *
+g_vfs_mountpoint_copy (GVfsMountpoint *mountpoint)
+{
+ GVfsMountpoint *copy;
+
+ copy = g_new (GVfsMountpoint, 1);
+ copy->method = g_strdup (mountpoint->method);
+ copy->user = g_strdup (mountpoint->user);
+ copy->host = g_strdup (mountpoint->host);
+ copy->port = mountpoint->port;
+ copy->path = g_strdup (mountpoint->path);
+
+ return copy;
+}
+
+void
+g_vfs_mountpoint_free (GVfsMountpoint *mountpoint)
+{
+ g_free (mountpoint->method);
+ g_free (mountpoint->user);
+ g_free (mountpoint->host);
+ g_free (mountpoint->path);
+ g_free (mountpoint);
+}
+
+GVfsMountpoint *
+g_vfs_mountpoint_from_dbus (DBusMessageIter *iter)
+{
+ return NULL;
+}
+
+void
+g_vfs_mountpoint_to_dbus (GVfsMountpoint *mountpoint,
+ DBusMessageIter *iter)
+{
+ dbus_bool_t res;
+ dbus_int32_t port;
+
+ res = TRUE;
+ res &= dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING,
+ &mountpoint->method);
+
+ /* TODO: Is this always utf8? */
+ res &= dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING,
+ &mountpoint->user);
+
+ res &= dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING,
+ &mountpoint->host);
+
+ port = mountpoint->port;
+ res &= dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &port);
+
+ res &= _g_dbus_message_iter_append_filename (iter, mountpoint->path);
+
+ if (!res)
+ g_error ("out of memory");
+}
diff --git a/daemon/gvfsmountpoint.h b/daemon/gvfsmountpoint.h
new file mode 100644
index 00000000..12459fe9
--- /dev/null
+++ b/daemon/gvfsmountpoint.h
@@ -0,0 +1,22 @@
+#ifndef __G_VFS_MOUNTPOINT_H__
+#define __G_VFS_MOUNTPOINT_H__
+
+#include <glib.h>
+#include <dbus/dbus.h>
+
+
+typedef struct {
+ char *method;
+ char *user;
+ char *host;
+ int port;
+ char *path;
+} GVfsMountpoint;
+
+GVfsMountpoint *g_vfs_mountpoint_copy (GVfsMountpoint *mountpoint);
+void g_vfs_mountpoint_free (GVfsMountpoint *mountpoint);
+GVfsMountpoint *g_vfs_mountpoint_from_dbus (DBusMessageIter *iter);
+void g_vfs_mountpoint_to_dbus (GVfsMountpoint *mountpoint,
+ DBusMessageIter *iter);
+
+#endif /* __G_VFS_MOUNTPOINT_H__ */
diff --git a/daemon/gvfsreadchannel.c b/daemon/gvfsreadchannel.c
index 54a0d2c5..71ad17ff 100644
--- a/daemon/gvfsreadchannel.c
+++ b/daemon/gvfsreadchannel.c
@@ -21,20 +21,16 @@
#include <gvfsjobseekread.h>
#include <gvfsjobcloseread.h>
-G_DEFINE_TYPE (GVfsReadChannel, g_vfs_read_channel, G_TYPE_OBJECT);
+static void g_vfs_read_channel_job_source_iface_init (GVfsJobSourceIface *iface);
-enum {
- PROP_0,
-};
+G_DEFINE_TYPE_WITH_CODE (GVfsReadChannel, g_vfs_read_channel, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VFS_JOB_SOURCE,
+ g_vfs_read_channel_job_source_iface_init))
enum {
- NEW_JOB,
- CLOSED,
- LAST_SIGNAL
+ PROP_0,
};
-static guint signals[LAST_SIGNAL] = { 0 };
-
typedef struct
{
GVfsReadChannel *read_channel;
@@ -101,6 +97,11 @@ g_vfs_read_channel_finalize (GObject *object)
}
static void
+g_vfs_read_channel_job_source_iface_init (GVfsJobSourceIface *iface)
+{
+}
+
+static void
g_vfs_read_channel_class_init (GVfsReadChannelClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -108,25 +109,6 @@ g_vfs_read_channel_class_init (GVfsReadChannelClass *klass)
g_type_class_add_private (klass, sizeof (GVfsReadChannelPrivate));
gobject_class->finalize = g_vfs_read_channel_finalize;
-
- signals[NEW_JOB] =
- g_signal_new ("new_job",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVfsReadChannelClass, new_job),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_VFS_JOB);
-
- signals[CLOSED] =
- g_signal_new ("closed",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVfsReadChannelClass, closed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
}
static void
@@ -150,7 +132,7 @@ g_vfs_read_channel_connection_closed (GVfsReadChannel *channel)
{
channel->priv->current_job = g_vfs_job_close_read_new (channel, channel->priv->backend_handle, channel->priv->backend);
channel->priv->current_job_seq_nr = 0;
- g_signal_emit (channel, signals[NEW_JOB], 0, channel->priv->current_job);
+ g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (channel), channel->priv->current_job);
}
/* Otherwise we'll close when current_job is finished */
}
@@ -230,7 +212,7 @@ got_command (GVfsReadChannel *channel,
{
channel->priv->current_job = job;
channel->priv->current_job_seq_nr = seq_nr;
- g_signal_emit (channel, signals[NEW_JOB], 0, job);
+ g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (channel), channel->priv->current_job);
}
}
@@ -385,7 +367,7 @@ send_reply_cb (GOutputStream *output_stream,
if (G_IS_VFS_JOB_CLOSE_READ (job))
{
- g_signal_emit (channel, signals[CLOSED], 0);
+ g_vfs_job_source_closed (G_VFS_JOB_SOURCE (channel));
channel->priv->backend_handle = NULL;
}
else if (channel->priv->connection_closed)
@@ -393,7 +375,7 @@ send_reply_cb (GOutputStream *output_stream,
channel->priv->current_job = g_vfs_job_close_read_new (channel, channel->priv->backend_handle,
channel->priv->backend);
channel->priv->current_job_seq_nr = 0;
- g_signal_emit (channel, signals[NEW_JOB], 0, channel->priv->current_job);
+ g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (channel), channel->priv->current_job);
}
g_object_unref (job);
diff --git a/daemon/gvfsreadchannel.h b/daemon/gvfsreadchannel.h
index 3ff59e1f..4e2b6d82 100644
--- a/daemon/gvfsreadchannel.h
+++ b/daemon/gvfsreadchannel.h
@@ -44,7 +44,7 @@ GVfsReadChannel *g_vfs_read_channel_new (GVfsBackend *back
int g_vfs_read_channel_steal_remote_fd (GVfsReadChannel *read_channel);
GVfsBackend *g_vfs_read_channel_get_backend (GVfsReadChannel *read_channel);
void g_vfs_read_channel_set_backend_handle (GVfsReadChannel *read_channel,
- GVfsBackendHandle backend_handle);
+ GVfsBackendHandle backend_handle);
gboolean g_vfs_read_channel_has_job (GVfsReadChannel *read_channel);
GVfsJob * g_vfs_read_channel_get_job (GVfsReadChannel *read_channel);
void g_vfs_read_channel_send_data (GVfsReadChannel *read_channel,
diff --git a/daemon/main.c b/daemon/main.c
index 696d54c1..cd5b1e7a 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -1,58 +1,50 @@
#include <config.h>
#include <glib.h>
+#include <glib/gi18n.h>
#include <dbus/dbus.h>
#include <dbus-gmain.h>
#include "gvfsdaemon.h"
#include "gvfsbackendtest.h"
#include <gvfsdaemonprotocol.h>
-static gboolean
-init_dbus (void)
-{
- DBusConnection *conn;
- DBusError error;
-
- dbus_error_init (&error);
-
- conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if (!conn)
- {
- g_printerr ("Failed to connect to the D-BUS daemon: %s\n",
- error.message);
-
- dbus_error_free (&error);
- return FALSE;
- }
-
- dbus_connection_setup_with_g_main (conn, NULL);
-
- return TRUE;
-}
-
-
int
main (int argc, char *argv[])
{
GMainLoop *loop;
GVfsDaemon *daemon;
- GVfsBackendTest *backend;
+ gboolean replace;
+ GError *error;
+ GOptionContext *context;
+ const GOptionEntry options[] = {
+ { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, N_("Replace old daemon."), NULL },
+ { NULL }
+ };
+
+ g_set_application_name (_("GVFS Daemon"));
+ context = g_option_context_new (_(""));
+
+ g_option_context_set_summary (context, "Main daemon for GVFS");
+
+ g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+ replace = FALSE;
+ error = NULL;
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_print ("%s, use --help for usage\n", error->message);
+ g_error_free (error);
+ return 1;
+ }
+
g_thread_init (NULL);
g_type_init ();
- if (!init_dbus ())
+ daemon = g_vfs_daemon_new (TRUE, replace);
+ if (daemon == NULL)
return 1;
- daemon = g_vfs_daemon_new ();
-
- backend = g_vfs_backend_test_new ();
- if (!g_vfs_daemon_add_backend (daemon, G_VFS_BACKEND (backend)))
- return 1;
- g_object_unref (backend);
-
-
loop = g_main_loop_new (NULL, FALSE);
g_print ("Entering mainloop\n");