Module Name: src
Committed By: bouyer
Date: Sun Jan 30 19:38:46 UTC 2011
Modified Files:
src/sys/ufs/ufs [bouyer-quota2]: ufs_quota.c
src/usr.bin/quota [bouyer-quota2]: getvfsquota.c getvfsquota.h
printquota.c printquota.h quota.c
src/usr.sbin/edquota [bouyer-quota2]: edquota.c
src/usr.sbin/repquota [bouyer-quota2]: repquota.c
Log Message:
Implement "get version" quotactl command, which return the filesystem's
enabled quota versiob (1 for legacy, 2 for new).
For quota2, make quota and repquota print the user's allowed grace period
if -v is given and not overquota (if overquota, the remaining time is
printed instead, as usual).
To generate a diff of this commit:
cvs rdiff -u -r1.68.4.4 -r1.68.4.5 src/sys/ufs/ufs/ufs_quota.c
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/usr.bin/quota/getvfsquota.c \
src/usr.bin/quota/getvfsquota.h
cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/usr.bin/quota/printquota.c \
src/usr.bin/quota/printquota.h
cvs rdiff -u -r1.33.2.3 -r1.33.2.4 src/usr.bin/quota/quota.c
cvs rdiff -u -r1.29.16.2 -r1.29.16.3 src/usr.sbin/edquota/edquota.c
cvs rdiff -u -r1.25.2.2 -r1.25.2.3 src/usr.sbin/repquota/repquota.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.68.4.4 src/sys/ufs/ufs/ufs_quota.c:1.68.4.5
--- src/sys/ufs/ufs/ufs_quota.c:1.68.4.4 Sun Jan 30 00:25:19 2011
+++ src/sys/ufs/ufs/ufs_quota.c Sun Jan 30 19:38:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $ */
+/* $NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $");
#if defined(_KERNEL_OPT)
#include "opt_quota.h"
@@ -60,6 +60,8 @@
kmutex_t dqlock;
kcondvar_t dqcv;
+static int quota_handle_cmd_get_version(struct mount *, struct lwp *,
+ prop_dictionary_t, prop_array_t);
static int quota_handle_cmd_get(struct mount *, struct lwp *,
prop_dictionary_t, int, prop_array_t);
static int quota_handle_cmd_set(struct mount *, struct lwp *,
@@ -151,6 +153,10 @@
prop_object_retain(datas);
prop_dictionary_remove(cmddict, "data"); /* prepare for return */
+ if (strcmp(cmd, "get version") == 0) {
+ error = quota_handle_cmd_get_version(mp, l, cmddict, datas);
+ goto end;
+ }
if (strcmp(cmd, "get") == 0) {
error = quota_handle_cmd_get(mp, l, cmddict, q2type, datas);
goto end;
@@ -171,6 +177,52 @@
return error;
}
+static int
+quota_handle_cmd_get_version(struct mount *mp, struct lwp *l,
+ prop_dictionary_t cmddict, prop_array_t datas)
+{
+ struct ufsmount *ump = VFSTOUFS(mp);
+ prop_array_t replies;
+ prop_dictionary_t data;
+ int error = 0;
+
+ if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0)
+ return EOPNOTSUPP;
+
+ replies = prop_array_create();
+ if (replies == NULL)
+ return ENOMEM;
+
+ data = prop_dictionary_create();
+ if (data == NULL) {
+ prop_object_release(replies);
+ return ENOMEM;
+ }
+
+#ifdef QUOTA
+ if (ump->um_flags & UFS_QUOTA) {
+ if (!prop_dictionary_set_int8(data, "version", 1))
+ error = ENOMEM;
+ } else
+#endif
+#ifdef QUOTA2
+ if (ump->um_flags & UFS_QUOTA2) {
+ if (!prop_dictionary_set_int8(data, "version", 2))
+ error = ENOMEM;
+ } else
+#endif
+ error = 0;
+ if (error)
+ prop_object_release(data);
+ else if (!prop_array_add_and_rel(replies, data))
+ error = ENOMEM;
+ if (error)
+ prop_object_release(replies);
+ else if (!prop_dictionary_set_and_rel(cmddict, "data", replies))
+ error = ENOMEM;
+ return error;
+}
+
/* XXX shouldn't all this be in kauth ? */
static int
quota_get_auth(struct mount *mp, struct lwp *l, uid_t id) {
Index: src/usr.bin/quota/getvfsquota.c
diff -u src/usr.bin/quota/getvfsquota.c:1.1.2.1 src/usr.bin/quota/getvfsquota.c:1.1.2.2
--- src/usr.bin/quota/getvfsquota.c:1.1.2.1 Fri Jan 28 22:15:36 2011
+++ src/usr.bin/quota/getvfsquota.c Sun Jan 30 19:38:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: getvfsquota.c,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $ */
+/* $NetBSD: getvfsquota.c,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: getvfsquota.c,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $");
+__RCSID("$NetBSD: getvfsquota.c,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $");
#include <stdio.h>
#include <stdlib.h>
@@ -48,15 +48,17 @@
/* retrieve quotas from vfs, for the given user id */
int
-getvfsquota(const char *mp, struct quota2_entry *q2e, long id, int type,
- int defaultq, int debug)
+getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
+ long id, int type, int defaultq, int debug)
{
prop_dictionary_t dict, data, cmd;
prop_array_t cmds, datas;
+ prop_object_iterator_t iter;
struct plistref pref;
int error;
int8_t error8;
bool ret;
+ int retval = 0;
dict = quota2_prop_create();
cmds = prop_array_create();
@@ -78,6 +80,9 @@
prop_object_release(data);
if (!quota2_prop_add_command(cmds, "get", qfextension[type], datas))
err(1, "prop_add_command");
+ if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
+ prop_array_create()))
+ err(1, "prop_add_command");
if (!prop_dictionary_set(dict, "commands", cmds))
err(1, "prop_dictionary_set(command)");
if (debug)
@@ -102,46 +107,64 @@
errx(1, "quota2_get_cmds: %s\n",
strerror(error));
}
- /* only one command, no need to iter */
- cmd = prop_array_get(cmds, 0);
- if (cmd == NULL)
- err(1, "prop_array_get(cmd)");
-
- if (!prop_dictionary_get_int8(cmd, "return", &error8))
- err(1, "prop_get(return)");
-
- if (error8) {
- if (error8 != ENOENT && error8 != ENODEV) {
- if (defaultq)
- fprintf(stderr, "get default %s quota: %s\n",
- qfextension[type], strerror(error8));
- else
- fprintf(stderr, "get %s quota for %ld: %s\n",
- qfextension[type], id, strerror(error8));
+ iter = prop_array_iterator(cmds);
+ if (iter == NULL)
+ err(1, "prop_array_iterator(cmds)");
+
+ while ((cmd = prop_object_iterator_next(iter)) != NULL) {
+ const char *cmdstr;
+ if (!prop_dictionary_get_cstring_nocopy(cmd, "command",
+ &cmdstr))
+ err(1, "prop_get(command)");
+ if (!prop_dictionary_get_int8(cmd, "return", &error8))
+ err(1, "prop_get(return)");
+
+ if (error8) {
+ if (error8 != ENOENT && error8 != ENODEV) {
+ if (defaultq) {
+ fprintf(stderr,
+ "get default %s quota: %s\n",
+ qfextension[type],
+ strerror(error8));
+ } else {
+ fprintf(stderr,
+ "get %s quota for %ld: %s\n",
+ qfextension[type], id,
+ strerror(error8));
+ }
+ }
+ prop_object_release(dict);
+ return (0);
+ }
+ datas = prop_dictionary_get(cmd, "data");
+ if (datas == NULL)
+ err(1, "prop_dict_get(datas)");
+
+ if (strcmp("get version", cmdstr) == 0) {
+ data = prop_array_get(datas, 0);
+ if (data == NULL)
+ err(1, "prop_array_get(version)");
+ if (!prop_dictionary_get_int8(data, "version", versp))
+ err(1, "prop_get_int8(version)");
+ continue;
+ }
+ if (strcmp("get", cmdstr) != 0)
+ err(1, "unknown command %s in reply", cmdstr);
+
+ /* only one data, no need to iter */
+ if (prop_array_count(datas) > 0) {
+ data = prop_array_get(datas, 0);
+ if (data == NULL)
+ err(1, "prop_array_get(data)");
+
+ error = quota2_dict_get_q2e_usage(data, q2e);
+ if (error) {
+ errx(1, "quota2_dict_get_q2e_usage: %s\n",
+ strerror(error));
+ }
+ retval = 1;
}
- prop_object_release(dict);
- return (0);
- }
- datas = prop_dictionary_get(cmd, "data");
- if (datas == NULL)
- err(1, "prop_dict_get(datas)");
-
- /* only one data, no need to iter */
- if (prop_array_count(datas) == 0) {
- /* no quota for this user/group */
- prop_object_release(dict);
- return (0);
- }
-
- data = prop_array_get(datas, 0);
- if (data == NULL)
- err(1, "prop_array_get(data)");
-
- error = quota2_dict_get_q2e_usage(data, q2e);
- if (error) {
- errx(1, "quota2_dict_get_q2e_usage: %s\n",
- strerror(error));
}
prop_object_release(dict);
- return (1);
+ return retval;
}
Index: src/usr.bin/quota/getvfsquota.h
diff -u src/usr.bin/quota/getvfsquota.h:1.1.2.1 src/usr.bin/quota/getvfsquota.h:1.1.2.2
--- src/usr.bin/quota/getvfsquota.h:1.1.2.1 Fri Jan 28 22:15:36 2011
+++ src/usr.bin/quota/getvfsquota.h Sun Jan 30 19:38:45 2011
@@ -1,5 +1,6 @@
-/* $NetBSD: getvfsquota.h,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $ */
+/* $NetBSD: getvfsquota.h,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $ */
-int getvfsquota(const char *, struct quota2_entry *, long, int, int, int);
+int getvfsquota(const char *, struct quota2_entry *, int8_t *,
+ long, int, int, int);
extern const char *qfextension[];
Index: src/usr.bin/quota/printquota.c
diff -u src/usr.bin/quota/printquota.c:1.1.2.3 src/usr.bin/quota/printquota.c:1.1.2.4
--- src/usr.bin/quota/printquota.c:1.1.2.3 Sun Jan 30 00:21:08 2011
+++ src/usr.bin/quota/printquota.c Sun Jan 30 19:38:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: printquota.c,v 1.1.2.3 2011/01/30 00:21:08 bouyer Exp $ */
+/* $NetBSD: printquota.c,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: printquota.c,v 1.1.2.3 2011/01/30 00:21:08 bouyer Exp $");
+__RCSID("$NetBSD: printquota.c,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $");
#endif
#endif /* not lint */
@@ -100,14 +100,11 @@
* Calculate the grace period and return a printable string for it.
*/
const char *
-timeprt(time_t seconds)
+timeprt(time_t now, time_t seconds)
{
time_t hours, minutes;
static char buf[20];
- static time_t now;
- if (now == 0)
- time(&now);
if (now > seconds)
return ("none");
seconds -= now;
Index: src/usr.bin/quota/printquota.h
diff -u src/usr.bin/quota/printquota.h:1.1.2.3 src/usr.bin/quota/printquota.h:1.1.2.4
--- src/usr.bin/quota/printquota.h:1.1.2.3 Sat Jan 29 17:42:37 2011
+++ src/usr.bin/quota/printquota.h Sun Jan 30 19:38:45 2011
@@ -1,7 +1,7 @@
-/* $NetBSD: printquota.h,v 1.1.2.3 2011/01/29 17:42:37 bouyer Exp $ */
+/* $NetBSD: printquota.h,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $ */
const char *intprt(uint64_t, u_int, int);
#define HN_PRIV_UNLIMITED 0x80000000 /* print "unlimited" instead of "-" */
-const char *timeprt(time_t);
+const char *timeprt(time_t, time_t);
int intrd(char *str, uint64_t *val, u_int);
Index: src/usr.bin/quota/quota.c
diff -u src/usr.bin/quota/quota.c:1.33.2.3 src/usr.bin/quota/quota.c:1.33.2.4
--- src/usr.bin/quota/quota.c:1.33.2.3 Fri Jan 28 22:15:36 2011
+++ src/usr.bin/quota/quota.c Sun Jan 30 19:38:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: quota.c,v 1.33.2.3 2011/01/28 22:15:36 bouyer Exp $ */
+/* $NetBSD: quota.c,v 1.33.2.4 2011/01/30 19:38:45 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: quota.c,v 1.33.2.3 2011/01/28 22:15:36 bouyer Exp $");
+__RCSID("$NetBSD: quota.c,v 1.33.2.4 2011/01/30 19:38:45 bouyer Exp $");
#endif
#endif /* not lint */
@@ -85,6 +85,7 @@
char fsname[MAXPATHLEN + 1];
};
#define FOUND 0x01
+#define QUOTA2 0x02
int alldigits(char *);
int callaurpc(char *, int, int, int, xdrproc_t, void *, xdrproc_t, void *);
@@ -336,7 +337,7 @@
{
struct quotause *qup;
struct quotause *quplist;
- const char *msgi, *msgb, *nam;
+ const char *msgi, *msgb, *nam, *timemsg;
int lines = 0;
static time_t now;
@@ -396,6 +397,15 @@
printf("%s\n", qup->fsname);
nam = "";
}
+ if (msgb)
+ timemsg = timeprt(now,
+ qup->q2e.q2e_val[Q2V_BLOCK].q2v_time);
+ else if ((qup->flags & QUOTA2) != 0 && vflag)
+ timemsg = timeprt(0,
+ qup->q2e.q2e_val[Q2V_BLOCK].q2v_grace);
+ else
+ timemsg = NULL;
+
printf("%12s%9s%c%8s%9s%8s"
, nam
, intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur
@@ -405,8 +415,17 @@
, HN_B, hflag)
, intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit
, HN_B, hflag)
- , (msgb == NULL) ? ""
- : timeprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_time));
+ , timemsg);
+
+ if (msgi)
+ timemsg = timeprt(now,
+ qup->q2e.q2e_val[Q2V_FILE].q2v_time);
+ else if ((qup->flags & QUOTA2) != 0 && vflag)
+ timemsg = timeprt(0,
+ qup->q2e.q2e_val[Q2V_FILE].q2v_grace);
+ else
+ timemsg = NULL;
+
printf("%8s%c%7s%8s%8s\n"
, intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_cur
, 0, hflag)
@@ -415,9 +434,7 @@
, 0, hflag)
, intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit
, 0, hflag)
- , (msgi == NULL) ? ""
- : timeprt(qup->q2e.q2e_val[Q2V_FILE].q2v_time)
- );
+ , timemsg);
continue;
}
}
@@ -466,6 +483,7 @@
struct quotause *quphead;
struct statvfs *fst;
int nfst, i;
+ int8_t version;
qup = quphead = quptail = NULL;
@@ -480,18 +498,21 @@
}
if (strncmp(fst[i].f_fstypename, "nfs",
sizeof(fst[i].f_fstypename)) == 0) {
+ version = 0;
if (getnfsquota(&fst[i], NULL, qup, id, quotatype) == 0)
continue;
} else if (strncmp(fst[i].f_fstypename, "ffs",
sizeof(fst[i].f_fstypename)) == 0 &&
(fst[i].f_flag & ST_QUOTA) != 0) {
- if (getvfsquota(fst[i].f_mntonname, &qup->q2e,
+ if (getvfsquota(fst[i].f_mntonname, &qup->q2e, &version,
id, quotatype, dflag, Dflag) == 0)
continue;
} else
continue;
(void)strncpy(qup->fsname, fst[i].f_mntonname,
sizeof(qup->fsname) - 1);
+ if (version == 2)
+ qup->flags |= QUOTA2;
if (quphead == NULL)
quphead = qup;
else
Index: src/usr.sbin/edquota/edquota.c
diff -u src/usr.sbin/edquota/edquota.c:1.29.16.2 src/usr.sbin/edquota/edquota.c:1.29.16.3
--- src/usr.sbin/edquota/edquota.c:1.29.16.2 Sun Jan 30 12:38:32 2011
+++ src/usr.sbin/edquota/edquota.c Sun Jan 30 19:38:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: edquota.c,v 1.29.16.2 2011/01/30 12:38:32 bouyer Exp $ */
+/* $NetBSD: edquota.c,v 1.29.16.3 2011/01/30 19:38:45 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
#else
-__RCSID("$NetBSD: edquota.c,v 1.29.16.2 2011/01/30 12:38:32 bouyer Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.29.16.3 2011/01/30 19:38:45 bouyer Exp $");
#endif
#endif /* not lint */
@@ -405,18 +405,26 @@
getprivs2(long id, int quotatype, const char *filesys, int defaultq)
{
struct quotause *qup;
+ int8_t version;
+
if ((qup = (struct quotause *)malloc(sizeof(*qup))) == NULL)
errx(2, "out of memory");
- qup->qfname = NULL;
+ memset(qup, 0, sizeof(*qup));
strcpy(qup->fsname, filesys);
- qup->flags |= QUOTA2;
if (defaultq)
qup->flags |= DEFAULT;
- if (!getvfsquota(filesys, &qup->q2e, id, quotatype, defaultq, Dflag)) {
+ if (!getvfsquota(filesys, &qup->q2e, &version,
+ id, quotatype, defaultq, Dflag)) {
/* no entry, get default entry */
- if (!getvfsquota(filesys, &qup->q2e, id, quotatype, 1, Dflag))
+ if (!getvfsquota(filesys, &qup->q2e, &version,
+ id, quotatype, 1, Dflag)) {
+ free(qup);
return NULL;
+ }
}
+ if (version == 2)
+ qup->flags |= QUOTA2;
+ qup->q2e.q2e_uid = id;
return qup;
}
@@ -495,7 +503,7 @@
struct quotause *qup;
for (qup = quplist; qup; qup = qup->next) {
- if (qup->flags & QUOTA2)
+ if (qup->qfname == NULL)
putprivs2(id, quotatype, qup);
else
putprivs1(id, quotatype, qup);
@@ -1041,7 +1049,7 @@
}
/*
- * Check to see if a particular quota is to be enabled.
+ * Check to see if a particular legacy quota is to be enabled in fstab
*/
int
hasquota(fs, type, qfnamep)
Index: src/usr.sbin/repquota/repquota.c
diff -u src/usr.sbin/repquota/repquota.c:1.25.2.2 src/usr.sbin/repquota/repquota.c:1.25.2.3
--- src/usr.sbin/repquota/repquota.c:1.25.2.2 Sat Jan 29 11:04:43 2011
+++ src/usr.sbin/repquota/repquota.c Sun Jan 30 19:38:45 2011
@@ -40,7 +40,7 @@
#if 0
static char sccsid[] = "@(#)repquota.c 8.2 (Berkeley) 11/22/94";
#else
-__RCSID("$NetBSD: repquota.c,v 1.25.2.2 2011/01/29 11:04:43 bouyer Exp $");
+__RCSID("$NetBSD: repquota.c,v 1.25.2.3 2011/01/30 19:38:45 bouyer Exp $");
#endif
#endif /* not lint */
@@ -98,7 +98,7 @@
int repquota2(const struct statvfs *, int);
int repquota1(const struct statvfs *, int);
void usage(void);
-void printquotas(int, const struct statvfs *);
+void printquotas(int, const struct statvfs *, int);
void dqblk2q2e(const struct dqblk *, struct quota2_entry *);
int
@@ -214,8 +214,8 @@
prop_array_t cmds, datas;
struct plistref pref;
int error;
- int8_t error8;
- prop_object_iterator_t iter;
+ int8_t error8, version = 0;
+ prop_object_iterator_t cmditer, dataiter;
struct quota2_entry *q2ep;
struct fileusage *fup;
const char *strid;
@@ -229,6 +229,9 @@
errx(1, "can't allocate proplist");
if (!quota2_prop_add_command(cmds, "getall", qfextension[type], datas))
err(1, "prop_add_command");
+ if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
+ prop_array_create()))
+ err(1, "prop_add_command");
if (!prop_dictionary_set(dict, "commands", cmds))
err(1, "prop_dictionary_set(command)");
if (Dflag)
@@ -252,57 +255,74 @@
errx(1, "quota2_get_cmds: %s\n",
strerror(error));
}
- /* only one command, no need to iter */
- cmd = prop_array_get(cmds, 0);
- if (cmd == NULL)
- err(1, "prop_array_get(cmd)");
-
- if (!prop_dictionary_get_int8(cmd, "return", &error8))
- err(1, "prop_get(return)");
-
- if (error8) {
- prop_object_release(dict);
- if (error8 != EOPNOTSUPP) {
- fprintf(stderr, "get %s quotas: %s\n",
- qfextension[type], strerror(error8));
- }
- return (error8);
- }
- datas = prop_dictionary_get(cmd, "data");
- if (datas == NULL)
- err(1, "prop_dict_get(datas)");
-
- iter = prop_array_iterator(datas);
- if (iter == NULL)
- err(1, "prop_array_iterator");
-
- while ((data = prop_object_iterator_next(iter)) != NULL) {
- strid = NULL;
- if (!prop_dictionary_get_uint32(data, "id", &id)) {
- if (!prop_dictionary_get_cstring_nocopy(data, "id",
- &strid))
- errx(1, "can't find id in quota entry");
- if (strcmp(strid, "default") != 0) {
- errx(1, "wrong id string %s in quota entry",
- strid);
+ cmditer = prop_array_iterator(cmds);
+ if (cmditer == NULL)
+ err(1, "prop_array_iterator(cmds)");
+
+ while ((cmd = prop_object_iterator_next(cmditer)) != NULL) {
+ const char *cmdstr;
+ if (!prop_dictionary_get_cstring_nocopy(cmd, "command",
+ &cmdstr))
+ err(1, "prop_get(command)");
+
+ if (!prop_dictionary_get_int8(cmd, "return", &error8))
+ err(1, "prop_get(return)");
+
+ if (error8) {
+ prop_object_release(dict);
+ if (error8 != EOPNOTSUPP) {
+ fprintf(stderr, "get %s quotas: %s\n",
+ qfextension[type], strerror(error8));
}
- q2ep = &defaultq2e[type];
- } else {
- if ((fup = lookup(id, type)) == 0)
- fup = addid(id, type, (char *)0);
- q2ep = &fup->fu_q2e;
- q2ep->q2e_uid = id;
+ return (error8);
}
-
- error = quota2_dict_get_q2e_usage(data, q2ep);
- if (error) {
- errx(1, "quota2_dict_get_q2e_usage: %s\n",
- strerror(error));
+ datas = prop_dictionary_get(cmd, "data");
+ if (datas == NULL)
+ err(1, "prop_dict_get(datas)");
+
+ if (strcmp("get version", cmdstr) == 0) {
+ data = prop_array_get(datas, 0);
+ if (data == NULL)
+ err(1, "prop_array_get(version)");
+ if (!prop_dictionary_get_int8(data, "version",
+ &version))
+ err(1, "prop_get_int8(version)");
+ continue;
+ }
+ dataiter = prop_array_iterator(datas);
+ if (dataiter == NULL)
+ err(1, "prop_array_iterator");
+
+ while ((data = prop_object_iterator_next(dataiter)) != NULL) {
+ strid = NULL;
+ if (!prop_dictionary_get_uint32(data, "id", &id)) {
+ if (!prop_dictionary_get_cstring_nocopy(data,
+ "id", &strid))
+ errx(1, "can't find id in quota entry");
+ if (strcmp(strid, "default") != 0) {
+ errx(1,
+ "wrong id string %s in quota entry",
+ strid);
+ }
+ q2ep = &defaultq2e[type];
+ } else {
+ if ((fup = lookup(id, type)) == 0)
+ fup = addid(id, type, (char *)0);
+ q2ep = &fup->fu_q2e;
+ q2ep->q2e_uid = id;
+ }
+
+ error = quota2_dict_get_q2e_usage(data, q2ep);
+ if (error) {
+ errx(1, "quota2_dict_get_q2e_usage: %s\n",
+ strerror(error));
+ }
}
+ prop_object_iterator_release(dataiter);
}
- prop_object_iterator_release(iter);
+ prop_object_iterator_release(cmditer);
prop_object_release(dict);
- printquotas(type, vfs);
+ printquotas(type, vfs, version);
return (0);
}
@@ -353,22 +373,29 @@
dqblk2q2e(&dqbuf, &fup->fu_q2e);
}
fclose(qf);
- printquotas(type, vfs);
+ printquotas(type, vfs, 1);
return (0);
}
void
-printquotas(int type, const struct statvfs *vfs)
+printquotas(int type, const struct statvfs *vfs, int version)
{
static int multiple = 0;
u_long id;
struct fileusage *fup;
+ const char *timemsg;
+ static time_t now;
+
+ if (now == 0)
+ time(&now);
if (multiple++)
printf("\n");
if (vflag)
- fprintf(stdout, "*** Report for %s quotas on %s (%s)\n",
- qfextension[type], vfs->f_mntonname, vfs->f_mntfromname);
+ fprintf(stdout,
+ "*** Report for %s quotas on %s (%s, version %d)\n",
+ qfextension[type], vfs->f_mntonname, vfs->f_mntfromname,
+ version);
printf(" Block limits File limits\n");
printf(type == USRQUOTA ? "User " : "Group");
printf(" used soft hard grace used soft hard grace\n");
@@ -383,6 +410,18 @@
printf("%s ", fup->fu_name);
else
printf("%-10s", fup->fu_name);
+
+ if (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit &&
+ fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >=
+ fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit)
+ timemsg = timeprt(now,
+ fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_time);
+ else if (vflag && version == 2)
+ timemsg = timeprt(0,
+ fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_grace);
+ else
+ timemsg = "";
+
printf("%c%c%9s%9s%9s%7s",
fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit &&
fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >=
@@ -398,10 +437,17 @@
HN_B, hflag),
intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit,
HN_B, hflag),
- (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit &&
- fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >=
- fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit) ?
- timeprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_time) : "");
+ timemsg);
+ if (fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit &&
+ fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >=
+ fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit)
+ timemsg = timeprt(now,
+ fup->fu_q2e.q2e_val[Q2V_FILE].q2v_time);
+ else if (vflag && version == 2)
+ timemsg = timeprt(0,
+ fup->fu_q2e.q2e_val[Q2V_FILE].q2v_grace);
+ else
+ timemsg = "";
printf(" %8s%8s%8s%7s\n",
intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur,
0, hflag),
@@ -409,10 +455,7 @@
0, hflag),
intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_hardlimit,
0, hflag),
- (fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit &&
- fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >=
- fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit) ?
- timeprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_time) : "");
+ timemsg);
memset(&fup->fu_q2e, 0, sizeof(fup->fu_q2e));
}
}