Attempt to import Lite2's df.

This commit is contained in:
Bruce Evans 1997-02-17 11:29:55 +00:00
parent ec0b206f7c
commit faa69d1a80
3 changed files with 499 additions and 0 deletions

12
bin/df/Makefile Normal file
View File

@ -0,0 +1,12 @@
# @(#)Makefile 8.3 (Berkeley) 5/8/95
PROG= df
SRCS= df.c vfslist.c
BINGRP= operator
BINMODE=2555
MOUNT= ${.CURDIR}/../../sbin/mount
CFLAGS+= -I${MOUNT}
.PATH: ${MOUNT}
.include <bsd.prog.mk>

126
bin/df/df.1 Normal file
View File

@ -0,0 +1,126 @@
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)df.1 8.3 (Berkeley) 5/8/95
.\"
.Dd May 8, 1995
.Dt DF 1
.Os BSD 4
.Sh NAME
.Nm df
.Nd display free disk space
.Sh SYNOPSIS
.Nm df
.Op Fl in
.Op Fl t Ar type
.Op Ar file | Ar filesystem ...
.Sh DESCRIPTION
.Nm Df
displays statistics about the amount of free disk space on the specified
.Ar filesystem
or on the filesystem of which
.Ar file
is a part.
Values are displayed in 512-byte per block block counts.
If neither a file or a filesystem operand is specified,
statistics for all mounted filesystems are displayed
(subject to the
.Fl t
option below).
.Pp
The following options are available:
.Bl -tag -width Ds
.It Fl i
Include statistics on the number of free inodes.
.It Fl n
Print out the previously obtained statistics from the filesystems.
This option should be used if it is possible that one or more
filesystems are in a state such that they will not be able to provide
statistics without a long delay.
When this option is specified,
.Nm df
will not request new statistics from the filesystems, but will respond
with the possibly stale statistics that were previously obtained.
.It Fl t
Only print out statistics for filesystems of the specified types.
More than one type may be specified in a comma separated list.
The list of filesystem types can be prefixed with
.Dq no
to specify the filesystem types for which action should
.Em not
be taken.
For example, the
.Nm df
command:
.Bd -literal -offset indent
df -t nonfs,mfs
.Ed
.Pp
lists all filesystems except those of type
.Tn NFS
and
.Tn MFS .
The
.Xr sysctl 8
command can be used to find out the types of filesystems
that are available on the system:
.Bd -literal -offset indent
sysctl vfs
.Ed
.El
.Sh ENVIRONMENTAL VARIABLES
.Bl -tag -width BLOCKSIZE
.It Ev BLOCKSIZE
If the environmental variable
.Ev BLOCKSIZE
is set, the block counts will be displayed in units of that size block.
.El
.Sh BUGS
The
.Fl n
and
.Fl t
flags are ignored if a file or filesystem is specified.
.Sh SEE ALSO
.Xr quota 1 ,
.Xr statfs 2 ,
.Xr fstatfs 2 ,
.Xr getfsstat 2 ,
.Xr getmntinfo 3 ,
.Xr fstab 5 ,
.Xr mount 8 ,
.Xr quot 8 ,
.Xr sysctl 8
.Sh HISTORY
A
.Nm df
command appeared in
.At v6 .

361
bin/df/df.c Normal file
View File

@ -0,0 +1,361 @@
/*
* Copyright (c) 1980, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <ufs/ufs/ufsmount.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int checkvfsname __P((const char *, char **));
char **makevfslist __P((char *));
long regetmntinfo __P((struct statfs **, long, char **));
int bread __P((off_t, void *, int));
char *getmntpt __P((char *));
void prtstat __P((struct statfs *, int));
void ufs_df __P((char *, int));
void usage __P((void));
int iflag, nflag;
struct ufs_args mdev;
int
main(argc, argv)
int argc;
char *argv[];
{
struct stat stbuf;
struct statfs statfsbuf, *mntbuf;
long mntsize;
int ch, err, i, maxwidth, width;
char *mntpt, **vfslist;
vfslist = NULL;
while ((ch = getopt(argc, argv, "int:")) != EOF)
switch (ch) {
case 'i':
iflag = 1;
break;
case 'n':
nflag = 1;
break;
case 't':
if (vfslist != NULL)
errx(1, "only one -t option may be specified.");
vfslist = makevfslist(optarg);
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
maxwidth = 0;
for (i = 0; i < mntsize; i++) {
width = strlen(mntbuf[i].f_mntfromname);
if (width > maxwidth)
maxwidth = width;
}
if (!*argv) {
mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
if (vfslist != NULL) {
maxwidth = 0;
for (i = 0; i < mntsize; i++) {
width = strlen(mntbuf[i].f_mntfromname);
if (width > maxwidth)
maxwidth = width;
}
}
for (i = 0; i < mntsize; i++)
prtstat(&mntbuf[i], maxwidth);
exit(0);
}
for (; *argv; argv++) {
if (stat(*argv, &stbuf) < 0) {
err = errno;
if ((mntpt = getmntpt(*argv)) == 0) {
warn("%s", *argv);
continue;
}
} else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
ufs_df(*argv, maxwidth);
continue;
} else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
if ((mntpt = getmntpt(*argv)) == 0) {
mntpt = mktemp(strdup("/tmp/df.XXXXXX"));
mdev.fspec = *argv;
if (mkdir(mntpt, DEFFILEMODE) != 0) {
warn("%s", mntpt);
continue;
}
if (mount("ufs", mntpt, MNT_RDONLY,
&mdev) != 0) {
ufs_df(*argv, maxwidth);
(void)rmdir(mntpt);
continue;
} else if (statfs(mntpt, &statfsbuf)) {
statfsbuf.f_mntonname[0] = '\0';
prtstat(&statfsbuf, maxwidth);
} else
warn("%s", *argv);
(void)unmount(mntpt, 0);
(void)rmdir(mntpt);
continue;
}
} else
mntpt = *argv;
/*
* Statfs does not take a `wait' flag, so we cannot
* implement nflag here.
*/
if (statfs(mntpt, &statfsbuf) < 0) {
warn("%s", mntpt);
continue;
}
if (argc == 1)
maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
prtstat(&statfsbuf, maxwidth);
}
return (0);
}
char *
getmntpt(name)
char *name;
{
long mntsize, i;
struct statfs *mntbuf;
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
for (i = 0; i < mntsize; i++) {
if (!strcmp(mntbuf[i].f_mntfromname, name))
return (mntbuf[i].f_mntonname);
}
return (0);
}
/*
* Make a pass over the filesystem info in ``mntbuf'' filtering out
* filesystem types not in vfslist and possibly re-stating to get
* current (not cached) info. Returns the new count of valid statfs bufs.
*/
long
regetmntinfo(mntbufp, mntsize, vfslist)
struct statfs **mntbufp;
long mntsize;
char **vfslist;
{
int i, j;
struct statfs *mntbuf;
if (vfslist == NULL)
return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT));
mntbuf = *mntbufp;
for (j = 0, i = 0; i < mntsize; i++) {
if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
continue;
if (!nflag)
(void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]);
else if (i != j)
mntbuf[j] = mntbuf[i];
j++;
}
return (j);
}
/*
* Convert statfs returned filesystem size into BLOCKSIZE units.
* Attempts to avoid overflow for large filesystems.
*/
#define fsbtoblk(num, fsbs, bs) \
(((fsbs) != 0 && (fsbs) < (bs)) ? \
(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
/*
* Print out status about a filesystem.
*/
void
prtstat(sfsp, maxwidth)
struct statfs *sfsp;
int maxwidth;
{
static long blocksize;
static int headerlen, timesthrough;
static char *header;
long used, availblks, inodes;
if (maxwidth < 11)
maxwidth = 11;
if (++timesthrough == 1) {
header = getbsize(&headerlen, &blocksize);
(void)printf("%-*.*s %s Used Avail Capacity",
maxwidth, maxwidth, "Filesystem", header);
if (iflag)
(void)printf(" iused ifree %%iused");
(void)printf(" Mounted on\n");
}
(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
(void)printf(" %*ld %8ld %8ld", headerlen,
fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
fsbtoblk(used, sfsp->f_bsize, blocksize),
fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
(void)printf(" %5.0f%%",
availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
if (iflag) {
inodes = sfsp->f_files;
used = inodes - sfsp->f_ffree;
(void)printf(" %7ld %7ld %5.0f%% ", used, sfsp->f_ffree,
inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
} else
(void)printf(" ");
(void)printf(" %s\n", sfsp->f_mntonname);
}
/*
* This code constitutes the pre-system call Berkeley df code for extracting
* information from filesystem superblocks.
*/
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <errno.h>
#include <fstab.h>
union {
struct fs iu_fs;
char dummy[SBSIZE];
} sb;
#define sblock sb.iu_fs
int rfd;
void
ufs_df(file, maxwidth)
char *file;
int maxwidth;
{
struct statfs statfsbuf;
struct statfs *sfsp;
char *mntpt;
static int synced;
if (synced++ == 0)
sync();
if ((rfd = open(file, O_RDONLY)) < 0) {
warn("%s", file);
return;
}
if (bread((off_t)SBOFF, &sblock, SBSIZE) == 0) {
(void)close(rfd);
return;
}
sfsp = &statfsbuf;
sfsp->f_type = 1;
strcpy(sfsp->f_fstypename, "ufs");
sfsp->f_flags = 0;
sfsp->f_bsize = sblock.fs_fsize;
sfsp->f_iosize = sblock.fs_bsize;
sfsp->f_blocks = sblock.fs_dsize;
sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
sblock.fs_cstotal.cs_nffree;
sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
(sblock.fs_dsize - sfsp->f_bfree);
if (sfsp->f_bavail < 0)
sfsp->f_bavail = 0;
sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg;
sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
sfsp->f_fsid.val[0] = 0;
sfsp->f_fsid.val[1] = 0;
if ((mntpt = getmntpt(file)) == 0)
mntpt = "";
memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
prtstat(sfsp, maxwidth);
(void)close(rfd);
}
int
bread(off, buf, cnt)
off_t off;
void *buf;
int cnt;
{
int nr;
(void)lseek(rfd, off, SEEK_SET);
if ((nr = read(rfd, buf, cnt)) != cnt) {
/* Probably a dismounted disk if errno == EIO. */
if (errno != EIO)
(void)fprintf(stderr, "\ndf: %qd: %s\n",
off, strerror(nr > 0 ? EIO : errno));
return (0);
}
return (1);
}
void
usage()
{
(void)fprintf(stderr,
"usage: df [-in] [-t type] [file | file_system ...]\n");
exit(1);
}