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

1.1       root        1: /*
                      2:  * Copyright (c) 1980, 1990 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Robert Elz at The University of Melbourne.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted provided
                      9:  * that: (1) source distributions retain this entire copyright notice and
                     10:  * comment, and (2) distributions including binaries display the following
                     11:  * acknowledgement:  ``This product includes software developed by the
                     12:  * University of California, Berkeley and its contributors'' in the
                     13:  * documentation or other materials provided with the distribution and in
                     14:  * all advertising materials mentioning features or use of this software.
                     15:  * Neither the name of the University nor the names of its contributors may
                     16:  * be used to endorse or promote products derived from this software without
                     17:  * specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: char copyright[] =
                     25: "@(#) Copyright (c) 1980, 1990 Regents of the University of California.\n\
                     26:  All rights reserved.\n";
                     27: #endif /* not lint */
                     28: 
                     29: #ifndef lint
                     30: static char sccsid[] = "@(#)repquota.c 5.10 (Berkeley) 6/1/90";
                     31: #endif /* not lint */
                     32: 
                     33: /*
                     34:  * Quota report
                     35:  */
                     36: #include <sys/param.h>
                     37: #include <sys/stat.h>
                     38: #include <ufs/quota.h>
                     39: #include <fstab.h>
                     40: #include <pwd.h>
                     41: #include <grp.h>
                     42: #include <stdio.h>
                     43: #include <errno.h>
                     44: 
                     45: struct fileusage {
                     46:        struct  fileusage *fu_next;
                     47:        struct  dqblk fu_dqblk;
                     48:        u_long  fu_id;
                     49:        char    fu_name[1];
                     50:        /* actually bigger */
                     51: };
                     52: #define FUHASH 1024    /* must be power of two */
                     53: struct fileusage *fuhead[MAXQUOTAS][FUHASH];
                     54: struct fileusage *lookup();
                     55: struct fileusage *addid();
                     56: u_long highid[MAXQUOTAS];      /* highest addid()'ed identifier per type */
                     57: 
                     58: int    vflag;                  /* verbose */
                     59: int    aflag;                  /* all file systems */
                     60: 
                     61: main(argc, argv)
                     62:        int argc;
                     63:        char **argv;
                     64: {
                     65:        register struct fstab *fs;
                     66:        register struct passwd *pw;
                     67:        register struct group *gr;
                     68:        int gflag = 0, uflag = 0, errs = 0;
                     69:        long i, argnum, done = 0;
                     70:        extern char *optarg;
                     71:        extern int optind;
                     72:        char ch, *qfnp;
                     73: 
                     74:        while ((ch = getopt(argc, argv, "aguv")) != EOF) {
                     75:                switch(ch) {
                     76:                case 'a':
                     77:                        aflag++;
                     78:                        break;
                     79:                case 'g':
                     80:                        gflag++;
                     81:                        break;
                     82:                case 'u':
                     83:                        uflag++;
                     84:                        break;
                     85:                case 'v':
                     86:                        vflag++;
                     87:                        break;
                     88:                default:
                     89:                        usage();
                     90:                }
                     91:        }
                     92:        argc -= optind;
                     93:        argv += optind;
                     94:        if (argc == 0 && !aflag)
                     95:                usage();
                     96:        if (!gflag && !uflag) {
                     97:                if (aflag)
                     98:                        gflag++;
                     99:                uflag++;
                    100:        }
                    101:        if (gflag) {
                    102:                setgrent();
                    103:                while ((gr = getgrent()) != 0)
                    104:                        (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name);
                    105:                endgrent();
                    106:        }
                    107:        if (uflag) {
                    108:                setpwent();
                    109:                while ((pw = getpwent()) != 0)
                    110:                        (void) addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name);
                    111:                endpwent();
                    112:        }
                    113:        setfsent();
                    114:        while ((fs = getfsent()) != NULL) {
                    115:                if (strcmp(fs->fs_vfstype, "ufs"))
                    116:                        continue;
                    117:                if (aflag) {
                    118:                        if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
                    119:                                errs += repquota(fs, GRPQUOTA, qfnp);
                    120:                        if (uflag && hasquota(fs, USRQUOTA, &qfnp))
                    121:                                errs += repquota(fs, USRQUOTA, qfnp);
                    122:                        continue;
                    123:                }
                    124:                if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
                    125:                    (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
                    126:                        done |= 1 << argnum;
                    127:                        if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
                    128:                                errs += repquota(fs, GRPQUOTA, qfnp);
                    129:                        if (uflag && hasquota(fs, USRQUOTA, &qfnp))
                    130:                                errs += repquota(fs, USRQUOTA, qfnp);
                    131:                }
                    132:        }
                    133:        endfsent();
                    134:        for (i = 0; i < argc; i++)
                    135:                if ((done & (1 << i)) == 0)
                    136:                        fprintf(stderr, "%s not found in fstab\n", argv[i]);
                    137:        exit(errs);
                    138: }
                    139: 
                    140: usage()
                    141: {
                    142:        fprintf(stderr, "Usage:\n\t%s\n\t%s\n",
                    143:                "repquota [-v] [-g] [-u] -a",
                    144:                "repquota [-v] [-g] [-u] filesys ...");
                    145:        exit(1);
                    146: }
                    147: 
                    148: repquota(fs, type, qfpathname)
                    149:        register struct fstab *fs;
                    150:        int type;
                    151:        char *qfpathname;
                    152: {
                    153:        register struct fileusage *fup;
                    154:        FILE *qf;
                    155:        u_long id;
                    156:        struct dqblk dqbuf;
                    157:        char *timeprt();
                    158:        static struct dqblk zerodqblk;
                    159:        static int warned = 0;
                    160:        static int multiple = 0;
                    161:        extern int errno;
                    162: 
                    163:        if (quotactl(fs->fs_file, QCMD(Q_SYNC, type), 0, 0) < 0 &&
                    164:            errno == EOPNOTSUPP && !warned && vflag) {
                    165:                warned++;
                    166:                fprintf(stdout,
                    167:                    "*** Warning: Quotas are not compiled into this kernel\n");
                    168:        }
                    169:        if (multiple++)
                    170:                printf("\n");
                    171:        if (vflag)
                    172:                fprintf(stdout, "*** Report for %s quotas on %s (%s)\n",
                    173:                    qfextension[type], fs->fs_file, fs->fs_spec);
                    174:        if ((qf = fopen(qfpathname, "r")) == NULL) {
                    175:                perror(qfpathname);
                    176:                return (1);
                    177:        }
                    178:        for (id = 0; ; id++) {
                    179:                fread(&dqbuf, sizeof(struct dqblk), 1, qf);
                    180:                if (feof(qf))
                    181:                        break;
                    182:                if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0)
                    183:                        continue;
                    184:                if ((fup = lookup(id, type)) == 0)
                    185:                        fup = addid(id, type, (char *)0);
                    186:                fup->fu_dqblk = dqbuf;
                    187:        }
                    188:        fclose(qf);
                    189:        printf("                        Block limits               File limits\n");
                    190:        printf("User            used    soft    hard  grace    used  soft  hard  grace\n");
                    191:        for (id = 0; id <= highid[type]; id++) {
                    192:                fup = lookup(id, type);
                    193:                if (fup == 0)
                    194:                        continue;
                    195:                if (fup->fu_dqblk.dqb_curinodes == 0 &&
                    196:                    fup->fu_dqblk.dqb_curblocks == 0)
                    197:                        continue;
                    198:                printf("%-10s", fup->fu_name);
                    199:                printf("%c%c%8d%8d%8d%7s",
                    200:                        fup->fu_dqblk.dqb_bsoftlimit && 
                    201:                            fup->fu_dqblk.dqb_curblocks >= 
                    202:                            fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-',
                    203:                        fup->fu_dqblk.dqb_isoftlimit &&
                    204:                            fup->fu_dqblk.dqb_curinodes >=
                    205:                            fup->fu_dqblk.dqb_isoftlimit ? '+' : '-',
                    206:                        dbtob(fup->fu_dqblk.dqb_curblocks) / 1024,
                    207:                        dbtob(fup->fu_dqblk.dqb_bsoftlimit) / 1024,
                    208:                        dbtob(fup->fu_dqblk.dqb_bhardlimit) / 1024,
                    209:                        fup->fu_dqblk.dqb_bsoftlimit && 
                    210:                            fup->fu_dqblk.dqb_curblocks >= 
                    211:                            fup->fu_dqblk.dqb_bsoftlimit ?
                    212:                            timeprt(fup->fu_dqblk.dqb_btime) : "");
                    213:                printf("  %6d%6d%6d%7s\n",
                    214:                        fup->fu_dqblk.dqb_curinodes,
                    215:                        fup->fu_dqblk.dqb_isoftlimit,
                    216:                        fup->fu_dqblk.dqb_ihardlimit,
                    217:                        fup->fu_dqblk.dqb_isoftlimit &&
                    218:                            fup->fu_dqblk.dqb_curinodes >=
                    219:                            fup->fu_dqblk.dqb_isoftlimit ?
                    220:                            timeprt(fup->fu_dqblk.dqb_itime) : "");
                    221:                fup->fu_dqblk = zerodqblk;
                    222:        }
                    223:        return (0);
                    224: }
                    225: 
                    226: /*
                    227:  * Check to see if target appears in list of size cnt.
                    228:  */
                    229: oneof(target, list, cnt)
                    230:        register char *target, *list[];
                    231:        int cnt;
                    232: {
                    233:        register int i;
                    234: 
                    235:        for (i = 0; i < cnt; i++)
                    236:                if (strcmp(target, list[i]) == 0)
                    237:                        return (i);
                    238:        return (-1);
                    239: }
                    240: 
                    241: /*
                    242:  * Check to see if a particular quota is to be enabled.
                    243:  */
                    244: hasquota(fs, type, qfnamep)
                    245:        register struct fstab *fs;
                    246:        int type;
                    247:        char **qfnamep;
                    248: {
                    249:        register char *opt;
                    250:        char *cp, *index(), *strtok();
                    251:        static char initname, usrname[100], grpname[100];
                    252:        static char buf[BUFSIZ];
                    253: 
                    254:        if (!initname) {
                    255:                sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
                    256:                sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
                    257:                initname = 1;
                    258:        }
                    259:        strcpy(buf, fs->fs_mntops);
                    260:        for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
                    261:                if (cp = index(opt, '='))
                    262:                        *cp++ = '\0';
                    263:                if (type == USRQUOTA && strcmp(opt, usrname) == 0)
                    264:                        break;
                    265:                if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
                    266:                        break;
                    267:        }
                    268:        if (!opt)
                    269:                return (0);
                    270:        if (cp) {
                    271:                *qfnamep = cp;
                    272:                return (1);
                    273:        }
                    274:        (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
                    275:        *qfnamep = buf;
                    276:        return (1);
                    277: }
                    278: 
                    279: /*
                    280:  * Routines to manage the file usage table.
                    281:  *
                    282:  * Lookup an id of a specific type.
                    283:  */
                    284: struct fileusage *
                    285: lookup(id, type)
                    286:        u_long id;
                    287:        int type;
                    288: {
                    289:        register struct fileusage *fup;
                    290: 
                    291:        for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
                    292:                if (fup->fu_id == id)
                    293:                        return (fup);
                    294:        return ((struct fileusage *)0);
                    295: }
                    296: 
                    297: /*
                    298:  * Add a new file usage id if it does not already exist.
                    299:  */
                    300: struct fileusage *
                    301: addid(id, type, name)
                    302:        u_long id;
                    303:        int type;
                    304:        char *name;
                    305: {
                    306:        struct fileusage *fup, **fhp;
                    307:        int len;
                    308:        extern char *calloc();
                    309: 
                    310:        if (fup = lookup(id, type))
                    311:                return (fup);
                    312:        if (name)
                    313:                len = strlen(name);
                    314:        else
                    315:                len = 10;
                    316:        if ((fup = (struct fileusage *)calloc(1, sizeof(*fup) + len)) == NULL) {
                    317:                fprintf(stderr, "out of memory for fileusage structures\n");
                    318:                exit(1);
                    319:        }
                    320:        fhp = &fuhead[type][id & (FUHASH - 1)];
                    321:        fup->fu_next = *fhp;
                    322:        *fhp = fup;
                    323:        fup->fu_id = id;
                    324:        if (id > highid[type])
                    325:                highid[type] = id;
                    326:        if (name) {
                    327:                bcopy(name, fup->fu_name, len + 1);
                    328:        } else {
                    329:                sprintf(fup->fu_name, "%u", id);
                    330:        }
                    331:        return (fup);
                    332: }
                    333: 
                    334: /*
                    335:  * Calculate the grace period and return a printable string for it.
                    336:  */
                    337: char *
                    338: timeprt(seconds)
                    339:        time_t seconds;
                    340: {
                    341:        time_t hours, minutes;
                    342:        static char buf[20];
                    343:        static time_t now;
                    344: 
                    345:        if (now == 0)
                    346:                time(&now);
                    347:        if (now > seconds)
                    348:                return ("none");
                    349:        seconds -= now;
                    350:        minutes = (seconds + 30) / 60;
                    351:        hours = (minutes + 30) / 60;
                    352:        if (hours >= 36) {
                    353:                sprintf(buf, "%ddays", (hours + 12) / 24);
                    354:                return (buf);
                    355:        }
                    356:        if (minutes >= 60) {
                    357:                sprintf(buf, "%2d:%d", minutes / 60, minutes % 60);
                    358:                return (buf);
                    359:        }
                    360:        sprintf(buf, "%2d", minutes);
                    361:        return (buf);
                    362: }

unix.superglobalmegacorp.com

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