|
|
1.1 ! root 1: static char *sccsid = "@(#)df.c 4.6 (Berkeley) 7/8/81"; ! 2: #include <stdio.h> ! 3: #include <fstab.h> ! 4: #include <sys/param.h> ! 5: #include <sys/filsys.h> ! 6: #include <sys/fblk.h> ! 7: #include <sys/stat.h> ! 8: /* ! 9: * df ! 10: */ ! 11: ! 12: #define NFS 32 /* Max number of filesystems */ ! 13: ! 14: #define KBYTE 1024 ! 15: ! 16: struct mtab { ! 17: char path[FSNMLG]; ! 18: char spec[FSNMLG]; ! 19: } mtab[NFS]; ! 20: struct stat stb; ! 21: int dev; ! 22: #define L10BS 6 ! 23: #define L10IS 5 ! 24: #define PCTFW 3 ! 25: int DEVNMLG; /* length of longest device name */ ! 26: int DIRNMLG; /* length of longest mount point name */ ! 27: ! 28: char *mpath(); ! 29: ! 30: daddr_t blkno = 1; ! 31: ! 32: int lflag; ! 33: int iflag; ! 34: ! 35: struct filsys sblock; ! 36: ! 37: int fi; ! 38: daddr_t alloc(); ! 39: ! 40: main(argc, argv) ! 41: register int argc; ! 42: register char **argv; ! 43: { ! 44: register int i; ! 45: register int r = 0; ! 46: ! 47: while (argc > 1 && argv[1][0]=='-') { ! 48: switch(argv[1][1]) { ! 49: ! 50: case 'l': ! 51: lflag++; ! 52: break; ! 53: ! 54: case 'i': ! 55: iflag++; ! 56: break; ! 57: ! 58: default: ! 59: fprintf(stderr, "usage: df [-i] [-l] [filsys...]\n"); ! 60: exit(0); ! 61: } ! 62: argc--, argv++; ! 63: } ! 64: ! 65: if ((i=open("/etc/mtab", 0)) >= 0) { ! 66: r = read(i, mtab, sizeof mtab); /* Probably returns short */ ! 67: (void) close(i); ! 68: r /= sizeof mtab[0]; ! 69: } ! 70: devlen(r); /* reads in all of /etc/fstab, too */ ! 71: printf("%-*.*s %-*.*s %*.*s %*.*s %*.*s", ! 72: DIRNMLG, DIRNMLG, "dir", ! 73: DEVNMLG, DEVNMLG, "dev", ! 74: L10BS, L10BS, "kbytes", ! 75: L10BS, L10BS, "used", ! 76: L10BS, L10BS, "free"); ! 77: if (lflag) ! 78: printf(" %*.*s", L10BS, L10BS, "hardway"); ! 79: printf(" %*.*s", PCTFW + 1, PCTFW + 1, "%use"); ! 80: if (iflag) ! 81: printf(" %*.*s %*.*s %*.*s", ! 82: L10IS, L10IS, "iused", ! 83: L10IS, L10IS, "ifree", ! 84: PCTFW + 1, PCTFW + 1, "%ino"); ! 85: putchar('\n'); ! 86: if(argc <= 1) { ! 87: for (i = 0; i < NFS && mtab[i].spec[0]; ++i) ! 88: dfree(mtab[i].path); ! 89: return (0); ! 90: } ! 91: ! 92: for(i=1; i<argc; i++) ! 93: dfree(argv[i]); ! 94: return (0); ! 95: } ! 96: ! 97: dfree(file) ! 98: char *file; ! 99: { ! 100: register daddr_t i; ! 101: register char *mp; ! 102: long blocks; ! 103: long free; ! 104: long used; ! 105: long hardway; ! 106: struct stat stbuf; ! 107: static char specbuf[FSNMLG + sizeof "/dev/"] = "/dev/"; ! 108: ! 109: if(stat(file, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) ! 110: { ! 111: struct stat mstbuf; ! 112: ! 113: for (i = 0; i < NFS && mtab[i].spec[0]; ++i) ! 114: { ! 115: strcpy(&specbuf[5], mtab[i].spec); ! 116: if(!stat(specbuf, &mstbuf) && mstbuf.st_rdev == stbuf.st_dev) ! 117: { ! 118: file = specbuf; ! 119: break; ! 120: } ! 121: } ! 122: if (i == NFS || mtab[i].spec[0] == '\0') ! 123: { ! 124: fprintf(stderr, "%s mounted on unknown device\n", file); ! 125: return; ! 126: } ! 127: } ! 128: else ! 129: if (strncmp("/dev/", file, sizeof "/dev/" - 1) != 0) ! 130: strcpy(&specbuf[5], file), file = specbuf; ! 131: fi = open(file, 0); ! 132: if(fi < 0) ! 133: { ! 134: fprintf(stderr,"cannot open %s\n", file); ! 135: return; ! 136: } ! 137: fstat(fi, &stb); ! 138: dev = stb.st_rdev; ! 139: if (lflag) ! 140: sync(); ! 141: bread(1L, (char *)&sblock, sizeof(sblock)); ! 142: blocks = (long) sblock.s_fsize - (long)sblock.s_isize; ! 143: free = sblock.s_tfree; ! 144: used = blocks - free; ! 145: blocks *= BSIZE(dev) / KBYTE; ! 146: free *= BSIZE(dev) / KBYTE; ! 147: used *= BSIZE(dev) / KBYTE; ! 148: printf("%-*.*s %-*.*s %*ld %*ld %*ld", ! 149: DIRNMLG, DIRNMLG, mp = mpath(file), ! 150: DEVNMLG, DEVNMLG, file + sizeof "/dev", ! 151: L10BS, blocks, L10BS, used, L10BS, free); ! 152: ! 153: if (lflag) { ! 154: hardway = 0; ! 155: if(BITFS(dev)) ! 156: hardway = alloc(); ! 157: else ! 158: while(alloc()) ! 159: hardway++; ! 160: hardway *= BSIZE(dev) / KBYTE; ! 161: printf(" %*ld", L10BS, free = hardway); ! 162: } ! 163: printf(" %*.0f%%", ! 164: PCTFW, blocks == 0 ? ! 165: 0.0 : (double) used / (double) blocks * 100.0); ! 166: if (iflag) { ! 167: int inodes = (sblock.s_isize - 2) * INOPB(dev); ! 168: used = inodes - sblock.s_tinode; ! 169: printf(" %*ld %*ld %*.0f%%", ! 170: L10IS, used, ! 171: L10IS, sblock.s_tinode, ! 172: PCTFW, inodes == 0 ? ! 173: 0.0 : (double) used / (double) inodes * 100.0); ! 174: } ! 175: printf("\n"); ! 176: close(fi); ! 177: } ! 178: ! 179: daddr_t ! 180: alloc() ! 181: { ! 182: int i, j, n; ! 183: daddr_t b; ! 184: struct fblk buf; ! 185: ! 186: if(!BITFS(dev)) { ! 187: i = --sblock.s_nfree; ! 188: if(i<0 || i>=NICFREE) { ! 189: printf("bad free count, b=%D\n", blkno); ! 190: return(0); ! 191: } ! 192: b = sblock.s_free[i]; ! 193: if(b == 0) ! 194: return(0); ! 195: if(b<sblock.s_isize || b>=sblock.s_fsize) { ! 196: printf("bad free block (%D)\n", b); ! 197: return(0); ! 198: } ! 199: if(sblock.s_nfree <= 0) { ! 200: bread(b, (char *)&buf, sizeof(buf)); ! 201: blkno = b; ! 202: sblock.s_nfree = buf.df_nfree; ! 203: for(i=0; i<NICFREE; i++) ! 204: sblock.s_free[i] = buf.df_free[i]; ! 205: } ! 206: return(b); ! 207: } ! 208: n = 0; ! 209: for(i = 0; i < BITMAP; i++) ! 210: for(j = 0; j < 32; j++) /* 32: bits per int */ ! 211: if(sblock.s_bfree[i] & (1 << j)) ! 212: n++; ! 213: return(n); ! 214: } ! 215: ! 216: bread(bno, buf, cnt) ! 217: daddr_t bno; ! 218: char *buf; ! 219: { ! 220: register int n; ! 221: extern errno; ! 222: ! 223: lseek(fi, bno<<BSHIFT(dev), 0); ! 224: if((n=read(fi, buf, cnt)) != cnt) { ! 225: printf("\nread error bno = %ld\n", bno); ! 226: printf("count = %d; errno = %d\n", n, errno); ! 227: exit(0); ! 228: } ! 229: } ! 230: ! 231: /* ! 232: * Given a name like /dev/rrp0h, returns the mounted path, like /usr. ! 233: */ ! 234: char *mpath(file) ! 235: char *file; ! 236: { ! 237: register int i; ! 238: ! 239: for (i=0; i<NFS; i++) ! 240: if (eq(file, mtab[i].spec)) ! 241: return mtab[i].path; ! 242: return ""; ! 243: } ! 244: ! 245: eq(f1, f2) ! 246: char *f1, *f2; ! 247: { ! 248: if (strncmp(f1, "/dev/", 5) == 0) ! 249: f1 += 5; ! 250: if (strncmp(f2, "/dev/", 5) == 0) ! 251: f2 += 5; ! 252: if (strcmp(f1, f2) == 0) ! 253: return 1; ! 254: if (*f1 == 'r' && strcmp(f1+1, f2) == 0) ! 255: return 1; ! 256: if (*f2 == 'r' && strcmp(f1, f2+1) == 0) ! 257: return 1; ! 258: if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0) ! 259: return 1; ! 260: return 0; ! 261: } ! 262: ! 263: mtabcmp(mp0, mp1) ! 264: struct mtab *mp0; ! 265: struct mtab *mp1; ! 266: { ! 267: /* ! 268: * don't let empty mtab slots sort to the front ! 269: * as dfree will break ! 270: * the wrong way to fix it: the whole algorithm is wrong ! 271: */ ! 272: if (mp0->path[0] == 0) ! 273: return (1); ! 274: if (mp1->path[0] == 0) ! 275: return (-1); ! 276: return (strncmp(mp0->path, mp1->path, sizeof (mp0->path))); ! 277: } ! 278: ! 279: devlen(r) ! 280: register int r; ! 281: { ! 282: register struct fstab *fsp; ! 283: register int i; ! 284: ! 285: DEVNMLG = 0; ! 286: DIRNMLG = 0; ! 287: if (setfsent() == 0) ! 288: perror(FSTAB), exit(1); ! 289: while( (fsp = getfsent()) != 0){ ! 290: if ( (strcmp(fsp->fs_type, FSTAB_RW) != 0) ! 291: &&(strcmp(fsp->fs_type, FSTAB_RO) != 0) ) ! 292: continue; ! 293: for (i = 0; mtab[i].spec[0]; ++i) ! 294: { ! 295: if (strncmp(mtab[i].spec, fsp->fs_spec + 5, ! 296: sizeof fsp->fs_spec - 5) == 0) ! 297: break; ! 298: } ! 299: if (i == r && i < NFS) ! 300: { ! 301: strncpy(mtab[r].spec, fsp->fs_spec + 5, ! 302: sizeof fsp->fs_spec - 5); ! 303: strncpy(mtab[r].path, fsp->fs_file, sizeof fsp->fs_file); ! 304: ++r; ! 305: } ! 306: if (DEVNMLG < (i = strlen(fsp->fs_spec))) ! 307: DEVNMLG = i; ! 308: if (DIRNMLG < (i = strlen(fsp->fs_file))) ! 309: DIRNMLG = i; ! 310: } ! 311: endfsent(); ! 312: DEVNMLG -= sizeof "/dev"; ! 313: if (DEVNMLG < sizeof "dev" - 1) ! 314: DEVNMLG = sizeof "dev" - 1; ! 315: if (DIRNMLG < sizeof "dir" - 1) ! 316: DIRNMLG = sizeof "dir" - 1; ! 317: qsort(&mtab[0], r, sizeof mtab[0], mtabcmp); ! 318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.