Stuf
[platform/upstream/busybox.git] / coreutils / df.c
1 /*
2  * Mini df implementation for busybox
3  *
4  * Copyright (C) 1999 by Lineo, inc.
5  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
6  * based on original code by (I think) Bruce Perens <bruce@pixar.com>.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 #include "internal.h"
25 #include <stdio.h>
26 #include <mntent.h>
27 #include <sys/stat.h>
28 #include <sys/vfs.h>
29 #include <fstab.h>
30
31 static const char df_usage[] = "df [filesystem ...]\n"
32     "\n" "\tPrint the filesystem space used and space available.\n";
33
34 extern const char mtab_file[]; /* Defined in utility.c */
35
36 static int df(char *device, const char *mountPoint)
37 {
38     struct statfs s;
39     long blocks_used;
40     long blocks_percent_used;
41     struct fstab* fstabItem;
42
43     if (statfs(mountPoint, &s) != 0) {
44         perror(mountPoint);
45         return FALSE;
46     }
47
48     if (s.f_blocks > 0) {
49         blocks_used = s.f_blocks - s.f_bfree;
50         blocks_percent_used = (long)
51             (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
52         /* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */
53         if (strcmp (device, "/dev/root") == 0) {
54             fstabItem = getfsfile ("/");
55             if (fstabItem != NULL)
56                 device = fstabItem->fs_spec;
57         }
58         printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
59                device,
60                (long) (s.f_blocks * (s.f_bsize / 1024.0)),
61                (long) ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)),
62                (long) (s.f_bavail * (s.f_bsize / 1024.0)),
63                blocks_percent_used, mountPoint);
64
65     }
66
67     return TRUE;
68 }
69
70 extern int df_main(int argc, char **argv)
71 {
72     printf("%-20s %-14s %s %s %s %s\n", "Filesystem",
73            "1k-blocks", "Used", "Available", "Use%", "Mounted on");
74
75     /* Only compiled in if BB_MTAB is not defined */
76     whine_if_fstab_is_missing();
77
78     if (argc > 1) {
79         struct mntent *mountEntry;
80         int status;
81
82         while (argc > 1) {
83             if ((mountEntry = findMountPoint(argv[1], mtab_file)) ==
84                 0) {
85                 fprintf(stderr, "%s: can't find mount point.\n", argv[1]);
86                 exit( FALSE);
87             }
88             status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
89             if (status != 0)
90                 exit( status);
91             argc--;
92             argv++;
93         }
94         exit( TRUE);
95     } else {
96         FILE *mountTable;
97         struct mntent *mountEntry;
98
99         mountTable = setmntent(mtab_file, "r");
100         if (mountTable == 0) {
101             perror(mtab_file);
102             exit(FALSE);
103         }
104
105         while ((mountEntry = getmntent(mountTable))) {
106             df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
107         }
108         endmntent(mountTable);
109     }
110
111     exit( TRUE);
112 }