diff options
-rw-r--r-- | usr.sbin/repquota/repquota.8 | 7 | ||||
-rw-r--r-- | usr.sbin/repquota/repquota.c | 196 |
2 files changed, 84 insertions, 119 deletions
diff --git a/usr.sbin/repquota/repquota.8 b/usr.sbin/repquota/repquota.8 index b669fdf..8b5ab68 100644 --- a/usr.sbin/repquota/repquota.8 +++ b/usr.sbin/repquota/repquota.8 @@ -39,12 +39,14 @@ .Nd summarize quotas for a file system .Sh SYNOPSIS .Nm +.Op Fl h .Op Fl g .Op Fl n .Op Fl u .Op Fl v .Ar filesystem Ar ... .Nm +.Op Fl h .Op Fl g .Op Fl n .Op Fl u @@ -64,6 +66,9 @@ Print the quotas of all the file systems listed in .It Fl g Print only group quotas (the default is to print both group and user quotas if they exist). +.It Fl h +Display information in a more human readable format +rather than in historic kilobyte format. .It Fl n Display user and group IDs numerically rather than converting to a user or group name. @@ -75,7 +80,7 @@ Print a header line before printing each file system quotas. .El .Pp For each user or group, the current -number files and amount of space (in kilobytes) is +number files and amount of space is printed, along with any quotas created with .Xr edquota 8 . .Pp diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index 19c1858..276a78d 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$"); #include <ufs/ufs/quota.h> #include <err.h> #include <errno.h> +#include <fcntl.h> #include <fstab.h> #include <grp.h> +#include <libutil.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> @@ -80,7 +82,6 @@ const char *qfextension[] = INITQFNAMES; struct fileusage { struct fileusage *fu_next; - struct dqblk fu_dqblk; u_long fu_id; char fu_name[1]; /* actually bigger */ @@ -94,11 +95,12 @@ u_long highid[MAXQUOTAS]; /* highest addid()'ed identifier per type */ int vflag; /* verbose */ int aflag; /* all filesystems */ int nflag; /* display user/group by id */ +int hflag; /* display in human readable format */ -int hasquota(struct fstab *, int, char **); int oneof(char *, char *[], int); -int repquota(struct fstab *, int, char *); +int repquota(struct fstab *, int); char *timeprt(time_t); +static void prthumanval(int64_t bytes); static void usage(void); int @@ -109,9 +111,8 @@ main(int argc, char *argv[]) struct group *gr; int ch, gflag = 0, uflag = 0, errs = 0; long i, argnum, done = 0; - char *qfnp; - while ((ch = getopt(argc, argv, "agnuv")) != -1) { + while ((ch = getopt(argc, argv, "aghnuv")) != -1) { switch(ch) { case 'a': aflag++; @@ -119,6 +120,9 @@ main(int argc, char *argv[]) case 'g': gflag++; break; + case 'h': + hflag++; + break; case 'n': nflag++; break; @@ -158,19 +162,19 @@ main(int argc, char *argv[]) if (strcmp(fs->fs_vfstype, "ufs")) continue; if (aflag) { - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += repquota(fs, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += repquota(fs, USRQUOTA, qfnp); + if (gflag) + errs += repquota(fs, GRPQUOTA); + if (uflag) + errs += repquota(fs, USRQUOTA); continue; } if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { done |= 1 << argnum; - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += repquota(fs, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += repquota(fs, USRQUOTA, qfnp); + if (gflag) + errs += repquota(fs, GRPQUOTA); + if (uflag) + errs += repquota(fs, USRQUOTA); } } endfsent(); @@ -184,87 +188,92 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n", - "usage: repquota [-v] [-g] [-n] [-u] -a", - " repquota [-v] [-g] [-n] [-u] filesystem ..."); + "usage: repquota [-h] [-v] [-g] [-n] [-u] -a", + " repquota [-h] [-v] [-g] [-n] [-u] filesystem ..."); exit(1); } int -repquota(struct fstab *fs, int type, char *qfpathname) +repquota(struct fstab *fs, int type) { struct fileusage *fup; - FILE *qf; - u_long id; + struct quotafile *qf; + u_long id, maxid; struct dqblk dqbuf; - static struct dqblk zerodqblk; - static int warned = 0; static int multiple = 0; - if (quotactl(fs->fs_file, QCMD(Q_SYNC, type), 0, 0) < 0 && - errno == EOPNOTSUPP && !warned && vflag) { - warned++; - fprintf(stdout, - "*** Warning: Quotas are not compiled into this kernel\n"); + if ((qf = quota_open(fs, type, O_RDONLY)) == NULL) { + if (vflag && !aflag) { + if (multiple++) + printf("\n"); + fprintf(stdout, "*** No %s quotas on %s (%s)\n", + qfextension[type], fs->fs_file, fs->fs_spec); + } + return(0); } if (multiple++) printf("\n"); if (vflag) fprintf(stdout, "*** Report for %s quotas on %s (%s)\n", qfextension[type], fs->fs_file, fs->fs_spec); - if ((qf = fopen(qfpathname, "r")) == NULL) { - warn("%s", qfpathname); - return (1); - } - for (id = 0; ; id++) { - fread(&dqbuf, sizeof(struct dqblk), 1, qf); - if (feof(qf)) + printf("%*s Block limits File limits\n", + max(UT_NAMESIZE,10), " "); + printf("User%*s used soft hard grace used soft hard grace\n", + max(UT_NAMESIZE,10), " "); + maxid = quota_maxid(qf); + for (id = 0; id <= maxid; id++) { + if (quota_read(qf, &dqbuf, id) != 0) break; if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) continue; if ((fup = lookup(id, type)) == 0) fup = addid(id, type, (char *)0); - fup->fu_dqblk = dqbuf; - } - fclose(qf); - printf("%*s Block limits File limits\n", - max(UT_NAMESIZE,10), " "); - printf("%s%*s used soft hard grace used soft hard grace\n", - type == USRQUOTA ? "User " : "Group", max(UT_NAMESIZE,10), " "); - for (id = 0; id <= highid[type]; id++) { - fup = lookup(id, type); - if (fup == 0) - continue; - if (fup->fu_dqblk.dqb_curinodes == 0 && - fup->fu_dqblk.dqb_curblocks == 0) - continue; printf("%-*s ", max(UT_NAMESIZE,10), fup->fu_name); - printf("%c%c %8lu %8lu %8lu %6s", - fup->fu_dqblk.dqb_bsoftlimit && - fup->fu_dqblk.dqb_curblocks >= - fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-', - fup->fu_dqblk.dqb_isoftlimit && - fup->fu_dqblk.dqb_curinodes >= - fup->fu_dqblk.dqb_isoftlimit ? '+' : '-', - (u_long)(dbtokb(fup->fu_dqblk.dqb_curblocks)), - (u_long)(dbtokb(fup->fu_dqblk.dqb_bsoftlimit)), - (u_long)(dbtokb(fup->fu_dqblk.dqb_bhardlimit)), - fup->fu_dqblk.dqb_bsoftlimit && - fup->fu_dqblk.dqb_curblocks >= - fup->fu_dqblk.dqb_bsoftlimit ? - timeprt(fup->fu_dqblk.dqb_btime) : "-"); - printf(" %7lu %7lu %7lu %6s\n", - (u_long)fup->fu_dqblk.dqb_curinodes, - (u_long)fup->fu_dqblk.dqb_isoftlimit, - (u_long)fup->fu_dqblk.dqb_ihardlimit, - fup->fu_dqblk.dqb_isoftlimit && - fup->fu_dqblk.dqb_curinodes >= - fup->fu_dqblk.dqb_isoftlimit ? - timeprt(fup->fu_dqblk.dqb_itime) : "-"); - fup->fu_dqblk = zerodqblk; + printf("%c%c", + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? '+' : '-', + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? '+' : '-'); + prthumanval(dqbuf.dqb_curblocks); + prthumanval(dqbuf.dqb_bsoftlimit); + prthumanval(dqbuf.dqb_bhardlimit); + printf(" %6s", + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? + timeprt(dqbuf.dqb_btime) : "-"); + printf(" %7llu %7llu %7llu %6s\n", + dqbuf.dqb_curinodes, + dqbuf.dqb_isoftlimit, + dqbuf.dqb_ihardlimit, + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? + timeprt(dqbuf.dqb_itime) : "-"); } return (0); } +static void +prthumanval(int64_t blocks) +{ + char buf[7]; + int flags; + + if (!hflag) { + printf("%7llu", dbtokb(blocks)); + return; + } + flags = HN_NOSPACE | HN_DECIMAL; + if (blocks != 0) + flags |= HN_B; + humanize_number(buf, sizeof(buf) - (blocks < 0 ? 0 : 1), + dbtob(blocks), "", HN_AUTOSCALE, flags); + (void)printf("%7s", buf); +} + /* * Check to see if target appears in list of size cnt. */ @@ -280,55 +289,6 @@ oneof(char *target, char *list[], int cnt) } /* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char **qfnamep) -{ - char *opt; - char *cp; - struct statfs sfb; - static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], qfname); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], qfname); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - return (0); - } - return (1); -} - -/* * Routines to manage the file usage table. * * Lookup an id of a specific type. |