Add new command-line flags, which ease edquota use in bach scripts:

- -f, which allows to restrict edquota to only one quota-enabled filesystem
- -s and -h, which allows to set soft and hard limits respectively, without
  the need to edit a file.
This commit is contained in:
bouyer 2002-12-04 21:01:13 +00:00
parent 1a82d4f05f
commit fecc966e36
2 changed files with 119 additions and 22 deletions

View File

@ -33,9 +33,9 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)edquota.8 8.2 (Berkeley) 4/27/95
.\" $NetBSD: edquota.8,v 1.8 2002/01/19 03:11:34 wiz Exp $
.\" $NetBSD: edquota.8,v 1.9 2002/12/04 21:01:13 bouyer Exp $
.\"
.Dd April 27, 1995
.Dd December 4, 2002
.Dt EDQUOTA 8
.Os
.Sh NAME
@ -44,18 +44,34 @@
.Sh SYNOPSIS
.Nm
.Op Fl u
.Op Fl f Ar filesystem
.Op Fl p Ar proto-username
.Ar username ...
.Nm ""
.Fl g
.Op Fl f Ar filesystem
.Op Fl p Ar proto-groupname
.Ar groupname ...
.Nm ""
.Fl t
.Op Fl u
.Op Fl f Ar filesystem
.Op Fl h Ar block#/inode#
.Op Fl s Ar block#/inode#
.Ar username ...
.Nm ""
.Fl t
.Fl g
.Op Fl f Ar filesystem
.Op Fl h Ar block#/inode#
.Op Fl s Ar block#/inode#
.Ar groupname ...
.Nm ""
.Op Fl u
.Op Fl f Ar filesystem
.Fl t
.Nm ""
.Fl g
.Op Fl f Ar filesystem
.Fl t
.Sh DESCRIPTION
.Nm
is a quota editor.
@ -63,11 +79,17 @@ By default, or if the
.Fl u
flag is specified,
one or more users may be specified on the command line.
For each user a temporary file is created
with an ASCII representation of the current
disk quotas for that user.
Unless
.Fl h
or
.Fl s
are used, a temporary file is created for each user with an ASCII
representation of the current disk quotas for that user.
The list of filesystems with user quotas is determined from
.Pa /etc/fstab .
By default, quota for all quota-enabled filesystems are edited; the
.Fl f
option can be used to restrict it to a single filesystem.
An editor is invoked on the ASCII file.
The editor invoked is
.Xr vi 1
@ -98,8 +120,15 @@ flag is specified,
.Nm
will duplicate the quotas of the prototypical user
specified for each user specified.
This is the normal mechanism used to
initialize quotas for groups of users.
This is the normal mechanism used to initialize quotas for groups of users.
.Pp
The
.Fl h
and
.Fl s
flags can be used to change quota limits (soft and hard, respectively)
without user interaction, for usage in e.g. batch scripts.
The arguments are the new block and inode number limit, separated by a slash.
.Pp
If the
.Fl g
@ -109,8 +138,7 @@ is invoked to edit the quotas of
one or more groups specified on the command line.
The
.Fl p
flag can be specified in conjunction with
the
flag can be specified in conjunction with the
.Fl g
flag to specify a prototypical group
to be duplicated among the listed set of groups.

View File

@ -44,7 +44,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\n\
#if 0
static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: edquota.c,v 1.21 2000/04/14 06:26:53 simonb Exp $");
__RCSID("$NetBSD: edquota.c,v 1.22 2002/12/04 21:01:13 bouyer Exp $");
#endif
#endif /* not lint */
@ -88,7 +88,7 @@ int main __P((int, char **));
void usage __P((void));
int getentry __P((char *, int));
struct quotause *
getprivs __P((long, int));
getprivs __P((long, int, char *));
void putprivs __P((long, int, struct quotause *));
int editit __P((char *));
int writeprivs __P((struct quotause *, int, char *, int));
@ -110,6 +110,8 @@ main(argc, argv)
long id, protoid;
int quotatype, tmpfd;
char *protoname;
char *soft = NULL, *hard = NULL;
char *fs = NULL;
int ch;
int tflag = 0, pflag = 0;
@ -119,7 +121,7 @@ main(argc, argv)
errx(1, "permission denied");
protoname = NULL;
quotatype = USRQUOTA;
while ((ch = getopt(argc, argv, "ugtp:")) != -1) {
while ((ch = getopt(argc, argv, "ugtp:s:h:f:")) != -1) {
switch(ch) {
case 'p':
protoname = optarg;
@ -134,6 +136,15 @@ main(argc, argv)
case 't':
tflag++;
break;
case 's':
soft = optarg;
break;
case 'h':
hard = optarg;
break;
case 'f':
fs = optarg;
break;
default:
usage();
}
@ -141,9 +152,11 @@ main(argc, argv)
argc -= optind;
argv += optind;
if (pflag) {
if (soft || hard)
usage();
if ((protoid = getentry(protoname, quotatype)) == -1)
exit(1);
protoprivs = getprivs(protoid, quotatype);
protoprivs = getprivs(protoid, quotatype, fs);
for (qup = protoprivs; qup; qup = qup->next) {
qup->dqblk.dqb_btime = 0;
qup->dqblk.dqb_itime = 0;
@ -155,10 +168,58 @@ main(argc, argv)
}
exit(0);
}
if (soft || hard) {
struct quotause *qup;
u_int32_t softb, hardb, softi, hardi;
if (tflag)
usage();
if (soft) {
if (sscanf(soft, "%d/%d", &softb, &softi) != 2)
usage();
softb = btodb((u_quad_t)softb * 1024);
}
if (hard) {
if (sscanf(hard, "%d/%d", &hardb, &hardi) != 2)
usage();
hardb = btodb((u_quad_t)hardb * 1024);
}
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
continue;
curprivs = getprivs(id, quotatype, fs);
for (qup = curprivs; qup; qup = qup->next) {
if (soft) {
if (softb &&
qup->dqblk.dqb_curblocks >= softb &&
(qup->dqblk.dqb_bsoftlimit == 0 ||
qup->dqblk.dqb_curblocks <
qup->dqblk.dqb_bsoftlimit))
qup->dqblk.dqb_btime = 0;
if (softi &&
qup->dqblk.dqb_curinodes >= softi &&
(qup->dqblk.dqb_isoftlimit == 0 ||
qup->dqblk.dqb_curinodes <
qup->dqblk.dqb_isoftlimit))
qup->dqblk.dqb_itime = 0;
qup->dqblk.dqb_bsoftlimit = softb;
qup->dqblk.dqb_isoftlimit = softi;
}
if (hard) {
qup->dqblk.dqb_bhardlimit = hardb;
qup->dqblk.dqb_ihardlimit = hardi;
}
}
putprivs(id, quotatype, curprivs);
freeprivs(curprivs);
}
exit(0);
}
tmpfd = mkstemp(tmpfil);
fchown(tmpfd, getuid(), getgid());
if (tflag) {
protoprivs = getprivs(0, quotatype);
if (soft || hard)
usage();
protoprivs = getprivs(0, quotatype, fs);
if (writetimes(protoprivs, tmpfd, quotatype) == 0)
exit(1);
if (editit(tmpfil) && readtimes(protoprivs, tmpfd))
@ -169,7 +230,7 @@ main(argc, argv)
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
continue;
curprivs = getprivs(id, quotatype);
curprivs = getprivs(id, quotatype, fs);
if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
continue;
if (editit(tmpfil) && readprivs(curprivs, tmpfd))
@ -184,10 +245,14 @@ main(argc, argv)
void
usage()
{
fprintf(stderr, "%s%s%s%s",
"Usage: edquota [-u] [-p username] username ...\n",
"\tedquota -g [-p groupname] groupname ...\n",
"\tedquota [-u] -t\n", "\tedquota -g -t\n");
fprintf(stderr,
"Usage: edquota [-u] [-p username] [-f filesystem] username ...\n"
"\tedquota -g [-p groupname] [-f filesystem] groupname ...\n"
"\tedquota [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] username ...\n"
"\tedquota -g [-f filesystem] [-s b#/i#] [-h b#/i#] groupname ...\n"
"\tedquota [-u] [-f filesystem] -t\n"
"\tedquota -g [-f filesystem] -t\n"
);
exit(1);
}
@ -229,9 +294,10 @@ getentry(name, quotatype)
* Collect the requested quota information.
*/
struct quotause *
getprivs(id, quotatype)
getprivs(id, quotatype, filesys)
long id;
int quotatype;
char *filesys;
{
struct fstab *fs;
struct quotause *qup, *quptail;
@ -247,6 +313,9 @@ getprivs(id, quotatype)
while ((fs = getfsent()) != NULL) {
if (strcmp(fs->fs_vfstype, "ffs"))
continue;
if (filesys && strcmp(fs->fs_spec, filesys) != 0 &&
strcmp(fs->fs_file, filesys) != 0)
continue;
if (!hasquota(fs, quotatype, &qfpathname))
continue;
qupsize = sizeof(*qup) + strlen(qfpathname);