1: #ifndef lint 2: static char *sccsid = "@(#)df.c 4.6 (Berkeley) 7/8/81"; 3: #endif 4: #include <sys/param.h> 5: #include <stdio.h> 6: #include <fstab.h> 7: #include <sys/filsys.h> 8: #include <sys/ino.h> 9: #include <sys/fblk.h> 10: #include <sys/stat.h> 11: /* 12: * df 13: */ 14: 15: #define NFS 20 /* Max number of filesystems */ 16: 17: struct { 18: char path[32]; 19: char spec[32]; 20: } mtab[NFS]; 21: char root[32]; 22: 23: char *mpath(); 24: 25: daddr_t blkno = 1; 26: 27: int lflag; 28: int iflag; 29: 30: struct filsys sblock; 31: 32: int fi; 33: daddr_t alloc(); 34: 35: main(argc, argv) 36: register char **argv; 37: { 38: register i; 39: 40: while (argc >= 1 && argv[1][0]=='-') { 41: switch(argv[1][1]) { 42: 43: case 'l': 44: lflag++; 45: break; 46: 47: case 'i': 48: iflag++; 49: break; 50: 51: default: 52: fprintf(stderr, "usage: df [ -il ] [ filsys... ]\n"); 53: exit(0); 54: } 55: argc--, argv++; 56: } 57: 58: if ((i=open("/etc/mtab", 0)) >= 0) { 59: read(i, (char *) mtab, sizeof mtab); /* Probably returns short */ 60: close(i); 61: } 62: printf("Filesystem Mounted on kbytes\t used\t free"); 63: if (lflag) 64: printf("\thardway"); 65: printf("\t%% used"); 66: if (iflag) 67: printf("\tiused\tifree\t%%iused"); 68: putchar('\n'); 69: if(argc <= 1) { 70: struct fstab *fsp; 71: if (setfsent() == 0) 72: perror(FSTAB), exit(1); 73: while( (fsp = getfsent()) != 0){ 74: if ( (strcmp(fsp->fs_type, FSTAB_RW) != 0) 75: &&(strcmp(fsp->fs_type, FSTAB_RO) != 0) ) 76: continue; 77: if (root[0] == 0) 78: strcpy(root, fsp->fs_spec); 79: dfree(fsp->fs_spec); 80: } 81: endfsent(); 82: exit(0); 83: } 84: 85: for(i=1; i<argc; i++) { 86: dfree(argv[i]); 87: } 88: } 89: 90: dfree(file) 91: char *file; 92: { 93: long blocks; 94: long free; 95: long used; 96: long hardway; 97: char *mp; 98: struct stat stbuf; 99: 100: if(stat(file, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) != S_IFCHR 101: && (stbuf.st_mode&S_IFMT) != S_IFBLK) { 102: int mt = open("/etc/mtab", 0), len; 103: char *str = "/dev/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 104: char mountedon[32]; 105: struct stat mstbuf; 106: while((len = read(mt, mountedon, 32)) == 32) { 107: read(mt, &str[5], 32); 108: if(stat(str, &mstbuf) == 0 && mstbuf.st_rdev == stbuf.st_dev) { 109: file = str; 110: break; 111: } 112: } 113: close(mt); 114: if(len == 0) { 115: fprintf(stderr, "%s: mounted on unknown device\n", file); 116: return; 117: } 118: } 119: fi = open(file, 0); 120: if(fi < 0) { 121: fprintf(stderr,"cannot open %s\n", file); 122: return; 123: } 124: if (lflag) 125: sync(); 126: bread(1L, (char *)&sblock, sizeof(sblock)); 127: printf("%-12.12s%s", file, mp = mpath(file)); 128: if (strlen(mp) < 4) 129: putchar('\t'); 130: 131: blocks = (long) sblock.s_fsize - (long)sblock.s_isize; 132: free = sblock.s_tfree; 133: used = blocks - free; 134: 135: printf("\t%6ld", blocks); 136: printf("\t%6ld", used); 137: printf("\t%6ld", free); 138: if (lflag) { 139: hardway = 0; 140: while(alloc()) 141: hardway++; 142: printf("\t%6ld", free=hardway); 143: } 144: printf("\t%5.0f%%", 145: blocks == 0L ? 0.0 : (double) used / (double)blocks * 100.0); 146: if (iflag) { 147: long inodes = ((long) (sblock.s_isize - 2)) * ((long) INOPB); 148: used = (double) (inodes - (long) sblock.s_tinode); 149: printf("\t%5ld\t%5d\t%5.0f%%", used, sblock.s_tinode, 150: inodes == 0L ? 0.0 : (double)used/(double)inodes*100.0); 151: } 152: printf("\n"); 153: close(fi); 154: } 155: 156: daddr_t 157: alloc() 158: { 159: int i; 160: daddr_t b; 161: struct fblk buf; 162: 163: i = --sblock.s_nfree; 164: if(i<0 || i>=NICFREE) { 165: printf("bad free count, b=%D\n", blkno); 166: return(0); 167: } 168: b = sblock.s_free[i]; 169: if(b == 0) 170: return(0); 171: if(b<sblock.s_isize || b>=sblock.s_fsize) { 172: printf("bad free block (%D)\n", b); 173: return(0); 174: } 175: if(sblock.s_nfree <= 0) { 176: bread(b, (char *)&buf, sizeof(buf)); 177: blkno = b; 178: sblock.s_nfree = buf.df_nfree; 179: for(i=0; i<NICFREE; i++) 180: sblock.s_free[i] = buf.df_free[i]; 181: } 182: return(b); 183: } 184: 185: bread(bno, buf, cnt) 186: daddr_t bno; 187: char *buf; 188: { 189: int n; 190: extern errno; 191: 192: lseek(fi, bno<<BSHIFT, 0); 193: if((n=read(fi, (char *) buf, cnt)) != cnt) { 194: printf("\nread error bno = %ld\n", bno); 195: printf("count = %d; errno = %d\n", n, errno); 196: exit(0); 197: } 198: } 199: 200: /* 201: * Given a name like /dev/rrp0h, returns the mounted path, like /usr. 202: */ 203: char *mpath(file) 204: char *file; 205: { 206: register int i; 207: 208: if (eq(file, root)) 209: return "/"; 210: for (i=0; i<NFS; i++) 211: if (eq(file, mtab[i].spec)) 212: return mtab[i].path; 213: return ""; 214: } 215: 216: eq(f1, f2) 217: char *f1, *f2; 218: { 219: if (strncmp(f1, "/dev/", 5) == 0) 220: f1 += 5; 221: if (strncmp(f2, "/dev/", 5) == 0) 222: f2 += 5; 223: if (strcmp(f1, f2) == 0) 224: return 1; 225: if (*f1 == 'r' && strcmp(f1+1, f2) == 0) 226: return 1; 227: if (*f2 == 'r' && strcmp(f1, f2+1) == 0) 228: return 1; 229: if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0) 230: return 1; 231: return 0; 232: }