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