tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: strtonum(3) from OpenBSD?
On Tue, 23 Jun 2009, Marc Balmer wrote:
> Yes, already more than one program apparently use it.
For instance bioctl(8) uses (an internal version of) it but weirdly even
though strtoul() is considered difficult and unsafe, it uses that also..?
(perhaps you can tell, I don't really like this function, patch below to
remove it from bioctl :)
iain
Index: Makefile
===================================================================
RCS file: /cvsroot/src/sbin/bioctl/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- Makefile 11 Apr 2009 07:58:11 -0000 1.4
+++ Makefile 23 Jun 2009 17:21:30 -0000
@@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.4 2009/04/11 07:58:11 lukem Exp $
PROG= bioctl
-SRCS= bioctl.c strtonum.c
+SRCS= bioctl.c
MAN= bioctl.8
.include <bsd.prog.mk>
Index: bioctl.c
===================================================================
RCS file: /cvsroot/src/sbin/bioctl/bioctl.c,v
retrieving revision 1.12
diff -u -r1.12 bioctl.c
--- bioctl.c 18 Jan 2009 00:27:59 -0000 1.12
+++ bioctl.c 23 Jun 2009 17:21:30 -0000
@@ -51,7 +51,6 @@
#include <unistd.h>
#include <ctype.h>
#include <util.h>
-#include "strtonum.h"
struct command {
const char *cmd_name;
@@ -94,7 +93,7 @@
#endif
static void bio_volops_remove(int, int, char **);
-static const char *str2locator(const char *, struct locator *);
+static int str2locator(const char *, struct locator *);
static struct bio_locate bl;
static struct command commands[] = {
@@ -199,34 +198,44 @@
/* NOTREACHED */
}
-static const char *
+/*
+ * locator is "channel:target[.lun]" where each of channel, target
+ * and lun are unsigned values in the range 0-256
+ */
+static int
str2locator(const char *string, struct locator *location)
{
- const char *errstr;
- char parse[80], *targ, *lun;
+ unsigned long n;
+ char *ep;
- strlcpy(parse, string, sizeof parse);
- targ = strchr(parse, ':');
- if (targ == NULL)
- return "target not specified";
-
- *targ++ = '\0';
- lun = strchr(targ, '.');
- if (lun != NULL) {
- *lun++ = '\0';
- location->lun = strtonum(lun, 0, 256, &errstr);
- if (errstr)
- return errstr;
- } else
+ if (string == NULL)
+ return 0;
+
+ n = strtoul(string, &ep, 10);
+ if (string[0] == '\0' || *ep != ':' || n > 256)
+ return 0;
+
+ location->channel = (int)n;
+
+ string = ep + 1;
+ n = strtoul(string, &ep, 10);
+ if (string[0] == '\0' || (*ep != '\0' && *ep != '.') || n > 256)
+ return 0;
+
+ location->target = (int)n;
+
+ if (*ep == '\0') {
location->lun = 0;
+ } else {
+ string = ep + 1;
+ n = strtoul(string, &ep, 10);
+ if (string[0] == '\0' || *ep != '\0' || n > 256)
+ return 0;
+
+ location->lun = (int)n;
+ }
- location->target = strtonum(targ, 0, 256, &errstr);
- if (errstr)
- return errstr;
- location->channel = strtonum(parse, 0, 256, &errstr);
- if (errstr)
- return errstr;
- return NULL;
+ return 1;
}
/*
@@ -663,14 +672,12 @@
bio_setstate_common(int fd, char *arg, struct bioc_setstate *bs,
struct locator *location)
{
- const char *errstr;
if (!arg || !location)
goto send;
- errstr = str2locator(arg, location);
- if (errstr)
- errx(EXIT_FAILURE, "Target %s: %s", arg, errstr);
+ if (!str2locator(arg, location))
+ errx(EXIT_FAILURE, "Invalid target %s", arg);
bs->bs_channel = location->channel;
bs->bs_target = location->target;
@@ -695,7 +702,6 @@
struct locator location;
uint64_t total_size = 0, disksize = 0;
int64_t volsize = 0;
- const char *errstr;
char *endptr, *stripe, levelstr[32];
char *scsiname, *raid_level, size[64];
int disk_first = 0, disk_end = 0;
@@ -745,9 +751,8 @@
if (*endptr != '\0')
errx(EXIT_FAILURE, "Invalid RAID_LEVEL value");
- errstr = str2locator(scsiname, &location);
- if (errstr)
- errx(EXIT_FAILURE, "Target %s: %s", scsiname, errstr);
+ if (!str2locator(scsiname, &location))
+ errx(EXIT_FAILURE, "Invalid target %s", scsiname);
/*
* Parse the device list that will be used for the volume,
@@ -899,7 +904,6 @@
{
struct bioc_volops bc;
struct locator location;
- const char *errstr;
char *endptr;
if (argc != 3 || strcmp(argv[0], "volume") != 0)
@@ -913,9 +917,8 @@
if (*endptr != '\0')
errx(EXIT_FAILURE, "Invalid Volume ID value");
- errstr = str2locator(argv[2], &location);
- if (errstr)
- errx(EXIT_FAILURE, "Target %s: %s", argv[2], errstr);
+ if (!str2locator(argv[2], &location))
+ errx(EXIT_FAILURE, "Invalid target %s", argv[2]);
bc.bc_channel = location.channel;
bc.bc_target = location.target;
@@ -939,7 +942,6 @@
struct bioc_vol bv;
struct bioc_disk bd;
struct bioc_blink bb;
- const char *errstr;
int v, d, rv, blink = 0;
if (argc != 2)
@@ -952,9 +954,8 @@
else
usage();
- errstr = str2locator(argv[1], &location);
- if (errstr)
- errx(EXIT_FAILURE, "Target %s: %s", argv[1], errstr);
+ if (!str2locator(argv[1], &location))
+ errx(EXIT_FAILURE, "Invalid target %s", argv[1]);
/* try setting blink on the device directly */
memset(&bb, 0, sizeof(bb));
Index: strtonum.c
===================================================================
RCS file: strtonum.c
diff -N strtonum.c
--- strtonum.c 1 May 2007 17:18:54 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,72 +0,0 @@
-/* $NetBSD: strtonum.c,v 1.1 2007/05/01 17:18:54 bouyer Exp $ */
-/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
-
-/*
- * Copyright (c) 2004 Ted Unangst and Todd Miller
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/cdefs.h>
-
-#ifndef lint
-__RCSID("$NetBSD: strtonum.c,v 1.1 2007/05/01 17:18:54 bouyer Exp $");
-#endif
-
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include "strtonum.h"
-
-#define INVALID 1
-#define TOOSMALL 2
-#define TOOLARGE 3
-
-long long
-strtonum(const char *numstr, long long minval, long long maxval,
- const char **errstrp)
-{
- long long ll = 0;
- char *ep;
- int error = 0;
- struct errval {
- const char *errstr;
- int err;
- } ev[4] = {
- { NULL, 0 },
- { "invalid", EINVAL },
- { "too small", ERANGE },
- { "too large", ERANGE },
- };
-
- ev[0].err = errno;
- errno = 0;
- if (minval > maxval)
- error = INVALID;
- else {
- ll = strtoll(numstr, &ep, 10);
- if (numstr == ep || *ep != '\0')
- error = INVALID;
- else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
- error = TOOSMALL;
- else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
- error = TOOLARGE;
- }
- if (errstrp != NULL)
- *errstrp = ev[error].errstr;
- errno = ev[error].err;
- if (error)
- ll = 0;
-
- return (ll);
-}
Index: strtonum.h
===================================================================
RCS file: strtonum.h
diff -N strtonum.h
--- strtonum.h 1 May 2007 17:18:54 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,4 +0,0 @@
-/* $NetBSD: strtonum.h,v 1.1 2007/05/01 17:18:54 bouyer Exp $ */
-
-long long strtonum(const char *, long long, long long, const char **);
-
Home |
Main Index |
Thread Index |
Old Index