svn commit: r198266 - projects/quota64/usr.sbin/repquota

Kirk McKusick mckusick at FreeBSD.org
Tue Oct 20 05:40:52 UTC 2009


Author: mckusick
Date: Tue Oct 20 05:40:51 2009
New Revision: 198266
URL: http://svn.freebsd.org/changeset/base/198266

Log:
  Update to work with quotafile functions in -libutil.
  Add -h flag to provide humanized output.

Modified:
  projects/quota64/usr.sbin/repquota/repquota.8
  projects/quota64/usr.sbin/repquota/repquota.c

Modified: projects/quota64/usr.sbin/repquota/repquota.8
==============================================================================
--- projects/quota64/usr.sbin/repquota/repquota.8	Tue Oct 20 05:37:54 2009	(r198265)
+++ projects/quota64/usr.sbin/repquota/repquota.8	Tue Oct 20 05:40:51 2009	(r198266)
@@ -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
 .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
 .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

Modified: projects/quota64/usr.sbin/repquota/repquota.c
==============================================================================
--- projects/quota64/usr.sbin/repquota/repquota.c	Tue Oct 20 05:37:54 2009	(r198265)
+++ projects/quota64/usr.sbin/repquota/repquota.c	Tue Oct 20 05:40:51 2009	(r198266)
@@ -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 add
 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 cn
 }
 
 /*
- * 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.


More information about the svn-src-projects mailing list