summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/edquota/edquota.845
-rw-r--r--usr.sbin/edquota/edquota.c127
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);
OpenPOWER on IntegriCloud