summaryrefslogtreecommitdiff
path: root/win32/statfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/statfs.c')
-rw-r--r--win32/statfs.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/win32/statfs.c b/win32/statfs.c
new file mode 100644
index 000000000..9e6703849
--- /dev/null
+++ b/win32/statfs.c
@@ -0,0 +1,80 @@
1#include <sys/vfs.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 drive[4], fsname[100];
14
15 if ( !GetDiskFreeSpaceEx(file, (PULARGE_INTEGER) &free_bytes_available,
16 (PULARGE_INTEGER) &total_number_of_bytes,
17 (PULARGE_INTEGER) &total_number_of_free_bytes) ) {
18 return -1;
19 }
20
21 if ( strlen(file) == 2 && file[1] == ':' ) {
22 /* GetVolumeInformation wants a backslash */
23 strcat(strcpy(drive, file), "\\");
24 file = drive;
25 }
26
27 if ( !GetVolumeInformation(file, NULL, 0, &serial, &namelen, &flags,
28 fsname, 100) ) {
29 return -1;
30 }
31
32 /* XXX I couldn't determine how to get block size. MSDN has a
33 * unhelpful hard-coded list here:
34 * http://support.microsoft.com/kb/140365
35 * but this depends on the filesystem type, the size of the disk and
36 * the version of Windows. So this code assumes the disk is NTFS
37 * and the version of Windows is >= Win2K.
38 */
39 if (total_number_of_bytes < UINT64_C(16) * 1024 * 1024 * 1024 * 1024)
40 buf->f_bsize = 4096;
41 else if (total_number_of_bytes < UINT64_C(32) * 1024 * 1024 * 1024 * 1024)
42 buf->f_bsize = 8192;
43 else if (total_number_of_bytes < UINT64_C(64) * 1024 * 1024 * 1024 * 1024)
44 buf->f_bsize = 16384;
45 else if (total_number_of_bytes < UINT64_C(128) * 1024 * 1024 * 1024 * 1024)
46 buf->f_bsize = 32768;
47 else
48 buf->f_bsize = 65536;
49
50 /*
51 * Valid filesystem names don't seem to be documented. The following
52 * are present in Wine.
53 */
54 if ( strcmp(fsname, "NTFS") == 0 ) {
55 buf->f_type = 0x5346544e;
56 }
57 else if ( strcmp(fsname, "FAT") == 0 || strcmp(fsname, "FAT32") == 0 ) {
58 buf->f_type = 0x4006;
59 }
60 else if ( strcmp(fsname, "CDFS") == 0 ) {
61 buf->f_type = 0x9660;
62 }
63 else {
64 buf->f_type = 0;
65 }
66
67 /* As with stat, -1 indicates a field is not known. */
68 buf->f_frsize = buf->f_bsize;
69 buf->f_blocks = total_number_of_bytes / buf->f_bsize;
70 buf->f_bfree = total_number_of_free_bytes / buf->f_bsize;
71 buf->f_bavail = free_bytes_available / buf->f_bsize;
72 buf->f_files = -1;
73 buf->f_ffree = -1;
74 buf->f_favail = -1;
75 buf->f_fsid = serial;
76 buf->f_flag = -1;
77 buf->f_namelen = namelen;
78
79 return 0;
80}