summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2012-07-11 10:27:35 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2012-07-11 10:27:35 +0000
commite5eefcc72799775dae197923a524bf802adf5d9e (patch)
tree831eb861d12d5479bfd4f94561826585536e7186 /sbin
parenta860b51fe2eb6a410556373b230b0bd6c8535f87 (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.c32
-rw-r--r--sbin/fdisk/misc.c167
-rw-r--r--sbin/fdisk/misc.h4
-rw-r--r--sbin/fdisk/part.c6
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;
}