From owner-svn-src-projects@FreeBSD.ORG Tue Feb 10 08:09:03 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 745851065670; Tue, 10 Feb 2009 08:09:03 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 61B4E8FC14; Tue, 10 Feb 2009 08:09:03 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1A893cB085440; Tue, 10 Feb 2009 08:09:03 GMT (envelope-from mckusick@svn.freebsd.org) Received: (from mckusick@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1A893qN085439; Tue, 10 Feb 2009 08:09:03 GMT (envelope-from mckusick@svn.freebsd.org) Message-Id: <200902100809.n1A893qN085439@svn.freebsd.org> From: Kirk McKusick Date: Tue, 10 Feb 2009 08:09:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188432 - projects/quota64/usr.sbin/edquota X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Feb 2009 08:09:03 -0000 Author: mckusick Date: Tue Feb 10 08:09:03 2009 New Revision: 188432 URL: http://svn.freebsd.org/changeset/base/188432 Log: More updates to edquota based on feedback from Dag-Erling Smorgrav. Modified: projects/quota64/usr.sbin/edquota/edquota.c Modified: projects/quota64/usr.sbin/edquota/edquota.c ============================================================================== --- projects/quota64/usr.sbin/edquota/edquota.c Tue Feb 10 06:08:28 2009 (r188431) +++ projects/quota64/usr.sbin/edquota/edquota.c Tue Feb 10 08:09:03 2009 (r188432) @@ -101,9 +101,11 @@ struct quotause { int alldigits(const char *s); int cvtatos(u_int64_t, char *, u_int64_t *); char *cvtstoa(u_int64_t); -u_int64_t cvtval(u_int64_t, char); +u_int64_t cvtblkval(u_int64_t, char, const char *); +u_int64_t cvtinoval(u_int64_t, char, const char *); int editit(char *); -char *fmthumanval(int64_t); +char *fmthumanvalblks(int64_t); +char *fmthumanvalinos(int64_t); void freeprivs(struct quotause *); int getentry(const char *, int); struct quotause *getprivs(long, int, char *); @@ -165,6 +167,12 @@ main(int argc, char *argv[]) (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; + if (i > 0 && !isdigit(*cp)) { + warnx("incorrect quota specification: " + "%s", oldoptarg); + usage(); + /* Not Reached */ + } switch (i) { case 0: strlcpy(qup->fsname, cp, @@ -173,34 +181,34 @@ main(int argc, char *argv[]) case 1: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bsoftlimit = - cvtval(lim, *endpt); + cvtblkval(lim, *endpt, + "block soft limit"); continue; case 2: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bhardlimit = - cvtval(lim, *endpt); + cvtblkval(lim, *endpt, + "block hard limit"); continue; case 3: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_isoftlimit = - cvtval(lim, *endpt); + cvtinoval(lim, *endpt, + "inode soft limit"); continue; case 4: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_ihardlimit = - cvtval(lim, *endpt); + cvtinoval(lim, *endpt, + "inode hard limit"); continue; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); - break; /* XXX: report an error */ + /* Not Reached */ } } - qup->dqblk.dqb_bsoftlimit = - btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); - qup->dqblk.dqb_bhardlimit = - btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); if (protoprivs == NULL) { protoprivs = curprivs = qup; } else { @@ -212,6 +220,7 @@ main(int argc, char *argv[]) break; default: usage(); + /* Not Reached */ } } argc -= optind; @@ -518,28 +527,29 @@ writeprivs(struct quotause *quplist, int fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); for (qup = quplist; qup; qup = qup->next) { fprintf(fd, "%s: in use: %s, ", qup->fsname, - fmthumanval(qup->dqblk.dqb_curblocks)); + fmthumanvalblks(qup->dqblk.dqb_curblocks)); fprintf(fd, "limits (soft = %s, ", - fmthumanval(qup->dqblk.dqb_bsoftlimit)); + fmthumanvalblks(qup->dqblk.dqb_bsoftlimit)); fprintf(fd, "hard = %s)\n", - fmthumanval(qup->dqblk.dqb_bhardlimit)); - fprintf(fd, "%s %llu, limits (soft = %llu, hard = %llu)\n", - "\tinodes in use:", - qup->dqblk.dqb_curinodes, - qup->dqblk.dqb_isoftlimit, - qup->dqblk.dqb_ihardlimit); + fmthumanvalblks(qup->dqblk.dqb_bhardlimit)); + fprintf(fd, "\tinodes in use: %s, ", + fmthumanvalinos(qup->dqblk.dqb_curinodes)); + fprintf(fd, "limits (soft = %s, ", + fmthumanvalinos(qup->dqblk.dqb_isoftlimit)); + fprintf(fd, "hard = %s)\n", + fmthumanvalinos(qup->dqblk.dqb_ihardlimit)); } fclose(fd); return (1); } char * -fmthumanval(int64_t blocks) +fmthumanvalblks(int64_t blocks) { static char numbuf[20]; if (hflag) { - humanize_number(numbuf, sizeof(numbuf) - (blocks < 0 ? 0 : 1), + humanize_number(numbuf, blocks < 0 ? 7 : 6, dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); return (numbuf); } @@ -547,6 +557,20 @@ fmthumanval(int64_t blocks) return(numbuf); } +char * +fmthumanvalinos(int64_t inos) +{ + static char numbuf[20]; + + if (hflag) { + humanize_number(numbuf, inos < 0 ? 7 : 6, + inos, "", HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); + return (numbuf); + } + snprintf(numbuf, sizeof(numbuf), "%llu", inos); + return(numbuf); +} + /* * Merge changes to an ASCII file into a quotause list. */ @@ -607,42 +631,48 @@ readprivs(struct quotause *quplist, char warnx("%s:%s: bad format", fsp, cp); return (0); } - dqblk.dqb_curblocks = cvtval(curitems, curitemunits); - dqblk.dqb_bsoftlimit = cvtval(softlimit, softunits); - dqblk.dqb_bhardlimit = cvtval(hardlimit, hardunits); + dqblk.dqb_curblocks = cvtblkval(curitems, curitemunits, + "current block count"); + dqblk.dqb_bsoftlimit = cvtblkval(softlimit, softunits, + "block soft limit"); + dqblk.dqb_bhardlimit = cvtblkval(hardlimit, hardunits, + "block hard limit"); if ((cp = strtok(line2, "\n")) == NULL) { warnx("%s: %s: bad format", fsp, line2); return (0); } - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c, hard = %llu%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); /* * The next three check for old-style input formats. */ if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c hard = %llu%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c hard = %llu%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c, hard = %llu%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); - if (cnt != 3) { - warnx("%s: %s: bad format", fsp, line2); + if (cnt != 6) { + warnx("%s: %s: bad format cnt %d", fsp, &cp[7], cnt); return (0); } - dqblk.dqb_curinodes = cvtval(curitems, curitemunits); - dqblk.dqb_isoftlimit = cvtval(softlimit, softunits); - dqblk.dqb_ihardlimit = cvtval(hardlimit, hardunits); + dqblk.dqb_curinodes = cvtinoval(curitems, curitemunits, + "current inode count"); + dqblk.dqb_isoftlimit = cvtinoval(softlimit, softunits, + "inode soft limit"); + dqblk.dqb_ihardlimit = cvtinoval(hardlimit, hardunits, + "inode hard limit"); for (qup = quplist; qup; qup = qup->next) { if (strcmp(fsp, qup->fsname)) continue; @@ -669,8 +699,10 @@ readprivs(struct quotause *quplist, char qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; qup->flags |= FOUND; - if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && - dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) + /* Humanized input returns only approximate counts */ + if (hflag || + (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && + dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes)) break; warnx("%s: cannot change current allocation", fsp); break; @@ -836,7 +868,7 @@ cvtatos(u_int64_t period, char *units, u * Convert a limit to number of disk blocks. */ u_int64_t -cvtval(u_int64_t limit, char units) +cvtblkval(u_int64_t limit, char units, const char *itemname) { switch(units) { @@ -872,11 +904,62 @@ cvtval(u_int64_t limit, char units) limit *= btodb(1152921504606846976); break; case ' ': - errx(2, "No space permitted between value and units\n"); + errx(2, "No space permitted between value and units for %s\n", + itemname); + break; + default: + errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", + limit, units, itemname); + break; + } + return (limit); +} + +/* + * Convert a limit to number of inodes. + */ +u_int64_t +cvtinoval(u_int64_t limit, char units, const char *itemname) +{ + + switch(units) { + case 'B': + case 'b': + case '\0': /* historic behavior */ + case ',': /* historic behavior */ + case ')': /* historic behavior */ + break; + case 'K': + case 'k': + limit *= 1000; + break; + case 'M': + case 'm': + limit *= 1000000; + break; + case 'G': + case 'g': + limit *= 1000000000; + break; + case 'T': + case 't': + limit *= 1000000000000; + break; + case 'P': + case 'p': + limit *= 1000000000000000; + break; + case 'E': + case 'e': + limit *= 1000000000000000000; + break; + case ' ': + errx(2, "No space permitted between value and units for %s\n", + itemname); break; default: - errx(2, "%llu%c: unknown units, specify K, M, G, T, P, or E\n", - limit, units); + errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", + limit, units, itemname); break; } return (limit);