add -k flag, change default output to 512 byte blocks
[unix-history] / usr / src / bin / df / df.c
CommitLineData
bcf1365c 1/*
704aadd2
KM
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
bcf1365c
DF
16 */
17
18#ifndef lint
19char copyright[] =
704aadd2 20"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
bcf1365c 21 All rights reserved.\n";
7e8aa4e0 22#endif /* not lint */
bcf1365c 23
97dd7000 24#ifndef lint
fc2797e7 25static char sccsid[] = "@(#)df.c 5.11 (Berkeley) %G%";
7e8aa4e0 26#endif /* not lint */
a98f5f82 27
8d335f7d
BJ
28/*
29 * df
30 */
fc2797e7 31#include <sys/param.h>
1e568652 32#include <sys/stat.h>
704aadd2 33#include <sys/mount.h>
fc2797e7
KB
34#include <sys/file.h>
35#include <stdio.h>
36#include <strings.h>
37#include <unistd.h>
704aadd2 38#include "pathnames.h"
c7b72342 39
1e568652 40char *getmntpt();
fc2797e7 41int iflag, kflag;
704aadd2
KM
42#ifdef COMPAT_43
43int oflag;
44#endif /* COMPAT_43 */
c7b72342
BJ
45
46main(argc, argv)
a98f5f82
BJ
47 int argc;
48 char **argv;
c7b72342 49{
dbdc06d4 50 extern int errno, optind;
cf537218 51 int err, ch, i;
fc2797e7
KB
52 long mntsize, getmntinfo();
53 char *mntpt, *mktemp();
1e568652 54 struct stat stbuf;
704aadd2 55 struct statfs statfsbuf, *mntbuf;
439847aa 56 struct ufs_args mdev;
c7b72342 57
fc2797e7 58 while ((ch = getopt(argc, argv, "iko")) != EOF)
dbdc06d4 59 switch(ch) {
8a7d0cad 60 case 'i':
fc2797e7
KB
61 iflag = 1;
62 break;
63 case 'k':
64 kflag = 1;
8a7d0cad 65 break;
704aadd2
KM
66#ifdef COMPAT_43
67 case 'o':
fc2797e7 68 oflag = 1;
704aadd2
KM
69 break;
70#endif /* COMPAT_43 */
dbdc06d4 71 case '?':
8a7d0cad 72 default:
fc2797e7
KB
73 fprintf(stderr,
74 "usage: df [-ik] [file | file_system ...]\n");
dbdc06d4 75 exit(1);
8a7d0cad 76 }
dbdc06d4
KB
77 argc -= optind;
78 argv += optind;
79
fc2797e7
KB
80 printf("Filesystem %s used avail capacity",
81 kflag ? " kbytes" : "512-blks");
704aadd2
KM
82 if (iflag)
83 printf(" iused ifree %%iused");
84 printf(" Mounted on\n");
85#ifdef COMPAT_43
86 if (oflag) {
87 olddf(argv);
88 exit(0);
89 }
90#endif /* COMPAT_43 */
91 if (!*argv) {
1e568652 92 mntsize = getmntinfo(&mntbuf);
704aadd2
KM
93 for (i = 0; i < mntsize; i++)
94 prtstat(&mntbuf[i]);
95 exit(0);
96 }
97 for (; *argv; argv++) {
1e568652 98 if (stat(*argv, &stbuf) < 0) {
cf537218
KM
99 err = errno;
100 if ((mntpt = getmntpt(*argv)) == 0) {
fc2797e7
KB
101 fprintf(stderr, "df: %s: %s\n", *argv,
102 strerror(err));
1e568652 103 continue;
cf537218 104 }
1e568652
KM
105 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
106 if ((mntpt = getmntpt(*argv)) == 0)
fc2797e7 107 mntpt = mktemp("/df.XXXXXX");
439847aa
KM
108 mdev.fspec = *argv;
109 if (!mkdir(mntpt) &&
110 !mount(MOUNT_UFS, mntpt, M_RDONLY, &mdev) &&
111 !statfs(mntpt, &statfsbuf)) {
112 statfsbuf.f_mntonname[0] = '\0';
113 prtstat(&statfsbuf);
fc2797e7
KB
114 } else
115 fprintf(stderr, "df: %s: %s\n",
116 *argv, strerror(errno));
117 (void)umount(mntpt, MNT_NOFORCE);
118 (void)rmdir(mntpt);
1e568652
KM
119 continue;
120 } else
121 mntpt = *argv;
122 if (statfs(mntpt, &statfsbuf) < 0) {
fc2797e7
KB
123 fprintf(stderr,
124 "df: %s: %s\n", mntpt, strerror(errno));
704aadd2
KM
125 continue;
126 }
127 prtstat(&statfsbuf);
128 }
129 exit(0);
130}
131
fc2797e7 132long
1e568652
KM
133getmntinfo(mntbufp)
134 struct statfs **mntbufp;
135{
136 int i;
137 static long mntsize;
138 static struct statfs *mntbuf = 0;
139 char *malloc();
140
141 if (mntbuf) {
142 *mntbufp = mntbuf;
143 return (mntsize);
144 }
145 if ((mntsize = getfsstat((struct statfs *)0, 0)) < 0) {
146 perror("df");
147 exit(1);
148 }
149 mntbuf = 0;
150 do {
151 if (mntbuf)
152 free((char *)mntbuf);
153 i = (mntsize + 1) * sizeof(struct statfs);
154 if ((mntbuf = (struct statfs *)malloc((unsigned)i)) == 0) {
155 fprintf(stderr,
fc2797e7 156 "df: no space for mount table buffer\n");
1e568652
KM
157 exit(1);
158 }
159 if ((mntsize = getfsstat(mntbuf, i)) < 0) {
160 perror("df");
161 exit(1);
162 }
163 } while (i == mntsize * sizeof(struct statfs));
164 *mntbufp = mntbuf;
165 return (mntsize);
166}
167
168char *
169getmntpt(name)
170 char *name;
171{
172 long mntsize, i;
173 struct statfs *mntbuf;
174
175 mntsize = getmntinfo(&mntbuf);
176 for (i = 0; i < mntsize; i++) {
177 if (!strcmp(mntbuf[i].f_mntfromname, name))
178 return (mntbuf[i].f_mntonname);
179 }
180 return (0);
181}
182
704aadd2
KM
183/*
184 * Print out status about a filesystem.
185 */
186prtstat(sfsp)
187 register struct statfs *sfsp;
188{
189 long used, availblks, inodes;
190
191 printf("%-12.12s", sfsp->f_mntfromname);
192 used = sfsp->f_blocks - sfsp->f_bfree;
193 availblks = sfsp->f_bavail + used;
fc2797e7
KB
194 printf("%8ld%8ld%8ld",
195 sfsp->f_blocks * sfsp->f_fsize / (kflag ? 1024 : 512),
196 used * sfsp->f_fsize / (kflag ? 1024 : 512),
197 sfsp->f_bavail * sfsp->f_fsize / (kflag ? 1024 : 512));
704aadd2
KM
198 printf("%6.0f%%",
199 availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
200 if (iflag) {
201 inodes = sfsp->f_files;
202 used = inodes - sfsp->f_ffree;
203 printf("%8ld%8ld%6.0f%% ", used, sfsp->f_ffree,
204 inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
205 } else
206 printf(" ");
207 printf(" %s\n", sfsp->f_mntonname);
208}
209
210#ifdef COMPAT_43
211/*
212 * This code constitutes the old df code for extracting
213 * information from filesystem superblocks.
214 */
704aadd2 215#include <ufs/fs.h>
704aadd2
KM
216#include <errno.h>
217#include <fstab.h>
704aadd2 218
fc2797e7 219char root[MAXPATHLEN];
704aadd2
KM
220
221union {
222 struct fs iu_fs;
223 char dummy[SBSIZE];
224} sb;
225#define sblock sb.iu_fs
226
227int fi;
228char *strcpy();
229
230olddf(argv)
231 char *argv[];
232{
233 struct fstab *fsp;
704aadd2 234
dda19894 235 sync();
dbdc06d4 236 if (!*argv) {
8d335f7d 237 if (setfsent() == 0)
3b72df1c 238 perror(_PATH_FSTAB), exit(1);
a98f5f82 239 while (fsp = getfsent()) {
1f65a82f 240 if (strcmp(fsp->fs_type, FSTAB_RW) &&
351ef297
SL
241 strcmp(fsp->fs_type, FSTAB_RO) &&
242 strcmp(fsp->fs_type, FSTAB_RQ))
f0861f40 243 continue;
c7b72342 244 if (root[0] == 0)
f4d092e2 245 (void) strcpy(root, fsp->fs_spec);
a98f5f82 246 dfree(fsp->fs_spec, 1);
c7b72342 247 }
6c5c8ac3 248 (void)endfsent();
c7b72342
BJ
249 exit(0);
250 }
dbdc06d4
KB
251 while (*argv)
252 dfree(*argv++, 0);
704aadd2 253 exit(0);
c7b72342
BJ
254}
255
a98f5f82
BJ
256dfree(file, infsent)
257 char *file;
258 int infsent;
c7b72342 259{
dbdc06d4 260 extern int errno;
a98f5f82 261 struct stat stbuf;
704aadd2
KM
262 struct statfs statfsbuf;
263 register struct statfs *sfsp;
a98f5f82 264 struct fstab *fsp;
fc2797e7 265 char *mntpt;
a98f5f82
BJ
266
267 if (stat(file, &stbuf) == 0 &&
268 (stbuf.st_mode&S_IFMT) != S_IFCHR &&
269 (stbuf.st_mode&S_IFMT) != S_IFBLK) {
270 if (infsent) {
fc2797e7 271 fprintf(stderr, "df: %s: screwy fstab entry\n", file);
8d335f7d
BJ
272 return;
273 }
6c5c8ac3 274 (void)setfsent();
a98f5f82
BJ
275 while (fsp = getfsent()) {
276 struct stat stb;
277
278 if (stat(fsp->fs_spec, &stb) == 0 &&
279 stb.st_rdev == stbuf.st_dev) {
280 file = fsp->fs_spec;
6c5c8ac3 281 (void)endfsent();
a98f5f82
BJ
282 goto found;
283 }
284 }
6c5c8ac3 285 (void)endfsent();
fc2797e7 286 fprintf(stderr, "df: %s: mounted on unknown device\n", file);
a98f5f82 287 return;
8d335f7d 288 }
a98f5f82 289found:
fc2797e7 290 if ((fi = open(file, O_RDONLY)) < 0) {
dbdc06d4 291 fprintf(stderr, "df: %s: %s\n", file, strerror(errno));
c7b72342
BJ
292 return;
293 }
6c5c8ac3 294 if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) {
f5064bf4
RC
295 (void) close(fi);
296 return;
297 }
704aadd2
KM
298 sfsp = &statfsbuf;
299 sfsp->f_type = MOUNT_UFS;
300 sfsp->f_flags = 0;
301 sfsp->f_fsize = sblock.fs_fsize;
302 sfsp->f_bsize = sblock.fs_bsize;
303 sfsp->f_blocks = sblock.fs_dsize;
304 sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
305 sblock.fs_cstotal.cs_nffree;
306 sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
307 (sblock.fs_dsize - sfsp->f_bfree);
308 if (sfsp->f_bavail < 0)
309 sfsp->f_bavail = 0;
310 sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg;
311 sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
312 sfsp->f_fsid.val[0] = 0;
313 sfsp->f_fsid.val[1] = 0;
1e568652
KM
314 if ((mntpt = getmntpt(file)) == 0)
315 mntpt = "";
316 bcopy((caddr_t)mntpt, (caddr_t)&sfsp->f_mntonname[0], MNAMELEN);
704aadd2
KM
317 bcopy((caddr_t)file, (caddr_t)&sfsp->f_mntfromname[0], MNAMELEN);
318 prtstat(sfsp);
f4d092e2 319 (void) close(fi);
c7b72342
BJ
320}
321
f4d092e2
KM
322long lseek();
323
6c5c8ac3
KM
324bread(off, buf, cnt)
325 long off;
a98f5f82 326 char *buf;
c7b72342
BJ
327{
328 int n;
329 extern errno;
330
fc2797e7 331 (void) lseek(fi, off, SEEK_SET);
a98f5f82 332 if ((n=read(fi, buf, cnt)) != cnt) {
f5064bf4
RC
333 /* probably a dismounted disk if errno == EIO */
334 if (errno != EIO) {
6c5c8ac3 335 printf("\nread error off = %ld\n", off);
f5064bf4
RC
336 printf("count = %d; errno = %d\n", n, errno);
337 }
338 return (0);
c7b72342 339 }
f5064bf4 340 return (1);
c7b72342 341}
704aadd2 342#endif /* COMPAT_43 */