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