1 static char *sccsid = "@(#)quot.c 4.1 (Berkeley) 10/01/80"; 2 /* 3 * Disk usage by user 4 */ 5 6 char *dargv[] = { 7 "/dev/rrp3", 8 0 9 }; 10 11 #include <stdio.h> 12 #include <ctype.h> 13 #include <pwd.h> 14 #include <sys/param.h> 15 #include <sys/ino.h> 16 #include <sys/inode.h> 17 #include <sys/filsys.h> 18 19 #define ITABSZ 256 20 #define ISIZ (BSIZE/sizeof(struct dinode)) 21 #define NUID 1000 22 struct filsys sblock; 23 struct dinode itab[ITABSZ]; 24 struct du 25 { 26 long blocks; 27 long nfiles; 28 int uid; 29 char *name; 30 } du[NUID]; 31 #define TSIZE 500 32 int sizes[TSIZE]; 33 long overflow; 34 35 int nflg; 36 int fflg; 37 int cflg; 38 39 int fi; 40 unsigned ino; 41 unsigned nfiles; 42 43 struct passwd *getpwent(); 44 char *malloc(); 45 char *copy(); 46 47 main(argc, argv) 48 char **argv; 49 { 50 register int n; 51 register struct passwd *lp; 52 register char **p; 53 54 for(n=0; n<NUID; n++) 55 du[n].uid = n; 56 while((lp=getpwent()) != 0) { 57 n = lp->pw_uid; 58 if (n>NUID) 59 continue; 60 if(du[n].name) 61 continue; 62 du[n].name = copy(lp->pw_name); 63 } 64 if (argc == 1) { 65 for (p = dargv; *p;) { 66 check(*p++); 67 report(); 68 } 69 return(0); 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 { 81 check(*argv); 82 report(); 83 } 84 } 85 return(0); 86 } 87 88 check(file) 89 char *file; 90 { 91 register unsigned i, j; 92 register c; 93 94 fi = open(file, 0); 95 if (fi < 0) { 96 printf("cannot open %s\n", file); 97 return; 98 } 99 printf("%s:\n", file); 100 sync(); 101 bread(1, (char *)&sblock, sizeof sblock); 102 nfiles = (sblock.s_isize-2)*(BSIZE/sizeof(struct dinode)); 103 ino = 0; 104 if (nflg) { 105 if (isdigit(c = getchar())) 106 ungetc(c, stdin); 107 else while (c!='\n' && c != EOF) 108 c = getchar(); 109 } 110 for(i=2; ino<nfiles; i += ITABSZ/ISIZ) { 111 bread(i, (char *)itab, sizeof itab); 112 for (j=0; j<ITABSZ && ino<nfiles; j++) { 113 ino++; 114 acct(&itab[j]); 115 } 116 } 117 } 118 119 acct(ip) 120 register struct dinode *ip; 121 { 122 register n; 123 register char *np; 124 static fino; 125 126 if ((ip->di_mode&IFMT) == 0) 127 return; 128 if (cflg) { 129 if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG) 130 return; 131 n = (ip->di_size+BSIZE-1)/BSIZE; 132 if (n >= TSIZE) { 133 overflow += n; 134 n = TSIZE-1; 135 } 136 sizes[n]++; 137 return; 138 } 139 if (ip->di_uid >= NUID) 140 return; 141 du[ip->di_uid].blocks += (ip->di_size+BSIZE-1)/BSIZE; 142 du[ip->di_uid].nfiles++; 143 if (nflg) { 144 tryagain: 145 if (fino==0) 146 if (scanf("%d", &fino)<=0) 147 return; 148 if (fino > ino) 149 return; 150 if (fino<ino) { 151 while ((n=getchar())!='\n' && n!=EOF) 152 ; 153 fino = 0; 154 goto tryagain; 155 } 156 if (np = du[ip->di_uid].name) 157 printf("%.7s ", np); 158 else 159 printf("%d ", ip->di_uid); 160 while ((n = getchar())==' ' || n=='\t') 161 ; 162 putchar(n); 163 while (n!=EOF && n!='\n') { 164 n = getchar(); 165 putchar(n); 166 } 167 fino = 0; 168 } 169 } 170 171 bread(bno, buf, cnt) 172 unsigned bno; 173 char *buf; 174 { 175 176 lseek(fi, (long)bno*BSIZE, 0); 177 if (read(fi, buf, cnt) != cnt) { 178 printf("read error %u\n", bno); 179 exit(1); 180 } 181 } 182 183 qcmp(p1, p2) 184 register struct du *p1, *p2; 185 { 186 if (p1->blocks > p2->blocks) 187 return(-1); 188 if (p1->blocks < p2->blocks) 189 return(1); 190 return(strcmp(p1->name, p2->name)); 191 } 192 193 report() 194 { 195 register i; 196 197 if (nflg) 198 return; 199 if (cflg) { 200 long t = 0; 201 for (i=0; i<TSIZE-1; i++) 202 if (sizes[i]) { 203 t += i*sizes[i]; 204 printf("%d %d %D\n", i, sizes[i], t); 205 } 206 printf("%d %d %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t); 207 return; 208 } 209 qsort(du, NUID, sizeof(du[0]), qcmp); 210 for (i=0; i<NUID; i++) { 211 if (du[i].blocks==0) 212 return; 213 printf("%5D\t", du[i].blocks); 214 if (fflg) 215 printf("%5D\t", du[i].nfiles); 216 if (du[i].name) 217 printf("%s\n", du[i].name); 218 else 219 printf("#%d\n", du[i].uid); 220 } 221 } 222 223 char * 224 copy(s) 225 char *s; 226 { 227 register char *p; 228 register n; 229 230 for(n=0; s[n]; n++) 231 ; 232 p = malloc((unsigned)n+1); 233 for(n=0; p[n] = s[n]; n++) 234 ; 235 return(p); 236 } 237