]>
git.saurik.com Git - apple/file_cmds.git/blob - df/df.c
0a1caddb5e540133a7af4bb0b226c9cad6d71dd2
1 /* $NetBSD: df.c,v 1.30 1998/07/28 05:31:24 mycroft Exp $ */
4 * Copyright (c) 1980, 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #include <sys/cdefs.h>
44 "@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
45 The Regents of the University of California. All rights reserved.\n");
50 static char sccsid
[] = "@(#)df.c 8.7 (Berkeley) 4/2/94";
52 __RCSID("$NetBSD: df.c,v 1.30 1998/07/28 05:31:24 mycroft Exp $");
56 #include <sys/param.h>
58 #include <sys/mount.h>
60 #include <ufs/ufs/ufsmount.h>
63 #define MOUNT_FFS "ffs"
74 extern char * strpct
__P((u_long num
, u_long denom
, u_int digits
));
76 int main
__P((int, char *[]));
77 int bread
__P((off_t
, void *, int));
78 char *getmntpt
__P((char *));
79 void prtstat
__P((struct statfs
*, int));
80 int ufs_df
__P((char *, struct statfs
*));
81 int selected
__P((const char *));
82 void maketypelist
__P((char *));
83 long regetmntinfo
__P((struct statfs
**, long));
84 void usage
__P((void));
86 int iflag
, kflag
, lflag
, nflag
;
87 char **typelist
= NULL
;
96 struct statfs
*mntbuf
;
98 int ch
, i
, maxwidth
, width
;
101 while ((ch
= getopt(argc
, argv
, "iklnt:")) != -1)
116 if (typelist
!= NULL
)
117 errx(1, "only one -t option may be specified.");
118 maketypelist(optarg
);
127 mntsize
= getmntinfo(&mntbuf
, MNT_NOWAIT
);
129 err(1, "retrieving information on mounted file systems");
132 mntsize
= regetmntinfo(&mntbuf
, mntsize
);
134 mntbuf
= malloc(argc
* sizeof(struct statfs
));
136 for (; *argv
; argv
++) {
137 if (stat(*argv
, &stbuf
) < 0) {
138 if ((mntpt
= getmntpt(*argv
)) == 0) {
142 } else if (S_ISCHR(stbuf
.st_mode
)) {
143 if (!ufs_df(*argv
, &mntbuf
[mntsize
]))
146 } else if (S_ISBLK(stbuf
.st_mode
)) {
147 if ((mntpt
= getmntpt(*argv
)) == 0) {
148 #ifdef __APPLE__ /* We lack mkdtemp() */
149 mntpt
= mktemp(strdup("/tmp/df.XXXXXX"));
151 if (mkdir(mntpt
, DEFFILEMODE
) != 0) {
153 mntpt
= strdup("/tmp/df.XXXXXX");
154 if (!mkdtemp(mntpt
)) {
160 if (mount(MOUNT_FFS
, mntpt
, MNT_RDONLY
,
167 } else if (!statfs(mntpt
,
169 mntbuf
[mntsize
].f_mntonname
[0] =
174 (void)unmount(mntpt
, 0);
181 * Statfs does not take a `wait' flag, so we cannot
182 * implement nflag here.
184 if (!statfs(mntpt
, &mntbuf
[mntsize
]))
186 (mntbuf
[mntsize
].f_flags
& MNT_LOCAL
) == 0)
187 warnx("Warning: %s is not a local %s",
188 *argv
, "file system");
190 (!selected(mntbuf
[mntsize
].f_fstypename
))
191 warnx("Warning: %s mounted as a %s %s",
193 mntbuf
[mntsize
].f_fstypename
,
203 for (i
= 0; i
< mntsize
; i
++) {
204 width
= strlen(mntbuf
[i
].f_mntfromname
);
205 if (width
> maxwidth
)
208 for (i
= 0; i
< mntsize
; i
++)
209 prtstat(&mntbuf
[i
], maxwidth
);
219 struct statfs
*mntbuf
;
221 mntsize
= getmntinfo(&mntbuf
, MNT_NOWAIT
);
222 for (i
= 0; i
< mntsize
; i
++) {
223 if (!strcmp(mntbuf
[i
].f_mntfromname
, name
))
224 return (mntbuf
[i
].f_mntonname
);
229 static enum { IN_LIST
, NOT_IN_LIST
} which
;
237 /* If no type specified, it's always selected. */
238 if (typelist
== NULL
)
240 for (av
= typelist
; *av
!= NULL
; ++av
)
241 if (!strncmp(type
, *av
, MFSNAMELEN
))
242 return (which
== IN_LIST
? 1 : 0);
243 return (which
== IN_LIST
? 0 : 1);
253 if ((fslist
== NULL
) || (fslist
[0] == '\0'))
254 errx(1, "empty type list");
258 * Note: the syntax is "noxxx,yyy" for no xxx's and
259 * no yyy's, not the more intuitive "noyyy,noyyy".
261 if (fslist
[0] == 'n' && fslist
[1] == 'o') {
267 /* Count the number of types. */
268 for (i
= 1, nextcp
= fslist
;
269 (nextcp
= strchr(nextcp
, ',')) != NULL
; i
++)
272 /* Build an array of that many types. */
273 if ((av
= typelist
= malloc((i
+ 1) * sizeof(char *))) == NULL
)
274 err(1, "can't allocate type array");
276 for (i
= 1, nextcp
= fslist
;
277 (nextcp
= strchr(nextcp
, ',')) != NULL
; i
++) {
281 /* Terminate the array. */
286 * Make a pass over the filesystem info in ``mntbuf'' filtering out
287 * filesystem types not in ``fsmask'' and possibly re-stating to get
288 * current (not cached) info. Returns the new count of valid statfs bufs.
291 regetmntinfo(mntbufp
, mntsize
)
292 struct statfs
**mntbufp
;
296 struct statfs
*mntbuf
;
298 if (!lflag
&& typelist
== NULL
)
299 return (nflag
? mntsize
: getmntinfo(mntbufp
, MNT_WAIT
));
303 for (i
= 0; i
< mntsize
; i
++) {
304 if (lflag
&& (mntbuf
[i
].f_flags
& MNT_LOCAL
) == 0)
306 if (!selected(mntbuf
[i
].f_fstypename
))
309 mntbuf
[j
] = mntbuf
[i
];
311 (void)statfs(mntbuf
[i
].f_mntonname
, &mntbuf
[j
]);
318 * Convert statfs returned filesystem size into BLOCKSIZE units.
319 * Attempts to avoid overflow for large filesystems.
321 #define fsbtoblk(num, fsbs, bs) \
322 ((long int) ((((float) fsbs) != 0 && ((float) fsbs) < ((float) bs)) ? \
323 ((float) num) / (((float) bs) / ((float) fsbs)) : ((float) num) * (((float) fsbs) / ((float) bs))))
326 * Print out status about a filesystem.
329 prtstat(sfsp
, maxwidth
)
333 static long blocksize
;
334 static int headerlen
, timesthrough
;
336 long used
, availblks
, inodes
;
337 static char *full
= "100%";
341 if (++timesthrough
== 1) {
344 header
= "1K-blocks";
345 headerlen
= strlen(header
);
347 header
= getbsize(&headerlen
, &blocksize
);
348 (void)printf("%-*.*s %s Used Avail Capacity",
349 maxwidth
, maxwidth
, "Filesystem", header
);
351 (void)printf(" iused ifree %%iused");
352 (void)printf(" Mounted on\n");
354 (void)printf("%-*.*s", maxwidth
, maxwidth
, sfsp
->f_mntfromname
);
355 used
= sfsp
->f_blocks
- sfsp
->f_bfree
;
356 availblks
= sfsp
->f_bavail
+ used
;
357 (void)printf(" %*ld %8ld %8ld", headerlen
,
358 fsbtoblk(sfsp
->f_blocks
, sfsp
->f_bsize
, blocksize
),
359 fsbtoblk(used
, sfsp
->f_bsize
, blocksize
),
360 fsbtoblk(sfsp
->f_bavail
, sfsp
->f_bsize
, blocksize
));
362 availblks
== 0 ? full
: strpct((u_long
)used
, (u_long
)availblks
, 0));
364 inodes
= sfsp
->f_files
;
365 used
= inodes
- sfsp
->f_ffree
;
366 (void)printf(" %7ld %7ld %6s ", used
, sfsp
->f_ffree
,
367 inodes
== 0 ? full
: strpct((u_long
)used
, (u_long
)inodes
, 0));
370 (void)printf(" %s\n", sfsp
->f_mntonname
);
374 * This code constitutes the pre-system call Berkeley df code for extracting
375 * information from filesystem superblocks.
377 #include <ufs/ufs/dinode.h>
378 #include <ufs/ffs/fs.h>
386 #define sblock sb.iu_fs
401 if ((rfd
= open(file
, O_RDONLY
)) < 0) {
405 if (bread((off_t
)SBOFF
, &sblock
, SBSIZE
) == 0) {
411 sfsp
->f_bsize
= sblock
.fs_fsize
;
412 sfsp
->f_iosize
= sblock
.fs_bsize
;
413 sfsp
->f_blocks
= sblock
.fs_dsize
;
414 sfsp
->f_bfree
= sblock
.fs_cstotal
.cs_nbfree
* sblock
.fs_frag
+
415 sblock
.fs_cstotal
.cs_nffree
;
416 sfsp
->f_bavail
= freespace(&sblock
, sblock
.fs_minfree
);
417 sfsp
->f_files
= sblock
.fs_ncg
* sblock
.fs_ipg
;
418 sfsp
->f_ffree
= sblock
.fs_cstotal
.cs_nifree
;
419 sfsp
->f_fsid
.val
[0] = 0;
420 sfsp
->f_fsid
.val
[1] = 0;
421 if ((mntpt
= getmntpt(file
)) == 0)
423 (void)memmove(&sfsp
->f_mntonname
[0], mntpt
, MNAMELEN
);
424 (void)memmove(&sfsp
->f_mntfromname
[0], file
, MNAMELEN
);
425 (void)strncpy(sfsp
->f_fstypename
, MOUNT_FFS
, MFSNAMELEN
);
438 (void)lseek(rfd
, off
, SEEK_SET
);
439 if ((nr
= read(rfd
, buf
, cnt
)) != cnt
) {
440 /* Probably a dismounted disk if errno == EIO. */
442 (void)fprintf(stderr
, "\ndf: %qd: %s\n",
443 (long long)off
, strerror(nr
> 0 ? EIO
: errno
));
452 (void)fprintf(stderr
, "usage: df [-ikln] [-t type] [file | file_system ...]\n");