Module Name:    src
Committed By:   bouyer
Date:           Sun Jan 30 22:49:32 UTC 2011

Modified Files:
        src/usr.bin/quota [bouyer-quota2]: printquota.c printquota.h
        src/usr.sbin/edquota [bouyer-quota2]: edquota.c

Log Message:
Allow edquota to edit per-user grace times on quota2 (or the default, global
grace times on quota1). Use re-use -t to specify the grace time on command
line; editing the grace time on quota1 is done with -d now.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.6 -r1.1.2.7 src/usr.bin/quota/printquota.c \
    src/usr.bin/quota/printquota.h
cvs rdiff -u -r1.29.16.4 -r1.29.16.5 src/usr.sbin/edquota/edquota.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/quota/printquota.c
diff -u src/usr.bin/quota/printquota.c:1.1.2.6 src/usr.bin/quota/printquota.c:1.1.2.7
--- src/usr.bin/quota/printquota.c:1.1.2.6	Sun Jan 30 21:37:39 2011
+++ src/usr.bin/quota/printquota.c	Sun Jan 30 22:49:31 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: printquota.c,v 1.1.2.6 2011/01/30 21:37:39 bouyer Exp $ */
+/*	$NetBSD: printquota.c,v 1.1.2.7 2011/01/30 22:49:31 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.6 2011/01/30 21:37:39 bouyer Exp $");
+__RCSID("$NetBSD: printquota.c,v 1.1.2.7 2011/01/30 22:49:31 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -148,17 +148,19 @@
 }
 
 /*
- * Calculate the grace period and return a precise string for it.
+ * Calculate the grace period and return a precise string for it,
+ * either in seconds or in format xWyDzHtMuS
  */
 const char *
-timepprt(time_t now, time_t seconds, int space)
+timepprt(time_t seconds, int hflag, int space)
 {
 	static char buf[20], *append;
 	int i, remain = space + 1;
 
-	if (now > seconds)
-		return ("none");
-	seconds -= now;
+	if (hflag == 0) {
+		snprintf(buf, remain, "%" PRId64, seconds);
+		return buf;
+	}
 
 	append = &buf[0];
 	if ((seconds / WEEK) > 0) {
@@ -199,6 +201,55 @@
 }
 
 /*
+ * convert a string of the form xWyDzHtMuS, or plain decimal, to 
+ * a time in seconds
+ */
+int
+timeprd(const char *str, time_t *valp)
+{
+	char buf[20];
+	char *cur, *next, *end;
+	time_t val= 0;
+
+	strncpy(buf, str, sizeof(buf));
+	next = buf;
+	cur = strsep(&next, "Ww");
+	if (next != NULL) {
+		val = strtoumax(cur, &end, 10) * WEEK;	
+		if (end[0] != '\0')
+			return EINVAL;
+	} else
+		next = cur;
+	cur = strsep(&next, "Dd");
+	if (next != NULL) {
+		val += strtoumax(cur, &end, 10) * DAY;	
+		if (end[0] != '\0')
+			return EINVAL;
+	} else
+		next = cur;
+	cur = strsep(&next, "Hh");
+	if (next != NULL) {
+		val += strtoumax(cur, &end, 10) * HOUR;	
+		if (end[0] != '\0')
+			return EINVAL;
+	} else
+		next = cur;
+	cur = strsep(&next, "Mm");
+	if (next != NULL) {
+		val += strtoumax(cur, &end, 10) * MINUTE;	
+		if (end[0] != '\0')
+			return EINVAL;
+	} else
+		next = cur;
+	cur = strsep(&next, "Ss");
+	val += strtoumax(cur, &end, 10);
+	if (end[0] != '\0')
+		return EINVAL;
+	*valp = val;
+	return 0;
+}
+
+/*
  * convert a string to a uint64 value
  */
 int
Index: src/usr.bin/quota/printquota.h
diff -u src/usr.bin/quota/printquota.h:1.1.2.6 src/usr.bin/quota/printquota.h:1.1.2.7
--- src/usr.bin/quota/printquota.h:1.1.2.6	Sun Jan 30 21:37:39 2011
+++ src/usr.bin/quota/printquota.h	Sun Jan 30 22:49:32 2011
@@ -1,7 +1,8 @@
-/*	$NetBSD: printquota.h,v 1.1.2.6 2011/01/30 21:37:39 bouyer Exp $ */
+/*	$NetBSD: printquota.h,v 1.1.2.7 2011/01/30 22:49:32 bouyer Exp $ */
 
 const char *intprt(uint64_t, u_int, int, int);
-const char *timeprt(time_t, time_t, int space);
-const char *timepprt(time_t, time_t, int space);
+const char *timeprt(time_t, time_t, int);
+const char *timepprt(time_t, int, int);
+int timeprd(const char *, time_t *);
 int intrd(char *str, uint64_t *val, u_int);
 

Index: src/usr.sbin/edquota/edquota.c
diff -u src/usr.sbin/edquota/edquota.c:1.29.16.4 src/usr.sbin/edquota/edquota.c:1.29.16.5
--- src/usr.sbin/edquota/edquota.c:1.29.16.4	Sun Jan 30 20:54:22 2011
+++ src/usr.sbin/edquota/edquota.c	Sun Jan 30 22:49:32 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: edquota.c,v 1.29.16.4 2011/01/30 20:54:22 bouyer Exp $ */
+/*      $NetBSD: edquota.c,v 1.29.16.5 2011/01/30 22:49:32 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.4 2011/01/30 20:54:22 bouyer Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.29.16.5 2011/01/30 22:49:32 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -130,10 +130,10 @@
 	long id, protoid;
 	int quotatype, tmpfd;
 	char *protoname;
-	char *soft = NULL, *hard = NULL;
+	char *soft = NULL, *hard = NULL, *grace = NULL;
 	char *fs = NULL;
 	int ch;
-	int tflag = 0, pflag = 0;
+	int pflag = 0;
 
 	if (argc < 2)
 		usage();
@@ -141,7 +141,7 @@
 		errx(1, "permission denied");
 	protoname = NULL;
 	quotatype = USRQUOTA;
-	while ((ch = getopt(argc, argv, "DHdugtp:s:h:f:")) != -1) {
+	while ((ch = getopt(argc, argv, "DHdugp:s:h:t:f:")) != -1) {
 		switch(ch) {
 		case 'D':
 			Dflag++;
@@ -162,15 +162,15 @@
 		case 'u':
 			quotatype = USRQUOTA;
 			break;
-		case 't':
-			tflag++;
-			break;
 		case 's':
 			soft = optarg;
 			break;
 		case 'h':
 			hard = optarg;
 			break;
+		case 't':
+			grace = optarg;
+			break;
 		case 'f':
 			fs = optarg;
 			break;
@@ -182,7 +182,7 @@
 	argv += optind;
 
 	if (pflag) {
-		if (soft || hard || dflag)
+		if (soft || hard || grace || dflag)
 			usage();
 		if ((protoid = getentry(protoname, quotatype)) == -1)
 			exit(1);
@@ -198,12 +198,11 @@
 		}
 		exit(0);
 	}
-	if (soft || hard) {
+	if (soft || hard || grace) {
 		struct quotause *lqup;
 		u_int64_t softb, hardb, softi, hardi;
+		time_t  graceb, gracei;
 		char *str;
-		if (tflag)
-			usage();
 		if (soft) {
 			str = strsep(&soft, "/");
 			if (str[0] == '\0' || soft == NULL || soft[0] == '\0')
@@ -224,6 +223,16 @@
 			if (intrd(hard, &hardi, 0) != 0)
 				errx(1, "%s: bad number", hard);
 		}
+		if (grace) {
+			str = strsep(&grace, "/");
+			if (str[0] == '\0' || grace == NULL || grace[0] == '\0')
+				usage();
+			    
+			if (timeprd(str, &graceb) != 0)
+				errx(1, "%s: bad number", str);
+			if (timeprd(grace, &gracei) != 0)
+				errx(1, "%s: bad number", grace);
+		}
 		if (dflag) {
 			curprivs = getprivs(0, quotatype, fs, 1);
 			for (lqup = curprivs; lqup; lqup = lqup->next) {
@@ -235,6 +244,10 @@
 					lqup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit = hardb;
 					lqup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit = hardi;
 				}
+				if (grace) {
+					lqup->q2e.q2e_val[Q2V_BLOCK].q2v_grace = graceb;
+					lqup->q2e.q2e_val[Q2V_FILE].q2v_grace = gracei;
+				}
 			}
 			putprivs(0, quotatype, curprivs);
 			freeprivs(curprivs);
@@ -263,6 +276,10 @@
 					lqup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit = hardb;
 					lqup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit = hardi;
 				}
+				if (grace) {
+					lqup->q2e.q2e_val[Q2V_BLOCK].q2v_grace = graceb;
+					lqup->q2e.q2e_val[Q2V_FILE].q2v_grace = gracei;
+				}
 			}
 			putprivs(id, quotatype, curprivs);
 			freeprivs(curprivs);
@@ -271,7 +288,7 @@
 	}
 	tmpfd = mkstemp(tmpfil);
 	fchown(tmpfd, getuid(), getgid());
-	if (tflag) {
+	if (0 /* XXX */) {
 		if (soft || hard)
 			usage();
 		protoprivs = getprivs(0, quotatype, fs, 0);
@@ -311,10 +328,8 @@
 	    "usage:\n"
 	    "  edquota [-D] [-H] [-u] [-p username] [-f filesystem] [-d] username ...\n"
 	    "  edquota [-D] [-H] -g [-p groupname] [-f filesystem] [-d] groupname ...\n"
-	    "  edquota [-D] [-H] [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] [-d] username ...\n"
-	    "  edquota [-D] [-H] -g [-f filesystem] [-s b#/i#] [-h b#/i#] [-d] groupname ...\n"
-	    "  edquota [-D] [-H] [-u] [-f filesystem] -t\n"
-	    "  edquota [-D] [-H] -g [-f filesystem] -t\n"
+	    "  edquota [-D] [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t[-d] username ...\n"
+	    "  edquota [-D] -g [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t[-d] groupname ...\n"
 	    );
 	exit(1);
 }
@@ -679,7 +694,7 @@
 		    qfextension[quotatype], name);
 	}
 	for (qup = quplist; qup; qup = qup->next) {
-		fprintf(fd, "%s: %s %s, limits (soft = %s, hard = %s)\n",
+		fprintf(fd, "%s: %s %s, limits (soft = %s, hard = %s",
 		    qup->fsname, "blocks in use:",
 		    intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur,
 			HN_NOSPACE | HN_B, Hflag, 20),
@@ -687,7 +702,13 @@
 			HN_NOSPACE | HN_B, Hflag, 20),
 		    intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit,
 			HN_NOSPACE | HN_B, Hflag, 20));
-		fprintf(fd, "%s %s, limits (soft = %s, hard = %s)\n",
+		if (qup->flags & (QUOTA2|DEFAULT)) {
+		    fprintf(fd, ", grace = %s",
+			timepprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_grace,
+			    Hflag, 20));
+		}
+		fprintf(fd, ")\n");
+		fprintf(fd, "%s %s, limits (soft = %s, hard = %s",
 		    "\tinodes in use:",
 		    intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_cur,
 			HN_NOSPACE, Hflag, 20),
@@ -695,6 +716,12 @@
 			HN_NOSPACE, Hflag, 20),
 		    intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit,
 			 HN_NOSPACE, Hflag, 20));
+		if (qup->flags & (QUOTA2|DEFAULT)) {
+		    fprintf(fd, ", grace = %s",
+			timepprt(qup->q2e.q2e_val[Q2V_FILE].q2v_grace,
+			    Hflag, 20));
+		}
+		fprintf(fd, ")\n");
 	}
 	fclose(fd);
 	return (1);
@@ -715,7 +742,9 @@
 	char *fsp;
 	static char line1[BUFSIZ], line2[BUFSIZ];
 	static char scurb[BUFSIZ], scuri[BUFSIZ], ssoft[BUFSIZ], shard[BUFSIZ];
+	static char stime[BUFSIZ];
 	uint64_t softb, hardb, softi, hardi;
+	time_t graceb = -1, gracei = -1;
 
 	(void)lseek(infd, (off_t)0, SEEK_SET);
 	fd = fdopen(dup(infd), "r");
@@ -730,31 +759,43 @@
 	while (fgets(line1, sizeof (line1), fd) != NULL &&
 	       fgets(line2, sizeof (line2), fd) != NULL) {
 		if ((fsp = strtok(line1, " \t:")) == NULL) {
-			warnx("%s: 4 bad format", line1);
+			warnx("%s: bad format", line1);
 			goto out;
 		}
 		if ((cp = strtok((char *)0, "\n")) == NULL) {
-			warnx("%s: %s: 5 bad format", fsp,
+			warnx("%s: %s: bad format", fsp,
 			    &fsp[strlen(fsp) + 1]);
 			goto out;
 		}
 #define last_char(str) ((str)[strlen(str) - 1])
 		cnt = sscanf(cp,
-		    " blocks in use: %s limits (soft = %s hard = %s\n",
-		    scurb, ssoft, shard);
-		if (cnt != 3) {
-			warnx("%s:%s: 6 bad format %d", fsp, cp, cnt);
+		    " blocks in use: %s limits (soft = %s hard = %s "
+		    "grace = %s\n", scurb, ssoft, shard, stime);
+		if (cnt == 3) {
+			if (last_char(scurb) != ',' ||
+			    last_char(ssoft) != ',' ||
+			    last_char(shard) != ')') {
+				warnx("%s:%s: bad format %d", fsp, cp, cnt);
+				goto out;
+			}
+			stime[0] = '\0';
+		} else if (cnt == 4) {
+			if (last_char(scurb) != ',' ||
+			    last_char(ssoft) != ',' ||
+			    last_char(shard) != ',' ||
+			    last_char(stime) != ')') {
+				warnx("%s:%s: bad format %d", fsp, cp, cnt);
+				goto out;
+			}
+		} else {
+			warnx("%s: %s: bad format", fsp, line2);
 			goto out;
 		}
 		/* drop last char which is ',' or ')' */
-		if (last_char(scurb) != ',' || last_char(ssoft) != ',' ||
-		    last_char(shard) != ')') {
-			warnx("%s:%s: 61 bad format %d", fsp, cp, cnt);
-			goto out;
-		}
 		last_char(scurb) = '\0';
 		last_char(ssoft) = '\0';
 		last_char(shard) = '\0';
+		last_char(stime) = '\0';
 		
 		if (intrd(ssoft, &softb, HN_B) != 0) {
 			warnx("%s:%s: bad number", fsp, ssoft);
@@ -764,26 +805,45 @@
 			warnx("%s:%s: bad number", fsp, shard);
 			goto out;
 		}
+		if (cnt == 4) {
+			if (timeprd(stime, &graceb) != 0) {
+				warnx("%s:%s: bad number", fsp, shard);
+				goto out;
+			}
+		}
+
 		if ((cp = strtok(line2, "\n")) == NULL) {
-			warnx("%s: %s: 7 bad format", fsp, line2);
+			warnx("%s: %s: bad format", fsp, line2);
 			goto out;
 		}
 		cnt = sscanf(cp,
-		    "\tinodes in use: %s limits (soft = %s hard = %s\n",
-		    scuri, ssoft, shard);
-		if (cnt != 3) {
-			warnx("%s: %s: 8 bad format", fsp, line2);
+		    "\tinodes in use: %s limits (soft = %s hard = %s "
+		    "grace = %s\n", scuri, ssoft, shard, stime);
+		if (cnt == 3) {
+			if (last_char(scuri) != ',' ||
+			    last_char(ssoft) != ',' ||
+			    last_char(shard) != ')') {
+				warnx("%s:%s: bad format %d", fsp, cp, cnt);
+				goto out;
+			}
+			stime[0] = '\0';
+		} else if (cnt == 4) {
+			if (last_char(scuri) != ',' ||
+			    last_char(ssoft) != ',' ||
+			    last_char(shard) != ',' ||
+			    last_char(stime) != ')') {
+				warnx("%s:%s: bad format %d", fsp, cp, cnt);
+				goto out;
+			}
+		} else {
+			warnx("%s: %s: bad format", fsp, line2);
 			goto out;
 		}
 		/* drop last char which is ',' or ')' */
-		if (last_char(scuri) != ',' || last_char(ssoft) != ',' ||
-		    last_char(shard) != ')') {
-			warnx("%s:%s: 81 bad format %d", fsp, cp, cnt);
-			goto out;
-		}
 		last_char(scuri) = '\0';
 		last_char(ssoft) = '\0';
 		last_char(shard) = '\0';
+		last_char(stime) = '\0';
 		if (intrd(ssoft, &softi, 0) != 0) {
 			warnx("%s:%s: bad number", fsp, ssoft);
 			goto out;
@@ -792,6 +852,12 @@
 			warnx("%s:%s: bad number", fsp, shard);
 			goto out;
 		}
+		if (cnt == 4) {
+			if (timeprd(stime, &gracei) != 0) {
+				warnx("%s:%s: bad number", fsp, shard);
+				goto out;
+			}
+		}
 		for (qup = quplist; qup; qup = qup->next) {
 			if (strcmp(fsp, qup->fsname))
 				continue;
@@ -825,8 +891,12 @@
 				qup->q2e.q2e_val[Q2V_FILE].q2v_time = 0;
 			qup->q2e.q2e_val[Q2V_BLOCK].q2v_softlimit = softb;
 			qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit = hardb;
+			if (graceb >= 0)
+				qup->q2e.q2e_val[Q2V_BLOCK].q2v_grace = graceb;
 			qup->q2e.q2e_val[Q2V_FILE].q2v_softlimit  = softi;
 			qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit  = hardi;
+			if (gracei >= 0)
+				qup->q2e.q2e_val[Q2V_FILE].q2v_grace = gracei;
 			qup->flags |= FOUND;
 		}
 	}
@@ -906,11 +976,11 @@
 	(void) fgets(line1, sizeof (line1), fd);
 	while (fgets(line1, sizeof (line1), fd) != NULL) {
 		if ((fsp = strtok(line1, " \t:")) == NULL) {
-			warnx("%s: 1 bad format", line1);
+			warnx("%s: bad format", line1);
 			goto bad;
 		}
 		if ((cp = strtok((char *)0, "\n")) == NULL) {
-			warnx("%s: %s: 2 bad format", fsp,
+			warnx("%s: %s: bad format", fsp,
 			    &fsp[strlen(fsp) + 1]);
 			goto bad;
 		}
@@ -918,7 +988,7 @@
 		    " block grace period: %ld %s file grace period: %ld %s",
 		    &lbtime, bunits, &litime, iunits);
 		if (cnt != 4) {
-			warnx("%s:%s: 3 bad format", fsp, cp);
+			warnx("%s:%s: bad format", fsp, cp);
 			goto bad;
 		}
 		itime = (time_t)litime;

Reply via email to