1 #ifndef lint 2 static char *sccsid = "@(#)quot.c 4.4 (Berkeley) 83/07/01"; 3 #endif 4 5 /* 6 * quot 7 */ 8 9 #include <stdio.h> 10 #include <ctype.h> 11 #include <pwd.h> 12 #include <sys/param.h> 13 #include <sys/inode.h> 14 #include <sys/fs.h> 15 16 #define ISIZ (MAXBSIZE/sizeof(struct dinode)) 17 #define NUID 1000 18 union { 19 struct fs u_sblock; 20 char dummy[SBSIZE]; 21 } sb_un; 22 #define sblock sb_un.u_sblock 23 struct dinode itab[MAXBSIZE/sizeof(struct dinode)]; 24 struct du 25 { 26 long blocks; 27 long blocks30,blocks60,blocks90; 28 long nfiles; 29 int uid; 30 char *name; 31 } du[NUID]; 32 #define TSIZE 500 33 int sizes[TSIZE]; 34 long overflow; 35 36 int nflg; 37 int fflg; 38 int cflg; 39 int vflg; 40 int hflg; 41 long now; 42 43 int fi; 44 unsigned ino; 45 unsigned nfiles; 46 47 struct passwd *getpwent(); 48 char *malloc(); 49 char *copy(); 50 51 main(argc, argv) 52 char **argv; 53 { 54 register int n; 55 register struct passwd *lp; 56 register char **p; 57 58 now = time(0); 59 for(n=0; n<NUID; n++) 60 du[n].uid = n; 61 while((lp=getpwent()) != 0) { 62 n = lp->pw_uid; 63 if (n>NUID) 64 continue; 65 if(du[n].name) 66 continue; 67 du[n].name = copy(lp->pw_name); 68 } 69 if (argc == 1) { 70 fprintf(stderr, "usage: df device ...\n"); 71 exit(1); 72 } 73 while (--argc) { 74 argv++; 75 if (argv[0][0]=='-') { 76 if (argv[0][1]=='n') 77 nflg++; 78 else if (argv[0][1]=='f') 79 fflg++; 80 else if (argv[0][1]=='c') 81 cflg++; 82 else if (argv[0][1]=='v') 83 vflg++; 84 else if (argv[0][1]=='h') 85 hflg++; 86 } else { 87 if (check(*argv) == 0) 88 report(); 89 } 90 } 91 return(0); 92 } 93 94 check(file) 95 char *file; 96 { 97 register unsigned i, j; 98 daddr_t iblk; 99 int c; 100 101 fi = open(file, 0); 102 if (fi < 0) { 103 printf("cannot open %s\n", file); 104 return (-1); 105 } 106 printf("%s:\n", file); 107 sync(); 108 bread(SBLOCK, (char *)&sblock, SBSIZE); 109 if (nflg) { 110 if (isdigit(c = getchar())) 111 ungetc(c, stdin); 112 else while (c!='\n' && c != EOF) 113 c = getchar(); 114 } 115 nfiles = sblock.fs_ipg * sblock.fs_ncg; 116 for (ino = 0; ino < nfiles; ) { 117 iblk = fsbtodb(&sblock, itod(&sblock, ino)); 118 bread(iblk, (char *)itab, sblock.fs_bsize); 119 for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++) { 120 if (ino++ < ROOTINO) 121 continue; 122 acct(&itab[j]); 123 } 124 } 125 } 126 127 acct(ip) 128 register struct dinode *ip; 129 { 130 register char *np; 131 long blks, frags, size; 132 char n; 133 static fino; 134 135 if ((ip->di_mode&IFMT) == 0) 136 return; 137 if (!hflg) { 138 /* 139 * Assume that there are no holes in files. 140 */ 141 blks = lblkno(&sblock, ip->di_size); 142 frags = blks * sblock.fs_frag + 143 numfrags(&sblock, dblksize(&sblock, ip, blks)); 144 } else { 145 /* 146 * Actually go out and count the number of allocated blocks. 147 */ 148 printf("Sorry, hard way not implemented yet...\n"); 149 exit(1); 150 } 151 size = frags * sblock.fs_fsize / 1024; 152 if (cflg) { 153 if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG) 154 return; 155 if (size >= TSIZE) { 156 overflow += size; 157 size = TSIZE-1; 158 } 159 sizes[size]++; 160 return; 161 } 162 if (ip->di_uid >= NUID) 163 return; 164 du[ip->di_uid].blocks += size; 165 #define DAY (60 * 60 * 24) /* seconds per day */ 166 if (now - ip->di_atime > 30 * DAY) 167 du[ip->di_uid].blocks30 += size; 168 if (now - ip->di_atime > 60 * DAY) 169 du[ip->di_uid].blocks60 += size; 170 if (now - ip->di_atime > 90 * DAY) 171 du[ip->di_uid].blocks90 += size; 172 du[ip->di_uid].nfiles++; 173 if (nflg) { 174 tryagain: 175 if (fino==0) 176 if (scanf("%d", &fino)<=0) 177 return; 178 if (fino > ino) 179 return; 180 if (fino<ino) { 181 while ((n=getchar())!='\n' && n!=EOF) 182 ; 183 fino = 0; 184 goto tryagain; 185 } 186 if (np = du[ip->di_uid].name) 187 printf("%.7s ", np); 188 else 189 printf("%d ", ip->di_uid); 190 while ((n = getchar())==' ' || n=='\t') 191 ; 192 putchar(n); 193 while (n!=EOF && n!='\n') { 194 n = getchar(); 195 putchar(n); 196 } 197 fino = 0; 198 } 199 } 200 201 bread(bno, buf, cnt) 202 unsigned bno; 203 char *buf; 204 { 205 206 lseek(fi, (long)bno*DEV_BSIZE, 0); 207 if (read(fi, buf, cnt) != cnt) { 208 printf("read error %u\n", bno); 209 exit(1); 210 } 211 } 212 213 qcmp(p1, p2) 214 register struct du *p1, *p2; 215 { 216 if (p1->blocks > p2->blocks) 217 return(-1); 218 if (p1->blocks < p2->blocks) 219 return(1); 220 if (p1->name == 0 || p2->name == 0) 221 return(0); /* doesn't matter */ 222 return(strcmp(p1->name, p2->name)); 223 } 224 225 report() 226 { 227 register i; 228 229 if (nflg) 230 return; 231 if (cflg) { 232 long t = 0; 233 for (i=0; i<TSIZE-1; i++) 234 if (sizes[i]) { 235 t += i*sizes[i]; 236 printf("%d %d %D\n", i, sizes[i], t); 237 } 238 printf("%d %d %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t); 239 return; 240 } 241 qsort(du, NUID, sizeof(du[0]), qcmp); 242 for (i=0; i<NUID; i++) { 243 if (du[i].blocks==0) 244 return; 245 printf("%5D\t", du[i].blocks); 246 if (fflg) 247 printf("%5D\t", du[i].nfiles); 248 if (du[i].name) 249 printf("%-8.8s", du[i].name); 250 else 251 printf("#%-8d", du[i].uid); 252 if (vflg) 253 printf("\t%5D\t%5D\t%5D", 254 du[i].blocks30, du[i].blocks60, du[i].blocks90); 255 printf("\n"); 256 } 257 } 258 259 char * 260 copy(s) 261 char *s; 262 { 263 register char *p; 264 register n; 265 266 for(n=0; s[n]; n++) 267 ; 268 p = malloc((unsigned)n+1); 269 for(n=0; p[n] = s[n]; n++) 270 ; 271 return(p); 272 } 273