diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2012-07-11 10:27:35 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2012-07-11 10:27:35 +0000 |
commit | e5eefcc72799775dae197923a524bf802adf5d9e (patch) | |
tree | 831eb861d12d5479bfd4f94561826585536e7186 /sbin | |
parent | a860b51fe2eb6a410556373b230b0bd6c8535f87 (diff) |
Simplify guts and calling of getuint(). Eliminate a useless 'help'
capablity by using help text as regular prompt for 'size' and
'offset'. Try to detect and handle more overflow/underflow conditions
in getuint() and ensure returned value is always within requested
bounds. Handle zero-length partitions by treating them as UNUSED.
tested & ok halex@
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/fdisk/cmd.c | 32 | ||||
-rw-r--r-- | sbin/fdisk/misc.c | 167 | ||||
-rw-r--r-- | sbin/fdisk/misc.h | 4 | ||||
-rw-r--r-- | sbin/fdisk/part.c | 6 |
4 files changed, 103 insertions, 106 deletions
diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c index db54b48b300..875b6640f31 100644 --- a/sbin/fdisk/cmd.c +++ b/sbin/fdisk/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.57 2012/07/09 17:19:55 krw Exp $ */ +/* $OpenBSD: cmd.c,v 1.58 2012/07/11 10:27:34 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -191,32 +191,10 @@ Xedit(cmd_t *cmd, disk_t *disk, mbr_t *mbr, mbr_t *tt, int offset) /* Fix up CHS values for LBA */ PRT_fix_CHS(disk, pp); } else { - u_int m; - u_int32_t d; - - /* Get data */ - d = pp->bs; - do { - pp->bs = getuint(disk, "offset", - "Starting sector for this partition.", d, - disk->real->size); - if (pp->bs == UINT_MAX) - printf("Invalid offset.\n"); - } while (pp->bs == UINT_MAX); - - m = MAX(pp->ns, disk->real->size - pp->bs); - if ( m > disk->real->size - pp->bs) { - /* dont have default value extend beyond end of disk */ - m = disk->real->size - pp->bs; - } - d = pp->ns; - do { - pp->ns = getuint(disk, "size", "Size of the partition.", - d, m); - if (pp->ns == UINT_MAX || pp->ns == 0) - printf("Invalid size.\n"); - } while (pp->ns == UINT_MAX || pp->ns == 0); - + pp->bs = getuint(disk, "Partition offset", pp->bs, + disk->real->size); + pp->ns = getuint(disk, "Partition size", pp->ns, + disk->real->size - pp->bs); /* Fix up CHS values */ PRT_fix_CHS(disk, pp); } diff --git a/sbin/fdisk/misc.c b/sbin/fdisk/misc.c index e594f623a7b..df1f02ef2e2 100644 --- a/sbin/fdisk/misc.c +++ b/sbin/fdisk/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.28 2012/07/09 17:19:55 krw Exp $ */ +/* $OpenBSD: misc.c,v 1.29 2012/07/11 10:27:34 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -232,97 +232,116 @@ putlong(void *p, u_int32_t l) /* * adapted from sbin/disklabel/editor.c - * Returns UINT_MAX on error */ u_int32_t -getuint(disk_t *disk, char *prompt, char *helpstring, u_int32_t oval, - u_int32_t maxval) +getuint(disk_t *disk, char *prompt, u_int32_t oval, u_int32_t maxval) { char buf[BUFSIZ], *endptr, *p, operator = '\0'; - u_int32_t rval = oval; size_t n; int mult = 1, secsize = unit_types[SECTORS].conversion; - double d; - int secpercyl; + double d, d2; + int secpercyl, saveerr; + char unit; + + if (oval > maxval) + oval = maxval; secpercyl = disk->real->sectors * disk->real->heads; - buf[0] = '\0'; do { printf("%s: [%u] ", prompt, oval); + if (fgets(buf, sizeof(buf), stdin) == NULL) errx(1, "eof"); + n = strlen(buf); if (n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; - if (buf[0] == '?') - puts(helpstring); - } while (buf[0] == '?'); - if (buf[0] == '*' && buf[1] == '\0') { - rval = maxval; - } else { + if (buf[0] == '\0') { + return (oval); + } else if (buf[0] == '*' && buf[1] == '\0') { + return (maxval); + } + /* deal with units */ - if (buf[0] != '\0' && n > 0) { - switch (tolower(buf[n-1])) { - - case 'c': - mult = secpercyl; - buf[--n] = '\0'; - break; - case 'b': - mult = -secsize; - buf[--n] = '\0'; - break; - case 's': - buf[--n] = '\0'; - break; - case 'k': - if (secsize > 1024) - mult = -secsize / 1024; - else - mult = 1024 / secsize; - buf[--n] = '\0'; - break; - case 'm': - mult = 1048576 / secsize; - buf[--n] = '\0'; - break; - case 'g': - mult = 1073741824 / secsize; - buf[--n] = '\0'; - 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) - rval = UINT_MAX; /* too big/small */ - else if (*endptr != '\0') { - errno = EINVAL; /* non-numbers in str */ - rval = UINT_MAX; - } else { - /* XXX - should check for overflow */ - if (mult > 0) - rval = d * mult; - else - /* Negative mult means divide (fancy) */ - rval = d / (-mult); - - /* Apply the operator */ - if (operator == '+') - rval += oval; - else if (operator == '-') - rval = oval - rval; - } + switch (tolower(buf[n-1])) { + case 'c': + unit = 'c'; + mult = secpercyl; + buf[--n] = '\0'; + break; + case 'b': + unit = 'b'; + mult = -secsize; + buf[--n] = '\0'; + break; + case 's': + unit = 's'; + mult = 1; + buf[--n] = '\0'; + break; + case 'k': + unit = 'k'; + if (secsize > 1024) + mult = -secsize / 1024; + else + mult = 1024 / secsize; + buf[--n] = '\0'; + break; + case 'm': + unit = 'm'; + mult = 1048576 / secsize; + buf[--n] = '\0'; + break; + case 'g': + unit = 'g'; + mult = 1073741824 / secsize; + buf[--n] = '\0'; + break; + default: + unit = ' '; + mult = 1; + break; } - } - return(rval); + /* deal with the operator */ + p = &buf[0]; + if (*p == '+' || *p == '-') + operator = *p++; + else + operator = ' '; + + endptr = p; + errno = 0; + d = strtod(p, &endptr); + saveerr = errno; + d2 = d; + if (mult > 0) + d *= mult; + else { + d /= (-mult); + d2 = d; + } + + /* Apply the operator */ + if (operator == '+') + d = oval + d; + else if (operator == '-') { + d = oval - d; + d2 = d; + } + + if (saveerr == ERANGE || d > maxval || d < 0 || d < d2) { + printf("%s is out of range: %c%s%c\n", prompt, operator, + p, unit); + } else if (*endptr != '\0') { + printf("%s is invalid: %c%s%c\n", prompt, operator, + p, unit); + } else { + break; + } + } while (1); + + return ((u_int32_t)d); } diff --git a/sbin/fdisk/misc.h b/sbin/fdisk/misc.h index cf86e87052f..b7c8039951f 100644 --- a/sbin/fdisk/misc.h +++ b/sbin/fdisk/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.16 2012/07/09 17:19:55 krw Exp $ */ +/* $OpenBSD: misc.h,v 1.17 2012/07/11 10:27:34 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -57,7 +57,7 @@ u_int16_t getshort(void *); u_int32_t getlong(void *); void putshort(void *, u_int16_t); void putlong(void *, u_int32_t); -u_int32_t getuint(disk_t *, char *, char *, u_int32_t, u_int32_t); +u_int32_t getuint(disk_t *, char *, u_int32_t, u_int32_t); #endif /* _MISC_H */ diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c index 6867749d65d..cc99b8201c6 100644 --- a/sbin/fdisk/part.c +++ b/sbin/fdisk/part.c @@ -1,4 +1,4 @@ -/* $OpenBSD: part.c,v 1.50 2009/04/29 22:58:24 deraadt Exp $ */ +/* $OpenBSD: part.c,v 1.51 2012/07/11 10:27:34 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -309,7 +309,7 @@ PRT_fix_BN(disk_t *disk, prt_t *part, int pn) u_int32_t end = 0; /* Zero out entry if not used */ - if (part->id == DOSPTYP_UNUSED ) { + if (part->id == DOSPTYP_UNUSED || part->ns == 0) { memset(part, 0, sizeof(*part)); return; } @@ -343,7 +343,7 @@ PRT_fix_CHS(disk_t *disk, prt_t *part) u_int32_t cyl, head, sect; /* Zero out entry if not used */ - if (part->id == DOSPTYP_UNUSED ) { + if (part->id == DOSPTYP_UNUSED || part->ns == 0) { memset(part, 0, sizeof(*part)); return; } |