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