blob: 94b6b823180b861da819f01e90082949d351d8c6 [file] [log] [blame]
Eric Andersenc4996011999-10-20 22:08:37 +00001/*
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
Eric Andersencc8ed391999-10-05 16:24:54 +000024#include "internal.h"
25#include <stdio.h>
26#include <mntent.h>
27#include <sys/stat.h>
28#include <sys/vfs.h>
Eric Andersen596e5461999-10-07 08:30:23 +000029#include <fstab.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000030
Eric Andersenc4996011999-10-20 22:08:37 +000031static const char df_usage[] = "df [filesystem ...]\n"
32 "\n" "\tPrint the filesystem space used and space available.\n";
Eric Andersencc8ed391999-10-05 16:24:54 +000033
Eric Andersend0246fb1999-11-04 21:18:07 +000034extern const char mtab_file[]; /* Defined in utility.c */
Eric Andersencc8ed391999-10-05 16:24:54 +000035
Eric Andersenc4996011999-10-20 22:08:37 +000036static int df(char *device, const char *mountPoint)
Eric Andersencc8ed391999-10-05 16:24:54 +000037{
Eric Andersenc4996011999-10-20 22:08:37 +000038 struct statfs s;
39 long blocks_used;
40 long blocks_percent_used;
Eric Andersencc8ed391999-10-05 16:24:54 +000041
Eric Andersenc4996011999-10-20 22:08:37 +000042 if (statfs(mountPoint, &s) != 0) {
43 perror(mountPoint);
44 return 1;
45 }
Eric Andersencc8ed391999-10-05 16:24:54 +000046
Eric Andersenc4996011999-10-20 22:08:37 +000047 if (s.f_blocks > 0) {
48 blocks_used = s.f_blocks - s.f_bfree;
49 blocks_percent_used = (long)
50 (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
51 if (strcmp(device, "/dev/root") == 0)
52 device = (getfsfile("/"))->fs_spec;
Eric Andersencc8ed391999-10-05 16:24:54 +000053
Eric Andersenc4996011999-10-20 22:08:37 +000054 printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
55 device,
56 (long) (s.f_blocks * (s.f_bsize / 1024.0)),
57 (long) ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)),
58 (long) (s.f_bavail * (s.f_bsize / 1024.0)),
59 blocks_percent_used, mountPoint);
Eric Andersencc8ed391999-10-05 16:24:54 +000060
Eric Andersenc4996011999-10-20 22:08:37 +000061 }
62
63 return 0;
Eric Andersencc8ed391999-10-05 16:24:54 +000064}
65
Eric Andersenc6cb79d1999-10-13 18:01:10 +000066/*
67 * Given a block device, find the mount table entry if that block device
68 * is mounted.
69 *
70 * Given any other file (or directory), find the mount table entry for its
71 * filesystem.
72 */
Eric Andersenc4996011999-10-20 22:08:37 +000073extern struct mntent *findMountPoint(const char *name, const char *table)
Eric Andersenc6cb79d1999-10-13 18:01:10 +000074{
Eric Andersenc4996011999-10-20 22:08:37 +000075 struct stat s;
76 dev_t mountDevice;
77 FILE *mountTable;
78 struct mntent *mountEntry;
Eric Andersenc6cb79d1999-10-13 18:01:10 +000079
Eric Andersenc4996011999-10-20 22:08:37 +000080 if (stat(name, &s) != 0)
81 return 0;
Eric Andersenc6cb79d1999-10-13 18:01:10 +000082
Eric Andersenc4996011999-10-20 22:08:37 +000083 if ((s.st_mode & S_IFMT) == S_IFBLK)
84 mountDevice = s.st_rdev;
85 else
86 mountDevice = s.st_dev;
Eric Andersenc6cb79d1999-10-13 18:01:10 +000087
Eric Andersenc6cb79d1999-10-13 18:01:10 +000088
Eric Andersenc4996011999-10-20 22:08:37 +000089 if ((mountTable = setmntent(table, "r")) == 0)
90 return 0;
91
92 while ((mountEntry = getmntent(mountTable)) != 0) {
93 if (strcmp(name, mountEntry->mnt_dir) == 0
94 || strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */
95 break;
96 if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */
97 break;
98 if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */
99 break;
100 }
101 endmntent(mountTable);
102 return mountEntry;
103}
104
105
106
107extern int df_main(int argc, char **argv)
108{
109 printf("%-20s %-14s %s %s %s %s\n", "Filesystem",
110 "1k-blocks", "Used", "Available", "Use%", "Mounted on");
111
112 if (argc > 1) {
113 struct mntent *mountEntry;
114 int status;
115
116 while (argc > 1) {
Eric Andersend0246fb1999-11-04 21:18:07 +0000117 if ((mountEntry = findMountPoint(argv[1], mtab_file)) ==
Eric Andersenc4996011999-10-20 22:08:37 +0000118 0) {
119 fprintf(stderr, "%s: can't find mount point.\n", argv[1]);
120 return 1;
121 }
122 status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
123 if (status != 0)
124 return status;
125 argc--;
126 argv++;
127 }
128 return 0;
129 } else {
130 FILE *mountTable;
131 struct mntent *mountEntry;
132
Eric Andersend0246fb1999-11-04 21:18:07 +0000133 mountTable = setmntent(mtab_file, "r");
Eric Andersenc4996011999-10-20 22:08:37 +0000134 if (mountTable == 0) {
Eric Andersend0246fb1999-11-04 21:18:07 +0000135 perror(mtab_file);
Eric Andersenc4996011999-10-20 22:08:37 +0000136 exit(FALSE);
137 }
138
139 while ((mountEntry = getmntent(mountTable))) {
140 int status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
141 if (status)
142 return status;
Eric Andersenc6cb79d1999-10-13 18:01:10 +0000143 }
144 endmntent(mountTable);
Eric Andersenc4996011999-10-20 22:08:37 +0000145 }
146
147 return 0;
Eric Andersenc6cb79d1999-10-13 18:01:10 +0000148}