Annotation of 42BSD/etc/quot.c, revision 1.1.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.