gvfs/gvfs-dice-backend.patch

2134 lines
59 KiB
Diff

diff -Naur ./gvfs-1.0.2.orig/configure.ac gvfs-1.0.2/configure.ac
--- ./gvfs-1.0.2.orig/configure.ac 2008-09-24 12:02:11.000000000 -0600
+++ gvfs-1.0.2/configure.ac 2008-11-07 14:52:13.000000000 -0700
@@ -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)
diff -Naur ./gvfs-1.0.2.orig/daemon/dice.mount.in gvfs-1.0.2/daemon/dice.mount.in
--- ./gvfs-1.0.2.orig/daemon/dice.mount.in 1969-12-31 17:00:00.000000000 -0700
+++ gvfs-1.0.2/daemon/dice.mount.in 2008-11-07 15:02:26.000000000 -0700
@@ -0,0 +1,6 @@
+[Mount]
+Type=dice
+Exec=@libexecdir@/gvfsd-dice
+AutoMount=true
+DBusName=org.gtk.vfs.mountpoint.dice
+
diff -Naur ./gvfs-1.0.2.orig/daemon/gvfsbackenddice.c gvfs-1.0.2/daemon/gvfsbackenddice.c
--- ./gvfs-1.0.2.orig/daemon/gvfsbackenddice.c 1969-12-31 17:00:00.000000000 -0700
+++ gvfs-1.0.2/daemon/gvfsbackenddice.c 2008-11-07 14:53:39.000000000 -0700
@@ -0,0 +1,1989 @@
+/* Novell DICE 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>
+ * Brady Anderson <banderso@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 G_FILE_ATTRIBUTE_DICE_LOCAL_PATH "dice::local-path"
+#define G_FILE_ATTRIBUTE_DICE_ID "dice::id"
+
+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 *dice_proxy;
+
+ GMountSpec *mount_spec;
+ GList *top_files; /* Files in toplevel dir */
+ guint num_top_files;
+};
+
+struct DiceHandle
+{
+ char *file_path;
+ GFileInputStream *input_stream;
+ GFileOutputStream *output_stream;
+} *PDiceHandle;
+
+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 ("(dice) g_vfs_backend_dice_init \n");
+ GVfsBackendDice *backend = G_VFS_BACKEND_DICE (ice_backend);
+ backend->dbus_connection = NULL;
+
+ DBusGConnection *connection;
+ GError *error;
+ DBusGProxy *dice_proxy;
+
+ g_printf(" (dice) 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);
+ }
+
+ g_printf(" (dice) got a connection to the session bus\n");
+ backend->dbus_connection = connection;
+
+ dice_proxy =
+ dbus_g_proxy_new_for_name (
+ backend->dbus_connection,
+ "Novell.ICEDesktop.Daemon",
+ "/Novell/ICEDesktop/Daemon",
+ "Novell.ICEDesktop.Daemon");
+
+ gboolean ping_successful;
+ error = NULL;
+ if (!dbus_g_proxy_call (
+ dice_proxy,
+ "Ping",
+ &error,
+ G_TYPE_INVALID, // Input params
+ G_TYPE_BOOLEAN,
+ &ping_successful, // Output params
+ G_TYPE_INVALID))
+ {
+ lose_gerror ("Could not ping the DICE Daemon", error);
+ exit (-1);
+ }
+
+ g_printf (" (dice) connected to the DICE Daemon.\n");
+ backend->dice_proxy = dice_proxy;
+}
+
+static void
+g_vfs_backend_dice_finalize (GObject *object)
+{
+ GVfsBackendDice *dice;
+
+ dice = G_VFS_BACKEND_DICE (object);
+ g_mount_spec_unref (dice->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;
+}
+*/
+
+
+/*
+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 }
+*/
+
+// Method to convert all DICE Exceptions to an
+// equivalent GIO_ERROR.
+// The Exception class is returned and contained
+// in the error->message field.
+GError * convert_dice_error_to_gio_status (GError *dice_error)
+{
+ GError *error;
+
+ if (strstr (dice_error->message, "PathNotFoundException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NoEntriesException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NoWorkspacesException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NoFoldersException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NoFolderEntriesException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NoFileEntriesException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "FolderNotFoundException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "FileNotFoundException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("No such file or directory"));
+ }
+ else if (strstr (dice_error->message, "NotAFolderException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_DIRECTORY,
+ _("is not a directory"));
+ error->code = G_IO_ERROR_NOT_DIRECTORY;
+ }
+ else if (strstr (dice_error->message, "NotAFileException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_REGULAR_FILE,
+ _("is not a file"));
+ }
+ else if (strstr (error->message, "NotAuthenticatedException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED,
+ _("Access denied"));
+ }
+ else if (strstr (dice_error->message, "FailedAuthenticationException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED,
+ _("Access denied"));
+ }
+ else if (strstr (dice_error->message, "DiskFullException") != NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NO_SPACE,
+ _("No available space"));
+ }
+ else
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("General failure"));
+ }
+
+ return error;
+}
+
+static GFileInfo *
+create_file_info_from_dbus_array (GValueArray *array_obj)
+{
+ g_printf (" *** create_file_info_from_dbus_array () ***\n");
+
+ if (array_obj == NULL) return NULL;
+
+ GFileInfo *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_time;
+ char timestr[200];
+ gint64 creationDateInSecondsFromEpoch = g_value_get_int64 (creation_time);
+ g_printf("timestamp: %lld\n", creationDateInSecondsFromEpoch);
+ tmp_time = localtime ((time_t *)&creationDateInSecondsFromEpoch);
+ if (strftime(timestr, sizeof (timestr), "%F %T", tmp_time) != 0)
+ {
+ g_printf ("\t\tCreation Time: %s\n", timestr);
+ }
+
+ gint64 modifiedDateInSecondsFromEpoch = g_value_get_int64 (last_modified_time);
+ g_printf("timestamp: %lld\n", modifiedDateInSecondsFromEpoch);
+ tmp_time = localtime ((time_t *)&modifiedDateInSecondsFromEpoch);
+ if (strftime(timestr, sizeof (timestr), "%F %T", tmp_time) != 0)
+ {
+ g_printf ("\t\tModifed Time: %s\n", timestr);
+ }
+
+ // Set the name, display name and the unique id
+ g_file_info_set_name (info, g_value_get_string (file_display_name));
+ g_file_info_set_display_name (info, g_value_get_string (file_display_name));
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE, g_value_get_string (file_id));
+
+ switch (g_value_get_int (file_type))
+ {
+ case 2:
+ case 3:
+ g_printf ("\t\tType: Directory\n");
+ gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_DIRECTORY);
+ g_file_info_set_content_type (info, "inode/directory");
+ g_file_info_set_size (info, 4096);
+ break;
+
+ case 4:
+ g_printf ("\t\tType: 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_printf ("\t\tLocal Path: %s\n", g_value_get_string (file_local_path));
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH, g_value_get_string (file_local_path));
+
+ // File size
+ g_printf ("\t\tFile Size: %lu\n", g_value_get_uint64 (size));
+ g_file_info_set_size (info, g_value_get_uint64 (size));
+
+ // Mime type
+ g_printf ("\t\tMime Type: %s\n", g_value_get_string (mime_type));
+ g_file_info_set_content_type (info, g_value_get_string (mime_type));
+
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+ //g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+
+ break;
+
+ default:
+ g_printf ("\t\tType: Unknown\n");
+ gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_UNKNOWN);
+ break;
+ }
+
+ // File Access
+
+/*
+ uint access_mask = g_value_get_uint (file_access_mask);
+ g_printf ("\t Access: %X\n", access_mask);
+ if (access_mask & 1) // Read
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, FALSE);
+
+ if (access_mask & 2) // Write
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
+
+ if (access_mask & 4) // Execute
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, FALSE);
+
+ if (access_mask & 8) // CanDelete
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
+
+ if (access_mask & 16) // CanTrash
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
+
+ if (access_mask && 32) // CanRename
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE);
+ */
+
+ // Set the creation and modified times
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CREATED, creationDateInSecondsFromEpoch);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, modifiedDateInSecondsFromEpoch);
+
+ GTimeVal t;
+ t.tv_sec = modifiedDateInSecondsFromEpoch;
+ g_file_info_set_modification_time (info, &t);
+
+ g_file_info_set_is_hidden (info, FALSE);
+ return info;
+}
+
+
+static void enumerate_workspaces (
+ GVfsBackendDice *dice_backend,
+ GVfsJob *job)
+{
+ GPtrArray *files = NULL;
+ GFileInfo *info;
+ GError *dbus_error = NULL;
+ int dbus_status;
+
+ g_print ("(dice) enumerate_workspaces - called");
+
+ // Read in all the workspaces
+ dbus_status =
+ dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "EnumerateWorkspaces",
+ &dbus_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);
+
+ g_print ("dbus_status: %d\n", dbus_status);
+ g_print ("dbus_error: 0x%X\n", dbus_error);
+
+ if (dbus_status > 0 && dbus_error == NULL)
+ {
+ // You have to say succeeded before you add the infos
+ 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);
+ }
+ else
+ {
+ if (dbus_error != NULL)
+ {
+ if (strstr(dbus_error->message, "NoEntries") != NULL ||
+ strstr (dbus_error->message, "NoWorkspaces") != NULL ||
+ strstr (dbus_error->message, "NoFolders") != NULL ||
+ strstr (dbus_error->message, "NoFiles") != NULL)
+ {
+ g_printf ("Hit the no more entries case");
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_vfs_job_enumerate_done (job);
+ }
+ else
+ {
+ g_vfs_job_failed (
+ G_VFS_JOB (job),
+ G_IO_ERROR,
+ dbus_error->code,
+ dbus_error->message);
+ }
+ }
+ else
+ {
+ g_vfs_job_failed (
+ G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Error enumerating a directory"));
+
+ }
+
+ g_error_free (dbus_error);
+ }
+
+ g_print ("(dice) enumerate_workspaces. \n");
+}
+
+
+/**
+ * ???
+ *
+ * Note: The returned object should be freed by the caller.
+ */
+static GFileInfo*
+get_g_file_info_from_dice (
+ GVfsBackendDice *dice_backend,
+ const char *filename,// GFile *file,
+ const char *attributes,
+ GFileQueryInfoFlags flags,
+ GVfsJob *job,
+ GError **error)
+{
+ g_printf("*** get_g_file_info_from_dice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+ GError *dbus_error = NULL;
+ GFileInfo *info = NULL;
+ GValueArray *dbus_file_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, _("DICE"));
+ 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.
+ if (dice_backend->dice_proxy == NULL)
+ {
+ *error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("No connection to the DICE daemon"));
+
+ return NULL;
+ }
+
+ if (!dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "GetFileByPath",
+ &dbus_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))
+ {
+ *error = convert_dice_error_to_gio_status (dbus_error);
+ g_error_free (dbus_error);
+ }
+ else
+ if (dbus_file_info != NULL)
+ {
+ info = create_file_info_from_dbus_array (dbus_file_info);
+ g_value_array_free (dbus_file_info);
+ }
+
+ g_printf(" success - returning from get_g_file_info_from_dice\n");
+ return info;
+}
+
+// Caller must free the returned GFileInfo on success
+static GFileInfo*
+create_g_file_info_in_dice (
+ GVfsBackendDice *ice_backend,
+ const char *filename,
+ GError **error)
+{
+ g_printf("*** create_g_file_info_in_dice ()\n");
+ g_printf("\tfilename: %s\n", filename);
+ GFileInfo *info = NULL;
+
+ GError *dbus_error = NULL;
+ if (ice_backend->dice_proxy == NULL)
+ {
+ if (*error != NULL)
+ *error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("No connection to the DICE daemon"));
+
+ return NULL;
+ }
+
+ GValueArray *dbus_file_info = NULL;
+
+ if (!dbus_g_proxy_call (
+ ice_backend->dice_proxy,
+ "CreateLocalFile",
+ &dbus_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 (dbus_error->message, "Exception:") != NULL)
+ {
+ g_printf ("Could not create file '%s': %s\n", filename, dbus_error->message);
+ dbus_file_info = NULL;
+ }
+
+ // Convert the returned dice error to an equivalent GIO_ERROR
+ *error = convert_dice_error_to_gio_status (dbus_error);
+ g_error_free (dbus_error);
+ }
+ else
+ 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_dice ()\n");
+ return info;
+}
+
+
+// Returns TRUE if the file was successfully deleted.
+// If FALSE, the caller must free the GError that may be set.
+static gboolean
+delete_local_file_from_dice (
+ GVfsBackendDice *dice_backend,
+ const char *filename,
+ GError **error)
+{
+ GError *dbus_error;
+ g_printf ("*** delete_local_file_from_dice ()\n");
+ g_printf ("\tfilename: %s\n", filename);
+
+ if (dice_backend->dice_proxy == NULL)
+ {
+ *error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("No connection to the DICE daemon"));
+
+ return FALSE;
+ }
+
+ if (error != NULL) *error = NULL;
+
+ dbus_error = NULL;
+ if (!dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "DeleteLocalFile",
+ &dbus_error,
+ // Input Params
+ G_TYPE_STRING,
+ filename,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID)) // Output Params (none)
+ {
+ if (strstr(dbus_error->message, "Exception:") != NULL)
+ {
+ g_printf ("Could not delete file '%s': %s\n", filename, dbus_error->message);
+ }
+ else
+ {
+ g_printf ("Could not delete the file '%s'\n", filename);
+ g_printf ("Received an unexpected dbus error: %s\n", dbus_error->message);
+ }
+
+ *error = convert_dice_error_to_gio_status (dbus_error);
+ g_error_free (dbus_error);
+ return FALSE;
+ }
+
+ g_printf(" success - returning from delete_local_file_from_dice ()\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_dice (
+ GVfsBackendDice *dice_backend,
+ const char *filename,
+ GError **error)
+{
+ GError *dbus_error;
+ g_printf ("*** update_local_file_in_dice ()\n");
+ g_printf ("\tfilename: %s\n", filename);
+
+ if (dice_backend->dice_proxy == NULL)
+ {
+ *error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("No connection to the DICE daemon"));
+
+ return FALSE;
+ }
+
+ if (error != NULL) *error = NULL;
+
+ dbus_error = NULL;
+ if (!dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "UpdateLocalFile",
+ &dbus_error,
+ // Input Params
+ G_TYPE_STRING,
+ filename,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID)) // Output Params (none)
+ {
+ if (strstr(dbus_error->message, "Exception:") != NULL)
+ {
+ g_printf ("Could not update file '%s': %s\n", filename, dbus_error->message);
+ }
+
+ *error = convert_dice_error_to_gio_status (dbus_error);
+ g_error_free (dbus_error);
+ return FALSE;
+ }
+
+ g_printf(" success - returning from update_local_file_in_dice ()\n");
+ return TRUE;
+}
+
+//
+// Procedure for calling DICE to retrieve
+// file system information, creating a
+// GFileInfo structure and populating it
+// with the correct information.
+//
+// NOTE! The caller must free the returned
+// GFileInfo data structure
+//
+static GFileInfo *
+get_g_filesystem_info_from_dice (
+ GVfsBackendDice *dice_backend,
+ GFile *file,
+ const char *attributes,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *dbus_error;
+ GValueArray *dbus_filesystem_info = NULL;
+
+ g_printf ("*** get_g_filesystem_info_from_dice ()\n");
+ //g_printf ("\tfilename: %s\n", filename);
+
+ if (dice_backend->dice_proxy == NULL)
+ {
+ *error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("No connection to the DICE daemon"));
+
+ return NULL;
+ }
+
+ if (error != NULL) *error = NULL;
+
+ dbus_error = NULL;
+
+ if (!dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "GetFileSystemInformation",
+ &dbus_error,
+ // Input Params
+ G_TYPE_STRING,
+ "/",
+ G_TYPE_INVALID,
+ // Output Params (struct of items)
+ dbus_g_type_get_struct (
+ "GValueArray",
+ G_TYPE_STRING, // Label
+ G_TYPE_INT, // Attributes (RO,RW)
+ G_TYPE_INT64, // Total Size (in bytes)
+ G_TYPE_INT64, // Available Size (in bytes)
+ G_TYPE_INVALID),
+ &dbus_filesystem_info,
+ G_TYPE_INVALID))
+ {
+ if (strstr(dbus_error->message, "Exception:") != NULL)
+ {
+ g_printf ("Could not get file system information '%s'\n", dbus_error->message);
+ }
+ else
+ {
+ g_printf ("Could not call DICE daemon's GetFileSystemInformation ()");
+ g_printf ("Received an unexpected dbus error: %s\n", dbus_error->message);
+ }
+
+ *error = convert_dice_error_to_gio_status (dbus_error);
+ g_error_free (dbus_error);
+ return NULL;
+ }
+
+ GValue *label = g_value_array_get_nth (dbus_filesystem_info, 0);
+ GValue *fsattributes = g_value_array_get_nth (dbus_filesystem_info, 1);
+ GValue *total_space = g_value_array_get_nth (dbus_filesystem_info, 2);
+ GValue *available_space = g_value_array_get_nth (dbus_filesystem_info, 3);
+
+ GFileInfo *info = g_file_info_new ();
+ if (g_value_get_int (fsattributes) == 1)
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE);
+ else
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, FALSE);
+
+ gint64 total = 4000000000;
+ gint64 available = 3000000000;
+
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, total);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, available);
+// g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, g_value_get_int64 (total_space));
+// g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, g_value_get_int64 (available_space));
+
+ g_value_array_free (dbus_filesystem_info);
+ 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 *dice_backend = G_VFS_BACKEND_DICE (backend);
+
+ g_print ("(dice) do_mount \n");
+
+ g_vfs_backend_set_display_name (backend, _("My Spaces"));
+
+ dice_backend->mount_spec = g_mount_spec_new ("dice");
+ g_vfs_backend_set_mount_spec (backend, dice_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 *dice_backend;
+
+ g_print ("(dice) do_umount \n");
+
+ dice_backend = G_VFS_BACKEND_DICE (backend);
+ g_mount_spec_unref (dice_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 *dice_backend = G_VFS_BACKEND_DICE (backend);
+ GFileInfo *info2;
+ GError *error = NULL;
+
+ g_print ("(dice) (filename = %s)\n", filename);
+
+ // NOTE! get_g_file_info_from_dice is completing the job on failure
+ // this needs to change
+ info2 =
+ get_g_file_info_from_dice (
+ dice_backend,
+ filename,
+ /*file,*/ "*",
+ flags, G_VFS_JOB (job),
+ &error);
+ if (info2 != NULL && error == NULL)
+ {
+ g_file_info_copy_into (info2, info);
+ g_object_unref (info2);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(dice) do_query_info success. \n");
+ }
+ else
+ {
+ g_printf ("Error code: %d\n", error->code);
+ g_printf ("Error message: %s\n", error->message);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ g_print ("(dice) 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 = NULL;
+
+ g_print ("(dice) do_query_fs_info (filename = %s) \n", filename);
+ file = g_file_new_for_path (filename);
+ if (file != NULL)
+ {
+ info2 = get_g_filesystem_info_from_dice (backend, file, "fs:*", G_VFS_JOB (job)->cancellable, &error);
+ if ((error) || (!info2))
+ {
+ g_print (" (dice) 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);
+ }
+ else
+ {
+ g_file_info_copy_into (info2, info);
+ g_object_unref (info2);
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, "dice");
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(dice) do_query_fs_info success. \n");
+ }
+
+ g_object_unref (file);
+ }
+ else
+ {
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, _("Error creating a file info from a path"));
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print ("(dice) do_query_fs_info failed - creating a new path. \n");
+ }
+
+ if (error != NULL) g_error_free (error);
+}
+
+
+static void
+do_enumerate (
+ GVfsBackend *backend,
+ GVfsJobEnumerate *job,
+ const char *filename,
+ GFileAttributeMatcher *attribute_matcher,
+ GFileQueryInfoFlags flags)
+{
+ GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+ GPtrArray *files = NULL;
+ GFileInfo *info;
+ GError *dbus_error = NULL;
+ int dbus_status;
+
+ g_print ("(dice) do_enumerate (filename = %s) \n", filename);
+
+ if (strlen (filename) == 1 && filename [0] == '/')
+ {
+ g_print(" ---> calling EnumerateWorkspaces ()\n");
+
+ // Read in all the workspaces
+ dbus_status =
+ dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "EnumerateWorkspaces",
+ &dbus_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);
+ }
+ else
+ {
+ g_print(" ---> calling EnumerateFiles ()\n");
+
+ // Read in the files contained in a specific directory
+ int dbus_status =
+ dbus_g_proxy_call (
+ dice_backend->dice_proxy,
+ "EnumerateFiles",
+ &dbus_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 (" ---- EnumerateFiles () out of dbus call\n");
+ g_print ("dbus_status: %d\n", dbus_status);
+ g_print ("dbus_error: 0x%X\n", dbus_error);
+
+ if (dbus_status > 0 && dbus_error == NULL)
+ {
+ // You have to say succeeded before you add the infos
+ 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);
+ }
+ else
+ {
+ if (dbus_error != NULL)
+ {
+ if (strstr (dbus_error->message, "NoEntries") != NULL ||
+ strstr (dbus_error->message, "NoWorkspaces") != NULL ||
+ strstr (dbus_error->message, "NoFolders") != NULL ||
+ strstr (dbus_error->message, "NoFiles") != NULL)
+ {
+ g_printf ("Hit the no more entries case");
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_vfs_job_enumerate_done (job);
+ }
+ else
+ {
+ GError *error = convert_dice_error_to_gio_status (dbus_error);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+ }
+ else
+ {
+ g_vfs_job_failed (
+ G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Error enumerating a directory"));
+
+ }
+
+ g_error_free (dbus_error);
+ }
+
+ g_print ("(dice) do_enumerate done. \n");
+}
+
+
+/******************
+ * Read Functions *
+ ******************/
+
+static void
+do_open_for_read (
+ GVfsBackend *backend,
+ GVfsJobOpenForRead *job,
+ const char *filename)
+{
+ GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+ struct DiceHandle *dice_handle;
+ GFileInputStream *stream;
+ GError *error = NULL;
+ GFile *file = NULL;
+ GFileInfo *info = NULL;
+
+ g_print ("(II) do_open_for_read (filename = '%s') \n", filename);
+
+ if (strcmp (filename, "/") == 0)
+ {
+ g_print ("caught the read on / case");
+
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_REGULAR_FILE,
+ _("Failed to read the root directory"));
+ goto do_open_for_read_error;
+ }
+
+ info =
+ get_g_file_info_from_dice (
+ dice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job),
+ &error);
+ if (error != NULL)
+ {
+ goto do_open_for_read_error;
+ }
+
+ g_assert (info != NULL);
+
+ // Build a GFile object from the local path
+ file =
+ get_g_file_from_local (
+ g_file_info_get_attribute_string (
+ info,
+ G_FILE_ATTRIBUTE_DICE_LOCAL_PATH),
+ G_VFS_JOB (job));
+ if (file == NULL)
+ {
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Unable to create a GFile object"));
+ goto do_open_for_read_error;
+ }
+
+ stream = g_file_read (file, G_VFS_JOB (job)->cancellable, &error);
+ if (stream == NULL)
+ {
+ g_print (" (EE) do_open_for_read: stream == NULL, error: %s \n", error->message);
+ goto do_open_for_read_error;
+ }
+
+ dice_handle = g_malloc (sizeof (struct DiceHandle));
+ dice_handle->input_stream = stream;
+ dice_handle->file_path = g_strdup (filename);
+ g_vfs_job_open_for_read_set_can_seek (job, TRUE);
+ g_vfs_job_open_for_read_set_handle (job, dice_handle);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_open_for_read success. \n");
+ g_object_unref (file);
+ g_object_unref (info);
+ return;
+
+do_open_for_read_error:
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ if (error != NULL) g_error_free (error);
+ if (info != NULL) g_object_unref (info);
+ if (file != NULL) g_object_unref (file);
+
+ return;
+}
+
+
+static void
+do_read (
+ GVfsBackend *backend,
+ GVfsJobRead *job,
+ GVfsBackendHandle handle,
+ char *buffer,
+ gsize bytes_requested)
+{
+ GError *error;
+ struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+ gssize s;
+
+ g_assert (dice_handle != NULL);
+ g_assert (dice_handle->input_stream);
+
+ g_print ("(II) do_read (handle = '%lx', buffer = '%lx', bytes_requested = %ld) \n",
+ (long int)dice_handle->input_stream, (long int)buffer, (long int)bytes_requested);
+
+ error = NULL;
+ s = g_input_stream_read (G_INPUT_STREAM (dice_handle->input_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 DiceHandle *dice_handle = (struct DiceHandle *)handle;
+
+ g_assert (dice_handle != NULL);
+ g_assert (dice_handle->input_stream != NULL);
+
+ g_print (
+ "(II) do_seek_on_read (handle = '%lx', offset = %ld) \n",
+ (long int)dice_handle->input_stream,
+ (long int)offset);
+
+ error = NULL;
+ if (g_seekable_seek (
+ G_SEEKABLE (dice_handle->input_stream),
+ offset,
+ type,
+ G_VFS_JOB (job)->cancellable, &error))
+ {
+ g_vfs_job_seek_read_set_offset (job, g_seekable_tell (G_SEEKABLE (dice_handle->input_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 DiceHandle *dice_handle = (struct DiceHandle *)handle;
+
+ g_assert (dice_handle != NULL);
+ g_assert (dice_handle->input_stream != NULL);
+
+ g_print ("(II) do_close_read (handle = '%lx') \n", (long int)dice_handle->input_stream);
+
+ error = NULL;
+ if (g_input_stream_close (
+ G_INPUT_STREAM (dice_handle->input_stream),
+ G_VFS_JOB (job)->cancellable, &error))
+ {
+ g_object_unref (dice_handle->input_stream);
+ if (dice_handle->file_path != NULL)
+ g_free (dice_handle->file_path);
+ g_free (dice_handle);
+ 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 *dice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+ GFileInfo *info = NULL;
+ GFile *file;
+ struct DiceHandle *dice_handle;
+
+ info =
+ get_g_file_info_from_dice (
+ dice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job),
+ &error);
+
+// g_file_new_for_path (filename);
+ if (info != NULL)
+ {
+ if (error != NULL) g_error_free (error);
+ 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;
+ }
+
+ // Create a limbo entry in the dice database
+ info = create_g_file_info_in_dice (dice_backend, filename, &error);
+ if (info == NULL)
+ {
+ // The error returned from the dice create call
+ // will be converted to the correct GIO_ERROR
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+
+ g_printf ("Successfully created the file locally");
+
+ // 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);
+
+ g_printf ("local path: %s\n", local_path);
+ 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 && !error)
+ {
+ g_printf ("g_file_create was successful\n");
+ dice_handle = g_malloc (sizeof (struct DiceHandle));
+ dice_handle->file_path = g_strdup (filename);
+ dice_handle->output_stream = stream;
+
+ //g_vfs_job_open_for_write_set_can_seek (job, TRUE);
+ g_vfs_job_open_for_write_set_handle (job, dice_handle);
+
+ //g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), dice_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_printf ("g_vfs_job_succeeded\n");
+ }
+ else
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+
+ g_object_unref (file);
+ return;
+}
+
+
+static void
+do_close_write (
+ GVfsBackend *backend,
+ GVfsJobCloseWrite *job,
+ GVfsBackendHandle handle)
+{
+ GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error = NULL;
+ struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+
+ g_print ("(II) do_close_write (handle = '%lx') \n", (long int)handle);
+ g_assert (dice_handle != NULL);
+ g_assert (dice_handle->output_stream != NULL);
+ g_assert (dice_handle->file_path != NULL);
+
+ if (!g_output_stream_close (
+ G_OUTPUT_STREAM(dice_handle->output_stream),
+ G_VFS_JOB (job)->cancellable,
+ &error))
+ {
+ g_printf ("Failed closing the output stream\n");
+ goto do_close_write_error;
+ }
+
+ // Notify DICE daemon that the file has been closed/changed
+ error = NULL;
+ if (update_local_file_in_dice (
+ dice_backend,
+ dice_handle->file_path,
+ &error) == FALSE)
+ {
+ g_print ("(II) failed updating dice of changes\n");
+ goto do_close_write_error;
+ }
+
+ g_object_unref (dice_handle->output_stream);
+ if (dice_handle->file_path != NULL)
+ g_free (dice_handle->file_path);
+ g_free (dice_handle);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_print ("(II) do_close_write success. \n");
+ return;
+
+do_close_write_error:
+ if (dice_handle != NULL)
+ {
+ if (dice_handle->file_path != NULL)
+ g_free (dice_handle->file_path);
+ g_free (dice_handle);
+ }
+
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_print (" (EE) do_close_write: failed, error: %s \n", error->message);
+ g_error_free (error);
+ return;
+}
+
+
+static void
+do_write (
+ GVfsBackend *backend,
+ GVfsJobWrite *job,
+ GVfsBackendHandle handle,
+ char *buffer,
+ gsize buffer_size)
+{
+ GError *error;
+ struct DiceHandle *dice_handle = (struct DiceHandle *)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 (dice_handle != NULL);
+ g_assert (dice_handle->output_stream != NULL);
+
+ error = NULL;
+ s =
+ g_output_stream_write (
+ G_OUTPUT_STREAM (dice_handle->output_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 *dice_backend = G_VFS_BACKEND_DICE (backend);
+ GError *error;
+ GFileInfo *info;
+ GFile *file;
+ struct DiceHandle *dice_handle = NULL;
+
+ g_print ("(II) do_append (filename = %s) \n", filename);
+
+ info =
+ get_g_file_info_from_dice (
+ dice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job),
+ &error);
+
+ if (info == NULL)
+ {
+ if (error != NULL) g_error_free (error);
+ // 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 != NULL)
+ {
+ error = NULL;
+ dice_handle = g_malloc (sizeof (struct DiceHandle));
+ dice_handle->output_stream =
+ g_file_append_to (file, flags, G_VFS_JOB (job)->cancellable, &error);
+ g_object_unref (file);
+ if (dice_handle->output_stream)
+ {
+ /* Should seek at the end of the file here */
+ if ((g_seekable_seek (
+ G_SEEKABLE (dice_handle->output_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 (dice_handle->output_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
+ dice_handle->file_path = g_strdup (filename);
+ g_vfs_job_open_for_write_set_can_seek (
+ job,
+ g_seekable_can_seek (G_SEEKABLE (dice_handle->output_stream)));
+ g_vfs_job_open_for_write_set_handle (job, dice_handle);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ g_print ("(II) do_append success. \n");
+ }
+ else
+ {
+ g_free (dice_handle);
+ 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);
+ }
+ }
+ else
+ {
+ g_print (" (EE) do_append: file == NULL \n");
+
+ g_vfs_job_failed (
+ G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("Unable to get the local path"));
+ }
+}
+
+
+static void
+do_replace (
+ GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags)
+{
+ GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+ struct DiceHandle *dice_handle = NULL;
+ GError *error = NULL;
+ GFile *file = NULL;
+ GFileInfo *info = NULL;
+
+ g_print ("(II) do_replace (filename = '%s', etag = '%s') \n", filename, etag);
+ g_print ("\t\t make_backup == %s\n", (make_backup == TRUE) ? "TRUE" : "FALSE");
+ g_print ("\t\t create flags == %X\n", flags);
+
+ if (make_backup == TRUE)
+ {
+ g_printf ("\t\tcan't create backups yet - fail");
+
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_CANT_CREATE_BACKUP,
+ _("backup creation is not supported"));
+
+ goto do_replace_error;
+ }
+
+
+ // Check if the file already exists in the DICE namespace
+ info =
+ get_g_file_info_from_dice (
+ dice_backend,
+ filename,
+ "*",
+ G_FILE_QUERY_INFO_NONE,
+ G_VFS_JOB (job),
+ &error);
+
+ if (info == NULL)
+ {
+ if (error != NULL)
+ {
+ g_error_free (error);
+ error = NULL;
+ }
+
+ g_printf ("\t\tfailed to find the filename in the dice namespace");
+
+ // Create a limbo entry in the dice database
+ info = create_g_file_info_in_dice (dice_backend, filename, &error);
+ if (info == NULL)
+ {
+ // The error returned from the dice create call
+ // will be converted to the correct GIO_ERROR
+ goto do_replace_error;
+ }
+
+ /*
+ if (etag == NULL)
+ etag = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
+ */
+
+ g_printf ("Successfully created the file locally");
+ }
+
+ // 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);
+ g_printf ("local path: %s\n", local_path);
+
+ // Create a GFile object from the local path
+ file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+ if (file == NULL)
+ {
+ g_print (" (EE) do_replace: file == NULL \n");
+ g_assert (file != NULL);
+ error =
+ g_error_new (
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ _("Unable to get the local path"));
+
+ goto do_replace_error;
+ }
+
+ dice_handle = g_malloc (sizeof (struct DiceHandle));
+ dice_handle->output_stream =
+ g_file_replace (
+ file,
+ NULL,
+ make_backup,
+ flags,
+ G_VFS_JOB (job)->cancellable,
+ &error);
+
+ if (dice_handle->output_stream == NULL)
+ {
+ g_print (" (EE) do_replace: stream == NULL, error: %s \n", error->message);
+ goto do_replace_error;
+ }
+
+
+ // Save off the filename so we can notify DICE Daemon during a close
+ dice_handle->file_path = g_strdup (filename);
+ g_vfs_job_open_for_write_set_handle (job, dice_handle);
+ g_object_unref (file);
+ g_object_unref (info);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ // Call dice with a local update
+ if (update_local_file_in_dice (
+ dice_backend,
+ filename,
+ &error) == FALSE)
+ {
+ g_error_free (error);
+ }
+
+ g_print ("(II) do_replace success. \n");
+ return;
+
+do_replace_error:
+ g_print (" do_replace failed - error message: %s\n", error->message);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ if (error != NULL) g_error_free (error);
+ if (info != NULL) g_object_unref (info);
+ if (file != NULL) g_object_unref (file);
+ if (dice_handle != NULL) g_free (dice_handle);
+ return;
+}
+
+
+static void
+do_delete (
+ GVfsBackend *backend,
+ GVfsJobDelete *job,
+ const char *filename)
+{
+ GVfsBackendDice *dice_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_dice (dice_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;
+}
diff -Naur ./gvfs-1.0.2.orig/daemon/gvfsbackenddice.h gvfs-1.0.2/daemon/gvfsbackenddice.h
--- ./gvfs-1.0.2.orig/daemon/gvfsbackenddice.h 1969-12-31 17:00:00.000000000 -0700
+++ gvfs-1.0.2/daemon/gvfsbackenddice.h 2008-11-07 14:53:39.000000000 -0700
@@ -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__ */
diff -Naur ./gvfs-1.0.2.orig/daemon/Makefile.am gvfs-1.0.2/daemon/Makefile.am
--- ./gvfs-1.0.2.orig/daemon/Makefile.am 2008-09-14 06:05:05.000000000 -0600
+++ gvfs-1.0.2/daemon/Makefile.am 2008-11-07 15:00:04.000000000 -0700
@@ -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 \
diff -Naur ./gvfs-1.0.2.orig/programs/gvfs-bash-completion.sh gvfs-1.0.2/programs/gvfs-bash-completion.sh
--- ./gvfs-1.0.2.orig/programs/gvfs-bash-completion.sh 2008-11-07 16:59:07.000000000 -0700
+++ gvfs-1.0.2/programs/gvfs-bash-completion.sh 2008-09-14 06:05:05.000000000 -0600
@@ -1,3 +1,4 @@
+#!/bin/sh
# Copyright (C) 2006-2007 Red Hat, Inc.
#