From fd60e9c668e55cc6c4a6f29130b96b7b4e33d6f3 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net" Date: Sun, 20 Jan 2008 13:18:54 +0000 Subject: Introduce strtonum(), which works like string_to_number(), but passes back the 'end' pointer. It is useful where you want to do boundary checking yet work with strings that are not entirely slurped by strtoul(), e.g.: s = "1/2"; /* one half */ if (!strtonum(s, &end, &value, 0, 5)) error("Zero-length string, or value out of bounds"); if (*end != '/') error("Malformed string"); info->param1 = value; if (!strtonum(end + 1, &end, &value, 2, 4)) error(".."); if (*end != '\0') error("Malformed string"); info->param2 = value; Signed-off-by: Jan Engelhardt --- xtables.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'xtables.c') diff --git a/xtables.c b/xtables.c index b8c2c6f..4313f5b 100644 --- a/xtables.c +++ b/xtables.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -199,6 +200,49 @@ int string_to_number(const char *s, unsigned int min, unsigned int max, return result; } +/* + * strtonum{,l} - string to number conversion + * + * If @end is NULL, we assume the caller does not want + * a case like "15a", so reject it. + */ +bool strtonuml(const char *s, char **end, unsigned long *value, + unsigned long min, unsigned long max) +{ + unsigned long v; + char *my_end; + + errno = 0; + v = strtoul(s, &my_end, 0); + + if (my_end == s) + return false; + if (end != NULL) + *end = my_end; + + if (errno != ERANGE && min <= v && (max == 0 || v <= max)) { + if (value != NULL) + *value = v; + if (end == NULL) + return *my_end == '\0'; + return true; + } + + return false; +} + +bool strtonum(const char *s, char **end, unsigned int *value, + unsigned int min, unsigned int max) +{ + unsigned long v; + bool ret; + + ret = strtonuml(s, end, &v, min, max); + if (value != NULL) + *value = v; + return ret; +} + int service_to_port(const char *name, const char *proto) { struct servent *service; -- cgit v1.2.3