|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)quot.c 4.11 (Berkeley) 85/09/09"; ! 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++, (char *)NULL) == 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, fs->fs_file) == 0) ! 115: report(); ! 116: } ! 117: endfsent(); ! 118: } ! 119: ! 120: check(file, fsdir) ! 121: char *file; ! 122: char *fsdir; ! 123: { ! 124: register int i, j, nfiles; ! 125: register struct du **dp; ! 126: daddr_t iblk; ! 127: int c, fd; ! 128: ! 129: /* ! 130: * Initialize tables between checks; ! 131: * because of the qsort done in report() ! 132: * the hash tables must be rebuilt each time. ! 133: */ ! 134: for (i = 0; i < TSIZE; i++) ! 135: sizes[i] = 0; ! 136: overflow = 0; ! 137: for (dp = duhash; dp < &duhash[DUHASH]; dp++) ! 138: *dp = 0; ! 139: ndu = 0; ! 140: fd = open(file, O_RDONLY); ! 141: if (fd < 0) { ! 142: fprintf(stderr, "quot: "); ! 143: perror(file); ! 144: return (-1); ! 145: } ! 146: printf("%s", file); ! 147: if (fsdir == NULL) { ! 148: register struct fstab *fs = getfsspec(file); ! 149: if (fs != NULL) ! 150: fsdir = fs->fs_file; ! 151: } ! 152: if (fsdir != NULL && *fsdir != '\0') ! 153: printf(" (%s)", fsdir); ! 154: printf(":\n"); ! 155: sync(); ! 156: bread(fd, SBLOCK, (char *)&sblock, SBSIZE); ! 157: if (nflg) { ! 158: if (isdigit(c = getchar())) ! 159: ungetc(c, stdin); ! 160: else while (c != '\n' && c != EOF) ! 161: c = getchar(); ! 162: } ! 163: nfiles = sblock.fs_ipg * sblock.fs_ncg; ! 164: for (ino = 0; ino < nfiles; ) { ! 165: iblk = fsbtodb(&sblock, itod(&sblock, ino)); ! 166: bread(fd, iblk, (char *)itab, sblock.fs_bsize); ! 167: for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) { ! 168: if (ino < ROOTINO) ! 169: continue; ! 170: acct(&itab[j]); ! 171: } ! 172: } ! 173: close(fd); ! 174: return (0); ! 175: } ! 176: ! 177: acct(ip) ! 178: register struct dinode *ip; ! 179: { ! 180: register struct du *dp; ! 181: struct du **hp; ! 182: long blks, frags, size; ! 183: int n; ! 184: static fino; ! 185: ! 186: if ((ip->di_mode & IFMT) == 0) ! 187: return; ! 188: /* ! 189: * By default, take block count in inode. Otherwise (-h), ! 190: * take the size field and estimate the blocks allocated. ! 191: * The latter does not account for holes in files. ! 192: */ ! 193: if (!hflg) ! 194: size = ip->di_blocks / 2; ! 195: else { ! 196: blks = lblkno(&sblock, ip->di_size); ! 197: frags = blks * sblock.fs_frag + ! 198: numfrags(&sblock, dblksize(&sblock, ip, blks)); ! 199: size = frags * sblock.fs_fsize / 1024; ! 200: } ! 201: if (cflg) { ! 202: if ((ip->di_mode&IFMT) != IFDIR && (ip->di_mode&IFMT) != IFREG) ! 203: return; ! 204: if (size >= TSIZE) { ! 205: overflow += size; ! 206: size = TSIZE-1; ! 207: } ! 208: sizes[size]++; ! 209: return; ! 210: } ! 211: hp = &duhash[HASH(ip->di_uid)]; ! 212: for (dp = *hp; dp; dp = dp->next) ! 213: if (dp->uid == ip->di_uid) ! 214: break; ! 215: if (dp == 0) { ! 216: if (ndu >= NDU) ! 217: return; ! 218: dp = &du[ndu++]; ! 219: dp->next = *hp; ! 220: *hp = dp; ! 221: dp->uid = ip->di_uid; ! 222: dp->nfiles = 0; ! 223: dp->blocks = 0; ! 224: dp->blocks30 = 0; ! 225: dp->blocks60 = 0; ! 226: dp->blocks90 = 0; ! 227: } ! 228: dp->blocks += size; ! 229: #define DAY (60 * 60 * 24) /* seconds per day */ ! 230: if (now - ip->di_atime > 30 * DAY) ! 231: dp->blocks30 += size; ! 232: if (now - ip->di_atime > 60 * DAY) ! 233: dp->blocks60 += size; ! 234: if (now - ip->di_atime > 90 * DAY) ! 235: dp->blocks90 += size; ! 236: dp->nfiles++; ! 237: while (nflg) { ! 238: register char *np; ! 239: ! 240: if (fino == 0) ! 241: if (scanf("%d", &fino) <= 0) ! 242: return; ! 243: if (fino > ino) ! 244: return; ! 245: if (fino < ino) { ! 246: while ((n = getchar()) != '\n' && n != EOF) ! 247: ; ! 248: fino = 0; ! 249: continue; ! 250: } ! 251: if (np = getname(dp->uid)) ! 252: printf("%.7s ", np); ! 253: else ! 254: printf("%d ", ip->di_uid); ! 255: while ((n = getchar()) == ' ' || n == '\t') ! 256: ; ! 257: putchar(n); ! 258: while (n != EOF && n != '\n') { ! 259: n = getchar(); ! 260: putchar(n); ! 261: } ! 262: fino = 0; ! 263: break; ! 264: } ! 265: } ! 266: ! 267: bread(fd, bno, buf, cnt) ! 268: unsigned bno; ! 269: char *buf; ! 270: { ! 271: ! 272: lseek(fd, (long)bno * DEV_BSIZE, L_SET); ! 273: if (read(fd, buf, cnt) != cnt) { ! 274: fprintf(stderr, "quot: read error at block %u\n", bno); ! 275: exit(1); ! 276: } ! 277: } ! 278: ! 279: qcmp(p1, p2) ! 280: register struct du *p1, *p2; ! 281: { ! 282: char *s1, *s2; ! 283: ! 284: if (p1->blocks > p2->blocks) ! 285: return (-1); ! 286: if (p1->blocks < p2->blocks) ! 287: return (1); ! 288: s1 = getname(p1->uid); ! 289: if (s1 == 0) ! 290: return (0); ! 291: s2 = getname(p2->uid); ! 292: if (s2 == 0) ! 293: return (0); ! 294: return (strcmp(s1, s2)); ! 295: } ! 296: ! 297: report() ! 298: { ! 299: register i; ! 300: register struct du *dp; ! 301: ! 302: if (nflg) ! 303: return; ! 304: if (cflg) { ! 305: register long t = 0; ! 306: ! 307: for (i = 0; i < TSIZE - 1; i++) ! 308: if (sizes[i]) { ! 309: t += i*sizes[i]; ! 310: printf("%d %d %D\n", i, sizes[i], t); ! 311: } ! 312: printf("%d %d %D\n", ! 313: TSIZE - 1, sizes[TSIZE - 1], overflow + t); ! 314: return; ! 315: } ! 316: qsort(du, ndu, sizeof (du[0]), qcmp); ! 317: for (dp = du; dp < &du[ndu]; dp++) { ! 318: register char *cp; ! 319: ! 320: if (dp->blocks == 0) ! 321: return; ! 322: printf("%5D\t", dp->blocks); ! 323: if (fflg) ! 324: printf("%5D\t", dp->nfiles); ! 325: if (cp = getname(dp->uid)) ! 326: printf("%-8.8s", cp); ! 327: else ! 328: printf("#%-8d", dp->uid); ! 329: if (vflg) ! 330: printf("\t%5D\t%5D\t%5D", ! 331: dp->blocks30, dp->blocks60, dp->blocks90); ! 332: printf("\n"); ! 333: } ! 334: } ! 335: ! 336: /* rest should be done with nameserver or database */ ! 337: ! 338: #include <pwd.h> ! 339: #include <grp.h> ! 340: #include <utmp.h> ! 341: ! 342: struct utmp utmp; ! 343: #define NMAX (sizeof (utmp.ut_name)) ! 344: #define SCPYN(a, b) strncpy(a, b, NMAX) ! 345: ! 346: #define NUID 64 /* power of 2 */ ! 347: #define UIDMASK 0x3f ! 348: ! 349: struct ncache { ! 350: int uid; ! 351: char name[NMAX+1]; ! 352: } nc[NUID]; ! 353: char outrangename[NMAX+1]; ! 354: int outrangeuid = -1; ! 355: ! 356: char * ! 357: getname(uid) ! 358: { ! 359: register struct passwd *pw; ! 360: struct passwd *getpwent(); ! 361: extern int _pw_stayopen; ! 362: register int cp; ! 363: ! 364: _pw_stayopen = 1; ! 365: cp = uid & UIDMASK; ! 366: if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0]) ! 367: return (nc[cp].name); ! 368: pw = getpwuid(uid); ! 369: if (!pw) ! 370: return (0); ! 371: nc[cp].uid = uid; ! 372: SCPYN(nc[cp].name, pw->pw_name); ! 373: return (nc[cp].name); ! 374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.