Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.2173
diff -u -r1.2173 ChangeLog
--- ChangeLog	23 Apr 2005 16:33:59 -0000	1.2173
+++ ChangeLog	28 Apr 2005 00:59:05 -0000
@@ -1,3 +1,14 @@
+2005-04-28  Alexander Brausewetter  <br@absb.de>
+
+	* libgnomevfs/gnome-vfs-method.h
+	* libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space)
+	* modules/file-method.c: (do_get_volume_free_space): Added module support
+	for gnome_vfs_get_volume_free_space.
+
+	Fixes bug #302202.
+
+	* doc/writing-modules.sgml: Updated documentation according to changes.
+
 2005-04-23  Christian Kellner <gicmo@gnome.org>
 
 	* modules/file-method.c: (get_access_info): Switch back to call 
Index: doc/writing-modules.sgml
===================================================================
RCS file: /cvs/gnome/gnome-vfs/doc/writing-modules.sgml,v
retrieving revision 1.10
diff -u -r1.10 writing-modules.sgml
--- doc/writing-modules.sgml	16 May 2004 12:09:43 -0000	1.10
+++ doc/writing-modules.sgml	28 Apr 2005 00:59:06 -0000
@@ -265,148 +265,221 @@
       <para>This object contains pointers to the module
       implementation functions.</para>
 
+      <para>A method can choose itself which functions to implement. However, it
+      must at least provide a <type>GnomeVFSMethodOpenFunc</type> and
+      <type>GnomeVFSMethodIsLocalFunc</type> implementation.
+      
+
+      <programlisting role="c">
+struct GnomeVFSMethod {
+	gsize method_table_size;			/* Used for versioning */
+	GnomeVFSMethodOpenFunc open;
+	GnomeVFSMethodCreateFunc create;
+	GnomeVFSMethodCloseFunc close;
+	GnomeVFSMethodReadFunc read;
+	GnomeVFSMethodWriteFunc write;
+	GnomeVFSMethodSeekFunc seek;
+	GnomeVFSMethodTellFunc tell;
+	GnomeVFSMethodTruncateHandleFunc truncate_handle;
+	GnomeVFSMethodOpenDirectoryFunc open_directory;
+	GnomeVFSMethodCloseDirectoryFunc close_directory;
+	GnomeVFSMethodReadDirectoryFunc read_directory;
+	GnomeVFSMethodGetFileInfoFunc get_file_info;
+	GnomeVFSMethodGetFileInfoFromHandleFunc get_file_info_from_handle;
+	GnomeVFSMethodIsLocalFunc is_local;
+	GnomeVFSMethodMakeDirectoryFunc make_directory;
+	GnomeVFSMethodRemoveDirectoryFunc remove_directory;
+	GnomeVFSMethodMoveFunc move;
+	GnomeVFSMethodUnlinkFunc unlink;
+	GnomeVFSMethodCheckSameFSFunc check_same_fs;
+	GnomeVFSMethodSetFileInfo set_file_info;
+	GnomeVFSMethodTruncateFunc truncate;
+	GnomeVFSMethodFindDirectoryFunc find_directory;
+	GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link;
+	GnomeVFSMethodMonitorAddFunc monitor_add;
+	GnomeVFSMethodMonitorCancelFunc monitor_cancel;
+	GnomeVFSMethodFileControlFunc file_control;
+	GnomeVFSMethodForgetCacheFunc forget_cache;
+	GnomeVFSMethodGetVolumeFreeSpaceFunc get_volume_free_space;
+};
+</programlisting>
+
       <programlisting role="c">
-GnomeVFSResult (* open)              (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle  **method_handle_return,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSOpenMode        mode,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* create)            (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle  **method_handle_return,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSOpenMode        mode,
-                                      gboolean                exclusive,
-                                      guint                   perm,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* close)             (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* read)              (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      gpointer                buffer,
-                                      GnomeVFSFileSize        num_bytes,
-                                      GnomeVFSFileSize       *bytes_read_return,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* write)             (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      gconstpointer           buffer,
-                                      GnomeVFSFileSize        num_bytes,
-                                      GnomeVFSFileSize       *bytes_written_return,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* seek)              (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      GnomeVFSSeekPosition    whence,
-                                      GnomeVFSFileOffset      offset,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* tell)              (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      GnomeVFSFileOffset     *offset_return);
-
-GnomeVFSResult (* truncate)          (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle  **method_handle,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSFileInfoOptions options,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* close_directory)   (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* read_directory)    (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      GnomeVFSFileInfo       *file_info,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* get_file_info)     (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSFileInfo       *file_info,
-                                      GnomeVFSFileInfoOptions options,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* get_file_info_from_handle)
-                                     (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandl e  *method_handle,
-                                      GnomeVFSFileInfo       *file_info,
-                                      GnomeVFSFileInfoOptions options,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* truncate)          (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSFileSize        length,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* truncate_handle)   (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *handle,
-                                      GnomeVFSFileSize        length,
-                                      GnomeVFSContext        *context);
-
-gboolean (* is_local)                (GnomeVFSMethod         *method,
-                                      const GnomeVFSURI      *uri);
-
-GnomeVFSResult (* make_directory)    (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *uri,
-                                      guint                   perm,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* find_directory)    (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *find_near_uri,
-                                      GnomeVFSFindDirectoryKind kind,
-                                      GnomeVFSURI           **result_uri,
-                                      gboolean                create_if_needed,
-                                      gboolean                find_if_needed,
-                                      guint                   perm,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* remove_directory)  (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* move)              (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *old_uri,
-                                      GnomeVFSURI            *new_uri,
-                                      gboolean                force_replace,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* unlink)            (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* check_same_fs)     (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *a,
-                                      GnomeVFSURI            *b,
-                                      gboolean               *same_fs_return,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* set_file_info)     (GnomeVFSMethod         *method,
-                                      GnomeVFSURI            *a,
-                                      const GnomeVFSFileInfo *info,
-                                      GnomeVFSSetFileInfoMask mask,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* create_symbolic_link) (GnomeVFSMethod      *method,
-                                      GnomeVFSURI            *uri,
-                                      const gchar            *target_reference,
-                                      GnomeVFSContext        *context);
-
-GnomeVFSResult (* monitor_add)       (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle  **method_handle_return,
-                                      GnomeVFSURI            *uri,
-                                      GnomeVFSMonitorType     monitor_type);
-
-GnomeVFSResult (* monitor_cancel)    (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *handle);
-
-GnomeVFSResult (* file_control)      (GnomeVFSMethod         *method,
-                                      GnomeVFSMethodHandle   *method_handle,
-                                      const char             *operation,
-                                      gpointer                operation_data,
-                                      GnomeVFSContext        *context);
+typedef GnomeVFSResult (* GnomeVFSMethodOpenFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle
+			       	 	**method_handle_return,
+					 GnomeVFSURI *uri,
+					 GnomeVFSOpenMode mode,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodCreateFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle
+			       	 	**method_handle_return,
+					 GnomeVFSURI *uri,
+					 GnomeVFSOpenMode mode,
+					 gboolean exclusive,
+					 guint perm,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodCloseFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodReadFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 gpointer buffer,
+					 GnomeVFSFileSize num_bytes,
+					 GnomeVFSFileSize *bytes_read_return,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodWriteFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 gconstpointer buffer,
+					 GnomeVFSFileSize num_bytes,
+					 GnomeVFSFileSize *bytes_written_return,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodSeekFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSSeekPosition  whence,
+					 GnomeVFSFileOffset    offset,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodTellFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSFileSize *offset_return);
+
+typedef GnomeVFSResult (* GnomeVFSMethodOpenDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle **method_handle,
+					 GnomeVFSURI *uri,
+					 GnomeVFSFileInfoOptions options,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodCloseDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodReadDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSFileInfo *file_info,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodGetFileInfoFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *uri,
+					 GnomeVFSFileInfo *file_info,
+					 GnomeVFSFileInfoOptions options,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodGetFileInfoFromHandleFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSFileInfo *file_info,
+					 GnomeVFSFileInfoOptions options,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodTruncateFunc) (GnomeVFSMethod *method,
+						       GnomeVFSURI *uri,
+						       GnomeVFSFileSize length,
+						       GnomeVFSContext *context);
+typedef GnomeVFSResult (* GnomeVFSMethodTruncateHandleFunc) (GnomeVFSMethod *method,
+							     GnomeVFSMethodHandle *handle,
+							     GnomeVFSFileSize length,
+							     GnomeVFSContext *context);
+
+typedef gboolean       (* GnomeVFSMethodIsLocalFunc)
+					(GnomeVFSMethod *method,
+					 const GnomeVFSURI *uri);
+
+typedef GnomeVFSResult (* GnomeVFSMethodMakeDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *uri,
+					 guint perm,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodFindDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *find_near_uri,
+					 GnomeVFSFindDirectoryKind kind,
+					 GnomeVFSURI **result_uri,
+					 gboolean create_if_needed,
+					 gboolean find_if_needed,
+					 guint perm,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodRemoveDirectoryFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *uri,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodMoveFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *old_uri,
+					 GnomeVFSURI *new_uri,
+					 gboolean force_replace,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodUnlinkFunc)
+                                        (GnomeVFSMethod *method,
+					 GnomeVFSURI *uri,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodCheckSameFSFunc)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *a,
+					 GnomeVFSURI *b,
+					 gboolean *same_fs_return,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodSetFileInfo)
+					(GnomeVFSMethod *method,
+					 GnomeVFSURI *a,
+					 const GnomeVFSFileInfo *info,
+					 GnomeVFSSetFileInfoMask mask,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodCreateSymbolicLinkFunc)
+                                        (GnomeVFSMethod *method,
+                                         GnomeVFSURI *uri,
+                                         const gchar *target_reference,
+                                         GnomeVFSContext *context);
+typedef GnomeVFSResult (* GnomeVFSMethodMonitorAddFunc)
+     					(GnomeVFSMethod *method,
+      					 GnomeVFSMethodHandle **method_handle_return,
+      					 GnomeVFSURI *uri,
+      					 GnomeVFSMonitorType monitor_type);
+
+typedef GnomeVFSResult (* GnomeVFSMethodMonitorCancelFunc)
+     					(GnomeVFSMethod *method,
+      					 GnomeVFSMethodHandle *handle);
+
+typedef GnomeVFSResult (* GnomeVFSMethodFileControlFunc)
+     					(GnomeVFSMethod *method,
+      					 GnomeVFSMethodHandle *method_handle,
+					 const char *operation,
+					 gpointer operation_data,
+					 GnomeVFSContext *context);
+
+typedef GnomeVFSResult (* GnomeVFSMethodForgetCacheFunc)
+     					(GnomeVFSMethod *method,
+      					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSFileOffset offset,
+					 GnomeVFSFileSize size);
+
+typedef GnomeVFSResult (* GnomeVFSMethodGetVolumeFreeSpaceFunc)
+     					(GnomeVFSMethod *method,
+					 const GnomeVFSURI *uri,
+				 	 GnomeVFSFileSize *free_space);
 </programlisting>
 
     </refsect2>
Index: libgnomevfs/gnome-vfs-method.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-method.h,v
retrieving revision 1.16
diff -u -r1.16 gnome-vfs-method.h
--- libgnomevfs/gnome-vfs-method.h	14 Apr 2005 18:48:29 -0000	1.16
+++ libgnomevfs/gnome-vfs-method.h	28 Apr 2005 00:59:07 -0000
@@ -222,6 +222,11 @@
       					 GnomeVFSMethodHandle *method_handle,
 					 GnomeVFSFileOffset offset,
 					 GnomeVFSFileSize size);
+
+typedef GnomeVFSResult (* GnomeVFSMethodGetVolumeFreeSpaceFunc)
+     					(GnomeVFSMethod *method,
+					 const GnomeVFSURI *uri,
+				 	 GnomeVFSFileSize *free_space);
 
 
 /* Use this macro to test whether a given function is implemented in
@@ -262,6 +267,7 @@
 	GnomeVFSMethodMonitorCancelFunc monitor_cancel;
 	GnomeVFSMethodFileControlFunc file_control;
 	GnomeVFSMethodForgetCacheFunc forget_cache;
+	GnomeVFSMethodGetVolumeFreeSpaceFunc get_volume_free_space;
 };
 
 gboolean	   gnome_vfs_method_init   (void);
Index: libgnomevfs/gnome-vfs-utils.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-utils.c,v
retrieving revision 1.98
diff -u -r1.98 gnome-vfs-utils.c
--- libgnomevfs/gnome-vfs-utils.c	20 Apr 2005 23:58:14 -0000	1.98
+++ libgnomevfs/gnome-vfs-utils.c	28 Apr 2005 00:59:08 -0000
@@ -37,6 +37,7 @@
 #include "gnome-vfs-ops.h"
 #include "gnome-vfs-mime-handlers.h"
 #include "gnome-vfs-mime-private.h"
+#include "gnome-vfs-method.h"
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <gconf/gconf-client.h>
@@ -50,16 +51,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#if HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-
-#if HAVE_SYS_VFS_H
-#include <sys/vfs.h>
-#elif HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-
 #define KILOBYTE_FACTOR 1024.0
 #define MEGABYTE_FACTOR (1024.0 * 1024.0)
 #define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
@@ -807,104 +798,23 @@
 
 /**
  * gnome_vfs_get_volume_free_space:
- * @vfs_uri:
- * @size:
+ * @vfs_uri: 
+ * @size: 
  * 
- * Stores in @size the amount of free space on a volume.
- * This only works for URIs with the file: scheme.
+ * Stores the amount of free space in bytes on @vfs-uri's
+ * volume in @size.
  *
- * Returns: GNOME_VFS_OK on success, otherwise an error code
+ * Returns: GNOME_VFS_OK on success, otherwise an
+ *          GNOME_VFS_ERROR_* code
  */
 GnomeVFSResult
 gnome_vfs_get_volume_free_space (const GnomeVFSURI *vfs_uri, 
 				 GnomeVFSFileSize  *size)
 {	
-#ifndef G_OS_WIN32
-	GnomeVFSFileSize free_blocks, block_size;
-       	int statfs_result;
-	const char *path, *scheme;
-	char *unescaped_path;
-
-#if HAVE_STATVFS
-	struct statvfs statfs_buffer;
-#else
-	struct statfs statfs_buffer;
-#endif
-
- 	*size = 0;
-
-	path = gnome_vfs_uri_get_path (vfs_uri);
-	if (path == NULL) {
+	if (!VFS_METHOD_HAS_FUNC(vfs_uri->method, get_volume_free_space))
 		return GNOME_VFS_ERROR_NOT_SUPPORTED;
-	}
 
-	scheme = gnome_vfs_uri_get_scheme (vfs_uri);
-	
-        /* We only handle the file scheme for now */
-	if (g_ascii_strcasecmp (scheme, "file") != 0 || !_gnome_vfs_istr_has_prefix (path, "/")) {
-		return GNOME_VFS_ERROR_NOT_SUPPORTED;
-	}
-
-	unescaped_path = gnome_vfs_unescape_string (path, G_DIR_SEPARATOR_S);
-	
-#if HAVE_STATVFS
-	statfs_result = statvfs (unescaped_path, &statfs_buffer);
-	block_size = statfs_buffer.f_frsize; 
-#else
-#if STATFS_ARGS == 2
-	statfs_result = statfs (unescaped_path, &statfs_buffer);
-#elif STATFS_ARGS == 4
-	statfs_result = statfs (unescaped_path, &statfs_buffer,
-				sizeof (statfs_buffer), 0);
-#endif
-	block_size = statfs_buffer.f_bsize; 
-#endif  
-
-	if (statfs_result != 0) {
-		g_free (unescaped_path);
-		return gnome_vfs_result_from_errno ();
-	}
-
-
-/* CF: I assume ncpfs is linux specific, if you are on a non-linux platform
- * where ncpfs is available, please file a bug about it on bugzilla.gnome.org
- * (2004-03-08)
- */
-#if defined(__linux__)
-	/* ncpfs does not know the amount of available and free space */
-	if (statfs_buffer.f_bavail == 0 && statfs_buffer.f_bfree == 0) {
-		/* statvfs does not contain an f_type field, we try again
-		 * with statfs.
-		 */
-		struct statfs statfs_buffer2;
-		statfs_result = statfs (unescaped_path, &statfs_buffer2);
-		g_free (unescaped_path);
-
-		if (statfs_result != 0) {
-			return gnome_vfs_result_from_errno ();
-		}
-		
-		/* linux/ncp_fs.h: NCP_SUPER_MAGIC == 0x564c */
-		if (statfs_buffer2.f_type == 0x564c)
-		{
-			return GNOME_VFS_ERROR_NOT_SUPPORTED;
-		}
-	} else {
-		/* everything is copacetic... free the unescaped path */
-		g_free (unescaped_path);
-	}
-#else 	
-	g_free (unescaped_path);
-#endif
-	free_blocks = statfs_buffer.f_bavail;
-
-	*size = block_size * free_blocks;
-	
-	return GNOME_VFS_OK;
-#else
-	g_warning ("Not implemented: gnome_vfs_get_volume_free_space()");
-	return GNOME_VFS_ERROR_NOT_SUPPORTED;
-#endif
+	return vfs_uri->method->get_volume_free_space (vfs_uri->method, vfs_uri, size);
 }
 
 char *
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.139
diff -u -r1.139 file-method.c
--- modules/file-method.c	23 Apr 2005 16:33:59 -0000	1.139
+++ modules/file-method.c	28 Apr 2005 00:59:10 -0000
@@ -60,6 +60,15 @@
 #include <fam.h>
 #endif
 
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#elif HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+
 #ifdef G_OS_WIN32
 #include <windows.h>
 #endif
@@ -2498,6 +2507,93 @@
 	return GNOME_VFS_ERROR_NOT_SUPPORTED;
 }
 
+static GnomeVFSResult
+do_get_volume_free_space (GnomeVFSMethod *method,
+			  const GnomeVFSURI *uri,
+			  GnomeVFSFileSize *free_space)
+{
+#ifndef G_OS_WIN32
+	GnomeVFSFileSize free_blocks, block_size;
+       	int statfs_result;
+	const char *path;
+	char *unescaped_path;
+
+#if HAVE_STATVFS
+	struct statvfs statfs_buffer;
+#else
+	struct statfs statfs_buffer;
+#endif
+
+ 	*free_space = 0;
+
+	path = gnome_vfs_uri_get_path (uri);
+	if (path == NULL || !_gnome_vfs_istr_has_prefix (path, "/")) {
+		return GNOME_VFS_ERROR_INVALID_URI;
+	}
+
+	unescaped_path = gnome_vfs_unescape_string (path, G_DIR_SEPARATOR_S);
+	
+#if HAVE_STATVFS
+	statfs_result = statvfs (unescaped_path, &statfs_buffer);
+	block_size = statfs_buffer.f_frsize; 
+#else
+#if STATFS_ARGS == 2
+	statfs_result = statfs (unescaped_path, &statfs_buffer);
+#elif STATFS_ARGS == 4
+	statfs_result = statfs (unescaped_path, &statfs_buffer,
+				sizeof (statfs_buffer), 0);
+#endif
+	block_size = statfs_buffer.f_bsize; 
+#endif  
+
+	if (statfs_result != 0) {
+		g_free (unescaped_path);
+		return gnome_vfs_result_from_errno ();
+	}
+
+
+/* CF: I assume ncpfs is linux specific, if you are on a non-linux platform
+ * where ncpfs is available, please file a bug about it on bugzilla.gnome.org
+ * (2004-03-08)
+ */
+#if defined(__linux__)
+	/* ncpfs does not know the amount of available and free space */
+	if (statfs_buffer.f_bavail == 0 && statfs_buffer.f_bfree == 0) {
+		/* statvfs does not contain an f_type field, we try again
+		 * with statfs.
+		 */
+		struct statfs statfs_buffer2;
+		statfs_result = statfs (unescaped_path, &statfs_buffer2);
+		g_free (unescaped_path);
+
+		if (statfs_result != 0) {
+			return gnome_vfs_result_from_errno ();
+		}
+		
+		/* linux/ncp_fs.h: NCP_SUPER_MAGIC == 0x564c */
+		if (statfs_buffer2.f_type == 0x564c)
+		{
+			return GNOME_VFS_ERROR_NOT_SUPPORTED;
+		}
+	} else {
+		/* everything is copacetic... free the unescaped path */
+		g_free (unescaped_path);
+	}
+#else 	
+	g_free (unescaped_path);
+#endif
+	free_blocks = statfs_buffer.f_bavail;
+
+	*free_space = block_size * free_blocks;
+	
+	return GNOME_VFS_OK;
+#else // G_OS_WIN32
+	g_warning ("Not implemented for WIN32: file-method.c:do_get_volume_free_space()");
+	return GNOME_VFS_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+
 static GnomeVFSMethod method = {
 	sizeof (GnomeVFSMethod),
 	do_open,
@@ -2526,7 +2622,8 @@
 	do_monitor_add,
 	do_monitor_cancel,
 	do_file_control,
-	do_forget_cache
+	do_forget_cache,
+	do_get_volume_free_space
 };
 
 GnomeVFSMethod *
