|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <fstab.h> ! 3: #include <libc.h> ! 4: #include <sys/param.h> ! 5: #include <sys/filsys.h> ! 6: #include <sys/stat.h> ! 7: /* ! 8: * df ! 9: */ ! 10: ! 11: #define NFS 64 /* Max number of filesystems */ ! 12: ! 13: struct mtab mtab[NFS]; ! 14: int nmtab; ! 15: #define L10BS 7 ! 16: #define L10IS 6 ! 17: #define PCTFW 3 ! 18: int DEVNMLG = 3; /* length of longest device name */ ! 19: int DIRNMLG = 3; /* length of longest mount point name */ ! 20: ! 21: #define BUNIT 1024 /* report in units of this size */ ! 22: ! 23: char *mpath(); ! 24: ! 25: int iflag; ! 26: struct filsys sblock; ! 27: int fi; ! 28: ! 29: main(argc, argv) ! 30: register int argc; ! 31: register char **argv; ! 32: { ! 33: register int i; ! 34: ! 35: nochk(1,0); /* for secure unix */ ! 36: nochk(2,0); ! 37: while (argc >= 1 && argv[1][0]=='-') { ! 38: switch(argv[1][1]) { ! 39: ! 40: case 'i': ! 41: iflag++; ! 42: break; ! 43: ! 44: default: ! 45: fprintf(stderr, "usage: df [-i] [filsys...]\n"); ! 46: exit(0); ! 47: } ! 48: argc--, argv++; ! 49: } ! 50: readtab(); ! 51: printf("%-*.*s %-*.*s %*.*s %*.*s %*.*s", ! 52: DIRNMLG, DIRNMLG, "dir", ! 53: DEVNMLG, DEVNMLG, "dev", ! 54: L10BS, L10BS, "kbytes", ! 55: L10BS, L10BS, "used", ! 56: L10BS, L10BS, "free"); ! 57: printf(" %*.*s", PCTFW + 1, PCTFW + 1, "%use"); ! 58: if (iflag) ! 59: printf(" %*.*s %*.*s %*.*s", ! 60: L10IS, L10IS, "iused", ! 61: L10IS, L10IS, "ifree", ! 62: PCTFW + 1, PCTFW + 1, "%ino"); ! 63: putchar('\n'); ! 64: if(argc <= 1) { ! 65: for (i = 0; i < nmtab; ++i) ! 66: dfree(mtab[i].spec); ! 67: exit(0); ! 68: } ! 69: for(i=1; i<argc; i++) ! 70: dfree(argv[i]); ! 71: exit(0); ! 72: } ! 73: ! 74: dfree(file) ! 75: char *file; ! 76: { ! 77: register daddr_t i; ! 78: long blocks; ! 79: long free; ! 80: long used; ! 81: struct stat stbuf; ! 82: dev_t dev; ! 83: char *spec; ! 84: ! 85: if (stat(file, &stbuf) < 0) { ! 86: perror(file); ! 87: return; ! 88: } ! 89: if ((stbuf.st_mode & S_IFMT) == S_IFBLK) ! 90: spec = file; ! 91: else { ! 92: dev = stbuf.st_dev; ! 93: for (i = 0; i < nmtab; i++) { ! 94: spec = mtab[i].spec; ! 95: if (stat(spec, &stbuf) < 0) ! 96: continue; ! 97: if (stbuf.st_rdev == dev) ! 98: break; ! 99: } ! 100: if (i == nmtab) { ! 101: fprintf(stderr, "%s: can't find filesystem\n", file); ! 102: return; ! 103: } ! 104: } ! 105: if((fi = open(spec, 0)) < 0) { ! 106: perror(spec); /* but we already did a stat! */ ! 107: return; ! 108: } ! 109: lseek(fi, SUPERB*BSIZE(stbuf.st_rdev), 0); ! 110: if (read(fi, (char *)&sblock, sizeof(sblock)) != sizeof(sblock)) { ! 111: perror(spec); ! 112: memset((char *)&sblock, 0, sizeof(sblock)); ! 113: } ! 114: blocks = (long) sblock.s_fsize - (long)sblock.s_isize; ! 115: free = sblock.s_tfree; ! 116: used = blocks - free; ! 117: blocks *= BSIZE(stbuf.st_rdev) / BUNIT; ! 118: free *= BSIZE(stbuf.st_rdev) / BUNIT; ! 119: used *= BSIZE(stbuf.st_rdev) / BUNIT; ! 120: printf("%-*.*s %-*.*s %*ld %*ld %*ld", ! 121: DIRNMLG, DIRNMLG, mpath(spec), ! 122: DEVNMLG, DEVNMLG, spec, ! 123: L10BS, blocks, L10BS, used, L10BS, free); ! 124: printf(" %*.0f%%", ! 125: PCTFW, blocks == 0 ? ! 126: 0.0 : (double) used / (double) blocks * 100.0); ! 127: if (iflag) { ! 128: int inodes = (sblock.s_isize - 2) * INOPB(stbuf.st_rdev); ! 129: used = inodes - sblock.s_tinode; ! 130: printf(" %*ld %*ld %*.0f%%", ! 131: L10IS, used, ! 132: L10IS, sblock.s_tinode, ! 133: PCTFW, inodes == 0 ? ! 134: 0.0 : (double) used / (double) inodes * 100.0); ! 135: } ! 136: printf("\n"); ! 137: close(fi); ! 138: } ! 139: ! 140: /* ! 141: * Given a name like /dev/rp0h, returns the mount point, like /usr. ! 142: */ ! 143: char *mpath(spec) ! 144: char *spec; ! 145: { ! 146: register int i; ! 147: ! 148: for (i=0; i<nmtab; i++) ! 149: if (strcmp(spec, mtab[i].spec) == 0) ! 150: return mtab[i].file; ! 151: return ""; ! 152: } ! 153: ! 154: /* ! 155: * hack: uninteresting mtab slots (empty or not type 0) ! 156: * always sort to the end. they were also omitted from the count. ! 157: * hence they are ignored. ! 158: */ ! 159: mtabcmp(mp0, mp1) ! 160: struct mtab *mp0; ! 161: struct mtab *mp1; ! 162: { ! 163: if (mp0->file[0] == 0 || mp0->type != 0) ! 164: return (1); ! 165: if (mp1->file[0] == 0 || mp1->type != 0) ! 166: return (-1); ! 167: return (strncmp(mp0->file, mp1->file, sizeof (mp0->file))); ! 168: } ! 169: ! 170: /* ! 171: * read the list of filesystems, and sort it ! 172: * assumes type 0 is the only interesting filesystem ! 173: */ ! 174: readtab() ! 175: { ! 176: register int i, n; ! 177: int f; ! 178: register struct fstab *fsp; ! 179: ! 180: mtab[0].file[0] = '/'; ! 181: /* ! 182: * cheap hack because root isn't in mtab ! 183: */ ! 184: if ((fsp = getfsfile(mtab[0].file)) != NULL) ! 185: strcpy(mtab[0].spec, fsp->fs_spec); ! 186: if ((f = open(MTAB, 0)) < 0) { ! 187: nmtab = 1; ! 188: return; ! 189: } ! 190: n = read(f, (char *)&mtab[1], sizeof(mtab)-sizeof(mtab[0])); ! 191: close(f); ! 192: n /= sizeof(mtab[0]); ! 193: nmtab = 0; ! 194: for (i = 0; i <= n; i++) { ! 195: if (mtab[i].file[0] == 0 || mtab[i].type != 0) ! 196: continue; ! 197: nmtab++; ! 198: if (DEVNMLG < (f = strlen(mtab[i].spec))) ! 199: DEVNMLG = f; ! 200: if (DIRNMLG < (f = strlen(mtab[i].file))) ! 201: DIRNMLG = f; ! 202: } ! 203: qsort((char *)&mtab[0], n+1, sizeof(mtab[0]), mtabcmp); ! 204: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.