Annotation of 43BSDReno/usr.sbin/edquota/edquota.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[] = "@(#)edquota.c  5.14 (Berkeley) 6/19/90";
                     31: #endif /* not lint */
                     32: 
                     33: /*
                     34:  * Disk quota editor.
                     35:  */
                     36: #include <sys/param.h>
                     37: #include <sys/stat.h>
                     38: #include <sys/file.h>
                     39: #include <sys/wait.h>
                     40: #include <ufs/quota.h>
                     41: #include <errno.h>
                     42: #include <fstab.h>
                     43: #include <pwd.h>
                     44: #include <grp.h>
                     45: #include <ctype.h>
                     46: #include <stdio.h>
                     47: #include <string.h>
                     48: #include "pathnames.h"
                     49: 
                     50: char tmpfil[] = _PATH_TMP;
                     51: 
                     52: struct quotause {
                     53:        struct  quotause *next;
                     54:        long    flags;
                     55:        struct  dqblk dqblk;
                     56:        char    fsname[MAXPATHLEN + 1];
                     57:        char    qfname[1];      /* actually longer */
                     58: } *getprivs();
                     59: #define        FOUND   0x01
                     60: 
                     61: main(argc, argv)
                     62:        register char **argv;
                     63:        int argc;
                     64: {
                     65:        register struct quotause *qup, *protoprivs, *curprivs;
                     66:        extern char *optarg;
                     67:        extern int optind;
                     68:        register long id, protoid;
                     69:        register int quotatype, tmpfd;
                     70:        char *protoname, ch;
                     71:        int tflag = 0, pflag = 0;
                     72: 
                     73:        if (argc < 2)
                     74:                usage();
                     75:        if (getuid()) {
                     76:                fprintf(stderr, "edquota: permission denied\n");
                     77:                exit(1);
                     78:        }
                     79:        quotatype = USRQUOTA;
                     80:        while ((ch = getopt(argc, argv, "ugtp:")) != EOF) {
                     81:                switch(ch) {
                     82:                case 'p':
                     83:                        protoname = optarg;
                     84:                        pflag++;
                     85:                        break;
                     86:                case 'g':
                     87:                        quotatype = GRPQUOTA;
                     88:                        break;
                     89:                case 'u':
                     90:                        quotatype = USRQUOTA;
                     91:                        break;
                     92:                case 't':
                     93:                        tflag++;
                     94:                        break;
                     95:                default:
                     96:                        usage();
                     97:                }
                     98:        }
                     99:        argc -= optind;
                    100:        argv += optind;
                    101:        if (pflag) {
                    102:                if ((protoid = getentry(protoname, quotatype)) == -1)
                    103:                        exit(1);
                    104:                protoprivs = getprivs(protoid, quotatype);
                    105:                for (qup = protoprivs; qup; qup = qup->next) {
                    106:                        qup->dqblk.dqb_btime = 0;
                    107:                        qup->dqblk.dqb_itime = 0;
                    108:                }
                    109:                while (argc-- > 0) {
                    110:                        if ((id = getentry(*argv++, quotatype)) < 0)
                    111:                                continue;
                    112:                        putprivs(id, quotatype, protoprivs);
                    113:                }
                    114:                exit(0);
                    115:        }
                    116:        tmpfd = mkstemp(tmpfil);
                    117:        fchown(tmpfd, getuid(), getgid());
                    118:        if (tflag) {
                    119:                protoprivs = getprivs(0, quotatype);
                    120:                if (writetimes(protoprivs, tmpfd, quotatype) == 0)
                    121:                        exit(1);
                    122:                if (editit(tmpfil) && readtimes(protoprivs, tmpfd))
                    123:                        putprivs(0, quotatype, protoprivs);
                    124:                freeprivs(protoprivs);
                    125:                exit(0);
                    126:        }
                    127:        for ( ; argc > 0; argc--, argv++) {
                    128:                if ((id = getentry(*argv, quotatype)) == -1)
                    129:                        continue;
                    130:                curprivs = getprivs(id, quotatype);
                    131:                if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
                    132:                        continue;
                    133:                if (editit(tmpfil) && readprivs(curprivs, tmpfd))
                    134:                        putprivs(id, quotatype, curprivs);
                    135:                freeprivs(curprivs);
                    136:        }
                    137:        close(tmpfd);
                    138:        unlink(tmpfil);
                    139:        exit(0);
                    140: }
                    141: 
                    142: usage()
                    143: {
                    144:        fprintf(stderr, "%s%s%s%s",
                    145:                "Usage: edquota [-u] [-p username] username ...\n",
                    146:                "\tedquota -g [-p groupname] groupname ...\n",
                    147:                "\tedquota [-u] -t\n", "\tedquota -g -t\n");
                    148:        exit(1);
                    149: }
                    150: 
                    151: /*
                    152:  * This routine converts a name for a particular quota type to
                    153:  * an identifier. This routine must agree with the kernel routine
                    154:  * getinoquota as to the interpretation of quota types.
                    155:  */
                    156: getentry(name, quotatype)
                    157:        char *name;
                    158:        int quotatype;
                    159: {
                    160:        struct passwd *pw;
                    161:        struct group *gr;
                    162: 
                    163:        if (alldigits(name))
                    164:                return (atoi(name));
                    165:        switch(quotatype) {
                    166:        case USRQUOTA:
                    167:                if (pw = getpwnam(name))
                    168:                        return (pw->pw_uid);
                    169:                fprintf(stderr, "%s: no such user\n", name);
                    170:                break;
                    171:        case GRPQUOTA:
                    172:                if (gr = getgrnam(name))
                    173:                        return (gr->gr_gid);
                    174:                fprintf(stderr, "%s: no such group\n", name);
                    175:                break;
                    176:        default:
                    177:                fprintf(stderr, "%d: unknown quota type\n", quotatype);
                    178:                break;
                    179:        }
                    180:        sleep(1);
                    181:        return (-1);
                    182: }
                    183: 
                    184: /*
                    185:  * Collect the requested quota information.
                    186:  */
                    187: struct quotause *
                    188: getprivs(id, quotatype)
                    189:        register long id;
                    190:        int quotatype;
                    191: {
                    192:        register struct fstab *fs;
                    193:        register struct quotause *qup, *quptail;
                    194:        struct quotause *quphead;
                    195:        int qcmd, qupsize, fd;
                    196:        char *qfpathname;
                    197:        static int warned = 0;
                    198:        extern int errno;
                    199: 
                    200:        setfsent();
                    201:        quphead = (struct quotause *)0;
                    202:        qcmd = QCMD(Q_GETQUOTA, quotatype);
                    203:        while (fs = getfsent()) {
                    204:                if (strcmp(fs->fs_vfstype, "ufs"))
                    205:                        continue;
                    206:                if (!hasquota(fs, quotatype, &qfpathname))
                    207:                        continue;
                    208:                qupsize = sizeof(*qup) + strlen(qfpathname);
                    209:                if ((qup = (struct quotause *)malloc(qupsize)) == NULL) {
                    210:                        fprintf(stderr, "edquota: out of memory\n");
                    211:                        exit(2);
                    212:                }
                    213:                if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) {
                    214:                        if (errno == EOPNOTSUPP && !warned) {
                    215:                                warned++;
                    216:                                fprintf(stderr, "Warning: %s\n",
                    217:                                    "Quotas are not compiled into this kernel");
                    218:                                sleep(3);
                    219:                        }
                    220:                        if ((fd = open(qfpathname, O_RDONLY)) < 0) {
                    221:                                fd = open(qfpathname, O_RDWR|O_CREAT, 0640);
                    222:                                if (fd < 0 && errno != ENOENT) {
                    223:                                        perror(qfpathname);
                    224:                                        free(qup);
                    225:                                        continue;
                    226:                                }
                    227:                                fprintf(stderr, "Creating quota file %s\n",
                    228:                                    qfpathname);
                    229:                                sleep(3);
                    230:                                (void) fchown(fd, getuid(),
                    231:                                    getentry(quotagroup, GRPQUOTA));
                    232:                                (void) fchmod(fd, 0640);
                    233:                        }
                    234:                        lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET);
                    235:                        switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) {
                    236:                        case 0:                 /* EOF */
                    237:                                /*
                    238:                                 * Convert implicit 0 quota (EOF)
                    239:                                 * into an explicit one (zero'ed dqblk)
                    240:                                 */
                    241:                                bzero((caddr_t)&qup->dqblk,
                    242:                                    sizeof(struct dqblk));
                    243:                                break;
                    244: 
                    245:                        case sizeof(struct dqblk):      /* OK */
                    246:                                break;
                    247: 
                    248:                        default:                /* ERROR */
                    249:                                fprintf(stderr, "edquota: read error in ");
                    250:                                perror(qfpathname);
                    251:                                close(fd);
                    252:                                free(qup);
                    253:                                continue;
                    254:                        }
                    255:                        close(fd);
                    256:                }
                    257:                strcpy(qup->qfname, qfpathname);
                    258:                strcpy(qup->fsname, fs->fs_file);
                    259:                if (quphead == NULL)
                    260:                        quphead = qup;
                    261:                else
                    262:                        quptail->next = qup;
                    263:                quptail = qup;
                    264:                qup->next = 0;
                    265:        }
                    266:        endfsent();
                    267:        return (quphead);
                    268: }
                    269: 
                    270: /*
                    271:  * Store the requested quota information.
                    272:  */
                    273: putprivs(id, quotatype, quplist)
                    274:        long id;
                    275:        int quotatype;
                    276:        struct quotause *quplist;
                    277: {
                    278:        register struct quotause *qup;
                    279:        int qcmd, fd;
                    280: 
                    281:        qcmd = QCMD(Q_SETQUOTA, quotatype);
                    282:        for (qup = quplist; qup; qup = qup->next) {
                    283:                if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0)
                    284:                        continue;
                    285:                if ((fd = open(qup->qfname, O_WRONLY)) < 0) {
                    286:                        perror(qup->qfname);
                    287:                } else {
                    288:                        lseek(fd, (long)id * (long)sizeof (struct dqblk), 0);
                    289:                        if (write(fd, &qup->dqblk, sizeof (struct dqblk)) !=
                    290:                            sizeof (struct dqblk)) {
                    291:                                fprintf(stderr, "edquota: ");
                    292:                                perror(qup->qfname);
                    293:                        }
                    294:                        close(fd);
                    295:                }
                    296:        }
                    297: }
                    298: 
                    299: /*
                    300:  * Take a list of priviledges and get it edited.
                    301:  */
                    302: editit(tmpfile)
                    303:        char *tmpfile;
                    304: {
                    305:        long omask;
                    306:        int pid, stat;
                    307:        extern char *getenv();
                    308: 
                    309:        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
                    310:  top:
                    311:        if ((pid = fork()) < 0) {
                    312:                extern errno;
                    313: 
                    314:                if (errno == EPROCLIM) {
                    315:                        fprintf(stderr, "You have too many processes\n");
                    316:                        return(0);
                    317:                }
                    318:                if (errno == EAGAIN) {
                    319:                        sleep(1);
                    320:                        goto top;
                    321:                }
                    322:                perror("fork");
                    323:                return (0);
                    324:        }
                    325:        if (pid == 0) {
                    326:                register char *ed;
                    327: 
                    328:                sigsetmask(omask);
                    329:                setgid(getgid());
                    330:                setuid(getuid());
                    331:                if ((ed = getenv("EDITOR")) == (char *)0)
                    332:                        ed = _PATH_VI;
                    333:                execlp(ed, ed, tmpfile, 0);
                    334:                perror(ed);
                    335:                exit(1);
                    336:        }
                    337:        waitpid(pid, &stat, 0);
                    338:        sigsetmask(omask);
                    339:        if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0)
                    340:                return (0);
                    341:        return (1);
                    342: }
                    343: 
                    344: /*
                    345:  * Convert a quotause list to an ASCII file.
                    346:  */
                    347: writeprivs(quplist, outfd, name, quotatype)
                    348:        struct quotause *quplist;
                    349:        int outfd;
                    350:        char *name;
                    351:        int quotatype;
                    352: {
                    353:        register struct quotause *qup;
                    354:        FILE *fd;
                    355: 
                    356:        ftruncate(outfd, 0);
                    357:        lseek(outfd, 0, L_SET);
                    358:        if ((fd = fdopen(dup(outfd), "w")) == NULL) {
                    359:                fprintf(stderr, "edquota: ");
                    360:                perror(tmpfil);
                    361:                exit(1);
                    362:        }
                    363:        fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name);
                    364:        for (qup = quplist; qup; qup = qup->next) {
                    365:                fprintf(fd, "%s: %s %d, limits (soft = %d, hard = %d)\n",
                    366:                    qup->fsname, "blocks in use:",
                    367:                    dbtob(qup->dqblk.dqb_curblocks) / 1024,
                    368:                    dbtob(qup->dqblk.dqb_bsoftlimit) / 1024,
                    369:                    dbtob(qup->dqblk.dqb_bhardlimit) / 1024);
                    370:                fprintf(fd, "%s %d, limits (soft = %d, hard = %d)\n",
                    371:                    "\tinodes in use:", qup->dqblk.dqb_curinodes,
                    372:                    qup->dqblk.dqb_isoftlimit, qup->dqblk.dqb_ihardlimit);
                    373:        }
                    374:        fclose(fd);
                    375:        return (1);
                    376: }
                    377: 
                    378: /*
                    379:  * Merge changes to an ASCII file into a quotause list.
                    380:  */
                    381: readprivs(quplist, infd)
                    382:        struct quotause *quplist;
                    383:        int infd;
                    384: {
                    385:        register struct quotause *qup;
                    386:        FILE *fd;
                    387:        int cnt;
                    388:        register char *cp;
                    389:        struct dqblk dqblk;
                    390:        char *fsp, line1[BUFSIZ], line2[BUFSIZ];
                    391: 
                    392:        lseek(infd, 0, L_SET);
                    393:        fd = fdopen(dup(infd), "r");
                    394:        if (fd == NULL) {
                    395:                fprintf(stderr, "Can't re-read temp file!!\n");
                    396:                return (0);
                    397:        }
                    398:        /*
                    399:         * Discard title line, then read pairs of lines to process.
                    400:         */
                    401:        (void) fgets(line1, sizeof (line1), fd);
                    402:        while (fgets(line1, sizeof (line1), fd) != NULL &&
                    403:               fgets(line2, sizeof (line2), fd) != NULL) {
                    404:                if ((fsp = strtok(line1, " \t:")) == NULL) {
                    405:                        fprintf(stderr, "%s: bad format\n", line1);
                    406:                        return (0);
                    407:                }
                    408:                if ((cp = strtok((char *)0, "\n")) == NULL) {
                    409:                        fprintf(stderr, "%s: %s: bad format\n", fsp,
                    410:                            &fsp[strlen(fsp) + 1]);
                    411:                        return (0);
                    412:                }
                    413:                cnt = sscanf(cp,
                    414:                    " blocks in use: %d, limits (soft = %d, hard = %d)",
                    415:                    &dqblk.dqb_curblocks, &dqblk.dqb_bsoftlimit,
                    416:                    &dqblk.dqb_bhardlimit);
                    417:                if (cnt != 3) {
                    418:                        fprintf(stderr, "%s:%s: bad format\n", fsp, cp);
                    419:                        return (0);
                    420:                }
                    421:                dqblk.dqb_curblocks = btodb(dqblk.dqb_curblocks * 1024);
                    422:                dqblk.dqb_bsoftlimit = btodb(dqblk.dqb_bsoftlimit * 1024);
                    423:                dqblk.dqb_bhardlimit = btodb(dqblk.dqb_bhardlimit * 1024);
                    424:                if ((cp = strtok(line2, "\n")) == NULL) {
                    425:                        fprintf(stderr, "%s: %s: bad format\n", fsp, line2);
                    426:                        return (0);
                    427:                }
                    428:                cnt = sscanf(cp,
                    429:                    "\tinodes in use: %d, limits (soft = %d, hard = %d)",
                    430:                    &dqblk.dqb_curinodes, &dqblk.dqb_isoftlimit,
                    431:                    &dqblk.dqb_ihardlimit);
                    432:                if (cnt != 3) {
                    433:                        fprintf(stderr, "%s: %s: bad format\n", fsp, line2);
                    434:                        return (0);
                    435:                }
                    436:                for (qup = quplist; qup; qup = qup->next) {
                    437:                        if (strcmp(fsp, qup->fsname))
                    438:                                continue;
                    439:                        /*
                    440:                         * Cause time limit to be reset when the quota
                    441:                         * is next used if previously had no soft limit
                    442:                         * or were under it, but now have a soft limit
                    443:                         * and are over it.
                    444:                         */
                    445:                        if (dqblk.dqb_bsoftlimit &&
                    446:                            qup->dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit &&
                    447:                            (qup->dqblk.dqb_bsoftlimit == 0 ||
                    448:                             qup->dqblk.dqb_curblocks <
                    449:                             qup->dqblk.dqb_bsoftlimit))
                    450:                                qup->dqblk.dqb_btime = 0;
                    451:                        if (dqblk.dqb_isoftlimit &&
                    452:                            qup->dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit &&
                    453:                            (qup->dqblk.dqb_isoftlimit == 0 ||
                    454:                             qup->dqblk.dqb_curinodes <
                    455:                             qup->dqblk.dqb_isoftlimit))
                    456:                                qup->dqblk.dqb_itime = 0;
                    457:                        qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit;
                    458:                        qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit;
                    459:                        qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit;
                    460:                        qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit;
                    461:                        qup->flags |= FOUND;
                    462:                        if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks &&
                    463:                            dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes)
                    464:                                break;
                    465:                        fprintf(stderr,
                    466:                            "%s: cannot change current allocation\n", fsp);
                    467:                        break;
                    468:                }
                    469:        }
                    470:        fclose(fd);
                    471:        /*
                    472:         * Disable quotas for any filesystems that have not been found.
                    473:         */
                    474:        for (qup = quplist; qup; qup = qup->next) {
                    475:                if (qup->flags & FOUND) {
                    476:                        qup->flags &= ~FOUND;
                    477:                        continue;
                    478:                }
                    479:                qup->dqblk.dqb_bsoftlimit = 0;
                    480:                qup->dqblk.dqb_bhardlimit = 0;
                    481:                qup->dqblk.dqb_isoftlimit = 0;
                    482:                qup->dqblk.dqb_ihardlimit = 0;
                    483:        }
                    484:        return (1);
                    485: }
                    486: 
                    487: /*
                    488:  * Convert a quotause list to an ASCII file of grace times.
                    489:  */
                    490: writetimes(quplist, outfd, quotatype)
                    491:        struct quotause *quplist;
                    492:        int outfd;
                    493:        int quotatype;
                    494: {
                    495:        register struct quotause *qup;
                    496:        char *cvtstoa();
                    497:        FILE *fd;
                    498: 
                    499:        ftruncate(outfd, 0);
                    500:        lseek(outfd, 0, L_SET);
                    501:        if ((fd = fdopen(dup(outfd), "w")) == NULL) {
                    502:                fprintf(stderr, "edquota: ");
                    503:                perror(tmpfil);
                    504:                exit(1);
                    505:        }
                    506:        fprintf(fd, "Time units may be: days, hours, minutes, or seconds\n");
                    507:        fprintf(fd, "Grace period before enforcing soft limits for %ss:\n",
                    508:            qfextension[quotatype]);
                    509:        for (qup = quplist; qup; qup = qup->next) {
                    510:                fprintf(fd, "%s: block grace period: %s, ",
                    511:                    qup->fsname, cvtstoa(qup->dqblk.dqb_btime));
                    512:                fprintf(fd, "file grace period: %s\n",
                    513:                    cvtstoa(qup->dqblk.dqb_itime));
                    514:        }
                    515:        fclose(fd);
                    516:        return (1);
                    517: }
                    518: 
                    519: /*
                    520:  * Merge changes of grace times in an ASCII file into a quotause list.
                    521:  */
                    522: readtimes(quplist, infd)
                    523:        struct quotause *quplist;
                    524:        int infd;
                    525: {
                    526:        register struct quotause *qup;
                    527:        FILE *fd;
                    528:        int cnt;
                    529:        register char *cp;
                    530:        time_t itime, btime, iseconds, bseconds;
                    531:        char *fsp, bunits[10], iunits[10], line1[BUFSIZ];
                    532: 
                    533:        lseek(infd, 0, L_SET);
                    534:        fd = fdopen(dup(infd), "r");
                    535:        if (fd == NULL) {
                    536:                fprintf(stderr, "Can't re-read temp file!!\n");
                    537:                return (0);
                    538:        }
                    539:        /*
                    540:         * Discard two title lines, then read lines to process.
                    541:         */
                    542:        (void) fgets(line1, sizeof (line1), fd);
                    543:        (void) fgets(line1, sizeof (line1), fd);
                    544:        while (fgets(line1, sizeof (line1), fd) != NULL) {
                    545:                if ((fsp = strtok(line1, " \t:")) == NULL) {
                    546:                        fprintf(stderr, "%s: bad format\n", line1);
                    547:                        return (0);
                    548:                }
                    549:                if ((cp = strtok((char *)0, "\n")) == NULL) {
                    550:                        fprintf(stderr, "%s: %s: bad format\n", fsp,
                    551:                            &fsp[strlen(fsp) + 1]);
                    552:                        return (0);
                    553:                }
                    554:                cnt = sscanf(cp,
                    555:                    " block grace period: %d %s file grace period: %d %s",
                    556:                    &btime, bunits, &itime, iunits);
                    557:                if (cnt != 4) {
                    558:                        fprintf(stderr, "%s:%s: bad format\n", fsp, cp);
                    559:                        return (0);
                    560:                }
                    561:                if (cvtatos(btime, bunits, &bseconds) == 0)
                    562:                        return (0);
                    563:                if (cvtatos(itime, iunits, &iseconds) == 0)
                    564:                        return (0);
                    565:                for (qup = quplist; qup; qup = qup->next) {
                    566:                        if (strcmp(fsp, qup->fsname))
                    567:                                continue;
                    568:                        qup->dqblk.dqb_btime = bseconds;
                    569:                        qup->dqblk.dqb_itime = iseconds;
                    570:                        qup->flags |= FOUND;
                    571:                        break;
                    572:                }
                    573:        }
                    574:        fclose(fd);
                    575:        /*
                    576:         * reset default grace periods for any filesystems
                    577:         * that have not been found.
                    578:         */
                    579:        for (qup = quplist; qup; qup = qup->next) {
                    580:                if (qup->flags & FOUND) {
                    581:                        qup->flags &= ~FOUND;
                    582:                        continue;
                    583:                }
                    584:                qup->dqblk.dqb_btime = 0;
                    585:                qup->dqblk.dqb_itime = 0;
                    586:        }
                    587:        return (1);
                    588: }
                    589: 
                    590: /*
                    591:  * Convert seconds to ASCII times.
                    592:  */
                    593: char *
                    594: cvtstoa(time)
                    595:        time_t time;
                    596: {
                    597:        static char buf[20];
                    598: 
                    599:        if (time % (24 * 60 * 60) == 0) {
                    600:                time /= 24 * 60 * 60;
                    601:                sprintf(buf, "%d day%s", time, time == 1 ? "" : "s");
                    602:        } else if (time % (60 * 60) == 0) {
                    603:                time /= 60 * 60;
                    604:                sprintf(buf, "%d hour%s", time, time == 1 ? "" : "s");
                    605:        } else if (time % 60 == 0) {
                    606:                time /= 60;
                    607:                sprintf(buf, "%d minute%s", time, time == 1 ? "" : "s");
                    608:        } else
                    609:                sprintf(buf, "%d second%s", time, time == 1 ? "" : "s");
                    610:        return (buf);
                    611: }
                    612: 
                    613: /*
                    614:  * Convert ASCII input times to seconds.
                    615:  */
                    616: cvtatos(time, units, seconds)
                    617:        time_t time;
                    618:        char *units;
                    619:        time_t *seconds;
                    620: {
                    621: 
                    622:        if (bcmp(units, "second", 6) == 0)
                    623:                *seconds = time;
                    624:        else if (bcmp(units, "minute", 6) == 0)
                    625:                *seconds = time * 60;
                    626:        else if (bcmp(units, "hour", 4) == 0)
                    627:                *seconds = time * 60 * 60;
                    628:        else if (bcmp(units, "day", 3) == 0)
                    629:                *seconds = time * 24 * 60 * 60;
                    630:        else {
                    631:                printf("%s: bad units, specify %s\n", units,
                    632:                    "days, hours, minutes, or seconds");
                    633:                return (0);
                    634:        }
                    635:        return (1);
                    636: }
                    637: 
                    638: /*
                    639:  * Free a list of quotause structures.
                    640:  */
                    641: freeprivs(quplist)
                    642:        struct quotause *quplist;
                    643: {
                    644:        register struct quotause *qup, *nextqup;
                    645: 
                    646:        for (qup = quplist; qup; qup = nextqup) {
                    647:                nextqup = qup->next;
                    648:                free(qup);
                    649:        }
                    650: }
                    651: 
                    652: /*
                    653:  * Check whether a string is completely composed of digits.
                    654:  */
                    655: alldigits(s)
                    656:        register char *s;
                    657: {
                    658:        register c;
                    659: 
                    660:        c = *s++;
                    661:        do {
                    662:                if (!isdigit(c))
                    663:                        return (0);
                    664:        } while (c = *s++);
                    665:        return (1);
                    666: }
                    667: 
                    668: /*
                    669:  * Check to see if a particular quota is to be enabled.
                    670:  */
                    671: hasquota(fs, type, qfnamep)
                    672:        register struct fstab *fs;
                    673:        int type;
                    674:        char **qfnamep;
                    675: {
                    676:        register char *opt;
                    677:        char *cp, *index(), *strtok();
                    678:        static char initname, usrname[100], grpname[100];
                    679:        static char buf[BUFSIZ];
                    680: 
                    681:        if (!initname) {
                    682:                sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
                    683:                sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
                    684:                initname = 1;
                    685:        }
                    686:        strcpy(buf, fs->fs_mntops);
                    687:        for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
                    688:                if (cp = index(opt, '='))
                    689:                        *cp++ = '\0';
                    690:                if (type == USRQUOTA && strcmp(opt, usrname) == 0)
                    691:                        break;
                    692:                if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
                    693:                        break;
                    694:        }
                    695:        if (!opt)
                    696:                return (0);
                    697:        if (cp) {
                    698:                *qfnamep = cp;
                    699:                return (1);
                    700:        }
                    701:        (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
                    702:        *qfnamep = buf;
                    703:        return (1);
                    704: }

unix.superglobalmegacorp.com

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