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