From 1fec28925427fe31c298eefeb67579c29ea65664 Mon Sep 17 00:00:00 2001 From: krw Date: Thu, 12 Jul 2018 16:59:59 +0000 Subject: [PATCH] Cleanup and clarify getuint64() by using the same functions as auto-allocation. parse_sizespec() and apply_unit(). No intentional functional change. Looked good to tb@ --- sbin/disklabel/editor.c | 153 +++++++++++++--------------------------- 1 file changed, 49 insertions(+), 104 deletions(-) diff --git a/sbin/disklabel/editor.c b/sbin/disklabel/editor.c index 0f587356af0..af28cbc74eb 100644 --- a/sbin/disklabel/editor.c +++ b/sbin/disklabel/editor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: editor.c,v 1.339 2018/07/12 16:53:09 krw Exp $ */ +/* $OpenBSD: editor.c,v 1.340 2018/07/12 16:59:59 krw Exp $ */ /* * Copyright (c) 1997-2000 Todd C. Miller @@ -1153,11 +1153,10 @@ u_int64_t getuint64(struct disklabel *lp, char *prompt, char *helpstring, u_int64_t oval, u_int64_t maxval, int *flags) { - char buf[BUFSIZ], *endptr, *p, operator = '\0'; + char buf[21], *p, operator = '\0'; + char *unit = NULL; u_int64_t rval = oval; - int64_t mult = 1; - size_t n; - double d, percent = 1.0; + double d; int rslt; rslt = snprintf(buf, sizeof(buf), "%llu", oval); @@ -1167,113 +1166,59 @@ getuint64(struct disklabel *lp, char *prompt, char *helpstring, p = getstring(prompt, helpstring, buf); if (p == NULL) return (CMD_ABORTED); - if (strlcpy(buf, p, sizeof(buf)) >= sizeof(buf)) - goto invalid; - n = strlen(buf); - - if (buf[0] == '*' && buf[1] == '\0') { + else if (p[0] == '\0') + rval = oval; + else if (p[0] == '*' && p[1] == '\0') rval = maxval; - } else { - /* deal with units */ - if (buf[0] != '\0' && n > 0) { - if (flags != NULL && (*flags & DO_CONVERSIONS)) { - switch (tolower((unsigned char)buf[n-1])) { - - case 'c': - mult = lp->d_secpercyl; - buf[--n] = '\0'; - break; - case 'b': - mult = -(int64_t)lp->d_secsize; - buf[--n] = '\0'; - break; - case 'k': - if (lp->d_secsize > 1024) - mult = -(int64_t)lp->d_secsize / - 1024LL; - else - mult = 1024LL / lp->d_secsize; - buf[--n] = '\0'; - break; - case 'm': - mult = (1024LL * 1024) / lp->d_secsize; - buf[--n] = '\0'; - break; - case 'g': - mult = (1024LL * 1024 * 1024) / - lp->d_secsize; - buf[--n] = '\0'; - break; - case 't': - mult = (1024LL * 1024 * 1024 * 1024) / - lp->d_secsize; - buf[--n] = '\0'; - break; - case '%': - buf[--n] = '\0'; - p = &buf[0]; - if (*p == '+' || *p == '-') - operator = *p++; - percent = strtod(p, NULL) / 100.0; - snprintf(buf, sizeof(buf), "%llu", - DL_GETDSIZE(lp)); - break; - case '&': - buf[--n] = '\0'; - p = &buf[0]; - if (*p == '+' || *p == '-') - operator = *p++; - percent = strtod(p, NULL) / 100.0; - snprintf(buf, sizeof(buf), "%llu", - maxval); - break; - } - } - - /* Did they give us an operator? */ - p = &buf[0]; - if (*p == '+' || *p == '-') - operator = *p++; - - endptr = p; - errno = 0; - d = strtod(p, &endptr); - if (errno == ERANGE || d < 0) - goto invalid; /* too big/small */ - else if (*endptr != '\0') { - goto invalid; /* non-numbers in str */ - } else { - if (mult > 0) - d = d * mult * percent; - else - d = d / (-mult) * percent; - - if (d < CMD_ABORTED) { - rval = d; - } else { + else { + if (*p == '+' || *p == '-') + operator = *p++; + if (parse_sizespec(p, &d, &unit) == -1) + goto invalid; + if (unit == NULL) + rval = d; + else if (flags != NULL && (*flags & DO_CONVERSIONS) == 0) + goto invalid; + else { + switch (tolower((unsigned char)*unit)) { + case 'b': + rval = d / lp->d_secsize; + break; + case 'c': + rval = d * lp->d_secpercyl; + break; + case '%': + rval = DL_GETDSIZE(lp) * (d / 100.0); + break; + case '&': + rval = maxval * (d / 100.0); + break; + default: + if (apply_unit(d, *unit, &rval) == -1) goto invalid; - } + rval = DL_BLKTOSEC(lp, rval); + break; + } + } - /* Range check then apply [+-] operator */ - if (operator == '+') { - if (CMD_ABORTED - oval > rval) - rval += oval; - else { - goto invalid; - } - } else if (operator == '-') { - if (oval >= rval) - rval = oval - rval; - else { - goto invalid; - } - } + /* Range check then apply [+-] operator */ + if (operator == '+') { + if (CMD_ABORTED - oval > rval) + rval += oval; + else { + goto invalid; + } + } else if (operator == '-') { + if (oval >= rval) + rval = oval - rval; + else { + goto invalid; } } } if (flags != NULL) { - if (mult != 1) + if (unit != NULL) *flags |= DO_ROUNDING; #ifdef SUN_CYLCHECK if (lp->d_flags & D_VENDOR) -- 2.20.1