Annotation of 43BSDReno/usr.sbin/quot/quot.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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