X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fstatvfs.c;h=e71b19a78e399aa486d286e90999b1450f0648c3;hp=40df9b9d76aa7b889698dbc3c8e71ae6841dc4cf;hb=43eed091129212dd29996838cf1d76af0f8fc135;hpb=63516f39a0b1381ef3d06d9eb55141bf6c4466b0 diff --git a/daemon/statvfs.c b/daemon/statvfs.c index 40df9b9..e71b19a 100644 --- a/daemon/statvfs.c +++ b/daemon/statvfs.c @@ -18,14 +18,23 @@ #include +#ifdef HAVE_WINDOWS_H +#include +#endif + #include #include #include #include -#include #include #include +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#include + #include "../src/guestfs_protocol.h" #include "daemon.h" #include "actions.h" @@ -33,6 +42,7 @@ guestfs_int_statvfs * do_statvfs (const char *path) { +#ifdef HAVE_STATVFS int r; guestfs_int_statvfs *ret; struct statvfs statbuf; @@ -65,4 +75,112 @@ do_statvfs (const char *path) ret->namemax = statbuf.f_namemax; return ret; + +#else /* !HAVE_STATVFS */ +# if WIN32 + + char *disk; + guestfs_int_statvfs *ret; + ULONGLONG free_bytes_available; /* for user - similar to bavail */ + ULONGLONG total_number_of_bytes; + ULONGLONG total_number_of_free_bytes; /* for everyone - bfree */ + + disk = sysroot_path (path); + if (!disk) { + reply_with_perror ("malloc"); + return NULL; + } + + if (!GetDiskFreeSpaceEx (disk, + (PULARGE_INTEGER) &free_bytes_available, + (PULARGE_INTEGER) &total_number_of_bytes, + (PULARGE_INTEGER) &total_number_of_free_bytes)) { + reply_with_perror ("GetDiskFreeSpaceEx"); + free (disk); + return NULL; + } + free (disk); + + ret = malloc (sizeof *ret); + if (ret == NULL) { + reply_with_perror ("malloc"); + return NULL; + } + + /* XXX I couldn't determine how to get block size. MSDN has a + * unhelpful hard-coded list here: + * http://support.microsoft.com/kb/140365 + * but this depends on the filesystem type, the size of the disk and + * the version of Windows. So this code assumes the disk is NTFS + * and the version of Windows is >= Win2K. + */ + if (total_number_of_bytes < 16ULL * 1024 * 1024 * 1024 * 1024) + ret->bsize = 4096; + else if (total_number_of_bytes < 32ULL * 1024 * 1024 * 1024 * 1024) + ret->bsize = 8192; + else if (total_number_of_bytes < 64ULL * 1024 * 1024 * 1024 * 1024) + ret->bsize = 16384; + else if (total_number_of_bytes < 128ULL * 1024 * 1024 * 1024 * 1024) + ret->bsize = 32768; + else + ret->bsize = 65536; + + /* As with stat, -1 indicates a field is not known. */ + ret->frsize = ret->bsize; + ret->blocks = total_number_of_bytes / ret->bsize; + ret->bfree = total_number_of_free_bytes / ret->bsize; + ret->bavail = free_bytes_available / ret->bsize; + ret->files = -1; + ret->ffree = -1; + ret->favail = -1; + ret->fsid = -1; + ret->flag = -1; + ret->namemax = FILENAME_MAX; + + return ret; + +# else /* !WIN32 */ + + char *disk; + int r; + guestfs_int_statvfs *ret; + struct fs_usage fsu; + + disk = sysroot_path (path); + if (!disk) { + reply_with_perror ("malloc"); + return NULL; + } + + r = get_fs_usage (disk, disk, &fsu); + free (disk); + + if (r == -1) { + reply_with_perror ("get_fs_usage: %s", path); + return NULL; + } + + ret = malloc (sizeof *ret); + if (ret == NULL) { + reply_with_perror ("malloc"); + return NULL; + } + + /* As with stat, -1 indicates a field is not known. */ + ret->bsize = fsu.f_bsize; + ret->frsize = -1; + ret->blocks = fsu.f_blocks; + ret->bfree = fsu.f_bfree; + ret->bavail = fsu.f_bavail; + ret->files = fsu.f_files; + ret->ffree = fsu.f_ffree; + ret->favail = -1; + ret->fsid = -1; + ret->flag = -1; + ret->namemax = -1; + + return ret; + +# endif /* !WIN32 */ +#endif /* !HAVE_STATVFS */ }