more stuff
[oweals/busybox.git] / coreutils / df.c
1 #include "internal.h"
2 #include <stdio.h>
3 #include <mntent.h>
4 #include <sys/stat.h>
5 #include <sys/vfs.h>
6 #include <fstab.h>
7
8 const char      df_usage[] = "df [filesystem ...]\n"
9 "\n"
10 "\tPrint the filesystem space used and space available.\n";
11
12
13 static int
14 df(char* device, const char * mountPoint)
15 {
16         struct statfs   s;
17         long            blocks_used;
18         long            blocks_percent_used;
19
20         if ( statfs(mountPoint, &s) != 0 ) {
21                 perror(mountPoint);
22                 return 1;
23         }
24         
25         if ( s.f_blocks > 0 ) {
26                 blocks_used = s.f_blocks - s.f_bfree;
27                 blocks_percent_used = (long)
28                  (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
29                 if ( strcmp(device, "/dev/root")==0)
30                     device=(getfsfile ("/"))->fs_spec;
31
32                 printf(
33                        "%-20s %9ld %9ld %9ld %3ld%% %s\n",
34                        device,
35                        (long)(s.f_blocks * (s.f_bsize / 1024.0)),
36                        (long)((s.f_blocks - s.f_bfree)  * (s.f_bsize / 1024.0)),
37                        (long)(s.f_bavail * (s.f_bsize / 1024.0)),
38                        blocks_percent_used,
39                        mountPoint);
40
41         }
42
43         return 0;
44 }
45
46 extern int
47 df_main(int argc, char * * argv)
48 {
49         printf("%-20s %-14s %s %s %s %s\n", "Filesystem",
50                 "1k-blocks", "Used", "Available", "Use%", "Mounted on");
51
52         if ( argc > 1 ) {
53                 struct mntent*  mountEntry;
54                 int             status;
55
56                 while ( argc > 1 ) {
57                         if ( (mountEntry = findMountPoint(argv[1], "/proc/mounts")) == 0 )
58                         {
59                                 fprintf(stderr, "%s: can't find mount point.\n" ,argv[1]);
60                                 return 1;
61                         }
62                         status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
63                         if ( status != 0 )
64                                 return status;
65                         argc--;
66                         argv++;
67                 }
68                 return 0;
69         }
70         else {
71                 FILE *          mountTable;
72                 struct mntent * mountEntry;
73
74                 mountTable = setmntent("/proc/mounts", "r");
75                 if ( mountTable == 0) {
76                         perror("/proc/mounts");
77                         exit( FALSE);
78                 }
79
80                 while ( (mountEntry = getmntent (mountTable))) {
81                         int status=df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
82                         if (status)
83                                 return status;
84                 }
85                 endmntent(mountTable);
86         }
87         
88         return 0;
89 }
90
91
92
93
94 /*
95  * Given a block device, find the mount table entry if that block device
96  * is mounted.
97  *
98  * Given any other file (or directory), find the mount table entry for its
99  * filesystem.
100  */
101 extern struct mntent *
102 findMountPoint(const char* name, const char* table)
103 {
104         struct stat     s;
105         dev_t                   mountDevice;
106         FILE *                  mountTable;
107         struct mntent * mountEntry;
108
109         if ( stat(name, &s) != 0 )
110                 return 0;
111
112         if ( (s.st_mode & S_IFMT) == S_IFBLK )
113                 mountDevice = s.st_rdev;
114         else
115                 mountDevice = s.st_dev;
116
117         
118         if ( (mountTable = setmntent(table, "r")) == 0 )
119                 return 0;
120
121         while ( (mountEntry = getmntent(mountTable)) != 0 ) {
122                 if ( strcmp(name, mountEntry->mnt_dir) == 0
123                  || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */
124                         break;
125                 if ( stat(mountEntry->mnt_fsname, &s) == 0
126                  && s.st_rdev == mountDevice )  /* Match the device. */
127                                 break;
128                 if ( stat(mountEntry->mnt_dir, &s) == 0
129                  && s.st_dev == mountDevice )   /* Match the directory's mount point. */
130                         break;
131         }
132         endmntent(mountTable);
133         return mountEntry;
134 }
135
136