aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-08-30 11:08:06 -0700
committerGarrett D'Amore <garrett@damore.org>2018-08-30 15:28:38 -0700
commit629002efac8085a9c6321a15b43a47a43ca0e084 (patch)
tree8d540d491a6583405e625dd11e12f993457837a7
parente7e980c228c76e108bbc4812f40645d93626757f (diff)
downloadnng-629002efac8085a9c6321a15b43a47a43ca0e084.tar.gz
nng-629002efac8085a9c6321a15b43a47a43ca0e084.tar.bz2
nng-629002efac8085a9c6321a15b43a47a43ca0e084.zip
fixes #686 strtoull() not present on Windows
This both makes new functions available to the core, and addresses a bug which would have prevented building the ZeroTier transport on Windows.
-rw-r--r--src/core/strs.c74
-rw-r--r--src/core/strs.h2
-rw-r--r--src/transport/zerotier/zerotier.c4
3 files changed, 77 insertions, 3 deletions
diff --git a/src/core/strs.c b/src/core/strs.c
index 98c1a5fa..ed403a3b 100644
--- a/src/core/strs.c
+++ b/src/core/strs.c
@@ -202,3 +202,77 @@ nni_asprintf(char **sp, const char *fmt, ...)
*sp = s;
return (0);
}
+
+int
+nni_strtou64(const char *s, uint64_t *u)
+{
+ uint64_t v = 0;
+
+ // Arguably we could use strtoull, but Windows doesn't conform
+ // to C99, and so lacks it.
+
+ if ((s == NULL) || (*s == '\0')) {
+ // Require a non-empty string.
+ return (NNG_EINVAL);
+ }
+ while (*s) {
+ uint64_t last = v;
+ if (isdigit(*s)) {
+ v *= 10;
+ v += (*s - '0');
+ } else {
+ return (NNG_EINVAL);
+ }
+ if (v < last) {
+ // Overflow!
+ return (NNG_EINVAL);
+ }
+ s++;
+ }
+ *u = v;
+ return (0);
+}
+
+int
+nni_strtox64(const char *s, uint64_t *u)
+{
+ uint64_t v = 0;
+
+ // Arguably we could use strtoull, but Windows doesn't conform
+ // to C99, and so lacks it.
+
+ if (s == NULL) {
+ return (NNG_EINVAL);
+ }
+ // Skip over 0x if present.
+ if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) {
+ s += 2;
+ }
+ if (*s == '\0') {
+ // Require a non-empty string.
+ return (NNG_EINVAL);
+ }
+
+ while (*s) {
+ uint64_t last = v;
+ if (isdigit(*s)) {
+ v *= 16;
+ v += (*s - '0');
+ } else if ((*s >= 'a') && (*s <= 'f')) {
+ v *= 16;
+ v += (*s - 'a') + 10;
+ } else if ((*s >= 'A') && (*s <= 'F')) {
+ v *= 16;
+ v += (*s - 'A') + 10;
+ } else {
+ return (NNG_EINVAL);
+ }
+ if (v < last) {
+ // Overflow!
+ return (NNG_EINVAL);
+ }
+ s++;
+ }
+ *u = v;
+ return (0);
+}
diff --git a/src/core/strs.h b/src/core/strs.h
index d4851ecf..4ed1fb57 100644
--- a/src/core/strs.h
+++ b/src/core/strs.h
@@ -22,5 +22,7 @@ extern char * nni_strcasestr(const char *, const char *);
extern int nni_strncasecmp(const char *, const char *, size_t);
extern int nni_strcasecmp(const char *, const char *);
extern int nni_asprintf(char **, const char *, ...);
+extern int nni_strtou64(const char *, uint64_t *); // parses decimal
+extern int nni_strtox64(const char *, uint64_t *); // parses hex
#endif // CORE_STRS_H
diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c
index 0b0303d9..95fedc0d 100644
--- a/src/transport/zerotier/zerotier.c
+++ b/src/transport/zerotier/zerotier.c
@@ -1529,14 +1529,12 @@ zt_walk_moons(const char *path, void *arg)
{
zt_node * ztn = arg;
const char *bn = nni_file_basename(path);
- char * ep;
uint64_t moonid;
if (strncmp(bn, "moon.", 5) != 0) {
return (NNI_FILE_WALK_CONTINUE);
}
- moonid = strtoull(bn + 5, &ep, 16);
- if (*ep == '\0') {
+ if (nni_strtox64(bn + 5, &moonid) == 0) {
ZT_Node_orbit(ztn->zn_znode, NULL, moonid, 0);
}
return (NNI_FILE_WALK_CONTINUE);