NFSv2/usr/src/bin/df.c
#ifndef lint
static char sccsid[] = "@(#)df.c 1.1 85/05/30 SMI"; /* from UCB 4.18 84/02/02 */
#endif
/*
* df
*/
#include <sys/param.h>
#include <errno.h>
#include <ufs/fs.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <stdio.h>
#include <mntent.h>
char *mpath();
int iflag;
struct mntent * getmntpt();
union {
struct fs iu_fs;
char dummy[SBSIZE];
} sb;
#define sblock sb.iu_fs
main(argc, argv)
int argc;
char **argv;
{
int i;
struct stat statb;
while (argc > 1 && argv[1][0]=='-') {
switch (argv[1][1]) {
case 'i':
iflag++;
break;
default:
fprintf(stderr, "usage: df [ -i ] [ file... ]\n");
exit(0);
}
argc--, argv++;
}
sync();
if (iflag)
printf("Filesystem iused ifree %%iused");
else
printf("Filesystem kbytes used avail capacity");
printf(" Mounted on\n");
if (argc <= 1) {
FILE *mtabp;
struct mntent *mnt;
if ((mtabp = setmntent(MOUNTED, "r")) == 0) {
perror(MOUNTED);
exit(1);
}
while (mnt = getmntent(mtabp)) {
if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
continue;
dfreemnt(mnt->mnt_dir, mnt);
}
endmntent(mtabp);
exit(0);
}
for (i=1; i<argc; i++) {
if (stat(argv[i], &statb) < 0) {
perror(argv[i]);
} else {
if ((statb.st_mode & S_IFBLK) == S_IFBLK) {
dfreedev(argv[i]);
} else {
dfreemnt(argv[i], getmntpt(argv[i]));
}
}
}
exit(0);
}
dfreedev(file)
char *file;
{
long totalblks, availblks, avail, free, used;
int fi;
fi = open(file, 0);
if (fi < 0) {
perror(file);
return;
}
if (bread(fi, SBLOCK, (char *)&sblock, SBSIZE) == 0) {
(void) close(fi);
return;
}
printf("%-20.20s", file);
if (iflag) {
int inodes = sblock.fs_ncg * sblock.fs_ipg;
used = inodes - sblock.fs_cstotal.cs_nifree;
printf("%8ld%8ld%6.0f%% ", used, sblock.fs_cstotal.cs_nifree,
inodes == 0 ? 0.0 : (double)used / (double)inodes * 100.0);
} else {
totalblks = sblock.fs_dsize;
free = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
sblock.fs_cstotal.cs_nffree;
used = totalblks - free;
availblks = totalblks * (100 - sblock.fs_minfree) / 100;
avail = availblks > used ? availblks - used : 0;
printf("%8d%8d%8d",
totalblks * sblock.fs_fsize / 1024,
used * sblock.fs_fsize / 1024,
avail * sblock.fs_fsize / 1024);
printf("%6.0f%%",
availblks==0? 0.0: (double)used/(double)availblks * 100.0);
printf(" ");
}
printf(" %s\n", mpath(file));
(void) close(fi);
}
dfreemnt(file, mnt)
char *file;
struct mntent *mnt;
{
struct statfs fs;
if (statfs(file, &fs) < 0) {
perror(file);
return;
}
printf("%-20.20s", mnt->mnt_fsname);
if (iflag) {
long files, used;
files = fs.f_files;
used = files - fs.f_ffree;
printf("%8ld%8ld%6.0f%% ", used, fs.f_ffree,
files == 0? 0.0: (double)used / (double)files * 100.0);
} else {
long totalblks, avail, free, used, reserved;
totalblks = fs.f_blocks;
free = fs.f_bfree;
used = totalblks - free;
avail = fs.f_bavail;
reserved = free - avail;
if (avail < 0)
avail = 0;
printf("%8d%8d%8d", totalblks * fs.f_bsize / 1024,
used * fs.f_bsize / 1024, avail * fs.f_bsize / 1024);
totalblks -= reserved;
printf("%6.0f%%",
totalblks==0? 0.0: (double)used/(double)totalblks * 100.0);
printf(" ");
}
printf(" %s\n", mnt->mnt_dir);
}
/*
* Given a name like /usr/src/etc/foo.c returns the mntent
* structure for the file system it lives in.
*/
struct mntent *
getmntpt(file)
char *file;
{
FILE *mntp;
struct mntent *mnt;
struct stat filestat, dirstat;
if (stat(file, &filestat) < 0) {
perror(file);
return(NULL);
}
if ((mntp = setmntent(MOUNTED, "r")) == 0) {
perror(MOUNTED);
exit(1);
}
while ((mnt = getmntent(mntp)) != 0) {
if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
continue;
if (strcmp(mnt->mnt_fsname, file) == 0) {
endmntent(mntp);
return(mnt);
}
if (stat(mnt->mnt_dir, &dirstat) < 0) {
perror(mnt->mnt_dir);
endmntent(mntp);
return(NULL);
}
if (filestat.st_dev == dirstat.st_dev) {
endmntent(mntp);
return(mnt);
}
}
fprintf(stderr, "Couldn't find mount point for %s\n", file);
exit(1);
/*NOTREACHED*/
}
/*
* Given a name like /dev/rrp0h, returns the mounted path, like /usr.
*/
char *
mpath(file)
char *file;
{
FILE *mntp;
register struct mntent *mnt;
if ((mntp = setmntent(MOUNTED, "r")) == 0) {
perror(MOUNTED);
exit(1);
}
while ((mnt = getmntent(mntp)) != 0) {
if (strcmp(file, mnt->mnt_fsname) == 0) {
endmntent(mntp);
return (mnt->mnt_dir);
}
}
endmntent(mntp);
return "";
}
long lseek();
bread(fi, bno, buf, cnt)
int fi;
daddr_t bno;
char *buf;
{
int n;
extern errno;
(void) lseek(fi, (long)(bno * DEV_BSIZE), 0);
if ((n=read(fi, buf, cnt)) != cnt) {
/* probably a dismounted disk if errno == EIO */
if (errno != EIO) {
printf("\nread error bno = %ld\n", bno);
printf("count = %d; errno = %d\n", n, errno);
}
return (0);
}
return (1);
}