diff options
-rw-r--r-- | usr.sbin/edquota/edquota.8 | 45 | ||||
-rw-r--r-- | usr.sbin/edquota/edquota.c | 127 |
2 files changed, 149 insertions, 23 deletions
diff --git a/usr.sbin/edquota/edquota.8 b/usr.sbin/edquota/edquota.8 index 8e43dab..15ab449 100644 --- a/usr.sbin/edquota/edquota.8 +++ b/usr.sbin/edquota/edquota.8 @@ -48,11 +48,21 @@ .Op Fl p Ar proto-username .Ar username ... .Nm +.Op Fl u +.Fl e Ar fspath Ns Op : Ns Ar bslim Ns Op : Ns Ar bhlim Ns Op : Ns Ar islim Ns Op : Ns Ar ihlim +.Op Fl e Ar ... +.Ar username ... +.Nm .Fl g .Op Fl f Ar fspath .Op Fl p Ar proto-groupname .Ar groupname ... .Nm +.Fl g +.Fl e Ar fspath Ns Op : Ns Ar bslim Ns Op : Ns Ar bhlim Ns Op : Ns Ar islim Ns Op : Ns Ar ihlim +.Op Fl e Ar ... +.Ar groupname ... +.Nm .Fl t .Op Fl u .Op Fl f Ar fspath @@ -118,6 +128,34 @@ for easy setup of default quotas for a group of users. The uids in question do not have to be currently assigned in .Pa /etc/passwd . .Pp +If one or more +.Fl e Ar fspath Ns Op : Ns Ar bslim Ns Op : Ns Ar bhlim Ns Op : Ns Ar islim Ns Op : Ns Ar ihlim +options are specified, +.Nm +will non-interactively set quotas defined by +.Ar bslim , +.Ar bhlim , +.Ar islim and +.Ar ihlim +on each particular filesystem referenced by +.Ar fspath . +Here +.Ar bslim +is soft limit on number of blocks, +.Ar bslim +is hard limit on number of blocks, +.Ar islim +is soft limit on number of files and +.Ar ihlim +is hard limit on number of files. +If any of the +.Ar bslim , +.Ar bhlim , +.Ar islim and +.Ar ihlim +values are omitted, it is assumed to be zero, therefore +indicating that no quota should be imposed. +.Pp If invoked with the .Fl f option, @@ -147,6 +185,13 @@ the .Fl g flag to specify a prototypical group to be duplicated among the listed set of groups. +Similarly, +.Fl e +flag can be specified in conjunction with +the +.Fl g +flag to non-interactively set-up quotas on the listed set +of groups. .Pp Users are permitted to exceed their soft limits for a grace period that may be specified per filesystem. diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 326c741..48e462a 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -101,12 +101,14 @@ int writeprivs(struct quotause *, int, char *, int); int main(int argc, char **argv) { - register struct quotause *qup, *protoprivs, *curprivs; - register long id, protoid; - register int quotatype, tmpfd; - register uid_t startuid, enduid; - char *protoname, *cp, ch; - int tflag = 0, pflag = 0; + struct quotause *qup, *protoprivs, *curprivs; + long id, protoid; + long long lim; + int i, quotatype, range, tmpfd; + uid_t startuid, enduid; + u_int32_t *limp; + char *protoname, *cp, *oldoptarg, ch; + int eflag = 0, tflag = 0, pflag = 0; char *fspath = NULL; char buf[30]; @@ -115,7 +117,8 @@ main(int argc, char **argv) if (getuid()) errx(1, "permission denied"); quotatype = USRQUOTA; - while ((ch = getopt(argc, argv, "ugtf:p:")) != -1) { + protoprivs = NULL; + while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) { switch(ch) { case 'f': fspath = optarg; @@ -133,6 +136,61 @@ main(int argc, char **argv) case 't': tflag++; break; + case 'e': + if ((qup = malloc(sizeof(*qup))) == NULL) + errx(2, "out of memory"); + bzero(qup, sizeof(*qup)); + i = 0; + oldoptarg = optarg; + for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; + i++) { + if (cp != oldoptarg) + *(cp - 1) = ':'; + limp = NULL; + switch (i) { + case 0: + strlcpy(qup->fsname, cp, + sizeof(qup->fsname)); + break; + case 1: + limp = &qup->dqblk.dqb_bsoftlimit; + break; + case 2: + limp = &qup->dqblk.dqb_bhardlimit; + break; + case 3: + limp = &qup->dqblk.dqb_isoftlimit; + break; + case 4: + limp = &qup->dqblk.dqb_ihardlimit; + break; + default: + warnx("incorrect quota specification: " + "%s", oldoptarg); + usage(); + break; /* XXX: report an error */ + } + if (limp != NULL) { + lim = strtoll(cp, NULL, 10); + if (lim < 0 || lim > UINT_MAX) + errx(1, "invalid limit value: " + "%lld", lim); + *limp = (u_int32_t)lim; + } + } + qup->dqblk.dqb_bsoftlimit = + btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); + qup->dqblk.dqb_bhardlimit = + btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); + if (protoprivs == NULL) { + protoprivs = curprivs = qup; + } else { + curprivs->next = qup; + curprivs = qup; + } + eflag++; + pflag++; + break; default: usage(); } @@ -140,12 +198,14 @@ main(int argc, char **argv) argc -= optind; argv += optind; if (pflag) { - if ((protoid = getentry(protoname, quotatype)) == -1) - exit(1); - protoprivs = getprivs(protoid, quotatype, fspath); - for (qup = protoprivs; qup; qup = qup->next) { - qup->dqblk.dqb_btime = 0; - qup->dqblk.dqb_itime = 0; + if (protoprivs == NULL) { + if ((protoid = getentry(protoname, quotatype)) == -1) + exit(1); + protoprivs = getprivs(protoid, quotatype, fspath); + for (qup = protoprivs; qup; qup = qup->next) { + qup->dqblk.dqb_btime = 0; + qup->dqblk.dqb_itime = 0; + } } for (; argc-- > 0; argv++) { if (strspn(*argv, "0123456789-") == strlen(*argv) && @@ -157,18 +217,35 @@ main(int argc, char **argv) errx(1, "ending uid (%d) must be >= starting uid (%d) when using uid ranges", enduid, startuid); - for ( ; startuid <= enduid; startuid++) { - snprintf(buf, sizeof(buf), "%d", + range = 1; + } else { + startuid = enduid = 0; + range = 0; + } + for ( ; startuid <= enduid; startuid++) { + if (range) + snprintf(buf, sizeof(buf), "%d", startuid); - if ((id = getentry(buf, quotatype)) < 0) - continue; - putprivs(id, quotatype, protoprivs); + else + snprintf(buf, sizeof(buf), "%s", + *argv); + if ((id = getentry(buf, quotatype)) < 0) + continue; + if (eflag) { + for (qup = protoprivs; qup; + qup = qup->next) { + curprivs = getprivs(id, + quotatype, qup->fsname); + if (curprivs == NULL) + continue; + strcpy(qup->qfname, + curprivs->qfname); + strcpy(qup->fsname, + curprivs->fsname); + } } - continue; + putprivs(id, quotatype, protoprivs); } - if ((id = getentry(*argv, quotatype)) < 0) - continue; - putprivs(id, quotatype, protoprivs); } exit(0); } @@ -203,9 +280,13 @@ main(int argc, char **argv) static void usage() { - fprintf(stderr, "%s\n%s\n%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: edquota [-u] [-f fspath] [-p username] username ...", + " edquota [-u] -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", + " username ...", " edquota -g [-f fspath] [-p groupname] groupname ...", + " edquota -g -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", + " groupname ...", " edquota [-u] -t [-f fspath]", " edquota -g -t [-f fspath]"); exit(1); |