Annotation of 43BSD/etc/quotacheck.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)quotacheck.c       5.6 (Berkeley) 11/3/85";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * Fix up / report on disc quotas & usage
        !            19:  */
        !            20: #include <stdio.h>
        !            21: #include <ctype.h>
        !            22: #include <signal.h>
        !            23: #include <errno.h>
        !            24: #include <sys/param.h>
        !            25: #include <sys/inode.h>
        !            26: #include <sys/fs.h>
        !            27: #include <sys/quota.h>
        !            28: #include <sys/stat.h>
        !            29: #include <sys/wait.h>
        !            30: #include <fstab.h>
        !            31: #include <pwd.h>
        !            32: 
        !            33: union {
        !            34:        struct  fs      sblk;
        !            35:        char    dummy[MAXBSIZE];
        !            36: } un;
        !            37: #define        sblock  un.sblk
        !            38: 
        !            39: #define        ITABSZ  256
        !            40: struct dinode  itab[ITABSZ];
        !            41: struct dinode  *dp;
        !            42: 
        !            43: #define LOGINNAMESIZE 8
        !            44: struct fileusage {
        !            45:        struct fileusage *fu_next;
        !            46:        struct dqusage fu_usage;
        !            47:        u_short fu_uid;
        !            48:        char fu_name[LOGINNAMESIZE + 1];
        !            49: };
        !            50: #define FUHASH 997
        !            51: struct fileusage *fuhead[FUHASH];
        !            52: struct fileusage *lookup();
        !            53: struct fileusage *adduid();
        !            54: int highuid;
        !            55: 
        !            56: int fi;
        !            57: ino_t ino;
        !            58: long done;
        !            59: struct passwd  *getpwent();
        !            60: struct dinode  *ginode();
        !            61: char *malloc(), *makerawname();
        !            62: 
        !            63: int    vflag;          /* verbose */
        !            64: int    aflag;          /* all file systems */
        !            65: int    pflag;          /* fsck like parallel check */
        !            66: 
        !            67: char *qfname = "quotas";
        !            68: char quotafile[MAXPATHLEN + 1];
        !            69: struct dqblk zerodqbuf;
        !            70: struct fileusage zerofileusage;
        !            71: 
        !            72: main(argc, argv)
        !            73:        int argc;
        !            74:        char **argv;
        !            75: {
        !            76:        register struct fstab *fs;
        !            77:        register struct fileusage *fup;
        !            78:        register struct passwd *pw;
        !            79:        int i, errs = 0;
        !            80: 
        !            81: again:
        !            82:        argc--, argv++;
        !            83:        if (argc > 0 && strcmp(*argv, "-v") == 0) {
        !            84:                vflag++;
        !            85:                goto again;
        !            86:        }
        !            87:        if (argc > 0 && strcmp(*argv, "-a") == 0) {
        !            88:                aflag++;
        !            89:                goto again;
        !            90:        }
        !            91:        if (argc > 0 && strcmp(*argv, "-p") == 0) {
        !            92:                pflag++;
        !            93:                goto again;
        !            94:        }
        !            95:        if (argc <= 0 && !aflag) {
        !            96:                fprintf(stderr, "Usage:\n\t%s\n\t%s\n",
        !            97:                        "quotacheck [-v] [-p] -a",
        !            98:                        "quotacheck [-v] [-p] filesys ...");
        !            99:                exit(1);
        !           100:        }
        !           101: 
        !           102:        setpwent();
        !           103:        while ((pw = getpwent()) != 0) {
        !           104:                fup = lookup(pw->pw_uid);
        !           105:                if (fup == 0) {
        !           106:                        fup = adduid(pw->pw_uid);
        !           107:                        strncpy(fup->fu_name, pw->pw_name,
        !           108:                                sizeof(fup->fu_name));
        !           109:                }
        !           110:        }
        !           111:        endpwent();
        !           112: 
        !           113:        if (pflag)
        !           114:                errs = preen(argc, argv);
        !           115:        else {
        !           116:                if (setfsent() == 0) {
        !           117:                        fprintf(stderr, "Can't open ");
        !           118:                        perror(FSTAB);
        !           119:                        exit(8);
        !           120:                }
        !           121:                while ((fs = getfsent()) != NULL) {
        !           122:                        if (aflag &&
        !           123:                            (fs->fs_type == 0 ||
        !           124:                             strcmp(fs->fs_type, FSTAB_RQ) != 0))
        !           125:                                continue;
        !           126:                        if (!aflag &&
        !           127:                            !(oneof(fs->fs_file, argv, argc) ||
        !           128:                              oneof(fs->fs_spec, argv, argc)))
        !           129:                                continue;
        !           130:                        (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
        !           131:                        errs += chkquota(fs->fs_spec, fs->fs_file, quotafile);
        !           132:                }
        !           133:                endfsent();
        !           134:        }
        !           135: 
        !           136:        for (i = 0; i < argc; i++)
        !           137:                if ((done & (1 << i)) == 0)
        !           138:                        fprintf(stderr, "%s not found in %s\n",
        !           139:                                argv[i], FSTAB);
        !           140:        exit(errs);
        !           141: }
        !           142: 
        !           143: preen(argc, argv)
        !           144:        int argc;
        !           145:        char **argv;
        !           146: {
        !           147:        register struct fstab *fs;
        !           148:        register int passno, anygtr;
        !           149:        register int errs;
        !           150:        union wait status;
        !           151: 
        !           152:        passno = 1;
        !           153:        errs = 0;
        !           154:        do {
        !           155:                anygtr = 0;
        !           156: 
        !           157:                if (setfsent() == 0) {
        !           158:                        fprintf(stderr, "Can't open ");
        !           159:                        perror(FSTAB);
        !           160:                        exit(8);
        !           161:                }
        !           162: 
        !           163:                while ((fs = getfsent()) != NULL) {
        !           164:                        if (fs->fs_passno > passno)
        !           165:                                anygtr = 1;
        !           166: 
        !           167:                        if (aflag &&
        !           168:                            (fs->fs_type == 0 ||
        !           169:                             strcmp(fs->fs_type, FSTAB_RQ) != 0))
        !           170:                                continue;
        !           171: 
        !           172:                        if (!aflag &&
        !           173:                            !(oneof(fs->fs_file, argv, argc) ||
        !           174:                              oneof(fs->fs_spec, argv, argc)))
        !           175:                                continue;
        !           176: 
        !           177:                        if (fs->fs_passno != passno)
        !           178:                                continue;
        !           179: 
        !           180:                        switch (fork()) {
        !           181:                        case -1:
        !           182:                                perror("fork");
        !           183:                                exit(8);
        !           184:                                break;
        !           185: 
        !           186:                        case 0:
        !           187:                                sprintf(quotafile, "%s/%s",
        !           188:                                        fs->fs_file, qfname);
        !           189:                                exit(chkquota(fs->fs_spec,
        !           190:                                        fs->fs_file, quotafile));
        !           191:                        }
        !           192:                }
        !           193: 
        !           194:                while (wait(&status) != -1) 
        !           195:                        errs += status.w_retcode;
        !           196: 
        !           197:                passno++;
        !           198:        } while (anygtr);
        !           199: 
        !           200:        return (errs);
        !           201: }
        !           202: 
        !           203: chkquota(fsdev, fsfile, qffile)
        !           204:        char *fsdev;
        !           205:        char *fsfile;
        !           206:        char *qffile;
        !           207: {
        !           208:        register struct fileusage *fup;
        !           209:        dev_t quotadev;
        !           210:        register FILE *qfi, *qfo;
        !           211:        u_short uid;
        !           212:        int cg, i, fdo;
        !           213:        char *rawdisk;
        !           214:        struct stat statb;
        !           215:        struct dqblk dqbuf;
        !           216:        static int warned = 0;
        !           217:        extern int errno;
        !           218: 
        !           219:        rawdisk = makerawname(fsdev);
        !           220:        if (vflag)
        !           221:                fprintf(stdout, "*** Checking quotas for %s (%s)\n", rawdisk, fsfile);
        !           222:        fi = open(rawdisk, 0);
        !           223:        if (fi < 0) {
        !           224:                perror(rawdisk);
        !           225:                return (1);
        !           226:        }
        !           227:        qfi = fopen(qffile, "r");
        !           228:        if (qfi == NULL) {
        !           229:                perror(qffile);
        !           230:                close(fi);
        !           231:                return (1);
        !           232:        }
        !           233:        if (fstat(fileno(qfi), &statb) < 0) {
        !           234:                perror(qffile);
        !           235:                fclose(qfi);
        !           236:                close(fi);
        !           237:                return (1);
        !           238:        }
        !           239:        quotadev = statb.st_dev;
        !           240:        if (stat(fsdev, &statb) < 0) {
        !           241:                perror(fsdev);
        !           242:                fclose(qfi);
        !           243:                close(fi);
        !           244:                return (1);
        !           245:        }
        !           246:        if (quotadev != statb.st_rdev) {
        !           247:                fprintf(stderr, "%s dev (0x%x) mismatch %s dev (0x%x)\n",
        !           248:                        qffile, quotadev, fsdev, statb.st_rdev);
        !           249:                fclose(qfi);
        !           250:                close(fi);
        !           251:                return (1);
        !           252:        }
        !           253:        /*
        !           254:         * Must do fdopen(open(qffile, 1), "w") instead of fopen(qffile, "w")
        !           255:         * because fopen(qffile, "w") would truncate the quota file.
        !           256:         */
        !           257:        fdo = open(qffile, 1);
        !           258:        if (fdo < 0 || (qfo = fdopen(fdo, "w")) == NULL) {
        !           259:                perror(qffile);
        !           260:                if (fdo >= 0)
        !           261:                        close(fdo);
        !           262:                fclose(qfi);
        !           263:                close(fi);
        !           264:                return (1);
        !           265:        }
        !           266:        if (quota(Q_SYNC, 0, quotadev, (caddr_t)0) < 0 &&
        !           267:            errno == EINVAL && !warned && vflag) {
        !           268:                warned++;
        !           269:                fprintf(stdout,
        !           270:                    "*** Warning: Quotas are not compiled into this kernel\n");
        !           271:        }
        !           272:        sync();
        !           273:        bread(SBLOCK, (char *)&sblock, SBSIZE);
        !           274:        ino = 0;
        !           275:        for (cg = 0; cg < sblock.fs_ncg; cg++) {
        !           276:                dp = NULL;
        !           277:                for (i = 0; i < sblock.fs_ipg; i++)
        !           278:                        acct(ginode());
        !           279:        }
        !           280:        for (uid = 0; uid <= highuid; uid++) {
        !           281:                i = fread(&dqbuf, sizeof(struct dqblk), 1, qfi);
        !           282:                if (i == 0)
        !           283:                        dqbuf = zerodqbuf;
        !           284:                fup = lookup(uid);
        !           285:                if (fup == 0)
        !           286:                        fup = &zerofileusage;
        !           287:                if (dqbuf.dqb_curinodes == fup->fu_usage.du_curinodes &&
        !           288:                    dqbuf.dqb_curblocks == fup->fu_usage.du_curblocks) {
        !           289:                        fup->fu_usage.du_curinodes = 0;
        !           290:                        fup->fu_usage.du_curblocks = 0;
        !           291:                        fseek(qfo, (long)sizeof(struct dqblk), 1);
        !           292:                        continue;
        !           293:                }
        !           294:                if (vflag) {
        !           295:                        if (pflag)
        !           296:                                printf("%s: ", rawdisk);
        !           297:                        if (fup->fu_name[0] != '\0')
        !           298:                                printf("%-8s fixed:", fup->fu_name);
        !           299:                        else
        !           300:                                printf("#%-7d fixed:", uid);
        !           301:                        if (dqbuf.dqb_curinodes != fup->fu_usage.du_curinodes)
        !           302:                                fprintf(stdout, "\tinodes %d -> %d",
        !           303:                                        dqbuf.dqb_curinodes, fup->fu_usage.du_curinodes);
        !           304:                        if (dqbuf.dqb_curblocks != fup->fu_usage.du_curblocks)
        !           305:                                fprintf(stdout, "\tblocks %d -> %d",
        !           306:                                        dqbuf.dqb_curblocks, fup->fu_usage.du_curblocks);
        !           307:                        fprintf(stdout, "\n");
        !           308:                }
        !           309:                dqbuf.dqb_curinodes = fup->fu_usage.du_curinodes;
        !           310:                dqbuf.dqb_curblocks = fup->fu_usage.du_curblocks;
        !           311:                fwrite(&dqbuf, sizeof(struct dqblk), 1, qfo);
        !           312:                quota(Q_SETDUSE, uid, quotadev, &fup->fu_usage);
        !           313:                fup->fu_usage.du_curinodes = 0;
        !           314:                fup->fu_usage.du_curblocks = 0;
        !           315:        }
        !           316:        fflush(qfo);
        !           317:        ftruncate(fileno(qfo), (off_t)((highuid + 1) * sizeof(struct dqblk)));
        !           318:        fclose(qfi);
        !           319:        fclose(qfo);
        !           320:        close(fi);
        !           321:        return (0);
        !           322: }
        !           323: 
        !           324: acct(ip)
        !           325:        register struct dinode *ip;
        !           326: {
        !           327:        register struct fileusage *fup;
        !           328: 
        !           329:        if (ip == NULL)
        !           330:                return;
        !           331:        if (ip->di_mode == 0)
        !           332:                return;
        !           333:        fup = adduid(ip->di_uid);
        !           334:        fup->fu_usage.du_curinodes++;
        !           335:        if ((ip->di_mode & IFMT) == IFCHR || (ip->di_mode & IFMT) == IFBLK)
        !           336:                return;
        !           337:        fup->fu_usage.du_curblocks += ip->di_blocks;
        !           338: }
        !           339: 
        !           340: oneof(target, list, n)
        !           341:        char *target, *list[];
        !           342:        register int n;
        !           343: {
        !           344:        register int i;
        !           345: 
        !           346:        for (i = 0; i < n; i++)
        !           347:                if (strcmp(target, list[i]) == 0) {
        !           348:                        done |= 1 << i;
        !           349:                        return (1);
        !           350:                }
        !           351:        return (0);
        !           352: }
        !           353: 
        !           354: struct dinode *
        !           355: ginode()
        !           356: {
        !           357:        register unsigned long iblk;
        !           358: 
        !           359:        if (dp == NULL || ++dp >= &itab[ITABSZ]) {
        !           360:                iblk = itod(&sblock, ino);
        !           361:                bread(fsbtodb(&sblock, iblk), (char *)itab, sizeof itab);
        !           362:                dp = &itab[ino % INOPB(&sblock)];
        !           363:        }
        !           364:        if (ino++ < ROOTINO)
        !           365:                return(NULL);
        !           366:        return(dp);
        !           367: }
        !           368: 
        !           369: bread(bno, buf, cnt)
        !           370:        long unsigned bno;
        !           371:        char *buf;
        !           372: {
        !           373:        extern  off_t lseek();
        !           374:        register off_t pos;
        !           375: 
        !           376:        pos = (off_t)dbtob(bno);
        !           377:        if (lseek(fi, pos, 0) != pos) {
        !           378:                perror("lseek");
        !           379:                exit(1);
        !           380:        }
        !           381: 
        !           382:        if (read(fi, buf, cnt) != cnt) {
        !           383:                perror("read");
        !           384:                exit(1);
        !           385:        }
        !           386: }
        !           387: 
        !           388: struct fileusage *
        !           389: lookup(uid)
        !           390:        u_short uid;
        !           391: {
        !           392:        register struct fileusage *fup;
        !           393: 
        !           394:        for (fup = fuhead[uid % FUHASH]; fup != 0; fup = fup->fu_next)
        !           395:                if (fup->fu_uid == uid)
        !           396:                        return (fup);
        !           397:        return ((struct fileusage *)0);
        !           398: }
        !           399: 
        !           400: struct fileusage *
        !           401: adduid(uid)
        !           402:        u_short uid;
        !           403: {
        !           404:        struct fileusage *fup, **fhp;
        !           405:        extern char *calloc();
        !           406: 
        !           407:        fup = lookup(uid);
        !           408:        if (fup != 0)
        !           409:                return (fup);
        !           410:        fup = (struct fileusage *)calloc(1, sizeof(struct fileusage));
        !           411:        if (fup == 0) {
        !           412:                fprintf(stderr, "out of memory for fileusage structures\n");
        !           413:                exit(1);
        !           414:        }
        !           415:        fhp = &fuhead[uid % FUHASH];
        !           416:        fup->fu_next = *fhp;
        !           417:        *fhp = fup;
        !           418:        fup->fu_uid = uid;
        !           419:        if (uid > highuid)
        !           420:                highuid = uid;
        !           421:        return (fup);
        !           422: }
        !           423: 
        !           424: char *
        !           425: makerawname(name)
        !           426:        char *name;
        !           427: {
        !           428:        register char *cp;
        !           429:        char tmp, ch, *rindex();
        !           430:        static char rawname[MAXPATHLEN];
        !           431: 
        !           432:        strcpy(rawname, name);
        !           433:        cp = rindex(rawname, '/');
        !           434:        if (cp == NULL)
        !           435:                return (name);
        !           436:        else
        !           437:                cp++;
        !           438:        for (ch = 'r'; *cp != '\0'; ) {
        !           439:                tmp = *cp;
        !           440:                *cp++ = ch;
        !           441:                ch = tmp;
        !           442:        }
        !           443:        *cp++ = ch;
        !           444:        *cp = '\0';
        !           445:        return (rawname);
        !           446: }

unix.superglobalmegacorp.com

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