1891082f3SDustin Sallings #include <stdio.h>
2420aa2d9SBrad Fitzpatrick #include <assert.h>
3674166c0SBrad Fitzpatrick #include <ctype.h>
4674166c0SBrad Fitzpatrick #include <errno.h>
5674166c0SBrad Fitzpatrick #include <string.h>
6674166c0SBrad Fitzpatrick #include <stdlib.h>
7891082f3SDustin Sallings #include <stdarg.h>
8420aa2d9SBrad Fitzpatrick
9420aa2d9SBrad Fitzpatrick #include "memcached.h"
10420aa2d9SBrad Fitzpatrick
1139f6eeb3SPaul Lindner /* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */
1239f6eeb3SPaul Lindner #define xisspace(c) isspace((unsigned char)c)
1339f6eeb3SPaul Lindner
safe_strtoull(const char * str,uint64_t * out)14a977b556SDustin Sallings bool safe_strtoull(const char *str, uint64_t *out) {
15420aa2d9SBrad Fitzpatrick assert(out != NULL);
16674166c0SBrad Fitzpatrick errno = 0;
17420aa2d9SBrad Fitzpatrick *out = 0;
18420aa2d9SBrad Fitzpatrick char *endptr;
19420aa2d9SBrad Fitzpatrick unsigned long long ull = strtoull(str, &endptr, 10);
20*51c8f31fSTrond Norbye if ((errno == ERANGE) || (str == endptr)) {
21674166c0SBrad Fitzpatrick return false;
22*51c8f31fSTrond Norbye }
23*51c8f31fSTrond Norbye
2439f6eeb3SPaul Lindner if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
25674166c0SBrad Fitzpatrick if ((long long) ull < 0) {
267659ae1cSDustin Sallings /* only check for negative signs in the uncommon case when
277659ae1cSDustin Sallings * the unsigned number is so big that it's negative as a
287659ae1cSDustin Sallings * signed number. */
29674166c0SBrad Fitzpatrick if (strchr(str, '-') != NULL) {
30674166c0SBrad Fitzpatrick return false;
31674166c0SBrad Fitzpatrick }
32674166c0SBrad Fitzpatrick }
33420aa2d9SBrad Fitzpatrick *out = ull;
34420aa2d9SBrad Fitzpatrick return true;
35420aa2d9SBrad Fitzpatrick }
36420aa2d9SBrad Fitzpatrick return false;
37420aa2d9SBrad Fitzpatrick }
38674166c0SBrad Fitzpatrick
safe_strtoll(const char * str,int64_t * out)39a977b556SDustin Sallings bool safe_strtoll(const char *str, int64_t *out) {
40674166c0SBrad Fitzpatrick assert(out != NULL);
41674166c0SBrad Fitzpatrick errno = 0;
42674166c0SBrad Fitzpatrick *out = 0;
43674166c0SBrad Fitzpatrick char *endptr;
44674166c0SBrad Fitzpatrick long long ll = strtoll(str, &endptr, 10);
45*51c8f31fSTrond Norbye if ((errno == ERANGE) || (str == endptr)) {
46674166c0SBrad Fitzpatrick return false;
47*51c8f31fSTrond Norbye }
48*51c8f31fSTrond Norbye
4939f6eeb3SPaul Lindner if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
50674166c0SBrad Fitzpatrick *out = ll;
51674166c0SBrad Fitzpatrick return true;
52674166c0SBrad Fitzpatrick }
53674166c0SBrad Fitzpatrick return false;
54674166c0SBrad Fitzpatrick }
5563ba0e14SDustin Sallings
safe_strtoul(const char * str,uint32_t * out)5663ba0e14SDustin Sallings bool safe_strtoul(const char *str, uint32_t *out) {
5763ba0e14SDustin Sallings char *endptr = NULL;
5863ba0e14SDustin Sallings unsigned long l = 0;
5963ba0e14SDustin Sallings assert(out);
6063ba0e14SDustin Sallings assert(str);
6163ba0e14SDustin Sallings *out = 0;
6263ba0e14SDustin Sallings errno = 0;
6363ba0e14SDustin Sallings
6463ba0e14SDustin Sallings l = strtoul(str, &endptr, 10);
65*51c8f31fSTrond Norbye if ((errno == ERANGE) || (str == endptr)) {
6663ba0e14SDustin Sallings return false;
6763ba0e14SDustin Sallings }
6863ba0e14SDustin Sallings
6939f6eeb3SPaul Lindner if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
7063ba0e14SDustin Sallings if ((long) l < 0) {
7163ba0e14SDustin Sallings /* only check for negative signs in the uncommon case when
7263ba0e14SDustin Sallings * the unsigned number is so big that it's negative as a
7363ba0e14SDustin Sallings * signed number. */
7463ba0e14SDustin Sallings if (strchr(str, '-') != NULL) {
7563ba0e14SDustin Sallings return false;
7663ba0e14SDustin Sallings }
7763ba0e14SDustin Sallings }
7863ba0e14SDustin Sallings *out = l;
7963ba0e14SDustin Sallings return true;
8063ba0e14SDustin Sallings }
8163ba0e14SDustin Sallings
8263ba0e14SDustin Sallings return false;
8363ba0e14SDustin Sallings }
8463ba0e14SDustin Sallings
safe_strtol(const char * str,int32_t * out)8563ba0e14SDustin Sallings bool safe_strtol(const char *str, int32_t *out) {
8663ba0e14SDustin Sallings assert(out != NULL);
8763ba0e14SDustin Sallings errno = 0;
8863ba0e14SDustin Sallings *out = 0;
8963ba0e14SDustin Sallings char *endptr;
9063ba0e14SDustin Sallings long l = strtol(str, &endptr, 10);
91*51c8f31fSTrond Norbye if ((errno == ERANGE) || (str == endptr)) {
9263ba0e14SDustin Sallings return false;
93*51c8f31fSTrond Norbye }
94*51c8f31fSTrond Norbye
9539f6eeb3SPaul Lindner if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
9663ba0e14SDustin Sallings *out = l;
9763ba0e14SDustin Sallings return true;
9863ba0e14SDustin Sallings }
9963ba0e14SDustin Sallings return false;
10063ba0e14SDustin Sallings }
101891082f3SDustin Sallings
vperror(const char * fmt,...)102891082f3SDustin Sallings void vperror(const char *fmt, ...) {
103891082f3SDustin Sallings int old_errno = errno;
1047fc4fcc9STrond Norbye char buf[1024];
105891082f3SDustin Sallings va_list ap;
106891082f3SDustin Sallings
107891082f3SDustin Sallings va_start(ap, fmt);
1087fc4fcc9STrond Norbye if (vsnprintf(buf, sizeof(buf), fmt, ap) == -1) {
1097fc4fcc9STrond Norbye buf[sizeof(buf) - 1] = '\0';
1107fc4fcc9STrond Norbye }
111891082f3SDustin Sallings va_end(ap);
112891082f3SDustin Sallings
113891082f3SDustin Sallings errno = old_errno;
114891082f3SDustin Sallings
115891082f3SDustin Sallings perror(buf);
116891082f3SDustin Sallings }
1179791b779STrond Norbye
1189791b779STrond Norbye #ifndef HAVE_HTONLL
mc_swap64(uint64_t in)1199791b779STrond Norbye static uint64_t mc_swap64(uint64_t in) {
1209791b779STrond Norbye #ifdef ENDIAN_LITTLE
1219791b779STrond Norbye /* Little endian, flip the bytes around until someone makes a faster/better
1229791b779STrond Norbye * way to do this. */
1239791b779STrond Norbye int64_t rv = 0;
1249791b779STrond Norbye int i = 0;
1259791b779STrond Norbye for(i = 0; i<8; i++) {
1269791b779STrond Norbye rv = (rv << 8) | (in & 0xff);
1279791b779STrond Norbye in >>= 8;
1289791b779STrond Norbye }
1299791b779STrond Norbye return rv;
1309791b779STrond Norbye #else
1319791b779STrond Norbye /* big-endian machines don't need byte swapping */
1329791b779STrond Norbye return in;
1339791b779STrond Norbye #endif
1349791b779STrond Norbye }
1359791b779STrond Norbye
ntohll(uint64_t val)1369791b779STrond Norbye uint64_t ntohll(uint64_t val) {
1379791b779STrond Norbye return mc_swap64(val);
1389791b779STrond Norbye }
1399791b779STrond Norbye
htonll(uint64_t val)1409791b779STrond Norbye uint64_t htonll(uint64_t val) {
1419791b779STrond Norbye return mc_swap64(val);
1429791b779STrond Norbye }
1439791b779STrond Norbye #endif
1449791b779STrond Norbye
145