#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); }