diff --git a/ChangeLog b/ChangeLog
index b8cf9dc63018ad48417c911e9486a146d6aaffa6..7ae5eba5d0dfd3a353cc815abab39a344d39c0de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2006-02-02	Benedikt Meurer <benny@xfce.org>
+
+	* configure.in.in: Check for statvfs() and statfs(), and required
+	  header files.
+	* thunar-vfs/thunar-vfs-info.{c,h}, thunar-vfs/thunar-vfs-volume.{c,h},
+	  thunar-vfs/thunar-vfs-volume-bsd.c, thunar-vfs/thunar-vfs.symbols:
+	  Move the get_free_space() method from ThunarVfsVolume to ThunarVfsInfo
+	  so we can use it even if no volume manager implementation is avail-
+	  able for the target system. Bug #1420.
+	* thunar/thunar-file.h: Add get_free_space() method to ThunarFile, so
+	  we can easily determine the amount free space for a given volume
+	  based on a file located on that volume. Bug #1421.
+	* thunar/thunar-list-model.c(thunar_list_model_get_statusbar_text): Use
+	  new method thunar_file_get_free_space().
+	* thunar/thunar-properties-dialog.c: Display the amount of free space
+	  on a certain volume in the properties dialog for folders.
+
 2006-02-02	Benedikt Meurer <benny@xfce.org>
 
 	* thunar/thunar-throbber.c: Fix typo in GDK_WINDOWING_X11. Cannot use
diff --git a/configure.in.in b/configure.in.in
index be70fe60c760cacaedc50cbfb3ce822060cc2080..56849d184702d3e21325c9582a712632af7e6162 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -104,17 +104,17 @@ dnl **********************************
 AC_CHECK_HEADERS([ctype.h dirent.h errno.h fcntl.h fnmatch.h fstab.h grp.h \
                   locale.h math.h memory.h mmintrin.h pwd.h sched.h setjmp.h \
                   stdarg.h stdlib.h string.h sys/xattr.h sys/extattr.h \
-                  sys/cdio.h sys/mman.h \
-                  sys/mount.h sys/param.h sys/stat.h sys/time.h sys/uio.h \
-                  sys/wait.h time.h wchar.h wctype.h])
+                  sys/cdio.h sys/mman.h sys/mount.h sys/param.h sys/stat.h \
+                  sys/statfs.h sys/statvfs.h sys/time.h sys/uio.h \
+                  sys/vfs.h sys/wait.h time.h wchar.h wctype.h])
 
 dnl ************************************
 dnl *** Check for standard functions ***
 dnl ************************************
 AC_FUNC_MMAP()
 AC_CHECK_FUNCS([attropen extattr_get_fd fgetxattr lchmod localtime_r \
-                mbrtowc pread pwrite readdir_r \
-                sched_yield setgroupent setpassent])
+                mbrtowc pread pwrite readdir_r sched_yield setgroupent \
+                setpassent statfs statvfs])
 
 dnl ***************************************
 dnl *** Check for working posix_madvise ***
diff --git a/thunar-vfs/thunar-vfs-info.c b/thunar-vfs/thunar-vfs-info.c
index de6734b7cc96cd0de4fd3e9e624e4e84a87b5aae..7e50684b4e5c7eeaaea66ccaccc5c6ea18a75407 100644
--- a/thunar-vfs/thunar-vfs-info.c
+++ b/thunar-vfs/thunar-vfs-info.c
@@ -22,9 +22,24 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -191,6 +206,63 @@ thunar_vfs_info_copy (const ThunarVfsInfo *info)
 
 
 
+/**
+ * thunar_vfs_info_get_free_space:
+ * @info              : a #ThunarVfsInfo.
+ * @free_space_return : return location for the amount of free space or %NULL.
+ *
+ * Determines the amount of free space available on the volume on which the
+ * file to which @info refers resides. If the system is able to determine the
+ * amount of free space, it will be placed into the location to which
+ * @free_space_return points and %TRUE will be returned, else the function
+ * will return %FALSE indicating that the system is unable to determine the
+ * amount of free space.
+ *
+ * Return value: %TRUE if the amount of free space could be determined, else
+ *               %FALSE:
+ **/
+gboolean
+thunar_vfs_info_get_free_space (const ThunarVfsInfo *info,
+                                ThunarVfsFileSize   *free_space_return)
+{
+#if defined(HAVE_STATFS)
+  struct statfs  statfsb;
+#elif defined(HAVE_STATVFS)
+  struct statvfs statvfsb;
+#endif
+  gchar          absolute_path[THUNAR_VFS_PATH_MAXSTRLEN];
+
+  g_return_val_if_fail (info != NULL, FALSE);
+  g_return_val_if_fail (info->ref_count > 0, FALSE);
+
+  /* determine the absolute path */
+  if (thunar_vfs_path_to_string (info->path, absolute_path, sizeof (absolute_path), NULL) < 0)
+    return FALSE;
+
+#if defined(HAVE_STATFS)
+  if (statfs (absolute_path, &statfsb) == 0)
+    {
+      /* good old BSD way */
+      if (G_LIKELY (free_space_return != NULL))
+        *free_space_return = (statfsb.f_bavail * statfsb.f_bsize);
+      return TRUE;
+    }
+#elif defined(HAVE_STATVFS)
+  if (statvfs (absolute_path, &statvfsb) == 0)
+    {
+      /* Linux, IRIX, Solaris way */
+      if (G_LIKELY (free_space_return != NULL))
+        *free_space_return = (statvfsb.f_bavail * statvfsb.f_bsize);
+      return TRUE;
+    }
+#endif
+
+  /* unable to determine the amount of free space */
+  return FALSE;
+}
+
+
+
 /**
  * thunar_vfs_info_read_link:
  * @info  : a #ThunarVfsInfo.
diff --git a/thunar-vfs/thunar-vfs-info.h b/thunar-vfs/thunar-vfs-info.h
index 55c2a5985c78c0462a0b6b0762cc976df85af894..b3e9d7340bb8941ef7e84d952a66237e99b52bf2 100644
--- a/thunar-vfs/thunar-vfs-info.h
+++ b/thunar-vfs/thunar-vfs-info.h
@@ -97,6 +97,9 @@ void                         thunar_vfs_info_unref            (ThunarVfsInfo
 
 ThunarVfsInfo               *thunar_vfs_info_copy             (const ThunarVfsInfo *info) G_GNUC_MALLOC;
 
+gboolean                     thunar_vfs_info_get_free_space   (const ThunarVfsInfo *info,
+                                                               ThunarVfsFileSize   *free_space_return);
+
 G_INLINE_FUNC const gchar   *thunar_vfs_info_get_custom_icon  (const ThunarVfsInfo *info);
 
 gchar                       *thunar_vfs_info_read_link        (const ThunarVfsInfo *info,
diff --git a/thunar-vfs/thunar-vfs-volume-bsd.c b/thunar-vfs/thunar-vfs-volume-bsd.c
index dd4a3de750fbed612345decec8933a7dfb06f344..7f8dc034f27f391cb703cfabb2f8d65b403d01ec 100644
--- a/thunar-vfs/thunar-vfs-volume-bsd.c
+++ b/thunar-vfs/thunar-vfs-volume-bsd.c
@@ -60,8 +60,6 @@ static ThunarVfsVolumeKind   thunar_vfs_volume_bsd_get_kind         (ThunarVfsVo
 static const gchar          *thunar_vfs_volume_bsd_get_name         (ThunarVfsVolume         *volume);
 static ThunarVfsVolumeStatus thunar_vfs_volume_bsd_get_status       (ThunarVfsVolume         *volume);
 static ThunarVfsPath        *thunar_vfs_volume_bsd_get_mount_point  (ThunarVfsVolume         *volume);
-static gboolean              thunar_vfs_volume_bsd_get_free_space   (ThunarVfsVolume         *volume,
-                                                                     ThunarVfsFileSize       *free_space_return);
 static gboolean              thunar_vfs_volume_bsd_eject            (ThunarVfsVolume         *volume,
                                                                      GtkWidget               *window,
                                                                      GError                 **error);
@@ -129,7 +127,6 @@ thunar_vfs_volume_bsd_volume_init (ThunarVfsVolumeIface *iface)
   iface->get_name = thunar_vfs_volume_bsd_get_name;
   iface->get_status = thunar_vfs_volume_bsd_get_status;
   iface->get_mount_point = thunar_vfs_volume_bsd_get_mount_point;
-  iface->get_free_space = thunar_vfs_volume_bsd_get_free_space;
   iface->eject = thunar_vfs_volume_bsd_eject;
   iface->mount = thunar_vfs_volume_bsd_mount;
   iface->unmount = thunar_vfs_volume_bsd_unmount;
@@ -199,17 +196,6 @@ thunar_vfs_volume_bsd_get_mount_point (ThunarVfsVolume *volume)
 
 
 
-static gboolean
-thunar_vfs_volume_bsd_get_free_space (ThunarVfsVolume   *volume,
-                                      ThunarVfsFileSize *free_space_return)
-{
-  ThunarVfsVolumeBSD *volume_bsd = THUNAR_VFS_VOLUME_BSD (volume);
-  *free_space_return = volume_bsd->info.f_bavail * volume_bsd->info.f_bsize;
-  return TRUE;
-}
-
-
-
 static gboolean
 thunar_vfs_volume_bsd_eject (ThunarVfsVolume *volume,
                              GtkWidget       *window,
diff --git a/thunar-vfs/thunar-vfs-volume.c b/thunar-vfs/thunar-vfs-volume.c
index 09f5f9758ca36461e2a718ab767b2300f2cecedb..f23718365db62a995ab5686924e051adf6926798 100644
--- a/thunar-vfs/thunar-vfs-volume.c
+++ b/thunar-vfs/thunar-vfs-volume.c
@@ -271,34 +271,6 @@ thunar_vfs_volume_is_removable (ThunarVfsVolume *volume)
 
 
 
-/**
- * thunar_vfs_volume_get_free_space:
- * @volume            : a #ThunarVfsVolume instance.
- * @free_space_return : location to store the free space to.
- *
- * Tries to determine the number of available bytes on the specified
- * @volume and places the result to the memory pointed to by
- * @free_space_return. The returned amount of bytes represents the
- * space available to the current user, which may be different from
- * the total free amount.
- *
- * If @volume is unable to determine the free space, %FALSE will be
- * returned and @free_space_return won't be set.
- *
- * Return value: %TRUE if the free amount was determined successfully,
- *               else %FALSE.
- **/
-gboolean
-thunar_vfs_volume_get_free_space (ThunarVfsVolume   *volume,
-                                  ThunarVfsFileSize *free_space_return)
-{
-  g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE);
-  g_return_val_if_fail (free_space_return != NULL, FALSE);
-  return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_free_space) (volume, free_space_return);
-}
-
-
-
 /**
  * thunar_vfs_volume_lookup_icon_name:
  * @volume     : a #ThunarVfsVolume instance.
diff --git a/thunar-vfs/thunar-vfs-volume.h b/thunar-vfs/thunar-vfs-volume.h
index 218bf8a7507550a53ed4fbb901a80b0aed1c6e5f..6ed1f0efde8f3bc706ca44fe23fc5a9890499ee7 100644
--- a/thunar-vfs/thunar-vfs-volume.h
+++ b/thunar-vfs/thunar-vfs-volume.h
@@ -81,8 +81,6 @@ struct _ThunarVfsVolumeIface
   const gchar          *(*get_name)         (ThunarVfsVolume   *volume);
   ThunarVfsVolumeStatus (*get_status)       (ThunarVfsVolume   *volume);
   ThunarVfsPath        *(*get_mount_point)  (ThunarVfsVolume   *volume);
-  gboolean              (*get_free_space)   (ThunarVfsVolume   *volume,
-                                             ThunarVfsFileSize *free_space_return);
   const gchar          *(*lookup_icon_name) (ThunarVfsVolume   *volume,
                                              GtkIconTheme      *icon_theme);
 
@@ -128,9 +126,6 @@ gboolean              thunar_vfs_volume_is_present        (ThunarVfsVolume   *vo
 gboolean              thunar_vfs_volume_is_ejectable      (ThunarVfsVolume   *volume);
 gboolean              thunar_vfs_volume_is_removable      (ThunarVfsVolume   *volume);
 
-gboolean              thunar_vfs_volume_get_free_space    (ThunarVfsVolume   *volume,
-                                                           ThunarVfsFileSize *free_space_return);
-
 const gchar          *thunar_vfs_volume_lookup_icon_name  (ThunarVfsVolume   *volume,
                                                            GtkIconTheme      *icon_theme);
 
diff --git a/thunar-vfs/thunar-vfs.symbols b/thunar-vfs/thunar-vfs.symbols
index bcaecdeebe8a7b8ce509fe44beda1c0ba4825423..44184309cea2fb150eb669076a1a5f3c3074f905 100644
--- a/thunar-vfs/thunar-vfs.symbols
+++ b/thunar-vfs/thunar-vfs.symbols
@@ -81,6 +81,7 @@ thunar_vfs_info_copy
 #ifdef INCLUDE_INTERNAL_SYMBOLS
 thunar_vfs_info_get_custom_icon
 #endif
+thunar_vfs_info_get_free_space
 thunar_vfs_info_read_link G_GNUC_MALLOC
 thunar_vfs_info_execute
 thunar_vfs_info_rename
@@ -297,7 +298,6 @@ thunar_vfs_volume_is_mounted
 thunar_vfs_volume_is_present
 thunar_vfs_volume_is_ejectable
 thunar_vfs_volume_is_removable
-thunar_vfs_volume_get_free_space
 thunar_vfs_volume_lookup_icon_name
 thunar_vfs_volume_eject
 thunar_vfs_volume_mount
diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h
index bbf59ce8811535f3ab414ac553e40fb99af76437..6421bafbdf90e01352e0311a80af6c00ccf346a9 100644
--- a/thunar/thunar-file.h
+++ b/thunar/thunar-file.h
@@ -146,6 +146,9 @@ static inline ThunarVfsFileType  thunar_file_get_kind             (const ThunarF
 static inline ThunarVfsFileMode  thunar_file_get_mode             (const ThunarFile       *file);
 static inline ThunarVfsFileSize  thunar_file_get_size             (const ThunarFile       *file);
 
+static inline gboolean           thunar_file_get_free_space       (const ThunarFile       *file,
+                                                                   ThunarVfsFileSize      *free_space_return);
+
 gchar                           *thunar_file_get_date_string      (const ThunarFile       *file,
                                                                    ThunarFileDateType      date_type);
 gchar                           *thunar_file_get_mode_string      (const ThunarFile       *file);
@@ -345,6 +348,29 @@ thunar_file_get_size (const ThunarFile *file)
   return file->info->size;
 }
 
+/**
+ * thunar_file_get_free_space:
+ * @file              : a #ThunarFile instance.
+ * @free_space_return : return location for the amount of
+ *                      free space or %NULL.
+ *
+ * Determines the amount of free space of the volume on
+ * which @file resides. Returns %TRUE if the amount of
+ * free space was determined successfully and placed into
+ * @free_space_return, else %FALSE will be returned.
+ *
+ * Return value: %TRUE if successfull, else %FALSE.
+ **/
+static inline gboolean
+thunar_file_get_free_space (const ThunarFile  *file,
+                            ThunarVfsFileSize *free_space_return)
+{
+  g_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
+  return thunar_vfs_info_get_free_space (file->info, free_space_return);
+}
+
+
+
 /**
  * thunar_file_get_custom_icon:
  * @file : a #ThunarFile instance.
diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c
index affdbd1fc6c656120679ce0e3c9396b145f89b58..5f53682581d150b0da700c2da0a1006f8016e12c 100644
--- a/thunar/thunar-list-model.c
+++ b/thunar/thunar-list-model.c
@@ -1977,7 +1977,6 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store,
   ThunarVfsMimeInfo *mime_info;
   ThunarVfsFileSize  size_summary;
   ThunarVfsFileSize  size;
-  ThunarVfsVolume   *volume;
   GtkTreeIter        iter;
   ThunarFile        *file;
   GList             *lp;
@@ -1991,9 +1990,9 @@ thunar_list_model_get_statusbar_text (ThunarListModel *store,
     {
       /* try to determine a file for the current folder */
       file = (store->folder != NULL) ? thunar_folder_get_corresponding_file (store->folder) : NULL;
-      volume = (file != NULL) ? thunar_file_get_volume (file, store->volume_manager) : NULL;
 
-      if (G_LIKELY (volume != NULL && thunar_vfs_volume_get_free_space (volume, &size)))
+      /* check if we can determine the amount of free space for the volume */
+      if (G_LIKELY (file != NULL && thunar_file_get_free_space (file, &size)))
         {
           size_string = thunar_vfs_humanize_size (size, NULL, 0);
           text = g_strdup_printf (ngettext ("%d item, Free space: %s", "%d items, Free space: %s", store->nrows), store->nrows, size_string);
diff --git a/thunar/thunar-properties-dialog.c b/thunar/thunar-properties-dialog.c
index aa0389ee47aa23a605c6e439b9eb322e3fc4d444..01502c83538b9d25d4090231b61d5a0214372b5a 100644
--- a/thunar/thunar-properties-dialog.c
+++ b/thunar/thunar-properties-dialog.c
@@ -99,6 +99,7 @@ struct _ThunarPropertiesDialog
   GtkWidget              *link_label;
   GtkWidget              *modified_label;
   GtkWidget              *accessed_label;
+  GtkWidget              *freespace_label;
   GtkWidget              *volume_image;
   GtkWidget              *volume_label;
   GtkWidget              *size_label;
@@ -339,8 +340,21 @@ thunar_properties_dialog_init (ThunarPropertiesDialog *dialog)
 
 
   /*
-     Fourth box (volume, size)
+     Fourth box (free space, volume, size)
    */
+  label = gtk_label_new (_("Free Space:"));
+  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
+  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
+  gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (label);
+
+  dialog->freespace_label = g_object_new (GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
+  exo_binding_new (G_OBJECT (dialog->freespace_label), "visible", G_OBJECT (label), "visible");
+  gtk_table_attach (GTK_TABLE (table), dialog->freespace_label, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (dialog->freespace_label);
+
+  ++row;
+
   label = gtk_label_new (_("Volume:"));
   gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
   gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
@@ -711,6 +725,19 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
       gtk_widget_hide (dialog->accessed_label);
     }
 
+  /* update the free space (only for folders) */
+  if (thunar_file_is_directory (dialog->file) && thunar_file_get_free_space (dialog->file, &size))
+    {
+      size_string = thunar_vfs_humanize_size (size, NULL, 0);
+      gtk_label_set_text (GTK_LABEL (dialog->freespace_label), size_string);
+      gtk_widget_show (dialog->freespace_label);
+      g_free (size_string);
+    }
+  else
+    {
+      gtk_widget_hide (dialog->freespace_label);
+    }
+
   /* update the volume */
   volume = thunar_file_get_volume (dialog->file, dialog->volume_manager);
   if (G_LIKELY (volume != NULL))
@@ -737,7 +764,7 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
       if (G_LIKELY (size_string != NULL))
         {
           size = thunar_file_get_size (dialog->file);
-          str = g_strdup_printf (_("%s (%u Bytes)"), size_string, (guint) size);
+          str = g_strdup_printf (_("%s (%lld Bytes)"), size_string, (gint64) size);
           gtk_label_set_text (GTK_LABEL (dialog->size_label), str);
           gtk_widget_show (dialog->size_label);
           g_free (size_string);