gvfs/gvfs-dice-backend.patch

1550 lines
46 KiB
Diff
Raw Normal View History

Index: configure.ac
===================================================================
--- configure.ac (revision 1810)
+++ configure.ac (working copy)
@@ -53,6 +53,10 @@
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
+PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
+AC_SUBST(DBUS_GLIB_CFLAGS)
+AC_SUBST(DBUS_GLIB_LIBS)
+
AC_ARG_WITH(dbus_service_dir, [ --with-dbus-service-dir=PATH choose directory for dbus service files, [default=PREFIX/share/dbus-1/services]], with_dbus_service_dir="$withval", with_dbus_service_dir=$datadir/dbus-1/services)
DBUS_SERVICE_DIR=$with_dbus_service_dir
AC_SUBST(DBUS_SERVICE_DIR)
Index: daemon/gvfsbackenddice.c
===================================================================
--- daemon/gvfsbackenddice.c (revision 0)
+++ daemon/gvfsbackenddice.c (revision 0)
@@ -0,0 +1,1394 @@
+/* Novell IceDesktop Backend for GVfs
+ *
+ * Copyright (C) 2008 Novell, 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: Boyd Timothy <btimothy@novell.com>
+ */
+
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <gio/gio.h>
+#include <gio/gunixmounts.h>
+#include <glib/gurifuncs.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <time.h>
+
+#include "gvfsbackenddice.h"
+#include "gvfsmonitor.h"
+#include "gvfsjobopenforread.h"
+#include "gvfsjobread.h"
+#include "gvfsjobseekread.h"
+#include "gvfsjobopenforwrite.h"
+#include "gvfsjobwrite.h"
+#include "gvfsjobclosewrite.h"
+#include "gvfsjobseekwrite.h"
+#include "gvfsjobsetdisplayname.h"
+#include "gvfsjobqueryinfo.h"
+#include "gvfsjobdelete.h"
+#include "gvfsjobqueryfsinfo.h"
+#include "gvfsjobqueryattributes.h"
+#include "gvfsjobenumerate.h"
+#include "gvfsjobcreatemonitor.h"
+#include "gvfsdaemonprotocol.h"
+#include "gvfsdaemonutils.h"
+
+//#define kIceDesktopRootPath "/home/boyd/.deskice"
+
+#define G_FILE_ATTRIBUTE_DICE_LOCAL_PATH "dice::local-path"
+
+static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
+static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
+static GFileInfo *create_file_info_from_dbus_array(GValueArray *array_obj);
+
+struct _GVfsBackendDice
+{
+ GVfsBackend parent_instance;
+ DBusGConnection *dbus_connection;
+ DBusGProxy *ice_daemon;
+
+ GMountSpec *mount_spec;
+ GList *top_files; /* Files in toplevel dir */
+ guint num_top_files;
+};
+
+struct IceOutputStream
+{
+ char *file_path;
+ GFileOutputStream *stream;
+};
+
+struct IceInputStream
+{
+ char *file_path;
+ GFileInputStream *stream;
+};
+
+G_DEFINE_TYPE (GVfsBackendDice, g_vfs_backend_dice, G_VFS_TYPE_BACKEND)
+
+#define DBUS_STRUCT_STRING_STRING_STRING (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID))
+
+static void
+g_vfs_backend_dice_init (GVfsBackendDice *ice_backend)
+{
+ g_print ("(ice) g_vfs_backend_dice_init \n");
+ GVfsBackendDice *backend = G_VFS_BACKEND_DICE (ice_backend);
+ backend->dbus_connection = NULL;
+
+ DBusGConnection *connection;
+ GError *error;
+ DBusGProxy *ice_daemon_proxy;
+
+ //
+ // Attempt to connect to the DICE Daemon. If it's not
+ // running, kick it in the pants so it will start up.
+
+ g_printf(" (ice) connecting to the ICE Daemon via DBus...\n");
+
+ error = NULL;
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL)
+ {
+ g_printerr ("Failed to open connection to bus: %s\n",
+ error->message);
+ g_error_free (error);
+ exit (1);
+ }
+ else
+ {
+ g_printf(" (ice) got a connection to the session bus\n");
+ }
+
+ backend->dbus_connection = connection;
+
+ // This call will not trigger activation
+ ice_daemon_proxy = dbus_g_proxy_new_for_name (backend->dbus_connection,
+ "Novell.ICEDesktop.Daemon",
+ "/Novell/ICEDesktop/Daemon",
+ "Novell.ICEDesktop.Daemon");
+
+ gboolean ping_successful;
+ error = NULL;
+ // This method should trigger activation
+ if (!dbus_g_proxy_call (ice_daemon_proxy, "Ping", &error,
+ G_TYPE_INVALID, // Input params
+ G_TYPE_BOOLEAN, &ping_successful, // Output params
+ G_TYPE_INVALID))
+ {
+// lose_gerror ("Could not ping the ICE Daemon, but it should start up soon!", error);
+ g_printf("Could not ping the DICE Daemon, but it should start up soon!\n");
+ g_error_free (error);
+ }
+ else
+ {
+ g_printf(" (ice) connected to the ICE Daemon.\n");
+ }
+
+ backend->ice_daemon = ice_daemon_proxy;
+}
+
+static void
+g_vfs_backend_dice_finalize (GObject *object)
+{
+ GVfsBackendDice *backend;
+
+ backend = G_VFS_BACKEND_DICE (object);
+
+ g_mount_spec_unref (backend->mount_spec);
+
+ if (G_OBJECT_CLASS (g_vfs_backend_dice_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_vfs_backend_dice_parent_class)->finalize) (object);
+}
+
+/*********************
+ * Utility Functions *
+ *********************/
+
+
+static void
+lose (const char *str, ...)
+{
+ va_list args;
+
+ va_start (args, str);
+
+ vfprintf (stderr, str, args);
+ fputc ('\n', stderr);
+
+ va_end (args);
+
+// exit (1);
+}
+
+
+static void
+lose_gerror (const char *prefix, GError *error)
+{
+ lose ("%s: %s", prefix, error->message);
+}
+
+
+/**
+ * Caller must free using g_free () if not NULL return.
+ */
+/*
+static char *
+get_last_path_component (const char *path)
+{
+ if (path == NULL)
+ return NULL;
+
+ g_printf (" (ice) get_last_path_component (%s)\n", path);
+ char *parsable_path = g_strdup (path);
+ char *path_component = NULL;
+ char *last_component = strtok (parsable_path, "/");
+ if (last_component != NULL)
+ {
+ while ((path_component = strtok (NULL, "/")) != NULL)
+ {
+ // Intentionally blank. Tokenize until we've reached
+ // the last token.
+ last_component = path_component;
+ }
+
+ // Make a copy of the last component
+ last_component = g_strdup (last_component);
+ }
+
+ g_free (parsable_path);
+
+ g_printf(" (ice) get_last_path_component () returning -> '%s'\n", last_component == NULL ? "(null)" : last_component);
+
+ return last_component;
+}
+*/
+
+static GFileInfo *
+create_file_info_from_dbus_array(GValueArray *array_obj)
+{
+ g_printf (" *** create_file_info_from_dbus_array () ***\n");
+ GFileInfo *info;
+
+ if (array_obj == NULL)
+ return NULL;
+
+ info = g_file_info_new ();
+
+ GValue *file_id = g_value_array_get_nth (array_obj, 0);
+ GValue *file_display_name = g_value_array_get_nth (array_obj, 1);
+ GValue *file_path = g_value_array_get_nth (array_obj, 2);
+ GValue *file_local_path = g_value_array_get_nth (array_obj, 3);
+ GValue *file_type = g_value_array_get_nth (array_obj, 4);
+ GValue *mime_type = g_value_array_get_nth (array_obj, 5);
+ GValue *file_access_mask = g_value_array_get_nth (array_obj, 6);
+ GValue *creation_time = g_value_array_get_nth (array_obj, 7);
+ GValue *last_access_time = g_value_array_get_nth (array_obj, 8);
+ GValue *last_modified_time = g_value_array_get_nth (array_obj, 9);
+ GValue *size = g_value_array_get_nth (array_obj, 10);
+ GValue *hidden = g_value_array_get_nth (array_obj, 11);
+
+
+
+
+ g_printf (" *** read a file info ***\n");
+ g_printf ("\t ID: %s\n", g_value_get_string (file_id));
+ g_printf ("\t Display Name: %s\n", g_value_get_string (file_display_name));
+ g_printf ("\t Path: %s\n", g_value_get_string (file_path));
+ g_printf ("\t Local Path: %s\n", g_value_get_string (file_local_path));
+ struct tm *tmp;
+ gint64 creationDateInSecondsFromEpoch = g_value_get_int64 (creation_time);
+ g_printf("timestamp: %lld\n", creationDateInSecondsFromEpoch);
+ tmp = localtime((time_t *)&creationDateInSecondsFromEpoch);
+ char timestr[200];
+
+ if (strftime(timestr, sizeof (timestr), "%F %T", tmp) != 0)
+ {
+ g_printf ("\tCreation Time: %s\n", timestr);
+ }
+ g_printf ("\t Mime Type: %s\n", g_value_get_string (mime_type));
+
+
+
+
+ g_file_info_set_name (info, g_value_get_string (file_path));
+ g_file_info_set_display_name (info, g_value_get_string (file_display_name));
+ switch (g_value_get_int (file_type))
+ {
+ case 2:
+ case 3:
+ g_printf ("\t Type: Directory\n");
+ gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_DIRECTORY);
+ break;
+ case 4:
+ g_printf ("\t Type: Regular\n");
+ gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_REGULAR);
+
+ // Store the local path in the file info
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH, g_value_get_string (file_local_path));
+ break;
+ default:
+ g_printf ("\t Type: Unknown\n");
+ gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_UNKNOWN);
+ break;
+ }
+ g_file_info_set_content_type (info, g_value_get_string (mime_type));
+
+ // File Access
+ uint access_mask = g_value_get_uint (file_access_mask);
+ if (access_mask & 1) // Read
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+ if (access_mask & 2) // Write
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+ if (access_mask & 4) // Execute
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, TRUE);
+ if (access_mask & 8) // CanDelete
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+ if (access_mask & 16) // CanTrash
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, TRUE);
+ if (access_mask && 32) // CanRename
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+
+ g_file_info_set_attribute_int64 (info, G_FILE_ATTRIBUTE_TIME_CREATED, g_value_get_int64 (creation_time));
+ g_file_info_set_attribute_int64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS, g_value_get_int64 (last_access_time));
+ g_file_info_set_attribute_int64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, g_value_get_int64 (last_modified_time));
+
+ g_file_info_set_size (info, g_value_get_uint64 (size));
+
+ g_file_info_set_is_hidden (info, g_value_get_boolean (hidden));
+
+ return info;
+}
+
+
+/**
+ * ???
+ *
+ * Note: The returned object should be freed by the caller.
+ */
+static GFileInfo*
+get_g_file_info_from_deskice (GVfsBackendDice *ice_backend,
+ const char *filename,// GFile *file,
+ const char *attributes, GFileQueryInfoFlags flags,
+ GVfsJob *job)
+{
+ g_printf("*** get_g_file_info_from_deskice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+ GFileInfo *info = NULL;
+
+ if (strlen (filename) == 1 && filename [0] == '/')
+ {
+ // This is the top-level item that will appear in
+ // Nautilus' sidebar as one of the "Places".
+ info = g_file_info_new ();
+ g_file_info_set_name (info, "/");
+ g_file_info_set_display_name (info, _("Workspaces"));
+ g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
+ return info;
+ }
+
+ // If we make it this far, we're dealing with either a
+ // workspace, a directory, or a file. Communicate via DBus
+ // to the DICE Daemon to determine the information for the
+ // given path.
+ GError *error;
+ if (ice_backend->ice_daemon == NULL)
+ return NULL;
+
+ GValueArray *dbus_file_info;
+
+ error = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon,
+ "GetFileByPath",
+ &error,
+ // Input Params
+ G_TYPE_STRING, filename, G_TYPE_INVALID,
+ // Output Params (struct of items)
+ dbus_g_type_get_struct (
+ "GValueArray",
+ G_TYPE_STRING, // Id
+ G_TYPE_STRING, // Display Name
+ G_TYPE_STRING, // Path
+ G_TYPE_STRING, // Local Path
+ G_TYPE_INT, // File Type
+ G_TYPE_STRING, // Mime Type
+ G_TYPE_UINT, // Access Mask
+ G_TYPE_INT64, // Creation Time
+ G_TYPE_INT64, // Last Access Time
+ G_TYPE_INT64, // Last Modified Time
+ G_TYPE_UINT64, // Size
+ G_TYPE_BOOLEAN, // Hidden
+ G_TYPE_INVALID),
+ &dbus_file_info,
+ G_TYPE_INVALID))
+ {
+ if (strstr(error->message, "Exception") != NULL)
+ {
+ g_printf ("No files for path: %s\n", error->message);
+ dbus_file_info = NULL;
+ }
+ else
+ {
+// lose_gerror ("Could not call DICE Daemon's GetFileByPath ()", error);
+// exit(-2);
+ g_printf("Could not call the DICE Daemon's GetFileByPath ()\n");
+ g_error_free (error);
+ return NULL;
+ }
+ g_error_free (error);
+ error = NULL;
+ }
+
+ if (dbus_file_info != NULL)
+ {
+ info = create_file_info_from_dbus_array(dbus_file_info);
+
+ g_value_array_free (dbus_file_info);
+ }
+
+ g_printf(" returning from get_g_file_info_from_deskice\n");
+
+ return info;
+}
+
+// Caller must free the returned GFileInfo on success
+static GFileInfo*
+create_g_file_info_in_deskice(GVfsBackendDice *ice_backend,
+ const char *filename)
+{
+ g_printf("*** create_g_file_info_in_deskice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+ GFileInfo *info = NULL;
+
+ GError *error;
+ if (ice_backend->ice_daemon == NULL)
+ return NULL;
+
+ GValueArray *dbus_file_info = NULL;
+
+ error = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon,
+ "CreateLocalFile",
+ &error,
+ // Input Params
+ G_TYPE_STRING, filename, G_TYPE_INVALID,
+ // Output Params (struct of items)
+ dbus_g_type_get_struct (
+ "GValueArray",
+ G_TYPE_STRING, // Id
+ G_TYPE_STRING, // Display Name
+ G_TYPE_STRING, // Path
+ G_TYPE_STRING, // Local Path
+ G_TYPE_INT, // File Type
+ G_TYPE_STRING, // Mime Type
+ G_TYPE_UINT, // Access Mask
+ G_TYPE_INT64, // Creation Time
+ G_TYPE_INT64, // Last Access Time
+ G_TYPE_INT64, // Last Modified Time
+ G_TYPE_UINT64, // Size
+ G_TYPE_BOOLEAN, // Hidden
+ G_TYPE_INVALID),
+ &dbus_file_info,
+ G_TYPE_INVALID))
+ {
+ if (strstr(error->message, "Exception") != NULL)
+ {
+ g_printf ("Could not create file '%s': %s\n", filename, error->message);
+ dbus_file_info = NULL;
+ }
+ else
+ {
+// lose_gerror ("Could not call DICE Daemon's CreateLocalFile ()", error);
+// exit(-2);
+ g_printf("Could not call the DICE Daemon's CreateLocalFile ()\n");
+ g_error_free (error);
+ return NULL;
+ }
+ g_error_free (error);
+ error = NULL;
+ }
+
+ if (dbus_file_info != NULL)
+ {
+ info = create_file_info_from_dbus_array(dbus_file_info);
+
+ g_value_array_free (dbus_file_info);
+ }
+
+ g_printf(" returning from create_g_file_info_in_deskice ()\n");
+
+ return info;
+}
+
+
+// Returns TRUE if the file was updated successfully.
+// If FALSE, the caller must free the GError that may be set.
+static gboolean
+delete_local_file_from_deskice(GVfsBackendDice *ice_backend,
+ const char *filename,
+ GError **error)
+{
+ GError *anError;
+ g_printf("*** delete_local_file_from_deskice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+
+ if (ice_backend->ice_daemon == NULL)
+ return FALSE; // TODO: Fix this with a real error
+
+ if (error != NULL)
+ *error = NULL;
+ anError = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon,
+ "DeleteLocalFile",
+ &anError,
+ // Input Params
+ G_TYPE_STRING, filename, G_TYPE_INVALID,
+ G_TYPE_INVALID)) // Output Params (none)
+ {
+ if (strstr(anError->message, "Exception") != NULL)
+ {
+ g_printf ("Could not delete file '%s': %s\n", filename, anError->message);
+ }
+ else
+ {
+// lose_gerror ("Could not call DICE Daemon's DeleteLocalFile ()", anError);
+// exit(-2);
+ g_printf("Could not call the DICE Daemon's DeleteLocalFile ()\n");
+ g_error_free (anError);
+ return FALSE;
+ }
+ if (error != NULL)
+ *error = anError;
+ return FALSE;
+ }
+
+ g_printf(" returning from delete_local_file_from_deskice ()\n");
+ return TRUE;
+}
+
+
+// This should be called any time our provider modifies a
+// file. Basically any time we close a file handle. Returns
+// TRUE if the file was updated successfully. If FALSE, the
+// caller must free the GError that may be set.
+static gboolean
+update_local_file_in_deskice(GVfsBackendDice *ice_backend,
+ const char *filename,
+ GError **error)
+{
+ GError *anError;
+ g_printf("*** update_local_file_in_deskice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+
+ if (ice_backend->ice_daemon == NULL)
+ return FALSE; // TODO: Fix this with a real error
+
+ if (error != NULL)
+ *error = NULL;
+ anError = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon,
+ "UpdateLocalFile",
+ &anError,
+ // Input Params
+ G_TYPE_STRING, filename, G_TYPE_INVALID,
+ G_TYPE_INVALID)) // Output Params (none)
+ {
+ if (strstr(anError->message, "Exception") != NULL)
+ {
+ g_printf ("Could not update file '%s': %s\n", filename, anError->message);
+ }
+ else
+ {
+// lose_gerror ("Could not call DICE Daemon's UpdateLocalFile ()", anError);
+// exit(-2);
+ g_printf("Could not call the DICE Daemon's UpdateLocalFile ()\n");
+ g_error_free (anError);
+ return FALSE;
+ }
+ if (error != NULL)
+ *error = anError;
+ return FALSE;
+ }
+
+ g_printf(" returning from update_local_file_in_deskice ()\n");
+ return TRUE;
+}
+
+
+// Caller must free the returned GFileInfo!
+static GFileInfo *
+get_g_filesystem_info_from_deskice (
+ GFile *file,
+ const char *attributes,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GFileInfo *info = g_file_info_new ();
+
+ // TODO: Implement get_g_filesystem_info_from_deskice
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, FALSE);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, 262144000);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, 524288000);
+
+ return info;
+}
+
+
+/* returned object should be freed in user's function */
+static GFile*
+get_g_file_from_local (const char *filename, GVfsJob *job)
+{
+ GVfs *local_vfs;
+ GFile *file = NULL;
+
+ local_vfs = g_vfs_get_local ();
+ if (! local_vfs) {
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Cannot get local vfs");
+ g_print (" (EE) get_g_file_from_local (filename = '%s'): local_vfs == NULL \n", filename);
+ return NULL;
+ }
+
+ file = g_vfs_get_file_for_path (local_vfs, filename);
+ if (! file) {
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Cannot get file from local vfs");
+ g_print (" (EE) get_g_file_from_local (filename = '%s'): file == NULL \n", filename);
+ return NULL;
+ }
+ return file;
+}
+
+
+/************
+ * Mounting *
+ ************/
+
+static void
+do_mount (GVfsBackend *backend,
+ GVfsJobMount *job,
+ GMountSpec *mount_spec,
+ GMountSource *mount_source,
+ gboolean is_automount)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+
+ g_print ("(ice) do_mount \n");
+
+ g_vfs_backend_set_display_name (backend, _("Workspaces"));
+
+ ice_backend->mount_spec = g_mount_spec_new ("dice");
+ g_vfs_backend_set_mount_spec (backend, ice_backend->mount_spec);
+
+ g_vfs_backend_set_icon_name (backend, "network-server");
+
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+static void
+do_unmount (GVfsBackend *backend, GVfsJobUnmount *job)
+{
+ GVfsBackendDice *ice_backend;
+
+ g_print ("(ice) do_umount \n");
+
+ ice_backend = G_VFS_BACKEND_DICE (backend);
+ g_mount_spec_unref (ice_backend->mount_spec);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+
+/*******************
+ * Query Functions *
+ *******************/
+
+
+static void
+do_query_info (GVfsBackend *backend,
+ GVfsJobQueryInfo *job,
+ const char *filename,
+ GFileQueryInfoFlags flags,
+ GFileInfo *info,
+ GFileAttributeMatcher *matcher)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GFileInfo *info2;
+
+ g_print ("(ice) do_query_info (filename = %s)\n", filename);
+
+ info2 = get_g_file_info_from_deskice (ice_backend, filename, /*file,*/ "*", flags, G_VFS_JOB (job));
+
+ if (info2) {
+ g_file_info_copy_into (info2, info);
+ g_object_unref (info2);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(ice) do_query_info success. \n");
+ }
+ else
+ {
+ g_print ("(ice) do_query_info failed. \n");
+ }
+}
+
+
+static void
+do_query_fs_info (GVfsBackend *backend,
+ GVfsJobQueryFsInfo *job,
+ const char *filename,
+ GFileInfo *info,
+ GFileAttributeMatcher *attribute_matcher)
+{
+ GFile *file;
+ GFileInfo *info2;
+ GError *error;
+
+ g_print ("(ice) do_query_fs_info (filename = %s) \n", filename);
+ file = g_file_new_for_path (filename);
+ if (file)
+ {
+ error = NULL;
+ info2 = get_g_filesystem_info_from_deskice (file, "fs:*", G_VFS_JOB (job)->cancellable, &error);
+ if ((error) || (! info2) )
+ {
+ g_print (" (ice) do_query_fs_info (filename = '%s'): g_file_query_filesystem_info failed: %s \n", filename, error->message);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+ else
+ {
+ g_file_info_copy_into (info2, info);
+ g_object_unref (info2);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(ice) do_query_fs_info success. \n");
+ }
+
+ g_object_unref (file);
+ }
+ else
+ {
+ g_print ("(ice) do_query_fs_info failed. \n");
+ }
+}
+
+
+static void
+do_enumerate (GVfsBackend *backend,
+ GVfsJobEnumerate *job,
+ const char *filename,
+ GFileAttributeMatcher *attribute_matcher,
+ GFileQueryInfoFlags flags)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GPtrArray *files = NULL;
+ GFileInfo *info;
+ GError *error;
+
+ g_print ("(ice) do_enumerate (filename = %s) \n", filename);
+
+ if (strlen (filename) == 1 && filename [0] == '/')
+ {
+ g_print(" ---> calling EnumerateWorkspaces ()\n");
+ // Read in all the workspaces
+ error = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon, "EnumerateWorkspaces", &error,
+ // Input params (none)
+ G_TYPE_INVALID,
+ // Output params
+ dbus_g_type_get_collection ("GPtrArray", dbus_g_type_get_struct ("GValueArray",
+ G_TYPE_STRING, // Id
+ G_TYPE_STRING, // Display Name
+ G_TYPE_STRING, // Path
+ G_TYPE_STRING, // Local Path
+ G_TYPE_INT, // File Type
+ G_TYPE_STRING, // Mime Type
+ G_TYPE_UINT, // Access Mask
+ G_TYPE_INT64, // Creation Time
+ G_TYPE_INT64, // Last Access Time
+ G_TYPE_INT64, // Last Modified Time
+ G_TYPE_UINT64, // Size
+ G_TYPE_BOOLEAN, // Hidden
+ G_TYPE_INVALID)),
+ &files,
+ G_TYPE_INVALID))
+ {
+ if (strstr(error->message, "Exception") != NULL)
+ {
+ g_printf ("No files for path: %s\n", error->message);
+ files = NULL;
+ }
+ else
+ {
+// lose_gerror ("Could not enumerate the workspaces", error);
+// exit(-2);
+ g_printf("Could not enumerate the workspaces\n");
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+
+ g_error_free (error);
+ error = NULL;
+ }
+ }
+ else
+ {
+ g_print(" ---> calling EnumerateFiles ()\n");
+ // Read in the files contained in a specific directory
+ error = NULL;
+ if (!dbus_g_proxy_call (ice_backend->ice_daemon, "EnumerateFiles", &error,
+ // Input params
+ G_TYPE_STRING, filename,
+ G_TYPE_INVALID,
+ // Output params
+ dbus_g_type_get_collection ("GPtrArray", dbus_g_type_get_struct ("GValueArray",
+ G_TYPE_STRING, // Id
+ G_TYPE_STRING, // Display Name
+ G_TYPE_STRING, // Path
+ G_TYPE_STRING, // Local Path
+ G_TYPE_INT, // File Type
+ G_TYPE_STRING, // Mime Type
+ G_TYPE_UINT, // Access Mask
+ G_TYPE_INT64, // Creation Time
+ G_TYPE_INT64, // Last Access Time
+ G_TYPE_INT64, // Last Modified Time
+ G_TYPE_UINT64, // Size
+ G_TYPE_BOOLEAN, // Hidden
+ G_TYPE_INVALID)),
+ &files,
+ G_TYPE_INVALID))
+ {
+ g_print(" <--- calling EnumerateFiles () in failure case\n");
+ if (strstr(error->message, "Exception") != NULL)
+ {
+ g_printf ("No files for path: %s\n", error->message);
+ files = NULL;
+ }
+ else
+ {
+// lose_gerror ("Could not enumerate the directory", error);
+// exit(-2);
+ g_printf("Could not enumerate the directory\n");
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+ g_error_free (error);
+ error = NULL;
+ }
+ }
+
+ g_print(" ---- EnumerateFiles () out of dbus call\n");
+ // Enumerate the files and create GFileInfos to add and publish
+ // over DBus.
+
+ // You have to say succeeded before doing anything else
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ if (files != NULL)
+ {
+ int i;
+ for (i = 0; i < files->len; i++)
+ {
+ GValueArray *dbus_array_obj = g_ptr_array_index (files, i);
+ if (dbus_array_obj != NULL)
+ {
+ info = create_file_info_from_dbus_array(dbus_array_obj);
+ g_vfs_job_enumerate_add_info (job, info);
+ g_object_unref (info);
+ }
+ }
+
+ g_ptr_array_free (files, TRUE);
+ }
+
+ g_vfs_job_enumerate_done (job);
+ g_print ("(ice) do_enumerate done. \n");
+}
+
+
+/******************
+ * Read Functions *
+ ******************/
+
+
+static void
+do_open_for_read (GVfsBackend *backend,
+ GVfsJobOpenForRead *job,
+ const char *filename)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ struct IceInputStream *ice_stream;
+ GFileInputStream *stream;
+ GError *error;
+ GFile *file;
+ GFileInfo *info;
+
+ g_print ("(II) do_open_for_read (filename = '%s') \n", filename);
+
+ info = get_g_file_info_from_deskice (ice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job));
+
+ g_assert (info != NULL);
+
+ // Get the local path of the file
+ const char *local_path = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+ g_assert (local_path != NULL);
+
+ file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+ g_object_unref (info);
+
+ if (file)
+ {
+ error = NULL;
+ stream = g_file_read (file, G_VFS_JOB (job)->cancellable, &error);
+ if (stream)
+ {
+ ice_stream = malloc (sizeof (struct IceInputStream));
+ ice_stream->stream = stream;
+ ice_stream->file_path = strdup (filename);
+ g_vfs_job_open_for_read_set_can_seek (job, g_seekable_can_seek (G_SEEKABLE (stream)));
+ g_vfs_job_open_for_read_set_handle (job, ice_stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_open_for_read success. \n");
+ }
+ else
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_open_for_read: stream == NULL, error: %s \n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (file);
+ }
+ else
+ {
+ g_print (" (EE) do_open_for_read: file == NULL \n");
+ g_vfs_job_failed (G_VFS_JOB (job),
+ G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to create GFile, file == NULL"));
+ }
+}
+
+
+static void
+do_read (GVfsBackend *backend,
+ GVfsJobRead *job,
+ GVfsBackendHandle _handle,
+ char *buffer,
+ gsize bytes_requested)
+{
+ GError *error;
+ struct IceInputStream *ice_stream = (struct IceInputStream *)_handle;
+// GFileInputStream *stream = _handle;
+ gssize s;
+
+ g_print ("(II) do_read (handle = '%lx', buffer = '%lx', bytes_requested = %ld) \n",
+ (long int)ice_stream->stream, (long int)buffer, (long int)bytes_requested);
+
+ g_assert (ice_stream != NULL);
+
+ error = NULL;
+ s = g_input_stream_read (G_INPUT_STREAM (ice_stream->stream), buffer, bytes_requested,
+ G_VFS_JOB (job)->cancellable, &error);
+ if (s >= 0) {
+ g_vfs_job_read_set_size (job, s);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_read success. \n");
+ } else {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_read: g_input_stream_read() failed, error: %s \n", error->message);
+ g_error_free (error);
+ }
+}
+
+
+static void
+do_seek_on_read (GVfsBackend *backend,
+ GVfsJobSeekRead *job,
+ GVfsBackendHandle _handle,
+ goffset offset,
+ GSeekType type)
+{
+ GError *error;
+ struct IceInputStream *ice_stream = (struct IceInputStream *)_handle;
+// GFileInputStream *stream = _handle;
+
+ g_print ("(II) do_seek_on_read (handle = '%lx', offset = %ld) \n", (long int)ice_stream->stream, (long int)offset);
+
+ g_assert (ice_stream != NULL);
+
+ error = NULL;
+ if (g_seekable_seek (G_SEEKABLE (ice_stream->stream), offset, type, G_VFS_JOB (job)->cancellable, &error)) {
+ g_vfs_job_seek_read_set_offset (job, g_seekable_tell (G_SEEKABLE (ice_stream->stream)));
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_seek_on_read success. \n");
+ } else {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_seek_on_read: g_file_input_stream_seek() failed, error: %s \n", error->message);
+ g_error_free (error);
+ }
+}
+
+
+static void
+do_close_read (GVfsBackend *backend,
+ GVfsJobCloseRead *job,
+ GVfsBackendHandle _handle)
+{
+ GError *error;
+ struct IceInputStream *ice_stream = (struct IceInputStream *)_handle;
+// GFileInputStream *stream = _handle;
+
+ g_print ("(II) try_close_read (handle = '%lx') \n", (long int)ice_stream->stream);
+
+ g_assert (ice_stream != NULL);
+
+ error = NULL;
+ if (g_input_stream_close (G_INPUT_STREAM (ice_stream->stream), G_VFS_JOB (job)->cancellable, &error)) {
+ free (ice_stream->file_path);
+ g_object_unref (ice_stream->stream);
+ free (ice_stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) try_close_read success. \n");
+ } else {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) try_close_read: g_input_stream_close() failed, error: %s \n", error->message);
+ g_error_free (error);
+ }
+}
+
+
+/*******************
+ * Write Functions *
+ *******************/
+
+
+static void
+do_create (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+ GFileInfo *info;
+ GFile *file;
+ struct IceOutputStream *ice_stream;
+
+ info = get_g_file_info_from_deskice (ice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job));
+
+// g_file_new_for_path (filename);
+ if (info)
+ {
+ g_object_unref (info);
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already exists"));
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+
+ // Actually create the file in deskice
+ info = create_g_file_info_in_deskice(ice_backend, filename);
+
+ if (info == NULL)
+ {
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, _("Error creating the file in deskice"));
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+
+ // Open the real local file file!
+ const char *local_path = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+ g_assert (local_path != NULL);
+
+ file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+ g_object_unref (info);
+
+ error = NULL;
+ GFileOutputStream *stream = g_file_create (file, flags, G_VFS_JOB (job)->cancellable, &error);
+ if (stream == NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+ else
+ {
+ // Wrap the GFileOutputStream into an IceOutputStream so we can
+ // keep track of the original file path.
+ ice_stream = malloc (sizeof (struct IceOutputStream));
+ ice_stream->file_path = strdup (filename);
+ ice_stream->stream = stream;
+
+ g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), ice_stream);
+ g_vfs_job_open_for_write_set_can_seek (G_VFS_JOB_OPEN_FOR_WRITE (job), g_seekable_can_seek (G_SEEKABLE (stream)));
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ }
+ g_object_unref (file);
+}
+
+
+static void
+do_close_write (GVfsBackend *backend,
+ GVfsJobCloseWrite *job,
+ GVfsBackendHandle handle)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+ struct IceOutputStream *ice_stream = (struct IceOutputStream *)handle;
+ //GFileOutputStream *stream = (GFileOutputStream *)handle;
+
+ g_print ("(II) do_close_write (handle = '%lx') \n", (long int)handle);
+
+ g_assert (ice_stream != NULL);
+
+ error = NULL;
+ if (g_output_stream_close (G_OUTPUT_STREAM(ice_stream->stream), G_VFS_JOB (job)->cancellable, &error))
+ {
+ // Notify DICE Daemon that the file has been closed/changed
+ error = NULL;
+ if (update_local_file_in_deskice(ice_backend,
+ ice_stream->file_path,
+ &error) == FALSE)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_close_write: g_input_stream_close() failed, error: %s \n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ g_object_unref (ice_stream->stream);
+ free (ice_stream->file_path);
+ free (ice_stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_close_write success. \n");
+ } else {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_close_write: g_input_stream_close() failed, error: %s \n", error->message);
+ g_error_free (error);
+ }
+}
+
+
+static void
+do_write (GVfsBackend *backend,
+ GVfsJobWrite *job,
+ GVfsBackendHandle handle,
+ char *buffer,
+ gsize buffer_size)
+{
+ GError *error;
+ struct IceOutputStream *ice_stream = (struct IceOutputStream *)handle;
+ //GFileOutputStream *stream = (GFileOutputStream *)handle;
+ gssize s;
+
+// g_print ("(II) do_write (handle = '%lx', buffer = '%lx', buffer_size = %ld) \n",
+// (long int)_handle, (long int)buffer, (long int)buffer_size);
+
+ g_assert (ice_stream != NULL);
+
+ error = NULL;
+ s = g_output_stream_write (G_OUTPUT_STREAM (ice_stream->stream), buffer, buffer_size, G_VFS_JOB (job)->cancellable, &error);
+ if (s >= 0) {
+ g_vfs_job_write_set_written_size (job, s);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_write success. \n");
+ } else {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_write: g_output_stream_write() failed, error: %s \n", error->message);
+ g_error_free (error);
+ }
+}
+
+
+static void
+do_append (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+ GFileInfo *info;
+ GFile *file;
+ struct IceOutputStream *ice_stream;
+ //GFileOutputStream *stream;
+
+ g_print ("(II) do_append (filename = %s) \n", filename);
+
+ info = get_g_file_info_from_deskice (ice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job));
+
+ if (info == NULL)
+ {
+ // The file must not exist, so just use the create function
+ do_create (backend, job, filename, flags);
+ return;
+ }
+
+ // Get the real local path
+ const char *local_path = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+ g_assert (local_path != NULL);
+
+ file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+ g_object_unref (info);
+
+ g_assert (file != NULL);
+
+ if (file)
+ {
+ error = NULL;
+ ice_stream = malloc (sizeof (struct IceOutputStream));
+ ice_stream->stream = g_file_append_to (file, flags, G_VFS_JOB (job)->cancellable, &error);
+ if (ice_stream->stream)
+ {
+ /* Should seek at the end of the file here */
+ if ((g_seekable_seek (G_SEEKABLE (ice_stream->stream), 0, G_SEEK_END, G_VFS_JOB (job)->cancellable, &error)) && (! error))
+ {
+ g_vfs_job_open_for_write_set_initial_offset (job, g_seekable_tell (G_SEEKABLE (ice_stream->stream)));
+ }
+ else
+ {
+ g_print (" (EE) do_append: error during g_file_output_stream_seek(), error: %s \n", error->message);
+ }
+
+ // Store the filename so we can close properly and notify the DICE Daemon
+ ice_stream->file_path = strdup (filename);
+ g_vfs_job_open_for_write_set_can_seek (job, g_seekable_can_seek (G_SEEKABLE (ice_stream->stream)));
+ g_vfs_job_open_for_write_set_handle (job, ice_stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ g_print ("(II) do_append success. \n");
+ }
+ else
+ {
+ free (ice_stream);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_append: stream == NULL, error: %s \n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (file);
+ }
+ else
+ {
+ g_print (" (EE) do_append: file == NULL \n");
+ }
+}
+
+
+static void
+do_replace (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ struct IceOutputStream *ice_stream;
+ //GFileOutputStream *stream;
+ GError *error;
+ GFile *file;
+ GFileInfo *info;
+
+ g_print ("(II) do_replace (filename = '%s', etag = '%s') \n", filename, etag);
+
+ info = get_g_file_info_from_deskice (ice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job));
+
+ if (info == NULL)
+ {
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Error in do_replace, file not found in deskice"));
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+
+ // Get the real local path
+ const char *local_path = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+ g_assert (local_path != NULL);
+
+ file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+ g_object_unref (info);
+
+ g_assert (file != NULL);
+
+ if (file)
+ {
+ error = NULL;
+ ice_stream = malloc (sizeof (struct IceOutputStream));
+ ice_stream->stream = g_file_replace (file, etag, make_backup, flags, G_VFS_JOB (job)->cancellable, &error);
+ if (ice_stream->stream)
+ {
+ // Save off the filename so we can notify DICE Daemon during a close
+ ice_stream->file_path = strdup (filename);
+ g_vfs_job_open_for_write_set_can_seek (job, g_seekable_can_seek (G_SEEKABLE (ice_stream->stream)));
+ g_vfs_job_open_for_write_set_handle (job, ice_stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_replace success. \n");
+ }
+ else
+ {
+ free (ice_stream);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_replace: stream == NULL, error: %s \n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (file);
+ }
+ else
+ {
+ g_print (" (EE) do_replace: file == NULL \n");
+ }
+}
+
+
+static void
+do_delete (GVfsBackend *backend,
+ GVfsJobDelete *job,
+ const char *filename)
+{
+ GVfsBackendDice *ice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+
+ g_print ("(II) do_delete (filename = %s) \n", filename);
+
+ if (filename != NULL)
+ {
+ error = NULL;
+ if (delete_local_file_from_deskice(ice_backend,
+ filename,
+ &error))
+ {
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_delete success. \n");
+ }
+ else
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_delete: g_file_delete == FALSE, error: %s \n", error->message);
+ g_error_free (error);
+ }
+ }
+ else
+ {
+ g_print (" (EE) do_delete: filename == NULL \n");
+ }
+}
+
+
+static void
+g_vfs_backend_dice_class_init (GVfsBackendDiceClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass);
+
+ gobject_class->finalize = g_vfs_backend_dice_finalize;
+
+ backend_class->mount = do_mount;
+ backend_class->unmount = do_unmount;
+ backend_class->query_info = do_query_info;
+ backend_class->query_fs_info = do_query_fs_info;
+ backend_class->enumerate = do_enumerate;
+
+ backend_class->open_for_read = do_open_for_read;
+ backend_class->read = do_read;
+ backend_class->seek_on_read = do_seek_on_read;
+ backend_class->close_read = do_close_read;
+
+ backend_class->create = do_create;
+ backend_class->close_write = do_close_write;
+ backend_class->write = do_write;
+ backend_class->append_to = do_append;
+ backend_class->replace = do_replace;
+
+ backend_class->delete = do_delete;
+
+// backend_class->move = do_move;
+// backend_class->make_directory = do_make_directory;
+
+// backend_class->create_dir_monitor = do_create_dir_monitor;
+// backend_class->create_file_monitor = do_create_file_monitor;
+}
Property changes on: daemon/gvfsbackenddice.c
___________________________________________________________________
Added: svn:mergeinfo
Index: daemon/gvfsbackenddice.h
===================================================================
--- daemon/gvfsbackenddice.h (revision 0)
+++ daemon/gvfsbackenddice.h (revision 0)
@@ -0,0 +1,50 @@
+/* Novell IceDesktop Backend for GVfs
+ *
+ * Copyright (C) 2008 Novell, 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: Boyd Timothy <btimothy@novell.com>
+ */
+
+#ifndef __G_VFS_BACKEND_DICE_H__
+#define __G_VFS_BACKEND_DICE_H__
+
+#include <gvfsbackend.h>
+#include <gmountspec.h>
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_BACKEND_DICE (g_vfs_backend_dice_get_type ())
+#define G_VFS_BACKEND_DICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDice))
+#define G_VFS_BACKEND_DICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDiceClass))
+#define G_VFS_IS_BACKEND_DICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_BACKEND_DICE))
+#define G_VFS_IS_BACKEND_DICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_BACKEND_DICE))
+#define G_VFS_BACKEND_DICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDiceClass))
+
+typedef struct _GVfsBackendDice GVfsBackendDice;
+typedef struct _GVfsBackendDiceClass GVfsBackendDiceClass;
+
+struct _GVfsBackendDiceClass
+{
+ GVfsBackendClass parent_class;
+};
+
+GType g_vfs_backend_dice_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __G_VFS_BACKEND_DICE_H__ */
Property changes on: daemon/gvfsbackenddice.h
___________________________________________________________________
Added: svn:mergeinfo
Index: daemon/Makefile.am
===================================================================
--- daemon/Makefile.am (revision 1814)
+++ daemon/Makefile.am (working copy)
@@ -8,6 +8,7 @@
-I$(top_srcdir)/common \
-I$(top_builddir) \
$(GLIB_CFLAGS) $(DBUS_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
$(OBEXFTP_CFLAGS) $(XML_CFLAGS) \
$(KEYRING_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \
@@ -21,7 +22,7 @@
libraries = \
libdaemon.la \
$(top_builddir)/common/libgvfscommon.la \
- $(GLIB_LIBS) $(DBUS_LIBS) $(KEYRING_LIBS)
+ $(GLIB_LIBS) $(DBUS_LIBS) $(DBUS_GLIB_LIBS) $(KEYRING_LIBS)
# D-BUS service file
%.service: %.service.in ../config.log
@@ -34,10 +35,10 @@
%.mount: %.mount.in ../config.log
sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
-libexec_PROGRAMS=gvfsd gvfsd-sftp gvfsd-trash gvfsd-computer gvfsd-burn gvfsd-localtest
+libexec_PROGRAMS=gvfsd gvfsd-sftp gvfsd-trash gvfsd-dice gvfsd-computer gvfsd-burn gvfsd-localtest
-mount_in_files = sftp.mount.in trash.mount.in computer.mount.in burn.mount.in localtest.mount.in
-mount_DATA = sftp.mount trash.mount computer.mount burn.mount localtest.mount
+mount_in_files = sftp.mount.in trash.mount.in dice.mount.in computer.mount.in burn.mount.in localtest.mount.in
+mount_DATA = sftp.mount trash.mount dice.mount computer.mount burn.mount localtest.mount
mount_in_files += http.mount.in dav.mount.in ftp.mount.in
if HAVE_HTTP
@@ -264,6 +265,19 @@
gvfsd_trash_LDADD = $(libraries)
+gvfsd_dice_SOURCES = \
+ gvfsbackenddice.c gvfsbackenddice.h \
+ daemon-main.c daemon-main.h \
+ daemon-main-generic.c
+
+gvfsd_dice_CPPFLAGS = \
+ -DBACKEND_HEADER=gvfsbackenddice.h \
+ -DDEFAULT_BACKEND_TYPE=dice \
+ -DMAX_JOB_THREADS=10 \
+ -DBACKEND_TYPES='"dice", G_VFS_TYPE_BACKEND_DICE,'
+
+gvfsd_dice_LDADD = $(libraries)
+
gvfsd_computer_SOURCES = \
gvfsbackendcomputer.c gvfsbackendcomputer.h \
daemon-main.c daemon-main.h \
Index: daemon/dice.mount.in
===================================================================
--- daemon/dice.mount.in (revision 0)
+++ daemon/dice.mount.in (revision 0)
@@ -0,0 +1,5 @@
+[Mount]
+Type=dice
+Exec=@libexecdir@/gvfsd-dice
+AutoMount=true
+DBusName=org.gtk.vfs.mountpoint.dice
Property changes on: daemon/dice.mount.in
___________________________________________________________________
Added: svn:mergeinfo