From 723a1e7b01661c32d6448528b453e4a08a2d5881 Mon Sep 17 00:00:00 2001 From: mpp Date: Sun, 11 Feb 2007 16:25:25 +0000 Subject: Add two new options to quota: -f path Only print quota information for the file system that path resides on. -r Display the quota information in a raw format. Reviewed by: freebsd-hackers --- usr.bin/quota/quota.1 | 41 +++++++++++++++++++-------- usr.bin/quota/quota.c | 77 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 94 insertions(+), 24 deletions(-) (limited to 'usr.bin/quota') diff --git a/usr.bin/quota/quota.1 b/usr.bin/quota/quota.1 index 9150198..6a0ae1a 100644 --- a/usr.bin/quota/quota.1 +++ b/usr.bin/quota/quota.1 @@ -35,7 +35,7 @@ .\" from: @(#)quota.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd October 22, 2006 +.Dd Februry 3, 2007 .Dt QUOTA 1 .Os .Sh NAME @@ -44,15 +44,18 @@ .Sh SYNOPSIS .Nm .Op Fl ghlu -.Op Fl v | Fl q +.Op Fl f Ar path +.Op Fl v | Fl q | Fl r .Nm .Op Fl hlu -.Op Fl v | Fl q +.Op Fl f Ar path +.Op Fl v | Fl q | Fl r .Ar user ... .Nm .Fl g .Op Fl hl -.Op Fl v | Fl q +.Op Fl f Ar path +.Op Fl v | Fl q | Fl r .Ar group ... .Sh DESCRIPTION The @@ -63,6 +66,10 @@ Disk block usage and limits are shown in 1024-byte blocks. .Pp The following options are available: .Bl -tag -width indent +.It Fl f Ar path +Only display quota information for the file system +that contains the specified path. +This can be any file within a mounted file system. .It Fl g Print group quotas for the group of which the user is a member. @@ -77,6 +84,21 @@ file systems. Print a more terse message, containing only information on file systems where usage is over quota. +The +.Fl q +flag takes precedence over the +.Fl v +flag. +.It Fl r +Display the raw quota information as it appears in the quota structure. +Non-zero time values will be also be displayed in +.Xr ctime 3 +format. +This option implies +.Fl v +and will override the +.Fl q +flag. .It Fl u Print the user quotas. This is the default unless @@ -106,12 +128,6 @@ flag and optional argument to view only the limits of groups of which they are members. .Pp The -.Fl q -flag takes precedence over the -.Fl v -flag. -.Pp -The .Nm utility tries to report the quotas of all mounted file systems. If the file system is mounted via @@ -128,7 +144,9 @@ file systems, quotas must be turned on in If .Nm exits with a non-zero status, one or more file systems -are over quota. +are over quota or the path specified with the +.Fl f +option does not exist. .Pp If the .Fl l @@ -148,6 +166,7 @@ to find file system names and locations .El .Sh SEE ALSO .Xr quotactl 2 , +.Xr ctime 3 , .Xr fstab 5 , .Xr edquota 8 , .Xr quotacheck 8 , diff --git a/usr.bin/quota/quota.c b/usr.bin/quota/quota.c index afe1a3d..3792af4 100644 --- a/usr.bin/quota/quota.c +++ b/usr.bin/quota/quota.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include const char *qfname = QUOTAFILENAME; @@ -93,6 +94,7 @@ static int showgid(u_long gid); static int showusrname(char *name); static int showgrpname(char *name); static int showquotas(int type, u_long id, const char *name); +static void showrawquotas(int type, u_long id, struct quotause *qup); static void heading(int type, u_long id, const char *name, const char *tag); static int ufshasquota(struct fstab *fs, int type, char **qfnamep); static int getufsquota(struct fstab *fs, struct quotause *qup, long id, @@ -105,8 +107,10 @@ static int alldigits(char *s); int hflag; int lflag; +int rflag; int qflag; int vflag; +char *filename = NULL; int main(int argc, char *argv[]) @@ -115,8 +119,11 @@ main(int argc, char *argv[]) gid_t mygid, gidset[NGROUPS]; int i, ch, gflag = 0, uflag = 0, errflag = 0; - while ((ch = getopt(argc, argv, "ghlquv")) != -1) { + while ((ch = getopt(argc, argv, "f:ghlrquv")) != -1) { switch(ch) { + case 'f': + filename = optarg; + break; case 'g': gflag++; break; @@ -129,6 +136,9 @@ main(int argc, char *argv[]) case 'q': qflag++; break; + case 'r': + rflag++; + break; case 'u': uflag++; break; @@ -185,9 +195,9 @@ usage(void) { fprintf(stderr, "%s\n%s\n%s\n", - "usage: quota [-ghlu] [-v | -q]", - " quota [-hlu] [-v | -q] user ...", - " quota -g [-hl] [-v | -q] group ..."); + "usage: quota [-ghlu] [-f path] [-v | -q | -r]", + " quota [-hlu] [-f path] [-v | -q | -r] user ...", + " quota -g [-hl] [-f path] [-v | -q | -r] group ..."); exit(1); } @@ -280,12 +290,6 @@ showquotas(int type, u_long id, const char *name) time(&now); quplist = getprivs(id, type); for (qup = quplist; qup; qup = qup->next) { - if (!vflag && - qup->dqblk.dqb_isoftlimit == 0 && - qup->dqblk.dqb_ihardlimit == 0 && - qup->dqblk.dqb_bsoftlimit == 0 && - qup->dqblk.dqb_bhardlimit == 0) - continue; msgi = (char *)0; if (qup->dqblk.dqb_ihardlimit && qup->dqblk.dqb_curinodes >= qup->dqblk.dqb_ihardlimit) { @@ -314,6 +318,16 @@ showquotas(int type, u_long id, const char *name) else msgb = "Over block quota on"; } + if (rflag) { + showrawquotas(type, id, qup); + continue; + } + if (!vflag && + qup->dqblk.dqb_isoftlimit == 0 && + qup->dqblk.dqb_ihardlimit == 0 && + qup->dqblk.dqb_bsoftlimit == 0 && + qup->dqblk.dqb_bhardlimit == 0) + continue; if (qflag) { if ((msgi != (char *)0 || msgb != (char *)0) && lines++ == 0) @@ -369,12 +383,39 @@ showquotas(int type, u_long id, const char *name) continue; } } - if (!qflag && lines == 0) + if (!qflag && !rflag && lines == 0) heading(type, id, name, "none"); return(overquota); } static void +showrawquotas(type, id, qup) + int type; + u_long id; + struct quotause *qup; +{ + printf("Raw %s quota information for id %lu on %s\n", + type == USRQUOTA ? "user" : "group", id, qup->fsname); + printf("block hard limit: %lu\n", qup->dqblk.dqb_bhardlimit); + printf("block soft limit: %lu\n", qup->dqblk.dqb_bsoftlimit); + printf("current block count: %lu\n", qup->dqblk.dqb_curblocks); + printf("i-node hard limit: %lu\n", qup->dqblk.dqb_ihardlimit); + printf("i-node soft limit: %lu\n", qup->dqblk.dqb_isoftlimit); + printf("current i-node count: %lu\n", qup->dqblk.dqb_curinodes); + printf("block grace time: %ld", qup->dqblk.dqb_btime); + if (qup->dqblk.dqb_btime != 0) + printf(" %s", ctime(&qup->dqblk.dqb_btime)); + else + printf("\n"); + printf("i-node grace time: %ld", qup->dqblk.dqb_itime); + if (qup->dqblk.dqb_itime != 0) + printf(" %s", ctime(&qup->dqblk.dqb_itime)); + else + printf("\n"); +} + + +static void heading(int type, u_long id, const char *name, const char *tag) { @@ -444,9 +485,13 @@ getprivs(long id, int quotatype) struct quotause *quphead; struct statfs *fst; int nfst, i; + int len; + struct statfs sfb; qup = quphead = (struct quotause *)0; + if (filename != NULL && statfs(filename, &sfb) != 0) + err(1, "cannot statfs %s", filename); nfst = getmntinfo(&fst, MNT_NOWAIT); if (nfst == 0) errx(2, "no filesystems mounted!"); @@ -457,11 +502,17 @@ getprivs(long id, int quotatype) == NULL) errx(2, "out of memory"); } + /* + * See if the user requested a specific file system + * or specified a file inside a mounted file system. + */ + if (filename != NULL && + strcmp(sfb.f_mntonname, fst[i].f_mntonname) != 0) + continue; if (strcmp(fst[i].f_fstypename, "nfs") == 0) { if (lflag) continue; - if (getnfsquota(&fst[i], qup, id, quotatype) - == 0) + if (getnfsquota(&fst[i], qup, id, quotatype) == 0) continue; } else if (strcmp(fst[i].f_fstypename, "ufs") == 0) { /* -- cgit v1.1