Annotation of 42BSD/etc/quot.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.