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 + */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#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 + */ + +#ifndef __G_VFS_BACKEND_DICE_H__ +#define __G_VFS_BACKEND_DICE_H__ + +#include +#include + +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