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