|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)quot.c 4.9 (Berkeley) 83/09/22"; ! 3: #endif ! 4: ! 5: /* ! 6: * quot ! 7: */ ! 8: ! 9: #include <stdio.h> ! 10: #include <ctype.h> ! 11: #include <sys/param.h> ! 12: #include <sys/inode.h> ! 13: #include <sys/fs.h> ! 14: #include <sys/file.h> ! 15: ! 16: #define ISIZ (MAXBSIZE/sizeof(struct dinode)) ! 17: union { ! 18: struct fs u_sblock; ! 19: char dummy[SBSIZE]; ! 20: } sb_un; ! 21: #define sblock sb_un.u_sblock ! 22: struct dinode itab[MAXBSIZE/sizeof(struct dinode)]; ! 23: ! 24: struct du { ! 25: struct du *next; ! 26: long blocks; ! 27: long blocks30; ! 28: long blocks60; ! 29: long blocks90; ! 30: long nfiles; ! 31: int uid; ! 32: #define NDU 2048 ! 33: } du[NDU]; ! 34: int ndu; ! 35: #define DUHASH 8209 /* smallest prime >= 4 * NDU */ ! 36: #define HASH(u) ((u) % DUHASH) ! 37: struct du *duhash[DUHASH]; ! 38: ! 39: #define TSIZE 500 ! 40: int sizes[TSIZE]; ! 41: long overflow; ! 42: ! 43: int nflg; ! 44: int fflg; ! 45: int cflg; ! 46: int vflg; ! 47: int hflg; ! 48: long now; ! 49: ! 50: unsigned ino; ! 51: ! 52: char *malloc(); ! 53: char *getname(); ! 54: ! 55: main(argc, argv) ! 56: int argc; ! 57: char *argv[]; ! 58: { ! 59: register int n; ! 60: ! 61: now = time(0); ! 62: argc--, argv++; ! 63: while (argc > 0 && argv[0][0] == '-') { ! 64: register char *cp; ! 65: ! 66: for (cp = &argv[0][1]; *cp; cp++) ! 67: switch (*cp) { ! 68: case 'n': ! 69: nflg++; break; ! 70: case 'f': ! 71: fflg++; break; ! 72: case 'c': ! 73: cflg++; break; ! 74: case 'v': ! 75: vflg++; break; ! 76: case 'h': ! 77: hflg++; break; ! 78: default: ! 79: fprintf(stderr, ! 80: "usage: quot [ -nfcvh ] [ device ... ]\n"); ! 81: exit(1); ! 82: } ! 83: argc--, argv++; ! 84: } ! 85: if (argc == 0) ! 86: quotall(); ! 87: while (argc-- > 0) ! 88: if (check(*argv++) == 0) ! 89: report(); ! 90: exit (0); ! 91: } ! 92: ! 93: #include <fstab.h> ! 94: ! 95: quotall() ! 96: { ! 97: register struct fstab *fs; ! 98: register char *cp; ! 99: char dev[80], *rindex(); ! 100: ! 101: if (setfsent() == 0) { ! 102: fprintf(stderr, "quot: no %s file\n", FSTAB); ! 103: exit(1); ! 104: } ! 105: while (fs = getfsent()) { ! 106: if (strcmp(fs->fs_type, FSTAB_RO) && ! 107: strcmp(fs->fs_type, FSTAB_RW) && ! 108: strcmp(fs->fs_type, FSTAB_RQ)) ! 109: continue; ! 110: cp = rindex(fs->fs_spec, '/'); ! 111: if (cp == 0) ! 112: continue; ! 113: sprintf(dev, "/dev/r%s", cp + 1); ! 114: if (check(dev) == 0) ! 115: report(); ! 116: } ! 117: endfsent(); ! 118: } ! 119: ! 120: check(file) ! 121: char *file; ! 122: { ! 123: register int i, j, nfiles; ! 124: register struct du **dp; ! 125: daddr_t iblk; ! 126: int c, fd; ! 127: ! 128: /* ! 129: * Initialize tables between checks; ! 130: * because of the qsort done in report() ! 131: * the hash tables must be rebuilt each time. ! 132: */ ! 133: for (i = 0; i < TSIZE; i++) ! 134: sizes[i] = 0; ! 135: overflow = 0; ! 136: for (dp = duhash; dp < &duhash[DUHASH]; dp++) ! 137: *dp = 0; ! 138: ndu = 0; ! 139: fd = open(file, O_RDONLY); ! 140: if (fd < 0) { ! 141: fprintf(stderr, "quot: "); ! 142: perror(file); ! 143: return (-1); ! 144: } ! 145: printf("%s:\n", file); ! 146: sync(); ! 147: bread(fd, SBLOCK, (char *)&sblock, SBSIZE); ! 148: if (nflg) { ! 149: if (isdigit(c = getchar())) ! 150: ungetc(c, stdin); ! 151: else while (c != '\n' && c != EOF) ! 152: c = getchar(); ! 153: } ! 154: nfiles = sblock.fs_ipg * sblock.fs_ncg; ! 155: for (ino = 0; ino < nfiles; ) { ! 156: iblk = fsbtodb(&sblock, itod(&sblock, ino)); ! 157: bread(fd, iblk, (char *)itab, sblock.fs_bsize); ! 158: for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) { ! 159: if (ino < ROOTINO) ! 160: continue; ! 161: acct(&itab[j]); ! 162: } ! 163: } ! 164: close(fd); ! 165: } ! 166: ! 167: acct(ip) ! 168: register struct dinode *ip; ! 169: { ! 170: register struct du *dp; ! 171: struct du **hp; ! 172: long blks, frags, size; ! 173: char n; ! 174: static fino; ! 175: ! 176: if ((ip->di_mode & IFMT) == 0) ! 177: return; ! 178: /* ! 179: * By default, take block count in inode. Otherwise (-h), ! 180: * take the size field and estimate the blocks allocated. ! 181: * The latter does not account for holes in files. ! 182: */ ! 183: if (!hflg) ! 184: size = ip->di_blocks / 2; ! 185: else { ! 186: blks = lblkno(&sblock, ip->di_size); ! 187: frags = blks * sblock.fs_frag + ! 188: numfrags(&sblock, dblksize(&sblock, ip, blks)); ! 189: size = frags * sblock.fs_fsize / 1024; ! 190: } ! 191: if (cflg) { ! 192: if ((ip->di_mode&IFMT) != IFDIR && (ip->di_mode&IFMT) != IFREG) ! 193: return; ! 194: if (size >= TSIZE) { ! 195: overflow += size; ! 196: size = TSIZE-1; ! 197: } ! 198: sizes[size]++; ! 199: return; ! 200: } ! 201: hp = &duhash[HASH(ip->di_uid)]; ! 202: for (dp = *hp; dp; dp = dp->next) ! 203: if (dp->uid == ip->di_uid) ! 204: break; ! 205: if (dp == 0) { ! 206: if (ndu >= NDU) ! 207: return; ! 208: dp = &du[ndu++]; ! 209: dp->next = *hp; ! 210: *hp = dp; ! 211: dp->uid = ip->di_uid; ! 212: dp->nfiles = 0; ! 213: dp->blocks = 0; ! 214: dp->blocks30 = 0; ! 215: dp->blocks60 = 0; ! 216: dp->blocks90 = 0; ! 217: } ! 218: dp->blocks += size; ! 219: #define DAY (60 * 60 * 24) /* seconds per day */ ! 220: if (now - ip->di_atime > 30 * DAY) ! 221: dp->blocks30 += size; ! 222: if (now - ip->di_atime > 60 * DAY) ! 223: dp->blocks60 += size; ! 224: if (now - ip->di_atime > 90 * DAY) ! 225: dp->blocks90 += size; ! 226: dp->nfiles++; ! 227: while (nflg) { ! 228: register char *np; ! 229: ! 230: if (fino == 0) ! 231: if (scanf("%d", &fino) <= 0) ! 232: return; ! 233: if (fino > ino) ! 234: return; ! 235: if (fino < ino) { ! 236: while ((n = getchar()) != '\n' && n != EOF) ! 237: ; ! 238: fino = 0; ! 239: continue; ! 240: } ! 241: if (np = getname(dp->uid)) ! 242: printf("%.7s ", np); ! 243: else ! 244: printf("%d ", ip->di_uid); ! 245: while ((n = getchar()) == ' ' || n == '\t') ! 246: ; ! 247: putchar(n); ! 248: while (n != EOF && n != '\n') { ! 249: n = getchar(); ! 250: putchar(n); ! 251: } ! 252: fino = 0; ! 253: break; ! 254: } ! 255: } ! 256: ! 257: bread(fd, bno, buf, cnt) ! 258: unsigned bno; ! 259: char *buf; ! 260: { ! 261: ! 262: lseek(fd, (long)bno * DEV_BSIZE, L_SET); ! 263: if (read(fd, buf, cnt) != cnt) { ! 264: fprintf(stderr, "quot: read error at block %u\n", bno); ! 265: exit(1); ! 266: } ! 267: } ! 268: ! 269: qcmp(p1, p2) ! 270: register struct du *p1, *p2; ! 271: { ! 272: char *s1, *s2; ! 273: ! 274: if (p1->blocks > p2->blocks) ! 275: return (-1); ! 276: if (p1->blocks < p2->blocks) ! 277: return (1); ! 278: s1 = getname(p1->uid); ! 279: if (s1 == 0) ! 280: return (0); ! 281: s2 = getname(p2->uid); ! 282: if (s2 == 0) ! 283: return (0); ! 284: return (strcmp(s1, s2)); ! 285: } ! 286: ! 287: report() ! 288: { ! 289: register i; ! 290: register struct du *dp; ! 291: ! 292: if (nflg) ! 293: return; ! 294: if (cflg) { ! 295: register long t = 0; ! 296: ! 297: for (i = 0; i < TSIZE - 1; i++) ! 298: if (sizes[i]) { ! 299: t += i*sizes[i]; ! 300: printf("%d %d %D\n", i, sizes[i], t); ! 301: } ! 302: printf("%d %d %D\n", ! 303: TSIZE - 1, sizes[TSIZE - 1], overflow + t); ! 304: return; ! 305: } ! 306: qsort(du, ndu, sizeof (du[0]), qcmp); ! 307: for (dp = du; dp < &du[ndu]; dp++) { ! 308: register char *cp; ! 309: ! 310: if (dp->blocks == 0) ! 311: return; ! 312: printf("%5D\t", dp->blocks); ! 313: if (fflg) ! 314: printf("%5D\t", dp->nfiles); ! 315: if (cp = getname(dp->uid)) ! 316: printf("%-8.8s", cp); ! 317: else ! 318: printf("#%-8d", dp->uid); ! 319: if (vflg) ! 320: printf("\t%5D\t%5D\t%5D", ! 321: dp->blocks30, dp->blocks60, dp->blocks90); ! 322: printf("\n"); ! 323: } ! 324: } ! 325: ! 326: #include <pwd.h> ! 327: #include <utmp.h> ! 328: ! 329: struct utmp utmp; ! 330: ! 331: #define NUID 2048 ! 332: #define NMAX (sizeof (utmp.ut_name)) ! 333: ! 334: char names[NUID][NMAX+1]; ! 335: char outrangename[NMAX+1]; ! 336: int outrangeuid = -1; ! 337: ! 338: char * ! 339: getname(uid) ! 340: int uid; ! 341: { ! 342: register struct passwd *pw; ! 343: static init; ! 344: struct passwd *getpwent(); ! 345: ! 346: if (uid >= 0 && uid < NUID && names[uid][0]) ! 347: return (&names[uid][0]); ! 348: if (uid >= 0 && uid == outrangeuid) ! 349: return (outrangename); ! 350: rescan: ! 351: if (init == 2) { ! 352: if (uid < NUID) ! 353: return (0); ! 354: setpwent(); ! 355: while (pw = getpwent()) { ! 356: if (pw->pw_uid != uid) ! 357: continue; ! 358: outrangeuid = pw->pw_uid; ! 359: strncpy(outrangename, pw->pw_name, NMAX); ! 360: endpwent(); ! 361: return (outrangename); ! 362: } ! 363: endpwent(); ! 364: return (0); ! 365: } ! 366: if (init == 0) ! 367: setpwent(), init = 1; ! 368: while (pw = getpwent()) { ! 369: if (pw->pw_uid < 0 || pw->pw_uid >= NUID) { ! 370: if (pw->pw_uid == uid) { ! 371: outrangeuid = pw->pw_uid; ! 372: strncpy(outrangename, pw->pw_name, NMAX); ! 373: return (outrangename); ! 374: } ! 375: continue; ! 376: } ! 377: if (names[pw->pw_uid][0]) ! 378: continue; ! 379: strncpy(names[pw->pw_uid], pw->pw_name, NMAX); ! 380: if (pw->pw_uid == uid) ! 381: return (&names[uid][0]); ! 382: } ! 383: init = 2; ! 384: goto rescan; ! 385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.