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