diff options
Diffstat (limited to 'coreutils/df.c')
-rw-r--r-- | coreutils/df.c | 185 |
1 files changed, 105 insertions, 80 deletions
diff --git a/coreutils/df.c b/coreutils/df.c index 0e9e5d61a..7d007a003 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -22,74 +22,45 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* BB_AUDIT SUSv3 _NOT_ compliant -- options -P and -t missing. Also blocksize. */ | ||
26 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */ | ||
27 | |||
28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
29 | * | ||
30 | * Size reduction. Removed floating point dependency. Added error checking | ||
31 | * on output. Output stats on 0-sized filesystems if specificly listed on | ||
32 | * the command line. Properly round *-blocks, Used, and Available quantities. | ||
33 | */ | ||
34 | |||
25 | #include <stdio.h> | 35 | #include <stdio.h> |
26 | #include <stdlib.h> | 36 | #include <stdlib.h> |
27 | #include <string.h> | 37 | #include <string.h> |
38 | #include <unistd.h> | ||
28 | #include <mntent.h> | 39 | #include <mntent.h> |
29 | #include <sys/vfs.h> | 40 | #include <sys/vfs.h> |
30 | #include <getopt.h> | ||
31 | #include "busybox.h" | 41 | #include "busybox.h" |
32 | 42 | ||
33 | extern const char mtab_file[]; /* Defined in utility.c */ | 43 | #ifndef CONFIG_FEATURE_HUMAN_READABLE |
34 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 44 | static long kscale(long b, long bs) |
35 | static unsigned long df_disp_hr = KILOBYTE; | 45 | { |
46 | return ( b * (long long) bs + KILOBYTE/2 ) / KILOBYTE; | ||
47 | } | ||
36 | #endif | 48 | #endif |
37 | 49 | ||
38 | static int do_df(char *device, const char *mount_point) | 50 | extern int df_main(int argc, char **argv) |
39 | { | 51 | { |
40 | struct statfs s; | ||
41 | long blocks_used; | 52 | long blocks_used; |
42 | long blocks_percent_used; | 53 | long blocks_percent_used; |
43 | |||
44 | if (statfs(mount_point, &s) != 0) { | ||
45 | perror_msg("%s", mount_point); | ||
46 | return FALSE; | ||
47 | } | ||
48 | |||
49 | if (s.f_blocks > 0) { | ||
50 | blocks_used = s.f_blocks - s.f_bfree; | ||
51 | if(blocks_used == 0) | ||
52 | blocks_percent_used = 0; | ||
53 | else { | ||
54 | blocks_percent_used = (long) | ||
55 | (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | ||
56 | } | ||
57 | if (strcmp(device, "/dev/root") == 0) { | ||
58 | /* Adjusts device to be the real root device, | ||
59 | * or leaves device alone if it can't find it */ | ||
60 | device = find_real_root_device_name(device); | ||
61 | if(device==NULL) | ||
62 | return FALSE; | ||
63 | } | ||
64 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 54 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
65 | printf("%-20s %9s ", device, | 55 | unsigned long df_disp_hr = KILOBYTE; |
66 | make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); | ||
67 | |||
68 | printf("%9s ", | ||
69 | make_human_readable_str( (s.f_blocks - s.f_bfree), s.f_bsize, df_disp_hr)); | ||
70 | |||
71 | printf("%9s %3ld%% %s\n", | ||
72 | make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), | ||
73 | blocks_percent_used, mount_point); | ||
74 | #else | ||
75 | printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", | ||
76 | device, | ||
77 | (long) (s.f_blocks * (s.f_bsize / (double)KILOBYTE)), | ||
78 | (long) ((s.f_blocks - s.f_bfree)*(s.f_bsize/(double)KILOBYTE)), | ||
79 | (long) (s.f_bavail * (s.f_bsize / (double)KILOBYTE)), | ||
80 | blocks_percent_used, mount_point); | ||
81 | #endif | 56 | #endif |
82 | } | ||
83 | |||
84 | return TRUE; | ||
85 | } | ||
86 | |||
87 | extern int df_main(int argc, char **argv) | ||
88 | { | ||
89 | int status = EXIT_SUCCESS; | 57 | int status = EXIT_SUCCESS; |
90 | int opt = 0; | 58 | int opt; |
91 | int i = 0; | 59 | FILE *mount_table; |
92 | char disp_units_hdr[80] = "1k-blocks"; /* default display is kilobytes */ | 60 | struct mntent *mount_entry; |
61 | struct statfs s; | ||
62 | static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */; | ||
63 | const char *disp_units_hdr = hdr_1k; | ||
93 | 64 | ||
94 | while ((opt = getopt(argc, argv, "k" | 65 | while ((opt = getopt(argc, argv, "k" |
95 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 66 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
@@ -101,52 +72,106 @@ extern int df_main(int argc, char **argv) | |||
101 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 72 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
102 | case 'h': | 73 | case 'h': |
103 | df_disp_hr = 0; | 74 | df_disp_hr = 0; |
104 | strcpy(disp_units_hdr, " Size"); | 75 | disp_units_hdr = " Size"; |
105 | break; | 76 | break; |
106 | case 'm': | 77 | case 'm': |
107 | df_disp_hr = MEGABYTE; | 78 | df_disp_hr = MEGABYTE; |
108 | strcpy(disp_units_hdr, "1M-blocks"); | 79 | disp_units_hdr = "1M-blocks"; |
109 | break; | 80 | break; |
110 | #endif | 81 | #endif |
111 | case 'k': | 82 | case 'k': |
112 | /* default display is kilobytes */ | 83 | /* default display is kilobytes */ |
84 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
85 | df_disp_hr = KILOBYTE; | ||
86 | disp_units_hdr = hdr_1k; | ||
87 | #endif | ||
113 | break; | 88 | break; |
114 | default: | 89 | default: |
115 | show_usage(); | 90 | bb_show_usage(); |
116 | } | 91 | } |
117 | } | 92 | } |
118 | 93 | ||
119 | printf("%-20s %-14s %s %s %s %s\n", "Filesystem", disp_units_hdr, | 94 | bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", |
120 | "Used", "Available", "Use%", "Mounted on"); | 95 | "", disp_units_hdr); |
121 | 96 | ||
122 | if(optind < argc) { | 97 | mount_table = NULL; |
123 | struct mntent *mount_entry; | 98 | argv += optind; |
124 | for(i = optind; i < argc; i++) | 99 | if (optind >= argc) { |
125 | { | 100 | if (!(mount_table = setmntent(bb_path_mtab_file, "r"))) { |
126 | if ((mount_entry = find_mount_point(argv[i], mtab_file)) == 0) { | 101 | bb_perror_msg_and_die(bb_path_mtab_file); |
127 | error_msg("%s: can't find mount point.", argv[i]); | ||
128 | status = EXIT_FAILURE; | ||
129 | } else if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir)) | ||
130 | status = EXIT_FAILURE; | ||
131 | } | 102 | } |
132 | } else { | 103 | } |
133 | FILE *mount_table; | ||
134 | struct mntent *mount_entry; | ||
135 | 104 | ||
136 | mount_table = setmntent(mtab_file, "r"); | 105 | do { |
137 | if (mount_table == 0) { | 106 | const char *device; |
138 | perror_msg("%s", mtab_file); | 107 | const char *mount_point; |
139 | return EXIT_FAILURE; | ||
140 | } | ||
141 | 108 | ||
142 | while ((mount_entry = getmntent(mount_table))) { | 109 | if (mount_table) { |
143 | if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir)) | 110 | if (!(mount_entry = getmntent(mount_table))) { |
111 | endmntent(mount_table); | ||
112 | break; | ||
113 | } | ||
114 | } else { | ||
115 | if (!(mount_point = *argv++)) { | ||
116 | break; | ||
117 | } | ||
118 | if (!(mount_entry = find_mount_point(mount_point, bb_path_mtab_file))) { | ||
119 | bb_error_msg("%s: can't find mount point.", mount_point); | ||
120 | SET_ERROR: | ||
144 | status = EXIT_FAILURE; | 121 | status = EXIT_FAILURE; |
122 | continue; | ||
123 | } | ||
145 | } | 124 | } |
146 | endmntent(mount_table); | ||
147 | } | ||
148 | 125 | ||
149 | return status; | 126 | device = mount_entry->mnt_fsname; |
127 | mount_point = mount_entry->mnt_dir; | ||
128 | |||
129 | if (statfs(mount_point, &s) != 0) { | ||
130 | bb_perror_msg("%s", mount_point); | ||
131 | goto SET_ERROR; | ||
132 | } | ||
133 | |||
134 | if ((s.f_blocks > 0) || !mount_table){ | ||
135 | blocks_used = s.f_blocks - s.f_bfree; | ||
136 | blocks_percent_used = 0; | ||
137 | if (blocks_used + s.f_bavail) { | ||
138 | blocks_percent_used = (((long long) blocks_used) * 100 | ||
139 | + (blocks_used + s.f_bavail)/2 | ||
140 | ) / (blocks_used + s.f_bavail); | ||
141 | } | ||
142 | |||
143 | if (strcmp(device, "/dev/root") == 0) { | ||
144 | /* Adjusts device to be the real root device, | ||
145 | * or leaves device alone if it can't find it */ | ||
146 | if ((device = find_real_root_device_name(device)) != NULL) { | ||
147 | goto SET_ERROR; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
152 | bb_printf("%-21s%9s ", device, | ||
153 | make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); | ||
154 | |||
155 | bb_printf("%9s ", | ||
156 | make_human_readable_str( (s.f_blocks - s.f_bfree), | ||
157 | s.f_bsize, df_disp_hr)); | ||
158 | |||
159 | bb_printf("%9s %3ld%% %s\n", | ||
160 | make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), | ||
161 | blocks_percent_used, mount_point); | ||
162 | #else | ||
163 | bb_printf("%-21s%9ld %9ld %9ld %3ld%% %s\n", | ||
164 | device, | ||
165 | kscale(s.f_blocks, s.f_bsize), | ||
166 | kscale(s.f_blocks-s.f_bfree, s.f_bsize), | ||
167 | kscale(s.f_bavail, s.f_bsize), | ||
168 | blocks_percent_used, mount_point); | ||
169 | #endif | ||
170 | } | ||
171 | |||
172 | } while (1); | ||
173 | |||
174 | bb_fflush_stdout_and_exit(status); | ||
150 | } | 175 | } |
151 | 176 | ||
152 | /* | 177 | /* |