20
23
#include <common/standard.h>
21
24
#include <proto/log.h>
23
/* enough to store 2^64-1 = 18446744073709551615 */
24
static char itoa_str[21];
26
/* enough to store 10 integers of :
27
* 2^64-1 = 18446744073709551615 or
28
* -2^63 = -9223372036854775808
30
char itoa_str[10][21];
27
33
* copies at most <size-1> chars from <src> to <dst>. Last char is always
46
* This function simply returns a statically allocated string containing
52
* This function simply returns a locally allocated string containing
47
53
* the ascii representation for number 'n' in decimal.
49
char *ultoa(unsigned long n)
55
const char *ultoa_r(unsigned long n, char *buffer, int size)
53
pos = itoa_str + sizeof(itoa_str) - 1;
59
pos = buffer + size - 1;
57
63
*pos-- = '0' + n % 10;
59
} while (n && pos >= itoa_str);
65
} while (n && pos >= buffer);
70
* This function simply returns a locally allocated string containing the ascii
71
* representation for number 'n' in decimal, unless n is 0 in which case it
72
* returns the alternate string (or an empty string if the alternate string is
73
* NULL). It use is intended for limits reported in reports, where it's
74
* desirable not to display anything if there is no limit. Warning! it shares
75
* the same vector as ultoa_r().
77
const char *limit_r(unsigned long n, char *buffer, int size, const char *alt)
79
return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
83
* converts <str> to a struct sockaddr_un* which is locally allocated.
84
* The format is "/path", where "/path" is a path to a UNIX domain socket.
86
struct sockaddr_un *str2sun(const char *str)
88
static struct sockaddr_un su;
89
int strsz; /* length included null */
91
memset(&su, 0, sizeof(su));
92
strsz = strlen(str) + 1;
93
if (strsz > sizeof(su.sun_path)) {
94
Alert("Socket path '%s' too long (max %d)\n",
95
str, sizeof(su.sun_path) - 1);
97
su.sun_family = AF_UNIX;
98
memcpy(su.sun_path, str, strsz);
65
104
* Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
125
* Checks <name> for invalid characters. Valid chars are [A-Za-z0-9_:.-]. If an
126
* invalid character is found, a pointer to it is returned. If everything is
127
* fine, NULL is returned.
129
const char *invalid_char(const char *name)
135
if (!isalnum((int)*name) && *name != '.' && *name != ':' &&
136
*name != '_' && *name != '-')
87
144
* converts <str> to a struct sockaddr_in* which is locally allocated.
248
* Parse IP address found in url.
250
static int url2ip(const char *addr, struct in_addr *dst)
252
int saw_digit, octets, ch;
254
const char *cp = addr;
261
unsigned char digit = (ch = *addr++) - '0';
262
if (digit > 9 && ch != '.')
265
u_int new = *tp * 10 + digit;
274
} else if (ch == '.' && saw_digit) {
286
memcpy(&dst->s_addr, tmp, 4);
291
* Resolve destination server from URL. Convert <str> to a sockaddr_in*.
293
int url2sa(const char *url, int ulen, struct sockaddr_in *addr)
295
const char *curr = url, *cp = url;
296
int ret, url_code = 0;
297
unsigned int http_code = 0;
299
/* Cleanup the room */
300
addr->sin_family = AF_INET;
301
addr->sin_addr.s_addr = 0;
304
/* Firstly, try to find :// pattern */
305
while (curr < url+ulen && url_code != 0x3a2f2f) {
306
url_code = ((url_code & 0xffff) << 8);
307
url_code += (unsigned char)*curr++;
310
/* Secondly, if :// pattern is found, verify parsed stuff
311
* before pattern is matching our http pattern.
312
* If so parse ip address and port in uri.
314
* WARNING: Current code doesn't support dynamic async dns resolver.
316
if (url_code == 0x3a2f2f) {
317
while (cp < curr - 3)
318
http_code = (http_code << 8) + *cp++;
319
http_code |= 0x20202020; /* Turn everything to lower case */
321
/* HTTP url matching */
322
if (http_code == 0x68747470) {
323
/* We are looking for IP address. If you want to parse and
324
* resolve hostname found in url, you can use str2sa(), but
325
* be warned this can slow down global daemon performances
326
* while handling lagging dns responses.
328
ret = url2ip(curr, &addr->sin_addr);
332
addr->sin_port = (*curr == ':') ? str2uic(++curr) : 80;
333
addr->sin_port = htons(addr->sin_port);
189
341
/* will try to encode the string <string> replacing all characters tagged in
190
342
* <map> with the hexadecimal representation of their ASCII-code (2 digits)
191
343
* prefixed by <escape>, and will store the result between <start> (included)
521
/* This function parses a time value optionally followed by a unit suffix among
522
* "d", "h", "m", "s", "ms" or "us". It converts the value into the unit
523
* expected by the caller. The computation does its best to avoid overflows.
524
* The value is returned in <ret> if everything is fine, and a NULL is returned
525
* by the function. In case of error, a pointer to the error is returned and
526
* <ret> is left untouched. Values are automatically rounded up when needed.
528
const char *parse_time_err(const char *text, unsigned *ret, unsigned unit_flags)
530
unsigned imult, idiv;
531
unsigned omult, odiv;
536
switch (unit_flags & TIME_UNIT_MASK) {
537
case TIME_UNIT_US: omult = 1000000; break;
538
case TIME_UNIT_MS: omult = 1000; break;
539
case TIME_UNIT_S: break;
540
case TIME_UNIT_MIN: odiv = 60; break;
541
case TIME_UNIT_HOUR: odiv = 3600; break;
542
case TIME_UNIT_DAY: odiv = 86400; break;
561
case '\0': /* no unit = default unit */
562
imult = omult = idiv = odiv = 1;
564
case 's': /* second = unscaled unit */
566
case 'u': /* microsecond : "us" */
567
if (text[1] == 's') {
572
case 'm': /* millisecond : "ms" or minute: "m" */
573
if (text[1] == 's') {
579
case 'h': /* hour : "h" */
582
case 'd': /* day : "d" */
590
if (omult % idiv == 0) { omult /= idiv; idiv = 1; }
591
if (idiv % omult == 0) { idiv /= omult; omult = 1; }
592
if (imult % odiv == 0) { imult /= odiv; odiv = 1; }
593
if (odiv % imult == 0) { odiv /= imult; imult = 1; }
595
value = (value * (imult * omult) + (idiv * odiv - 1)) / (idiv * odiv);
371
601
* Local variables: