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