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