Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/edquota Make editor-based edquota work again.
details: https://anonhg.NetBSD.org/src/rev/accec6a58140
branches: trunk
changeset: 780979:accec6a58140
user: dholland <dholland%NetBSD.org@localhost>
date: Tue Aug 14 03:55:48 2012 +0000
description:
Make editor-based edquota work again.
The format is somewhat different; I'm operating under the assumption
that nobody has automated editing scripts for the old format because
it's much easier just to use the command-line interface of
edquota. The new format is more scalable and more parseable.
Also, do a better job of diagnosing editing errors, and don't blindly
erase all quota information for the user being edited when a parse
error occurs after editing.
diffstat:
usr.sbin/edquota/edquota.c | 634 +++++++++++++++++++++++++-------------------
1 files changed, 366 insertions(+), 268 deletions(-)
diffs (truncated from 796 to 300 lines):
diff -r 4e09e53efbed -r accec6a58140 usr.sbin/edquota/edquota.c
--- a/usr.sbin/edquota/edquota.c Tue Aug 14 02:55:00 2012 +0000
+++ b/usr.sbin/edquota/edquota.c Tue Aug 14 03:55:48 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: edquota.c,v 1.49 2012/08/13 23:08:58 dholland Exp $ */
+/* $NetBSD: edquota.c,v 1.50 2012/08/14 03:55:48 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
#else
-__RCSID("$NetBSD: edquota.c,v 1.49 2012/08/13 23:08:58 dholland Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.50 2012/08/14 03:55:48 dholland Exp $");
#endif
#endif /* not lint */
@@ -89,6 +89,13 @@
#define MAX_TMPSTR (100+MAXPATHLEN)
+enum sources {
+ SRC_EDITED, /* values came from user */
+ SRC_QUOTA, /* values came from a specific quota entry */
+ SRC_DEFAULT, /* values were copied from the default quota entry */
+ SRC_CLEAR, /* values arose by zeroing out a quota entry */
+};
+
struct quotause {
struct quotause *next;
unsigned found:1, /* found after running editor */
@@ -96,6 +103,7 @@
isdefault:1;
struct quotaval qv[EDQUOTA_NUMOBJTYPES];
+ enum sources source[EDQUOTA_NUMOBJTYPES];
char fsname[MAXPATHLEN + 1];
char implementation[32];
};
@@ -149,6 +157,46 @@
return -1;
}
+/*
+ * check if a source is "real" (reflects actual data) or not
+ */
+static bool
+source_is_real(enum sources source)
+{
+ switch (source) {
+ case SRC_EDITED:
+ case SRC_QUOTA:
+ return true;
+ case SRC_DEFAULT:
+ case SRC_CLEAR:
+ return false;
+ }
+ assert(!"encountered invalid source");
+ return false;
+}
+
+/*
+ * some simple string tools
+ */
+
+static /*const*/ char *
+skipws(/*const*/ char *s)
+{
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+ return s;
+}
+
+static /*const*/ char *
+skipword(/*const*/ char *s)
+{
+ while (*s != '\0' && *s != '\n' && *s != ' ' && *s != '\t') {
+ s++;
+ }
+ return s;
+}
+
////////////////////////////////////////////////////////////
// quotause operations
@@ -159,6 +207,7 @@
quotause_create(void)
{
struct quotause *qup;
+ unsigned i;
qup = malloc(sizeof(*qup));
if (qup == NULL) {
@@ -169,7 +218,10 @@
qup->found = 0;
qup->xgrace = 0;
qup->isdefault = 0;
- memset(qup->qv, 0, sizeof(qup->qv));
+ for (i=0; i<EDQUOTA_NUMOBJTYPES; i++) {
+ quotaval_clear(&qup->qv[i]);
+ qup->source[i] = SRC_CLEAR;
+ }
qup->fsname[0] = '\0';
return qup;
@@ -360,13 +412,30 @@
qk.qk_idtype = idtype;
qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
qk.qk_objtype = objtype;
- if (quota_get(qh, &qk, &qup->qv[objtype])) {
- /* no entry, get default entry */
- qk.qk_id = QUOTA_DEFAULTID;
- if (quota_get(qh, &qk, &qup->qv[objtype])) {
- return -1;
- }
+ if (quota_get(qh, &qk, &qup->qv[objtype]) == 0) {
+ /* succeeded */
+ qup->source[objtype] = SRC_QUOTA;
+ return 0;
+ }
+ if (errno != ENOENT) {
+ /* serious failure */
+ return -1;
}
+
+ /* no entry, get default entry */
+ qk.qk_id = QUOTA_DEFAULTID;
+ if (quota_get(qh, &qk, &qup->qv[objtype]) == 0) {
+ /* succeeded */
+ qup->source[objtype] = SRC_DEFAULT;
+ return 0;
+ }
+ if (errno != ENOENT) {
+ return -1;
+ }
+
+ /* use a zeroed-out entry */
+ quotaval_clear(&qup->qv[objtype]);
+ qup->source[objtype] = SRC_CLEAR;
return 0;
}
@@ -448,18 +517,24 @@
err(1, "%s: quota_open", qup->fsname);
}
- qk.qk_idtype = idtype;
- qk.qk_id = id;
- qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
- if (quota_put(qh, &qk, &qup->qv[QO_BLK])) {
- err(1, "%s: quota_put (%s blocks)", qup->fsname, idname);
+ if (source_is_real(qup->source[QUOTA_OBJTYPE_BLOCKS])) {
+ qk.qk_idtype = idtype;
+ qk.qk_id = id;
+ qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+ if (quota_put(qh, &qk, &qup->qv[QO_BLK])) {
+ err(1, "%s: quota_put (%s blocks)", qup->fsname,
+ idname);
+ }
}
- qk.qk_idtype = idtype;
- qk.qk_id = id;
- qk.qk_objtype = QUOTA_OBJTYPE_FILES;
- if (quota_put(qh, &qk, &qup->qv[QO_FL])) {
- err(1, "%s: quota_put (%s files)", qup->fsname, idname);
+ if (source_is_real(qup->source[QUOTA_OBJTYPE_FILES])) {
+ qk.qk_idtype = idtype;
+ qk.qk_id = id;
+ qk.qk_objtype = QUOTA_OBJTYPE_FILES;
+ if (quota_put(qh, &qk, &qup->qv[QO_FL])) {
+ err(1, "%s: quota_put (%s files)", qup->fsname,
+ idname);
+ }
}
quota_close(qh);
@@ -497,18 +572,7 @@
qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq,
&qlist->idtypename);
if (qup == NULL) {
- /*
- * XXX: returning NULL is totally wrong. On
- * serious error, abort; on minor error, warn
- * and continue.
- *
- * Note: we cannot warn unconditionally here
- * because this case apparently includes "no
- * quota entry on this volume" and that causes
- * the atf tests to fail. Bletch.
- */
- /*return NULL;*/
- /*warnx("getprivs2 failed");*/
+ warnx("getprivs2 failed for id %ld", id);
continue;
}
@@ -526,9 +590,7 @@
/* if we get there, filesys is not mounted. try the old way */
qup = getprivs1(id, idtype, filesys);
if (qup == NULL) {
- /* XXX. see above */
- /*return NULL;*/
- /*warnx("getprivs1 failed");*/
+ warnx("getprivs1 failed");
return qlist;
}
quotalist_append(qlist, qup);
@@ -710,6 +772,7 @@
struct quotause *qup;
FILE *fd;
char b0[32], b1[32], b2[32], b3[32];
+ const char *comm;
(void)ftruncate(outfd, 0);
(void)lseek(outfd, (off_t)0, SEEK_SET);
@@ -722,46 +785,38 @@
}
for (qup = qlist->head; qup; qup = qup->next) {
struct quotaval *q = qup->qv;
- fprintf(fd, "%s (%s):\n",
- qup->fsname, qup->implementation);
- if (!qup->isdefault || qup->xgrace) {
- fprintf(fd, "\tblocks in use: %s, "
- "limits (soft = %s, hard = %s",
- intprt(b1, 21, q[QO_BLK].qv_usage,
- HN_NOSPACE | HN_B, Hflag),
- intprt(b2, 21, q[QO_BLK].qv_softlimit,
- HN_NOSPACE | HN_B, Hflag),
- intprt(b3, 21, q[QO_BLK].qv_hardlimit,
- HN_NOSPACE | HN_B, Hflag));
- if (qup->xgrace)
- fprintf(fd, ", ");
- } else
- fprintf(fd, "\tblocks: (");
-
+
+ fprintf(fd, "%s (%s):\n", qup->fsname, qup->implementation);
+
+ comm = source_is_real(qup->source[QO_BLK]) ? "" : "#";
+ fprintf(fd, "\tblocks:\n");
+ fprintf(fd, "\t\t%susage: %s\n", comm,
+ intprt(b1, 21, q[QO_BLK].qv_usage,
+ HN_NOSPACE | HN_B, Hflag));
+ fprintf(fd, "\t\t%slimits: soft %s, hard %s\n", comm,
+ intprt(b2, 21, q[QO_BLK].qv_softlimit,
+ HN_NOSPACE | HN_B, Hflag),
+ intprt(b3, 21, q[QO_BLK].qv_hardlimit,
+ HN_NOSPACE | HN_B, Hflag));
if (qup->xgrace || qup->isdefault) {
- fprintf(fd, "grace = %s",
- timepprt(b0, 21, q[QO_BLK].qv_grace, Hflag));
+ fprintf(fd, "\t\t%sgrace: %s\n", comm,
+ timepprt(b0, 21, q[QO_BLK].qv_grace, Hflag));
}
- fprintf(fd, ")\n");
- if (!qup->isdefault || qup->xgrace) {
- fprintf(fd, "\tinodes in use: %s, "
- "limits (soft = %s, hard = %s",
- intprt(b1, 21, q[QO_FL].qv_usage,
- HN_NOSPACE, Hflag),
- intprt(b2, 21, q[QO_FL].qv_softlimit,
- HN_NOSPACE, Hflag),
- intprt(b3, 21, q[QO_FL].qv_hardlimit,
- HN_NOSPACE, Hflag));
- if (qup->xgrace)
- fprintf(fd, ", ");
- } else
- fprintf(fd, "\tinodes: (");
+ comm = source_is_real(qup->source[QO_FL]) ? "" : "#";
+ fprintf(fd, "\tinodes:\n");
+ fprintf(fd, "\t\t%susage: %s\n", comm,
+ intprt(b1, 21, q[QO_FL].qv_usage,
+ HN_NOSPACE, Hflag));
+ fprintf(fd, "\t\t%slimits: soft %s, hard %s\n", comm,
+ intprt(b2, 21, q[QO_FL].qv_softlimit,
+ HN_NOSPACE, Hflag),
+ intprt(b3, 21, q[QO_FL].qv_hardlimit,
+ HN_NOSPACE, Hflag));
if (qup->xgrace || qup->isdefault) {
- fprintf(fd, "grace = %s",
- timepprt(b0, 21, q[QO_FL].qv_grace, Hflag));
+ fprintf(fd, "\t\t%sgrace: %s\n", comm,
+ timepprt(b0, 21, q[QO_FL].qv_grace, Hflag));
}
- fprintf(fd, ")\n");
}
fclose(fd);
return 1;
@@ -773,239 +828,278 @@
static int
readprivs(struct quotalist *qlist, int infd, int dflag)
{
- struct quotause *qup;
- FILE *fd;
- int cnt;
- char fsp[BUFSIZ];
Home |
Main Index |
Thread Index |
Old Index