pidfile.c: not used anymore
[oweals/busybox.git] / coreutils / df.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini df implementation for busybox
4  *
5  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6  * based on original code by (I think) Bruce Perens <bruce@pixar.com>.
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9  */
10
11 /* BB_AUDIT SUSv3 _NOT_ compliant -- options -P and -t missing.  Also blocksize. */
12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */
13
14 /* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
15  *
16  * Size reduction.  Removed floating point dependency.  Added error checking
17  * on output.  Output stats on 0-sized filesystems if specifically listed on
18  * the command line.  Properly round *-blocks, Used, and Available quantities.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <mntent.h>
26 #include <sys/vfs.h>
27 #include "busybox.h"
28
29 #ifndef CONFIG_FEATURE_HUMAN_READABLE
30 static long kscale(long b, long bs)
31 {
32         return ( b * (long long) bs + 1024/2 ) / 1024;
33 }
34 #endif
35
36 int df_main(int argc, char **argv);
37 int df_main(int argc, char **argv)
38 {
39         long blocks_used;
40         long blocks_percent_used;
41 #ifdef CONFIG_FEATURE_HUMAN_READABLE
42         unsigned long df_disp_hr = 1024;
43 #endif
44         int status = EXIT_SUCCESS;
45         unsigned opt;
46         FILE *mount_table;
47         struct mntent *mount_entry;
48         struct statfs s;
49         static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */
50         const char *disp_units_hdr = hdr_1k;
51
52 #ifdef CONFIG_FEATURE_HUMAN_READABLE
53         opt_complementary = "h-km:k-hm:m-hk";
54         opt = getopt32(argc, argv, "hmk");
55         if (opt & 1) {
56                 df_disp_hr = 0;
57                 disp_units_hdr = "     Size";
58         }
59         if (opt & 2) {
60                 df_disp_hr = 1024*1024;
61                 disp_units_hdr = "1M-blocks";
62         }
63 #else
64         opt = getopt32(argc, argv, "k");
65 #endif
66
67         printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n",
68                           "", disp_units_hdr);
69
70         mount_table = NULL;
71         argv += optind;
72         if (optind >= argc) {
73                 mount_table = setmntent(bb_path_mtab_file, "r");
74                 if (!mount_table) {
75                         bb_perror_msg_and_die(bb_path_mtab_file);
76                 }
77         }
78
79         do {
80                 const char *device;
81                 const char *mount_point;
82
83                 if (mount_table) {
84                         mount_entry = getmntent(mount_table);
85                         if (!mount_entry) {
86                                 endmntent(mount_table);
87                                 break;
88                         }
89                 } else {
90                         mount_point = *argv++;
91                         if (!mount_point) {
92                                 break;
93                         }
94                         mount_entry = find_mount_point(mount_point, bb_path_mtab_file);
95                         if (!mount_entry) {
96                                 bb_error_msg("%s: can't find mount point", mount_point);
97  SET_ERROR:
98                                 status = EXIT_FAILURE;
99                                 continue;
100                         }
101                 }
102
103                 device = mount_entry->mnt_fsname;
104                 mount_point = mount_entry->mnt_dir;
105
106                 if (statfs(mount_point, &s) != 0) {
107                         bb_perror_msg("%s", mount_point);
108                         goto SET_ERROR;
109                 }
110
111                 if ((s.f_blocks > 0) || !mount_table){
112                         blocks_used = s.f_blocks - s.f_bfree;
113                         blocks_percent_used = 0;
114                         if (blocks_used + s.f_bavail) {
115                                 blocks_percent_used = (((long long) blocks_used) * 100
116                                                 + (blocks_used + s.f_bavail)/2
117                                                 ) / (blocks_used + s.f_bavail);
118                         }
119
120                         if (strcmp(device, "rootfs") == 0) {
121                                 continue;
122                         } else if (strcmp(device, "/dev/root") == 0) {
123                                 /* Adjusts device to be the real root device,
124                                 * or leaves device alone if it can't find it */
125                                 device = find_block_device("/");
126                                 if (!device) {
127                                         goto SET_ERROR;
128                                 }
129                         }
130
131 #ifdef CONFIG_FEATURE_HUMAN_READABLE
132                         printf("%-20s %9s ", device,
133                                 make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr));
134
135                         printf("%9s ",
136                                 make_human_readable_str( (s.f_blocks - s.f_bfree),
137                                                 s.f_bsize, df_disp_hr));
138
139                         printf("%9s %3ld%% %s\n",
140                                           make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr),
141                                           blocks_percent_used, mount_point);
142 #else
143                         printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
144                                           device,
145                                           kscale(s.f_blocks, s.f_bsize),
146                                           kscale(s.f_blocks-s.f_bfree, s.f_bsize),
147                                           kscale(s.f_bavail, s.f_bsize),
148                                           blocks_percent_used, mount_point);
149 #endif
150                 }
151
152         } while (1);
153
154         fflush_stdout_and_exit(status);
155 }