]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Introduce strtonum(), which works like string_to_number(), but passes
authorJan Engelhardt <jengelh@medozas.de>
Sun, 20 Jan 2008 13:18:54 +0000 (13:18 +0000)
committerPatrick McHardy <kaber@trash.net>
Sun, 20 Jan 2008 13:18:54 +0000 (13:18 +0000)
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 <jengelh@computergmbh.de>
include/xtables.h
xtables.c

index 577b3c6a4dae3fc712e8a0e91b77e93f068e0e98..728b1aa3f29f9a8385e140107a09315ffade9cbc 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 #include <linux/netfilter/x_tables.h>
 #include <libiptc/libxtc.h>
+#include <stdbool.h>
 
 #ifndef XT_LIB_DIR
 #define XT_LIB_DIR "/usr/local/lib/iptables"
@@ -206,6 +207,10 @@ extern int string_to_number(const char *s,
                            unsigned int min,
                            unsigned int max,
                            unsigned int *ret);
+extern bool strtonuml(const char *, char **, unsigned long *,
+       unsigned long, unsigned long);
+extern bool strtonum(const char *, char **, unsigned int *,
+       unsigned int, unsigned int);
 extern int service_to_port(const char *name, const char *proto);
 extern u_int16_t parse_port(const char *port, const char *proto);
 extern void
index b8c2c6f4f36498c827f312c58feacebed887d419..4313f5ba25eb6edf2721d70c4f25e5a4365dfd08 100644 (file)
--- a/xtables.c
+++ b/xtables.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <netdb.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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;