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