|
|
researchv10 Norman
#include <stdio.h>
#include <fstab.h>
#include <libc.h>
#include <sys/param.h>
#include <sys/filsys.h>
#include <sys/stat.h>
/*
* df
*/
#define NFS 64 /* Max number of filesystems */
struct mtab mtab[NFS];
int nmtab;
#define L10BS 7
#define L10IS 6
#define PCTFW 3
int DEVNMLG = 3; /* length of longest device name */
int DIRNMLG = 3; /* length of longest mount point name */
#define BUNIT 1024 /* report in units of this size */
char *mpath();
int iflag;
struct filsys sblock;
int fi;
main(argc, argv)
register int argc;
register char **argv;
{
register int i;
nochk(1,0); /* for secure unix */
nochk(2,0);
while (argc >= 1 && argv[1][0]=='-') {
switch(argv[1][1]) {
case 'i':
iflag++;
break;
default:
fprintf(stderr, "usage: df [-i] [filsys...]\n");
exit(0);
}
argc--, argv++;
}
readtab();
printf("%-*.*s %-*.*s %*.*s %*.*s %*.*s",
DIRNMLG, DIRNMLG, "dir",
DEVNMLG, DEVNMLG, "dev",
L10BS, L10BS, "kbytes",
L10BS, L10BS, "used",
L10BS, L10BS, "free");
printf(" %*.*s", PCTFW + 1, PCTFW + 1, "%use");
if (iflag)
printf(" %*.*s %*.*s %*.*s",
L10IS, L10IS, "iused",
L10IS, L10IS, "ifree",
PCTFW + 1, PCTFW + 1, "%ino");
putchar('\n');
if(argc <= 1) {
for (i = 0; i < nmtab; ++i)
dfree(mtab[i].spec);
exit(0);
}
for(i=1; i<argc; i++)
dfree(argv[i]);
exit(0);
}
dfree(file)
char *file;
{
register daddr_t i;
long blocks;
long free;
long used;
struct stat stbuf;
dev_t dev;
char *spec;
if (stat(file, &stbuf) < 0) {
perror(file);
return;
}
if ((stbuf.st_mode & S_IFMT) == S_IFBLK)
spec = file;
else {
dev = stbuf.st_dev;
for (i = 0; i < nmtab; i++) {
spec = mtab[i].spec;
if (stat(spec, &stbuf) < 0)
continue;
if (stbuf.st_rdev == dev)
break;
}
if (i == nmtab) {
fprintf(stderr, "%s: can't find filesystem\n", file);
return;
}
}
if((fi = open(spec, 0)) < 0) {
perror(spec); /* but we already did a stat! */
return;
}
lseek(fi, SUPERB*BSIZE(stbuf.st_rdev), 0);
if (read(fi, (char *)&sblock, sizeof(sblock)) != sizeof(sblock)) {
perror(spec);
memset((char *)&sblock, 0, sizeof(sblock));
}
blocks = (long) sblock.s_fsize - (long)sblock.s_isize;
free = sblock.s_tfree;
used = blocks - free;
blocks *= BSIZE(stbuf.st_rdev) / BUNIT;
free *= BSIZE(stbuf.st_rdev) / BUNIT;
used *= BSIZE(stbuf.st_rdev) / BUNIT;
printf("%-*.*s %-*.*s %*ld %*ld %*ld",
DIRNMLG, DIRNMLG, mpath(spec),
DEVNMLG, DEVNMLG, spec,
L10BS, blocks, L10BS, used, L10BS, free);
printf(" %*.0f%%",
PCTFW, blocks == 0 ?
0.0 : (double) used / (double) blocks * 100.0);
if (iflag) {
int inodes = (sblock.s_isize - 2) * INOPB(stbuf.st_rdev);
used = inodes - sblock.s_tinode;
printf(" %*ld %*ld %*.0f%%",
L10IS, used,
L10IS, sblock.s_tinode,
PCTFW, inodes == 0 ?
0.0 : (double) used / (double) inodes * 100.0);
}
printf("\n");
close(fi);
}
/*
* Given a name like /dev/rp0h, returns the mount point, like /usr.
*/
char *mpath(spec)
char *spec;
{
register int i;
for (i=0; i<nmtab; i++)
if (strcmp(spec, mtab[i].spec) == 0)
return mtab[i].file;
return "";
}
/*
* hack: uninteresting mtab slots (empty or not type 0)
* always sort to the end. they were also omitted from the count.
* hence they are ignored.
*/
mtabcmp(mp0, mp1)
struct mtab *mp0;
struct mtab *mp1;
{
if (mp0->file[0] == 0 || mp0->type != 0)
return (1);
if (mp1->file[0] == 0 || mp1->type != 0)
return (-1);
return (strncmp(mp0->file, mp1->file, sizeof (mp0->file)));
}
/*
* read the list of filesystems, and sort it
* assumes type 0 is the only interesting filesystem
*/
readtab()
{
register int i, n;
int f;
register struct fstab *fsp;
mtab[0].file[0] = '/';
/*
* cheap hack because root isn't in mtab
*/
if ((fsp = getfsfile(mtab[0].file)) != NULL)
strcpy(mtab[0].spec, fsp->fs_spec);
if ((f = open(MTAB, 0)) < 0) {
nmtab = 1;
return;
}
n = read(f, (char *)&mtab[1], sizeof(mtab)-sizeof(mtab[0]));
close(f);
n /= sizeof(mtab[0]);
nmtab = 0;
for (i = 0; i <= n; i++) {
if (mtab[i].file[0] == 0 || mtab[i].type != 0)
continue;
nmtab++;
if (DEVNMLG < (f = strlen(mtab[i].spec)))
DEVNMLG = f;
if (DIRNMLG < (f = strlen(mtab[i].file)))
DIRNMLG = f;
}
qsort((char *)&mtab[0], n+1, sizeof(mtab[0]), mtabcmp);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.