aboutsummaryrefslogtreecommitdiff
path: root/win32/statfs.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--win32/statfs.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/win32/statfs.c b/win32/statfs.c
new file mode 100644
index 000000000..97b3ce679
--- /dev/null
+++ b/win32/statfs.c
@@ -0,0 +1,70 @@
1#include <sys/statfs.h>
2#include "libbb.h"
3
4/*
5 * Code from libguestfs (with addition of GetVolumeInformation call)
6 */
7int statfs(const char *file, struct statfs *buf)
8{
9 ULONGLONG free_bytes_available; /* for user - similar to bavail */
10 ULONGLONG total_number_of_bytes;
11 ULONGLONG total_number_of_free_bytes; /* for everyone - bfree */
12 DWORD serial, namelen, flags;
13 char fsname[100];
14 struct mntent *mnt;
15 /* Valid filesystem names don't seem to be documented. The following
16 * are present in Wine (dlls/kernel32/volume.c). */
17#define FS_NAMES "NTFS\0FAT\0FAT32\0CDFS\0UDF\0"
18 int fstypes[] = {0, 0x5346544e, 0x4006, 0x4006, 0x9660, 0x15013346};
19
20 if ( (mnt=find_mount_point(file, 0)) == NULL ) {
21 return -1;
22 }
23
24 file = mnt->mnt_dir;
25 if ( !GetDiskFreeSpaceEx(file, (PULARGE_INTEGER) &free_bytes_available,
26 (PULARGE_INTEGER) &total_number_of_bytes,
27 (PULARGE_INTEGER) &total_number_of_free_bytes) ) {
28 errno = err_win_to_posix();
29 return -1;
30 }
31
32 if ( !GetVolumeInformation(file, NULL, 0, &serial, &namelen, &flags,
33 fsname, 100) ) {
34 errno = err_win_to_posix();
35 return -1;
36 }
37
38 memset(buf, 0, sizeof(*buf));
39
40 /* XXX I couldn't determine how to get block size. MSDN has a
41 * unhelpful hard-coded list here:
42 * http://support.microsoft.com/kb/140365
43 * but this depends on the filesystem type, the size of the disk and
44 * the version of Windows. So this code assumes the disk is NTFS
45 * and the version of Windows is >= Win2K.
46 */
47 if (total_number_of_bytes < UINT64_C(16) * 1024 * 1024 * 1024 * 1024)
48 buf->f_bsize = 4096;
49 else if (total_number_of_bytes < UINT64_C(32) * 1024 * 1024 * 1024 * 1024)
50 buf->f_bsize = 8192;
51 else if (total_number_of_bytes < UINT64_C(64) * 1024 * 1024 * 1024 * 1024)
52 buf->f_bsize = 16384;
53 else if (total_number_of_bytes < UINT64_C(128) * 1024 * 1024 * 1024 * 1024)
54 buf->f_bsize = 32768;
55 else
56 buf->f_bsize = 65536;
57
58 buf->f_type = fstypes[index_in_strings(FS_NAMES, fsname)+1];
59 buf->f_frsize = buf->f_bsize;
60 buf->f_blocks = total_number_of_bytes / buf->f_bsize;
61 buf->f_bfree = total_number_of_free_bytes / buf->f_bsize;
62 buf->f_bavail = free_bytes_available / buf->f_bsize;
63 //buf->f_files = 0;
64 //buf->f_ffree = 0;
65 buf->f_fsid = serial;
66 //buf->f_flag = 0;
67 buf->f_namelen = namelen;
68
69 return 0;
70}