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

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)quotacheck.c       4.4 (Berkeley, Melbourne) 6/22/83";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Fix up / report on disc quotas & usage
        !             7:  */
        !             8: #include <stdio.h>
        !             9: #include <ctype.h>
        !            10: #include <signal.h>
        !            11: #include <sys/param.h>
        !            12: #include <sys/inode.h>
        !            13: #include <sys/fs.h>
        !            14: #include <sys/quota.h>
        !            15: #include <sys/stat.h>
        !            16: #include <fstab.h>
        !            17: #include <pwd.h>
        !            18: 
        !            19: union {
        !            20:        struct  fs      sblk;
        !            21:        char    dummy[MAXBSIZE];
        !            22: } un;
        !            23: #define        sblock  un.sblk
        !            24: 
        !            25: #define        ITABSZ  256
        !            26: struct dinode  itab[ITABSZ];
        !            27: struct dinode  *dp;
        !            28: long   blocks;
        !            29: dev_t  dev;
        !            30: 
        !            31: #define LOGINNAMESIZE 8
        !            32: struct fileusage {
        !            33:        struct fileusage *fu_next;
        !            34:        struct dqusage fu_usage;
        !            35:        u_short fu_uid;
        !            36:        char fu_name[LOGINNAMESIZE + 1];
        !            37: };
        !            38: #define FUHASH 997
        !            39: struct fileusage *fuhead[FUHASH];
        !            40: struct fileusage *lookup();
        !            41: struct fileusage *adduid();
        !            42: int highuid;
        !            43: 
        !            44: int fi;
        !            45: ino_t ino;
        !            46: long done;
        !            47: struct passwd  *getpwent();
        !            48: struct dinode  *ginode();
        !            49: char *malloc(), *makerawname();
        !            50: 
        !            51: int    vflag;          /* verbose */
        !            52: int    aflag;          /* all file systems */
        !            53: 
        !            54: char *qfname = "quotas";
        !            55: char quotafile[MAXPATHLEN + 1];
        !            56: struct dqblk zerodqbuf;
        !            57: 
        !            58: main(argc, argv)
        !            59:        int argc;
        !            60:        char **argv;
        !            61: {
        !            62:        register struct fstab *fs;
        !            63:        register struct fileusage *fup;
        !            64:        register struct passwd *pw;
        !            65:        int i, errs = 0;
        !            66: 
        !            67: again:
        !            68:        argc--, argv++;
        !            69:        if (argc > 0 && strcmp(*argv, "-v") == 0) {
        !            70:                vflag++;
        !            71:                goto again;
        !            72:        }
        !            73:        if (argc > 0 && strcmp(*argv, "-a") == 0) {
        !            74:                aflag++;
        !            75:                goto again;
        !            76:        }
        !            77:        if (argc <= 0 && !aflag) {
        !            78:                fprintf(stderr, "Usage:\n\t%s\n\t%s\n",
        !            79:                        "quotacheck [-v] -a",
        !            80:                        "quotacheck [-v] filesys ...");
        !            81:                exit(1);
        !            82:        }
        !            83:        if (vflag) {
        !            84:                setpwent();
        !            85:                while ((pw = getpwent()) != 0) {
        !            86:                        fup = lookup(pw->pw_uid);
        !            87:                        if (fup == 0)
        !            88:                                fup = adduid(pw->pw_uid);
        !            89:                        strncpy(fup->fu_name, pw->pw_name,
        !            90:                                sizeof(fup->fu_name));
        !            91:                }
        !            92:                endpwent();
        !            93:        }
        !            94:        setfsent();
        !            95:        while ((fs = getfsent()) != NULL) {
        !            96:                if (aflag &&
        !            97:                    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
        !            98:                        continue;
        !            99:                if (!aflag &&
        !           100:                    !(oneof(fs->fs_file, argv, argc) ||
        !           101:                      oneof(fs->fs_spec, argv, argc)))
        !           102:                        continue;
        !           103:                (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
        !           104:                errs += chkquota(fs->fs_spec, quotafile);
        !           105:        }
        !           106:        endfsent();
        !           107:        for (i = 0; i < argc; i++)
        !           108:                if ((done & (1 << i)) == 0)
        !           109:                        fprintf(stderr, "%s not found in /etc/fstab\n",
        !           110:                                argv[i]);
        !           111:        exit(errs);
        !           112: }
        !           113: 
        !           114: chkquota(fsdev, qffile)
        !           115:        char *fsdev;
        !           116:        char *qffile;
        !           117: {
        !           118:        register struct fileusage *fup;
        !           119:        dev_t quotadev;
        !           120:        FILE *qf;
        !           121:        u_short uid;
        !           122:        int cg, i;
        !           123:        char *rawdisk;
        !           124:        struct stat statb;
        !           125:        struct dqblk dqbuf;
        !           126: 
        !           127:        rawdisk = makerawname(fsdev);
        !           128:        if (vflag)
        !           129:                fprintf(stdout, "*** Check quotas for %s\n", rawdisk);
        !           130:        fi = open(rawdisk, 0);
        !           131:        if (fi < 0) {
        !           132:                perror(rawdisk);
        !           133:                return (1);
        !           134:        }
        !           135:        qf = fopen(qffile, "r+");
        !           136:        if (qf == NULL) {
        !           137:                perror(qffile);
        !           138:                return (1);
        !           139:        }
        !           140:        if (fstat(fileno(qf), &statb) < 0) {
        !           141:                perror(qffile);
        !           142:                return (1);
        !           143:        }
        !           144:        quotadev = statb.st_dev;
        !           145:        if (stat(fsdev, &statb) < 0) {
        !           146:                perror(fsdev);
        !           147:                return (1);
        !           148:        }
        !           149:        if (quotadev != statb.st_rdev) {
        !           150:                fprintf(stderr, "%s dev (0x%x) mismatch %s dev (0x%x)\n",
        !           151:                        qffile, quotadev, fsdev, statb.st_rdev);
        !           152:                return (1);
        !           153:        }
        !           154:        quota(Q_SYNC, 0, quotadev, 0);
        !           155:        sync();
        !           156:        bread(SBLOCK, (char *)&sblock, SBSIZE);
        !           157:        ino = 0;
        !           158:        for (cg = 0; cg < sblock.fs_ncg; cg++) {
        !           159:                dp = NULL;
        !           160:                for (i = 0; i < sblock.fs_ipg; i++)
        !           161:                        acct(ginode());
        !           162:        }
        !           163:        for (uid = 0; uid <= highuid; uid++) {
        !           164:                fup = lookup(uid);
        !           165:                if (fup == 0)
        !           166:                        continue;
        !           167:                fseek(qf, uid * sizeof(struct dqblk), 0);
        !           168:                i = fread(&dqbuf, sizeof(struct dqblk), 1, qf);
        !           169:                if (i == 0)
        !           170:                        dqbuf = zerodqbuf;
        !           171:                if (dqbuf.dqb_curinodes == fup->fu_usage.du_curinodes &&
        !           172:                    dqbuf.dqb_curblocks == fup->fu_usage.du_curblocks) {
        !           173:                        fup->fu_usage.du_curinodes = 0;
        !           174:                        fup->fu_usage.du_curblocks = 0;
        !           175:                        continue;
        !           176:                }
        !           177:                if (vflag) {
        !           178:                        if (fup->fu_name[0] != '\0')
        !           179:                                printf("%-10s fixed:", fup->fu_name);
        !           180:                        else
        !           181:                                printf("#%-9d fixed:", uid);
        !           182:                        fprintf(stdout, " inodes (old %d, new %d)",
        !           183:                            dqbuf.dqb_curinodes, fup->fu_usage.du_curinodes);
        !           184:                        fprintf(stdout, " blocks (old %d, new %d)\n",
        !           185:                            dqbuf.dqb_curblocks, fup->fu_usage.du_curblocks);
        !           186:                }
        !           187:                dqbuf.dqb_curinodes = fup->fu_usage.du_curinodes;
        !           188:                dqbuf.dqb_curblocks = fup->fu_usage.du_curblocks;
        !           189:                fseek(qf, uid * sizeof(struct dqblk), 0);
        !           190:                fwrite(&dqbuf, sizeof(struct dqblk), 1, qf);
        !           191:                quota(Q_SETDUSE, uid, quotadev, &fup->fu_usage);
        !           192:                fup->fu_usage.du_curinodes = 0;
        !           193:                fup->fu_usage.du_curblocks = 0;
        !           194:        }
        !           195:        return (0);
        !           196: }
        !           197: 
        !           198: acct(ip)
        !           199:        register struct dinode *ip;
        !           200: {
        !           201:        register n;
        !           202:        register struct fileusage *fup;
        !           203: 
        !           204:        if (ip == NULL)
        !           205:                return;
        !           206:        if (ip->di_mode == 0)
        !           207:                return;
        !           208:        fup = lookup(ip->di_uid);
        !           209:        if (fup == 0)
        !           210:                fup = adduid(ip->di_uid);
        !           211:        fup->fu_usage.du_curinodes++;
        !           212:        if ((ip->di_mode & IFMT) == IFCHR || (ip->di_mode & IFMT) == IFBLK)
        !           213:                return;
        !           214:        fup->fu_usage.du_curblocks += ip->di_blocks;
        !           215: }
        !           216: 
        !           217: oneof(target, list, n)
        !           218:        char *target, *list[];
        !           219:        register int n;
        !           220: {
        !           221:        register int i;
        !           222: 
        !           223:        for (i = 0; i < n; i++)
        !           224:                if (strcmp(target, list[i]) == 0) {
        !           225:                        done |= 1 << i;
        !           226:                        return (1);
        !           227:                }
        !           228:        return (0);
        !           229: }
        !           230: 
        !           231: struct dinode *
        !           232: ginode()
        !           233: {
        !           234:        register unsigned long iblk;
        !           235: 
        !           236:        if (dp == NULL || ++dp >= &itab[ITABSZ]) {
        !           237:                iblk = itod(&sblock, ino);
        !           238:                bread(fsbtodb(&sblock, iblk), (char *)itab, sizeof itab);
        !           239:                dp = &itab[ino % INOPB(&sblock)];
        !           240:        }
        !           241:        if (ino++ < ROOTINO)
        !           242:                return(NULL);
        !           243:        return(dp);
        !           244: }
        !           245: 
        !           246: bread(bno, buf, cnt)
        !           247:        long unsigned bno;
        !           248:        char *buf;
        !           249: {
        !           250: 
        !           251:        lseek(fi, (long)dbtob(bno), 0);
        !           252:        if (read(fi, buf, cnt) != cnt) {
        !           253:                printf("read error %u\n", bno);
        !           254:                exit(1);
        !           255:        }
        !           256: }
        !           257: 
        !           258: struct fileusage *
        !           259: lookup(uid)
        !           260:        u_short uid;
        !           261: {
        !           262:        register struct fileusage *fup;
        !           263: 
        !           264:        for (fup = fuhead[uid % FUHASH]; fup != 0; fup = fup->fu_next)
        !           265:                if (fup->fu_uid == uid)
        !           266:                        return (fup);
        !           267:        return ((struct fileusage *)0);
        !           268: }
        !           269: 
        !           270: struct fileusage *
        !           271: adduid(uid)
        !           272:        u_short uid;
        !           273: {
        !           274:        struct fileusage *fup, **fhp;
        !           275: 
        !           276:        fup = lookup(uid);
        !           277:        if (fup != 0)
        !           278:                return (fup);
        !           279:        fup = (struct fileusage *)calloc(1, sizeof(struct fileusage));
        !           280:        if (fup == 0) {
        !           281:                fprintf(stderr, "out of memory for fileusage structures\n");
        !           282:                exit(1);
        !           283:        }
        !           284:        fhp = &fuhead[uid % FUHASH];
        !           285:        fup->fu_next = *fhp;
        !           286:        *fhp = fup;
        !           287:        fup->fu_uid = uid;
        !           288:        if (uid > highuid)
        !           289:                highuid = uid;
        !           290:        return (fup);
        !           291: }
        !           292: 
        !           293: char *
        !           294: makerawname(name)
        !           295:        char *name;
        !           296: {
        !           297:        register char *cp;
        !           298:        char tmp, ch, *rindex();
        !           299:        static char rawname[MAXPATHLEN];
        !           300: 
        !           301:        strcpy(rawname, name);
        !           302:        cp = rindex(rawname, '/') + 1;
        !           303:        if (cp == (char *)1 || *cp == 'r')
        !           304:                return (name);
        !           305:        for (ch = 'r'; *cp != '\0'; ) {
        !           306:                tmp = *cp;
        !           307:                *cp++ = ch;
        !           308:                ch = tmp;
        !           309:        }
        !           310:        *cp++ = ch;
        !           311:        *cp = '\0';
        !           312:        return (rawname);
        !           313: }

unix.superglobalmegacorp.com

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