diff --git a/gvfs-nds-no-vfs-init.patch b/gvfs-nds-no-vfs-init.patch new file mode 100644 index 0000000..c383586 --- /dev/null +++ b/gvfs-nds-no-vfs-init.patch @@ -0,0 +1,213 @@ +diff -Nurp gvfs-1.0.2_old/daemon/gvfsbackendnds.c gvfs-1.0.2_new/daemon/gvfsbackendnds.c +--- gvfs-1.0.2_old/daemon/gvfsbackendnds.c 2009-01-16 22:25:34.000000000 +0530 ++++ gvfs-1.0.2_new/daemon/gvfsbackendnds.c 2009-01-16 23:57:55.000000000 +0530 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #include "gvfsbackendnds.h" + #include "gvfsjobmountmountable.h" +@@ -49,8 +50,6 @@ + + + +-/* Function Pointer to /opt/novell/lib/libinterface.so */ +-int (*retrieve_children)(char *) = NULL; + + typedef struct { + char *name; +@@ -199,6 +198,9 @@ update_cache (GVfsBackendNds *backend,co + int res; + char *ptr=NULL; + char *server_name=NULL; ++ struct utsname utsbuf; ++/* Function Pointer to /opt/novell/lib/libinterface.so */ ++int (*retrieve_children)(char *); + + entries = NULL; + entry_errno = 0; +@@ -232,17 +234,42 @@ if(backend->server == NULL) //retrieve + + else //retrieve object names + { +- handle = dlopen("/opt/novell/lib/libinterface.so",RTLD_NOW); ++ uname(&utsbuf); ++ if(!strcmp(utsbuf.machine,"x86_64")) ++ handle = dlopen("/usr/lib64/libinterface.so",RTLD_NOW | RTLD_DEEPBIND); ++ else ++ handle = dlopen("/usr/lib/libinterface.so",RTLD_NOW | RTLD_DEEPBIND); + + if(handle == NULL) + { + return; + } + *(void **)(&retrieve_children) = dlsym(handle,"retrieve_children"); ++ ++ unlink("/tmp/ndsobjects.txt"); ++ + if(retrieve_children != NULL) + { + res = (*retrieve_children)(server_name); +- } ++ ++ if(res == 0) ++ { ++ fptr = fopen("/tmp/ndsobjects.txt","r"); ++ if(fptr == NULL) ++ { ++ entry_errno = -1; ++ goto out; ++ } ++ objectname = (char *)malloc(sizeof(char) * 400); ++ while (fgets(objectname,400,fptr) != NULL) ++ { ++ objectlist = g_list_append(objectlist,g_strdup(objectname)); ++ memset(objectname,'\0',400); ++ } ++ fclose(fptr); ++ free(objectname); ++ } ++ } + else + { + return; +@@ -265,6 +292,8 @@ for(object = objectlist;object != NULL;o + entries = g_list_append (entries, entry); + } + ++//if(objectlist != NULL) ++//g_list_free(objectlist); + + out: + +@@ -274,7 +303,7 @@ for(object = objectlist;object != NULL;o + backend->entries = entries; + g_mutex_unlock (backend->entries_lock); + } +- backend->entry_errno = entry_errno; ++ backend->entry_errno = entry_errno; + + } + +@@ -376,15 +405,14 @@ do_mount (GVfsBackend *backend, + display_name = g_strdup (_("NVVFS Top Directory")); + browse_mount_spec = g_mount_spec_new ("nds"); + icon = "network-workgroup"; +- + } + else + { + display_name = g_strdup_printf (_("NVVFS Objects")); + browse_mount_spec = g_mount_spec_new ("nds"); ++ //g_mount_spec_set (browse_mount_spec, "host", op_backend->mounted_server); + g_mount_spec_set (browse_mount_spec, "host", op_backend->server); + icon = "network-server"; +- + } + + g_vfs_backend_set_display_name (backend, display_name); +@@ -424,6 +452,74 @@ try_mount (GVfsBackend *backend, + return FALSE; + } + ++static void ++run_mount_mountable (GVfsBackendNds *backend, ++ GVfsJobMountMountable *job, ++ const char *filename, ++ GMountSource *mount_source) ++{ ++ BrowseEntry *entry; ++ GError *error = NULL; ++ GMountSpec *mount_spec; ++ ++ g_mutex_lock (backend->entries_lock); ++ ++backend->server = g_strdup(filename); ++ ++ mount_spec = get_mount_spec_for_share (backend->server, filename); ++ g_vfs_job_mount_mountable_set_target (job, mount_spec, "/", TRUE); ++ g_mount_spec_unref (mount_spec); ++ g_mutex_unlock (backend->entries_lock); ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++} ++ ++ ++static gboolean ++do_mount_mountable (GVfsBackend *backend, ++ GVfsJobMountMountable *job, ++ const char *filename, ++ GMountSource *mount_source) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ ++update_cache (op_backend,filename); ++ ++ run_mount_mountable (op_backend, ++ job, ++ filename, ++ mount_source); ++ return TRUE; ++} ++ ++static gboolean ++try_mount_mountable (GVfsBackend *backend, ++ GVfsJobMountMountable *job, ++ const char *filename, ++ GMountSource *mount_source) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ ++ ++ if (is_root (filename)) ++ { ++ g_vfs_job_failed (G_VFS_JOB (job), ++ G_IO_ERROR, G_IO_ERROR_NOT_MOUNTABLE_FILE, ++ _("The file is not a mountable")); ++ return TRUE; ++ } ++ ++update_cache (op_backend,filename); ++ ++ run_mount_mountable (op_backend, ++ job, ++ filename, ++ mount_source); ++ return TRUE; ++} ++ ++ ++ + #define SUB_DELIM_CHARS "!$&'()*+,;=" + + static gboolean +@@ -482,7 +578,10 @@ get_file_info_from_entry (GVfsBackendNds + g_file_info_set_edit_name (info, entry->name_utf8); + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL, TRUE); + +- icon = g_themed_icon_new ("network-server"); ++ if(backend->server == NULL) //NDS-Tree icon ++ icon = g_themed_icon_new ("ncl-ndstree"); ++ else ++ icon = g_themed_icon_new ("ncl-nwcontext"); + + if (icon) + { +@@ -634,7 +733,6 @@ try_enumerate (GVfsBackend *backend, + { + GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); + +- + update_cache (op_backend,filename); + + run_enumerate (op_backend, job, filename, matcher); +@@ -648,7 +746,6 @@ g_vfs_backend_nds_class_init (GVfsBacken + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass); + +- + gobject_class->finalize = g_vfs_backend_nds_finalize; + + backend_class->mount = do_mount; diff --git a/gvfs-novell-nautilus-plugin-filesystem.patch b/gvfs-novell-nautilus-plugin-filesystem.patch new file mode 100644 index 0000000..52b0235 --- /dev/null +++ b/gvfs-novell-nautilus-plugin-filesystem.patch @@ -0,0 +1,679 @@ +diff -Nurp gvfs-1.0.2_org/daemon/gvfsbackendnvvfs.c gvfs-1.0.2/daemon/gvfsbackendnvvfs.c +--- gvfs-1.0.2_org/daemon/gvfsbackendnvvfs.c 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2/daemon/gvfsbackendnvvfs.c 2009-01-08 16:57:14.000000000 +0530 +@@ -0,0 +1,580 @@ ++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2006-2007 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * ++ * Authors: Alexander Larsson ++ * Cosimo Cecchi ++ */ ++ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "gvfsbackendnvvfs.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 "gvfsjobmountmountable.h" ++#include "gvfsjobqueryinfo.h" ++#include "gvfsjobdelete.h" ++#include "gvfsjobqueryfsinfo.h" ++#include "gvfsjobqueryattributes.h" ++#include "gvfsjobenumerate.h" ++#include "gvfsjobcreatemonitor.h" ++#include "gvfsdaemonprotocol.h" ++ ++ ++ ++typedef struct { ++ char *filename; ++ char *display_name; ++ GIcon *icon; ++ GFile *root; ++ int prio; ++ gboolean can_mount; ++ gboolean can_unmount; ++ gboolean can_eject; ++} NovellNautilus; ++ ++static NovellNautilus root = { "/" }; ++ ++struct _GVfsBackendNvvfs ++{ ++ GVfsBackend parent_instance; ++ ++ GVolumeMonitor *volume_monitor; ++ ++ GVfsMonitor *root_monitor; ++ ++ GList *files; ++ ++ guint recompute_idle_tag; ++ ++ GMountSpec *mount_spec; ++}; ++ ++G_DEFINE_TYPE (GVfsBackendNvvfs, g_vfs_backend_nvvfs, G_VFS_TYPE_BACKEND) ++ ++static void ++nvvfs_file_free (NovellNautilus *file) ++{ ++ g_free (file->filename); ++ g_free (file->display_name); ++ if (file->icon) ++ g_object_unref (file->icon); ++ if (file->root) ++ g_object_unref (file->root); ++ ++ g_slice_free (NovellNautilus, file); ++} ++ ++/* Assumes filename equal */ ++static gboolean ++nvvfs_file_equal (NovellNautilus *a, ++ NovellNautilus *b) ++{ ++ if (strcmp (a->display_name, b->display_name) != 0) ++ return FALSE; ++ ++ if (!g_icon_equal (a->icon, b->icon)) ++ return FALSE; ++ ++ if ((a->root != NULL && b->root != NULL && ++ !g_file_equal (a->root, b->root)) || ++ (a->root != NULL && b->root == NULL) || ++ (a->root == NULL && b->root != NULL)) ++ return FALSE; ++ ++ if (a->prio != b->prio) ++ return FALSE; ++ ++ if (a->can_mount != b->can_mount || ++ a->can_unmount != b->can_unmount || ++ a->can_eject != b->can_eject) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++static void object_changed (GVolumeMonitor *monitor, ++ gpointer object, ++ GVfsBackendNvvfs *backend); ++ ++static void ++g_vfs_backend_nvvfs_finalize (GObject *object) ++{ ++ GVfsBackendNvvfs *backend; ++ ++ backend = G_VFS_BACKEND_NVVFS (object); ++ ++ if (backend->volume_monitor) ++ { ++ g_signal_handlers_disconnect_by_func(backend->volume_monitor, object_changed, backend); ++ g_object_unref (backend->volume_monitor); ++ } ++ ++ g_mount_spec_unref (backend->mount_spec); ++ ++ if (backend->recompute_idle_tag) ++ { ++ g_source_remove (backend->recompute_idle_tag); ++ backend->recompute_idle_tag = 0; ++ } ++ ++ g_object_unref (backend->root_monitor); ++ ++ if (G_OBJECT_CLASS (g_vfs_backend_nvvfs_parent_class)->finalize) ++ (*G_OBJECT_CLASS (g_vfs_backend_nvvfs_parent_class)->finalize) (object); ++} ++ ++static void ++g_vfs_backend_nvvfs_init (GVfsBackendNvvfs *nvvfs_backend) ++{ ++ GVfsBackend *backend = G_VFS_BACKEND (nvvfs_backend); ++ GMountSpec *mount_spec; ++ ++ g_vfs_backend_set_display_name (backend, _("Nvvfs")); ++ g_vfs_backend_set_icon_name (backend, "gnome-fs-client"); ++ g_vfs_backend_set_user_visible (backend, FALSE); ++ ++ mount_spec = g_mount_spec_new ("nvvfs"); ++ g_vfs_backend_set_mount_spec (backend, mount_spec); ++ nvvfs_backend->mount_spec = mount_spec; ++} ++ ++static gboolean ++filename_is_used (GList *files, const char *filename) ++{ ++ NovellNautilus *file; ++ ++ while (files != NULL) ++ { ++ file = files->data; ++ ++ if (file->filename == NULL) ++ return FALSE; ++ ++ if (strcmp (file->filename, filename) == 0) ++ return TRUE; ++ ++ files = files->next; ++ } ++ return FALSE; ++} ++ ++static int ++sort_file_by_filename (NovellNautilus *a, NovellNautilus *b) ++{ ++ return strcmp (a->filename, b->filename); ++} ++ ++static void ++convert_slashes (char *str) ++{ ++ char *s; ++ ++ while ((s = strchr (str, '/')) != NULL) ++ *s = '\\'; ++} ++ ++static void ++update_from_files (GVfsBackendNvvfs *backend, ++ GList *files) ++{ ++ GList *old_files; ++ GList *oldl, *newl; ++ char *filename; ++ NovellNautilus *old, *new; ++ int cmp; ++ ++ old_files = backend->files; ++ backend->files = files; ++ ++ /* Generate change events */ ++ oldl = old_files; ++ newl = files; ++ while (oldl != NULL || newl != NULL) ++ { ++ if (oldl == NULL) ++ { ++ cmp = 1; ++ new = newl->data; ++ old = NULL; ++ } ++ else if (newl == NULL) ++ { ++ cmp = -1; ++ new = NULL; ++ old = oldl->data; ++ } ++ else ++ { ++ new = newl->data; ++ old = oldl->data; ++ cmp = strcmp (old->filename, new->filename); ++ } ++ ++ if (cmp == 0) ++ { ++ if (!nvvfs_file_equal (old, new)) ++ { ++ filename = g_strconcat ("/", new->filename, NULL); ++ g_vfs_monitor_emit_event (backend->root_monitor, ++ G_FILE_MONITOR_EVENT_CHANGED, ++ filename, ++ NULL); ++ g_free (filename); ++ } ++ ++ oldl = oldl->next; ++ newl = newl->next; ++ } ++ else if (cmp < 0) ++ { ++ filename = g_strconcat ("/", old->filename, NULL); ++ g_vfs_monitor_emit_event (backend->root_monitor, ++ G_FILE_MONITOR_EVENT_DELETED, ++ filename, ++ NULL); ++ g_free (filename); ++ oldl = oldl->next; ++ } ++ else ++ { ++ filename = g_strconcat ("/", new->filename, NULL); ++ g_vfs_monitor_emit_event (backend->root_monitor, ++ G_FILE_MONITOR_EVENT_CREATED, ++ filename, ++ NULL); ++ g_free (filename); ++ newl = newl->next; ++ } ++ } ++ ++ g_list_foreach (old_files, (GFunc)nvvfs_file_free, NULL); ++} ++ ++static void ++recompute_files (GVfsBackendNvvfs *backend) ++{ ++ GVolumeMonitor *volume_monitor; ++ GList *drives, *volumes, *mounts, *l, *ll; ++ GDrive *drive; ++ GVolume *volume; ++ GMount *mount; ++ NovellNautilus *file; ++ GList *files; ++ char *basename, *filename; ++ const char *extension; ++ int uniq; ++ ++ gchar *nclmnt_path = "/var/opt/novell/nclmnt/"; ++ gchar *user_name=NULL; ++ gchar *path_ncl=NULL; ++ ++ volume_monitor = backend->volume_monitor; ++ ++ files = NULL; ++ ++ ++// Im building the path for Novell Client mounts ++ user_name = g_get_user_name(); ++ path_ncl = g_strconcat(nclmnt_path,user_name,NULL); ++ ++ file = g_slice_new0 (NovellNautilus); ++ file->filename = g_strdup ("root.link"); ++ file->display_name = g_strdup (_("AvailableConnections")); ++ file->icon = g_themed_icon_new("ncl-logo"); ++ file->root = g_file_new_for_path (path_ncl); ++ file->prio = 0; ++ ++ files = g_list_prepend (files, file); ++ ++ files = g_list_sort (files, (GCompareFunc)sort_file_by_filename); ++ ++ update_from_files (backend, files); ++} ++ ++static gboolean ++recompute_files_in_idle (GVfsBackendNvvfs *backend) ++{ ++ backend->recompute_idle_tag = 0; ++ ++ recompute_files (backend); ++ ++ return FALSE; ++} ++ ++static void ++object_changed (GVolumeMonitor *monitor, ++ gpointer object, ++ GVfsBackendNvvfs *backend) ++{ ++ if (backend->recompute_idle_tag == 0) ++ backend->recompute_idle_tag = ++ g_idle_add ((GSourceFunc)recompute_files_in_idle, ++ backend); ++} ++ ++static gboolean ++try_mount (GVfsBackend *backend, ++ GVfsJobMount *job, ++ GMountSpec *mount_spec, ++ GMountSource *mount_source, ++ gboolean is_automount) ++{ ++ GVfsBackendNvvfs *nvvfs_backend = G_VFS_BACKEND_NVVFS (backend); ++ int i; ++ char *signals[] = { ++ "volume-added", ++ "volume-removed", ++ "volume-changed", ++ "mount-added", ++ "mount-removed", ++ "mount-changed", ++ "drive-connected", ++ "drive-disconnected", ++ "drive-changed", ++ NULL ++ }; ++ ++ nvvfs_backend->volume_monitor = g_volume_monitor_get (); ++ ++ /* TODO: connect all signals to object_changed */ ++ ++ for (i = 0; signals[i] != NULL; i++) ++ g_signal_connect_data (nvvfs_backend->volume_monitor, ++ signals[i], ++ (GCallback)object_changed, ++ backend, ++ NULL, 0); ++ ++ nvvfs_backend->root_monitor = g_vfs_monitor_new (backend); ++ ++ recompute_files (nvvfs_backend); ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ ++ return TRUE; ++} ++ ++static NovellNautilus * ++lookup (GVfsBackendNvvfs *backend, ++ GVfsJob *job, ++ const char *filename) ++{ ++ GList *l; ++ NovellNautilus *file; ++ ++ if (*filename != '/') ++ goto out; ++ ++ while (*filename == '/') ++ filename++; ++ ++ if (*filename == 0) ++ return &root; ++ ++ if (strchr (filename, '/') != NULL) ++ goto out; ++ ++ for (l = backend->files; l != NULL; l = l->next) ++ { ++ file = l->data; ++ ++ if (strcmp (file->filename, filename) == 0) ++ return file; ++ } ++ ++ out: ++ g_vfs_job_failed (job, G_IO_ERROR, ++ G_IO_ERROR_NOT_FOUND, ++ _("File doesn't exist")); ++ return NULL; ++} ++ ++ ++static gboolean ++try_open_for_read (GVfsBackend *backend, ++ GVfsJobOpenForRead *job, ++ const char *filename) ++{ ++ NovellNautilus *file; ++ ++ file = lookup (G_VFS_BACKEND_NVVFS (backend), ++ G_VFS_JOB (job), filename); ++ ++ if (file == &root) ++ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, ++ G_IO_ERROR_IS_DIRECTORY, ++ _("Can't open directory")); ++ else if (file != NULL) ++ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, ++ G_IO_ERROR_NOT_SUPPORTED, ++ _("Can't open mountable file")); ++ return TRUE; ++} ++ ++static void ++file_info_from_file (NovellNautilus *file, ++ GFileInfo *info) ++{ ++ char *uri; ++ ++ g_file_info_set_name (info, file->filename); ++ g_file_info_set_display_name (info, file->display_name); ++ ++ if (file->icon) ++ g_file_info_set_icon (info, file->icon); ++ ++ if (file->root) ++ { ++ uri = g_file_get_uri (file->root); ++ ++ g_file_info_set_attribute_string (info, ++ G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, ++ uri); ++ g_free (uri); ++ } ++ ++ g_file_info_set_sort_order (info, file->prio); ++ ++ g_file_info_set_file_type (info, G_FILE_TYPE_MOUNTABLE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT, file->can_mount); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT, file->can_unmount); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT, file->can_eject); ++ ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE); ++} ++ ++static gboolean ++try_enumerate (GVfsBackend *backend, ++ GVfsJobEnumerate *job, ++ const char *filename, ++ GFileAttributeMatcher *attribute_matcher, ++ GFileQueryInfoFlags flags) ++{ ++ NovellNautilus *file; ++ GList *l; ++ GFileInfo *info; ++ ++ file = lookup (G_VFS_BACKEND_NVVFS (backend), ++ G_VFS_JOB (job), filename); ++ ++ if (file != &root) ++ { ++ if (file != NULL) ++ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, ++ G_IO_ERROR_NOT_DIRECTORY, ++ _("The file is not a directory")); ++ return TRUE; ++ } ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ ++ /* Enumerate root */ ++ for (l = G_VFS_BACKEND_NVVFS (backend)->files; l != NULL; l = l->next) ++ { ++ file = l->data; ++ ++ info = g_file_info_new (); ++ ++ file_info_from_file (file, info); ++ g_vfs_job_enumerate_add_info (job, info); ++ g_object_unref (info); ++ } ++ ++ g_vfs_job_enumerate_done (job); ++ ++ return TRUE; ++} ++ ++static gboolean ++try_query_info (GVfsBackend *backend, ++ GVfsJobQueryInfo *job, ++ const char *filename, ++ GFileQueryInfoFlags flags, ++ GFileInfo *info, ++ GFileAttributeMatcher *matcher) ++{ ++ NovellNautilus *file; ++ ++ file = lookup (G_VFS_BACKEND_NVVFS (backend), ++ G_VFS_JOB (job), filename); ++ ++ if (file == &root) ++ { ++ GIcon *icon; ++ ++ g_file_info_set_name (info, "/"); ++ g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); ++ g_file_info_set_display_name (info, _("Nvvfs")); ++ icon = g_themed_icon_new ("gnome-fs-client"); ++ g_file_info_set_icon (info, icon); ++ g_object_unref (icon); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE); ++ g_file_info_set_content_type (info, "inode/directory"); ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ } ++ else if (file != NULL) ++ { ++ file_info_from_file (file, info); ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ } ++ ++ return TRUE; ++} ++ ++static void ++g_vfs_backend_nvvfs_class_init (GVfsBackendNvvfsClass *klass) ++{ ++ GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ++ GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass); ++ ++ gobject_class->finalize = g_vfs_backend_nvvfs_finalize; ++ ++ backend_class->try_mount = try_mount; ++ backend_class->try_open_for_read = try_open_for_read; ++ backend_class->try_query_info = try_query_info; ++ backend_class->try_enumerate = try_enumerate; ++} +diff -Nurp gvfs-1.0.2_org/daemon/gvfsbackendnvvfs.h gvfs-1.0.2/daemon/gvfsbackendnvvfs.h +--- gvfs-1.0.2_org/daemon/gvfsbackendnvvfs.h 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2/daemon/gvfsbackendnvvfs.h 2009-01-08 15:49:22.000000000 +0530 +@@ -0,0 +1,50 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2006-2007 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * ++ * Author: Alexander Larsson ++ */ ++ ++#ifndef __G_VFS_BACKEND_NVVFS_H__ ++#define __G_VFS_BACKEND_NVVFS_H__ ++ ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++#define G_VFS_TYPE_BACKEND_NVVFS (g_vfs_backend_nvvfs_get_type ()) ++#define G_VFS_BACKEND_NVVFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_BACKEND_NVVFS, GVfsBackendNvvfs)) ++#define G_VFS_BACKEND_NVVFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_BACKEND_NVVFS, GVfsBackendNvvfsClass)) ++#define G_VFS_IS_BACKEND_NVVFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_BACKEND_NVVFS)) ++#define G_VFS_IS_BACKEND_NVVFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_BACKEND_NVVFS)) ++#define G_VFS_BACKEND_NVVFS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_BACKEND_NVVFS, GVfsBackendNvvfsClass)) ++ ++typedef struct _GVfsBackendNvvfs GVfsBackendNvvfs; ++typedef struct _GVfsBackendNvvfsClass GVfsBackendNvvfsClass; ++ ++struct _GVfsBackendNvvfsClass ++{ ++ GVfsBackendClass parent_class; ++}; ++ ++GType g_vfs_backend_nvvfs_get_type (void) G_GNUC_CONST; ++ ++G_END_DECLS ++ ++#endif /* __G_VFS_BACKEND_NVVFS_H__ */ +diff -Nurp gvfs-1.0.2_org/daemon/Makefile.am gvfs-1.0.2/daemon/Makefile.am +--- gvfs-1.0.2_org/daemon/Makefile.am 2008-09-14 17:35:05.000000000 +0530 ++++ gvfs-1.0.2/daemon/Makefile.am 2009-01-08 15:51:44.000000000 +0530 +@@ -95,6 +95,10 @@ mount_DATA += archive.mount + libexec_PROGRAMS += gvfsd-archive + endif + ++mount_in_files += nvvfs.mount.in ++mount_DATA += nvvfs.mount ++libexec_PROGRAMS += gvfsd-nvvfs ++ + EXTRA_DIST = gvfs-daemon.service.in $(mount_in_files) obexftp-marshal.list + + DISTCLEANFILES = gvfs-daemon.service $(mount_DATA) +@@ -395,3 +399,17 @@ gvfsd_dav_CPPFLAGS = \ + + gvfsd_dav_LDADD = $(libraries) $(HTTP_LIBS) + ++gvfsd_nvvfs_SOURCES = \ ++ gvfsbackendnvvfs.c gvfsbackendnvvfs.h \ ++ daemon-main.c daemon-main.h \ ++ daemon-main-generic.c ++ ++gvfsd_nvvfs_CPPFLAGS = \ ++ -DBACKEND_HEADER=gvfsbackendnvvfs.h \ ++ -DDEFAULT_BACKEND_TYPE=nvvfs \ ++ -DMAX_JOB_THREADS=1 \ ++ -DBACKEND_TYPES='"nvvfs", G_VFS_TYPE_BACKEND_NVVFS,' ++ ++gvfsd_nvvfs_LDADD = $(libraries) ++ ++ +diff -Nurp gvfs-1.0.2_org/daemon/nvvfs.mount.in gvfs-1.0.2/daemon/nvvfs.mount.in +--- gvfs-1.0.2_org/daemon/nvvfs.mount.in 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2/daemon/nvvfs.mount.in 2009-01-08 15:49:32.000000000 +0530 +@@ -0,0 +1,5 @@ ++[Mount] ++Type=nvvfs ++Exec=@libexecdir@/gvfsd-nvvfs ++AutoMount=false ++Scheme=nvvfs diff --git a/gvfs.changes b/gvfs.changes index c874761..68742f1 100644 --- a/gvfs.changes +++ b/gvfs.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Fri Jan 16 20:09:06 CET 2009 - ksamrat@novell.com + +- gvfs-nds-no-vfs-init.patch - Avoid issues with vfs initialization + +------------------------------------------------------------------- +Thu Jan 15 07:55:22 CET 2009 - ksamrat@novell.com + +- gvfsd-nds.patch +- gvfs-novell-nautilus-plugin-filesystem.patch +- Provide the Nautilus backend for NDS and Novell File system browsing +- Solves bugs bnc#420155 , bnc#449396 + ------------------------------------------------------------------- Thu Jan 8 01:04:01 CET 2009 - hpj@novell.com diff --git a/gvfs.spec b/gvfs.spec index e4012ce..089ad72 100644 --- a/gvfs.spec +++ b/gvfs.spec @@ -45,7 +45,7 @@ BuildRequires: extra-rpm-macros %endif Summary: VFS functionality for GLib Version: 1.0.2 -Release: 3 +Release: 5 License: LGPL v2.0 or later Group: Development/Libraries/C and C++ Source0: %{name}-%{version}.tar.bz2 @@ -59,6 +59,12 @@ Patch2: gvfs-obexftp-updated-apis-3.patch Patch3: gvfs-smb-browse-auth.patch # PATCH-FIX-UPSTREAM gvfs-429959-handle-blank-schemas.patch bnc429959 hpj@suse.de -- Fix URI handler lookup with blank schemas. Patch4: gvfs-429959-handle-blank-schemas.patch +# PATCH-FEATURE-OPENSUSE gvfs-novell-nautilus-plugin-filesystem.patch ksamrat@novell.com -- Provides gvfs backend for novell nautilus plugin +Patch5: gvfs-novell-nautilus-plugin-filesystem.patch +# PATCH-FEATURE-OPENSUSE gvfsd-nds.patch ksamrat@novell.com -- Provides NDS browsing for nautilus +Patch6: gvfsd-nds.patch +# PATCH-FEATURE-OPENSUSE gvfs-nds-no-vfs-init.patch ksamrat@novell.com -- Avoid vfs initialize issues +Patch7: gvfs-nds-no-vfs-init.patch Url: http://www.gnome.org BuildRoot: %{_tmppath}/%{name}-%{version}-build AutoReqProv: on @@ -148,6 +154,9 @@ Authors: %patch2 %patch3 -p0 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" @@ -209,6 +218,8 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/%{name}/gvfsd-smb %{_libdir}/%{name}/gvfsd-smb-browse %{_libdir}/%{name}/gvfsd-trash +%{_libdir}/%{name}/gvfsd-nvvfs +%{_libdir}/%{name}/gvfsd-nds %files -n libgvfscommon0 %defattr(-, root, root) @@ -222,6 +233,13 @@ rm -rf $RPM_BUILD_ROOT %files lang -f %{name}.lang %changelog +* Fri Jan 16 2009 ksamrat@novell.com +- gvfs-nds-no-vfs-init.patch - Avoid issues with vfs initialization +* Thu Jan 15 2009 ksamrat@novell.com +- gvfsd-nds.patch +- gvfs-novell-nautilus-plugin-filesystem.patch +- Provide the Nautilus backend for NDS and Novell File system browsing +- Solves bugs bnc#420155 , bnc#449396 * Thu Jan 08 2009 hpj@novell.com - Added gvfs-429959-handle-blank-schemas.patch (bnc#429959). * Fri Dec 05 2008 hpj@novell.com diff --git a/gvfsd-nds.patch b/gvfsd-nds.patch new file mode 100644 index 0000000..6edbe76 --- /dev/null +++ b/gvfsd-nds.patch @@ -0,0 +1,767 @@ +diff -Nurp gvfs-1.0.2_old/daemon/gvfsbackendnds.c gvfs-1.0.2_new/daemon/gvfsbackendnds.c +--- gvfs-1.0.2_old/daemon/gvfsbackendnds.c 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2_new/daemon/gvfsbackendnds.c 2009-01-15 10:43:07.000000000 +0530 +@@ -0,0 +1,666 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2006-2007 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * ++ * Author: Alexander Larsson ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "gvfsbackendnds.h" ++#include "gvfsjobmountmountable.h" ++#include "gvfsjobopenforread.h" ++#include "gvfsjobread.h" ++#include "gvfsjobseekread.h" ++#include "gvfsjobqueryinfo.h" ++#include "gvfsjobenumerate.h" ++#include "gvfsdaemonprotocol.h" ++#include "gmounttracker.h" ++#include "gvfsmonitor.h" ++ ++ ++ ++/* Function Pointer to /opt/novell/lib/libinterface.so */ ++int (*retrieve_children)(char *) = NULL; ++ ++typedef struct { ++ char *name; ++ char *name_normalized; ++ char *name_utf8; ++} BrowseEntry; ++ ++struct _GVfsBackendNds ++{ ++ GVfsBackend parent_instance; ++ ++ char *server; ++ char *mounted_server; ++ ++ GMutex *entries_lock; ++ GList *entries; ++ int entry_errno; ++}; ++ ++static GMountTracker *mount_tracker = NULL; ++ ++G_DEFINE_TYPE (GVfsBackendNds, g_vfs_backend_nds, G_VFS_TYPE_BACKEND) ++ ++static gboolean ++is_root (const char *filename) ++{ ++ const char *p; ++ ++ p = filename; ++ while (*p == '/') ++ p++; ++ ++ return *p == 0; ++} ++ ++static char * ++normalize_nds_name_helper (const char *name, gssize len, gboolean valid_utf8) ++{ ++ if (valid_utf8) ++ return g_utf8_casefold (name, len); ++ else ++ return g_ascii_strdown (name, len); ++} ++ ++static char * ++normalize_nds_name (const char *name, gssize len) ++{ ++ gboolean valid_utf8; ++ ++ valid_utf8 = g_utf8_validate (name, len, NULL); ++ return normalize_nds_name_helper (name, len, valid_utf8); ++} ++ ++static char * ++nds_name_to_utf8 (const char *name, gboolean *valid_utf8_out) ++{ ++ GString *string; ++ const gchar *remainder, *invalid; ++ gint remaining_bytes, valid_bytes; ++ gboolean valid_utf8; ++ ++ remainder = name; ++ remaining_bytes = strlen (name); ++ valid_utf8 = TRUE; ++ ++ string = g_string_sized_new (remaining_bytes); ++ while (remaining_bytes != 0) ++ { ++ if (g_utf8_validate (remainder, remaining_bytes, &invalid)) ++ break; ++ valid_utf8 = FALSE; ++ ++ valid_bytes = invalid - remainder; ++ ++ g_string_append_len (string, remainder, valid_bytes); ++ /* append U+FFFD REPLACEMENT CHARACTER */ ++ g_string_append (string, "\357\277\275"); ++ ++ remaining_bytes -= valid_bytes + 1; ++ remainder = invalid + 1; ++ } ++ ++ g_string_append (string, remainder); ++ ++ if (valid_utf8_out) ++ *valid_utf8_out = valid_utf8; ++ ++ return g_string_free (string, FALSE); ++} ++ ++static void ++browse_entry_free (BrowseEntry *entry) ++{ ++if(entry->name != NULL) ++ g_free (entry->name); ++if(entry != NULL) ++ g_free (entry); ++} ++ ++ ++static void ++g_vfs_backend_nds_finalize (GObject *object) ++{ ++ GVfsBackendNds *backend; ++ ++ backend = G_VFS_BACKEND_NDS (object); ++ ++if(backend->mounted_server != NULL) ++ g_free (backend->mounted_server); ++if(backend->server != NULL) ++ g_free (backend->server); ++ ++ g_mutex_free (backend->entries_lock); ++ ++ g_list_foreach (backend->entries, (GFunc)browse_entry_free, NULL); ++if(backend->entries != NULL) ++ g_list_free (backend->entries); ++ ++ if (G_OBJECT_CLASS (g_vfs_backend_nds_parent_class)->finalize) ++ (*G_OBJECT_CLASS (g_vfs_backend_nds_parent_class)->finalize) (object); ++} ++ ++static void ++g_vfs_backend_nds_init (GVfsBackendNds *backend) ++{ ++ backend->entries_lock = g_mutex_new (); ++ ++ if (mount_tracker == NULL) ++ mount_tracker = g_mount_tracker_new (NULL); ++} ++ ++ ++static void ++update_cache (GVfsBackendNds *backend,const char *filename) ++{ ++ GString *uri; ++ GList *entries; ++ int entry_errno; ++ char *objectname=NULL; ++ char *treename=NULL; ++ GList *objectlist=NULL; ++ GList *object=NULL; ++ GList *l; ++ FILE *fptr=NULL; ++ void *handle=NULL; //handle for dlopen ++ int res; ++ char *ptr=NULL; ++ char *server_name=NULL; ++ ++ entries = NULL; ++ entry_errno = 0; ++ ++if(backend->server != NULL) ++{ ++ server_name = g_strdup(backend->server); ++ if((ptr = strchr(server_name,'%')) != NULL) ++ *ptr = '\0'; ++ ++} ++ ++if(backend->server == NULL) //retrieve Tree names ++{ ++ treename = (char *)malloc(sizeof(char) * 80); ++ system("/opt/novell/ncl/bin/retrieve_trees.pl"); ++ fptr = fopen("/tmp/ndstrees.txt","r"); ++ if(fptr == NULL) ++ { ++ entry_errno = -1; ++ goto out; ++ } ++ while (fgets(treename,80,fptr) != NULL) ++ { ++ objectlist = g_list_append(objectlist,g_strdup(treename)); ++ memset(treename,'\0',80); ++ } ++ fclose(fptr); ++ free(treename); ++} ++ ++else //retrieve object names ++{ ++ handle = dlopen("/opt/novell/lib/libinterface.so",RTLD_NOW); ++ ++ if(handle == NULL) ++ { ++ return; ++ } ++ *(void **)(&retrieve_children) = dlsym(handle,"retrieve_children"); ++ if(retrieve_children != NULL) ++ { ++ res = (*retrieve_children)(server_name); ++ } ++ else ++ { ++ return; ++ } ++ dlclose(handle); ++} ++ ++ ++ gboolean valid_utf8; ++ BrowseEntry *entry; ++ ++for(object = objectlist;object != NULL;object = object->next) ++{ ++ entry = g_new (BrowseEntry, 1); ++ objectname = object->data; ++ entry->name = g_strdup (objectname); ++ entry->name_utf8 = nds_name_to_utf8 (objectname, &valid_utf8); ++ entry->name_normalized = normalize_nds_name_helper (objectname, -1, valid_utf8); ++ ++ entries = g_list_append (entries, entry); ++} ++ ++ ++ out: ++ ++ if(entry_errno == 0) ++ { ++ g_mutex_lock (backend->entries_lock); ++ backend->entries = entries; ++ g_mutex_unlock (backend->entries_lock); ++ } ++ backend->entry_errno = entry_errno; ++ ++} ++ ++static BrowseEntry * ++find_entry_unlocked (GVfsBackendNds *backend, ++ const char *filename) ++{ ++ BrowseEntry *entry, *found; ++ GList *l; ++ char *end; ++ int len; ++ char *normalized; ++ ++ while (*filename == '/') ++ filename++; ++ ++ end = strchr (filename, '/'); ++ if (end) ++ { ++ len = end - filename; ++ ++ while (*end == '/') ++ end++; ++ ++ if (*end != 0) ++ return NULL; ++ } ++ else ++ len = strlen (filename); ++ ++ /* First look for an exact filename match */ ++ found = NULL; ++ for (l = backend->entries; l != NULL; l = l->next) ++ { ++ entry = l->data; ++ ++ if (strncmp (filename, entry->name, len) == 0 && ++ strlen (entry->name) == len) ++ { ++ found = entry; ++ break; ++ } ++ } ++ ++ if (found == NULL) ++ { ++ /* That failed, try normalizing the filename */ ++ normalized = normalize_nds_name (filename, len); ++ ++ for (l = backend->entries; l != NULL; l = l->next) ++ { ++ entry = l->data; ++ ++ if (strcmp (normalized, entry->name_normalized) == 0) ++ { ++ found = entry; ++ break; ++ } ++ } ++if(normalized != NULL) ++ g_free (normalized); ++ } ++ ++ return found; ++} ++ ++static GMountSpec * ++get_mount_spec_for_share (const char *server, const char *share) ++{ ++ GMountSpec *mount_spec; ++ char *normalized; ++ ++ mount_spec = g_mount_spec_new ("nds"); ++ g_mount_spec_set (mount_spec, "host", server); ++ g_mount_spec_set (mount_spec, "share", share); ++ ++ return mount_spec; ++} ++ ++ ++ ++static void ++do_mount (GVfsBackend *backend, ++ GVfsJobMount *job, ++ GMountSpec *mount_spec, ++ GMountSource *mount_source, ++ gboolean is_automount) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ char *display_name; ++ char *icon; ++ GMountSpec *browse_mount_spec; ++ char *ptr = NULL; ++ ++ ++ icon = NULL; ++ if (op_backend->server == NULL) ++ { ++ display_name = g_strdup (_("NVVFS Top Directory")); ++ browse_mount_spec = g_mount_spec_new ("nds"); ++ icon = "network-workgroup"; ++ ++ } ++ else ++ { ++ display_name = g_strdup_printf (_("NVVFS Objects")); ++ browse_mount_spec = g_mount_spec_new ("nds"); ++ g_mount_spec_set (browse_mount_spec, "host", op_backend->server); ++ icon = "network-server"; ++ ++ } ++ ++ g_vfs_backend_set_display_name (backend, display_name); ++ g_free (display_name); ++ if (icon) ++ g_vfs_backend_set_icon_name (backend, icon); ++ g_vfs_backend_set_user_visible (backend, FALSE); ++ g_vfs_backend_set_mount_spec (backend, browse_mount_spec); ++ g_mount_spec_unref (browse_mount_spec); ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++} ++ ++static gboolean ++try_mount (GVfsBackend *backend, ++ GVfsJobMount *job, ++ GMountSpec *mount_spec, ++ GMountSource *mount_source, ++ gboolean is_automount) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ char *server; ++ char *share; ++ ++ server = g_mount_spec_get (mount_spec, "host"); ++ if (server) ++ { ++ op_backend->server = g_strdup (server); ++ op_backend->mounted_server = g_strdup (server); ++ } ++ else ++ { ++ op_backend->server = NULL; ++ op_backend->mounted_server = NULL; ++ } ++ ++ return FALSE; ++} ++ ++#define SUB_DELIM_CHARS "!$&'()*+,;=" ++ ++static gboolean ++is_valid (char c, const char *reserved_chars_allowed) ++{ ++ if (g_ascii_isalnum (c) || ++ c == '-' || ++ c == '.' || ++ c == '_' || ++ c == '~') ++ return TRUE; ++ ++ if (reserved_chars_allowed && ++ strchr (reserved_chars_allowed, c) != NULL) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static void ++g_string_append_encoded (GString *string, ++ const char *encoded, ++ const char *encoded_end, ++ const char *reserved_chars_allowed) ++{ ++ char c; ++ static const gchar hex[16] = "0123456789ABCDEF"; ++ ++ if (encoded_end == NULL) ++ encoded_end = encoded + strlen (encoded); ++ ++ while (encoded < encoded_end) ++ { ++ c = *encoded++; ++ ++ if (is_valid (c, reserved_chars_allowed)) ++ g_string_append_c (string, c); ++ else ++ { ++ g_string_append_c (string, '%'); ++ g_string_append_c (string, hex[((guchar)c) >> 4]); ++ g_string_append_c (string, hex[((guchar)c) & 0xf]); ++ } ++ } ++} ++ ++static void ++get_file_info_from_entry (GVfsBackendNds *backend, BrowseEntry *entry, GFileInfo *info) ++{ ++ GMountSpec *mount_spec; ++ GString *uri; ++ GIcon *icon; ++ ++ g_file_info_set_name (info, entry->name); ++ g_file_info_set_display_name (info, entry->name_utf8); ++ g_file_info_set_edit_name (info, entry->name_utf8); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL, TRUE); ++ ++ icon = g_themed_icon_new ("network-server"); ++ ++ if (icon) ++ { ++ g_file_info_set_icon (info, icon); ++ g_object_unref (icon); ++ } ++ ++ mount_spec = NULL; ++ ++ g_file_info_set_file_type (info, G_FILE_TYPE_SHORTCUT); ++ ++ uri = g_string_new ("nds://"); ++ g_string_append_encoded (uri, entry->name, NULL, NULL); ++ g_string_append_c (uri, '/'); ++ ++ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, uri->str); ++ ++ g_string_free (uri, TRUE); ++ ++} ++ ++static void ++run_query_info (GVfsBackendNds *backend, ++ GVfsJobQueryInfo *job, ++ const char *filename, ++ GFileInfo *info, ++ GFileAttributeMatcher *matcher) ++{ ++ BrowseEntry *entry; ++ ++ g_mutex_lock (backend->entries_lock); ++ ++ entry = find_entry_unlocked (backend, filename); ++ ++ if (entry) ++ get_file_info_from_entry (backend, entry, info); ++ ++ g_mutex_unlock (backend->entries_lock); ++ ++ if (entry) ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ else ++ g_vfs_job_failed (G_VFS_JOB (job), ++ G_IO_ERROR, G_IO_ERROR_NOT_FOUND, ++ _("File doesn't exist")); ++} ++ ++static void ++do_query_info (GVfsBackend *backend, ++ GVfsJobQueryInfo *job, ++ const char *filename, ++ GFileQueryInfoFlags flags, ++ GFileInfo *info, ++ GFileAttributeMatcher *matcher) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ ++ run_query_info (op_backend, job, filename, info, matcher); ++} ++ ++static gboolean ++try_query_info (GVfsBackend *backend, ++ GVfsJobQueryInfo *job, ++ const char *filename, ++ GFileQueryInfoFlags flags, ++ GFileInfo *info, ++ GFileAttributeMatcher *matcher) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ const char *icon_name; ++ GIcon *icon; ++ ++ if (filename && is_root (filename)) ++ { ++ g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); ++ g_file_info_set_name (info, "/"); ++ g_file_info_set_display_name (info, g_vfs_backend_get_display_name (backend)); ++ icon_name = g_vfs_backend_get_icon_name (backend); ++ if (icon_name) ++ { ++ icon = g_themed_icon_new (icon_name); ++ g_file_info_set_icon (info, icon); ++ g_object_unref (icon); ++ } ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++ ++ run_query_info (op_backend, job, filename, info, matcher); ++ return TRUE; ++} ++ ++static void ++run_enumerate (GVfsBackendNds *backend, ++ GVfsJobEnumerate *job, ++ const char *filename, ++ GFileAttributeMatcher *matcher) ++{ ++ GList *files, *l; ++ GFileInfo *info; ++ ++ g_vfs_job_succeeded (G_VFS_JOB (job)); ++ ++ files = NULL; ++ g_mutex_lock (backend->entries_lock); ++ for (l = backend->entries; l != NULL; l = l->next) ++ { ++ BrowseEntry *entry = l->data; ++ ++ info = g_file_info_new (); ++ get_file_info_from_entry (backend, entry, info); ++ ++ files = g_list_prepend (files, info); ++ } ++ g_mutex_unlock (backend->entries_lock); ++ ++ files = g_list_reverse (files); ++ ++ g_vfs_job_enumerate_add_infos (job, files); ++ g_list_foreach (files, (GFunc)g_object_unref, NULL); ++ g_list_free (files); ++ ++ g_vfs_job_enumerate_done (job); ++} ++ ++static void ++do_enumerate (GVfsBackend *backend, ++ GVfsJobEnumerate *job, ++ const char *filename, ++ GFileAttributeMatcher *matcher, ++ GFileQueryInfoFlags flags) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ ++ update_cache (op_backend,filename); ++ ++ run_enumerate (op_backend, job, filename, matcher); ++} ++ ++static gboolean ++try_enumerate (GVfsBackend *backend, ++ GVfsJobEnumerate *job, ++ const char *filename, ++ GFileAttributeMatcher *matcher, ++ GFileQueryInfoFlags flags) ++{ ++ GVfsBackendNds *op_backend = G_VFS_BACKEND_NDS (backend); ++ ++ ++ update_cache (op_backend,filename); ++ ++ run_enumerate (op_backend, job, filename, matcher); ++ return TRUE; ++} ++ ++ ++static void ++g_vfs_backend_nds_class_init (GVfsBackendNdsClass *klass) ++{ ++ GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ++ GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass); ++ ++ ++ gobject_class->finalize = g_vfs_backend_nds_finalize; ++ ++ backend_class->mount = do_mount; ++ backend_class->try_mount = try_mount; ++ backend_class->query_info = do_query_info; ++ backend_class->try_query_info = try_query_info; ++ backend_class->enumerate = do_enumerate; ++ backend_class->try_enumerate = try_enumerate; ++} ++ ++void ++g_vfs_nds_daemon_init (void) ++{ ++ g_set_application_name (_("Displaying Embedded Objects")); ++} +diff -Nurp gvfs-1.0.2_old/daemon/gvfsbackendnds.h gvfs-1.0.2_new/daemon/gvfsbackendnds.h +--- gvfs-1.0.2_old/daemon/gvfsbackendnds.h 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2_new/daemon/gvfsbackendnds.h 2009-01-14 14:40:44.000000000 +0530 +@@ -0,0 +1,53 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2006-2007 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * ++ * Author: Alexander Larsson ++ */ ++ ++#ifndef __G_VFS_BACKEND_NDS_H__ ++#define __G_VFS_BACKEND_NDS_H__ ++ ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++#define G_VFS_TYPE_BACKEND_NDS (g_vfs_backend_nds_get_type ()) ++#define G_VFS_BACKEND_NDS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_BACKEND_NDS, GVfsBackendNds)) ++#define G_VFS_BACKEND_NDS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_BACKEND_NDS, GVfsBackendNdsClass)) ++#define G_VFS_IS_BACKEND_NDS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_BACKEND_NDS)) ++#define G_VFS_IS_BACKEND_NDS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_BACKEND_NDS)) ++#define G_VFS_BACKEND_NDS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_BACKEND_NDS, GVfsBackendNdsClass)) ++ ++typedef struct _GVfsBackendNds GVfsBackendNds; ++typedef struct _GVfsBackendNdsClass GVfsBackendNdsClass; ++ ++struct _GVfsBackendNdsClass ++{ ++ GVfsBackendClass parent_class; ++}; ++ ++GType g_vfs_backend_nds_get_type (void) G_GNUC_CONST; ++ ++#define BACKEND_SETUP_FUNC g_vfs_nds_daemon_init ++void g_vfs_nds_daemon_init (void); ++ ++G_END_DECLS ++ ++#endif /* __G_VFS_BACKEND_NDS_H__ */ +diff -Nurp gvfs-1.0.2_old/daemon/Makefile.am gvfs-1.0.2_new/daemon/Makefile.am +--- gvfs-1.0.2_old/daemon/Makefile.am 2008-09-14 17:35:05.000000000 +0530 ++++ gvfs-1.0.2_new/daemon/Makefile.am 2009-01-14 14:33:49.000000000 +0530 +@@ -95,6 +95,10 @@ mount_DATA += archive.mount + libexec_PROGRAMS += gvfsd-archive + endif + ++mount_in_files += nds.mount.in ++mount_DATA += nds.mount ++libexec_PROGRAMS += gvfsd-nds ++ + EXTRA_DIST = gvfs-daemon.service.in $(mount_in_files) obexftp-marshal.list + + DISTCLEANFILES = gvfs-daemon.service $(mount_DATA) +@@ -395,3 +399,16 @@ gvfsd_dav_CPPFLAGS = \ + + gvfsd_dav_LDADD = $(libraries) $(HTTP_LIBS) + ++gvfsd_nds_SOURCES = \ ++ gvfsbackendnds.c gvfsbackendnds.h \ ++ daemon-main.c daemon-main.h \ ++ daemon-main-generic.c ++ ++gvfsd_nds_CPPFLAGS = \ ++ -DBACKEND_HEADER=gvfsbackendnds.h \ ++ -DDEFAULT_BACKEND_TYPE=nds \ ++ -DMAX_JOB_THREADS=1 \ ++ -DBACKEND_TYPES='"nds", G_VFS_TYPE_BACKEND_NDS,' ++ ++gvfsd_nds_LDADD = $(libraries) -ldl ++ +diff -Nurp gvfs-1.0.2_old/daemon/nds.mount.in gvfs-1.0.2_new/daemon/nds.mount.in +--- gvfs-1.0.2_old/daemon/nds.mount.in 1970-01-01 05:30:00.000000000 +0530 ++++ gvfs-1.0.2_new/daemon/nds.mount.in 2009-01-14 14:41:15.000000000 +0530 +@@ -0,0 +1,5 @@ ++[Mount] ++Type=nds ++Exec=@libexecdir@/gvfsd-nds ++AutoMount=false ++Scheme=nds