|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)quot.c 4.14 (Berkeley) 88/04/18"; ! 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: extern char *optarg; ! 60: extern int optind; ! 61: int ch; ! 62: time_t time(); ! 63: ! 64: while ((ch = getopt(argc, argv, "cfhnv")) != EOF) ! 65: switch((char)ch) { ! 66: case 'c': ! 67: cflg++; break; ! 68: case 'f': ! 69: fflg++; break; ! 70: case 'h': /* undocumented */ ! 71: hflg++; break; ! 72: case 'n': ! 73: nflg++; break; ! 74: case 'v': /* undocumented */ ! 75: vflg++; break; ! 76: case '?': ! 77: default: ! 78: fputs("usage: quot [-cfn] [filesystem ...]\n", stderr); ! 79: exit(1); ! 80: } ! 81: argc -= optind; ! 82: argv += optind; ! 83: ! 84: (void)time(&now); ! 85: if (argc) ! 86: for (; *argv; ++argv) { ! 87: if (check(*argv, (char *)NULL) == 0) ! 88: report(); ! 89: } ! 90: else ! 91: quotall(); ! 92: exit(0); ! 93: } ! 94: ! 95: #include <sys/dir.h> ! 96: #include <fstab.h> ! 97: ! 98: quotall() ! 99: { ! 100: register struct fstab *fs; ! 101: register char *cp; ! 102: char dev[MAXNAMLEN + 10], *rindex(); ! 103: ! 104: while (fs = getfsent()) { ! 105: if (strcmp(fs->fs_type, FSTAB_RO) && ! 106: strcmp(fs->fs_type, FSTAB_RW) && ! 107: strcmp(fs->fs_type, FSTAB_RQ)) ! 108: continue; ! 109: cp = rindex(fs->fs_spec, '/'); ! 110: if (cp == 0) ! 111: continue; ! 112: (void)sprintf(dev, "/dev/r%s", cp + 1); ! 113: if (check(dev, fs->fs_file) == 0) ! 114: report(); ! 115: } ! 116: } ! 117: ! 118: check(file, fsdir) ! 119: char *file; ! 120: char *fsdir; ! 121: { ! 122: register int i, j, nfiles; ! 123: register struct du **dp; ! 124: daddr_t iblk; ! 125: long dev_bsize; ! 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", file); ! 146: if (fsdir == NULL) { ! 147: register struct fstab *fs = getfsspec(file); ! 148: if (fs != NULL) ! 149: fsdir = fs->fs_file; ! 150: } ! 151: if (fsdir != NULL && *fsdir != '\0') ! 152: printf(" (%s)", fsdir); ! 153: printf(":\n"); ! 154: sync(); ! 155: bread(fd, (long)SBOFF, (char *)&sblock, SBSIZE); ! 156: dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); ! 157: if (nflg) { ! 158: if (isdigit(c = getchar())) ! 159: (void)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 * dev_bsize, (char *)itab, (int)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\t", np); ! 253: else ! 254: printf("%u\t", 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: long bno; ! 269: char *buf; ! 270: { ! 271: off_t lseek(); ! 272: ! 273: (void)lseek(fd, bno, L_SET); ! 274: if (read(fd, buf, cnt) != cnt) { ! 275: fprintf(stderr, "quot: read error at block %ld\n", bno); ! 276: exit(1); ! 277: } ! 278: } ! 279: ! 280: qcmp(p1, p2) ! 281: register struct du *p1, *p2; ! 282: { ! 283: char *s1, *s2; ! 284: ! 285: if (p1->blocks > p2->blocks) ! 286: return (-1); ! 287: if (p1->blocks < p2->blocks) ! 288: return (1); ! 289: s1 = getname(p1->uid); ! 290: if (s1 == 0) ! 291: return (0); ! 292: s2 = getname(p2->uid); ! 293: if (s2 == 0) ! 294: return (0); ! 295: return (strcmp(s1, s2)); ! 296: } ! 297: ! 298: report() ! 299: { ! 300: register i; ! 301: register struct du *dp; ! 302: ! 303: if (nflg) ! 304: return; ! 305: if (cflg) { ! 306: register long t = 0; ! 307: ! 308: for (i = 0; i < TSIZE - 1; i++) ! 309: if (sizes[i]) { ! 310: t += i*sizes[i]; ! 311: printf("%d\t%d\t%ld\n", i, sizes[i], t); ! 312: } ! 313: printf("%d\t%d\t%ld\n", ! 314: TSIZE - 1, sizes[TSIZE - 1], overflow + t); ! 315: return; ! 316: } ! 317: qsort(du, ndu, sizeof (du[0]), qcmp); ! 318: for (dp = du; dp < &du[ndu]; dp++) { ! 319: register char *cp; ! 320: ! 321: if (dp->blocks == 0) ! 322: return; ! 323: printf("%5D\t", dp->blocks); ! 324: if (fflg) ! 325: printf("%5D\t", dp->nfiles); ! 326: if (cp = getname(dp->uid)) ! 327: printf("%-8.8s", cp); ! 328: else ! 329: printf("#%-8d", dp->uid); ! 330: if (vflg) ! 331: printf("\t%5D\t%5D\t%5D", ! 332: dp->blocks30, dp->blocks60, dp->blocks90); ! 333: printf("\n"); ! 334: } ! 335: } ! 336: ! 337: /* rest should be done with nameserver or database */ ! 338: ! 339: #include <pwd.h> ! 340: #include <grp.h> ! 341: #include <utmp.h> ! 342: ! 343: struct utmp utmp; ! 344: #define NMAX (sizeof (utmp.ut_name)) ! 345: #define SCPYN(a, b) strncpy(a, b, NMAX) ! 346: ! 347: #define NUID 64 /* power of 2 */ ! 348: #define UIDMASK 0x3f ! 349: ! 350: struct ncache { ! 351: int uid; ! 352: char name[NMAX+1]; ! 353: } nc[NUID]; ! 354: ! 355: char * ! 356: getname(uid) ! 357: { ! 358: register struct passwd *pw; ! 359: struct passwd *getpwent(); ! 360: extern int _pw_stayopen; ! 361: register int cp; ! 362: ! 363: _pw_stayopen = 1; ! 364: cp = uid & UIDMASK; ! 365: if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0]) ! 366: return (nc[cp].name); ! 367: pw = getpwuid(uid); ! 368: if (!pw) ! 369: return (0); ! 370: nc[cp].uid = uid; ! 371: SCPYN(nc[cp].name, pw->pw_name); ! 372: return (nc[cp].name); ! 373: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.