summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/.gitignore1
-rw-r--r--client/Makefile.am81
-rw-r--r--client/gdaemonfile.c2805
-rw-r--r--client/gdaemonfile.h54
-rw-r--r--client/gdaemonfileenumerator.c461
-rw-r--r--client/gdaemonfileenumerator.h57
-rw-r--r--client/gdaemonfileinputstream.c1643
-rw-r--r--client/gdaemonfileinputstream.h52
-rw-r--r--client/gdaemonfilemonitor.c213
-rw-r--r--client/gdaemonfilemonitor.h52
-rw-r--r--client/gdaemonfileoutputstream.c1374
-rw-r--r--client/gdaemonfileoutputstream.h53
-rw-r--r--client/gdaemonmount.c421
-rw-r--r--client/gdaemonmount.h57
-rw-r--r--client/gdaemonvfs.c1010
-rw-r--r--client/gdaemonvfs.h73
-rw-r--r--client/gdaemonvolumemonitor.c329
-rw-r--r--client/gdaemonvolumemonitor.h60
-rw-r--r--client/gvfsdaemondbus.c1024
-rw-r--r--client/gvfsdaemondbus.h80
-rw-r--r--client/gvfsfusedaemon.c2207
-rw-r--r--client/gvfsurimapper.c220
-rw-r--r--client/gvfsurimapper.h109
-rw-r--r--client/gvfsuriutils.c288
-rw-r--r--client/gvfsuriutils.h50
-rw-r--r--client/httpuri.c313
-rw-r--r--client/smburi.c297
-rw-r--r--client/test-uri-utils.c58
28 files changed, 0 insertions, 13442 deletions
diff --git a/client/.gitignore b/client/.gitignore
deleted file mode 100644
index b185be91..00000000
--- a/client/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-gvfs-fuse-daemon
diff --git a/client/Makefile.am b/client/Makefile.am
deleted file mode 100644
index 274d9fd3..00000000
--- a/client/Makefile.am
+++ /dev/null
@@ -1,81 +0,0 @@
-NULL =
-
-INCLUDES = -I$(top_srcdir) \
- -I$(top_srcdir)/client \
- -I$(top_srcdir)/common \
- $(GLIB_CFLAGS) $(DBUS_CFLAGS) \
- -DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
- -DGVFS_MODULE_DIR=\"$(libdir)/gvfs/modules\" \
- -DGVFS_LOCALEDIR=\""$(localedir)"\" \
- -DDBUS_API_SUBJECT_TO_CHANGE
-
-module_flags = -export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_vfs_.*|g_io_module_load|g_io_module_unload'
-
-## Common to dynamic and static client libs
-
-gvfsclientincludedir=$(includedir)/gvfs-client/gvfs/
-gvfsclientinclude_HEADERS = \
- gvfsuriutils.h gvfsurimapper.h \
- $(NULL)
-
-URI_PARSER_SOURCES = \
- smburi.c \
- httpuri.c \
- $(NULL)
-
-vfssources = \
- gdaemonvfs.c gdaemonvfs.h \
- gdaemonmount.c gdaemonmount.h \
- gdaemonvolumemonitor.c gdaemonvolumemonitor.h \
- gdaemonfile.c gdaemonfile.h \
- gdaemonfileinputstream.c gdaemonfileinputstream.h \
- gdaemonfileoutputstream.c gdaemonfileoutputstream.h \
- gdaemonfileenumerator.c gdaemonfileenumerator.h \
- gdaemonfilemonitor.c gdaemonfilemonitor.h \
- gvfsdaemondbus.c gvfsdaemondbus.h \
- gvfsuriutils.c gvfsuriutils.h \
- gvfsurimapper.c gvfsurimapper.h \
- $(URI_PARSER_SOURCES) \
- $(NULL)
-
-vfslibs = \
- $(top_builddir)/common/libgvfscommon.la \
- $(DBUS_LIBS) \
- $(GLIB_LIBS) \
- $(NULL)
-
-## Dynamic client lib
-
-giomodules_LTLIBRARIES = libgvfsdbus.la
-
-libgvfsdbus_la_LDFLAGS = $(module_flags)
-libgvfsdbus_la_SOURCES = $(vfssources)
-libgvfsdbus_la_LIBADD = $(vfslibs)
-
-noinst_PROGRAMS = test-uri-utils
-
-test_uri_utils_SOURCES = test-uri-utils.c gvfsuriutils.c gvfsuriutils.h
-test_uri_utils_LDADD = $(vfslibs)
-test_uri_utils_CFLAGS = $(INCLUDES)
-
-if USE_FUSE
-
-## FUSE daemon
-
-libexec_PROGRAMS = gvfs-fuse-daemon
-
-gvfs_fuse_daemon_SOURCES = \
- gvfsfusedaemon.c
-
-gvfs_fuse_daemon_CFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/common \
- $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(FUSE_CFLAGS) \
- -DG_LOG_DOMAIN=\"GVFS-FUSE\" -DG_DISABLE_DEPRECATED \
- -DDBUS_API_SUBJECT_TO_CHANGE
-
-gvfs_fuse_daemon_LDADD = \
- $(top_builddir)/common/libgvfscommon.la \
- $(GLIB_LIBS) $(DBUS_LIBS) $(FUSE_LIBS)
-
-endif
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
deleted file mode 100644
index 9e8eb637..00000000
--- a/client/gdaemonfile.c
+++ /dev/null
@@ -1,2805 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include "gdaemonfile.h"
-#include "gvfsdaemondbus.h"
-#include "gdaemonmount.h"
-#include <gvfsdaemonprotocol.h>
-#include <gdaemonfileinputstream.h>
-#include <gdaemonfileoutputstream.h>
-#include <gdaemonfilemonitor.h>
-#include <gdaemonfileenumerator.h>
-#include <glib/gi18n-lib.h>
-#include "gdbusutils.h"
-#include "gmountoperationdbus.h"
-#include <gio/gio.h>
-
-static void g_daemon_file_file_iface_init (GFileIface *iface);
-
-struct _GDaemonFile
-{
- GObject parent_instance;
-
- GMountSpec *mount_spec;
- char *path;
-};
-
-static void g_daemon_file_read_async (GFile *file,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer callback_data);
-
-G_DEFINE_TYPE_WITH_CODE (GDaemonFile, g_daemon_file, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
- g_daemon_file_file_iface_init))
-
-static void
-g_daemon_file_finalize (GObject *object)
-{
- GDaemonFile *daemon_file;
-
- daemon_file = G_DAEMON_FILE (object);
-
- g_mount_spec_unref (daemon_file->mount_spec);
- g_free (daemon_file->path);
-
- if (G_OBJECT_CLASS (g_daemon_file_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_file_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_file_class_init (GDaemonFileClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_daemon_file_finalize;
-}
-
-static void
-g_daemon_file_init (GDaemonFile *daemon_file)
-{
-}
-
-GFile *
-g_daemon_file_new (GMountSpec *mount_spec,
- const char *path)
-{
- GDaemonFile *daemon_file;
-
- daemon_file = g_object_new (G_TYPE_DAEMON_FILE, NULL);
- daemon_file->mount_spec = g_mount_spec_get_unique_for (mount_spec);
- daemon_file->path = g_mount_spec_canonicalize_path (path);
-
- return G_FILE (daemon_file);
-}
-
-static gboolean
-g_daemon_file_is_native (GFile *file)
-{
- return FALSE;
-}
-
-static gboolean
-g_daemon_file_has_uri_scheme (GFile *file,
- const char *uri_scheme)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- const char *scheme;
-
- scheme = _g_daemon_vfs_mountspec_get_uri_scheme (daemon_file->mount_spec);
- return g_ascii_strcasecmp (scheme, uri_scheme) == 0;
-}
-
-static char *
-g_daemon_file_get_uri_scheme (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- const char *scheme;
-
- scheme = _g_daemon_vfs_mountspec_get_uri_scheme (daemon_file->mount_spec);
-
- return g_strdup (scheme);
-}
-
-static char *
-g_daemon_file_get_basename (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- char *last_slash;
-
- /* This code relies on the path being canonicalized */
-
- last_slash = strrchr (daemon_file->path, '/');
- /* If no slash, or only "/" fallback to full path */
- if (last_slash == NULL ||
- last_slash[1] == '\0')
- return g_strdup (daemon_file->path);
-
- return g_strdup (last_slash + 1);
-}
-
-static char *
-g_daemon_file_get_path (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- GMountInfo *mount_info;
- const char *rel_path;
- char *path;
-
- /* This is a sync i/o call, which is a bit unfortunate, as
- * this is supposed to be a fast call. However, in almost all
- * cases this will be cached.
- */
-
- mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- NULL);
-
- if (mount_info == NULL)
- return NULL;
-
- path = NULL;
-
- if (mount_info->fuse_mountpoint)
- {
- rel_path = daemon_file->path +
- strlen (mount_info->mount_spec->mount_prefix);
-
- path = g_build_filename (mount_info->fuse_mountpoint, rel_path, NULL);
- }
-
- g_mount_info_unref (mount_info);
-
- return path;
-}
-
-static char *
-g_daemon_file_get_uri (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
-
- return _g_daemon_vfs_get_uri_for_mountspec (daemon_file->mount_spec,
- daemon_file->path,
- FALSE);
-}
-
-static char *
-g_daemon_file_get_parse_name (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
-
- return _g_daemon_vfs_get_uri_for_mountspec (daemon_file->mount_spec,
- daemon_file->path,
- TRUE);
-}
-
-static GFile *
-new_file_for_new_path (GDaemonFile *daemon_file,
- const char *new_path)
-{
- GFile *new_file;
- GMountSpec *new_spec;
-
- new_spec = _g_daemon_vfs_get_mount_spec_for_path (daemon_file->mount_spec,
- daemon_file->path,
- new_path);
-
- new_file = g_daemon_file_new (new_spec, new_path);
- g_mount_spec_unref (new_spec);
-
- return new_file;
-}
-
-static GFile *
-g_daemon_file_get_parent (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- const char *path;
- GFile *parent;
- const char *base;
- char *parent_path;
- gsize len;
-
- path = daemon_file->path;
- base = strrchr (path, '/');
- if (base == NULL ||
- *(base+1) == 0)
- return NULL;
-
- while (base > path && *base == '/')
- base--;
-
- len = (guint) 1 + base - path;
-
- parent_path = g_new (gchar, len + 1);
- g_memmove (parent_path, path, len);
- parent_path[len] = 0;
-
- parent = new_file_for_new_path (daemon_file, parent_path);
- g_free (parent_path);
-
- return parent;
-}
-
-static GFile *
-g_daemon_file_dup (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
-
- return g_daemon_file_new (daemon_file->mount_spec,
- daemon_file->path);
-}
-
-static guint
-g_daemon_file_hash (GFile *file)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
-
- return
- g_str_hash (daemon_file->path) ^
- GPOINTER_TO_UINT (daemon_file->mount_spec); /* We have unique mount_spec objects so hash directly on it */
-}
-
-static gboolean
-g_daemon_file_equal (GFile *file1,
- GFile *file2)
-{
- GDaemonFile *daemon_file1 = G_DAEMON_FILE (file1);
- GDaemonFile *daemon_file2 = G_DAEMON_FILE (file2);
-
- return daemon_file1->mount_spec == daemon_file2->mount_spec &&
- g_str_equal (daemon_file1->path, daemon_file2->path);
-}
-
-
-static const char *
-match_prefix (const char *path, const char *prefix)
-{
- int prefix_len;
-
- prefix_len = strlen (prefix);
- if (strncmp (path, prefix, prefix_len) != 0)
- return NULL;
-
- /* Handle the case where prefix is the root, so that
- * the IS_DIR_SEPRARATOR check below works */
- if (prefix_len > 0 &&
- prefix[prefix_len-1] == '/')
- prefix_len--;
-
-
- return path + prefix_len;
-}
-
-static gboolean
-g_daemon_file_prefix_matches (GFile *parent,
- GFile *descendant)
-{
- GDaemonFile *parent_daemon = G_DAEMON_FILE (parent);
- GDaemonFile *descendant_daemon = G_DAEMON_FILE (descendant);
- const char *remainder;
-
- if (descendant_daemon->mount_spec != parent_daemon->mount_spec)
- return FALSE;
-
- remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
- if (remainder != NULL && *remainder == '/')
- return TRUE;
- return FALSE;
-}
-
-static char *
-g_daemon_file_get_relative_path (GFile *parent,
- GFile *descendant)
-{
- GDaemonFile *parent_daemon = G_DAEMON_FILE (parent);
- GDaemonFile *descendant_daemon = G_DAEMON_FILE (descendant);
- const char *remainder;
-
- if (descendant_daemon->mount_spec != parent_daemon->mount_spec)
- return NULL;
-
- remainder = match_prefix (descendant_daemon->path, parent_daemon->path);
-
- if (remainder != NULL && *remainder == '/')
- return g_strdup (remainder + 1);
- return NULL;
-}
-
-static GFile *
-g_daemon_file_resolve_relative_path (GFile *file,
- const char *relative_path)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- char *path;
- GFile *child;
-
- if (*relative_path == '/')
- return new_file_for_new_path (daemon_file, relative_path);
-
- path = g_build_path ("/", daemon_file->path, relative_path, NULL);
- child = new_file_for_new_path (daemon_file, path);
- g_free (path);
-
- return child;
-}
-
-static DBusMessage *
-create_empty_message (GFile *file,
- const char *op,
- GMountInfo **mount_info_out,
- GError **error)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- DBusMessage *message;
- GMountInfo *mount_info;
- const char *path;
-
- mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- error);
- if (mount_info == NULL)
- return NULL;
-
- if (mount_info_out)
- *mount_info_out = g_mount_info_ref (mount_info);
-
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- op);
-
- path = g_mount_info_resolve_path (mount_info,
- daemon_file->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path, 0);
-
- g_mount_info_unref (mount_info);
- return message;
-}
-
-static DBusMessage *
-do_sync_path_call (GFile *file,
- const char *op,
- GMountInfo **mount_info_out,
- DBusConnection **connection_out,
- GCancellable *cancellable,
- GError **error,
- int first_arg_type,
- ...)
-{
- DBusMessage *message, *reply;
- va_list var_args;
- GError *my_error;
-
- retry:
-
- message = create_empty_message (file, op, mount_info_out, error);
- if (!message)
- return NULL;
-
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (message,
- first_arg_type,
- var_args);
- va_end (var_args);
-
-
- my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- connection_out,
- NULL, NULL, NULL,
- cancellable, &my_error);
- dbus_message_unref (message);
-
- if (reply == NULL)
- {
- if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
- {
- g_error_free (my_error);
- goto retry;
- }
- g_propagate_error (error, my_error);
- }
-
- return reply;
-}
-
-static DBusMessage *
-do_sync_2_path_call (GFile *file1,
- GFile *file2,
- const char *op,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- DBusConnection **connection_out,
- GCancellable *cancellable,
- GError **error,
- int first_arg_type,
- ...)
-{
- GDaemonFile *daemon_file1 = G_DAEMON_FILE (file1);
- GDaemonFile *daemon_file2 = G_DAEMON_FILE (file2);
- DBusMessage *message, *reply;
- GMountInfo *mount_info1, *mount_info2;
- const char *path1, *path2;
- va_list var_args;
- GError *my_error;
-
- retry:
-
- mount_info1 = _g_daemon_vfs_get_mount_info_sync (daemon_file1->mount_spec,
- daemon_file1->path,
- error);
- if (mount_info1 == NULL)
- return NULL;
-
- mount_info2 = NULL;
- if (daemon_file2)
- {
- mount_info2 = _g_daemon_vfs_get_mount_info_sync (daemon_file2->mount_spec,
- daemon_file2->path,
- error);
- if (mount_info2 == NULL)
- {
- g_mount_info_unref (mount_info1);
- return NULL;
- }
-
- if (mount_info1 != mount_info2)
- {
- g_mount_info_unref (mount_info1);
- /* For copy this will cause the fallback code to be involved */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Operation not supported, files on different mounts"));
- return NULL;
- }
- }
-
- message =
- dbus_message_new_method_call (mount_info1->dbus_id,
- mount_info1->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- op);
-
- path1 = g_mount_info_resolve_path (mount_info1,
- daemon_file1->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path1, 0);
-
- if (daemon_file2)
- {
- path2 = g_mount_info_resolve_path (mount_info2,
- daemon_file2->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path2, 0);
- }
-
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (message,
- first_arg_type,
- var_args);
- va_end (var_args);
-
- my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- connection_out,
- callback_obj_path,
- callback,
- callback_user_data,
- cancellable, &my_error);
- dbus_message_unref (message);
-
- g_mount_info_unref (mount_info1);
- if (mount_info2)
- g_mount_info_unref (mount_info2);
-
- if (reply == NULL)
- {
- if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
- {
- g_error_free (my_error);
- goto retry;
- }
- g_propagate_error (error, my_error);
- }
-
- return reply;
-}
-
-typedef void (*AsyncPathCallCallback) (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data);
-
-
-typedef struct {
- GSimpleAsyncResult *result;
- GFile *file;
- char *op;
- GCancellable *cancellable;
- DBusMessage *args;
- AsyncPathCallCallback callback;
- gpointer callback_data;
- GDestroyNotify notify;
-} AsyncPathCall;
-
-static void
-async_path_call_free (AsyncPathCall *data)
-{
- if (data->notify)
- data->notify (data->callback_data);
-
- if (data->result)
- g_object_unref (data->result);
- g_object_unref (data->file);
- g_free (data->op);
- if (data->cancellable)
- g_object_unref (data->cancellable);
- if (data->args)
- dbus_message_unref (data->args);
- g_free (data);
-}
-
-static void
-async_path_call_done (DBusMessage *reply,
- DBusConnection *connection,
- GError *io_error,
- gpointer _data)
-{
- AsyncPathCall *data = _data;
- GSimpleAsyncResult *result;
-
- if (io_error != NULL)
- {
- g_simple_async_result_set_from_error (data->result, io_error);
- g_simple_async_result_complete (data->result);
- async_path_call_free (data);
- }
- else
- {
- result = data->result;
- g_object_weak_ref (G_OBJECT (result), (GWeakNotify)async_path_call_free, data);
- data->result = NULL;
-
- data->callback (reply, connection,
- result,
- data->cancellable,
- data->callback_data);
-
- /* Free data here, or later if callback ref:ed the result */
- g_object_unref (result);
- }
-}
-
-static void
-do_async_path_call_callback (GMountInfo *mount_info,
- gpointer _data,
- GError *error)
-{
- AsyncPathCall *data = _data;
- GDaemonFile *daemon_file = G_DAEMON_FILE (data->file);
- const char *path;
- DBusMessage *message;
- DBusMessageIter arg_source, arg_dest;
-
- if (error != NULL)
- {
- g_simple_async_result_set_from_error (data->result, error);
- g_simple_async_result_complete (data->result);
- async_path_call_free (data);
- return;
- }
-
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- data->op);
-
- path = g_mount_info_resolve_path (mount_info, daemon_file->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path, 0);
-
- /* Append more args from data->args */
-
- if (data->args)
- {
- dbus_message_iter_init (data->args, &arg_source);
- dbus_message_iter_init_append (message, &arg_dest);
-
- _g_dbus_message_iter_copy (&arg_dest, &arg_source);
- }
-
- _g_vfs_daemon_call_async (message,
- async_path_call_done, data,
- data->cancellable);
-
- dbus_message_unref (message);
-}
-
-static void
-do_async_path_call (GFile *file,
- const char *op,
- GCancellable *cancellable,
- GAsyncReadyCallback op_callback,
- gpointer op_callback_data,
- AsyncPathCallCallback callback,
- gpointer callback_data,
- GDestroyNotify notify,
- int first_arg_type,
- ...)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- va_list var_args;
- AsyncPathCall *data;
-
- data = g_new0 (AsyncPathCall, 1);
-
- data->result = g_simple_async_result_new (G_OBJECT (file),
- op_callback, op_callback_data,
- NULL);
-
- data->file = g_object_ref (file);
- data->op = g_strdup (op);
- if (cancellable)
- data->cancellable = g_object_ref (cancellable);
- data->callback = callback;
- data->callback_data = callback_data;
- data->notify = notify;
-
- if (first_arg_type != 0)
- {
- data->args = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
- if (data->args == NULL)
- _g_dbus_oom ();
-
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (data->args,
- first_arg_type,
- var_args);
- va_end (var_args);
- }
-
-
- _g_daemon_vfs_get_mount_info_async (daemon_file->mount_spec,
- daemon_file->path,
- do_async_path_call_callback,
- data);
-}
-
-
-static GFileEnumerator *
-g_daemon_file_enumerate_children (GFile *file,
- const char *attributes,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
- dbus_uint32_t flags_dbus;
- char *obj_path;
- GDaemonFileEnumerator *enumerator;
- DBusConnection *connection;
- char *uri;
-
- enumerator = g_daemon_file_enumerator_new (file);
- obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
-
-
- uri = g_file_get_uri (file);
-
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_ENUMERATE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
- g_free (uri);
- g_free (obj_path);
-
- if (reply == NULL)
- goto error;
-
- dbus_message_unref (reply);
-
- g_daemon_file_enumerator_set_sync_connection (enumerator, connection);
-
- return G_FILE_ENUMERATOR (enumerator);
-
- error:
- if (reply)
- dbus_message_unref (reply);
- g_object_unref (enumerator);
- return NULL;
-}
-
-static GFileInfo *
-g_daemon_file_query_info (GFile *file,
- const char *attributes,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
- dbus_uint32_t flags_dbus;
- DBusMessageIter iter;
- GFileInfo *info;
- char *uri;
-
- uri = g_file_get_uri (file);
-
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_INFO,
- NULL, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
-
- g_free (uri);
-
- if (reply == NULL)
- return NULL;
-
- info = NULL;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from get_info"));
- goto out;
- }
-
- info = _g_dbus_get_file_info (&iter, error);
-
- out:
- dbus_message_unref (reply);
- return info;
-}
-
-static void
-query_info_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- DBusMessageIter iter;
- GFileInfo *info;
- GError *error;
-
- info = NULL;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from query_info"));
- g_simple_async_result_complete (result);
- return;
- }
-
- error = NULL;
- info = _g_dbus_get_file_info (&iter, &error);
- if (info == NULL)
- {
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- g_simple_async_result_complete (result);
- return;
- }
-
- g_simple_async_result_set_op_res_gpointer (result, info, g_object_unref);
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_query_info_async (GFile *file,
- const char *attributes,
- GFileQueryInfoFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint32 dbus_flags;
- char *uri;
-
- uri = g_file_get_uri (file);
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_INFO,
- cancellable,
- callback, user_data,
- query_info_async_cb, NULL, NULL,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_STRING, &uri,
- 0);
-
- g_free (uri);
-}
-
-static GFileInfo *
-g_daemon_file_query_info_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFileInfo *info;
-
- info = g_simple_async_result_get_op_res_gpointer (simple);
- if (info)
- return g_object_ref (info);
-
- return NULL;
-}
-
-typedef struct {
- GSimpleAsyncResult *result;
- gboolean can_seek;
-} GetFDData;
-
-static void
-read_async_get_fd_cb (int fd,
- gpointer callback_data)
-{
- GetFDData *data = callback_data;
- GFileInputStream *stream;
-
- if (fd == -1)
- {
- g_simple_async_result_set_error (data->result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Couldn't get stream file descriptor"));
- }
- else
- {
- stream = g_daemon_file_input_stream_new (fd, data->can_seek);
- g_simple_async_result_set_op_res_gpointer (data->result, stream, g_object_unref);
- }
-
- g_simple_async_result_complete (data->result);
-
- g_object_unref (data->result);
- g_free (data);
-}
-
-static void
-read_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- dbus_bool_t can_seek;
- GetFDData *get_fd_data;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from open"));
- g_simple_async_result_complete (result);
- return;
- }
-
- get_fd_data = g_new0 (GetFDData, 1);
- get_fd_data->result = g_object_ref (result);
- get_fd_data->can_seek = can_seek;
-
- _g_dbus_connection_get_fd_async (connection, fd_id,
- read_async_get_fd_cb, get_fd_data);
-}
-
-static void
-g_daemon_file_read_async (GFile *file,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer callback_data)
-{
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ,
- cancellable,
- callback, callback_data,
- read_async_cb, NULL, NULL,
- 0);
-}
-
-static GFileInputStream *
-g_daemon_file_read_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- gpointer op;
-
- op = g_simple_async_result_get_op_res_gpointer (simple);
- if (op)
- return g_object_ref (op);
-
- return NULL;
-}
-
-
-static GFileInputStream *
-g_daemon_file_read (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ,
- NULL, &connection,
- cancellable, error,
- 0);
- if (reply == NULL)
- return NULL;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from open"));
- return NULL;
- }
-
- dbus_message_unref (reply);
-
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_input_stream_new (fd, can_seek);
-}
-
-static GFileOutputStream *
-g_daemon_file_append_to (GFile *file,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t make_backup;
- guint32 dbus_flags;
- char *etag;
-
- mode = 1;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
- if (reply == NULL)
- return NULL;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from open"));
- return NULL;
- }
-
- dbus_message_unref (reply);
-
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
-}
-
-static GFileOutputStream *
-g_daemon_file_create (GFile *file,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t make_backup;
- char *etag;
- guint32 dbus_flags;
-
- mode = 0;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
- if (reply == NULL)
- return NULL;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from open"));
- return NULL;
- }
-
- dbus_message_unref (reply);
-
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
-}
-
-static GFileOutputStream *
-g_daemon_file_replace (GFile *file,
- const char *etag,
- gboolean make_backup,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t dbus_make_backup;
- guint32 dbus_flags;
-
- mode = 2;
- dbus_make_backup = make_backup;
- dbus_flags = flags;
-
- if (etag == NULL)
- etag = "";
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &dbus_make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
- if (reply == NULL)
- return NULL;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from open"));
- return NULL;
- }
-
- dbus_message_unref (reply);
-
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
-}
-
-static void
-mount_mountable_location_mounted_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GSimpleAsyncResult *result = user_data;
- GError *error = NULL;
-
- if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error))
- {
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- }
-
- g_simple_async_result_complete (result);
- g_object_unref (result);
-
-}
-
-static void
-mount_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- GMountOperation *mount_operation = callback_data;
- GMountSpec *mount_spec;
- char *path;
- DBusMessageIter iter;
- GFile *file;
- dbus_bool_t must_mount_location, is_uri;
-
- path = NULL;
-
- dbus_message_iter_init (reply, &iter);
-
- if (!_g_dbus_message_iter_get_args (&iter, NULL,
- DBUS_TYPE_BOOLEAN, &is_uri,
- G_DBUS_TYPE_CSTRING, &path,
- DBUS_TYPE_BOOLEAN, &must_mount_location,
- 0))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from call"));
- g_simple_async_result_complete (result);
-
- return;
- }
-
- if (is_uri)
- {
- file = g_file_new_for_uri (path);
- }
- else
- {
- mount_spec = g_mount_spec_from_dbus (&iter);
- if (mount_spec == NULL)
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from call"));
- g_simple_async_result_complete (result);
- return;
- }
-
- file = g_daemon_file_new (mount_spec, path);
- g_mount_spec_unref (mount_spec);
- }
-
- g_free (path);
- g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref);
-
- if (must_mount_location)
- {
- g_file_mount_enclosing_volume (file,
- 0,
- mount_operation,
- cancellable,
- mount_mountable_location_mounted_cb,
- g_object_ref (result));
-
- }
- else
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_mount_mountable (GFile *file,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GMountSource *mount_source;
- const char *dbus_id, *obj_path;
-
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
-
- dbus_id = g_mount_source_get_dbus_id (mount_source);
- obj_path = g_mount_source_get_obj_path (mount_source);
-
- if (mount_operation)
- g_object_ref (mount_operation);
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MOUNT_MOUNTABLE,
- cancellable,
- callback, user_data,
- mount_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_STRING, &dbus_id,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
-
- g_object_unref (mount_source);
-}
-
-static GFile *
-g_daemon_file_mount_mountable_finish (GFile *file,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- GFile *result_file;
-
- result_file = g_simple_async_result_get_op_res_gpointer (simple);
- if (result_file)
- return g_object_ref (result_file);
-
- return NULL;
-}
-
-static void
-eject_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_eject_mountable (GFile *file,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint32 dbus_flags;
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_EJECT_MOUNTABLE,
- cancellable,
- callback, user_data,
- eject_mountable_async_cb,
- NULL, NULL,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-}
-
-static gboolean
-g_daemon_file_eject_mountable_finish (GFile *file,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
-
-static void
-unmount_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_unmount_mountable (GFile *file,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint32 dbus_flags;
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_UNMOUNT_MOUNTABLE,
- cancellable,
- callback, user_data,
- unmount_mountable_async_cb,
- NULL, NULL,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-}
-
-static gboolean
-g_daemon_file_unmount_mountable_finish (GFile *file,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
-
-
-typedef struct {
- GFile *file;
- GMountOperation *mount_operation;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} MountData;
-
-static void g_daemon_file_mount_enclosing_volume (GFile *location,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-static void
-mount_reply (DBusMessage *reply,
- GError *error,
- gpointer user_data)
-{
- MountData *data = user_data;
- GSimpleAsyncResult *res;
-
- if (reply == NULL)
- {
- res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
- data->callback,
- data->user_data,
- error);
- }
- else
- {
- res = g_simple_async_result_new (G_OBJECT (data->file),
- data->callback,
- data->user_data,
- g_daemon_file_mount_enclosing_volume);
- }
-
- g_simple_async_result_complete (res);
-
- g_object_unref (data->file);
- if (data->mount_operation)
- g_object_unref (data->mount_operation);
- g_free (data);
-}
-
-static void
-g_daemon_file_mount_enclosing_volume (GFile *location,
- GMountMountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonFile *daemon_file;
- DBusMessage *message;
- GMountSpec *spec;
- GMountSource *mount_source;
- DBusMessageIter iter;
- MountData *data;
-
- daemon_file = G_DAEMON_FILE (location);
-
- message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_MOUNT_LOCATION);
-
- spec = g_mount_spec_copy (daemon_file->mount_spec);
- g_mount_spec_set_mount_prefix (spec, daemon_file->path);
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus (&iter, spec);
- g_mount_spec_unref (spec);
-
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
- g_mount_source_to_dbus (mount_source, message);
- g_object_unref (mount_source);
-
- data = g_new0 (MountData, 1);
- data->callback = callback;
- data->user_data = user_data;
- data->file = g_object_ref (location);
- if (mount_operation)
- data->mount_operation = g_object_ref (mount_operation);
-
- /* TODO: Ignoring cancellable here */
- _g_dbus_connection_call_async (_g_daemon_vfs_get_async_bus (),
- message,
- G_VFS_DBUS_MOUNT_TIMEOUT_MSECS,
- mount_reply, data);
-
- dbus_message_unref (message);
-}
-
-static gboolean
-g_daemon_file_mount_enclosing_volume_finish (GFile *location,
- GAsyncResult *result,
- GError **error)
-{
- /* Errors handled in generic code */
- return TRUE;
-}
-
-static GFileInfo *
-g_daemon_file_query_filesystem_info (GFile *file,
- const char *attributes,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
- DBusMessageIter iter;
- GFileInfo *info;
-
- if (attributes == NULL)
- attributes = "";
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_FILESYSTEM_INFO,
- NULL, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &attributes,
- 0);
- if (reply == NULL)
- return NULL;
-
- info = NULL;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from get_filesystem_info"));
- goto out;
- }
-
- info = _g_dbus_get_file_info (&iter, error);
-
- out:
- dbus_message_unref (reply);
- return info;
-}
-
-static void
-query_fs_info_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- DBusMessageIter iter;
- GFileInfo *info;
- GError *error;
-
- info = NULL;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from query_info"));
- g_simple_async_result_complete (result);
- return;
- }
-
- error = NULL;
- info = _g_dbus_get_file_info (&iter, &error);
- if (info == NULL)
- {
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- g_simple_async_result_complete (result);
- return;
- }
-
- g_simple_async_result_set_op_res_gpointer (result, info, g_object_unref);
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_query_filesystem_info_async (GFile *file,
- const char *attributes,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_FILESYSTEM_INFO,
- cancellable,
- callback, user_data,
- query_fs_info_async_cb, NULL, NULL,
- DBUS_TYPE_STRING, &attributes,
- 0);
-}
-
-static GFileInfo *
-g_daemon_file_query_filesystem_info_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFileInfo *info;
-
- info = g_simple_async_result_get_op_res_gpointer (simple);
- if (info)
- return g_object_ref (info);
-
- return NULL;
-}
-
-static GMount *
-g_daemon_file_find_enclosing_mount (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- GMountInfo *mount_info;
- GDaemonMount *mount;
-
- mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- error);
- if (mount_info == NULL)
- return NULL;
-
- if (mount_info->user_visible)
- {
- /* if we have a daemon volume monitor then return one of it's mounts */
- mount = g_daemon_volume_monitor_find_mount_by_mount_info (mount_info);
- if (mount == NULL)
- {
- mount = g_daemon_mount_new (mount_info, NULL);
- }
- g_mount_info_unref (mount_info);
-
- if (mount)
- return G_MOUNT (mount);
- }
-
- g_set_error_literal (error, G_IO_ERROR,
- G_IO_ERROR_NOT_FOUND,
- /* translators: this is an error message when there is no user visible "mount" object
- corresponding to a particular path/uri */
- _("Could not find enclosing mount"));
- return NULL;
-}
-
-static GFile *
-g_daemon_file_get_child_for_display_name (GFile *file,
- const char *display_name,
- GError **error)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- GMountInfo *mount_info;
- char *basename;
- GFile *child;
-
- mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- NULL);
-
-
- if (mount_info && mount_info->prefered_filename_encoding)
- {
- basename = g_convert (display_name, -1,
- mount_info->prefered_filename_encoding,
- "UTF-8",
- NULL, NULL,
- NULL);
- if (basename == NULL)
- {
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_INVALID_FILENAME,
- _("Invalid filename %s"), display_name);
- return NULL;
- }
-
- child = g_file_get_child (file, basename);
- g_free (basename);
- }
- else
- child = g_file_get_child (file, display_name);
-
- return child;
-}
-
-static GFile *
-g_daemon_file_set_display_name (GFile *file,
- const char *display_name,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFile *daemon_file;
- DBusMessage *reply;
- DBusMessageIter iter;
- char *new_path;
-
- daemon_file = G_DAEMON_FILE (file);
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_SET_DISPLAY_NAME,
- NULL, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &display_name,
- 0);
- if (reply == NULL)
- return NULL;
-
-
- if (!dbus_message_iter_init (reply, &iter) ||
- !_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &new_path,
- 0))
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from query_filesystem_info"));
- goto out;
- }
-
- file = new_file_for_new_path (daemon_file, new_path);
- g_free (new_path);
-
- out:
- dbus_message_unref (reply);
- return file;
-}
-
-static gboolean
-g_daemon_file_delete (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_DELETE,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-static gboolean
-g_daemon_file_trash (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_TRASH,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-static gboolean
-g_daemon_file_make_directory (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MAKE_DIRECTORY,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-static gboolean
-g_daemon_file_make_symbolic_link (GFile *file,
- const char *symlink_value,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MAKE_SYMBOLIC_LINK,
- NULL, NULL,
- cancellable, error,
- G_DBUS_TYPE_CSTRING, &symlink_value,
- 0);
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-static GFileAttributeInfoList *
-g_daemon_file_query_settable_attributes (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
- GFileAttributeInfoList *list;
- DBusMessageIter iter;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_SETTABLE_ATTRIBUTES,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init (reply, &iter);
- list = _g_dbus_get_attribute_info_list (&iter, error);
-
- dbus_message_unref (reply);
-
- return list;
-}
-
-static GFileAttributeInfoList *
-g_daemon_file_query_writable_namespaces (GFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *reply;
- GFileAttributeInfoList *list;
- DBusMessageIter iter;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_WRITABLE_NAMESPACES,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init (reply, &iter);
- list = _g_dbus_get_attribute_info_list (&iter, error);
-
- dbus_message_unref (reply);
-
- return list;
-
-}
-
-static gboolean
-g_daemon_file_set_attribute (GFile *file,
- const char *attribute,
- GFileAttributeType type,
- gpointer value_p,
- GFileQueryInfoFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusMessage *message, *reply;
- DBusMessageIter iter;
- dbus_uint32_t flags_dbus;
- GError *my_error;
-
- retry:
-
- message = create_empty_message (file, G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE, NULL, error);
- if (!message)
- return FALSE;
-
- dbus_message_iter_init_append (message, &iter);
-
- flags_dbus = flags;
- dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_UINT32,
- &flags_dbus);
-
- _g_dbus_append_file_attribute (&iter, attribute, type, value_p);
-
- my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- NULL,
- NULL, NULL, NULL,
- cancellable, &my_error);
-
- dbus_message_unref (message);
-
- if (reply == NULL)
- {
- if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
- {
- g_error_free (my_error);
- goto retry;
- }
- g_propagate_error (error, my_error);
- return FALSE;
- }
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-struct ProgressCallbackData {
- GFileProgressCallback progress_callback;
- gpointer progress_callback_data;
-};
-
-static DBusHandlerResult
-progress_callback_message (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- struct ProgressCallbackData *data = user_data;
- dbus_uint64_t current_dbus, total_dbus;
-
- if (dbus_message_is_method_call (message,
- G_VFS_DBUS_PROGRESS_INTERFACE,
- G_VFS_DBUS_PROGRESS_OP_PROGRESS))
- {
- if (dbus_message_get_args (message, NULL,
- DBUS_TYPE_UINT64, &current_dbus,
- DBUS_TYPE_UINT64, &total_dbus,
- 0))
- data->progress_callback (current_dbus, total_dbus, data->progress_callback_data);
- }
- else
- g_warning ("Unknown progress callback message type\n");
-
- /* TODO: demarshal args and call reall callback */
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static gboolean
-file_transfer (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- gboolean remove_source,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
-{
- DBusMessage *reply;
- char *obj_path, *dbus_obj_path;
- dbus_uint32_t flags_dbus;
- dbus_bool_t dbus_remove_source;
- struct ProgressCallbackData data;
- char *local_path = NULL;
- gboolean source_is_daemon;
- gboolean dest_is_daemon;
- gboolean native_transfer;
-
- native_transfer = FALSE;
- source_is_daemon = G_IS_DAEMON_FILE (source);
- dest_is_daemon = G_IS_DAEMON_FILE (destination);
-
- if (source_is_daemon && dest_is_daemon)
- native_transfer = TRUE;
- else if (dest_is_daemon && !source_is_daemon)
- local_path = g_file_get_path (source);
- else if (source_is_daemon && !dest_is_daemon)
- local_path = g_file_get_path (destination);
- else
- {
- /* Fall back to default copy/move */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Operation not supported");
- return FALSE;
- }
-
- if (!native_transfer && local_path == NULL)
- {
- /* This will cause the fallback code to be involved */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Operation not supported, files on different mounts"));
- return FALSE;
-
- }
-
- if (progress_callback)
- {
- obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path);
- dbus_obj_path = obj_path;
- }
- else
- {
- obj_path = NULL;
- /* Can't pass NULL obj path as arg */
- dbus_obj_path = "/org/gtk/vfs/void";
- }
-
- data.progress_callback = progress_callback;
- data.progress_callback_data = progress_callback_data;
-
- flags_dbus = flags;
- dbus_remove_source = remove_source;
-
- if (native_transfer == TRUE)
- {
- const char *method_string;
-
- if (remove_source == FALSE)
- method_string = G_VFS_DBUS_MOUNT_OP_COPY;
- else
- method_string = G_VFS_DBUS_MOUNT_OP_MOVE;
-
- reply = do_sync_2_path_call (source, destination,
- method_string,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- 0);
- }
- else if (dest_is_daemon == TRUE)
- {
- reply = do_sync_2_path_call (destination, NULL,
- G_VFS_DBUS_MOUNT_OP_PUSH,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- G_DBUS_TYPE_CSTRING, &local_path,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- DBUS_TYPE_BOOLEAN, &dbus_remove_source,
- 0);
- }
- else
- {
- reply = do_sync_2_path_call (source, NULL,
- G_VFS_DBUS_MOUNT_OP_PULL,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- G_DBUS_TYPE_CSTRING, &local_path,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- DBUS_TYPE_BOOLEAN, &dbus_remove_source,
- 0);
-
- }
-
- g_free (local_path);
- g_free (obj_path);
-
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
-}
-
-static gboolean
-g_daemon_file_copy (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
-{
- gboolean result;
-
- result = file_transfer (source,
- destination,
- flags,
- FALSE,
- cancellable,
- progress_callback,
- progress_callback_data,
- error);
-
- return result;
-}
-
-static gboolean
-g_daemon_file_move (GFile *source,
- GFile *destination,
- GFileCopyFlags flags,
- GCancellable *cancellable,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GError **error)
-{
- gboolean result;
-
- result = file_transfer (source,
- destination,
- flags,
- TRUE,
- cancellable,
- progress_callback,
- progress_callback_data,
- error);
-
- return result;
-}
-
-static GFileMonitor*
-g_daemon_file_monitor_dir (GFile* file,
- GFileMonitorFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- GFileMonitor *monitor;
- char *obj_path;
- dbus_uint32_t flags_dbus;
- GMountInfo *mount_info;
- DBusMessage *reply;
-
- flags_dbus = flags;
-
- mount_info = NULL;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_CREATE_DIR_MONITOR,
- &mount_info, NULL,
- cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- 0);
-
- if (reply == NULL)
- {
- if (mount_info)
- g_mount_info_unref (mount_info);
- return NULL;
- }
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_INVALID))
- {
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from monitor_dir"));
- return NULL;
- }
-
- monitor = g_daemon_file_monitor_new (mount_info->dbus_id,
- obj_path);
-
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
-
- return monitor;
-}
-
-static GFileMonitor*
-g_daemon_file_monitor_file (GFile* file,
- GFileMonitorFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- GFileMonitor *monitor;
- char *obj_path;
- dbus_uint32_t flags_dbus;
- GMountInfo *mount_info;
- DBusMessage *reply;
-
- flags_dbus = flags;
-
- mount_info = NULL;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_CREATE_FILE_MONITOR,
- &mount_info, NULL,
- cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- 0);
-
- if (reply == NULL)
- {
- if (mount_info)
- g_mount_info_unref (mount_info);
- return NULL;
- }
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_INVALID))
- {
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from monitor_file"));
- return NULL;
- }
-
- monitor = g_daemon_file_monitor_new (mount_info->dbus_id,
- obj_path);
-
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
-
- return monitor;
-}
-
-typedef struct
-{
- GSimpleAsyncResult *result;
- dbus_bool_t can_seek;
- guint64 initial_offset;
-}
-StreamOpenParams;
-
-static void
-stream_open_cb (gint fd, StreamOpenParams *params)
-{
- GFileOutputStream *output_stream;
-
- if (fd == -1)
- {
- g_simple_async_result_set_error (params->result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", _("Didn't get stream file descriptor"));
- goto out;
- }
-
- output_stream = g_daemon_file_output_stream_new (fd, params->can_seek, params->initial_offset);
- g_simple_async_result_set_op_res_gpointer (params->result, output_stream, g_object_unref);
-
-out:
- g_simple_async_result_complete (params->result);
- g_object_unref (params->result);
- g_slice_free (StreamOpenParams, params);
-}
-
-static void
-append_to_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- StreamOpenParams *open_params;
-
- open_params = g_slice_new0 (StreamOpenParams);
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", _("Invalid return value from open"));
- goto failure;
- }
-
- open_params->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
-
-failure:
- g_slice_free (StreamOpenParams, open_params);
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_append_to_async (GFile *file,
- GFileCreateFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint16 mode;
- dbus_bool_t make_backup;
- guint32 dbus_flags;
- char *etag;
-
- mode = 1;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- append_to_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-}
-
-static GFileOutputStream *
-g_daemon_file_append_to_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFileOutputStream *output_stream;
-
- output_stream = g_simple_async_result_get_op_res_gpointer (simple);
- if (output_stream)
- return g_object_ref (output_stream);
-
- return NULL;
-}
-
-static void
-create_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- StreamOpenParams *open_params;
-
- open_params = g_slice_new0 (StreamOpenParams);
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", _("Invalid return value from open"));
- goto failure;
- }
-
- open_params->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
-
-failure:
- g_slice_free (StreamOpenParams, open_params);
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_create_async (GFile *file,
- GFileCreateFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint16 mode;
- dbus_bool_t make_backup;
- char *etag;
- guint32 dbus_flags;
-
- mode = 0;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- create_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-}
-
-static GFileOutputStream *
-g_daemon_file_create_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFileOutputStream *output_stream;
-
- output_stream = g_simple_async_result_get_op_res_gpointer (simple);
- if (output_stream)
- return g_object_ref (output_stream);
-
- return NULL;
-}
-
-static void
-enumerate_children_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- GDaemonFileEnumerator *enumerator = callback_data;
-
- if (reply == NULL || connection == NULL)
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid return value from enumerate_children");
- goto out;
- }
-
- g_object_ref (enumerator);
-
- g_simple_async_result_set_op_res_gpointer (result, enumerator, g_object_unref);
-
-out:
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_enumerate_children_async (GFile *file,
- const char *attributes,
- GFileQueryInfoFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- dbus_uint32_t flags_dbus;
- char *obj_path;
- GDaemonFileEnumerator *enumerator;
- char *uri;
-
- enumerator = g_daemon_file_enumerator_new (file);
- obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
-
- uri = g_file_get_uri (file);
-
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_ENUMERATE,
- cancellable,
- callback, user_data,
- enumerate_children_async_cb, enumerator, g_object_unref,
- DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
- g_free (uri);
- g_free (obj_path);
-}
-
-static GFileEnumerator *
-g_daemon_file_enumerate_children_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GDaemonFileEnumerator *enumerator;
-
- enumerator = g_simple_async_result_get_op_res_gpointer (simple);
- if (enumerator)
- return g_object_ref (enumerator);
-
- return NULL;
-}
-
-typedef struct
-{
- GFile *file;
- GSimpleAsyncResult *result;
- GCancellable *cancellable;
-}
-FindEnclosingMountData;
-
-static void
-find_enclosing_mount_cb (GMountInfo *mount_info,
- gpointer user_data,
- GError *error)
-{
- FindEnclosingMountData *data = user_data;
- GError *my_error = NULL;
-
- if (data->cancellable && g_cancellable_set_error_if_cancelled (data->cancellable, &my_error))
- {
- g_simple_async_result_set_from_error (data->result, my_error);
- goto out;
- }
-
- if (error)
- {
- g_simple_async_result_set_from_error (data->result, error);
- goto out;
- }
-
- if (!mount_info)
- {
- g_simple_async_result_set_error (data->result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Internal error: \"%s\"",
- "No error but no mount info from g_daemon_vfs_get_mount_info_async");
- goto out;
- }
-
- if (mount_info->user_visible)
- {
- GDaemonMount *mount;
-
- /* if we have a daemon volume monitor then return one of it's mounts */
- mount = g_daemon_volume_monitor_find_mount_by_mount_info (mount_info);
- if (mount == NULL)
- mount = g_daemon_mount_new (mount_info, NULL);
-
- if (mount)
- g_simple_async_result_set_op_res_gpointer (data->result, mount, g_object_unref);
- else
- g_simple_async_result_set_error (data->result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Internal error: \"%s\"",
- "Mount info did not yield a mount");
- }
-
-out:
- g_simple_async_result_complete (data->result);
-
- if (my_error)
- g_error_free (my_error);
- if (data->cancellable)
- g_object_unref (data->cancellable);
- g_object_unref (data->file);
- g_object_unref (data->result);
- g_free (data);
-}
-
-static void
-g_daemon_file_find_enclosing_mount_async (GFile *file,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- FindEnclosingMountData *data;
-
- data = g_new0 (FindEnclosingMountData, 1);
-
- data->result = g_simple_async_result_new (G_OBJECT (file),
- callback, user_data,
- NULL);
- data->file = g_object_ref (file);
-
- if (cancellable)
- data->cancellable = g_object_ref (cancellable);
-
- _g_daemon_vfs_get_mount_info_async (daemon_file->mount_spec,
- daemon_file->path,
- find_enclosing_mount_cb,
- data);
-}
-
-static GMount *
-g_daemon_file_find_enclosing_mount_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GMount *mount;
-
- mount = g_simple_async_result_get_op_res_gpointer (simple);
- if (mount)
- return g_object_ref (mount);
-
- return NULL;
-}
-
-static void
-replace_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- StreamOpenParams *open_params;
-
- open_params = g_slice_new0 (StreamOpenParams);
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", _("Invalid return value from open"));
- goto failure;
- }
-
- open_params->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
-
-failure:
- g_slice_free (StreamOpenParams, open_params);
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_replace_async (GFile *file,
- const char *etag,
- gboolean make_backup,
- GFileCreateFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- dbus_bool_t dbus_make_backup = make_backup;
- guint32 dbus_flags = flags;
- guint16 mode = 2;
-
- if (etag == NULL)
- etag = "";
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- replace_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &dbus_make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-}
-
-static GFileOutputStream *
-g_daemon_file_replace_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFileOutputStream *output_stream;
-
- output_stream = g_simple_async_result_get_op_res_gpointer (simple);
- if (output_stream)
- return g_object_ref (output_stream);
-
- return NULL;
-}
-
-static void
-set_display_name_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- GDaemonFile *daemon_file = callback_data;
- GFile *file;
- DBusMessageIter iter;
- gchar *new_path;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- !_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &new_path,
- 0))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", "Invalid return value from set_display_name");
- goto out;
- }
-
- file = new_file_for_new_path (daemon_file, new_path);
- g_free (new_path);
-
- g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref);
-
-out:
- g_simple_async_result_complete (result);
-}
-
-static void
-g_daemon_file_set_display_name_async (GFile *file,
- const char *display_name,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_object_ref (file);
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_SET_DISPLAY_NAME,
- cancellable,
- callback, user_data,
- set_display_name_async_cb, file, g_object_unref,
- DBUS_TYPE_STRING, &display_name,
- 0);
-}
-
-static GFile *
-g_daemon_file_set_display_name_finish (GFile *file,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
- GFile *new_file;
-
- new_file = g_simple_async_result_get_op_res_gpointer (simple);
- return new_file;
-}
-
-#if 0
-
-static void
-g_daemon_file_set_attributes_async (GFile *file,
- GFileInfo *info,
- GFileQueryInfoFlags flags,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- /* TODO */
-}
-
-static gboolean
-g_daemon_file_set_attributes_finish (GFile *file,
- GAsyncResult *result,
- GFileInfo **info,
- GError **error)
-{
- /* TODO */
-}
-
-#endif
-
-static void
-g_daemon_file_file_iface_init (GFileIface *iface)
-{
- iface->dup = g_daemon_file_dup;
- iface->hash = g_daemon_file_hash;
- iface->equal = g_daemon_file_equal;
- iface->is_native = g_daemon_file_is_native;
- iface->has_uri_scheme = g_daemon_file_has_uri_scheme;
- iface->get_uri_scheme = g_daemon_file_get_uri_scheme;
- iface->get_basename = g_daemon_file_get_basename;
- iface->get_path = g_daemon_file_get_path;
- iface->get_uri = g_daemon_file_get_uri;
- iface->get_parse_name = g_daemon_file_get_parse_name;
- iface->get_parent = g_daemon_file_get_parent;
- iface->prefix_matches = g_daemon_file_prefix_matches;
- iface->get_relative_path = g_daemon_file_get_relative_path;
- iface->resolve_relative_path = g_daemon_file_resolve_relative_path;
- iface->get_child_for_display_name = g_daemon_file_get_child_for_display_name;
- iface->enumerate_children = g_daemon_file_enumerate_children;
- iface->query_info = g_daemon_file_query_info;
- iface->query_info_async = g_daemon_file_query_info_async;
- iface->query_info_finish = g_daemon_file_query_info_finish;
- iface->find_enclosing_mount = g_daemon_file_find_enclosing_mount;
- iface->read_fn = g_daemon_file_read;
- iface->append_to = g_daemon_file_append_to;
- iface->create = g_daemon_file_create;
- iface->replace = g_daemon_file_replace;
- iface->read_async = g_daemon_file_read_async;
- iface->read_finish = g_daemon_file_read_finish;
- iface->mount_enclosing_volume = g_daemon_file_mount_enclosing_volume;
- iface->mount_enclosing_volume_finish = g_daemon_file_mount_enclosing_volume_finish;
- iface->mount_mountable = g_daemon_file_mount_mountable;
- iface->mount_mountable_finish = g_daemon_file_mount_mountable_finish;
- iface->unmount_mountable = g_daemon_file_unmount_mountable;
- iface->unmount_mountable_finish = g_daemon_file_unmount_mountable_finish;
- iface->eject_mountable = g_daemon_file_eject_mountable;
- iface->eject_mountable_finish = g_daemon_file_eject_mountable_finish;
- iface->query_filesystem_info = g_daemon_file_query_filesystem_info;
- iface->query_filesystem_info_async = g_daemon_file_query_filesystem_info_async;
- iface->query_filesystem_info_finish = g_daemon_file_query_filesystem_info_finish;
- iface->set_display_name = g_daemon_file_set_display_name;
- iface->delete_file = g_daemon_file_delete;
- iface->trash = g_daemon_file_trash;
- iface->make_directory = g_daemon_file_make_directory;
- iface->copy = g_daemon_file_copy;
- iface->move = g_daemon_file_move;
- iface->query_settable_attributes = g_daemon_file_query_settable_attributes;
- iface->query_writable_namespaces = g_daemon_file_query_writable_namespaces;
- iface->set_attribute = g_daemon_file_set_attribute;
- iface->make_symbolic_link = g_daemon_file_make_symbolic_link;
- iface->monitor_dir = g_daemon_file_monitor_dir;
- iface->monitor_file = g_daemon_file_monitor_file;
-
- /* Async operations */
-
- iface->append_to_async = g_daemon_file_append_to_async;
- iface->append_to_finish = g_daemon_file_append_to_finish;
- iface->create_async = g_daemon_file_create_async;
- iface->create_finish = g_daemon_file_create_finish;
- iface->enumerate_children_async = g_daemon_file_enumerate_children_async;
- iface->enumerate_children_finish = g_daemon_file_enumerate_children_finish;
- iface->find_enclosing_mount_async = g_daemon_file_find_enclosing_mount_async;
- iface->find_enclosing_mount_finish = g_daemon_file_find_enclosing_mount_finish;
- iface->replace_async = g_daemon_file_replace_async;
- iface->replace_finish = g_daemon_file_replace_finish;
- iface->set_display_name_async = g_daemon_file_set_display_name_async;
- iface->set_display_name_finish = g_daemon_file_set_display_name_finish;
-#if 0
- iface->set_attributes_async = g_daemon_file_set_attributes_async;
- iface->set_attributes_finish = g_daemon_file_set_attributes_finish;
-#endif
-}
diff --git a/client/gdaemonfile.h b/client/gdaemonfile.h
deleted file mode 100644
index 297066a9..00000000
--- a/client/gdaemonfile.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_FILE_H__
-#define __G_DAEMON_FILE_H__
-
-#include <gio/gio.h>
-#include "gdaemonvfs.h"
-#include "gmountspec.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_FILE (g_daemon_file_get_type ())
-#define G_DAEMON_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_FILE, GDaemonFile))
-#define G_DAEMON_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_FILE, GDaemonFileClass))
-#define G_IS_DAEMON_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_FILE))
-#define G_IS_DAEMON_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_FILE))
-#define G_DAEMON_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DAEMON_FILE, GDaemonFileClass))
-
-typedef struct _GDaemonFile GDaemonFile;
-typedef struct _GDaemonFileClass GDaemonFileClass;
-
-struct _GDaemonFileClass
-{
- GObjectClass parent_class;
-};
-
-GType g_daemon_file_get_type (void) G_GNUC_CONST;
-
-GFile * g_daemon_file_new (GMountSpec *mount_spec,
- const char *path);
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_FILE_H__ */
diff --git a/client/gdaemonfileenumerator.c b/client/gdaemonfileenumerator.c
deleted file mode 100644
index 56b1488d..00000000
--- a/client/gdaemonfileenumerator.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gdaemonfileenumerator.h>
-#include <gio/gio.h>
-#include <gvfsdaemondbus.h>
-#include <gvfsdaemonprotocol.h>
-
-#define OBJ_PATH_PREFIX "/org/gtk/vfs/client/enumerator/"
-
-/* atomic */
-static volatile gint path_counter = 1;
-
-G_LOCK_DEFINE_STATIC(infos);
-
-struct _GDaemonFileEnumerator
-{
- GFileEnumerator parent;
-
- gint id;
- DBusConnection *sync_connection; /* NULL if async, i.e. we're listening on main dbus connection */
-
- /* protected by infos lock */
- GList *infos;
- gboolean done;
-
- /* For async ops, also protected by infos lock */
- int async_requested_files;
- GCancellable *async_cancel;
- gulong cancelled_tag;
- guint timeout_tag;
- GSimpleAsyncResult *async_res;
-};
-
-G_DEFINE_TYPE (GDaemonFileEnumerator, g_daemon_file_enumerator, G_TYPE_FILE_ENUMERATOR)
-
-static GFileInfo * g_daemon_file_enumerator_next_file (GFileEnumerator *enumerator,
- GCancellable *cancellable,
- GError **error);
-static void g_daemon_file_enumerator_next_files_async (GFileEnumerator *enumerator,
- int num_files,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-static GList * g_daemon_file_enumerator_next_files_finish (GFileEnumerator *enumerator,
- GAsyncResult *result,
- GError **error);
-static gboolean g_daemon_file_enumerator_close (GFileEnumerator *enumerator,
- GCancellable *cancellable,
- GError **error);
-static void g_daemon_file_enumerator_close_async (GFileEnumerator *enumerator,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-static gboolean g_daemon_file_enumerator_close_finish (GFileEnumerator *enumerator,
- GAsyncResult *result,
- GError **error);
-static DBusHandlerResult g_daemon_file_enumerator_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
-
-static void
-free_info_list (GList *infos)
-{
- g_list_foreach (infos, (GFunc)g_object_unref, NULL);
- g_list_free (infos);
-}
-
-static void
-g_daemon_file_enumerator_finalize (GObject *object)
-{
- GDaemonFileEnumerator *daemon;
- char *path;
-
- daemon = G_DAEMON_FILE_ENUMERATOR (object);
-
- path = g_daemon_file_enumerator_get_object_path (daemon);
- _g_dbus_unregister_vfs_filter (path);
- g_free (path);
-
- free_info_list (daemon->infos);
-
- if (daemon->sync_connection)
- dbus_connection_unref (daemon->sync_connection);
-
- if (G_OBJECT_CLASS (g_daemon_file_enumerator_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_file_enumerator_parent_class)->finalize) (object);
-}
-
-
-static void
-g_daemon_file_enumerator_class_init (GDaemonFileEnumeratorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass);
-
- gobject_class->finalize = g_daemon_file_enumerator_finalize;
-
- enumerator_class->next_file = g_daemon_file_enumerator_next_file;
- enumerator_class->next_files_async = g_daemon_file_enumerator_next_files_async;
- enumerator_class->next_files_finish = g_daemon_file_enumerator_next_files_finish;
- enumerator_class->close_fn = g_daemon_file_enumerator_close;
- enumerator_class->close_async = g_daemon_file_enumerator_close_async;
- enumerator_class->close_finish = g_daemon_file_enumerator_close_finish;
-}
-
-static void
-g_daemon_file_enumerator_init (GDaemonFileEnumerator *daemon)
-{
- char *path;
-
- daemon->id = g_atomic_int_exchange_and_add (&path_counter, 1);
-
- path = g_daemon_file_enumerator_get_object_path (daemon);
- _g_dbus_register_vfs_filter (path, g_daemon_file_enumerator_dbus_filter,
- G_OBJECT (daemon));
- g_free (path);
-}
-
-GDaemonFileEnumerator *
-g_daemon_file_enumerator_new (GFile *file)
-{
- GDaemonFileEnumerator *daemon;
-
- daemon = g_object_new (G_TYPE_DAEMON_FILE_ENUMERATOR,
- "container", file,
- NULL);
-
- return daemon;
-}
-
-/* Called with infos lock held */
-static void
-trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok)
-{
- GList *rest, *l;
-
- if (ok)
- {
- l = daemon->infos;
- rest = g_list_nth (l, daemon->async_requested_files);
- if (rest)
- {
- /* Split list */
- rest->prev->next = NULL;
- rest->prev = NULL;
- }
- daemon->infos = rest;
-
- g_simple_async_result_set_op_res_gpointer (daemon->async_res,
- l,
- (GDestroyNotify)free_info_list);
- }
-
- g_simple_async_result_complete_in_idle (daemon->async_res);
-
- if (daemon->cancelled_tag != 0)
- g_signal_handler_disconnect (daemon->async_cancel,
- daemon->cancelled_tag);
- daemon->async_cancel = 0;
- daemon->cancelled_tag = 0;
-
- if (daemon->timeout_tag != 0)
- g_source_remove (daemon->timeout_tag);
- daemon->timeout_tag = 0;
-
- daemon->async_requested_files = 0;
-
- g_object_unref (daemon->async_res);
- daemon->async_res = NULL;
-}
-
-static DBusHandlerResult
-g_daemon_file_enumerator_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- GDaemonFileEnumerator *enumerator = user_data;
- const char *member;
- DBusMessageIter iter, array_iter;
- GList *infos;
- GFileInfo *info;
-
- member = dbus_message_get_member (message);
-
- if (strcmp (member, G_VFS_DBUS_ENUMERATOR_OP_DONE) == 0)
- {
- G_LOCK (infos);
- enumerator->done = TRUE;
- if (enumerator->async_requested_files > 0)
- trigger_async_done (enumerator, TRUE);
- G_UNLOCK (infos);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- else if (strcmp (member, G_VFS_DBUS_ENUMERATOR_OP_GOT_INFO) == 0)
- {
- infos = NULL;
-
- dbus_message_iter_init (message, &iter);
- if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY &&
- dbus_message_iter_get_element_type (&iter) == DBUS_TYPE_STRUCT)
- {
- dbus_message_iter_recurse (&iter, &array_iter);
-
- while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT)
- {
- info = _g_dbus_get_file_info (&array_iter, NULL);
- if (info)
- g_assert (G_IS_FILE_INFO (info));
-
- if (info)
- infos = g_list_prepend (infos, info);
-
- dbus_message_iter_next (&iter);
- }
- }
-
- infos = g_list_reverse (infos);
-
- G_LOCK (infos);
- enumerator->infos = g_list_concat (enumerator->infos, infos);
- if (enumerator->async_requested_files > 0 &&
- g_list_length (enumerator->infos) >= enumerator->async_requested_files)
- trigger_async_done (enumerator, TRUE);
- G_UNLOCK (infos);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-char *
-g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator)
-{
- return g_strdup_printf (OBJ_PATH_PREFIX"%d", enumerator->id);
-}
-
-void
-g_daemon_file_enumerator_set_sync_connection (GDaemonFileEnumerator *enumerator,
- DBusConnection *connection)
-{
- enumerator->sync_connection = dbus_connection_ref (connection);
-}
-
-static GFileInfo *
-g_daemon_file_enumerator_next_file (GFileEnumerator *enumerator,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (enumerator);
- GFileInfo *info;
- gboolean done;
- int count;
-
- info = NULL;
- done = FALSE;
- count = 0;
- while (count++ < G_VFS_DBUS_TIMEOUT_MSECS / 100)
- {
- G_LOCK (infos);
- if (daemon->infos)
- {
- done = TRUE;
- info = daemon->infos->data;
- if (info)
- g_assert (G_IS_FILE_INFO (info));
- daemon->infos = g_list_delete_link (daemon->infos, daemon->infos);
- }
- else if (daemon->done)
- done = TRUE;
- G_UNLOCK (infos);
-
- if (info)
- g_assert (G_IS_FILE_INFO (info));
-
- if (done)
- break;
-
- /* We sleep only 100 msecs here, not the full time because we might have
- * raced with the filter func being called after unlocking
- * and setting done or ->infos. So, we want to check it again reasonaby soon.
- */
- if (daemon->sync_connection != NULL)
- {
- /* The initializing call for the enumerator was a sync one, and we
- have a reference to its private connection. In order to ensure we
- get the responses sent to that originating connection we pump it
- here.
- This should be safe as we're either on the thread that did the call
- so its our connection, or its the private connection for another
- thread. If that thread is idle the pumping won't affect anything, and
- if it is doing something thats ok to, because we don't use filters
- on the private sync connections so we won't cause any reentrancy
- (except the file enumerator filter, but that is safe to run in
- some other thread).
- */
- if (!dbus_connection_read_write_dispatch (daemon->sync_connection, 100))
- break;
- }
- else
- {
- /* The enumerator was initialized by an async call, so responses will
- come to the async dbus connection. We can't pump that as that would
- cause all sort of filters and stuff to run, possibly on the wrong
- thread. If you want to do async next_files you must create the
- enumerator asynchrounously.
- */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't do synchronous next_files() on a file enumerator created asynchronously");
- return NULL;
- }
- }
-
- return info;
-}
-
-static void
-async_cancelled (GCancellable *cancellable,
- GDaemonFileEnumerator *daemon)
-{
- g_simple_async_result_set_error (daemon->async_res,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- trigger_async_done (daemon, FALSE);
-}
-
-static gboolean
-async_timeout (gpointer data)
-{
- GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (data);
- trigger_async_done (daemon, TRUE);
- return FALSE;
-}
-
-static void
-g_daemon_file_enumerator_next_files_async (GFileEnumerator *enumerator,
- int num_files,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (enumerator);
-
- if (daemon->sync_connection != NULL)
- {
- /* If the enumerator was created synchronously then the connection used
- * for return messages will be the private connection for that thread.
- * We can't rely on it being pumped, so we don't support this.
- * We could possibly pump it ourselves in this case, but i'm not sure
- * how much sense this makes, so we don't for now.
- */
- g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't do asynchronous next_files() on a file enumerator created synchronously");
- return;
- }
-
- G_LOCK (infos);
- daemon->async_cancel = cancellable;
- daemon->cancelled_tag = 0;
- daemon->timeout_tag = 0;
- daemon->async_requested_files = num_files;
- daemon->async_res = g_simple_async_result_new (G_OBJECT (enumerator), callback, user_data,
- g_daemon_file_enumerator_next_files_async);
-
- /* Maybe we already have enough info to fulfill the requeust already */
- if (daemon->done ||
- g_list_length (daemon->infos) >= daemon->async_requested_files)
- trigger_async_done (daemon, TRUE);
- else
- {
- if (cancellable)
- daemon->cancelled_tag = g_signal_connect (cancellable, "cancelled", (GCallback)async_cancelled, daemon);
- daemon->timeout_tag = g_timeout_add (G_VFS_DBUS_TIMEOUT_MSECS,
- async_timeout, daemon);
- }
-
- G_UNLOCK (infos);
-}
-
-static GList *
-g_daemon_file_enumerator_next_files_finish (GFileEnumerator *enumerator,
- GAsyncResult *result,
- GError **error)
-{
- GList *l;
-
- l = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- /* We want the caller to own this, and not the result, so clear the result data */
- g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result),
- NULL, NULL);
-
- return l;
-}
-
-static gboolean
-g_daemon_file_enumerator_close (GFileEnumerator *enumerator,
- GCancellable *cancellable,
- GError **error)
-{
- /*GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (enumerator); */
-
- return TRUE;
-}
-
-
-/* We want an explicitly async version of close (doing nothing) to avoid
- the default thread-using version. */
-static void
-g_daemon_file_enumerator_close_async (GFileEnumerator *enumerator,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (enumerator), callback, user_data,
- g_daemon_file_enumerator_close_async);
- g_simple_async_result_complete_in_idle (res);
- g_object_unref (res);
-}
-
-static gboolean
-g_daemon_file_enumerator_close_finish (GFileEnumerator *enumerator,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
diff --git a/client/gdaemonfileenumerator.h b/client/gdaemonfileenumerator.h
deleted file mode 100644
index 25f5195a..00000000
--- a/client/gdaemonfileenumerator.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_FILE_ENUMERATOR_H__
-#define __G_DAEMON_FILE_ENUMERATOR_H__
-
-#include <gio/gio.h>
-#include <dbus/dbus.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_FILE_ENUMERATOR (g_daemon_file_enumerator_get_type ())
-#define G_DAEMON_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_FILE_ENUMERATOR, GDaemonFileEnumerator))
-#define G_DAEMON_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_FILE_ENUMERATOR, GDaemonFileEnumeratorClass))
-#define G_IS_DAEMON_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_FILE_ENUMERATOR))
-#define G_IS_DAEMON_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_FILE_ENUMERATOR))
-#define G_DAEMON_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DAEMON_FILE_ENUMERATOR, GDaemonFileEnumeratorClass))
-
-typedef struct _GDaemonFileEnumerator GDaemonFileEnumerator;
-typedef struct _GDaemonFileEnumeratorClass GDaemonFileEnumeratorClass;
-typedef struct _GDaemonFileEnumeratorPrivate GDaemonFileEnumeratorPrivate;
-
-struct _GDaemonFileEnumeratorClass
-{
- GFileEnumeratorClass parent_class;
-};
-
-GType g_daemon_file_enumerator_get_type (void) G_GNUC_CONST;
-
-GDaemonFileEnumerator *g_daemon_file_enumerator_new (GFile *file);
-char * g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator);
-void g_daemon_file_enumerator_set_sync_connection (GDaemonFileEnumerator *enumerator,
- DBusConnection *connection);
-
-
-G_END_DECLS
-
-#endif /* __G_FILE_DAEMON_FILE_ENUMERATOR_H__ */
diff --git a/client/gdaemonfileinputstream.c b/client/gdaemonfileinputstream.c
deleted file mode 100644
index 8cdc3622..00000000
--- a/client/gdaemonfileinputstream.c
+++ /dev/null
@@ -1,1643 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-#include <gio/gunixinputstream.h>
-#include <gio/gunixoutputstream.h>
-#include "gdaemonfileinputstream.h"
-#include "gvfsdaemondbus.h"
-#include <gvfsdaemonprotocol.h>
-
-#define MAX_READ_SIZE (4*1024*1024)
-
-typedef enum {
- INPUT_STATE_IN_REPLY_HEADER,
- INPUT_STATE_IN_BLOCK
-} InputState;
-
-typedef enum {
- STATE_OP_DONE,
- STATE_OP_READ,
- STATE_OP_WRITE,
- STATE_OP_SKIP
-} StateOp;
-
-typedef enum {
- READ_STATE_INIT = 0,
- READ_STATE_WROTE_COMMAND,
- READ_STATE_HANDLE_INPUT,
- READ_STATE_HANDLE_INPUT_BLOCK,
- READ_STATE_SKIP_BLOCK,
- READ_STATE_HANDLE_HEADER,
- READ_STATE_READ_BLOCK
-} ReadState;
-
-typedef struct {
- ReadState state;
-
- /* Input */
- char *buffer;
- gsize buffer_size;
- /* Output */
- gssize ret_val;
- GError *ret_error;
-
- gboolean sent_cancel;
-
- guint32 seq_nr;
-} ReadOperation;
-
-typedef enum {
- SEEK_STATE_INIT = 0,
- SEEK_STATE_WROTE_REQUEST,
- SEEK_STATE_HANDLE_INPUT,
- SEEK_STATE_HANDLE_INPUT_BLOCK,
- SEEK_STATE_SKIP_BLOCK,
- SEEK_STATE_HANDLE_HEADER
-} SeekState;
-
-typedef struct {
- SeekState state;
-
- /* Input */
- goffset offset;
- GSeekType seek_type;
- /* Output */
- gboolean ret_val;
- GError *ret_error;
- goffset ret_offset;
-
- gboolean sent_cancel;
- gboolean sent_seek;
-
- guint32 seq_nr;
-} SeekOperation;
-
-typedef enum {
- CLOSE_STATE_INIT = 0,
- CLOSE_STATE_WROTE_REQUEST,
- CLOSE_STATE_HANDLE_INPUT,
- CLOSE_STATE_HANDLE_INPUT_BLOCK,
- CLOSE_STATE_SKIP_BLOCK,
- CLOSE_STATE_HANDLE_HEADER
-} CloseState;
-
-typedef struct {
- CloseState state;
-
- /* Input */
-
- /* Output */
- gboolean ret_val;
- GError *ret_error;
-
- gboolean sent_cancel;
-
- guint32 seq_nr;
-} CloseOperation;
-
-
-typedef struct {
- gboolean cancelled;
-
- char *io_buffer;
- gsize io_size;
- gsize io_res;
- /* The operation always succeeds, or gets cancelled.
- If we get an error doing the i/o that is considered fatal */
- gboolean io_allow_cancel;
- gboolean io_cancelled;
-} IOOperationData;
-
-typedef StateOp (*state_machine_iterator) (GDaemonFileInputStream *file, IOOperationData *io_op, gpointer data);
-
-struct _GDaemonFileInputStream {
- GFileInputStream parent;
-
- GOutputStream *command_stream;
- GInputStream *data_stream;
- guint can_seek : 1;
-
- int seek_generation;
- guint32 seq_nr;
- goffset current_offset;
-
- InputState input_state;
- gsize input_block_size;
- int input_block_seek_generation;
- GString *input_buffer;
-
- GString *output_buffer;
-};
-
-static gssize g_daemon_file_input_stream_read (GInputStream *stream,
- void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error);
-static gssize g_daemon_file_input_stream_skip (GInputStream *stream,
- gsize count,
- GCancellable *cancellable,
- GError **error);
-static gboolean g_daemon_file_input_stream_close (GInputStream *stream,
- GCancellable *cancellable,
- GError **error);
-static GFileInfo *g_daemon_file_input_stream_query_info (GFileInputStream *stream,
- char *attributes,
- GCancellable *cancellable,
- GError **error);
-static goffset g_daemon_file_input_stream_tell (GFileInputStream *stream);
-static gboolean g_daemon_file_input_stream_can_seek (GFileInputStream *stream);
-static gboolean g_daemon_file_input_stream_seek (GFileInputStream *stream,
- goffset offset,
- GSeekType type,
- GCancellable *cancellable,
- GError **error);
-static void g_daemon_file_input_stream_read_async (GInputStream *stream,
- void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data);
-static gssize g_daemon_file_input_stream_read_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error);
-static void g_daemon_file_input_stream_skip_async (GInputStream *stream,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data);
-static gssize g_daemon_file_input_stream_skip_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error);
-static void g_daemon_file_input_stream_close_async (GInputStream *stream,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data);
-static gboolean g_daemon_file_input_stream_close_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error);
-
-
-G_DEFINE_TYPE (GDaemonFileInputStream, g_daemon_file_input_stream,
- G_TYPE_FILE_INPUT_STREAM)
-
-static void
-g_daemon_file_input_stream_finalize (GObject *object)
-{
- GDaemonFileInputStream *file;
-
- file = G_DAEMON_FILE_INPUT_STREAM (object);
-
- if (file->command_stream)
- g_object_unref (file->command_stream);
- if (file->data_stream)
- g_object_unref (file->data_stream);
-
- g_string_free (file->input_buffer, TRUE);
- g_string_free (file->output_buffer, TRUE);
-
- if (G_OBJECT_CLASS (g_daemon_file_input_stream_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_file_input_stream_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_file_input_stream_class_init (GDaemonFileInputStreamClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
- GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
-
- gobject_class->finalize = g_daemon_file_input_stream_finalize;
-
- stream_class->read_fn = g_daemon_file_input_stream_read;
- if (0) stream_class->skip = g_daemon_file_input_stream_skip;
- stream_class->close_fn = g_daemon_file_input_stream_close;
-
- stream_class->read_async = g_daemon_file_input_stream_read_async;
- stream_class->read_finish = g_daemon_file_input_stream_read_finish;
- if (0)
- {
- stream_class->skip_async = g_daemon_file_input_stream_skip_async;
- stream_class->skip_finish = g_daemon_file_input_stream_skip_finish;
- }
- stream_class->close_async = g_daemon_file_input_stream_close_async;
- stream_class->close_finish = g_daemon_file_input_stream_close_finish;
-
- file_stream_class->tell = g_daemon_file_input_stream_tell;
- file_stream_class->can_seek = g_daemon_file_input_stream_can_seek;
- file_stream_class->seek = g_daemon_file_input_stream_seek;
- file_stream_class->query_info = g_daemon_file_input_stream_query_info;
-
-}
-
-static void
-g_daemon_file_input_stream_init (GDaemonFileInputStream *info)
-{
- info->output_buffer = g_string_new ("");
- info->input_buffer = g_string_new ("");
- info->seq_nr = 1;
-}
-
-GFileInputStream *
-g_daemon_file_input_stream_new (int fd,
- gboolean can_seek)
-{
- GDaemonFileInputStream *stream;
-
- stream = g_object_new (G_TYPE_DAEMON_FILE_INPUT_STREAM, NULL);
-
- stream->command_stream = g_unix_output_stream_new (fd, FALSE);
- stream->data_stream = g_unix_input_stream_new (fd, TRUE);
- stream->can_seek = can_seek;
-
- return G_FILE_INPUT_STREAM (stream);
-}
-
-static gboolean
-error_is_cancel (GError *error)
-{
- return error != NULL &&
- error->domain == G_IO_ERROR &&
- error->code == G_IO_ERROR_CANCELLED;
-}
-
-static void
-append_request (GDaemonFileInputStream *stream, guint32 command,
- guint32 arg1, guint32 arg2, guint32 *seq_nr)
-{
- GVfsDaemonSocketProtocolRequest cmd;
-
- g_assert (sizeof (cmd) == G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE);
-
- if (seq_nr)
- *seq_nr = stream->seq_nr;
-
- cmd.command = g_htonl (command);
- cmd.seq_nr = g_htonl (stream->seq_nr++);
- cmd.arg1 = g_htonl (arg1);
- cmd.arg2 = g_htonl (arg2);
- cmd.data_len = 0;
-
- g_string_append_len (stream->output_buffer,
- (char *)&cmd, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE);
-}
-
-static gsize
-get_reply_header_missing_bytes (GString *buffer)
-{
- GVfsDaemonSocketProtocolReply *reply;
- guint32 type;
- guint32 arg2;
-
- if (buffer->len < G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE)
- return G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE - buffer->len;
-
- reply = (GVfsDaemonSocketProtocolReply *)buffer->str;
-
- type = g_ntohl (reply->type);
- arg2 = g_ntohl (reply->arg2);
-
- if (type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR)
- return G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE + arg2 - buffer->len;
- return 0;
-}
-
-static char *
-decode_reply (GString *buffer, GVfsDaemonSocketProtocolReply *reply_out)
-{
- GVfsDaemonSocketProtocolReply *reply;
- reply = (GVfsDaemonSocketProtocolReply *)buffer->str;
- reply_out->type = g_ntohl (reply->type);
- reply_out->seq_nr = g_ntohl (reply->seq_nr);
- reply_out->arg1 = g_ntohl (reply->arg1);
- reply_out->arg2 = g_ntohl (reply->arg2);
-
- return buffer->str + G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE;
-}
-
-static void
-decode_error (GVfsDaemonSocketProtocolReply *reply, char *data, GError **error)
-{
- g_set_error_literal (error,
- g_quark_from_string (data),
- reply->arg1,
- data + strlen (data) + 1);
-}
-
-
-static gboolean
-run_sync_state_machine (GDaemonFileInputStream *file,
- state_machine_iterator iterator,
- gpointer data,
- GCancellable *cancellable,
- GError **error)
-{
- gssize res;
- StateOp io_op;
- IOOperationData io_data;
- GError *io_error;
-
- memset (&io_data, 0, sizeof (io_data));
-
- while (TRUE)
- {
- if (cancellable)
- io_data.cancelled = g_cancellable_is_cancelled (cancellable);
-
- io_op = iterator (file, &io_data, data);
-
- if (io_op == STATE_OP_DONE)
- return TRUE;
-
- io_error = NULL;
- if (io_op == STATE_OP_READ)
- {
- res = g_input_stream_read (file->data_stream,
- io_data.io_buffer, io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else if (io_op == STATE_OP_SKIP)
- {
- res = g_input_stream_skip (file->data_stream,
- io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else if (io_op == STATE_OP_WRITE)
- {
- res = g_output_stream_write (file->command_stream,
- io_data.io_buffer, io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else
- {
- res = 0;
- g_assert_not_reached ();
- }
-
- if (res == -1)
- {
- if (error_is_cancel (io_error))
- {
- io_data.io_res = 0;
- io_data.io_cancelled = TRUE;
- g_error_free (io_error);
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), io_error->message);
- g_error_free (io_error);
- return FALSE;
- }
- }
- else if (res == 0 && io_data.io_size != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), _("End of stream"));
- return FALSE;
- }
- else
- {
- io_data.io_res = res;
- io_data.io_cancelled = FALSE;
- }
- }
-}
-
-/* read cycle:
-
- if we know of a (partially read) matching outstanding block, read from it
- create packet, append to outgoing
- flush outgoing
- start processing input, looking for a data block with same seek gen,
- or an error with same seq nr
- on cancel, send cancel command and go back to loop
- */
-
-static StateOp
-iterate_read_state_machine (GDaemonFileInputStream *file, IOOperationData *io_op, ReadOperation *op)
-{
- gsize len;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case READ_STATE_INIT:
- /* If we're already reading some data, but we didn't read all, just use that
- and don't even send a request */
- if (file->input_state == INPUT_STATE_IN_BLOCK &&
- file->seek_generation == file->input_block_seek_generation)
- {
- op->state = READ_STATE_READ_BLOCK;
- io_op->io_buffer = op->buffer;
- io_op->io_size = MIN (op->buffer_size, file->input_block_size);
- io_op->io_allow_cancel = TRUE; /* Allow cancel before we sent request */
- return STATE_OP_READ;
- }
-
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_READ,
- op->buffer_size, 0, &op->seq_nr);
- op->state = READ_STATE_WROTE_COMMAND;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case READ_STATE_WROTE_COMMAND:
- if (io_op->io_cancelled)
- {
- op->ret_val = -1;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->state = READ_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case READ_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, NULL);
- op->state = READ_STATE_WROTE_COMMAND;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (file->input_state == INPUT_STATE_IN_BLOCK)
- {
- op->state = READ_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- else if (file->input_state == INPUT_STATE_IN_REPLY_HEADER)
- {
- op->state = READ_STATE_HANDLE_HEADER;
- break;
- }
- g_assert_not_reached ();
- break;
-
- /* No op */
- case READ_STATE_HANDLE_INPUT_BLOCK:
- g_assert (file->input_state == INPUT_STATE_IN_BLOCK);
-
- if (file->seek_generation ==
- file->input_block_seek_generation)
- {
- op->state = READ_STATE_READ_BLOCK;
- io_op->io_buffer = op->buffer;
- io_op->io_size = MIN (op->buffer_size, file->input_block_size);
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_READ;
- }
- else
- {
- op->state = READ_STATE_SKIP_BLOCK;
- io_op->io_buffer = NULL;
- io_op->io_size = file->input_block_size;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_SKIP;
- }
- break;
-
- /* Read block data */
- case READ_STATE_SKIP_BLOCK:
- if (io_op->io_cancelled)
- {
- op->state = READ_STATE_HANDLE_INPUT;
- break;
- }
-
- g_assert (io_op->io_res <= file->input_block_size);
- file->input_block_size -= io_op->io_res;
-
- if (file->input_block_size == 0)
- file->input_state = INPUT_STATE_IN_REPLY_HEADER;
-
- op->state = READ_STATE_HANDLE_INPUT;
- break;
-
- /* read header data, (or manual io_len/res = 0) */
- case READ_STATE_HANDLE_HEADER:
- if (io_op->io_cancelled)
- {
- op->state = READ_STATE_HANDLE_INPUT;
- break;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = -1;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_DATA)
- {
- g_string_truncate (file->input_buffer, 0);
- file->input_state = INPUT_STATE_IN_BLOCK;
- file->input_block_size = reply.arg1;
- file->input_block_seek_generation = reply.arg2;
- op->state = READ_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = READ_STATE_HANDLE_HEADER;
- break;
-
- /* Read block data */
- case READ_STATE_READ_BLOCK:
- if (io_op->io_cancelled)
- {
- op->ret_val = -1;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res > 0)
- {
- g_assert (io_op->io_res <= file->input_block_size);
- file->input_block_size -= io_op->io_res;
- if (file->input_block_size == 0)
- file->input_state = INPUT_STATE_IN_REPLY_HEADER;
- }
-
- op->ret_val = io_op->io_res;
- op->ret_error = NULL;
- return STATE_OP_DONE;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
-
- }
-}
-
-static gssize
-g_daemon_file_input_stream_read (GInputStream *stream,
- void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileInputStream *file;
- ReadOperation op;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return -1;
-
- /* Limit for sanity and to avoid 32bit overflow */
- if (count > MAX_READ_SIZE)
- count = MAX_READ_SIZE;
-
- memset (&op, 0, sizeof (op));
- op.state = READ_STATE_INIT;
- op.buffer = buffer;
- op.buffer_size = count;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_read_state_machine,
- &op, cancellable, error))
- return -1; /* IO Error */
-
- if (op.ret_val == -1)
- g_propagate_error (error, op.ret_error);
- else
- file->current_offset += op.ret_val;
-
- return op.ret_val;
-}
-
-static gssize
-g_daemon_file_input_stream_skip (GInputStream *stream,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
-#if 0
- GDaemonFileInputStream *file;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-#endif
- /* TODO: implement skip */
- g_assert_not_reached ();
-
- return 0;
-}
-
-static StateOp
-iterate_close_state_machine (GDaemonFileInputStream *file, IOOperationData *io_op, CloseOperation *op)
-{
- gsize len;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case CLOSE_STATE_INIT:
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CLOSE,
- 0, 0, &op->seq_nr);
- op->state = CLOSE_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case CLOSE_STATE_WROTE_REQUEST:
- if (io_op->io_cancelled)
- {
- op->ret_val = FALSE;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case CLOSE_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, NULL);
- op->state = CLOSE_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (file->input_state == INPUT_STATE_IN_BLOCK)
- {
- op->state = CLOSE_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- else if (file->input_state == INPUT_STATE_IN_REPLY_HEADER)
- {
- op->state = CLOSE_STATE_HANDLE_HEADER;
- break;
- }
- g_assert_not_reached ();
- break;
-
- /* No op */
- case CLOSE_STATE_HANDLE_INPUT_BLOCK:
- g_assert (file->input_state == INPUT_STATE_IN_BLOCK);
-
- op->state = CLOSE_STATE_SKIP_BLOCK;
- io_op->io_buffer = NULL;
- io_op->io_size = file->input_block_size;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_SKIP;
-
- /* Read block data */
- case CLOSE_STATE_SKIP_BLOCK:
- if (io_op->io_cancelled)
- {
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
- }
-
- g_assert (io_op->io_res <= file->input_block_size);
- file->input_block_size -= io_op->io_res;
-
- if (file->input_block_size == 0)
- file->input_state = INPUT_STATE_IN_REPLY_HEADER;
-
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
-
- /* read header data, (or manual io_len/res = 0) */
- case CLOSE_STATE_HANDLE_HEADER:
- if (io_op->io_cancelled)
- {
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = FALSE;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_DATA)
- {
- g_string_truncate (file->input_buffer, 0);
- file->input_state = INPUT_STATE_IN_BLOCK;
- file->input_block_size = reply.arg1;
- file->input_block_seek_generation = reply.arg2;
- op->state = CLOSE_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_CLOSED)
- {
- op->ret_val = TRUE;
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = CLOSE_STATE_HANDLE_HEADER;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
- }
-}
-
-
-static gboolean
-g_daemon_file_input_stream_close (GInputStream *stream,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileInputStream *file;
- CloseOperation op;
- gboolean res;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- /* We need to do a full roundtrip to guarantee that the writes have
- reached the disk. */
-
- memset (&op, 0, sizeof (op));
- op.state = CLOSE_STATE_INIT;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_close_state_machine,
- &op, cancellable, error))
- res = FALSE;
- else
- {
- if (!op.ret_val)
- g_propagate_error (error, op.ret_error);
- res = op.ret_val;
- }
-
- /* Return the first error, but close all streams */
- if (res)
- res = g_output_stream_close (file->command_stream, cancellable, error);
- else
- g_output_stream_close (file->command_stream, cancellable, NULL);
-
- if (res)
- res = g_input_stream_close (file->data_stream, cancellable, error);
- else
- g_input_stream_close (file->data_stream, cancellable, NULL);
-
- return res;
-}
-
-static goffset
-g_daemon_file_input_stream_tell (GFileInputStream *stream)
-{
- GDaemonFileInputStream *file;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- return file->current_offset;
-}
-
-static gboolean
-g_daemon_file_input_stream_can_seek (GFileInputStream *stream)
-{
- GDaemonFileInputStream *file;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- return file->can_seek;
-}
-
-static StateOp
-iterate_seek_state_machine (GDaemonFileInputStream *file, IOOperationData *io_op, SeekOperation *op)
-{
- gsize len;
- guint32 request;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case SEEK_STATE_INIT:
- request = G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_SET;
- if (op->seek_type == G_SEEK_CUR)
- op->offset = file->current_offset + op->offset;
- else if (op->seek_type == G_SEEK_END)
- request = G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_END;
- append_request (file, request,
- op->offset & 0xffffffff,
- op->offset >> 32,
- &op->seq_nr);
- op->state = SEEK_STATE_WROTE_REQUEST;
- op->sent_seek = FALSE;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case SEEK_STATE_WROTE_REQUEST:
- if (io_op->io_cancelled)
- {
- op->ret_val = -1;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- /* We weren't cancelled before first byte sent, so now we will send
- * the seek request. Increase the seek generation now. */
- if (!op->sent_seek)
- file->seek_generation++;
- op->sent_seek = TRUE;
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case SEEK_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, NULL);
- op->state = SEEK_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (file->input_state == INPUT_STATE_IN_BLOCK)
- {
- op->state = SEEK_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- else if (file->input_state == INPUT_STATE_IN_REPLY_HEADER)
- {
- op->state = SEEK_STATE_HANDLE_HEADER;
- break;
- }
- g_assert_not_reached ();
- break;
-
- /* No op */
- case SEEK_STATE_HANDLE_INPUT_BLOCK:
- g_assert (file->input_state == INPUT_STATE_IN_BLOCK);
-
- op->state = SEEK_STATE_SKIP_BLOCK;
- /* Reuse client buffer for skipping */
- io_op->io_buffer = NULL;
- io_op->io_size = file->input_block_size;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_SKIP;
-
- /* Read block data */
- case SEEK_STATE_SKIP_BLOCK:
- if (io_op->io_cancelled)
- {
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
- }
-
- g_assert (io_op->io_res <= file->input_block_size);
- file->input_block_size -= io_op->io_res;
-
- if (file->input_block_size == 0)
- file->input_state = INPUT_STATE_IN_REPLY_HEADER;
-
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
-
- /* read header data, (or manual io_len/res = 0) */
- case SEEK_STATE_HANDLE_HEADER:
- if (io_op->io_cancelled)
- {
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = FALSE;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_DATA)
- {
- g_string_truncate (file->input_buffer, 0);
- file->input_state = INPUT_STATE_IN_BLOCK;
- file->input_block_size = reply.arg1;
- file->input_block_seek_generation = reply.arg2;
- op->state = SEEK_STATE_HANDLE_INPUT_BLOCK;
- break;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SEEK_POS)
- {
- op->ret_val = TRUE;
- op->ret_offset = ((goffset)reply.arg2) << 32 | (goffset)reply.arg1;
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = SEEK_STATE_HANDLE_HEADER;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
- }
-}
-
-static gboolean
-g_daemon_file_input_stream_seek (GFileInputStream *stream,
- goffset offset,
- GSeekType type,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileInputStream *file;
- SeekOperation op;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- if (!file->can_seek)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Seek not supported on stream"));
- return FALSE;
- }
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return FALSE;
-
- memset (&op, 0, sizeof (op));
- op.state = SEEK_STATE_INIT;
- op.offset = offset;
- op.seek_type = type;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_seek_state_machine,
- &op, cancellable, error))
- return FALSE; /* IO Error */
-
- if (!op.ret_val)
- g_propagate_error (error, op.ret_error);
- else
- file->current_offset = op.ret_offset;
-
- return op.ret_val;
-}
-
-static GFileInfo *
-g_daemon_file_input_stream_query_info (GFileInputStream *stream,
- char *attributes,
- GCancellable *cancellable,
- GError **error)
-{
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("The query info operation is not supported"));
-
- return NULL;
-}
-
-/************************************************************************
- * Async I/O Code *
- ************************************************************************/
-
-typedef struct AsyncIterator AsyncIterator;
-
-typedef void (*AsyncIteratorDone) (GInputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer callback_data,
- GError *io_error);
-
-struct AsyncIterator {
- AsyncIteratorDone done_cb;
- GDaemonFileInputStream *file;
- GCancellable *cancellable;
- IOOperationData io_data;
- state_machine_iterator iterator;
- gpointer iterator_data;
- int io_priority;
- GAsyncReadyCallback callback;
- gpointer callback_data;
-};
-
-static void async_iterate (AsyncIterator *iterator);
-
-static void
-async_iterator_done (AsyncIterator *iterator, GError *io_error)
-{
- iterator->done_cb (G_INPUT_STREAM (iterator->file),
- iterator->iterator_data,
- iterator->callback,
- iterator->callback_data,
- io_error);
-
- g_free (iterator);
-
-}
-
-static void
-async_op_handle (AsyncIterator *iterator,
- gssize res,
- GError *io_error)
-{
- IOOperationData *io_data = &iterator->io_data;
- GError *error;
-
- if (io_error != NULL)
- {
- if (error_is_cancel (io_error))
- {
- io_data->io_res = 0;
- io_data->io_cancelled = TRUE;
- }
- else
- {
- error = NULL;
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), io_error->message);
- async_iterator_done (iterator, error);
- g_error_free (error);
- return;
- }
- }
- else if (res == 0 && io_data->io_size != 0)
- {
- error = NULL;
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), _("End of stream"));
- async_iterator_done (iterator, error);
- g_error_free (error);
- return;
- }
- else
- {
- io_data->io_res = res;
- io_data->io_cancelled = FALSE;
- }
-
- async_iterate (iterator);
-}
-
-static void
-async_read_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GInputStream *stream = G_INPUT_STREAM (source_object);
- gssize count_read;
- GError *error = NULL;
-
- count_read = g_input_stream_read_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, count_read, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_skip_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GInputStream *stream = G_INPUT_STREAM (source_object);
- gssize count_skipped;
- GError *error = NULL;
-
- count_skipped = g_input_stream_skip_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, count_skipped, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_write_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- gssize bytes_written;
- GError *error = NULL;
-
- bytes_written = g_output_stream_write_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, bytes_written, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_iterate (AsyncIterator *iterator)
-{
- IOOperationData *io_data = &iterator->io_data;
- GDaemonFileInputStream *file = iterator->file;
- StateOp io_op;
-
- io_data->cancelled =
- g_cancellable_is_cancelled (iterator->cancellable);
-
- io_op = iterator->iterator (file, io_data, iterator->iterator_data);
-
- if (io_op == STATE_OP_DONE)
- {
- async_iterator_done (iterator, NULL);
- return;
- }
-
- /* TODO: Handle allow_cancel... */
-
- if (io_op == STATE_OP_READ)
- {
- g_input_stream_read_async (file->data_stream,
- io_data->io_buffer, io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_read_op_callback, iterator);
- }
- else if (io_op == STATE_OP_SKIP)
- {
- g_input_stream_skip_async (file->data_stream,
- io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_skip_op_callback, iterator);
- }
- else if (io_op == STATE_OP_WRITE)
- {
- g_output_stream_write_async (file->command_stream,
- io_data->io_buffer, io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_write_op_callback, iterator);
- }
- else
- g_assert_not_reached ();
-}
-
-static void
-run_async_state_machine (GDaemonFileInputStream *file,
- state_machine_iterator iterator_cb,
- gpointer iterator_data,
- int io_priority,
- GAsyncReadyCallback callback,
- gpointer data,
- GCancellable *cancellable,
- AsyncIteratorDone done_cb)
-{
- AsyncIterator *iterator;
-
- iterator = g_new0 (AsyncIterator, 1);
- iterator->file = file;
- iterator->iterator = iterator_cb;
- iterator->iterator_data = iterator_data;
- iterator->io_priority = io_priority;
- iterator->cancellable = cancellable;
- iterator->callback = callback;
- iterator->callback_data = data;
- iterator->done_cb = done_cb;
-
- async_iterate (iterator);
-}
-
-static void
-async_read_done (GInputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer user_data,
- GError *io_error)
-{
- ReadOperation *op;
- gssize count_read;
- GError *error;
- GSimpleAsyncResult *simple;
-
- op = op_data;
-
- if (io_error)
- {
- count_read = -1;
- error = io_error;
- }
- else
- {
- count_read = op->ret_val;
- error = op->ret_error;
- }
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_daemon_file_input_stream_read_async);
-
- g_simple_async_result_set_op_res_gssize (simple, count_read);
-
- if (count_read == -1)
- g_simple_async_result_set_from_error (simple, error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- if (op->ret_error)
- g_error_free (op->ret_error);
- g_free (op);
-}
-
-static void
-g_daemon_file_input_stream_read_async (GInputStream *stream,
- void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonFileInputStream *file;
- ReadOperation *op;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- /* Limit for sanity and to avoid 32bit overflow */
- if (count > MAX_READ_SIZE)
- count = MAX_READ_SIZE;
-
- op = g_new0 (ReadOperation, 1);
- op->state = READ_STATE_INIT;
- op->buffer = buffer;
- op->buffer_size = count;
-
- run_async_state_machine (file,
- (state_machine_iterator)iterate_read_state_machine,
- op,
- io_priority,
- callback, user_data,
- cancellable,
- async_read_done);
-}
-
-static gssize
-g_daemon_file_input_stream_read_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- gssize nread;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- g_assert (g_simple_async_result_get_source_tag (simple) == g_daemon_file_input_stream_read_async);
-
- nread = g_simple_async_result_get_op_res_gssize (simple);
- return nread;
-}
-
-
-static void
-g_daemon_file_input_stream_skip_async (GInputStream *stream,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data)
-{
- g_assert_not_reached ();
- /* TODO: Not implemented */
-}
-
-static gssize
-g_daemon_file_input_stream_skip_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- g_assert_not_reached ();
- /* TODO: Not implemented */
-}
-
-static void
-async_close_done (GInputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer user_data,
- GError *io_error)
-{
- GDaemonFileInputStream *file;
- GSimpleAsyncResult *simple;
- CloseOperation *op;
- gboolean result;
- GError *error;
- GCancellable *cancellable = NULL; /* TODO: get cancellable */
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- op = op_data;
-
- if (io_error)
- {
- result = FALSE;
- error = io_error;
- }
- else
- {
- result = op->ret_val;
- error = op->ret_error;
- }
-
- if (result)
- result = g_output_stream_close (file->command_stream, cancellable, &error);
- else
- g_output_stream_close (file->command_stream, cancellable, NULL);
-
- if (result)
- result = g_input_stream_close (file->data_stream, cancellable, &error);
- else
- g_input_stream_close (file->data_stream, cancellable, NULL);
-
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_daemon_file_input_stream_read_async);
-
- if (!result)
- g_simple_async_result_set_from_error (simple, error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- if (op->ret_error)
- g_error_free (op->ret_error);
- g_free (op);
-}
-
-static void
-g_daemon_file_input_stream_close_async (GInputStream *stream,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data)
-{
- GDaemonFileInputStream *file;
- CloseOperation *op;
-
- file = G_DAEMON_FILE_INPUT_STREAM (stream);
-
- op = g_new0 (CloseOperation, 1);
- op->state = CLOSE_STATE_INIT;
-
- run_async_state_machine (file,
- (state_machine_iterator)iterate_close_state_machine,
- op, io_priority,
- callback, data,
- cancellable,
- async_close_done);
-}
-
-static gboolean
-g_daemon_file_input_stream_close_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- /* Failures handled in generic close_finish code */
- return TRUE;
-}
diff --git a/client/gdaemonfileinputstream.h b/client/gdaemonfileinputstream.h
deleted file mode 100644
index 2d4cc4ce..00000000
--- a/client/gdaemonfileinputstream.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_FILE_INPUT_STREAM_H__
-#define __G_DAEMON_FILE_INPUT_STREAM_H__
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_FILE_INPUT_STREAM (g_daemon_file_input_stream_get_type ())
-#define G_DAEMON_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_FILE_INPUT_STREAM, GDaemonFileInputStream))
-#define G_DAEMON_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_FILE_INPUT_STREAM, GDaemonFileInputStreamClass))
-#define G_IS_DAEMON_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_FILE_INPUT_STREAM))
-#define G_IS_DAEMON_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_FILE_INPUT_STREAM))
-#define G_DAEMON_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DAEMON_FILE_INPUT_STREAM, GDaemonFileInputStreamClass))
-
-typedef struct _GDaemonFileInputStream GDaemonFileInputStream;
-typedef struct _GDaemonFileInputStreamClass GDaemonFileInputStreamClass;
-
-struct _GDaemonFileInputStreamClass
-{
- GFileInputStreamClass parent_class;
-};
-
-GType g_daemon_file_input_stream_get_type (void) G_GNUC_CONST;
-
-GFileInputStream *g_daemon_file_input_stream_new (int fd,
- gboolean can_seek);
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_FILE_INPUT_STREAM_H__ */
diff --git a/client/gdaemonfilemonitor.c b/client/gdaemonfilemonitor.c
deleted file mode 100644
index 61b35e54..00000000
--- a/client/gdaemonfilemonitor.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-#include <string.h>
-
-#include "gdaemonfilemonitor.h"
-#include <gio/gio.h>
-#include <gvfsdaemondbus.h>
-#include <gvfsdaemonprotocol.h>
-#include "gdbusutils.h"
-#include "gmountspec.h"
-#include "gdaemonfile.h"
-
-#define OBJ_PATH_PREFIX "/org/gtk/vfs/client/filemonitor/"
-
-/* atomic */
-static volatile gint path_counter = 1;
-
-static gboolean g_daemon_file_monitor_cancel (GFileMonitor* monitor);
-static DBusHandlerResult g_daemon_file_monitor_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
-
-
-struct _GDaemonFileMonitor
-{
- GFileMonitor parent_instance;
-
- char *object_path;
- char *remote_obj_path;
- char *remote_id;
-};
-
-G_DEFINE_TYPE (GDaemonFileMonitor, g_daemon_file_monitor, G_TYPE_FILE_MONITOR)
-
-static void
-g_daemon_file_monitor_finalize (GObject* object)
-{
- GDaemonFileMonitor *daemon_monitor;
-
- daemon_monitor = G_DAEMON_FILE_MONITOR (object);
-
- _g_dbus_unregister_vfs_filter (daemon_monitor->object_path);
-
- g_free (daemon_monitor->object_path);
- g_free (daemon_monitor->remote_id);
- g_free (daemon_monitor->remote_obj_path);
-
- if (G_OBJECT_CLASS (g_daemon_file_monitor_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_file_monitor_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_file_monitor_class_init (GDaemonFileMonitorClass* klass)
-{
- GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
- GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass);
-
- gobject_class->finalize = g_daemon_file_monitor_finalize;
-
- file_monitor_class->cancel = g_daemon_file_monitor_cancel;
-}
-
-static void
-g_daemon_file_monitor_init (GDaemonFileMonitor* daemon_monitor)
-{
- gint id;
-
- id = g_atomic_int_exchange_and_add (&path_counter, 1);
-
- daemon_monitor->object_path = g_strdup_printf (OBJ_PATH_PREFIX"%d", id);
-
- _g_dbus_register_vfs_filter (daemon_monitor->object_path,
- g_daemon_file_monitor_dbus_filter,
- G_OBJECT (daemon_monitor));
-}
-
-GFileMonitor*
-g_daemon_file_monitor_new (const char *remote_id,
- const char *remote_obj_path)
-{
- GDaemonFileMonitor* daemon_monitor;
- DBusMessage *message;
-
- daemon_monitor = g_object_new (G_TYPE_DAEMON_FILE_MONITOR, NULL);
-
- daemon_monitor->remote_id = g_strdup (remote_id);
- daemon_monitor->remote_obj_path = g_strdup (remote_obj_path);
-
- message =
- dbus_message_new_method_call (daemon_monitor->remote_id,
- daemon_monitor->remote_obj_path,
- G_VFS_DBUS_MONITOR_INTERFACE,
- G_VFS_DBUS_MONITOR_OP_SUBSCRIBE);
-
- _g_dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH,
- &daemon_monitor->object_path, 0);
-
- _g_vfs_daemon_call_async (message,
- NULL, NULL,
- NULL);
-
- dbus_message_unref (message);
-
- return G_FILE_MONITOR (daemon_monitor);
-}
-
-static DBusHandlerResult
-g_daemon_file_monitor_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- GDaemonFileMonitor *monitor = G_DAEMON_FILE_MONITOR (user_data);
- const char *member;
- guint32 event_type;
- DBusMessageIter iter;
- GMountSpec *spec1, *spec2;
- char *path1, *path2;
- GFile *file1, *file2;
-
- member = dbus_message_get_member (message);
-
- if (strcmp (member, G_VFS_DBUS_MONITOR_CLIENT_OP_CHANGED) == 0)
- {
- dbus_message_iter_init (message, &iter);
-
- if (!_g_dbus_message_iter_get_args (&iter, NULL,
- DBUS_TYPE_UINT32, &event_type,
- 0))
- return DBUS_HANDLER_RESULT_HANDLED;
-
- spec1 = g_mount_spec_from_dbus (&iter);
- if (!_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &path1,
- 0))
- {
- g_mount_spec_unref (spec1);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- file1 = g_daemon_file_new (spec1, path1);
-
- g_mount_spec_unref (spec1);
- g_free (path1);
-
- file2 = NULL;
-
- spec2 = g_mount_spec_from_dbus (&iter);
- if (spec2) {
- if (_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &path2,
- 0))
- {
- file2 = g_daemon_file_new (spec2, path2);
-
- g_free (path2);
- }
-
- g_mount_spec_unref (spec2);
- }
-
- g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
- file1, file2,
- event_type);
-
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-static gboolean
-g_daemon_file_monitor_cancel (GFileMonitor* monitor)
-{
- GDaemonFileMonitor *daemon_monitor = G_DAEMON_FILE_MONITOR (monitor);
- DBusMessage *message;
-
- message =
- dbus_message_new_method_call (daemon_monitor->remote_id,
- daemon_monitor->remote_obj_path,
- G_VFS_DBUS_MONITOR_INTERFACE,
- G_VFS_DBUS_MONITOR_OP_UNSUBSCRIBE);
-
- _g_vfs_daemon_call_async (message,
- NULL, NULL,
- NULL);
-
- dbus_message_unref (message);
-
- return TRUE;
-}
-
diff --git a/client/gdaemonfilemonitor.h b/client/gdaemonfilemonitor.h
deleted file mode 100644
index 9cd02175..00000000
--- a/client/gdaemonfilemonitor.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_FILE_MONITOR_H__
-#define __G_DAEMON_FILE_MONITOR_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_FILE_MONITOR (g_daemon_file_monitor_get_type ())
-#define G_DAEMON_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_FILE_MONITOR, GDaemonFileMonitor))
-#define G_DAEMON_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_DAEMON_FILE_MONITOR, GDaemonFileMonitorClass))
-#define G_IS_DAEMON_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_FILE_MONITOR))
-#define G_IS_DAEMON_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_FILE_MONITOR))
-
-typedef struct _GDaemonFileMonitor GDaemonFileMonitor;
-typedef struct _GDaemonFileMonitorClass GDaemonFileMonitorClass;
-
-struct _GDaemonFileMonitorClass {
- GFileMonitorClass parent_class;
-};
-
-GType g_daemon_file_monitor_get_type (void) G_GNUC_CONST;
-
-GFileMonitor* g_daemon_file_monitor_new (const char *remote_id,
- const char *remote_obj_path);
-
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_FILE_MONITOR_H__ */
diff --git a/client/gdaemonfileoutputstream.c b/client/gdaemonfileoutputstream.c
deleted file mode 100644
index 525475c8..00000000
--- a/client/gdaemonfileoutputstream.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-#include <gio/gunixinputstream.h>
-#include <gio/gunixoutputstream.h>
-#include "gdaemonfileoutputstream.h"
-#include "gvfsdaemondbus.h"
-#include <gvfsdaemonprotocol.h>
-
-#define MAX_WRITE_SIZE (4*1024*1024)
-
-typedef enum {
- STATE_OP_DONE,
- STATE_OP_READ,
- STATE_OP_WRITE,
- STATE_OP_SKIP
-} StateOp;
-
-typedef enum {
- WRITE_STATE_INIT = 0,
- WRITE_STATE_WROTE_COMMAND,
- WRITE_STATE_SEND_DATA,
- WRITE_STATE_HANDLE_INPUT
-} WriteState;
-
-typedef struct {
- WriteState state;
-
- /* Output */
- const char *buffer;
- gsize buffer_size;
- gsize buffer_pos;
-
- /* Input */
- gssize ret_val;
- GError *ret_error;
-
- gboolean sent_cancel;
-
- guint32 seq_nr;
-} WriteOperation;
-
-typedef enum {
- SEEK_STATE_INIT = 0,
- SEEK_STATE_WROTE_REQUEST,
- SEEK_STATE_HANDLE_INPUT
-} SeekState;
-
-typedef struct {
- SeekState state;
-
- /* Output */
- goffset offset;
- GSeekType seek_type;
- /* Output */
- gboolean ret_val;
- GError *ret_error;
- goffset ret_offset;
-
- gboolean sent_cancel;
-
- guint32 seq_nr;
-} SeekOperation;
-
-typedef enum {
- CLOSE_STATE_INIT = 0,
- CLOSE_STATE_WROTE_REQUEST,
- CLOSE_STATE_HANDLE_INPUT
-} CloseState;
-
-typedef struct {
- CloseState state;
-
- /* Output */
-
- /* Output */
- gboolean ret_val;
- GError *ret_error;
-
- gboolean sent_cancel;
-
- guint32 seq_nr;
-} CloseOperation;
-
-
-typedef struct {
- gboolean cancelled;
-
- char *io_buffer;
- gsize io_size;
- gsize io_res;
- /* The operation always succeeds, or gets cancelled.
- If we get an error doing the i/o that is considered fatal */
- gboolean io_allow_cancel;
- gboolean io_cancelled;
-} IOOperationData;
-
-typedef StateOp (*state_machine_iterator) (GDaemonFileOutputStream *file, IOOperationData *io_op, gpointer data);
-
-struct _GDaemonFileOutputStream {
- GFileOutputStream parent;
-
- GOutputStream *command_stream;
- GInputStream *data_stream;
- guint can_seek : 1;
-
- guint32 seq_nr;
- goffset current_offset;
-
- gsize input_block_size;
- GString *input_buffer;
-
- GString *output_buffer;
-
- char *etag;
-
-};
-
-static gssize g_daemon_file_output_stream_write (GOutputStream *stream,
- const void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error);
-static gboolean g_daemon_file_output_stream_close (GOutputStream *stream,
- GCancellable *cancellable,
- GError **error);
-static GFileInfo *g_daemon_file_output_stream_query_info (GFileOutputStream *stream,
- char *attributes,
- GCancellable *cancellable,
- GError **error);
-static char *g_daemon_file_output_stream_get_etag (GFileOutputStream *stream);
-static goffset g_daemon_file_output_stream_tell (GFileOutputStream *stream);
-static gboolean g_daemon_file_output_stream_can_seek (GFileOutputStream *stream);
-static gboolean g_daemon_file_output_stream_seek (GFileOutputStream *stream,
- goffset offset,
- GSeekType type,
- GCancellable *cancellable,
- GError **error);
-static void g_daemon_file_output_stream_write_async (GOutputStream *stream,
- const void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data);
-static gssize g_daemon_file_output_stream_write_finish (GOutputStream *stream,
- GAsyncResult *result,
- GError **error);
-static void g_daemon_file_output_stream_close_async (GOutputStream *stream,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data);
-static gboolean g_daemon_file_output_stream_close_finish (GOutputStream *stream,
- GAsyncResult *result,
- GError **error);
-
-G_DEFINE_TYPE (GDaemonFileOutputStream, g_daemon_file_output_stream,
- G_TYPE_FILE_OUTPUT_STREAM)
-
-static void
-g_daemon_file_output_stream_finalize (GObject *object)
-{
- GDaemonFileOutputStream *file;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (object);
-
- if (file->command_stream)
- g_object_unref (file->command_stream);
- if (file->data_stream)
- g_object_unref (file->data_stream);
-
- g_string_free (file->input_buffer, TRUE);
- g_string_free (file->output_buffer, TRUE);
-
- g_free (file->etag);
-
- if (G_OBJECT_CLASS (g_daemon_file_output_stream_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_file_output_stream_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_file_output_stream_class_init (GDaemonFileOutputStreamClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
- GFileOutputStreamClass *file_stream_class = G_FILE_OUTPUT_STREAM_CLASS (klass);
-
- gobject_class->finalize = g_daemon_file_output_stream_finalize;
-
- stream_class->write_fn = g_daemon_file_output_stream_write;
- stream_class->close_fn = g_daemon_file_output_stream_close;
-
- stream_class->write_async = g_daemon_file_output_stream_write_async;
- stream_class->write_finish = g_daemon_file_output_stream_write_finish;
- stream_class->close_async = g_daemon_file_output_stream_close_async;
- stream_class->close_finish = g_daemon_file_output_stream_close_finish;
-
- file_stream_class->tell = g_daemon_file_output_stream_tell;
- file_stream_class->can_seek = g_daemon_file_output_stream_can_seek;
- file_stream_class->seek = g_daemon_file_output_stream_seek;
- file_stream_class->query_info = g_daemon_file_output_stream_query_info;
- file_stream_class->get_etag = g_daemon_file_output_stream_get_etag;
-}
-
-static void
-g_daemon_file_output_stream_init (GDaemonFileOutputStream *info)
-{
- info->output_buffer = g_string_new ("");
- info->input_buffer = g_string_new ("");
- info->seq_nr = 1;
-}
-
-GFileOutputStream *
-g_daemon_file_output_stream_new (int fd,
- gboolean can_seek,
- goffset initial_offset)
-{
- GDaemonFileOutputStream *stream;
-
- stream = g_object_new (G_TYPE_DAEMON_FILE_OUTPUT_STREAM, NULL);
-
- stream->command_stream = g_unix_output_stream_new (fd, FALSE);
- stream->data_stream = g_unix_input_stream_new (fd, TRUE);
- stream->can_seek = can_seek;
- stream->current_offset = initial_offset;
-
- return G_FILE_OUTPUT_STREAM (stream);
-}
-
-static gboolean
-error_is_cancel (GError *error)
-{
- return error != NULL &&
- error->domain == G_IO_ERROR &&
- error->code == G_IO_ERROR_CANCELLED;
-}
-
-static void
-append_request (GDaemonFileOutputStream *stream, guint32 command,
- guint32 arg1, guint32 arg2, guint32 data_len, guint32 *seq_nr)
-{
- GVfsDaemonSocketProtocolRequest cmd;
-
- g_assert (sizeof (cmd) == G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE);
-
- if (seq_nr)
- *seq_nr = stream->seq_nr;
-
- cmd.command = g_htonl (command);
- cmd.seq_nr = g_htonl (stream->seq_nr++);
- cmd.arg1 = g_htonl (arg1);
- cmd.arg2 = g_htonl (arg2);
- cmd.data_len = g_htonl (data_len);
-
- g_string_append_len (stream->output_buffer,
- (char *)&cmd, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE);
-}
-
-static gsize
-get_reply_header_missing_bytes (GString *buffer)
-{
- GVfsDaemonSocketProtocolReply *reply;
- guint32 type;
- guint32 arg2;
-
- if (buffer->len < G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE)
- return G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE - buffer->len;
-
- reply = (GVfsDaemonSocketProtocolReply *)buffer->str;
-
- type = g_ntohl (reply->type);
- arg2 = g_ntohl (reply->arg2);
-
- /* ERROR and CLOSED has extra data w/ len in arg2 */
- if (type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR ||
- type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_CLOSED)
- return G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE + arg2 - buffer->len;
- return 0;
-}
-
-static char *
-decode_reply (GString *buffer, GVfsDaemonSocketProtocolReply *reply_out)
-{
- GVfsDaemonSocketProtocolReply *reply;
- reply = (GVfsDaemonSocketProtocolReply *)buffer->str;
- reply_out->type = g_ntohl (reply->type);
- reply_out->seq_nr = g_ntohl (reply->seq_nr);
- reply_out->arg1 = g_ntohl (reply->arg1);
- reply_out->arg2 = g_ntohl (reply->arg2);
-
- return buffer->str + G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE;
-}
-
-static void
-decode_error (GVfsDaemonSocketProtocolReply *reply, char *data, GError **error)
-{
- g_set_error_literal (error,
- g_quark_from_string (data),
- reply->arg1,
- data + strlen (data) + 1);
-}
-
-
-static gboolean
-run_sync_state_machine (GDaemonFileOutputStream *file,
- state_machine_iterator iterator,
- gpointer data,
- GCancellable *cancellable,
- GError **error)
-{
- gssize res;
- StateOp io_op;
- IOOperationData io_data;
- GError *io_error;
-
- memset (&io_data, 0, sizeof (io_data));
-
- while (TRUE)
- {
- if (cancellable)
- io_data.cancelled = g_cancellable_is_cancelled (cancellable);
-
- io_op = iterator (file, &io_data, data);
-
- if (io_op == STATE_OP_DONE)
- return TRUE;
-
- io_error = NULL;
- if (io_op == STATE_OP_READ)
- {
- res = g_input_stream_read (file->data_stream,
- io_data.io_buffer, io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else if (io_op == STATE_OP_SKIP)
- {
- res = g_input_stream_skip (file->data_stream,
- io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else if (io_op == STATE_OP_WRITE)
- {
- res = g_output_stream_write (file->command_stream,
- io_data.io_buffer, io_data.io_size,
- io_data.io_allow_cancel ? cancellable : NULL,
- &io_error);
- }
- else
- {
- res = 0;
- g_assert_not_reached ();
- }
-
- if (res == -1)
- {
- if (error_is_cancel (io_error))
- {
- io_data.io_res = 0;
- io_data.io_cancelled = TRUE;
- g_error_free (io_error);
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), io_error->message);
- g_error_free (io_error);
- return FALSE;
- }
- }
- else if (res == 0 && io_data.io_size != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), _("End of stream"));
- return FALSE;
- }
- else
- {
- io_data.io_res = res;
- io_data.io_cancelled = FALSE;
- }
- }
-}
-
-/* read cycle:
-
- if we know of a (partially read) matching outstanding block, read from it
- create packet, append to outgoing
- flush outgoing
- start processing output, looking for a data block with same seek gen,
- or an error with same seq nr
- on cancel, send cancel command and go back to loop
- */
-
-static StateOp
-iterate_write_state_machine (GDaemonFileOutputStream *file, IOOperationData *io_op, WriteOperation *op)
-{
- gsize len;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case WRITE_STATE_INIT:
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_WRITE,
- op->buffer_size, 0, op->buffer_size, &op->seq_nr);
- op->state = WRITE_STATE_WROTE_COMMAND;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case WRITE_STATE_WROTE_COMMAND:
- if (io_op->io_cancelled)
- {
- op->ret_val = -1;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->buffer_pos = 0;
- if (op->sent_cancel)
- op->state = WRITE_STATE_HANDLE_INPUT;
- else
- op->state = WRITE_STATE_SEND_DATA;
- break;
-
- /* No op */
- case WRITE_STATE_SEND_DATA:
- op->buffer_pos += io_op->io_res;
-
- if (op->buffer_pos < op->buffer_size)
- {
- io_op->io_buffer = (char *)(op->buffer + op->buffer_pos);
- io_op->io_size = op->buffer_size - op->buffer_pos;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- op->state = WRITE_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case WRITE_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, 0, NULL);
- op->state = WRITE_STATE_WROTE_COMMAND;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = -1;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_WRITTEN)
- {
- op->ret_val = reply.arg1;
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = WRITE_STATE_HANDLE_INPUT;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
-
- }
-}
-
-static gssize
-g_daemon_file_output_stream_write (GOutputStream *stream,
- const void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileOutputStream *file;
- WriteOperation op;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return -1;
-
- /* Limit for sanity and to avoid 32bit overflow */
- if (count > MAX_WRITE_SIZE)
- count = MAX_WRITE_SIZE;
-
- memset (&op, 0, sizeof (op));
- op.state = WRITE_STATE_INIT;
- op.buffer = buffer;
- op.buffer_size = count;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_write_state_machine,
- &op, cancellable, error))
- return -1; /* IO Error */
-
- if (op.ret_val == -1)
- g_propagate_error (error, op.ret_error);
- else
- file->current_offset += op.ret_val;
-
- return op.ret_val;
-}
-
-static StateOp
-iterate_close_state_machine (GDaemonFileOutputStream *file, IOOperationData *io_op, CloseOperation *op)
-{
- gsize len;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case CLOSE_STATE_INIT:
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CLOSE,
- 0, 0, 0, &op->seq_nr);
- op->state = CLOSE_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case CLOSE_STATE_WROTE_REQUEST:
- if (io_op->io_cancelled)
- {
- op->ret_val = FALSE;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case CLOSE_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, 0, NULL);
- op->state = CLOSE_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = FALSE;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_CLOSED)
- {
- op->ret_val = TRUE;
- if (reply.arg2 > 0)
- file->etag = g_strndup (data, reply.arg2);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = CLOSE_STATE_HANDLE_INPUT;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
- }
-}
-
-
-static gboolean
-g_daemon_file_output_stream_close (GOutputStream *stream,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileOutputStream *file;
- CloseOperation op;
- gboolean res;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- /* We need to do a full roundtrip to guarantee that the writes have
- reached the disk. */
-
- memset (&op, 0, sizeof (op));
- op.state = CLOSE_STATE_INIT;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_close_state_machine,
- &op, cancellable, error))
- res = FALSE;
- else
- {
- if (!op.ret_val)
- g_propagate_error (error, op.ret_error);
- res = op.ret_val;
- }
-
- /* Return the first error, but close all streams */
- if (res)
- res = g_output_stream_close (file->command_stream, cancellable, error);
- else
- g_output_stream_close (file->command_stream, cancellable, NULL);
-
- if (res)
- res = g_input_stream_close (file->data_stream, cancellable, error);
- else
- g_input_stream_close (file->data_stream, cancellable, NULL);
-
- return res;
-}
-
-static goffset
-g_daemon_file_output_stream_tell (GFileOutputStream *stream)
-{
- GDaemonFileOutputStream *file;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- return file->current_offset;
-}
-
-static gboolean
-g_daemon_file_output_stream_can_seek (GFileOutputStream *stream)
-{
- GDaemonFileOutputStream *file;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- return file->can_seek;
-}
-
-static StateOp
-iterate_seek_state_machine (GDaemonFileOutputStream *file, IOOperationData *io_op, SeekOperation *op)
-{
- gsize len;
- guint32 request;
-
- while (TRUE)
- {
- switch (op->state)
- {
- /* Initial state for read op */
- case SEEK_STATE_INIT:
- request = G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_SET;
- if (op->seek_type == G_SEEK_CUR)
- op->offset = file->current_offset + op->offset;
- else if (op->seek_type == G_SEEK_END)
- request = G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_END;
- append_request (file, request,
- op->offset & 0xffffffff,
- op->offset >> 32,
- 0,
- &op->seq_nr);
- op->state = SEEK_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = TRUE; /* Allow cancel before first byte of request sent */
- return STATE_OP_WRITE;
-
- /* wrote parts of output_buffer */
- case SEEK_STATE_WROTE_REQUEST:
- if (io_op->io_cancelled)
- {
- op->ret_val = -1;
- g_set_error_literal (&op->ret_error,
- G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return STATE_OP_DONE;
- }
-
- if (io_op->io_res < file->output_buffer->len)
- {
- memcpy (file->output_buffer->str,
- file->output_buffer->str + io_op->io_res,
- file->output_buffer->len - io_op->io_res);
- g_string_truncate (file->output_buffer,
- file->output_buffer->len - io_op->io_res);
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
- g_string_truncate (file->output_buffer, 0);
-
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
-
- /* No op */
- case SEEK_STATE_HANDLE_INPUT:
- if (io_op->cancelled && !op->sent_cancel)
- {
- op->sent_cancel = TRUE;
- append_request (file, G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL,
- op->seq_nr, 0, 0, NULL);
- op->state = SEEK_STATE_WROTE_REQUEST;
- io_op->io_buffer = file->output_buffer->str;
- io_op->io_size = file->output_buffer->len;
- io_op->io_allow_cancel = FALSE;
- return STATE_OP_WRITE;
- }
-
- if (io_op->io_res > 0)
- {
- gsize unread_size = io_op->io_size - io_op->io_res;
- g_string_set_size (file->input_buffer,
- file->input_buffer->len - unread_size);
- }
-
- len = get_reply_header_missing_bytes (file->input_buffer);
- if (len > 0)
- {
- gsize current_len = file->input_buffer->len;
- g_string_set_size (file->input_buffer,
- current_len + len);
- io_op->io_buffer = file->input_buffer->str + current_len;
- io_op->io_size = len;
- io_op->io_allow_cancel = !op->sent_cancel;
- return STATE_OP_READ;
- }
-
- /* Got full header */
-
- {
- GVfsDaemonSocketProtocolReply reply;
- char *data;
- data = decode_reply (file->input_buffer, &reply);
-
- if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_ERROR &&
- reply.seq_nr == op->seq_nr)
- {
- op->ret_val = FALSE;
- decode_error (&reply, data, &op->ret_error);
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- else if (reply.type == G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SEEK_POS)
- {
- op->ret_val = TRUE;
- op->ret_offset = ((goffset)reply.arg2) << 32 | (goffset)reply.arg1;
- g_string_truncate (file->input_buffer, 0);
- return STATE_OP_DONE;
- }
- /* Ignore other reply types */
- }
-
- g_string_truncate (file->input_buffer, 0);
-
- /* This wasn't interesting, read next reply */
- op->state = SEEK_STATE_HANDLE_INPUT;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Clear io_op between non-op state switches */
- io_op->io_size = 0;
- io_op->io_res = 0;
- io_op->io_cancelled = FALSE;
- }
-}
-
-static gboolean
-g_daemon_file_output_stream_seek (GFileOutputStream *stream,
- goffset offset,
- GSeekType type,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonFileOutputStream *file;
- SeekOperation op;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- if (!file->can_seek)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Seek not supported on stream"));
- return FALSE;
- }
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return FALSE;
-
- memset (&op, 0, sizeof (op));
- op.state = SEEK_STATE_INIT;
- op.offset = offset;
- op.seek_type = type;
-
- if (!run_sync_state_machine (file, (state_machine_iterator)iterate_seek_state_machine,
- &op, cancellable, error))
- return FALSE; /* IO Error */
-
- if (!op.ret_val)
- g_propagate_error (error, op.ret_error);
- else
- file->current_offset = op.ret_offset;
-
- return op.ret_val;
-}
-
-static char *
-g_daemon_file_output_stream_get_etag (GFileOutputStream *stream)
-{
- GDaemonFileOutputStream *file;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- return g_strdup (file->etag);
-}
-
-static GFileInfo *
-g_daemon_file_output_stream_query_info (GFileOutputStream *stream,
- char *attributes,
- GCancellable *cancellable,
- GError **error)
-{
-#if 0
- GDaemonFileOutputStream *file;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-#endif
-
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- _("Query info not supported on stream"));
-
- return NULL;
-}
-
-/************************************************************************
- * Async I/O Code *
- ************************************************************************/
-
-typedef struct AsyncIterator AsyncIterator;
-
-typedef void (*AsyncIteratorDone) (GOutputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer callback_data,
- GError *io_error);
-
-struct AsyncIterator {
- AsyncIteratorDone done_cb;
- GDaemonFileOutputStream *file;
- GCancellable *cancellable;
- IOOperationData io_data;
- state_machine_iterator iterator;
- gpointer iterator_data;
- int io_priority;
- GAsyncReadyCallback callback;
- gpointer callback_data;
-};
-
-static void async_iterate (AsyncIterator *iterator);
-
-static void
-async_iterator_done (AsyncIterator *iterator, GError *io_error)
-{
- iterator->done_cb (G_OUTPUT_STREAM (iterator->file),
- iterator->iterator_data,
- iterator->callback,
- iterator->callback_data,
- io_error);
-
- g_free (iterator);
-
-}
-
-static void
-async_op_handle (AsyncIterator *iterator,
- gssize res,
- GError *io_error)
-{
- IOOperationData *io_data = &iterator->io_data;
- GError *error;
-
- if (io_error != NULL)
- {
- if (error_is_cancel (io_error))
- {
- io_data->io_res = 0;
- io_data->io_cancelled = TRUE;
- }
- else
- {
- error = NULL;
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), io_error->message);
- async_iterator_done (iterator, error);
- g_error_free (error);
- return;
- }
- }
- else if (res == 0 && io_data->io_size != 0)
- {
- error = NULL;
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error in stream protocol: %s"), _("End of stream"));
- async_iterator_done (iterator, error);
- g_error_free (error);
- return;
- }
- else
- {
- io_data->io_res = res;
- io_data->io_cancelled = FALSE;
- }
-
- async_iterate (iterator);
-}
-
-static void
-async_read_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GInputStream *stream = G_INPUT_STREAM (source_object);
- gssize count_read;
- GError *error = NULL;
-
- count_read = g_input_stream_read_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, count_read, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_skip_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GInputStream *stream = G_INPUT_STREAM (source_object);
- gssize count_skipped;
- GError *error = NULL;
-
- count_skipped = g_input_stream_skip_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, count_skipped, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_write_op_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- gssize bytes_written;
- GError *error = NULL;
-
- bytes_written = g_output_stream_write_finish (stream, res, &error);
-
- async_op_handle ((AsyncIterator *)user_data, bytes_written, error);
- if (error)
- g_error_free (error);
-}
-
-static void
-async_iterate (AsyncIterator *iterator)
-{
- IOOperationData *io_data = &iterator->io_data;
- GDaemonFileOutputStream *file = iterator->file;
- StateOp io_op;
-
- io_data->cancelled =
- g_cancellable_is_cancelled (iterator->cancellable);
-
- io_op = iterator->iterator (file, io_data, iterator->iterator_data);
-
- if (io_op == STATE_OP_DONE)
- {
- async_iterator_done (iterator, NULL);
- return;
- }
-
- /* TODO: Handle allow_cancel... */
-
- if (io_op == STATE_OP_READ)
- {
- g_input_stream_read_async (file->data_stream,
- io_data->io_buffer, io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_read_op_callback, iterator);
- }
- else if (io_op == STATE_OP_SKIP)
- {
- g_input_stream_skip_async (file->data_stream,
- io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_skip_op_callback, iterator);
- }
- else if (io_op == STATE_OP_WRITE)
- {
- g_output_stream_write_async (file->command_stream,
- io_data->io_buffer, io_data->io_size,
- iterator->io_priority,
- io_data->io_allow_cancel ? iterator->cancellable : NULL,
- async_write_op_callback, iterator);
- }
- else
- g_assert_not_reached ();
-}
-
-static void
-run_async_state_machine (GDaemonFileOutputStream *file,
- state_machine_iterator iterator_cb,
- gpointer iterator_data,
- int io_priority,
- GAsyncReadyCallback callback,
- gpointer data,
- GCancellable *cancellable,
- AsyncIteratorDone done_cb)
-{
- AsyncIterator *iterator;
-
- iterator = g_new0 (AsyncIterator, 1);
- iterator->file = file;
- iterator->iterator = iterator_cb;
- iterator->iterator_data = iterator_data;
- iterator->io_priority = io_priority;
- iterator->cancellable = cancellable;
- iterator->callback = callback;
- iterator->callback_data = data;
- iterator->done_cb = done_cb;
-
- async_iterate (iterator);
-}
-
-static void
-async_write_done (GOutputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer user_data,
- GError *io_error)
-{
- GSimpleAsyncResult *simple;
- WriteOperation *op;
- gssize count_written;
- GError *error;
-
- op = op_data;
-
- if (io_error)
- {
- count_written = -1;
- error = io_error;
- }
- else
- {
- count_written = op->ret_val;
- error = op->ret_error;
- }
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_daemon_file_output_stream_write_async);
-
- g_simple_async_result_set_op_res_gssize (simple, count_written);
-
- if (count_written == -1)
- g_simple_async_result_set_from_error (simple, error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- if (op->ret_error)
- g_error_free (op->ret_error);
- g_free (op);
-}
-
-static void
-g_daemon_file_output_stream_write_async (GOutputStream *stream,
- const void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data)
-{
- GDaemonFileOutputStream *file;
- WriteOperation *op;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- /* Limit for sanity and to avoid 32bit overflow */
- if (count > MAX_WRITE_SIZE)
- count = MAX_WRITE_SIZE;
-
- op = g_new0 (WriteOperation, 1);
- op->state = WRITE_STATE_INIT;
- op->buffer = buffer;
- op->buffer_size = count;
-
- run_async_state_machine (file,
- (state_machine_iterator)iterate_write_state_machine,
- op,
- io_priority,
- callback, data,
- cancellable,
- async_write_done);
-}
-
-static gssize
-g_daemon_file_output_stream_write_finish (GOutputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- gssize nwritten;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- g_assert (g_simple_async_result_get_source_tag (simple) == g_daemon_file_output_stream_write_async);
-
- nwritten = g_simple_async_result_get_op_res_gssize (simple);
- return nwritten;
-}
-
-static void
-async_close_done (GOutputStream *stream,
- gpointer op_data,
- GAsyncReadyCallback callback,
- gpointer user_data,
- GError *io_error)
-{
- GDaemonFileOutputStream *file;
- GSimpleAsyncResult *simple;
- CloseOperation *op;
- gboolean result;
- GError *error;
- GCancellable *cancellable = NULL; /* TODO: get cancellable */
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- op = op_data;
-
- if (io_error)
- {
- result = FALSE;
- error = io_error;
- }
- else
- {
- result = op->ret_val;
- error = op->ret_error;
- }
-
- if (result)
- result = g_output_stream_close (file->command_stream, cancellable, &error);
- else
- g_output_stream_close (file->command_stream, cancellable, NULL);
-
- if (result)
- result = g_input_stream_close (file->data_stream, cancellable, &error);
- else
- g_input_stream_close (file->data_stream, cancellable, NULL);
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_daemon_file_output_stream_close_async);
-
- if (!result)
- g_simple_async_result_set_from_error (simple, error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- if (op->ret_error)
- g_error_free (op->ret_error);
- g_free (op);
-}
-
-static void
-g_daemon_file_output_stream_close_async (GOutputStream *stream,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer data)
-{
- GDaemonFileOutputStream *file;
- CloseOperation *op;
-
- file = G_DAEMON_FILE_OUTPUT_STREAM (stream);
-
- op = g_new0 (CloseOperation, 1);
- op->state = CLOSE_STATE_INIT;
-
- run_async_state_machine (file,
- (state_machine_iterator)iterate_close_state_machine,
- op, io_priority,
- (GAsyncReadyCallback)callback, data,
- cancellable,
- (AsyncIteratorDone)async_close_done);
-}
-
-static gboolean
-g_daemon_file_output_stream_close_finish (GOutputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- /* Failures handled in generic close_finish code */
- return TRUE;
-}
diff --git a/client/gdaemonfileoutputstream.h b/client/gdaemonfileoutputstream.h
deleted file mode 100644
index e609a48b..00000000
--- a/client/gdaemonfileoutputstream.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_FILE_OUTPUT_STREAM_H__
-#define __G_DAEMON_FILE_OUTPUT_STREAM_H__
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_FILE_OUTPUT_STREAM (g_daemon_file_output_stream_get_type ())
-#define G_DAEMON_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_FILE_OUTPUT_STREAM, GDaemonFileOutputStream))
-#define G_DAEMON_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_FILE_OUTPUT_STREAM, GDaemonFileOutputStreamClass))
-#define G_IS_DAEMON_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_FILE_OUTPUT_STREAM))
-#define G_IS_DAEMON_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_FILE_OUTPUT_STREAM))
-#define G_DAEMON_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DAEMON_FILE_OUTPUT_STREAM, GDaemonFileOutputStreamClass))
-
-typedef struct _GDaemonFileOutputStream GDaemonFileOutputStream;
-typedef struct _GDaemonFileOutputStreamClass GDaemonFileOutputStreamClass;
-
-struct _GDaemonFileOutputStreamClass
-{
- GFileOutputStreamClass parent_class;
-};
-
-GType g_daemon_file_output_stream_get_type (void) G_GNUC_CONST;
-
-GFileOutputStream *g_daemon_file_output_stream_new (int fd,
- gboolean can_seek,
- goffset initial_offset);
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_FILE_OUTPUT_STREAM_H__ */
diff --git a/client/gdaemonmount.c b/client/gdaemonmount.c
deleted file mode 100644
index 43d8e181..00000000
--- a/client/gdaemonmount.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-#include "gdaemonvolumemonitor.h"
-#include "gdaemonmount.h"
-#include "gvfsdaemondbus.h"
-#include "gdaemonfile.h"
-#include "gvfsdaemonprotocol.h"
-#include "gdbusutils.h"
-
-/* Protects all fields of GDaemonMount that can change
- which at this point is just foreign_volume */
-G_LOCK_DEFINE_STATIC(daemon_mount);
-
-struct _GDaemonMount {
- GObject parent;
-
- GMountInfo *mount_info;
-
- GVolume *foreign_volume;
- GVolumeMonitor *volume_monitor;
-};
-
-static void g_daemon_mount_mount_iface_init (GMountIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GDaemonMount, g_daemon_mount, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
- g_daemon_mount_mount_iface_init))
-
-static void
-g_daemon_mount_finalize (GObject *object)
-{
- GDaemonMount *mount;
-
- mount = G_DAEMON_MOUNT (object);
-
- if (mount->foreign_volume != NULL)
- g_object_unref (mount->foreign_volume);
-
- if (mount->volume_monitor != NULL)
- g_object_remove_weak_pointer (G_OBJECT (mount->volume_monitor), (gpointer) &(mount->volume_monitor));
-
- g_mount_info_unref (mount->mount_info);
-
- if (G_OBJECT_CLASS (g_daemon_mount_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_mount_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_mount_class_init (GDaemonMountClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = g_daemon_mount_finalize;
-}
-
-static void
-g_daemon_mount_init (GDaemonMount *daemon_mount)
-{
-}
-
-GDaemonMount *
-g_daemon_mount_new (GMountInfo *mount_info,
- GVolumeMonitor *volume_monitor)
-{
- GDaemonMount *mount;
-
- mount = g_object_new (G_TYPE_DAEMON_MOUNT, NULL);
- mount->mount_info = g_mount_info_ref (mount_info);
- mount->volume_monitor = volume_monitor;
- g_object_set_data (G_OBJECT (mount), "g-stable-name", (gpointer) mount_info->stable_name);
- if (mount->volume_monitor != NULL)
- g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(mount->volume_monitor));
-
- return mount;
-}
-
-GMountInfo *
-g_daemon_mount_get_mount_info (GDaemonMount *mount)
-{
- return mount->mount_info;
-}
-
-static GFile *
-g_daemon_mount_get_root (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
-
- return g_daemon_file_new (daemon_mount->mount_info->mount_spec, "/");
-}
-
-static GIcon *
-g_daemon_mount_get_icon (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
-
- return g_themed_icon_new_with_default_fallbacks (daemon_mount->mount_info->icon);
-}
-
-static char *
-g_daemon_mount_get_name (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
-
- return g_strdup (daemon_mount->mount_info->display_name);
-}
-
-static char *
-g_daemon_mount_get_uuid (GMount *mount)
-{
- return NULL;
-}
-
-static GVolume *
-g_daemon_mount_get_volume (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- if (daemon_mount->foreign_volume != NULL)
- return g_object_ref (daemon_mount->foreign_volume);
- return NULL;
-}
-
-static GDrive *
-g_daemon_mount_get_drive (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- GDrive *drive;
-
- G_LOCK (daemon_mount);
- drive = NULL;
- if (daemon_mount->foreign_volume != NULL)
- drive = g_volume_get_drive (daemon_mount->foreign_volume);
- G_UNLOCK (daemon_mount);
- return drive;
-}
-
-static gboolean
-g_daemon_mount_can_unmount (GMount *mount)
-{
- return TRUE;
-}
-
-static gboolean
-g_daemon_mount_can_eject (GMount *mount)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- gboolean res;
-
- G_LOCK (daemon_mount);
- res = FALSE;
- if (daemon_mount->foreign_volume != NULL)
- res = g_volume_can_eject (daemon_mount->foreign_volume);
- G_UNLOCK (daemon_mount);
-
- return res;
-}
-
-static void
-foreign_volume_removed (GVolume *volume, gpointer user_data)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (user_data);
-
- G_LOCK (daemon_mount);
-
- g_object_ref (daemon_mount);
-
- if (daemon_mount->foreign_volume == volume)
- {
- g_object_unref (daemon_mount->foreign_volume);
- daemon_mount->foreign_volume = NULL;
- }
-
- G_UNLOCK (daemon_mount);
-
- g_signal_emit_by_name (daemon_mount, "changed");
- if (daemon_mount->volume_monitor != NULL)
- g_signal_emit_by_name (daemon_mount->volume_monitor, "mount_changed", daemon_mount);
-
- g_object_unref (daemon_mount);
-}
-
-void
-g_daemon_mount_set_foreign_volume (GDaemonMount *mount,
- GVolume *foreign_volume)
-{
- G_LOCK (daemon_mount);
-
- if (mount->foreign_volume != NULL)
- g_object_unref (mount->foreign_volume);
-
- if (foreign_volume != NULL)
- {
- mount->foreign_volume = foreign_volume;
- g_signal_connect_object (foreign_volume, "removed", (GCallback) foreign_volume_removed, mount, 0);
- }
- else
- mount->foreign_volume = NULL;
-
- G_UNLOCK (daemon_mount);
-}
-
-static void
-unmount_reply (DBusMessage *reply,
- DBusConnection *connection,
- GError *io_error,
- gpointer _data)
-{
- GSimpleAsyncResult *result = _data;
-
- if (io_error != NULL)
- g_simple_async_result_set_from_error (result, io_error);
-
- g_simple_async_result_complete (result);
- g_object_unref (result);
-}
-
-static void
-g_daemon_mount_unmount (GMount *mount,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- DBusMessage *message;
- GMountInfo *mount_info;
- GSimpleAsyncResult *res;
- guint32 dbus_flags;
-
- mount_info = daemon_mount->mount_info;
-
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- G_VFS_DBUS_MOUNT_OP_UNMOUNT);
-
- dbus_flags = flags;
- _g_dbus_message_append_args (message, DBUS_TYPE_UINT32, &dbus_flags, 0);
-
- res = g_simple_async_result_new (G_OBJECT (mount),
- callback, user_data,
- g_daemon_mount_unmount);
-
- _g_vfs_daemon_call_async (message,
- unmount_reply, res,
- cancellable);
-
- dbus_message_unref (message);
-}
-
-static gboolean
-g_daemon_mount_unmount_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return TRUE;
-}
-
-typedef struct {
- GObject *object;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} EjectWrapperOp;
-
-static void
-eject_wrapper_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- EjectWrapperOp *data = user_data;
- data->callback (data->object, res, data->user_data);
- g_free (data);
-}
-
-static void
-g_daemon_mount_eject (GMount *mount,
- GMountUnmountFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- GDrive *drive;
-
- G_LOCK (daemon_mount);
-
- drive = NULL;
- if (daemon_mount->foreign_volume != NULL)
- drive = g_volume_get_drive (G_VOLUME (daemon_mount->foreign_volume));
-
- G_UNLOCK (daemon_mount);
-
- if (drive != NULL)
- {
- EjectWrapperOp *data;
- data = g_new0 (EjectWrapperOp, 1);
- data->object = G_OBJECT (mount);
- data->callback = callback;
- data->user_data = user_data;
- g_drive_eject (drive, flags, cancellable, eject_wrapper_callback, data);
- g_object_unref (drive);
- }
-}
-
-static gboolean
-g_daemon_mount_eject_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- GDrive *drive;
- gboolean res;
-
- res = TRUE;
-
- G_LOCK (daemon_mount);
-
- drive = NULL;
- if (daemon_mount->foreign_volume != NULL)
- drive = g_volume_get_drive (G_VOLUME (daemon_mount->foreign_volume));
-
- G_UNLOCK (daemon_mount);
-
- if (drive != NULL)
- {
- res = g_drive_eject_finish (drive, result, error);
- g_object_unref (drive);
- }
-
- return res;
-}
-
-static char **
-g_daemon_mount_guess_content_type_sync (GMount *mount,
- gboolean force_rescan,
- GCancellable *cancellable,
- GError **error)
-{
- GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- char **result;
-
- result = NULL;
- G_LOCK (daemon_mount);
- if (daemon_mount->mount_info->x_content_types != NULL &&
- strlen (daemon_mount->mount_info->x_content_types) > 0)
- result = g_strsplit (daemon_mount->mount_info->x_content_types, " ", 0);
- G_UNLOCK (daemon_mount);
-
- return result;
-}
-
-static void
-g_daemon_mount_guess_content_type (GMount *mount,
- gboolean force_rescan,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new (G_OBJECT (mount),
- callback,
- user_data,
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static char **
-g_daemon_mount_guess_content_type_finish (GMount *mount,
- GAsyncResult *result,
- GError **error)
-{
- return g_daemon_mount_guess_content_type_sync (mount, FALSE, NULL, error);
-}
-
-static void
-g_daemon_mount_mount_iface_init (GMountIface *iface)
-{
- iface->get_root = g_daemon_mount_get_root;
- iface->get_name = g_daemon_mount_get_name;
- iface->get_icon = g_daemon_mount_get_icon;
- iface->get_uuid = g_daemon_mount_get_uuid;
- iface->get_volume = g_daemon_mount_get_volume;
- iface->get_drive = g_daemon_mount_get_drive;
- iface->can_unmount = g_daemon_mount_can_unmount;
- iface->can_eject = g_daemon_mount_can_eject;
- iface->unmount = g_daemon_mount_unmount;
- iface->unmount_finish = g_daemon_mount_unmount_finish;
- iface->eject = g_daemon_mount_eject;
- iface->eject_finish = g_daemon_mount_eject_finish;
- iface->guess_content_type = g_daemon_mount_guess_content_type;
- iface->guess_content_type_finish = g_daemon_mount_guess_content_type_finish;
- iface->guess_content_type_sync = g_daemon_mount_guess_content_type_sync;
-}
diff --git a/client/gdaemonmount.h b/client/gdaemonmount.h
deleted file mode 100644
index bf4ba099..00000000
--- a/client/gdaemonmount.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_MOUNT_H__
-#define __G_DAEMON_MOUNT_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-#include "gdaemonvfs.h"
-#include "gdaemonvolumemonitor.h"
-#include "gmounttracker.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_MOUNT (g_daemon_mount_get_type ())
-#define G_DAEMON_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_MOUNT, GDaemonMount))
-#define G_DAEMON_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_MOUNT, GDaemonMountClass))
-#define G_IS_DAEMON_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_MOUNT))
-#define G_IS_DAEMON_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_MOUNT))
-
-typedef struct _GDaemonMountClass GDaemonMountClass;
-
-struct _GDaemonMountClass {
- GObjectClass parent_class;
-};
-
-GType g_daemon_mount_get_type (void) G_GNUC_CONST;
-
-GDaemonMount *g_daemon_mount_new (GMountInfo *mount_info,
- GVolumeMonitor *volume_monitor);
-
-GMountInfo *g_daemon_mount_get_mount_info (GDaemonMount *mount);
-
-void g_daemon_mount_set_foreign_volume (GDaemonMount *mount, GVolume *foreign_volume);
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_MOUNT_H__ */
diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c
deleted file mode 100644
index 7479bd82..00000000
--- a/client/gdaemonvfs.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-#include <string.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <dbus/dbus.h>
-#include "gdaemonvfs.h"
-#include "gvfsuriutils.h"
-#include "gdaemonfile.h"
-#include <gio/gio.h>
-#include <gvfsdaemonprotocol.h>
-#include <gmodule.h>
-#include "gvfsdaemondbus.h"
-#include "gdbusutils.h"
-#include "gmountspec.h"
-#include "gvfsurimapper.h"
-#include "gdaemonvolumemonitor.h"
-#include <glib/gi18n-lib.h>
-
-typedef struct {
- char *type;
- char *scheme;
- char **scheme_aliases;
- int default_port;
- gboolean host_is_inet;
-} MountableInfo;
-
-struct _GDaemonVfs
-{
- GVfs parent;
-
- DBusConnection *async_bus;
-
- GVfs *wrapped_vfs;
- GList *mount_cache;
-
- GHashTable *from_uri_hash;
- GHashTable *to_uri_hash;
-
- MountableInfo **mountable_info;
- char **supported_uri_schemes;
-};
-
-struct _GDaemonVfsClass
-{
- GVfsClass parent_class;
-};
-
-G_DEFINE_DYNAMIC_TYPE (GDaemonVfs, g_daemon_vfs, G_TYPE_VFS)
-
-static GDaemonVfs *the_vfs = NULL;
-
-G_LOCK_DEFINE_STATIC(mount_cache);
-
-
-static void fill_mountable_info (GDaemonVfs *vfs);
-
-static void
-g_daemon_vfs_finalize (GObject *object)
-{
- GDaemonVfs *vfs;
-
- vfs = G_DAEMON_VFS (object);
-
- if (vfs->from_uri_hash)
- g_hash_table_destroy (vfs->from_uri_hash);
-
- if (vfs->to_uri_hash)
- g_hash_table_destroy (vfs->to_uri_hash);
-
- g_strfreev (vfs->supported_uri_schemes);
-
- if (vfs->async_bus)
- {
- dbus_connection_close (vfs->async_bus);
- dbus_connection_unref (vfs->async_bus);
- }
-
- if (vfs->wrapped_vfs)
- g_object_unref (vfs->wrapped_vfs);
-
- /* must chain up */
- G_OBJECT_CLASS (g_daemon_vfs_parent_class)->finalize (object);
-}
-
-static MountableInfo *
-get_mountable_info_for_scheme (GDaemonVfs *vfs,
- const char *scheme)
-{
- MountableInfo *info;
- int i, j;
-
- if (vfs->mountable_info == NULL)
- return NULL;
-
- for (i = 0; vfs->mountable_info[i] != NULL; i++)
- {
- info = vfs->mountable_info[i];
-
- if (info->scheme != NULL && strcmp (info->scheme, scheme) == 0)
- return info;
-
- if (info->scheme_aliases != NULL)
- {
- for (j = 0; info->scheme_aliases[j] != NULL; j++)
- {
- if (strcmp (info->scheme_aliases[j], scheme) == 0)
- return info;
- }
- }
-
- }
-
- return NULL;
-}
-
-static MountableInfo *
-get_mountable_info_for_type (GDaemonVfs *vfs,
- const char *type)
-{
- MountableInfo *info;
- int i;
-
- if (vfs->mountable_info == NULL)
- return NULL;
-
- for (i = 0; vfs->mountable_info[i] != NULL; i++)
- {
- info = vfs->mountable_info[i];
-
- if (strcmp (info->type, type) == 0)
- return info;
- }
-
- return NULL;
-}
-
-static void
-str_tolower_inplace (char *str)
-{
- char *p = str;
-
- while (*p != 0)
- {
- *p = g_ascii_tolower (*p);
- p++;
- }
-
-}
-
-static gboolean
-get_mountspec_from_uri (GDaemonVfs *vfs,
- const char *uri,
- GMountSpec **spec_out,
- char **path_out)
-{
- GMountSpec *spec;
- char *path;
- GVfsUriMapper *mapper;
- char *scheme;
- GVfsUriMountInfo *info;
-
- scheme = g_uri_parse_scheme (uri);
- if (scheme == NULL)
- return FALSE;
-
- /* convert the scheme to lower case since g_uri_parse_scheme
- * doesn't do that and we compare with g_str_equal */
- str_tolower_inplace (scheme);
-
- spec = NULL;
- path = NULL;
-
- mapper = g_hash_table_lookup (vfs->from_uri_hash, scheme);
-
- if (mapper)
- {
- info = g_vfs_uri_mapper_from_uri (mapper, uri);
- if (info != NULL)
- {
- spec = g_mount_spec_new_from_data (info->keys, NULL);
- path = info->path;
- /* We took over ownership of info parts, custom free: */
- g_free (info);
- }
- }
-
- if (spec == NULL)
- {
- GDecodedUri *decoded;
- MountableInfo *mountable;
- char *type;
- int l;
-
- decoded = g_vfs_decode_uri (uri);
- if (decoded)
- {
- mountable = get_mountable_info_for_scheme (vfs, decoded->scheme);
-
- if (mountable)
- type = mountable->type;
- else
- type = decoded->scheme;
-
- spec = g_mount_spec_new (type);
-
- if (decoded->host && *decoded->host)
- {
- if (mountable && mountable->host_is_inet)
- {
- /* Convert hostname to lower case */
- str_tolower_inplace (decoded->host);
-
- /* Remove brackets aroung ipv6 addresses */
- l = strlen (decoded->host);
- if (decoded->host[0] == '[' &&
- decoded->host[l - 1] == ']')
- g_mount_spec_set_with_len (spec, "host", decoded->host+1, l - 2);
- else
- g_mount_spec_set (spec, "host", decoded->host);
- }
- else
- g_mount_spec_set (spec, "host", decoded->host);
- }
-
- if (decoded->userinfo && *decoded->userinfo)
- g_mount_spec_set (spec, "user", decoded->userinfo);
-
- if (decoded->port != -1 &&
- (mountable == NULL ||
- mountable->default_port == 0 ||
- mountable->default_port != decoded->port))
- {
- char *port = g_strdup_printf ("%d", decoded->port);
- g_mount_spec_set (spec, "port", port);
- g_free (port);
- }
-
- if (decoded->query && *decoded->query)
- g_mount_spec_set (spec, "query", decoded->query);
- if (decoded->fragment && *decoded->fragment)
- g_mount_spec_set (spec, "fragment", decoded->fragment);
-
- path = g_strdup (decoded->path);
-
- g_vfs_decoded_uri_free (decoded);
- }
- }
-
- g_free (scheme);
-
- if (spec == NULL)
- return FALSE;
-
- *spec_out = spec;
- *path_out = path;
-
- return TRUE;
-}
-
-static void
-g_daemon_vfs_init (GDaemonVfs *vfs)
-{
- GType *mappers;
- guint n_mappers;
- const char * const *schemes, * const *mount_types;
- GVfsUriMapper *mapper;
- GList *modules;
- int i;
-
- bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- vfs->async_bus = dbus_bus_get_private (DBUS_BUS_SESSION, NULL);
-
- if (vfs->async_bus == NULL)
- return; /* Not supported, return here and return false in vfs_is_active() */
-
- g_assert (the_vfs == NULL);
- the_vfs = vfs;
-
- if (g_thread_supported ())
- dbus_threads_init_default ();
-
- /* We disable SIGPIPE globally. This is sort of bad
- for s library to do since its a global resource.
- However, without this there is no way to be able
- to handle mount daemons dying without client apps
- crashing, which is much worse.
-
- I blame Unix, there really should be a portable
- way to do this on all unixes, but there isn't,
- even for somewhat modern ones like solaris.
- */
- signal (SIGPIPE, SIG_IGN);
-
- fill_mountable_info (vfs);
-
- vfs->wrapped_vfs = g_vfs_get_local ();
-
- dbus_connection_set_exit_on_disconnect (vfs->async_bus, FALSE);
-
- _g_dbus_connection_integrate_with_main (vfs->async_bus);
-
- modules = g_io_modules_load_all_in_directory (GVFS_MODULE_DIR);
-
- vfs->from_uri_hash = g_hash_table_new (g_str_hash, g_str_equal);
- vfs->to_uri_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- mappers = g_type_children (G_VFS_TYPE_URI_MAPPER, &n_mappers);
-
- for (i = 0; i < n_mappers; i++)
- {
- int j;
- mapper = g_object_new (mappers[i], NULL);
-
- schemes = g_vfs_uri_mapper_get_handled_schemes (mapper);
-
- for (j = 0; schemes != NULL && schemes[j] != NULL; j++)
- g_hash_table_insert (vfs->from_uri_hash, (char *)schemes[j], mapper);
-
- mount_types = g_vfs_uri_mapper_get_handled_mount_types (mapper);
- for (j = 0; mount_types != NULL && mount_types[j] != NULL; j++)
- g_hash_table_insert (vfs->to_uri_hash, (char *)mount_types[j], mapper);
- }
-
- /* The above should have ref:ed the modules anyway */
- g_list_foreach (modules, (GFunc)g_type_module_unuse, NULL);
- g_list_free (modules);
- g_free (mappers);
-}
-
-GDaemonVfs *
-g_daemon_vfs_new (void)
-{
- return g_object_new (G_TYPE_DAEMON_VFS, NULL);
-}
-
-static GFile *
-g_daemon_vfs_get_file_for_path (GVfs *vfs,
- const char *path)
-{
- /* TODO: detect fuse paths and convert to daemon vfs GFiles */
-
- return g_vfs_get_file_for_path (G_DAEMON_VFS (vfs)->wrapped_vfs, path);
-}
-
-static GFile *
-g_daemon_vfs_get_file_for_uri (GVfs *vfs,
- const char *uri)
-{
- GDaemonVfs *daemon_vfs;
- GFile *file;
- GMountSpec *spec;
- char *path;
-
- daemon_vfs = G_DAEMON_VFS (vfs);
-
- if (g_ascii_strncasecmp (uri, "file:", 5) == 0)
- {
- path = g_filename_from_uri (uri, NULL, NULL);
-
- if (path == NULL)
- /* Dummy file */
- return g_vfs_get_file_for_uri (G_DAEMON_VFS (vfs)->wrapped_vfs, uri);
-
- file = g_daemon_vfs_get_file_for_path (vfs, path);
- g_free (path);
- return file;
- }
-
- if (get_mountspec_from_uri (daemon_vfs, uri, &spec, &path))
- {
- file = g_daemon_file_new (spec, path);
- g_mount_spec_unref (spec);
- g_free (path);
- return file;
- }
-
- /* Dummy file */
- return g_vfs_get_file_for_uri (G_DAEMON_VFS (vfs)->wrapped_vfs, uri);
-}
-
-GMountSpec *
-_g_daemon_vfs_get_mount_spec_for_path (GMountSpec *spec,
- const char *path,
- const char *new_path)
-{
- const char *type;
- GVfsUriMapper *mapper;
- GMountSpec *new_spec;
-
- type = g_mount_spec_get_type (spec);
-
- if (type == NULL)
- return g_mount_spec_ref (spec);
-
- new_spec = NULL;
- mapper = g_hash_table_lookup (the_vfs->to_uri_hash, type);
- if (mapper)
- {
- GVfsUriMountInfo info, *new_info;
- info.keys = spec->items;
- info.path = (char *)path;
- new_info = g_vfs_uri_mapper_get_mount_info_for_path (mapper, &info, new_path);
- if (new_info != NULL)
- {
- new_spec = g_mount_spec_new_from_data (new_info->keys, NULL);
- /* We took over ownership of parts of new_info, custom free: */
- g_free (new_info->path);
- g_free (new_info);
- }
- }
-
- if (new_spec == NULL)
- new_spec = g_mount_spec_ref (spec);
-
- return new_spec;
-}
-
-char *
-_g_daemon_vfs_get_uri_for_mountspec (GMountSpec *spec,
- char *path,
- gboolean allow_utf8)
-{
- char *uri;
- const char *type;
- GVfsUriMapper *mapper;
-
- type = g_mount_spec_get_type (spec);
- if (type == NULL)
- {
- GString *string = g_string_new ("unknown://");
- if (path)
- g_string_append_uri_escaped (string,
- path,
- "!$&'()*+,;=:@/",
- allow_utf8);
-
- return g_string_free (string, FALSE);
- }
-
- uri = NULL;
- mapper = g_hash_table_lookup (the_vfs->to_uri_hash, type);
- if (mapper)
- {
- GVfsUriMountInfo info;
- info.keys = spec->items;
- info.path = path;
- uri = g_vfs_uri_mapper_to_uri (mapper, &info, allow_utf8);
- }
-
- if (uri == NULL)
- {
- GDecodedUri decoded;
- MountableInfo *mountable;
- const char *port;
- gboolean free_host;
-
- memset (&decoded, 0, sizeof (decoded));
- decoded.port = -1;
-
- mountable = get_mountable_info_for_type (the_vfs, type);
-
- if (mountable)
- decoded.scheme = mountable->scheme;
- else
- decoded.scheme = (char *)type;
- decoded.host = (char *)g_mount_spec_get (spec, "host");
- free_host = FALSE;
- if (mountable && mountable->host_is_inet && decoded.host != NULL && strchr (decoded.host, ':') != NULL)
- {
- free_host = TRUE;
- decoded.host = g_strconcat ("[", decoded.host, "]", NULL);
- }
-
- decoded.userinfo = (char *)g_mount_spec_get (spec, "user");
- port = g_mount_spec_get (spec, "port");
- if (port != NULL)
- decoded.port = atoi (port);
-
- if (path == NULL)
- decoded.path = "/";
- else
- decoded.path = path;
-
- decoded.query = (char *)g_mount_spec_get (spec, "query");
- decoded.fragment = (char *)g_mount_spec_get (spec, "fragment");
-
- uri = g_vfs_encode_uri (&decoded, FALSE);
-
- if (free_host)
- g_free (decoded.host);
- }
-
- return uri;
-}
-
-const char *
-_g_daemon_vfs_mountspec_get_uri_scheme (GMountSpec *spec)
-{
- const char *type, *scheme;
- GVfsUriMapper *mapper;
- MountableInfo *mountable;
-
- type = g_mount_spec_get_type (spec);
- mapper = g_hash_table_lookup (the_vfs->to_uri_hash, type);
-
- scheme = NULL;
- if (mapper)
- {
- GVfsUriMountInfo info;
-
- info.keys = spec->items;
- info.path = "/";
-
- scheme = g_vfs_uri_mapper_to_uri_scheme (mapper, &info);
- }
-
- if (scheme == NULL)
- {
- mountable = get_mountable_info_for_type (the_vfs, type);
- if (mountable)
- scheme = mountable->scheme;
- else
- scheme = type;
- }
-
- return scheme;
-}
-
-static int
-find_string (GPtrArray *array, const char *find_me)
-{
- int i;
-
- g_return_val_if_fail (find_me != NULL, -1);
-
- for (i = 0; i < array->len; ++i)
- {
- if (strcmp (g_ptr_array_index (array, i), find_me) == 0)
- return i;
- }
-
- return -1;
-}
-
-
-static void
-fill_mountable_info (GDaemonVfs *vfs)
-{
- DBusMessage *message, *reply;
- DBusError error;
- DBusMessageIter iter, array_iter, struct_iter;
- MountableInfo *info;
- GPtrArray *infos, *uri_schemes;
- gint i, count;
-
- message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTABLE_INFO);
-
- if (message == NULL)
- _g_dbus_oom ();
-
- dbus_message_set_auto_start (message, TRUE);
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (vfs->async_bus,
- message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- &error);
- dbus_message_unref (message);
-
- if (dbus_error_is_set (&error))
- {
- dbus_error_free (&error);
- return;
- }
-
- if (reply == NULL)
- _g_dbus_oom ();
-
- dbus_message_iter_init (reply, &iter);
-
- dbus_message_iter_recurse (&iter, &array_iter);
-
- infos = g_ptr_array_new ();
- uri_schemes = g_ptr_array_new ();
- count = 0;
- do
- {
- char *type, *scheme, **scheme_aliases;
- int scheme_aliases_len;
- gint32 default_port;
- dbus_bool_t host_is_inet;
-
- if (dbus_message_iter_get_arg_type (&array_iter) != DBUS_TYPE_STRUCT)
- break;
-
- dbus_message_iter_recurse (&array_iter, &struct_iter);
-
- if (!_g_dbus_message_iter_get_args (&struct_iter, NULL,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_STRING, &scheme,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &scheme_aliases, &scheme_aliases_len,
- DBUS_TYPE_INT32, &default_port,
- DBUS_TYPE_BOOLEAN, &host_is_inet,
- 0))
- break;
-
- info = g_new0 (MountableInfo, 1);
- info->type = g_strdup (type);
- if (*scheme != 0)
- {
- info->scheme = g_strdup (scheme);
- if (find_string (uri_schemes, scheme) == -1)
- g_ptr_array_add (uri_schemes, g_strdup (scheme));
- }
-
- if (scheme_aliases_len > 0)
- {
- info->scheme_aliases = g_new (char *, scheme_aliases_len + 1);
- for (i = 0; i < scheme_aliases_len; i++)
- {
- info->scheme_aliases[i] = g_strdup (scheme_aliases[i]);
- if (find_string (uri_schemes, scheme_aliases[i]) == -1)
- g_ptr_array_add (uri_schemes, g_strdup (scheme_aliases[i]));
- }
- info->scheme_aliases[scheme_aliases_len] = NULL;
- }
-
- info->default_port = default_port;
- info->host_is_inet = host_is_inet;
-
- g_ptr_array_add (infos, info);
-
- g_strfreev (scheme_aliases);
- }
- while (dbus_message_iter_next (&array_iter));
-
- dbus_message_unref (reply);
-
- g_ptr_array_add (uri_schemes, NULL);
- g_ptr_array_add (infos, NULL);
- vfs->mountable_info = (MountableInfo **)g_ptr_array_free (infos, FALSE);
- vfs->supported_uri_schemes = (char **)g_ptr_array_free (uri_schemes, FALSE);
-}
-
-
-static const gchar * const *
-g_daemon_vfs_get_supported_uri_schemes (GVfs *vfs)
-{
- return (const gchar * const *) G_DAEMON_VFS (vfs)->supported_uri_schemes;
-}
-
-static GMountInfo *
-lookup_mount_info_in_cache_locked (GMountSpec *spec,
- const char *path)
-{
- GMountInfo *info;
- GList *l;
-
- info = NULL;
- for (l = the_vfs->mount_cache; l != NULL; l = l->next)
- {
- GMountInfo *mount_info = l->data;
-
- if (g_mount_spec_match_with_path (mount_info->mount_spec, spec, path))
- {
- info = g_mount_info_ref (mount_info);
- break;
- }
- }
-
- return info;
-}
-
-static GMountInfo *
-lookup_mount_info_in_cache (GMountSpec *spec,
- const char *path)
-{
- GMountInfo *info;
-
- G_LOCK (mount_cache);
- info = lookup_mount_info_in_cache_locked (spec, path);
- G_UNLOCK (mount_cache);
-
- return info;
-}
-
-void
-_g_daemon_vfs_invalidate_dbus_id (const char *dbus_id)
-{
- GList *l, *next;
-
- G_LOCK (mount_cache);
- for (l = the_vfs->mount_cache; l != NULL; l = next)
- {
- GMountInfo *mount_info = l->data;
- next = l->next;
-
- if (strcmp (mount_info->dbus_id, dbus_id) == 0)
- {
- the_vfs->mount_cache = g_list_delete_link (the_vfs->mount_cache, l);
- g_mount_info_unref (mount_info);
- }
- }
-
- G_UNLOCK (mount_cache);
-}
-
-
-static GMountInfo *
-handler_lookup_mount_reply (DBusMessage *reply,
- GError **error)
-{
- DBusError derror;
- GMountInfo *info;
- DBusMessageIter iter;
- GList *l;
- gboolean in_cache;
-
-
- if (_g_error_from_message (reply, error))
- return NULL;
-
- dbus_error_init (&derror);
- dbus_message_iter_init (reply, &iter);
-
- info = g_mount_info_from_dbus (&iter);
- if (info == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error while getting mount info: %s"),
- "Invalid reply");
- return NULL;
- }
-
- G_LOCK (mount_cache);
-
- in_cache = FALSE;
- /* Already in cache from other thread? */
- for (l = the_vfs->mount_cache; l != NULL; l = l->next)
- {
- GMountInfo *cached_info = l->data;
-
- if (g_mount_info_equal (info, cached_info))
- {
- in_cache = TRUE;
- g_mount_info_unref (info);
- info = g_mount_info_ref (cached_info);
- break;
- }
- }
-
- /* No, lets add it to the cache */
- if (!in_cache)
- the_vfs->mount_cache = g_list_prepend (the_vfs->mount_cache, g_mount_info_ref (info));
-
- G_UNLOCK (mount_cache);
-
- return info;
-}
-
-typedef struct {
- GMountInfoLookupCallback callback;
- gpointer user_data;
-} GetMountInfoData;
-
-static void
-async_get_mount_info_response (DBusMessage *reply,
- GError *io_error,
- void *_data)
-{
- GetMountInfoData *data = _data;
- GMountInfo *info;
- GError *error;
-
- if (reply == NULL)
- data->callback (NULL, data->user_data, io_error);
- else
- {
- error = NULL;
- info = handler_lookup_mount_reply (reply, &error);
-
- data->callback (info, data->user_data, error);
-
- if (info)
- g_mount_info_unref (info);
-
- if (error)
- g_error_free (error);
- }
-
- g_free (data);
-}
-
-void
-_g_daemon_vfs_get_mount_info_async (GMountSpec *spec,
- const char *path,
- GMountInfoLookupCallback callback,
- gpointer user_data)
-{
- GMountInfo *info;
- GetMountInfoData *data;
- DBusMessage *message;
- DBusMessageIter iter;
-
- info = lookup_mount_info_in_cache (spec, path);
-
- if (info != NULL)
- {
- callback (info, user_data, NULL);
- g_mount_info_unref (info);
- return;
- }
-
- message =
- dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT);
- dbus_message_set_auto_start (message, TRUE);
-
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus_with_path (&iter, spec, path);
-
- data = g_new0 (GetMountInfoData, 1);
- data->callback = callback;
- data->user_data = user_data;
-
- _g_dbus_connection_call_async (the_vfs->async_bus, message, G_VFS_DBUS_TIMEOUT_MSECS,
- async_get_mount_info_response,
- data);
-
- dbus_message_unref (message);
-}
-
-
-GMountInfo *
-_g_daemon_vfs_get_mount_info_sync (GMountSpec *spec,
- const char *path,
- GError **error)
-{
- GMountInfo *info;
- DBusConnection *conn;
- DBusMessage *message, *reply;
- DBusMessageIter iter;
- DBusError derror;
-
- info = lookup_mount_info_in_cache (spec, path);
-
- if (info != NULL)
- return info;
-
- conn = _g_dbus_connection_get_sync (NULL, error);
- if (conn == NULL)
- return NULL;
-
- message =
- dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT);
- dbus_message_set_auto_start (message, TRUE);
-
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus_with_path (&iter, spec, path);
-
- dbus_error_init (&derror);
- reply = dbus_connection_send_with_reply_and_block (conn, message, -1, &derror);
- dbus_message_unref (message);
-
- if (!reply)
- {
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- return NULL;
- }
-
- info = handler_lookup_mount_reply (reply, error);
-
- dbus_message_unref (reply);
-
- return info;
-}
-
-static GFile *
-g_daemon_vfs_parse_name (GVfs *vfs,
- const char *parse_name)
-{
- GFile *file;
-
- if (g_path_is_absolute (parse_name) ||
- *parse_name == '~')
- {
- /* TODO: detect fuse paths and convert to daemon vfs GFiles ? */
- file = g_vfs_parse_name (G_DAEMON_VFS (vfs)->wrapped_vfs, parse_name);
- }
- else
- {
- file = g_daemon_vfs_get_file_for_uri (vfs, parse_name);
- }
-
- return file;
-}
-
-DBusConnection *
-_g_daemon_vfs_get_async_bus (void)
-{
- return the_vfs->async_bus;
-}
-
-static gboolean
-g_daemon_vfs_is_active (GVfs *vfs)
-{
- GDaemonVfs *daemon_vfs = G_DAEMON_VFS (vfs);
- return daemon_vfs->async_bus != NULL;
-}
-
-static void
-g_daemon_vfs_class_finalize (GDaemonVfsClass *klass)
-{
-}
-
-static void
-g_daemon_vfs_class_init (GDaemonVfsClass *class)
-{
- GObjectClass *object_class;
- GVfsClass *vfs_class;
-
- object_class = (GObjectClass *) class;
-
- g_daemon_vfs_parent_class = g_type_class_peek_parent (class);
-
- object_class->finalize = g_daemon_vfs_finalize;
-
- vfs_class = G_VFS_CLASS (class);
-
- vfs_class->is_active = g_daemon_vfs_is_active;
- vfs_class->get_file_for_path = g_daemon_vfs_get_file_for_path;
- vfs_class->get_file_for_uri = g_daemon_vfs_get_file_for_uri;
- vfs_class->get_supported_uri_schemes = g_daemon_vfs_get_supported_uri_schemes;
- vfs_class->parse_name = g_daemon_vfs_parse_name;
-}
-
-/* Module API */
-
-void g_vfs_uri_mapper_smb_register (GIOModule *module);
-void g_vfs_uri_mapper_http_register (GIOModule *module);
-void g_vfs_uri_mapper_sftp_register (GIOModule *module);
-
-void
-g_io_module_load (GIOModule *module)
-{
- /* This is so that system daemons can use gio
- * without spawning private dbus instances.
- * See bug 526454.
- */
- if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
- return;
-
- /* Make this module resident so that we ground the common
- * library. If that is unloaded we could get into all kinds
- * of strange situations. This is safe to do even if we loaded
- * some other common-using module first as all modules are loaded
- * before any are freed.
- */
- g_type_module_use (G_TYPE_MODULE (module));
-
- g_daemon_vfs_register_type (G_TYPE_MODULE (module));
- g_daemon_volume_monitor_register_types (G_TYPE_MODULE (module));
-
- g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
- G_TYPE_DAEMON_VFS,
- "gvfs",
- 10);
-
- g_vfs_uri_mapper_register (module);
- g_vfs_uri_mapper_smb_register (module);
- g_vfs_uri_mapper_http_register (module);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h
deleted file mode 100644
index 3b17b880..00000000
--- a/client/gdaemonvfs.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_VFS_H__
-#define __G_DAEMON_VFS_H__
-
-#include <gio/gio.h>
-#include <dbus/dbus.h>
-#include "gmountspec.h"
-#include "gmounttracker.h"
-#include "gvfsuriutils.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_VFS (g_daemon_vfs_get_type ())
-#define G_DAEMON_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_DAEMON_VFS, GDaemonVfs))
-#define G_DAEMON_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_DAEMON_VFS, GDaemonVfsClass))
-#define G_IS_DAEMON_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_DAEMON_VFS))
-#define G_IS_DAEMON_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_DAEMON_VFS))
-#define G_DAEMON_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_DAEMON_VFS, GDaemonVfsClass))
-
-typedef struct _GDaemonVfs GDaemonVfs;
-typedef struct _GDaemonVfsClass GDaemonVfsClass;
-
-typedef void (*GMountInfoLookupCallback) (GMountInfo *mount_info,
- gpointer data,
- GError *error);
-
-GType g_daemon_vfs_get_type (void);
-
-GDaemonVfs *g_daemon_vfs_new (void);
-
-char * _g_daemon_vfs_get_uri_for_mountspec (GMountSpec *spec,
- char *path,
- gboolean allow_utf8);
-const char * _g_daemon_vfs_mountspec_get_uri_scheme (GMountSpec *spec);
-void _g_daemon_vfs_get_mount_info_async (GMountSpec *spec,
- const char *path,
- GMountInfoLookupCallback callback,
- gpointer user_data);
-GMountInfo * _g_daemon_vfs_get_mount_info_sync (GMountSpec *spec,
- const char *path,
- GError **error);
-GMountSpec * _g_daemon_vfs_get_mount_spec_for_path (GMountSpec *spec,
- const char *path,
- const char *new_path);
-void _g_daemon_vfs_invalidate_dbus_id (const char *dbus_id);
-DBusConnection *_g_daemon_vfs_get_async_bus (void);
-
-
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_VFS_H__ */
diff --git a/client/gdaemonvolumemonitor.c b/client/gdaemonvolumemonitor.c
deleted file mode 100644
index e26bde09..00000000
--- a/client/gdaemonvolumemonitor.c
+++ /dev/null
@@ -1,329 +0,0 @@
-
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include "gdaemonvolumemonitor.h"
-#include "gdaemonmount.h"
-#include "gdaemonvfs.h"
-#include "gmounttracker.h"
-
-G_LOCK_DEFINE_STATIC(daemon_vm);
-
-static GDaemonVolumeMonitor *_the_daemon_volume_monitor;
-
-struct _GDaemonVolumeMonitor {
- GVolumeMonitor parent;
-
- GMountTracker *mount_tracker;
- GList *mounts;
-};
-
-G_DEFINE_DYNAMIC_TYPE (GDaemonVolumeMonitor, g_daemon_volume_monitor, G_TYPE_VOLUME_MONITOR)
-
-static GList *
-get_mounts (GVolumeMonitor *volume_monitor)
-{
- GDaemonVolumeMonitor *monitor;
- GList *l;
-
- G_LOCK (daemon_vm);
-
- monitor = G_DAEMON_VOLUME_MONITOR (volume_monitor);
-
- l = g_list_copy (monitor->mounts);
- g_list_foreach (l, (GFunc)g_object_ref, NULL);
-
- G_UNLOCK (daemon_vm);
-
- return l;
-}
-
-static GList *
-get_volumes (GVolumeMonitor *volume_monitor)
-{
- /* TODO: Can daemon mounts have volumes? */
- return NULL;
-}
-
-static GList *
-get_connected_drives (GVolumeMonitor *volume_monitor)
-{
- /* TODO: Can daemon mounts have drives? */
- return NULL;
-}
-
-static GVolume *
-get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
-{
- return NULL;
-}
-
-static GMount *
-get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
-{
- return NULL;
-}
-
-static GDaemonMount *
-find_mount_by_mount_info (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info)
-{
- GDaemonMount *found_mount = NULL;
- GList *l;
-
- for (l = daemon_monitor->mounts; l; l = g_list_next (l))
- {
- GDaemonMount *existing_mount = l->data;
- GMountInfo *existing_mount_info;
-
- existing_mount_info = g_daemon_mount_get_mount_info (existing_mount);
- if (g_mount_info_equal (mount_info, existing_mount_info))
- {
- found_mount = existing_mount;
- break;
- }
- }
-
- return found_mount;
-}
-
-GDaemonMount *
-g_daemon_volume_monitor_find_mount_by_mount_info (GMountInfo *mount_info)
-{
- GDaemonMount *daemon_mount;
-
- G_LOCK (daemon_vm);
-
- daemon_mount = NULL;
- if (_the_daemon_volume_monitor != NULL)
- {
- daemon_mount = find_mount_by_mount_info (_the_daemon_volume_monitor, mount_info);
-
- if (daemon_mount != NULL)
- g_object_ref (daemon_mount);
- }
-
- G_UNLOCK (daemon_vm);
-
- return daemon_mount;
-}
-
-static void
-mount_added (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info)
-{
- GDaemonMount *mount;
- GVolume *volume;
-
- G_LOCK (daemon_vm);
-
- mount = find_mount_by_mount_info (daemon_monitor, mount_info);
- if (mount)
- {
- g_warning (G_STRLOC ": Mount was added twice!");
-
- G_UNLOCK (daemon_vm);
- return;
- }
-
- if (mount_info->user_visible)
- {
- mount = g_daemon_mount_new (mount_info, G_VOLUME_MONITOR (daemon_monitor));
- volume = g_volume_monitor_adopt_orphan_mount (G_MOUNT (mount));
- if (volume != NULL)
- g_daemon_mount_set_foreign_volume (mount, volume);
- daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
-
- /* Ref for the signal emission, other ref is owned by volume monitor */
- g_object_ref (mount);
- }
-
- G_UNLOCK (daemon_vm);
-
- if (mount)
- {
- /* Emit signal outside lock */
- g_signal_emit_by_name (daemon_monitor, "mount_added", mount);
- g_object_unref (mount);
- }
-}
-
-static void
-mount_removed (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info)
-{
- GDaemonMount *mount;
-
- G_LOCK (daemon_vm);
-
- mount = find_mount_by_mount_info (daemon_monitor, mount_info);
- if (!mount)
- {
- if (mount_info->user_visible)
- g_warning (G_STRLOC ": An unknown mount was removed!");
-
- G_UNLOCK (daemon_vm);
- return;
- }
-
- daemon_monitor->mounts = g_list_remove (daemon_monitor->mounts, mount);
-
- G_UNLOCK (daemon_vm);
-
- g_signal_emit_by_name (daemon_monitor, "mount_removed", mount);
- g_signal_emit_by_name (mount, "unmounted");
-
- g_object_unref (mount);
-}
-
-static void
-g_daemon_volume_monitor_init (GDaemonVolumeMonitor *daemon_monitor)
-{
- GList *mounts, *l;
- GDaemonMount *mount;
- GMountInfo *info;
- GVolume *volume;
-
- _the_daemon_volume_monitor = daemon_monitor;
-
- daemon_monitor->mount_tracker = g_mount_tracker_new (_g_daemon_vfs_get_async_bus ());
-
- g_signal_connect_swapped (daemon_monitor->mount_tracker, "mounted",
- (GCallback) mount_added, daemon_monitor);
- g_signal_connect_swapped (daemon_monitor->mount_tracker, "unmounted",
- (GCallback) mount_removed, daemon_monitor);
-
- /* Initialize with current list */
- mounts = g_mount_tracker_list_mounts (daemon_monitor->mount_tracker);
-
- for (l = mounts; l != NULL; l = l->next) {
- info = l->data;
- if (info->user_visible)
- {
- mount = g_daemon_mount_new (info, G_VOLUME_MONITOR (daemon_monitor));
- volume = g_volume_monitor_adopt_orphan_mount (G_MOUNT (mount));
- if (volume != NULL)
- g_daemon_mount_set_foreign_volume (mount, volume);
- daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount);
- }
-
- g_mount_info_unref (info);
- }
-
- g_list_free (mounts);
-}
-
-static void
-g_daemon_volume_monitor_finalize (GObject *object)
-{
- GDaemonVolumeMonitor *monitor;
-
- monitor = G_DAEMON_VOLUME_MONITOR (object);
-
- g_signal_handlers_disconnect_by_func (monitor->mount_tracker, mount_added, monitor);
- g_signal_handlers_disconnect_by_func (monitor->mount_tracker, mount_removed, monitor);
-
- g_object_unref (monitor->mount_tracker);
-
- g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL);
- g_list_free (monitor->mounts);
-
- if (G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize) (object);
-}
-
-static void
-g_daemon_volume_monitor_dispose (GObject *object)
-{
- GDaemonVolumeMonitor *monitor;
-
- monitor = G_DAEMON_VOLUME_MONITOR (object);
-
- G_LOCK (daemon_vm);
- _the_daemon_volume_monitor = NULL;
- G_UNLOCK (daemon_vm);
-
- if (G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->dispose)
- (*G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->dispose) (object);
-}
-
-static void
-g_daemon_volume_monitor_class_finalize (GDaemonVolumeMonitorClass *klass)
-{
-}
-
-static gboolean
-is_supported (void)
-{
- GVfs *vfs;
- gboolean res;
-
- res = FALSE;
-
- /* Don't do anything if the default vfs is not DAEMON_VFS */
- vfs = g_vfs_get_default ();
-
- if (vfs != NULL && G_IS_DAEMON_VFS (vfs))
- res = TRUE;
-
- return res;
-}
-
-static void
-g_daemon_volume_monitor_class_init (GDaemonVolumeMonitorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
-
- gobject_class->finalize = g_daemon_volume_monitor_finalize;
- gobject_class->dispose = g_daemon_volume_monitor_dispose;
-
- monitor_class->is_supported = is_supported;
- monitor_class->get_mounts = get_mounts;
- monitor_class->get_volumes = get_volumes;
- monitor_class->get_connected_drives = get_connected_drives;
- monitor_class->get_volume_for_uuid = get_volume_for_uuid;
- monitor_class->get_mount_for_uuid = get_mount_for_uuid;
-}
-
-GVolumeMonitor *
-g_daemon_volume_monitor_new (void)
-{
- GDaemonVolumeMonitor *monitor;
-
- monitor = g_object_new (G_TYPE_DAEMON_VOLUME_MONITOR, NULL);
-
- return G_VOLUME_MONITOR (monitor);
-}
-
-void
-g_daemon_volume_monitor_register_types (GTypeModule *module)
-{
- g_daemon_volume_monitor_register_type (G_TYPE_MODULE (module));
- g_io_extension_point_implement (G_VOLUME_MONITOR_EXTENSION_POINT_NAME,
- G_TYPE_DAEMON_VOLUME_MONITOR,
- "gvfs",
- 0);
-}
diff --git a/client/gdaemonvolumemonitor.h b/client/gdaemonvolumemonitor.h
deleted file mode 100644
index 4019ca35..00000000
--- a/client/gdaemonvolumemonitor.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_DAEMON_VOLUME_MONITOR_H__
-#define __G_DAEMON_VOLUME_MONITOR_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-#include "gmounttracker.h"
-
-G_BEGIN_DECLS
-
-#define G_TYPE_DAEMON_VOLUME_MONITOR (g_daemon_volume_monitor_get_type ())
-#define G_DAEMON_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_VOLUME_MONITOR, GDaemonVolumeMonitor))
-#define G_DAEMON_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_VOLUME_MONITOR, GDaemonVolumeMonitorClass))
-#define G_IS_DAEMON_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_VOLUME_MONITOR))
-#define G_IS_DAEMON_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_VOLUME_MONITOR))
-
-typedef struct _GDaemonVolumeMonitor GDaemonVolumeMonitor;
-typedef struct _GDaemonVolumeMonitorClass GDaemonVolumeMonitorClass;
-
-/* Forward definitions */
-typedef struct _GDaemonMount GDaemonMount;
-typedef struct _GDaemonVolume GDaemonVolume;
-typedef struct _GDaemonDrive GDaemonDrive;
-
-struct _GDaemonVolumeMonitorClass {
- GVolumeMonitorClass parent_class;
-
-};
-
-GType g_daemon_volume_monitor_get_type (void) G_GNUC_CONST;
-void g_daemon_volume_monitor_register_types (GTypeModule *type_module);
-
-GVolumeMonitor *g_daemon_volume_monitor_new (void);
-
-GDaemonMount *g_daemon_volume_monitor_find_mount_by_mount_info (GMountInfo *mount_info);
-
-G_END_DECLS
-
-#endif /* __G_DAEMON_VOLUME_MONITOR_H__ */
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
deleted file mode 100644
index aabb8dea..00000000
--- a/client/gvfsdaemondbus.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <poll.h>
-
-#include <glib/gi18n-lib.h>
-
-#include <gio/gio.h>
-#include "gvfsdaemondbus.h"
-#include <gvfsdaemonprotocol.h>
-#include <gdaemonvfs.h>
-#include "gdbusutils.h"
-#include "gsysutils.h"
-
-/* Extra vfs-specific data for DBusConnections */
-typedef struct {
- int extra_fd;
- int extra_fd_count;
- char *async_dbus_id;
-
- /* Only used for async connections */
- GHashTable *outstanding_fds;
- GSource *extra_fd_source;
-} VfsConnectionData;
-
-static gint32 vfs_data_slot = -1;
-static GOnce once_init_dbus = G_ONCE_INIT;
-
-static GStaticPrivate local_connections = G_STATIC_PRIVATE_INIT;
-
-/* dbus id -> async connection */
-static GHashTable *async_map = NULL;
-G_LOCK_DEFINE_STATIC(async_map);
-
-/* dbus object path -> dbus message filter */
-static GHashTable *obj_path_map = NULL;
-G_LOCK_DEFINE_STATIC(obj_path_map);
-
-static void setup_async_fd_receive (VfsConnectionData *connection_data);
-static void invalidate_local_connection (const char *dbus_id,
- GError **error);
-
-
-GQuark
-_g_vfs_error_quark (void)
-{
- return g_quark_from_static_string ("g-vfs-error-quark");
-}
-
-static gpointer
-vfs_dbus_init (gpointer arg)
-{
- if (!dbus_connection_allocate_data_slot (&vfs_data_slot))
- g_error ("Unable to allocate data slot");
-
- return NULL;
-}
-
-/**************************************************************************
- * message filters for vfs dbus connections *
- *************************************************************************/
-
-typedef struct {
- DBusHandleMessageFunction callback;
- GObject *data;
-} PathMapEntry;
-
-void
-_g_dbus_register_vfs_filter (const char *obj_path,
- DBusHandleMessageFunction callback,
- GObject *data)
-{
- PathMapEntry * entry;
-
- G_LOCK (obj_path_map);
-
- if (obj_path_map == NULL)
- obj_path_map = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
-
- entry = g_new (PathMapEntry,1 );
- entry->callback = callback;
- entry->data = data;
-
- g_hash_table_insert (obj_path_map, g_strdup (obj_path), entry);
-
- G_UNLOCK (obj_path_map);
-}
-
-void
-_g_dbus_unregister_vfs_filter (const char *obj_path)
-{
- G_LOCK (obj_path_map);
-
- if (obj_path_map)
- g_hash_table_remove (obj_path_map, obj_path);
-
- G_UNLOCK (obj_path_map);
-}
-
-static DBusHandlerResult
-vfs_connection_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- PathMapEntry *entry;
- DBusHandlerResult res;
- DBusHandleMessageFunction callback;
- GObject *data;
- VfsConnectionData *connection_data;
- const char *path;
-
- callback = NULL;
- data = NULL;
-
- if (dbus_message_is_signal (message,
- DBUS_INTERFACE_LOCAL,
- "Disconnected"))
- {
- connection_data = dbus_connection_get_data (connection, vfs_data_slot);
- if (connection_data->async_dbus_id)
- {
- _g_daemon_vfs_invalidate_dbus_id (connection_data->async_dbus_id);
- G_LOCK (async_map);
- g_hash_table_remove (async_map, connection_data->async_dbus_id);
- G_UNLOCK (async_map);
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- path = dbus_message_get_path (message);
- G_LOCK (obj_path_map);
- if (obj_path_map && path)
- {
- entry = g_hash_table_lookup (obj_path_map,
- path);
-
- if (entry)
- {
- callback = entry->callback;
- data = g_object_ref (entry->data);
- }
- }
- G_UNLOCK (obj_path_map);
-
- res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (callback)
- {
- res = callback (connection, message, data);
- g_object_unref (data);
- }
-
- return res;
-}
-
-static void
-connection_data_free (gpointer p)
-{
- VfsConnectionData *data = p;
-
- if (data->extra_fd != -1)
- close (data->extra_fd);
-
- if (data->extra_fd_source)
- {
- g_source_destroy (data->extra_fd_source);
- g_source_unref (data->extra_fd_source);
- }
-
- if (data->outstanding_fds)
- g_hash_table_destroy (data->outstanding_fds);
-
- g_free (data->async_dbus_id);
-
- g_free (data);
-}
-
-static void
-vfs_connection_setup (DBusConnection *connection,
- int extra_fd,
- gboolean async)
-{
- VfsConnectionData *connection_data;
-
- connection_data = g_new0 (VfsConnectionData, 1);
- connection_data->extra_fd = extra_fd;
- connection_data->extra_fd_count = 0;
-
- if (async)
- setup_async_fd_receive (connection_data);
-
- if (!dbus_connection_set_data (connection, vfs_data_slot, connection_data, connection_data_free))
- _g_dbus_oom ();
-
- if (!dbus_connection_add_filter (connection, vfs_connection_filter, NULL, NULL))
- _g_dbus_oom ();
-}
-
-/**************************************************************************
- * Functions to get fds from vfs dbus connections *
- *************************************************************************/
-
-typedef struct {
- int fd;
- GetFdAsyncCallback callback;
- gpointer callback_data;
-} OutstandingFD;
-
-static void
-outstanding_fd_free (OutstandingFD *outstanding)
-{
- if (outstanding->fd != -1)
- close (outstanding->fd);
-
- g_free (outstanding);
-}
-
-static void
-async_connection_accept_new_fd (VfsConnectionData *data,
- GIOCondition condition,
- int fd)
-{
- int new_fd;
- int fd_id;
- OutstandingFD *outstanding_fd;
-
- if (condition & G_IO_HUP)
- {
- close (data->extra_fd);
- data->extra_fd = -1;
- g_source_destroy (data->extra_fd_source);
- g_source_unref (data->extra_fd_source);
- data->extra_fd_source = NULL;
- return;
- }
-
- fd_id = data->extra_fd_count;
- new_fd = _g_socket_receive_fd (data->extra_fd);
- if (new_fd != -1)
- {
- data->extra_fd_count++;
-
- outstanding_fd = g_hash_table_lookup (data->outstanding_fds, GINT_TO_POINTER (fd_id));
-
- if (outstanding_fd)
- {
- outstanding_fd->callback (new_fd, outstanding_fd->callback_data);
- g_hash_table_remove (data->outstanding_fds, GINT_TO_POINTER (fd_id));
- }
- else
- {
- outstanding_fd = g_new0 (OutstandingFD, 1);
- outstanding_fd->fd = new_fd;
- outstanding_fd->callback = NULL;
- outstanding_fd->callback_data = NULL;
- g_hash_table_insert (data->outstanding_fds,
- GINT_TO_POINTER (fd_id),
- outstanding_fd);
- }
- }
-}
-
-static void
-setup_async_fd_receive (VfsConnectionData *connection_data)
-{
- connection_data->outstanding_fds =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- (GDestroyNotify)outstanding_fd_free);
-
-
- connection_data->extra_fd_source =
- __g_fd_source_new (connection_data->extra_fd, POLLIN|POLLERR, NULL);
- g_source_set_callback (connection_data->extra_fd_source,
- (GSourceFunc)async_connection_accept_new_fd,
- connection_data, NULL);
- g_source_attach (connection_data->extra_fd_source, NULL);
-}
-
-int
-_g_dbus_connection_get_fd_sync (DBusConnection *connection,
- int fd_id)
-{
- VfsConnectionData *data;
- int fd;
-
- data = dbus_connection_get_data (connection, vfs_data_slot);
- g_assert (data != NULL);
-
- /* I don't think we can get reorders here, can we?
- * Its a sync per-thread connection after all
- */
- g_assert (fd_id == data->extra_fd_count);
-
- fd = _g_socket_receive_fd (data->extra_fd);
- if (fd != -1)
- data->extra_fd_count++;
-
- return fd;
-}
-
-void
-_g_dbus_connection_get_fd_async (DBusConnection *connection,
- int fd_id,
- GetFdAsyncCallback callback,
- gpointer callback_data)
-{
- VfsConnectionData *data;
- OutstandingFD *outstanding_fd;
- int fd;
-
- data = dbus_connection_get_data (connection, vfs_data_slot);
- g_assert (data != NULL);
-
- outstanding_fd = g_hash_table_lookup (data->outstanding_fds, GINT_TO_POINTER (fd_id));
-
- if (outstanding_fd)
- {
- fd = outstanding_fd->fd;
- outstanding_fd->fd = -1;
- g_hash_table_remove (data->outstanding_fds, GINT_TO_POINTER (fd_id));
- callback (fd, callback_data);
- }
- else
- {
- outstanding_fd = g_new0 (OutstandingFD, 1);
- outstanding_fd->fd = -1;
- outstanding_fd->callback = callback;
- outstanding_fd->callback_data = callback_data;
- g_hash_table_insert (data->outstanding_fds,
- GINT_TO_POINTER (fd_id),
- outstanding_fd);
- }
-}
-
-/*******************************************************************
- * Caching of async connections *
- *******************************************************************/
-
-
-static DBusConnection *
-get_connection_for_async (const char *dbus_id)
-{
- DBusConnection *connection;
-
- connection = NULL;
- G_LOCK (async_map);
- if (async_map != NULL)
- connection = g_hash_table_lookup (async_map, dbus_id);
- if (connection)
- dbus_connection_ref (connection);
- G_UNLOCK (async_map);
-
- return connection;
-}
-
-static void
-close_and_unref_connection (void *data)
-{
- DBusConnection *connection = data;
-
- dbus_connection_close (connection);
- dbus_connection_unref (connection);
-}
-
-static void
-set_connection_for_async (DBusConnection *connection, const char *dbus_id)
-{
- VfsConnectionData *data;
-
- G_LOCK (async_map);
- data = dbus_connection_get_data (connection, vfs_data_slot);
- data->async_dbus_id = g_strdup (dbus_id);
-
- if (async_map == NULL)
- async_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, close_and_unref_connection);
-
- g_hash_table_insert (async_map, g_strdup (dbus_id), connection);
- dbus_connection_ref (connection);
- G_UNLOCK (async_map);
-}
-
-/**************************************************************************
- * Asynchronous daemon calls *
- *************************************************************************/
-
-typedef struct {
- const char *dbus_id;
-
- DBusMessage *message;
- DBusConnection *connection;
- GCancellable *cancellable;
-
- GVfsAsyncDBusCallback callback;
- gpointer callback_data;
-
- GError *io_error;
- gulong cancelled_tag;
-} AsyncDBusCall;
-
-static void
-async_call_finish (AsyncDBusCall *async_call,
- DBusMessage *reply)
-{
- if (async_call->callback)
- async_call->callback (reply, async_call->connection,
- async_call->io_error,
- async_call->callback_data);
-
- if (async_call->connection)
- dbus_connection_unref (async_call->connection);
- dbus_message_unref (async_call->message);
- if (async_call->cancellable)
- g_object_unref (async_call->cancellable);
- if (async_call->io_error)
- g_error_free (async_call->io_error);
- g_free (async_call);
-}
-
-static void
-async_dbus_response (DBusMessage *reply,
- GError *error,
- gpointer data)
-{
- AsyncDBusCall *async_call = data;
-
- if (async_call->cancelled_tag)
- g_signal_handler_disconnect (async_call->cancellable,
- async_call->cancelled_tag);
-
- if (reply == NULL)
- async_call->io_error = g_error_copy (error);
-
- async_call_finish (async_call, reply);
-}
-
-typedef struct {
- DBusConnection *connection;
- dbus_uint32_t serial;
-} AsyncCallCancelData;
-
-static void
-async_call_cancel_data_free (gpointer _data)
-{
- AsyncCallCancelData *data = _data;
-
- dbus_connection_unref (data->connection);
- g_free (data);
-}
-
-/* Might be called on another thread */
-static void
-async_call_cancelled_cb (GCancellable *cancellable,
- gpointer _data)
-{
- AsyncCallCancelData *data = _data;
- DBusMessage *cancel_message;
-
- /* Send cancellation message, this just queues it, sending
- * will happen in mainloop */
- cancel_message = dbus_message_new_method_call (NULL,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_CANCEL);
- if (cancel_message != NULL)
- {
- if (dbus_message_append_args (cancel_message,
- DBUS_TYPE_UINT32, &data->serial,
- DBUS_TYPE_INVALID))
- dbus_connection_send (data->connection,
- cancel_message, NULL);
- dbus_message_unref (cancel_message);
- }
-}
-
-static void
-async_call_send (AsyncDBusCall *async_call)
-{
- AsyncCallCancelData *cancel_data;
-
- if (async_call->cancellable)
- {
- cancel_data = g_new0 (AsyncCallCancelData, 1);
- cancel_data->connection = dbus_connection_ref (async_call->connection);
- cancel_data->serial = dbus_message_get_serial (async_call->message);
- async_call->cancelled_tag =
- g_signal_connect_data (async_call->cancellable, "cancelled",
- (GCallback)async_call_cancelled_cb,
- cancel_data,
- (GClosureNotify)async_call_cancel_data_free,
- 0);
- }
-
- _g_dbus_connection_call_async (async_call->connection,
- async_call->message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- async_dbus_response,
- async_call);
-}
-
-static void
-async_get_connection_response (DBusMessage *reply,
- GError *error,
- void *data)
-{
- AsyncDBusCall *async_call = data;
- DBusError derror;
- char *address1, *address2;
- int extra_fd;
- DBusConnection *connection, *existing_connection;
-
- if (reply == NULL)
- {
- async_call->io_error = g_error_copy (error);
- async_call_finish (async_call, NULL);
- return;
- }
-
- dbus_error_init (&derror);
- if (!dbus_message_get_args (reply, &derror,
- DBUS_TYPE_STRING, &address1,
- DBUS_TYPE_STRING, &address2,
- DBUS_TYPE_INVALID))
- {
- _g_error_from_dbus (&derror, &async_call->io_error);
- dbus_error_free (&derror);
- async_call_finish (async_call, NULL);
- return;
- }
-
- /* I don't know of any way to do an async connect */
- error = NULL;
- extra_fd = _g_socket_connect (address2, &error);
- if (extra_fd == -1)
- {
- g_set_error (&async_call->io_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error connecting to daemon: %s"), error->message);
- g_error_free (error);
- async_call_finish (async_call, NULL);
- return;
- }
-
- /* Unfortunately dbus doesn't have an async open */
- dbus_error_init (&derror);
- connection = dbus_connection_open_private (address1, &derror);
- if (!connection)
- {
- close (extra_fd);
- dbus_message_unref (reply);
-
- g_set_error (&async_call->io_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- async_call_finish (async_call, NULL);
- return;
- }
-
- vfs_connection_setup (connection, extra_fd, TRUE);
-
- /* Maybe we already had a connection? This happens if we requested
- * the same owner several times in parallel.
- * If so, just drop this connection and use that.
- */
-
- existing_connection = get_connection_for_async (async_call->dbus_id);
- if (existing_connection != NULL)
- {
- async_call->connection = existing_connection;
- dbus_connection_close (connection);
- dbus_connection_unref (connection);
- }
- else
- {
- _g_dbus_connection_integrate_with_main (connection);
- set_connection_for_async (connection, async_call->dbus_id);
- async_call->connection = connection;
- }
-
- /* Maybe we were canceled while setting up connection, then
- * avoid doing the operation */
- if (g_cancellable_set_error_if_cancelled (async_call->cancellable, &async_call->io_error))
- {
- async_call_finish (async_call, NULL);
- return;
- }
-
- async_call_send (async_call);
-}
-
-static void
-open_connection_async (AsyncDBusCall *async_call)
-{
- DBusMessage *get_connection_message;
-
- get_connection_message = dbus_message_new_method_call (async_call->dbus_id,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_GET_CONNECTION);
-
- if (get_connection_message == NULL)
- _g_dbus_oom ();
-
-
- _g_dbus_connection_call_async (_g_daemon_vfs_get_async_bus (),
- get_connection_message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- async_get_connection_response,
- async_call);
-
- dbus_message_unref (get_connection_message);
-}
-
-void
-_g_vfs_daemon_call_async (DBusMessage *message,
- GVfsAsyncDBusCallback callback,
- gpointer callback_data,
- GCancellable *cancellable)
-{
- AsyncDBusCall *async_call;
-
- g_once (&once_init_dbus, vfs_dbus_init, NULL);
-
- async_call = g_new0 (AsyncDBusCall, 1);
- async_call->dbus_id = dbus_message_get_destination (message);
- async_call->message = dbus_message_ref (message);
- if (cancellable)
- async_call->cancellable = g_object_ref (cancellable);
- async_call->callback = callback;
- async_call->callback_data = callback_data;
-
- async_call->connection = get_connection_for_async (async_call->dbus_id);
- if (async_call->connection == NULL)
- open_connection_async (async_call);
- else
- async_call_send (async_call);
-}
-
-/**************************************************************************
- * Synchronous daemon calls *
- *************************************************************************/
-
-DBusMessage *
-_g_vfs_daemon_call_sync (DBusMessage *message,
- DBusConnection **connection_out,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- DBusError derror;
- DBusMessage *reply;
- DBusPendingCall *pending;
- int dbus_fd;
- int cancel_fd;
- gboolean sent_cancel;
- DBusMessage *cancel_message;
- dbus_uint32_t serial;
- gboolean handle_callbacks;
- const char *dbus_id = dbus_message_get_destination (message);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return NULL;
-
- connection = _g_dbus_connection_get_sync (dbus_id, error);
- if (connection == NULL)
- return NULL;
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return NULL;
-
- handle_callbacks = FALSE;
- if (callback_obj_path != NULL && callback != NULL)
- {
- struct DBusObjectPathVTable vtable = { NULL, callback };
- handle_callbacks = dbus_connection_register_object_path (connection,
- callback_obj_path,
- &vtable,
- callback_user_data);
- }
-
- reply = NULL;
- cancel_fd = g_cancellable_get_fd (cancellable);
- if (cancel_fd != -1 || handle_callbacks)
- {
- if (!dbus_connection_send_with_reply (connection, message,
- &pending,
- G_VFS_DBUS_TIMEOUT_MSECS))
- _g_dbus_oom ();
-
- if (pending == NULL ||
- !dbus_connection_get_is_connected (connection))
- {
- if (pending)
- dbus_pending_call_unref (pending);
- invalidate_local_connection (dbus_id, error);
- goto out;
- }
-
- /* Make sure the message is sent */
- dbus_connection_flush (connection);
-
- if (!dbus_connection_get_unix_fd (connection, &dbus_fd))
- {
- dbus_pending_call_unref (pending);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- "No fd");
- goto out;
- }
-
- sent_cancel = (cancel_fd == -1);
- while (!dbus_pending_call_get_completed (pending))
- {
- struct pollfd poll_fds[2];
- int poll_ret;
-
- do
- {
- poll_fds[0].events = POLLIN;
- poll_fds[0].fd = dbus_fd;
- poll_fds[1].events = POLLIN;
- poll_fds[1].fd = cancel_fd;
- poll_ret = poll (poll_fds, sent_cancel?1:2, -1);
- }
- while (poll_ret == -1 && errno == EINTR);
-
- if (poll_ret == -1)
- {
- dbus_pending_call_unref (pending);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- "poll error");
- goto out;
- }
-
- if (!sent_cancel && g_cancellable_is_cancelled (cancellable))
- {
- sent_cancel = TRUE;
- serial = dbus_message_get_serial (message);
- cancel_message =
- dbus_message_new_method_call (NULL,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_CANCEL);
- if (cancel_message != NULL)
- {
- if (dbus_message_append_args (cancel_message,
- DBUS_TYPE_UINT32, &serial,
- DBUS_TYPE_INVALID))
- {
- dbus_connection_send (connection, cancel_message, NULL);
- dbus_connection_flush (connection);
- }
-
- dbus_message_unref (cancel_message);
- }
- }
-
- if (poll_fds[0].revents != 0)
- {
- dbus_connection_read_write (connection,
- G_VFS_DBUS_TIMEOUT_MSECS);
-
- while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS)
- ;
- }
- }
-
- reply = dbus_pending_call_steal_reply (pending);
- dbus_pending_call_unref (pending);
- }
- else
- {
- dbus_error_init (&derror);
- reply = dbus_connection_send_with_reply_and_block (connection, message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- &derror);
- if (!reply)
- {
- if (dbus_error_has_name (&derror, DBUS_ERROR_NO_REPLY) &&
- !dbus_connection_get_is_connected (connection))
- {
- /* The mount for this connection died, we invalidate
- * the caches, and then caller needs to retry.
- */
-
- invalidate_local_connection (dbus_id, error);
- }
- else
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- goto out;
- }
- }
-
- if (connection_out)
- *connection_out = connection;
-
- out:
-
- if (handle_callbacks)
- dbus_connection_unregister_object_path (connection, callback_obj_path);
-
- if (reply != NULL && _g_error_from_message (reply, error))
- {
- dbus_message_unref (reply);
- return NULL;
- }
-
- return reply;
-}
-
-/*************************************************************************
- * get per-thread synchronous dbus connections *
- *************************************************************************/
-
-typedef struct {
- GHashTable *connections;
- DBusConnection *session_bus;
-} ThreadLocalConnections;
-
-static void
-free_mount_connection (DBusConnection *conn)
-{
- dbus_connection_close (conn);
- dbus_connection_unref (conn);
-}
-
-static void
-free_local_connections (ThreadLocalConnections *local)
-{
- g_hash_table_destroy (local->connections);
- if (local->session_bus)
- free_mount_connection (local->session_bus);
- g_free (local);
-}
-
-static void
-invalidate_local_connection (const char *dbus_id,
- GError **error)
-{
- ThreadLocalConnections *local;
-
- _g_daemon_vfs_invalidate_dbus_id (dbus_id);
-
- local = g_static_private_get (&local_connections);
- if (local)
- g_hash_table_remove (local->connections, dbus_id);
-
- g_set_error_literal (error,
- G_VFS_ERROR,
- G_VFS_ERROR_RETRY,
- "Cache invalid, retry (internally handled)");
-}
-
-DBusConnection *
-_g_dbus_connection_get_sync (const char *dbus_id,
- GError **error)
-{
- DBusConnection *bus;
- ThreadLocalConnections *local;
- GError *local_error;
- DBusConnection *connection;
- DBusMessage *message, *reply;
- DBusError derror;
- char *address1, *address2;
- int extra_fd;
-
- g_once (&once_init_dbus, vfs_dbus_init, NULL);
-
- local = g_static_private_get (&local_connections);
- if (local == NULL)
- {
- local = g_new0 (ThreadLocalConnections, 1);
- local->connections = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)free_mount_connection);
- g_static_private_set (&local_connections, local, (GDestroyNotify)free_local_connections);
- }
-
- if (dbus_id == NULL)
- {
- /* Session bus */
-
- if (local->session_bus)
- {
- if (dbus_connection_get_is_connected (local->session_bus))
- return local->session_bus;
-
- /* Session bus was disconnected, re-connect */
- local->session_bus = NULL;
- dbus_connection_unref (local->session_bus);
- }
- }
- else
- {
- /* Mount daemon connection */
-
- connection = g_hash_table_lookup (local->connections, dbus_id);
- if (connection != NULL)
- {
- if (!dbus_connection_get_is_connected (connection))
- {
- /* The mount for this connection died, we invalidate
- * the caches, and then caller needs to retry.
- */
-
- invalidate_local_connection (dbus_id, error);
- return NULL;
- }
-
- return connection;
- }
- }
-
- dbus_error_init (&derror);
-
- if (local->session_bus == NULL)
- {
- bus = dbus_bus_get_private (DBUS_BUS_SESSION, &derror);
- if (bus == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Couldn't get main dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- return NULL;
- }
-
- local->session_bus = bus;
-
- if (dbus_id == NULL)
- return bus; /* We actually wanted the session bus, so done */
- }
-
- message = dbus_message_new_method_call (dbus_id,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_GET_CONNECTION);
- reply = dbus_connection_send_with_reply_and_block (local->session_bus, message, -1,
- &derror);
- dbus_message_unref (message);
-
- if (!reply)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- return NULL;
- }
-
- if (_g_error_from_message (reply, error))
- return NULL;
-
- dbus_message_get_args (reply, NULL,
- DBUS_TYPE_STRING, &address1,
- DBUS_TYPE_STRING, &address2,
- DBUS_TYPE_INVALID);
-
- local_error = NULL;
- extra_fd = _g_socket_connect (address2, &local_error);
- if (extra_fd == -1)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error connecting to daemon: %s"), local_error->message);
- g_error_free (local_error);
- dbus_message_unref (reply);
- return NULL;
- }
-
- dbus_error_init (&derror);
- connection = dbus_connection_open_private (address1, &derror);
- if (!connection)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- derror.message);
- close (extra_fd);
- dbus_message_unref (reply);
- dbus_error_free (&derror);
- return NULL;
- }
- dbus_message_unref (reply);
-
- vfs_connection_setup (connection, extra_fd, FALSE);
-
- g_hash_table_insert (local->connections, g_strdup (dbus_id), connection);
-
- return connection;
-}
diff --git a/client/gvfsdaemondbus.h b/client/gvfsdaemondbus.h
deleted file mode 100644
index 7a132cdc..00000000
--- a/client/gvfsdaemondbus.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_VFS_DAEMON_DBUS_H__
-#define __G_VFS_DAEMON_DBUS_H__
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-/* Used for internal errors */
-GQuark _g_vfs_error_quark (void);
-#define G_VFS_ERROR _g_vfs_error_quark()
-
-typedef enum
-{
- G_VFS_ERROR_RETRY
-} GVfsError;
-
-
-typedef void (*GVfsAsyncDBusCallback) (DBusMessage *reply,
- DBusConnection *connection,
- GError *io_error,
- gpointer callback_data);
-typedef void (*GetFdAsyncCallback) (int fd,
- gpointer callback_data);
-
-void _g_dbus_register_vfs_filter (const char *obj_path,
- DBusHandleMessageFunction callback,
- GObject *data);
-void _g_dbus_unregister_vfs_filter (const char *obj_path);
-GList * _g_dbus_bus_list_names_with_prefix_sync (DBusConnection *connection,
- const char *prefix,
- DBusError *error);
-DBusConnection *_g_dbus_connection_get_sync (const char *dbus_id,
- GError **error);
-int _g_dbus_connection_get_fd_sync (DBusConnection *conn,
- int fd_id);
-void _g_dbus_connection_get_fd_async (DBusConnection *connection,
- int fd_id,
- GetFdAsyncCallback callback,
- gpointer callback_data);
-void _g_vfs_daemon_call_async (DBusMessage *message,
- GVfsAsyncDBusCallback callback,
- gpointer callback_data,
- GCancellable *cancellable);
-DBusMessage * _g_vfs_daemon_call_sync (DBusMessage *message,
- DBusConnection **connection_out,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- GCancellable *cancellable,
- GError **error);
-GFileInfo * _g_dbus_get_file_info (DBusMessageIter *iter,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __G_VFS_DAEMON_DBUS_H__ */
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
deleted file mode 100644
index ef3314c3..00000000
--- a/client/gvfsfusedaemon.c
+++ /dev/null
@@ -1,2207 +0,0 @@
-/* gvfsfusedaemon.c - FUSE file system mapping daemon for GVFS
- *
- * Copyright (C) 2007-2008 Hans Petter Jansson
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Hans Petter Jansson <hpj@novell.com>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/vfs.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <dbus/dbus.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib/gprintf.h>
-#include <gio/gio.h>
-
-#include <glib/gurifuncs.h>
-
-/* stuff from common/ */
-#include <gdaemonmount.h>
-#include <gvfsdaemonprotocol.h>
-#include <gdbusutils.h>
-
-#define FUSE_USE_VERSION 26
-#include <fuse.h>
-
-#define DEBUG_ENABLED 0
-
-#define GET_FILE_HANDLE(fi) ((gpointer) (fi)->fh)
-#define SET_FILE_HANDLE(fi, fh) ((fi)->fh = (guint64) (fh))
-
-typedef struct {
- time_t creation_time;
- char *name;
- GFile *root;
-} MountRecord;
-
-typedef enum {
- FILE_OP_NONE,
- FILE_OP_READ,
- FILE_OP_WRITE
-} FileOp;
-
-typedef struct {
- gint refcount;
-
- GMutex *mutex;
- gchar *path;
- FileOp op;
- gpointer stream;
- gint length;
- size_t pos;
-} FileHandle;
-
-static GThread *subthread = NULL;
-static GMainLoop *subthread_main_loop = NULL;
-static GVfs *gvfs = NULL;
-
-static GVolumeMonitor *volume_monitor = NULL;
-
-/* Contains pointers to MountRecord */
-static GList *mount_list = NULL;
-static GMutex *mount_list_mutex;
-
-static time_t daemon_creation_time;
-static uid_t daemon_uid;
-static gid_t daemon_gid;
-
-static GStaticMutex global_mutex = G_STATIC_MUTEX_INIT;
-static GHashTable *global_fh_table = NULL;
-
-/* ------- *
- * Helpers *
- * ------- */
-
-static void
-debug_print (const gchar *message, ...)
-{
-#if DEBUG_ENABLED
-
- static FILE *debug_fhd = NULL;
- va_list var_args;
- char *file;
-
- if (!debug_fhd)
- {
- file = g_build_filename (g_get_home_dir (), "vfs.debug", NULL);
- debug_fhd = fopen (file, "at");
- g_free (file);
- }
-
- if (!debug_fhd)
- return;
-
- va_start (var_args, message);
- g_vfprintf (debug_fhd, message, var_args);
- va_end (var_args);
-
- fflush (debug_fhd);
-
-#endif
-}
-
-typedef struct {
- gint gioerror;
- gint errno_value;
-} ErrorMap;
-
-static gint
-errno_from_error (GError *error)
-{
- gint i;
- static const ErrorMap error_map [] =
- {
- { G_IO_ERROR_FAILED, EIO },
- { G_IO_ERROR_NOT_FOUND, ENOENT },
- { G_IO_ERROR_EXISTS, EEXIST },
- { G_IO_ERROR_IS_DIRECTORY, EISDIR },
- { G_IO_ERROR_NOT_DIRECTORY, ENOTDIR },
- { G_IO_ERROR_NOT_EMPTY, ENOTEMPTY },
- { G_IO_ERROR_NOT_REGULAR_FILE, EIO },
- { G_IO_ERROR_NOT_SYMBOLIC_LINK, EIO },
- { G_IO_ERROR_NOT_MOUNTABLE_FILE, EIO },
- { G_IO_ERROR_FILENAME_TOO_LONG, ENAMETOOLONG },
- { G_IO_ERROR_INVALID_FILENAME, EIO },
- { G_IO_ERROR_TOO_MANY_LINKS, ELOOP },
- { G_IO_ERROR_NO_SPACE, ENOSPC },
- { G_IO_ERROR_INVALID_ARGUMENT, EINVAL },
- { G_IO_ERROR_PERMISSION_DENIED, EACCES },
- { G_IO_ERROR_NOT_SUPPORTED, ENOTSUP },
- { G_IO_ERROR_NOT_MOUNTED, EIO },
- { G_IO_ERROR_ALREADY_MOUNTED, EIO },
- { G_IO_ERROR_CLOSED, EIO },
- { G_IO_ERROR_CANCELLED, EIO },
- { G_IO_ERROR_PENDING, EIO },
- { G_IO_ERROR_READ_ONLY, EACCES },
- { G_IO_ERROR_CANT_CREATE_BACKUP, EIO },
- { G_IO_ERROR_WRONG_ETAG, EIO },
- { G_IO_ERROR_TIMED_OUT, EIO },
- { G_IO_ERROR_BUSY, EBUSY },
- { -1, -1 }
- };
-
- if (error->domain != G_IO_ERROR)
- return EIO;
-
- for (i = 0; error_map [i].gioerror >= 0; i++)
- {
- if (error_map [i].gioerror == error->code)
- break;
- }
-
- if (error_map [i].gioerror >= 0)
- return error_map [i].errno_value;
-
- return EIO;
-}
-
-static FileHandle *
-file_handle_new (const gchar *path)
-{
- FileHandle *file_handle;
-
- file_handle = g_new0 (FileHandle, 1);
- file_handle->refcount = 1;
- file_handle->mutex = g_mutex_new ();
- file_handle->op = FILE_OP_NONE;
- file_handle->path = g_strdup (path);
-
- return file_handle;
-}
-
-static FileHandle *
-file_handle_ref (FileHandle *file_handle)
-{
- g_atomic_int_inc (&file_handle->refcount);
- return file_handle;
-}
-
-static void
-file_handle_unref (FileHandle *file_handle)
-{
- if (g_atomic_int_dec_and_test (&file_handle->refcount))
- {
- g_static_mutex_lock (&global_mutex);
-
- /* Test again, since e.g. get_file_handle_for_path() might have
- * snatched the global mutex and revived the file handle between
- * g_atomic_int_dec_and_test() and us obtaining the lock. */
-
- if (g_atomic_int_get (&file_handle->refcount) == 0)
- g_hash_table_remove (global_fh_table, file_handle->path);
-
- g_static_mutex_unlock (&global_mutex);
- }
-}
-
-static void
-file_handle_close_stream (FileHandle *file_handle)
-{
- debug_print ("file_handle_close_stream\n");
- if (file_handle->stream)
- {
- switch (file_handle->op)
- {
- case FILE_OP_READ:
- g_input_stream_close (file_handle->stream, NULL, NULL);
- break;
-
- case FILE_OP_WRITE:
- g_output_stream_close (file_handle->stream, NULL, NULL);
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- g_object_unref (file_handle->stream);
- file_handle->stream = NULL;
- file_handle->op = FILE_OP_NONE;
- }
-}
-
-/* Called on hash table removal */
-static void
-file_handle_free (FileHandle *file_handle)
-{
- file_handle_close_stream (file_handle);
- g_mutex_free (file_handle->mutex);
- g_free (file_handle->path);
- g_free (file_handle);
-}
-
-static FileHandle *
-get_file_handle_for_path (const gchar *path)
-{
- FileHandle *fh;
-
- g_static_mutex_lock (&global_mutex);
-
- fh = g_hash_table_lookup (global_fh_table, path);
- if (fh)
- file_handle_ref (fh);
-
- g_static_mutex_unlock (&global_mutex);
-
- return fh;
-}
-
-static FileHandle *
-get_or_create_file_handle_for_path (const gchar *path)
-{
- FileHandle *fh;
-
- g_static_mutex_lock (&global_mutex);
-
- fh = g_hash_table_lookup (global_fh_table, path);
-
- if (fh)
- {
- file_handle_ref (fh);
- }
- else
- {
- fh = file_handle_new (path);
- g_hash_table_insert (global_fh_table, fh->path, fh);
- }
-
- g_static_mutex_unlock (&global_mutex);
-
- return fh;
-}
-
-static void
-reindex_file_handle_for_path (const gchar *old_path, const gchar *new_path)
-{
- gchar *old_path_internal;
- FileHandle *fh;
-
- g_static_mutex_lock (&global_mutex);
-
- if (!g_hash_table_lookup_extended (global_fh_table, old_path,
- (gpointer *) &old_path_internal,
- (gpointer *) &fh))
- goto out;
-
- g_hash_table_steal (global_fh_table, old_path);
-
- g_free (fh->path);
- fh->path = g_strdup (new_path);
-
- g_hash_table_insert (global_fh_table, fh->path, fh);
-
- out:
- g_static_mutex_unlock (&global_mutex);
-}
-
-static MountRecord *
-mount_record_new (GMount *mount)
-{
- MountRecord *mount_record;
- char *name;
-
- mount_record = g_new (MountRecord, 1);
-
- mount_record->root = g_mount_get_root (mount);
- name = g_object_get_data (G_OBJECT (mount), "g-stable-name");
- if (name != NULL && *name != 0)
- name = g_strdup (name);
- else
- name = g_mount_get_name (mount);
-
- /* Keep in sync with gvfs daemon mount tracker */
- mount_record->name = g_uri_escape_string (name, "+@#$., ", TRUE);
- g_free (name);
- mount_record->creation_time = time (NULL);
-
- return mount_record;
-}
-
-static void
-mount_record_free (MountRecord *mount_record)
-{
- g_object_unref (mount_record->root);
- g_free (mount_record->name);
- g_free (mount_record);
-}
-
-static void
-mount_list_lock (void)
-{
- g_mutex_lock (mount_list_mutex);
-}
-
-static void
-mount_list_unlock (void)
-{
- g_mutex_unlock (mount_list_mutex);
-}
-
-static void
-mount_list_free (void)
-{
- g_list_foreach (mount_list, (GFunc) mount_record_free, NULL);
- g_list_free (mount_list);
- mount_list = NULL;
-}
-
-static gboolean
-mount_record_for_mount_exists (GMount *mount)
-{
- GList *l;
- GFile *root;
- gboolean res;
-
- g_assert (mount != NULL);
-
- root = g_mount_get_root (mount);
-
- res = FALSE;
-
- mount_list_lock ();
-
- for (l = mount_list; l != NULL; l = l->next)
- {
- MountRecord *this_mount_record = l->data;
-
- if (g_file_equal (root, this_mount_record->root))
- {
- res = TRUE;
- break;
- }
- }
-
- mount_list_unlock ();
-
- g_object_unref (root);
-
- return res;
-}
-
-static GFile *
-mount_record_find_root_by_mount_name (const gchar *mount_name)
-{
- GList *l;
- GFile *root;
-
- g_assert (mount_name != NULL);
-
- root = NULL;
-
- mount_list_lock ();
-
- for (l = mount_list; l != NULL; l = l->next)
- {
- MountRecord *mount_record = l->data;
-
- if (strcmp (mount_name, mount_record->name) == 0)
- {
- root = g_object_ref (mount_record->root);
- break;
- }
- }
-
- mount_list_unlock ();
-
- return root;
-}
-
-static void
-mount_list_update (void)
-{
- GList *mounts;
- GList *l;
-
- mounts = g_volume_monitor_get_mounts (volume_monitor);
-
- for (l = mounts; l != NULL; l = l->next)
- {
- GMount *mount = l->data;
-
- if (!mount_record_for_mount_exists (mount))
- {
- mount_list_lock ();
- mount_list = g_list_prepend (mount_list, mount_record_new (mount));
- mount_list_unlock ();
- }
-
- g_object_unref (mount);
- }
-
- g_list_free (mounts);
-}
-
-#if 0
-
-static gint
-file_info_get_attribute_as_int (GFileInfo *file_info, const gchar *attribute)
-{
- GFileAttributeType attribute_type;
- gint int_result;
-
- attribute_type = g_file_info_get_attribute_type (file_info, attribute);
-
- switch (attribute_type)
- {
- case G_FILE_ATTRIBUTE_TYPE_UINT32:
- int_result = g_file_info_get_attribute_uint32 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_INT32:
- int_result = g_file_info_get_attribute_int32 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_UINT64:
- int_result = g_file_info_get_attribute_uint64 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_INT64:
- int_result = g_file_info_get_attribute_int64 (file_info, attribute);
- break;
-
- default:
- int_result = 0;
- g_assert_not_reached ();
- break;
- }
-
- return int_result;
-}
-
-#endif
-
-static guint
-file_info_get_attribute_as_uint (GFileInfo *file_info, const gchar *attribute)
-{
- GFileAttributeType attribute_type;
- guint uint_result;
-
- attribute_type = g_file_info_get_attribute_type (file_info, attribute);
-
- switch (attribute_type)
- {
- case G_FILE_ATTRIBUTE_TYPE_UINT32:
- uint_result = g_file_info_get_attribute_uint32 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_INT32:
- uint_result = g_file_info_get_attribute_int32 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_UINT64:
- uint_result = g_file_info_get_attribute_uint64 (file_info, attribute);
- break;
-
- case G_FILE_ATTRIBUTE_TYPE_INT64:
- uint_result = g_file_info_get_attribute_int64 (file_info, attribute);
- break;
-
- default:
- uint_result = 0;
- g_assert_not_reached ();
- break;
- }
-
- return uint_result;
-}
-
-static gboolean
-path_is_mount_list (const gchar *path)
-{
- while (*path == '/')
- path++;
-
- return *path == 0;
-}
-
-
-static GFile *
-file_from_full_path (const gchar *path)
-{
- gchar *mount_name;
- GFile *file = NULL;
- const gchar *s1, *s2;
- GFile *root;
-
- file = NULL;
-
- s1 = path;
- while (*s1 == '/')
- s1++;
-
- if (*s1)
- {
- s2 = strchr (s1, '/');
- if (s2 == NULL)
- s2 = s1 + strlen (s1);
-
- mount_name = g_strndup (s1, s2 - s1);
- root = mount_record_find_root_by_mount_name (mount_name);
- g_free (mount_name);
-
- if (root)
- {
- while (*s2 == '/')
- s2++;
- file = g_file_resolve_relative_path (root, s2);
- g_object_unref (root);
- }
- }
-
- return file;
-}
-
-/* ------------- *
- * VFS functions *
- * ------------- */
-
-#if 0
-
-/* A stat -f <path> on a FUSE mount always results in this function being called with a path
- * of '/'. This means we can't return valid info for the various mounts. Hopefully we can
- * fix this in the future. */
-
-static gint
-vfs_statfs (const gchar *path, struct statvfs *stbuf)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_statfs: %s\n", path);
-
- if ((file = file_from_full_path (path)))
- {
- GFileInfo *file_info;
-
- file_info = g_file_get_filesystem_info (file, "*", NULL, &error);
-
- if (file_info)
- {
- memset (stbuf, 0, sizeof (*stbuf));
-
- stbuf->f_bsize = 4096;
- stbuf->f_frsize = 4096; /* Ignored by FUSE */
- stbuf->f_blocks = 0;
- stbuf->f_bfree = 0;
- stbuf->f_bavail = 0;
- stbuf->f_files = 0;
- stbuf->f_ffree = 0;
- stbuf->f_favail = 0; /* Ignored by FUSE */
- stbuf->f_fsid = 1; /* Ignored by FUSE */
- stbuf->f_flag = 0; /* Ignored by FUSE */
- stbuf->f_namemax = 1024;
-
- if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE))
- stbuf->f_blocks = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE) / 4096;
- if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE))
- stbuf->f_bfree = stbuf->f_bavail = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE) / 4096;
- }
- else if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- result = -EIO;
- }
-
- g_object_unref (file);
- }
-
- debug_print ("vfs_statfs: -> %s\n", strerror (-result));
-
- return result;
-}
-
-#endif
-
-static gint
-vfs_statfs (const gchar *path, struct statvfs *stbuf)
-{
- gint result = 0;
-
- debug_print ("vfs_statfs: %s\n", path);
-
- memset (stbuf, 0, sizeof (*stbuf));
-
- stbuf->f_bsize = 4096;
- stbuf->f_frsize = 4096; /* Ignored by FUSE */
- stbuf->f_blocks = 0;
- stbuf->f_bfree = 0;
- stbuf->f_bavail = 0;
- stbuf->f_files = 0;
- stbuf->f_ffree = 0;
- stbuf->f_favail = 0; /* Ignored by FUSE */
- stbuf->f_fsid = 1; /* Ignored by FUSE */
- stbuf->f_flag = 0; /* Ignored by FUSE */
- stbuf->f_namemax = 1024;
-
- debug_print ("vfs_statfs: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static mode_t
-file_info_get_stat_mode (GFileInfo *file_info)
-{
- GFileType file_type;
- mode_t unix_mode;
-
- file_type = g_file_info_get_file_type (file_info);
-
- switch (file_type)
- {
- case G_FILE_TYPE_REGULAR:
- unix_mode = S_IFREG;
- break;
-
- case G_FILE_TYPE_DIRECTORY:
- case G_FILE_TYPE_MOUNTABLE:
- unix_mode = S_IFDIR;
- break;
-
- case G_FILE_TYPE_SYMBOLIC_LINK:
- case G_FILE_TYPE_SHORTCUT:
- unix_mode = S_IFLNK;
- break;
-
- case G_FILE_TYPE_SPECIAL:
- default:
- unix_mode = 0;
- break;
- }
-
- if (file_type == G_FILE_TYPE_DIRECTORY ||
- !g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ) ||
- g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
- unix_mode |= S_IRUSR;
- if (!g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) ||
- g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
- unix_mode |= S_IWUSR;
- if (file_type == G_FILE_TYPE_DIRECTORY ||
- !g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE) ||
- g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE))
- unix_mode |= S_IXUSR;
-
- return unix_mode;
-}
-
-static gint
-getattr_for_file (GFile *file, struct stat *sbuf)
-{
- GFileInfo *file_info;
- GError *error = NULL;
- gint result = 0;
-
- file_info = g_file_query_info (file, "*", 0, NULL, &error);
-
- if (file_info)
- {
- GTimeVal mod_time;
-
- sbuf->st_mode = file_info_get_stat_mode (file_info);
- sbuf->st_size = g_file_info_get_size (file_info);
- sbuf->st_uid = daemon_uid;
- sbuf->st_gid = daemon_gid;
-
- g_file_info_get_modification_time (file_info, &mod_time);
- sbuf->st_mtime = mod_time.tv_sec;
- sbuf->st_ctime = mod_time.tv_sec;
- sbuf->st_atime = mod_time.tv_sec;
-
- if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_TIME_CHANGED))
- sbuf->st_ctime = file_info_get_attribute_as_uint (file_info, G_FILE_ATTRIBUTE_TIME_CHANGED);
- if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_TIME_ACCESS))
- sbuf->st_atime = file_info_get_attribute_as_uint (file_info, G_FILE_ATTRIBUTE_TIME_ACCESS);
-
- /* Setting st_nlink to 1 for directories makes 'find' work */
- sbuf->st_nlink = 1;
-
- g_object_unref (file_info);
- }
- else
- {
- if (error)
- {
- debug_print ("Error from GVFS: %s\n", error->message);
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- debug_print ("No file info, but no error from GVFS.\n");
- result = -EIO;
- }
- }
-
- return result;
-}
-
-static gint
-vfs_getattr (const gchar *path, struct stat *sbuf)
-{
- GFile *file;
- gint result = 0;
- FileHandle *fh;
-
- debug_print ("vfs_getattr: %s\n", path);
-
- fh = get_file_handle_for_path (path);
- if (fh)
- g_mutex_lock (fh->mutex);
-
- memset (sbuf, 0, sizeof (*sbuf));
-
- sbuf->st_dev = 0; /* dev_t ID of device containing file */
- sbuf->st_ino = 0; /* ino_t inode number */
- sbuf->st_uid = 0; /* uid_t user ID of owner */
- sbuf->st_gid = 0; /* gid_t group ID of owner */
- sbuf->st_rdev = 0; /* dev_t device ID (if special file) */
- sbuf->st_size = 0; /* off_t total size, in bytes */
- sbuf->st_blocks = 0; /* blkcnt_t number of blocks allocated */
- sbuf->st_atime = 0; /* time_t time of last access */
- sbuf->st_mtime = 0; /* time_t time of last modification */
- sbuf->st_ctime = 0; /* time_t time of last status change */
- sbuf->st_blksize = 4096; /* blksize_t blocksize for filesystem I/O */
-
- if (path_is_mount_list (path))
- {
- /* Mount list */
-
- sbuf->st_mode = S_IFDIR | 0500; /* mode_t protection */
- sbuf->st_nlink = 2 + g_list_length (mount_list); /* nlink_t number of hard links */
- sbuf->st_atime = daemon_creation_time;
- sbuf->st_mtime = daemon_creation_time;
- sbuf->st_ctime = daemon_creation_time;
- sbuf->st_uid = daemon_uid;
- sbuf->st_gid = daemon_gid;
- }
- else if ((file = file_from_full_path (path)))
- {
- /* Submount */
-
- result = getattr_for_file (file, sbuf);
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- if (fh)
- {
- g_mutex_unlock (fh->mutex);
- file_handle_unref (fh);
- }
-
- debug_print ("vfs_getattr: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_readlink (const gchar *path, gchar *target, size_t size)
-{
- debug_print ("vfs_readlink: %s\n", path);
-
- return 0;
-}
-
-static gint
-setup_input_stream (GFile *file, FileHandle *fh)
-{
- GError *error = NULL;
- gint result = 0;
-
- if (fh->stream)
- {
- debug_print ("setup_input_stream: have stream\n");
-
- if (fh->op == FILE_OP_READ)
- {
- debug_print ("setup_input_stream: doing read\n");
- }
- else
- {
- debug_print ("setup_input_stream: doing write\n");
-
- g_output_stream_close (fh->stream, NULL, NULL);
- g_object_unref (fh->stream);
- fh->stream = NULL;
- }
- }
-
- if (!fh->stream)
- {
- debug_print ("setup_input_stream: no stream\n");
- fh->stream = g_file_read (file, NULL, &error);
- fh->pos = 0;
- }
-
- if (fh->stream)
- fh->op = FILE_OP_READ;
- else
- fh->op = FILE_OP_NONE;
-
- if (error)
- {
- debug_print ("setup_input_stream: error\n");
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- return result;
-}
-
-static gint
-setup_output_stream (GFile *file, FileHandle *fh)
-{
- GError *error = NULL;
- gint result = 0;
-
- if (fh->stream)
- {
- if (fh->op == FILE_OP_WRITE)
- {
- }
- else
- {
- g_input_stream_close (fh->stream, NULL, NULL);
- g_object_unref (fh->stream);
- fh->stream = NULL;
- }
- }
-
- if (!fh->stream)
- {
- fh->stream = g_file_append_to (file, 0, NULL, &error);
- if (fh->stream)
- fh->pos = g_seekable_tell (G_SEEKABLE (fh->stream));
- }
-
- if (fh->stream)
- fh->op = FILE_OP_WRITE;
- else
- fh->op = FILE_OP_NONE;
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- return result;
-}
-
-static gint
-vfs_open (const gchar *path, struct fuse_file_info *fi)
-{
- GFile *file;
- gint result = 0;
-
- debug_print ("vfs_open: %s\n", path);
-
- if (path_is_mount_list (path))
- result = -EISDIR;
- else if ((file = file_from_full_path (path)))
- {
- GFileInfo *file_info;
- GError *error = NULL;
-
- file_info = g_file_query_info (file, "*", 0, NULL, &error);
-
- if (file_info)
- {
- GFileType file_type = g_file_info_get_file_type (file_info);
-
- if (file_type == G_FILE_TYPE_REGULAR)
- {
- FileHandle *fh = get_or_create_file_handle_for_path (path);
-
- /* File exists */
-
- SET_FILE_HANDLE (fi, fh);
-
- debug_print ("vfs_open: flags=%o\n", fi->flags);
-
- /* Set up a stream here, so we can check for errors */
-
- g_mutex_lock (fh->mutex);
-
- if (fi->flags & O_WRONLY || fi->flags & O_RDWR)
- result = setup_output_stream (file, fh);
- else
- result = setup_input_stream (file, fh);
-
- g_mutex_unlock (fh->mutex);
-
- /* The added reference to the file handle is released in vfs_release() */
- }
- else if (file_type == G_FILE_TYPE_DIRECTORY)
- {
- /* EISDIR is supposedly only for attempts to write to directory handles,
- * but outside readdir(), we don't support reading them either. */
- result = -EISDIR;
- }
- else
- {
- result = -EACCES;
- }
-
- g_object_unref (file_info);
- }
- else
- {
- if (error)
- {
- debug_print ("Error from GVFS: %s\n", error->message);
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- debug_print ("No file info, but no error from GVFS.\n");
- result = -EIO;
- }
- }
-
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_open: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_create (const gchar *path, mode_t mode, struct fuse_file_info *fi)
-{
- GFile *file;
- gint result = 0;
-
- debug_print ("vfs_create: %s\n", path);
-
- if (path_is_mount_list (path))
- result = -EEXIST;
- if ((file = file_from_full_path (path)))
- {
- GFileInfo *file_info;
- GError *error = NULL;
-
- file_info = g_file_query_info (file, "*", 0, NULL, &error);
-
- if (file_info)
- {
- result = -EEXIST;
- g_object_unref (file_info);
- }
- else
- {
- GFileOutputStream *file_output_stream;
-
- if (error)
- {
- g_error_free (error);
- error = NULL;
- }
-
- file_output_stream = g_file_create (file, 0, NULL, &error);
- if (file_output_stream)
- {
- FileHandle *fh = get_or_create_file_handle_for_path (path);
-
- /* Success */
-
- SET_FILE_HANDLE (fi, fh);
-
- g_mutex_lock (fh->mutex);
-
- file_handle_close_stream (fh);
- fh->stream = file_output_stream;
- fh->op = FILE_OP_WRITE;
-
- g_mutex_unlock (fh->mutex);
-
- /* The added reference to the file handle is released in vfs_release() */
- }
- else
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
-
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_create: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_release (const gchar *path, struct fuse_file_info *fi)
-{
- FileHandle *fh = GET_FILE_HANDLE (fi);
-
- debug_print ("vfs_release: %s\n", path);
-
- if (fh)
- file_handle_unref (fh);
-
- return 0;
-}
-
-static gint
-read_stream (FileHandle *fh, gchar *output_buf, size_t output_buf_size, off_t offset)
-{
- GInputStream *input_stream;
- gint n_bytes_skipped = 0;
- gint n_bytes_read = 0;
- gint result = 0;
- GError *error = NULL;
-
- input_stream = fh->stream;
-
- if (offset != fh->pos)
- {
- if (g_seekable_can_seek (G_SEEKABLE (input_stream)))
- {
- /* Can seek */
-
- debug_print ("read_stream: seeking to offset %d.\n", offset);
-
- if (g_seekable_seek (G_SEEKABLE (input_stream), offset, G_SEEK_SET, NULL, &error))
- {
- fh->pos = offset;
- }
- else
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- else if (offset > fh->pos)
- {
- /* Can skip ahead */
-
- debug_print ("read_stream: skipping to offset %d.\n", offset);
-
- n_bytes_skipped = g_input_stream_skip (input_stream, offset - fh->pos, NULL, &error);
-
- if (n_bytes_skipped > 0)
- fh->pos += n_bytes_skipped;
-
- if (n_bytes_skipped != offset - fh->pos)
- {
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- result = -EIO;
- }
- }
- }
- else
- {
- /* Can't seek, can't skip backwards */
-
- debug_print ("read_stream: can't seek nor skip to offset %d!\n", offset);
-
- result = -ENOTSUP;
- }
- }
-
- if (result == 0)
- {
- while (n_bytes_read < output_buf_size)
- {
- gboolean part_result;
- gsize part_bytes_read = 0;
-
- part_result = g_input_stream_read_all (input_stream,
- output_buf + n_bytes_read,
- output_buf_size - n_bytes_read,
- &part_bytes_read,
- NULL,
- &error);
-
- n_bytes_read += part_bytes_read;
- fh->pos += part_bytes_read;
-
- if (!part_result || part_bytes_read == 0)
- break;
- }
-
- result = n_bytes_read;
-
- if (n_bytes_read < output_buf_size)
- {
- debug_print ("read_stream: wanted %d bytes, but got %d.\n", output_buf_size, n_bytes_read);
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- }
-
- return result;
-}
-
-static gint
-vfs_read (const gchar *path, gchar *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
-{
- GFile *file;
- gint result = 0;
-
- debug_print ("vfs_read: %s\n", path);
-
- if ((file = file_from_full_path (path)))
- {
- FileHandle *fh = GET_FILE_HANDLE (fi);
-
- g_mutex_lock (fh->mutex);
-
- result = setup_input_stream (file, fh);
-
- if (result == 0)
- {
- result = read_stream (fh, buf, size, offset);
- }
- else
- {
- debug_print ("vfs_read: failed to setup input_stream!\n");
- }
-
- g_object_unref (file);
- g_mutex_unlock (fh->mutex);
- }
- else
- {
- result = -EIO;
- }
-
- if (result < 0)
- debug_print ("vfs_read: -> %s\n", strerror (-result));
- else
- debug_print ("vfs_read: -> %d bytes read.\n", result);
-
- return result;
-}
-
-static gint
-write_stream (FileHandle *fh, const gchar *input_buf, size_t input_buf_size, off_t offset)
-{
- GOutputStream *output_stream;
- gint n_bytes_written = 0;
- gint result = 0;
- GError *error = NULL;
-
- debug_print ("write_stream: %d bytes at offset %d.\n", input_buf_size, offset);
-
- output_stream = fh->stream;
-
- if (offset != fh->pos)
- {
- if (g_seekable_can_seek (G_SEEKABLE (output_stream)))
- {
- /* Can seek */
-
- if (g_seekable_seek (G_SEEKABLE (output_stream), offset, G_SEEK_SET, NULL, &error))
- {
- fh->pos = offset;
- }
- else
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- else
- {
- /* Can't seek, and output streams can't skip */
-
- result = -ENOTSUP;
- }
- }
-
- if (result == 0)
- {
- while (n_bytes_written < input_buf_size)
- {
- gboolean part_result;
- gsize part_bytes_written = 0;
-
- part_result = g_output_stream_write_all (output_stream,
- (void *) (input_buf + n_bytes_written),
- input_buf_size - n_bytes_written,
- &part_bytes_written,
- NULL,
- &error);
-
- n_bytes_written += part_bytes_written;
- fh->pos += part_bytes_written;
-
- if (!part_result)
- break;
- }
-
- result = n_bytes_written;
-
- if (n_bytes_written < input_buf_size)
- {
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- else if (!g_output_stream_flush (output_stream, NULL, &error))
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
-
- return result;
-}
-
-static gint
-vfs_write (const gchar *path, const gchar *buf, size_t len, off_t offset,
- struct fuse_file_info *fi)
-{
- GFile *file;
- gint result = 0;
-
- debug_print ("vfs_write: %s\n", path);
-
- if ((file = file_from_full_path (path)))
- {
- FileHandle *fh = GET_FILE_HANDLE (fi);
-
- g_mutex_lock (fh->mutex);
-
- result = setup_output_stream (file, fh);
- if (result == 0)
- {
- result = write_stream (fh, buf, len, offset);
- }
-
- g_object_unref (file);
- g_mutex_unlock (fh->mutex);
- }
- else
- {
- result = -EIO;
- }
-
- if (result < 0)
- debug_print ("vfs_write: -> %s\n", strerror (-result));
- else
- debug_print ("vfs_write: -> %d bytes written.\n", result);
-
- return result;
-}
-
-static gint
-vfs_flush (const gchar *path, struct fuse_file_info *fi)
-{
- debug_print ("vfs_flush: %s\n", path);
-
- return 0;
-}
-
-static gint
-vfs_opendir (const gchar *path, struct fuse_file_info *fi)
-{
- GFile *file;
- gint result = 0;
-
- debug_print ("vfs_opendir: %s\n", path);
-
- if (path_is_mount_list (path))
- {
- /* Mount list */
- }
- else if ((file = file_from_full_path (path)) != NULL)
- {
- /* Submount */
-
- /* TODO: Check that path exists */
-
- g_object_unref (file);
- }
- else
- {
- /* Not found */
-
- result = -ENOENT;
- }
-
- return result;
-}
-
-static gint
-readdir_for_file (GFile *base_file, gpointer buf, fuse_fill_dir_t filler)
-{
- GFileEnumerator *enumerator;
- GFileInfo *file_info;
- GError *error = NULL;
-
- g_assert (base_file != NULL);
-
- enumerator = g_file_enumerate_children (base_file, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
- if (!enumerator)
- {
- gint result;
-
- if (error)
- {
- debug_print ("Error from GVFS: %s\n", error->message);
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- debug_print ("No file info, but no error from GVFS.\n");
- result = -EIO;
- }
-
- return result;
- }
-
- filler (buf, ".", NULL, 0);
- filler (buf, "..", NULL, 0);
-
- while ((file_info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)
- {
- filler (buf, g_file_info_get_name (file_info), NULL, 0);
- g_object_unref (file_info);
- }
-
- g_object_unref (enumerator);
-
- return 0;
-}
-
-static gint
-vfs_readdir (const gchar *path, gpointer buf, fuse_fill_dir_t filler, off_t offset,
- struct fuse_file_info *fi)
-{
- GFile *base_file;
- gint result = 0;
-
- debug_print ("vfs_readdir: %s\n", path);
-
- if (path_is_mount_list (path))
- {
- GList *l;
-
- /* Mount list */
-
- filler (buf, ".", NULL, 0);
- filler (buf, "..", NULL, 0);
-
- mount_list_lock ();
-
- for (l = mount_list; l; l = g_list_next (l))
- {
- MountRecord *mount_record = l->data;
-
- filler (buf, mount_record->name, NULL, 0);
- }
-
- mount_list_unlock ();
- }
- else if ((base_file = file_from_full_path (path)))
- {
- /* Submount */
-
- result = readdir_for_file (base_file, buf, filler);
-
- g_object_unref (base_file);
- }
- else
- {
- /* Not found */
-
- result = -ENOENT;
- }
-
- return result;
-}
-
-static gint
-vfs_rename (const gchar *old_path, const gchar *new_path)
-{
- GFile *old_file;
- GFile *new_file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_rename: %s -> %s\n", old_path, new_path);
-
- old_file = file_from_full_path (old_path);
- new_file = file_from_full_path (new_path);
-
- if (old_file && new_file)
- {
- FileHandle *fh;
-
- fh = get_file_handle_for_path (old_path);
-
- if (fh)
- {
- g_mutex_lock (fh->mutex);
- file_handle_close_stream (fh);
- }
-
- g_file_move (old_file, new_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
-
- if (error)
- {
- debug_print ("vfs_rename failed: %s\n", error->message);
-
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- reindex_file_handle_for_path (old_path, new_path);
- }
-
- if (fh)
- {
- g_mutex_unlock (fh->mutex);
- file_handle_unref (fh);
- }
-
- if (result == -EISDIR)
- {
- /* This makes e.g. 'mv' fall back to a recursive copy + delete operation */
- result = -EXDEV;
- }
- }
- else
- {
- result = -ENOENT;
- }
-
- if (old_file)
- g_object_unref (old_file);
- if (new_file)
- g_object_unref (new_file);
-
- debug_print ("vfs_rename: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_unlink (const gchar *path)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_unlink: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- FileHandle *fh;
-
- fh = get_file_handle_for_path (path);
-
- if (fh)
- {
- g_mutex_lock (fh->mutex);
- file_handle_close_stream (fh);
- }
-
- g_file_delete (file, NULL, &error);
-
- if (fh)
- {
- g_mutex_unlock (fh->mutex);
- file_handle_unref (fh);
- }
-
- if (error)
- {
- debug_print ("vfs_unlink failed: %s (%s)\n", path, error->message);
-
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_unlink: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_mkdir (const gchar *path, mode_t mode)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_mkdir: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- if (g_file_make_directory (file, NULL, &error))
- {
- /* Ignore errors setting the mode. We already created the directory, and that's
- * good enough. */
- g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_MODE, mode, 0, NULL, NULL);
- }
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_mkdir: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_rmdir (const gchar *path)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_rmdir: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- GFileInfo *file_info;
-
- file_info = g_file_query_info (file, "*", 0, NULL, &error);
- if (file_info)
- {
- if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
- {
- g_file_delete (file, NULL, &error);
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- else
- {
- result = -ENOTDIR;
- }
- }
- else
- {
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- result = -ENOENT;
- }
- }
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_rmdir: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_ftruncate (const gchar *path, off_t size, struct fuse_file_info *fi)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_ftruncate: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- FileHandle *fh = GET_FILE_HANDLE (fi);
-
- g_mutex_lock (fh->mutex);
-
- result = setup_output_stream (file, fh);
-
- if (result == 0)
- {
- if (g_seekable_can_truncate (G_SEEKABLE (fh->stream)))
- {
- g_seekable_truncate (fh->stream, size, NULL, &error);
- }
- else if (size == 0)
- {
- g_output_stream_close (fh->stream, NULL, NULL);
- g_object_unref (fh->stream);
- fh->stream = NULL;
-
- fh->stream = g_file_replace (file, 0, FALSE, 0, NULL, &error);
- }
- else
- {
- result = -ENOTSUP;
- }
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
-
- g_object_unref (file);
- g_mutex_unlock (fh->mutex);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_ftruncate: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_truncate (const gchar *path, off_t size)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_truncate: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- GFileOutputStream *file_output_stream = NULL;
- FileHandle *fh;
-
- fh = get_file_handle_for_path (path);
- if (fh)
- g_mutex_lock (fh->mutex);
-
- if (size == 0)
- {
- file_output_stream = g_file_replace (file, 0, FALSE, 0, NULL, &error);
- }
- else
- {
- file_output_stream = g_file_append_to (file, 0, NULL, &error);
- if (file_output_stream)
- g_seekable_truncate (G_SEEKABLE (file_output_stream), size, NULL, &error);
- }
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- if (file_output_stream)
- {
- g_output_stream_close (G_OUTPUT_STREAM (file_output_stream), NULL, NULL);
- g_object_unref (file_output_stream);
- }
-
- if (fh)
- {
- g_mutex_unlock (fh->mutex);
- file_handle_unref (fh);
- }
-
- g_object_unref (file);
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_truncate: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_symlink (const gchar *path_old, const gchar *path_new)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_symlink: %s -> %s\n", path_new, path_old);
-
- file = file_from_full_path (path_new);
-
- if (file)
- {
- g_file_make_symbolic_link (file, path_old, NULL, &error);
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_symlink: -> %s\n", strerror (-result));
-
- return result;
-}
-
-static gint
-vfs_access (const gchar *path, gint mode)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_access: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- GFileInfo *file_info;
-
- file_info = g_file_query_info (file, "*", 0, NULL, &error);
- if (file_info)
- {
- if ((mode & R_OK && (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ) &&
- !g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))) ||
- (mode & W_OK && (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) &&
- !g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))) ||
- (mode & X_OK && (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE) &&
- !g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE))))
- result = -EACCES;
-
- g_object_unref (file_info);
- }
- else if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
- else
- {
- result = -EIO;
- }
-
- g_object_unref (file);
- }
- else if (path_is_mount_list (path))
- {
- result = 0;
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_access: -> %s\n", strerror (-result));
- return result;
-}
-
-static gint
-vfs_utimens (const gchar *path, const struct timespec tv [2])
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- debug_print ("vfs_utimens: %s\n", path);
-
- file = file_from_full_path (path);
-
- if (file)
- {
- guint64 atime;
- guint64 mtime;
-
- if (tv)
- {
- atime = (guint64) tv [0].tv_sec * 1000000 + (guint64) tv [0].tv_nsec / (guint64) 1000;
- mtime = (guint64) tv [1].tv_sec * 1000000 + (guint64) tv [1].tv_nsec / (guint64) 1000;
- }
- else
- {
- struct timeval tiv;
-
- gettimeofday (&tiv, NULL);
- atime = (guint64) tiv.tv_sec * (guint64) 1000000 + (guint64) tiv.tv_usec;
- mtime = atime;
- }
-
- g_file_set_attribute (file, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
- G_FILE_ATTRIBUTE_TYPE_UINT64, &atime,
- 0, NULL, &error);
-
- if (!error)
- {
- g_file_set_attribute (file, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
- G_FILE_ATTRIBUTE_TYPE_UINT64, &mtime,
- 0, NULL, &error);
- }
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- g_object_unref (file);
- }
- else if (path_is_mount_list (path))
- {
- /* */
- }
- else
- {
- result = -ENOENT;
- }
-
- debug_print ("vfs_utimens: -> %s\n", strerror (-result));
- return result;
-}
-
-static gint
-vfs_chmod (const gchar *path, mode_t mode)
-{
- GFile *file;
- GError *error = NULL;
- gint result = 0;
-
- file = file_from_full_path (path);
-
- if (file)
- {
- g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_MODE, mode, 0, NULL, &error);
-
- if (error)
- {
- result = -errno_from_error (error);
- g_error_free (error);
- }
-
- g_object_unref (file);
- }
-
- return result;
-}
-
-static void
-mount_tracker_mounted_cb (GVolumeMonitor *volume_monitor,
- GMount *mount)
-{
- MountRecord *mount_record;
-
- if (mount_record_for_mount_exists (mount))
- return;
-
- mount_record = mount_record_new (mount);
-
- mount_list_lock ();
- mount_list = g_list_prepend (mount_list, mount_record);
- mount_list_unlock ();
-}
-
-static void
-mount_tracker_unmounted_cb (GVolumeMonitor *volume_monitor,
- GMount *mount)
-{
- GFile *root;
- GList *l;
-
- root = g_mount_get_root (mount);
-
- mount_list_lock ();
-
- root = g_mount_get_root (mount);
-
- for (l = mount_list; l != NULL; l = l->next)
- {
- MountRecord *mount_record = l->data;
-
- if (g_file_equal (root, mount_record->root))
- {
- mount_list = g_list_delete_link (mount_list, l);
- mount_record_free (mount_record);
- break;
- }
- }
-
- mount_list_unlock ();
-
- g_object_unref (root);
-}
-
-static gpointer
-subthread_main (gpointer data)
-{
-
- mount_list_update ();
-
- g_signal_connect (volume_monitor, "mount_added", (GCallback) mount_tracker_mounted_cb, NULL);
- g_signal_connect (volume_monitor, "mount_removed", (GCallback) mount_tracker_unmounted_cb, NULL);
-
- g_main_loop_run (subthread_main_loop);
-
- g_signal_handlers_disconnect_by_func (volume_monitor, mount_tracker_mounted_cb, NULL);
- g_signal_handlers_disconnect_by_func (volume_monitor, mount_tracker_unmounted_cb, NULL);
-
- g_main_loop_unref (subthread_main_loop);
- subthread_main_loop = NULL;
-
- g_object_unref (volume_monitor);
- volume_monitor = NULL;
-
- /* Tell the main thread to unmount. Using kill() is necessary according to FUSE maintainers. */
- kill (getpid (), SIGHUP);
-
- return NULL;
-}
-
-static DBusHandlerResult
-dbus_filter_func (DBusConnection *connection,
- DBusMessage *message,
- void *data)
-{
- if (dbus_message_is_signal (message,
- DBUS_INTERFACE_DBUS,
- "NameOwnerChanged"))
- {
- const char *service, *old_owner, *new_owner;
-
- dbus_message_get_args (message,
- NULL,
- DBUS_TYPE_STRING, &service,
- DBUS_TYPE_STRING, &old_owner,
- DBUS_TYPE_STRING, &new_owner,
- DBUS_TYPE_INVALID);
-
- /* Handle monitor owner going away */
- if (service != NULL &&
- strcmp (G_VFS_DBUS_DAEMON_NAME, service) == 0 &&
- *new_owner == 0)
- {
- /* The daemon died, unmount */
- g_main_loop_quit (subthread_main_loop);
- }
- }
- else if (dbus_message_is_signal (message,
- DBUS_INTERFACE_LOCAL,
- "Disconnected"))
- {
- /* Session bus died, unmount */
- g_main_loop_quit (subthread_main_loop);
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static gpointer
-vfs_init (struct fuse_conn_info *conn)
-{
- DBusConnection *dbus_conn;
- DBusMessage *message;
- DBusError error;
-
- daemon_creation_time = time (NULL);
- daemon_uid = getuid ();
- daemon_gid = getgid ();
-
- mount_list_mutex = g_mutex_new ();
- global_fh_table = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, (GDestroyNotify) file_handle_free);
-
- dbus_error_init (&error);
-
- dbus_conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if (dbus_conn == NULL)
- {
- g_printerr ("Failed to connect to the D-BUS daemon: %s\n",
- error.message);
- dbus_error_free (&error);
- return NULL;
- }
-
- dbus_connection_set_exit_on_disconnect (dbus_conn, FALSE);
-
- _g_dbus_connection_integrate_with_main (dbus_conn);
-
- dbus_bus_add_match (dbus_conn,
- "type='signal',sender='" DBUS_SERVICE_DBUS "',"
- "interface='" DBUS_INTERFACE_DBUS "',"
- "member='NameOwnerChanged',"
- "arg0='"G_VFS_DBUS_DAEMON_NAME"'",
- NULL);
- dbus_connection_add_filter (dbus_conn,
- dbus_filter_func,
- NULL,
- NULL);
-
- message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_REGISTER_FUSE);
- dbus_message_set_auto_start (message, TRUE);
- dbus_connection_send (dbus_conn, message, NULL);
- dbus_connection_flush (dbus_conn);
-
- gvfs = g_vfs_get_default ();
-
- volume_monitor = g_object_new (g_type_from_name ("GDaemonVolumeMonitor"), NULL);
-
- subthread_main_loop = g_main_loop_new (NULL, FALSE);
- subthread = g_thread_create ((GThreadFunc) subthread_main, NULL, FALSE, NULL);
-
- return NULL;
-}
-
-static void
-vfs_destroy (gpointer param)
-{
- mount_list_free ();
- if (subthread_main_loop != NULL)
- g_main_loop_quit (subthread_main_loop);
- g_mutex_free (mount_list_mutex);
- g_object_unref (gvfs);
-}
-
-static struct fuse_operations vfs_oper =
-{
- .init = vfs_init,
- .destroy = vfs_destroy,
-
- .getattr = vfs_getattr,
- .readdir = vfs_readdir,
-
- .statfs = vfs_statfs,
-
- .opendir = vfs_opendir,
- .readdir = vfs_readdir,
- .readlink = vfs_readlink,
-
- .open = vfs_open,
- .create = vfs_create,
- .release = vfs_release,
- .flush = vfs_flush,
-
- .read = vfs_read,
- .write = vfs_write,
-
- .rename = vfs_rename,
- .unlink = vfs_unlink,
- .mkdir = vfs_mkdir,
- .rmdir = vfs_rmdir,
- .ftruncate = vfs_ftruncate,
- .truncate = vfs_truncate,
- .symlink = vfs_symlink,
- .access = vfs_access,
- .utimens = vfs_utimens,
- .chmod = vfs_chmod,
-
-#if 0
- .chown = vfs_chown,
- .setxattr = vfs_setxattr,
- .getxattr = vfs_getxattr,
- .listxattr = vfs_listxattr,
- .removexattr = vfs_removexattr,
-#endif
-};
-
-gint
-main (gint argc, gchar *argv [])
-{
- g_type_init ();
- g_thread_init (NULL);
-
- return fuse_main (argc, argv, &vfs_oper, NULL /* user data */);
-}
diff --git a/client/gvfsurimapper.c b/client/gvfsurimapper.c
deleted file mode 100644
index 9c98347a..00000000
--- a/client/gvfsurimapper.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-#include <string.h>
-#include <gmodule.h>
-#include "gvfsurimapper.h"
-
-G_DEFINE_DYNAMIC_TYPE (GVfsUriMapper, g_vfs_uri_mapper, G_TYPE_OBJECT)
-
-void
-g_vfs_uri_mapper_register (GIOModule *module)
-{
- g_vfs_uri_mapper_register_type (G_TYPE_MODULE (module));
-}
-
-GVfsUriMountInfo *
-g_vfs_uri_mount_info_new (const char *type)
-{
- GVfsUriMountInfo *info;
-
- info = g_new0 (GVfsUriMountInfo, 1);
- info->keys = g_array_new (TRUE, TRUE, sizeof (GVfsUriMountInfoKey));
-
- if (type != NULL)
- g_vfs_uri_mount_info_set (info, "type", type);
-
- return info;
-}
-
-void
-g_vfs_uri_mount_info_free (GVfsUriMountInfo *info)
-{
- int i;
- GVfsUriMountInfoKey *key;
-
- for (i = 0; i < info->keys->len; i++) {
- key = &g_array_index (info->keys, GVfsUriMountInfoKey, i);
-
- g_free (key->key);
- g_free (key->value);
- }
- g_array_free (info->keys, TRUE);
- g_free (info->path);
- g_free (info);
-}
-
-static GVfsUriMountInfoKey *
-lookup_key (GVfsUriMountInfo *info,
- const char *key)
-{
- int i;
- GVfsUriMountInfoKey *keyp;
-
- for (i = 0; i < info->keys->len; i++) {
- keyp = &g_array_index (info->keys, GVfsUriMountInfoKey, i);
-
- if (strcmp (keyp->key, key) == 0)
- return keyp;
- }
-
- return NULL;
-}
-
-const char *
-g_vfs_uri_mount_info_get (GVfsUriMountInfo *info,
- const char *key)
-{
- GVfsUriMountInfoKey *keyp;
-
- keyp = lookup_key (info, key);
-
- if (keyp)
- return keyp->value;
-
- return NULL;
-}
-
-void
-g_vfs_uri_mount_info_set_with_len (GVfsUriMountInfo *info,
- const char *key,
- const char *value,
- int value_len)
-{
- GVfsUriMountInfoKey *keyp;
- GVfsUriMountInfoKey keyv;
- char *value_copy;
-
- if (value_len == -1)
- value_copy = g_strdup (value);
- else
- value_copy = g_strndup (value, value_len);
-
- keyp = lookup_key (info, key);
- if (keyp)
- {
- g_free (keyp->value);
- keyp->value = value_copy;
- }
- else
- {
- keyv.key = g_strdup (key);
- keyv.value = value_copy;
- g_array_append_val (info->keys, keyv);
- }
-}
-
-void
-g_vfs_uri_mount_info_set (GVfsUriMountInfo *info,
- const char *key,
- const char *value)
-{
- g_vfs_uri_mount_info_set_with_len (info, key, value, -1);
-}
-
-
-static void
-g_vfs_uri_mapper_class_finalize (GVfsUriMapperClass *klass)
-{
-}
-
-static void
-g_vfs_uri_mapper_class_init (GVfsUriMapperClass *klass)
-{
-}
-
-static void
-g_vfs_uri_mapper_init (GVfsUriMapper *vfs)
-{
-}
-
-const char * const *
-g_vfs_uri_mapper_get_handled_schemes (GVfsUriMapper *mapper)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- return (* class->get_handled_schemes) (mapper);
-}
-
-
-GVfsUriMountInfo *
-g_vfs_uri_mapper_from_uri (GVfsUriMapper *mapper,
- const char *uri)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- return (* class->from_uri) (mapper, uri);
-}
-
-GVfsUriMountInfo *
-g_vfs_uri_mapper_get_mount_info_for_path (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info,
- const char *new_path)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- if (class->get_mount_info_for_path != NULL)
- return (* class->get_mount_info_for_path) (mapper, info, new_path);
- else
- return NULL;
-}
-
-const char * const *
-g_vfs_uri_mapper_get_handled_mount_types (GVfsUriMapper *mapper)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- return (* class->get_handled_mount_types) (mapper);
-}
-
-char *
-g_vfs_uri_mapper_to_uri (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info,
- gboolean allow_utf8)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- return (* class->to_uri) (mapper, mount_info, allow_utf8);
-}
-
-const char *
-g_vfs_uri_mapper_to_uri_scheme (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info)
-{
- GVfsUriMapperClass *class;
-
- class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
-
- return (* class->to_uri_scheme) (mapper, mount_info);
-}
-
diff --git a/client/gvfsurimapper.h b/client/gvfsurimapper.h
deleted file mode 100644
index 6a3b5ea5..00000000
--- a/client/gvfsurimapper.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_VFS_URI_MAPPER_H__
-#define __G_VFS_URI_MAPPER_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define G_VFS_TYPE_URI_MAPPER (g_vfs_uri_mapper_get_type ())
-#define G_VFS_URI_MAPPER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_URI_MAPPER, GVfsUriMapper))
-#define G_VFS_URI_MAPPER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_URI_MAPPER, GVfsUriMapperClass))
-#define G_VFS_URI_MAPPER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_URI_MAPPER, GVfsUriMapperClass))
-#define G_IS_VFS_URI_MAPPER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_URI_MAPPER))
-#define G_IS_VFS_URI_MAPPER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_URI_MAPPER))
-
-typedef struct _GVfsUriMapper GVfsUriMapper; /* Dummy typedef */
-typedef struct _GVfsUriMapperClass GVfsUriMapperClass;
-
-struct _GVfsUriMapper {
- GObject parent;
-};
-
-/* Keep in sync with GMountSpecItem */
-typedef struct {
- char *key;
- char *value;
-} GVfsUriMountInfoKey;
-
-typedef struct {
- GArray *keys;
- char *path;
-} GVfsUriMountInfo;
-
-struct _GVfsUriMapperClass
-{
- GObjectClass parent_class;
-
- /* Virtual Table */
-
- const char * const * (*get_handled_schemes) (GVfsUriMapper *mapper);
- GVfsUriMountInfo * (*from_uri) (GVfsUriMapper *mapper,
- const char *uri);
- GVfsUriMountInfo * (*get_mount_info_for_path) (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info,
- const char *new_path);
-
- const char * const * (*get_handled_mount_types) (GVfsUriMapper *mapper);
- char * (*to_uri) (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info,
- gboolean allow_utf8);
- const char * (*to_uri_scheme) (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info);
-};
-
-GType g_vfs_uri_mapper_get_type (void);
-void g_vfs_uri_mapper_register (GIOModule *module);
-
-GVfsUriMountInfo *g_vfs_uri_mount_info_new (const char *type);
-void g_vfs_uri_mount_info_free (GVfsUriMountInfo *info);
-const char * g_vfs_uri_mount_info_get (GVfsUriMountInfo *info,
- const char *key);
-void g_vfs_uri_mount_info_set (GVfsUriMountInfo *info,
- const char *key,
- const char *value);
-void g_vfs_uri_mount_info_set_with_len (GVfsUriMountInfo *info,
- const char *key,
- const char *value,
- int value_len);
-
-const char * const *g_vfs_uri_mapper_get_handled_schemes (GVfsUriMapper *mapper);
-GVfsUriMountInfo * g_vfs_uri_mapper_from_uri (GVfsUriMapper *mapper,
- const char *uri);
-GVfsUriMountInfo * g_vfs_uri_mapper_get_mount_info_for_path (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info,
- const char *new_path);
-
-const char * const *g_vfs_uri_mapper_get_handled_mount_types (GVfsUriMapper *mapper);
-char * g_vfs_uri_mapper_to_uri (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_info,
- gboolean allow_utf8);
-const char * g_vfs_uri_mapper_to_uri_scheme (GVfsUriMapper *mapper,
- GVfsUriMountInfo *mount_infoxo);
-
-
-G_END_DECLS
-
-#endif /* __G_VFS_URI_MAPPER_H__ */
diff --git a/client/gvfsuriutils.c b/client/gvfsuriutils.c
deleted file mode 100644
index c9bae69b..00000000
--- a/client/gvfsuriutils.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-#include "gvfsuriutils.h"
-#include <string.h>
-#include <stdlib.h>
-
-void
-g_vfs_decoded_uri_free (GDecodedUri *decoded)
-{
- if (decoded == NULL)
- return;
-
- g_free (decoded->scheme);
- g_free (decoded->query);
- g_free (decoded->fragment);
- g_free (decoded->userinfo);
- g_free (decoded->host);
- g_free (decoded->path);
- g_free (decoded);
-}
-
-GDecodedUri *
-g_vfs_decoded_uri_new (void)
-{
- GDecodedUri *uri;
-
- uri = g_new0 (GDecodedUri, 1);
- uri->port = -1;
-
- return uri;
-}
-
-GDecodedUri *
-g_vfs_decode_uri (const char *uri)
-{
- GDecodedUri *decoded;
- const char *p, *in, *hier_part_start, *hier_part_end, *query_start, *fragment_start;
- char *out;
- char c;
-
- /* From RFC 3986 Decodes:
- * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
- */
-
- p = uri;
-
- /* Decode scheme:
- scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- */
-
- if (!g_ascii_isalpha (*p))
- return NULL;
-
- while (1)
- {
- c = *p++;
-
- if (c == ':')
- break;
-
- if (!(g_ascii_isalnum(c) ||
- c == '+' ||
- c == '-' ||
- c == '.'))
- return NULL;
- }
-
- decoded = g_vfs_decoded_uri_new ();
-
- decoded->scheme = g_malloc (p - uri);
- out = decoded->scheme;
- for (in = uri; in < p - 1; in++)
- *out++ = g_ascii_tolower (*in);
- *out = 0;
-
- hier_part_start = p;
-
- query_start = strchr (p, '?');
- if (query_start)
- {
- hier_part_end = query_start++;
- fragment_start = strchr (query_start, '#');
- if (fragment_start)
- {
- decoded->query = g_strndup (query_start, fragment_start - query_start);
- decoded->fragment = g_strdup (fragment_start+1);
- }
- else
- {
- decoded->query = g_strdup (query_start);
- decoded->fragment = NULL;
- }
- }
- else
- {
- /* No query */
- decoded->query = NULL;
- fragment_start = strchr (p, '#');
- if (fragment_start)
- {
- hier_part_end = fragment_start++;
- decoded->fragment = g_strdup (fragment_start);
- }
- else
- {
- hier_part_end = p + strlen (p);
- decoded->fragment = NULL;
- }
- }
-
- /* 3:
- hier-part = "//" authority path-abempty
- / path-absolute
- / path-rootless
- / path-empty
-
- */
-
- if (hier_part_start[0] == '/' &&
- hier_part_start[1] == '/')
- {
- const char *authority_start, *authority_end;
- const char *userinfo_start, *userinfo_end;
- const char *host_start, *host_end;
- const char *port_start;
-
- authority_start = hier_part_start + 2;
- /* authority is always followed by / or nothing */
- authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
- if (authority_end == NULL)
- authority_end = hier_part_end;
-
- /* 3.2:
- authority = [ userinfo "@" ] host [ ":" port ]
- */
-
- userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
- if (userinfo_end)
- {
- userinfo_start = authority_start;
- decoded->userinfo = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL);
- if (decoded->userinfo == NULL)
- {
- g_vfs_decoded_uri_free (decoded);
- return NULL;
- }
- host_start = userinfo_end + 1;
- }
- else
- host_start = authority_start;
-
- /* We should handle hostnames in brackets, as those are used by IPv6 URIs
- * See http://tools.ietf.org/html/rfc2732 */
- if (*host_start == '[')
- {
- char *s;
-
- port_start = NULL;
- host_end = memchr (host_start, ']', authority_end - host_start);
- if (host_end == NULL)
- {
- g_vfs_decoded_uri_free (decoded);
- return NULL;
- }
-
- /* Look for the start of the port,
- * And we sure we don't have it start somewhere
- * in the path section */
- s = (char *) host_end;
- while (1)
- {
- if (*s == '/')
- {
- port_start = NULL;
- break;
- }
- else if (*s == ':')
- {
- port_start = s;
- break;
- }
- else if (*s == '\0')
- {
- break;
- }
-
- s++;
- }
- }
- else
- {
- port_start = memchr (host_start, ':', authority_end - host_start);
- }
-
- if (port_start)
- {
- host_end = port_start++;
-
- decoded->port = atoi(port_start);
- }
- else
- {
- host_end = authority_end;
- decoded->port = -1;
- }
-
- decoded->host = g_strndup (host_start, host_end - host_start);
-
- hier_part_start = authority_end;
- }
-
- decoded->path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/");
-
- if (decoded->path == NULL)
- {
- g_vfs_decoded_uri_free (decoded);
- return NULL;
- }
-
- return decoded;
-}
-
-char *
-g_vfs_encode_uri (GDecodedUri *decoded, gboolean allow_utf8)
-{
- GString *uri;
-
- uri = g_string_new (NULL);
-
- g_string_append (uri, decoded->scheme);
- g_string_append (uri, "://");
-
- if (decoded->host != NULL)
- {
- if (decoded->userinfo)
- {
- /* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
- g_string_append_uri_escaped (uri, decoded->userinfo,
- G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, allow_utf8);
- g_string_append_c (uri, '@');
- }
-
- g_string_append (uri, decoded->host);
-
- if (decoded->port != -1)
- {
- g_string_append_c (uri, ':');
- g_string_append_printf (uri, "%d", decoded->port);
- }
- }
-
- g_string_append_uri_escaped (uri, decoded->path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, allow_utf8);
-
- if (decoded->query)
- {
- g_string_append_c (uri, '?');
- g_string_append (uri, decoded->query);
- }
-
- if (decoded->fragment)
- {
- g_string_append_c (uri, '#');
- g_string_append (uri, decoded->fragment);
- }
-
- return g_string_free (uri, FALSE);
-}
diff --git a/client/gvfsuriutils.h b/client/gvfsuriutils.h
deleted file mode 100644
index 20de00d3..00000000
--- a/client/gvfsuriutils.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#ifndef __G_VFS_URI_UTILS_H__
-#define __G_VFS_URI_UTILS_H__
-
-#include <glib.h>
-#include <glib/gurifuncs.h>
-
-G_BEGIN_DECLS
-
-typedef struct {
- char *scheme;
- char *userinfo;
- char *host;
- int port; /* -1 => not in uri */
- char *path;
- char *query;
- char *fragment;
-} GDecodedUri;
-
-char * g_vfs_encode_uri (GDecodedUri *decoded,
- gboolean allow_utf8);
-void g_vfs_decoded_uri_free (GDecodedUri *decoded);
-GDecodedUri *g_vfs_decode_uri (const char *uri);
-GDecodedUri *g_vfs_decoded_uri_new (void);
-
-
-G_END_DECLS
-
-#endif /* __G_VFS_URI_UTILS_H__ */
diff --git a/client/httpuri.c b/client/httpuri.c
deleted file mode 100644
index 7eef0cbb..00000000
--- a/client/httpuri.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Christian Kellner <gicmo@gnome.org>
- */
-
-#include <config.h>
-#include <string.h>
-
-#include <stdlib.h> /* atoi */
-
-#include <gio/gio.h>
-#include <gvfsurimapper.h>
-#include <gvfsuriutils.h>
-
-typedef struct _GVfsUriMapperHttp GVfsUriMapperHttp;
-typedef struct _GVfsUriMapperHttpClass GVfsUriMapperHttpClass;
-
-struct _GVfsUriMapperHttp
-{
- GVfsUriMapper parent;
-};
-
-struct _GVfsUriMapperHttpClass
-{
- GVfsUriMapperClass parent_class;
-};
-
-GType g_vfs_uri_mapper_http_get_type (void);
-void g_vfs_uri_mapper_http_register (GIOModule *module);
-
-G_DEFINE_DYNAMIC_TYPE (GVfsUriMapperHttp, g_vfs_uri_mapper_http, G_VFS_TYPE_URI_MAPPER)
-
-static void
-g_vfs_uri_mapper_http_init (GVfsUriMapperHttp *vfs)
-{
-}
-
-static const char * const *
-http_get_handled_schemes (GVfsUriMapper *mapper)
-{
- static const char *schemes[] = {
- "http",
- "https",
- "dav",
- "davs",
- NULL
- };
- return schemes;
-}
-
-static inline gboolean
-port_is_defaul_port (int port, gboolean ssl)
-{
- if (ssl)
- return port == 443;
- else
- return port == 80;
-}
-
-static GVfsUriMountInfo *
-http_from_uri (GVfsUriMapper *mapper,
- const char *uri_str)
-{
- GVfsUriMountInfo *info;
- char *path;
- gboolean ssl;
-
- path = NULL;
- if (!g_ascii_strncasecmp (uri_str, "http", 4))
- {
- GDecodedUri *uri;
-
- uri = g_vfs_decode_uri (uri_str);
-
- info = g_vfs_uri_mount_info_new ("http");
- g_vfs_uri_mount_info_set (info, "uri", uri_str);
-
- if (uri)
- {
- path = uri->path;
- uri->path = NULL;
- g_vfs_decoded_uri_free (uri);
- }
- }
- else
- {
- GDecodedUri *uri;
-
- uri = g_vfs_decode_uri (uri_str);
-
- if (uri == NULL)
- return NULL;
-
- info = g_vfs_uri_mount_info_new ("dav");
- ssl = !g_ascii_strcasecmp (uri->scheme, "davs");
- g_vfs_uri_mount_info_set (info, "ssl", ssl ? "true" : "false");
-
- if (uri->host && *uri->host)
- g_vfs_uri_mount_info_set (info, "host", uri->host);
-
- if (uri->userinfo && *uri->userinfo)
- g_vfs_uri_mount_info_set (info, "user", uri->userinfo);
-
- /* only set the port if it isn't the default port */
- if (uri->port != -1 && ! port_is_defaul_port (uri->port, ssl))
- {
- char *port = g_strdup_printf ("%d", uri->port);
- g_vfs_uri_mount_info_set (info, "port", port);
- g_free (port);
- }
-
- path = uri->path;
- uri->path = NULL;
-
- g_vfs_decoded_uri_free (uri);
- }
-
-
- info->path = path;
- return info;
-}
-
-static GVfsUriMountInfo *
-http_get_mount_info_for_path (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info,
- const char *new_path)
-{
- const char *type;
-
- type = g_vfs_uri_mount_info_get (info, "type");
-
- if (strcmp (type, "http") == 0)
- {
- const char *uri_str;
- char *new_uri;
- GDecodedUri *uri;
- GVfsUriMountInfo *new_info;
-
- uri_str = g_vfs_uri_mount_info_get (info, "uri");
-
- uri = g_vfs_decode_uri (uri_str);
-
- if (uri == NULL)
- return NULL;
-
- if (strcmp (uri->path, new_path) == 0)
- {
- g_vfs_decoded_uri_free (uri);
- return NULL;
- }
-
- g_free (uri->path);
- uri->path = g_strdup (new_path);
-
- g_free (uri->query);
- uri->query = NULL;
-
- g_free (uri->fragment);
- uri->fragment = NULL;
-
- new_info = g_vfs_uri_mount_info_new ("http");
-
- new_uri = g_vfs_encode_uri (uri, TRUE);
- g_vfs_uri_mount_info_set (new_info, "uri", new_uri);
- g_free (new_uri);
-
- uri->path = NULL;
-
- g_vfs_decoded_uri_free (uri);
-
- return new_info;
- }
- else
- return NULL;
-}
-
-static const char * const *
-http_get_handled_mount_types (GVfsUriMapper *mapper)
-{
- static const char *types[] = {
- "http",
- "dav",
- NULL
- };
- return types;
-}
-
-static char *
-http_to_uri (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info,
- gboolean allow_utf8)
-{
- char *res;
- const char *type;
- const char *host;
- const char *user;
- const char *port;
- const char *ssl;
-
- type = g_vfs_uri_mount_info_get (info, "type");
-
- if (strcmp (type, "http") == 0)
- {
- res = g_strdup (g_vfs_uri_mount_info_get (info, "uri"));
- }
- else
- {
- GDecodedUri *decoded_uri;
- int port_num;
-
- decoded_uri = g_new0 (GDecodedUri, 1);
-
- ssl = g_vfs_uri_mount_info_get (info, "ssl");
- host = g_vfs_uri_mount_info_get (info, "host");
- user = g_vfs_uri_mount_info_get (info, "user");
- port = g_vfs_uri_mount_info_get (info, "port");
-
- if (ssl && strcmp (ssl, "true") == 0)
- decoded_uri->scheme = g_strdup ("davs");
- else
- decoded_uri->scheme = g_strdup ("dav");
-
- decoded_uri->host = g_strdup (host);
- decoded_uri->userinfo = g_strdup (user);
-
- if (port && (port_num = atoi (port)))
- decoded_uri->port = port_num;
- else
- decoded_uri->port = -1;
-
- decoded_uri->path = g_strdup (info->path);
-
- res = g_vfs_encode_uri (decoded_uri, allow_utf8);
- g_vfs_decoded_uri_free (decoded_uri);
- }
-
- return res;
-}
-
-static const char *
-http_to_uri_scheme (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info)
-{
- const gchar *ssl;
- const gchar *type;
- gboolean is_dav;
- gboolean is_ssl;
-
- ssl = g_vfs_uri_mount_info_get (info, "ssl");
- type = g_vfs_uri_mount_info_get (info, "type");
-
- if (strcmp (type, "dav") == 0)
- is_dav = TRUE;
- else if (strcmp (type, "http") == 0)
- is_dav = FALSE;
- else
- return NULL;
-
- is_ssl =
- ssl != NULL &&
- strcmp (ssl, "true") == 0;
-
- if (is_dav && is_ssl)
- return "davs";
- else if (is_dav && !is_ssl)
- return "dav";
- else if (!is_dav && is_ssl)
- return "https";
- else
- return "http";
-}
-
-static void
-g_vfs_uri_mapper_http_class_finalize (GVfsUriMapperHttpClass *klass)
-{
-}
-
-static void
-g_vfs_uri_mapper_http_class_init (GVfsUriMapperHttpClass *class)
-{
- GVfsUriMapperClass *mapper_class;
-
- mapper_class = G_VFS_URI_MAPPER_CLASS (class);
- mapper_class->get_handled_schemes = http_get_handled_schemes;
- mapper_class->from_uri = http_from_uri;
- mapper_class->get_mount_info_for_path = http_get_mount_info_for_path;
- mapper_class->get_handled_mount_types = http_get_handled_mount_types;
- mapper_class->to_uri = http_to_uri;
- mapper_class->to_uri_scheme = http_to_uri_scheme;
-}
-
-void
-g_vfs_uri_mapper_http_register (GIOModule *module)
-{
- g_vfs_uri_mapper_http_register_type (G_TYPE_MODULE (module));
-}
diff --git a/client/smburi.c b/client/smburi.c
deleted file mode 100644
index d3804cf4..00000000
--- a/client/smburi.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Alexander Larsson <alexl@redhat.com>
- */
-
-#include <config.h>
-#include <string.h>
-
-#include <gio/gio.h>
-#include <gvfsurimapper.h>
-#include <gvfsuriutils.h>
-
-typedef struct _GVfsUriMapperSmb GVfsUriMapperSmb;
-typedef struct _GVfsUriMapperSmbClass GVfsUriMapperSmbClass;
-
-struct _GVfsUriMapperSmb
-{
- GVfsUriMapper parent;
-};
-
-struct _GVfsUriMapperSmbClass
-{
- GVfsUriMapperClass parent_class;
-};
-
-GType g_vfs_uri_mapper_smb_get_type (void);
-void g_vfs_uri_mapper_smb_register (GIOModule *module);
-
-G_DEFINE_DYNAMIC_TYPE (GVfsUriMapperSmb, g_vfs_uri_mapper_smb, G_VFS_TYPE_URI_MAPPER)
-
-static void
-g_vfs_uri_mapper_smb_init (GVfsUriMapperSmb *vfs)
-{
-}
-
-static char *
-normalize_smb_name (const char *name, gssize len)
-{
- gboolean valid_utf8;
-
- valid_utf8 = g_utf8_validate (name, len, NULL);
-
- if (valid_utf8)
- return g_utf8_casefold (name, len);
- else
- return g_ascii_strdown (name, len);
-}
-
-static const char * const *
-smb_get_handled_schemes (GVfsUriMapper *mapper)
-{
- static const char *schemes[] = {
- "smb",
- NULL
- };
- return schemes;
-}
-
-static GVfsUriMountInfo *
-smb_from_uri (GVfsUriMapper *mapper,
- const char *uri_str)
-{
- char *tmp;
- const char *p;
- const char *share, *share_end;
- GDecodedUri *uri;
- GVfsUriMountInfo *info;
-
- uri = g_vfs_decode_uri (uri_str);
- if (uri == NULL)
- return NULL;
-
- if (uri->host == NULL || strlen (uri->host) == 0)
- {
- /* uri form: smb:/// or smb:///$path */
- info = g_vfs_uri_mount_info_new ("smb-network");
- if (uri->path == NULL || *uri->path == 0)
- info->path = g_strdup ("/");
- else
- info->path = g_strdup (uri->path);
- }
- else
- {
- /* host set */
- p = uri->path;
- while (p && *p == '/')
- p++;
-
- if (p == NULL || *p == 0)
- {
- /* uri form: smb://$host/ */
- info = g_vfs_uri_mount_info_new ("smb-server");
- tmp = normalize_smb_name (uri->host, -1);
- g_vfs_uri_mount_info_set (info, "server", tmp);
- g_free (tmp);
- info->path = g_strdup ("/");
- }
- else
- {
- share = p;
- share_end = strchr (share, '/');
- if (share_end == NULL)
- share_end = share + strlen (share);
-
- p = share_end;
-
- while (*p == '/')
- p++;
-
- if (*p == 0)
- {
- /* uri form: smb://$host/$share/
- * Here we special case smb-server files by adding "._" to the names in the uri */
- if (share[0] == '.' && share[1] == '_')
- {
- info = g_vfs_uri_mount_info_new ("smb-server");
- tmp = normalize_smb_name (uri->host, -1);
- g_vfs_uri_mount_info_set (info, "server", tmp);
- g_free (tmp);
- tmp = normalize_smb_name (share + 2, share_end - (share + 2));
- info->path = g_strconcat ("/", tmp, NULL);
- g_free (tmp);
- }
- else
- {
- info = g_vfs_uri_mount_info_new ("smb-share");
- tmp = normalize_smb_name (uri->host, -1);
- g_vfs_uri_mount_info_set (info, "server", tmp);
- g_free (tmp);
- tmp = normalize_smb_name (share, share_end - share);
- g_vfs_uri_mount_info_set (info, "share", tmp);
- g_free (tmp);
- info->path = g_strdup ("/");
- }
- }
- else
- {
- info = g_vfs_uri_mount_info_new ("smb-share");
-
- tmp = normalize_smb_name (uri->host, -1);
- g_vfs_uri_mount_info_set (info, "server", tmp);
- g_free (tmp);
-
- tmp = normalize_smb_name (share, share_end - share);
- g_vfs_uri_mount_info_set (info, "share", tmp);
- g_free (tmp);
-
- info->path = g_strconcat ("/", p, NULL);
- }
- }
- }
-
- if (uri->userinfo)
- {
- const char *user = uri->userinfo;
- p = strchr (uri->userinfo, ';');
- if (p)
- {
- if (p != user)
- g_vfs_uri_mount_info_set_with_len (info, "domain", user, p - user);
- user = p + 1;
- }
- if (*user != 0)
- g_vfs_uri_mount_info_set (info, "user", user);
- }
-
- g_vfs_decoded_uri_free (uri);
-
- return info;
-}
-
-static const char * const *
-smb_get_handled_mount_types (GVfsUriMapper *mapper)
-{
- static const char *types[] = {
- "smb-network",
- "smb-server",
- "smb-share",
- NULL
- };
- return types;
-}
-
-static char *
-smb_to_uri (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info,
- gboolean allow_utf8)
-{
- const char *type;
- const char *server;
- const char *share;
- const char *user;
- const char *domain;
- char *s;
- GDecodedUri *uri;
-
- uri = g_new0 (GDecodedUri, 1);
-
- type = g_vfs_uri_mount_info_get (info, "type");
-
- uri->scheme = g_strdup ("smb");
- uri->port = -1;
-
- if (strcmp (type, "smb-network") == 0)
- {
- uri->path = g_strdup (info->path);
- }
- else if (strcmp (type, "smb-server") == 0)
- {
- server = g_vfs_uri_mount_info_get (info, "server");
- uri->host = g_strdup (server);
-
- /* Map the mountables in server to ._share because the actual share mount maps to smb://server/share */
- if (info->path && info->path[0] == '/' && info->path[1] != 0)
- uri->path = g_strconcat ("/._", info->path + 1, NULL);
- else
- uri->path = g_strdup ("/");
- }
- else if (strcmp (type, "smb-share") == 0)
- {
- server = g_vfs_uri_mount_info_get (info, "server");
- uri->host = g_strdup (server);
- share = g_vfs_uri_mount_info_get (info, "share");
- if (info->path[0] == '/')
- uri->path = g_strconcat ("/", share, info->path, NULL);
- else
- uri->path = g_strconcat ("/", share, "/", info->path, NULL);
-
- user = g_vfs_uri_mount_info_get (info, "user");
- domain = g_vfs_uri_mount_info_get (info, "domain");
- if (user) {
- if (domain)
- uri->userinfo = g_strconcat (domain, ";", user, NULL);
- else
- uri->userinfo = g_strdup (user);
- }
- }
-
- s = g_vfs_encode_uri (uri, allow_utf8);
- g_vfs_decoded_uri_free (uri);
- return s;
-}
-
-static const char *
-smb_to_uri_scheme (GVfsUriMapper *mapper,
- GVfsUriMountInfo *info)
-{
- const gchar *type = g_vfs_uri_mount_info_get (info, "type");
-
- if (strcmp ("smb-network", type) == 0 ||
- strcmp ("smb-server", type) == 0 ||
- strcmp ("smb-share", type) == 0)
- return "smb";
- else
- return NULL;
-}
-
-static void
-g_vfs_uri_mapper_smb_class_finalize (GVfsUriMapperSmbClass *klass)
-{
-}
-
-static void
-g_vfs_uri_mapper_smb_class_init (GVfsUriMapperSmbClass *class)
-{
- GVfsUriMapperClass *mapper_class;
-
- mapper_class = G_VFS_URI_MAPPER_CLASS (class);
- mapper_class->get_handled_schemes = smb_get_handled_schemes;
- mapper_class->from_uri = smb_from_uri;
- mapper_class->get_handled_mount_types = smb_get_handled_mount_types;
- mapper_class->to_uri = smb_to_uri;
- mapper_class->to_uri_scheme = smb_to_uri_scheme;
-}
-
-void
-g_vfs_uri_mapper_smb_register (GIOModule *module)
-{
- g_vfs_uri_mapper_smb_register_type (G_TYPE_MODULE (module));
-}
diff --git a/client/test-uri-utils.c b/client/test-uri-utils.c
deleted file mode 100644
index 41cfb057..00000000
--- a/client/test-uri-utils.c
+++ /dev/null
@@ -1,58 +0,0 @@
-
-#include <string.h>
-
-#include "gvfsuriutils.h"
-
-
-typedef struct {
- const char *uri;
- const char *expected_host;
- guint expected_port;
-} TestURIs;
-
-static TestURIs uris[] = {
- { "https://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:443/", "[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]", 443 },
- { "http://test:443/", "test", 443 },
- { "http://test/", "test", -1 },
- { "obex://[00:FF:FF:FF:FF:FF]/MMC/foo.jpg", "[00:FF:FF:FF:FF:FF]", -1 },
- { "obex://[00:FF:FF:FF:FF:FF]/C:", "[00:FF:FF:FF:FF:FF]", -1 },
- { "http://windows-host:8080/C:/", "windows-host", 8080 },
-};
-
-int main (int argc, char **argv)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (uris); i++) {
- GDecodedUri *decoded;
- char *encoded;
-
- decoded = g_vfs_decode_uri (uris[i].uri);
- if (decoded == NULL) {
- g_warning ("Failed to parse \"%s\"", uris[i].uri);
- return 1;
- }
- if (decoded->host == NULL || strcmp (decoded->host, uris[i].expected_host) != 0) {
- g_warning ("Wrong host for \"%s\" (got '%s', expected '%s')", uris[i].uri, decoded->host, uris[i].expected_host);
- g_vfs_decoded_uri_free (decoded);
- return 1;
- }
- if (decoded->port != uris[i].expected_port) {
- g_warning ("Wrong port for \"%s\"", uris[i].uri);
- g_vfs_decoded_uri_free (decoded);
- return 1;
- }
- encoded = g_vfs_encode_uri (decoded, TRUE);
- if (encoded == NULL || strcmp (encoded, uris[i].uri) != 0) {
- g_warning ("Failed to re-encode \"%s\" from '%s'", uris[i].uri, encoded);
- g_vfs_decoded_uri_free (decoded);
- g_free (encoded);
- return 1;
- }
- g_free (encoded);
- g_vfs_decoded_uri_free (decoded);
- }
-
- return 0;
-}
-