diff --git a/src/tools.c b/src/tools.c
new file mode 100644
index 0000000..fbec3f5
--- /dev/null
+++ b/src/tools.c
@@ -0,0 +1,4726 @@
+/*
+ * General purpose functions.
+ *
+ * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifdef __ELF__
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <link.h>
+#endif
+
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
+#include <sys/auxv.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <import/eb32tree.h>
+#include <import/eb32sctree.h>
+
+#include <haproxy/api.h>
+#include <haproxy/chunk.h>
+#include <haproxy/namespace.h>
+#include <haproxy/tools.h>
+#include <types/global.h>
+#include <proto/applet.h>
+#include <proto/dns.h>
+#include <proto/hlua.h>
+#include <proto/listener.h>
+#include <proto/proto_udp.h>
+#include <proto/ssl_sock.h>
+#include <proto/stream_interface.h>
+#include <proto/task.h>
+
+/* This macro returns false if the test __x is false. Many
+ * of the following parsing function must be abort the processing
+ * if it returns 0, so this macro is useful for writing light code.
+ */
+#define RET0_UNLESS(__x) do { if (!(__x)) return 0; } while (0)
+
+/* enough to store NB_ITOA_STR integers of :
+ *   2^64-1 = 18446744073709551615 or
+ *    -2^63 = -9223372036854775808
+ *
+ * The HTML version needs room for adding the 25 characters
+ * '<span class="rls"></span>' around digits at positions 3N+1 in order
+ * to add spacing at up to 6 positions : 18 446 744 073 709 551 615
+ */
+THREAD_LOCAL char itoa_str[NB_ITOA_STR][171];
+THREAD_LOCAL int itoa_idx = 0; /* index of next itoa_str to use */
+
+/* sometimes we'll need to quote strings (eg: in stats), and we don't expect
+ * to quote strings larger than a max configuration line.
+ */
+THREAD_LOCAL char quoted_str[NB_QSTR][QSTR_SIZE + 1];
+THREAD_LOCAL int quoted_idx = 0;
+
+/*
+ * unsigned long long ASCII representation
+ *
+ * return the last char '\0' or NULL if no enough
+ * space in dst
+ */
+char *ulltoa(unsigned long long n, char *dst, size_t size)
+{
+	int i = 0;
+	char *res;
+
+	switch(n) {
+		case 1ULL ... 9ULL:
+			i = 0;
+			break;
+
+		case 10ULL ... 99ULL:
+			i = 1;
+			break;
+
+		case 100ULL ... 999ULL:
+			i = 2;
+			break;
+
+		case 1000ULL ... 9999ULL:
+			i = 3;
+			break;
+
+		case 10000ULL ... 99999ULL:
+			i = 4;
+			break;
+
+		case 100000ULL ... 999999ULL:
+			i = 5;
+			break;
+
+		case 1000000ULL ... 9999999ULL:
+			i = 6;
+			break;
+
+		case 10000000ULL ... 99999999ULL:
+			i = 7;
+			break;
+
+		case 100000000ULL ... 999999999ULL:
+			i = 8;
+			break;
+
+		case 1000000000ULL ... 9999999999ULL:
+			i = 9;
+			break;
+
+		case 10000000000ULL ... 99999999999ULL:
+			i = 10;
+			break;
+
+		case 100000000000ULL ... 999999999999ULL:
+			i = 11;
+			break;
+
+		case 1000000000000ULL ... 9999999999999ULL:
+			i = 12;
+			break;
+
+		case 10000000000000ULL ... 99999999999999ULL:
+			i = 13;
+			break;
+
+		case 100000000000000ULL ... 999999999999999ULL:
+			i = 14;
+			break;
+
+		case 1000000000000000ULL ... 9999999999999999ULL:
+			i = 15;
+			break;
+
+		case 10000000000000000ULL ... 99999999999999999ULL:
+			i = 16;
+			break;
+
+		case 100000000000000000ULL ... 999999999999999999ULL:
+			i = 17;
+			break;
+
+		case 1000000000000000000ULL ... 9999999999999999999ULL:
+			i = 18;
+			break;
+
+		case 10000000000000000000ULL ... ULLONG_MAX:
+			i = 19;
+			break;
+	}
+	if (i + 2 > size) // (i + 1) + '\0'
+		return NULL;  // too long
+	res = dst + i + 1;
+	*res = '\0';
+	for (; i >= 0; i--) {
+		dst[i] = n % 10ULL + '0';
+		n /= 10ULL;
+	}
+	return res;
+}
+
+/*
+ * unsigned long ASCII representation
+ *
+ * return the last char '\0' or NULL if no enough
+ * space in dst
+ */
+char *ultoa_o(unsigned long n, char *dst, size_t size)
+{
+	int i = 0;
+	char *res;
+
+	switch (n) {
+		case 0U ... 9UL:
+			i = 0;
+			break;
+
+		case 10U ... 99UL:
+			i = 1;
+			break;
+
+		case 100U ... 999UL:
+			i = 2;
+			break;
+
+		case 1000U ... 9999UL:
+			i = 3;
+			break;
+
+		case 10000U ... 99999UL:
+			i = 4;
+			break;
+
+		case 100000U ... 999999UL:
+			i = 5;
+			break;
+
+		case 1000000U ... 9999999UL:
+			i = 6;
+			break;
+
+		case 10000000U ... 99999999UL:
+			i = 7;
+			break;
+
+		case 100000000U ... 999999999UL:
+			i = 8;
+			break;
+#if __WORDSIZE == 32
+
+		case 1000000000ULL ... ULONG_MAX:
+			i = 9;
+			break;
+
+#elif __WORDSIZE == 64
+
+		case 1000000000ULL ... 9999999999UL:
+			i = 9;
+			break;
+
+		case 10000000000ULL ... 99999999999UL:
+			i = 10;
+			break;
+
+		case 100000000000ULL ... 999999999999UL:
+			i = 11;
+			break;
+
+		case 1000000000000ULL ... 9999999999999UL:
+			i = 12;
+			break;
+
+		case 10000000000000ULL ... 99999999999999UL:
+			i = 13;
+			break;
+
+		case 100000000000000ULL ... 999999999999999UL:
+			i = 14;
+			break;
+
+		case 1000000000000000ULL ... 9999999999999999UL:
+			i = 15;
+			break;
+
+		case 10000000000000000ULL ... 99999999999999999UL:
+			i = 16;
+			break;
+
+		case 100000000000000000ULL ... 999999999999999999UL:
+			i = 17;
+			break;
+
+		case 1000000000000000000ULL ... 9999999999999999999UL:
+			i = 18;
+			break;
+
+		case 10000000000000000000ULL ... ULONG_MAX:
+			i = 19;
+			break;
+
+#endif
+	}
+	if (i + 2 > size) // (i + 1) + '\0'
+		return NULL;  // too long
+	res = dst + i + 1;
+	*res = '\0';
+	for (; i >= 0; i--) {
+		dst[i] = n % 10U + '0';
+		n /= 10U;
+	}
+	return res;
+}
+
+/*
+ * signed long ASCII representation
+ *
+ * return the last char '\0' or NULL if no enough
+ * space in dst
+ */
+char *ltoa_o(long int n, char *dst, size_t size)
+{
+	char *pos = dst;
+
+	if (n < 0) {
+		if (size < 3)
+			return NULL; // min size is '-' + digit + '\0' but another test in ultoa
+		*pos = '-';
+		pos++;
+		dst = ultoa_o(-n, pos, size - 1);
+	} else {
+		dst = ultoa_o(n, dst, size);
+	}
+	return dst;
+}
+
+/*
+ * signed long long ASCII representation
+ *
+ * return the last char '\0' or NULL if no enough
+ * space in dst
+ */
+char *lltoa(long long n, char *dst, size_t size)
+{
+	char *pos = dst;
+
+	if (n < 0) {
+		if (size < 3)
+			return NULL; // min size is '-' + digit + '\0' but another test in ulltoa
+		*pos = '-';
+		pos++;
+		dst = ulltoa(-n, pos, size - 1);
+	} else {
+		dst = ulltoa(n, dst, size);
+	}
+	return dst;
+}
+
+/*
+ * write a ascii representation of a unsigned into dst,
+ * return a pointer to the last character
+ * Pad the ascii representation with '0', using size.
+ */
+char *utoa_pad(unsigned int n, char *dst, size_t size)
+{
+	int i = 0;
+	char *ret;
+
+	switch(n) {
+		case 0U ... 9U:
+			i = 0;
+			break;
+
+		case 10U ... 99U:
+			i = 1;
+			break;
+
+		case 100U ... 999U:
+			i = 2;
+			break;
+
+		case 1000U ... 9999U:
+			i = 3;
+			break;
+
+		case 10000U ... 99999U:
+			i = 4;
+			break;
+
+		case 100000U ... 999999U:
+			i = 5;
+			break;
+
+		case 1000000U ... 9999999U:
+			i = 6;
+			break;
+
+		case 10000000U ... 99999999U:
+			i = 7;
+			break;
+
+		case 100000000U ... 999999999U:
+			i = 8;
+			break;
+
+		case 1000000000U ... 4294967295U:
+			i = 9;
+			break;
+	}
+	if (i + 2 > size) // (i + 1) + '\0'
+		return NULL;  // too long
+	if (i < size)
+		i = size - 2; // padding - '\0'
+
+	ret = dst + i + 1;
+	*ret = '\0';
+	for (; i >= 0; i--) {
+		dst[i] = n % 10U + '0';
+		n /= 10U;
+	}
+	return ret;
+}
+
+/*
+ * copies at most <size-1> chars from <src> to <dst>. Last char is always
+ * set to 0, unless <size> is 0. The number of chars copied is returned
+ * (excluding the terminating zero).
+ * This code has been optimized for size and speed : on x86, it's 45 bytes
+ * long, uses only registers, and consumes only 4 cycles per char.
+ */
+int strlcpy2(char *dst, const char *src, int size)
+{
+	char *orig = dst;
+	if (size) {
+		while (--size && (*dst = *src)) {
+			src++; dst++;
+		}
+		*dst = 0;
+	}
+	return dst - orig;
+}
+
+/*
+ * This function simply returns a locally allocated string containing
+ * the ascii representation for number 'n' in decimal.
+ */
+char *ultoa_r(unsigned long n, char *buffer, int size)
+{
+	char *pos;
+	
+	pos = buffer + size - 1;
+	*pos-- = '\0';
+	
+	do {
+		*pos-- = '0' + n % 10;
+		n /= 10;
+	} while (n && pos >= buffer);
+	return pos + 1;
+}
+
+/*
+ * This function simply returns a locally allocated string containing
+ * the ascii representation for number 'n' in decimal.
+ */
+char *lltoa_r(long long int in, char *buffer, int size)
+{
+	char *pos;
+	int neg = 0;
+	unsigned long long int n;
+
+	pos = buffer + size - 1;
+	*pos-- = '\0';
+
+	if (in < 0) {
+		neg = 1;
+		n = -in;
+	}
+	else
+		n = in;
+
+	do {
+		*pos-- = '0' + n % 10;
+		n /= 10;
+	} while (n && pos >= buffer);
+	if (neg && pos > buffer)
+		*pos-- = '-';
+	return pos + 1;
+}
+
+/*
+ * This function simply returns a locally allocated string containing
+ * the ascii representation for signed number 'n' in decimal.
+ */
+char *sltoa_r(long n, char *buffer, int size)
+{
+	char *pos;
+
+	if (n >= 0)
+		return ultoa_r(n, buffer, size);
+
+	pos = ultoa_r(-n, buffer + 1, size - 1) - 1;
+	*pos = '-';
+	return pos;
+}
+
+/*
+ * This function simply returns a locally allocated string containing
+ * the ascii representation for number 'n' in decimal, formatted for
+ * HTML output with tags to create visual grouping by 3 digits. The
+ * output needs to support at least 171 characters.
+ */
+const char *ulltoh_r(unsigned long long n, char *buffer, int size)
+{
+	char *start;
+	int digit = 0;
+	
+	start = buffer + size;
+	*--start = '\0';
+	
+	do {
+		if (digit == 3 && start >= buffer + 7)
+			memcpy(start -= 7, "</span>", 7);
+
+		if (start >= buffer + 1) {
+			*--start = '0' + n % 10;
+			n /= 10;
+		}
+
+		if (digit == 3 && start >= buffer + 18)
+			memcpy(start -= 18, "<span class=\"rls\">", 18);
+
+		if (digit++ == 3)
+			digit = 1;
+	} while (n && start > buffer);
+	return start;
+}
+
+/*
+ * This function simply returns a locally allocated string containing the ascii
+ * representation for number 'n' in decimal, unless n is 0 in which case it
+ * returns the alternate string (or an empty string if the alternate string is
+ * NULL). It use is intended for limits reported in reports, where it's
+ * desirable not to display anything if there is no limit. Warning! it shares
+ * the same vector as ultoa_r().
+ */
+const char *limit_r(unsigned long n, char *buffer, int size, const char *alt)
+{
+	return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
+}
+
+/* returns a locally allocated string containing the quoted encoding of the
+ * input string. The output may be truncated to QSTR_SIZE chars, but it is
+ * guaranteed that the string will always be properly terminated. Quotes are
+ * encoded by doubling them as is commonly done in CSV files. QSTR_SIZE must
+ * always be at least 4 chars.
+ */
+const char *qstr(const char *str)
+{
+	char *ret = quoted_str[quoted_idx];
+	char *p, *end;
+
+	if (++quoted_idx >= NB_QSTR)
+		quoted_idx = 0;
+
+	p = ret;
+	end = ret + QSTR_SIZE;
+
+	*p++ = '"';
+
+	/* always keep 3 chars to support passing "" and the ending " */
+	while (*str && p < end - 3) {
+		if (*str == '"') {
+			*p++ = '"';
+			*p++ = '"';
+		}
+		else
+			*p++ = *str;
+		str++;
+	}
+	*p++ = '"';
+	return ret;
+}
+
+/*
+ * Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
+ *
+ * It looks like this one would be a good candidate for inlining, but this is
+ * not interesting because it around 35 bytes long and often called multiple
+ * times within the same function.
+ */
+int ishex(char s)
+{
+	s -= '0';
+	if ((unsigned char)s <= 9)
+		return 1;
+	s -= 'A' - '0';
+	if ((unsigned char)s <= 5)
+		return 1;
+	s -= 'a' - 'A';
+	if ((unsigned char)s <= 5)
+		return 1;
+	return 0;
+}
+
+/* rounds <i> down to the closest value having max 2 digits */
+unsigned int round_2dig(unsigned int i)
+{
+	unsigned int mul = 1;
+
+	while (i >= 100) {
+		i /= 10;
+		mul *= 10;
+	}
+	return i * mul;
+}
+
+/*
+ * Checks <name> for invalid characters. Valid chars are [A-Za-z0-9_:.-]. If an
+ * invalid character is found, a pointer to it is returned. If everything is
+ * fine, NULL is returned.
+ */
+const char *invalid_char(const char *name)
+{
+	if (!*name)
+		return name;
+
+	while (*name) {
+		if (!isalnum((unsigned char)*name) && *name != '.' && *name != ':' &&
+		    *name != '_' && *name != '-')
+			return name;
+		name++;
+	}
+	return NULL;
+}
+
+/*
+ * Checks <name> for invalid characters. Valid chars are [_.-] and those
+ * accepted by <f> function.
+ * If an invalid character is found, a pointer to it is returned.
+ * If everything is fine, NULL is returned.
+ */
+static inline const char *__invalid_char(const char *name, int (*f)(int)) {
+
+	if (!*name)
+		return name;
+
+	while (*name) {
+		if (!f((unsigned char)*name) && *name != '.' &&
+		    *name != '_' && *name != '-')
+			return name;
+
+		name++;
+	}
+
+	return NULL;
+}
+
+/*
+ * Checks <name> for invalid characters. Valid chars are [A-Za-z0-9_.-].
+ * If an invalid character is found, a pointer to it is returned.
+ * If everything is fine, NULL is returned.
+ */
+const char *invalid_domainchar(const char *name) {
+	return __invalid_char(name, isalnum);
+}
+
+/*
+ * Checks <name> for invalid characters. Valid chars are [A-Za-z_.-].
+ * If an invalid character is found, a pointer to it is returned.
+ * If everything is fine, NULL is returned.
+ */
+const char *invalid_prefix_char(const char *name) {
+	return __invalid_char(name, isalnum);
+}
+
+/*
+ * converts <str> to a struct sockaddr_storage* provided by the caller. The
+ * caller must have zeroed <sa> first, and may have set sa->ss_family to force
+ * parse a specific address format. If the ss_family is 0 or AF_UNSPEC, then
+ * the function tries to guess the address family from the syntax. If the
+ * family is forced and the format doesn't match, an error is returned. The
+ * string is assumed to contain only an address, no port. The address can be a
+ * dotted IPv4 address, an IPv6 address, a host name, or empty or "*" to
+ * indicate INADDR_ANY. NULL is returned if the host part cannot be resolved.
+ * The return address will only have the address family and the address set,
+ * all other fields remain zero. The string is not supposed to be modified.
+ * The IPv6 '::' address is IN6ADDR_ANY. If <resolve> is non-zero, the hostname
+ * is resolved, otherwise only IP addresses are resolved, and anything else
+ * returns NULL. If the address contains a port, this one is preserved.
+ */
+struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, int resolve)
+{
+	struct hostent *he;
+	/* max IPv6 length, including brackets and terminating NULL */
+	char tmpip[48];
+	int port = get_host_port(sa);
+
+	/* check IPv6 with square brackets */
+	if (str[0] == '[') {
+		size_t iplength = strlen(str);
+
+		if (iplength < 4) {
+			/* minimal size is 4 when using brackets "[::]" */
+			goto fail;
+		}
+		else if (iplength >= sizeof(tmpip)) {
+			/* IPv6 literal can not be larger than tmpip */
+			goto fail;
+		}
+		else {
+			if (str[iplength - 1] != ']') {
+				/* if address started with bracket, it should end with bracket */
+				goto fail;
+			}
+			else {
+				memcpy(tmpip, str + 1, iplength - 2);
+				tmpip[iplength - 2] = '\0';
+				str = tmpip;
+			}
+		}
+	}
+
+	/* Any IPv6 address */
+	if (str[0] == ':' && str[1] == ':' && !str[2]) {
+		if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
+			sa->ss_family = AF_INET6;
+		else if (sa->ss_family != AF_INET6)
+			goto fail;
+		set_host_port(sa, port);
+		return sa;
+	}
+
+	/* Any address for the family, defaults to IPv4 */
+	if (!str[0] || (str[0] == '*' && !str[1])) {
+		if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
+			sa->ss_family = AF_INET;
+		set_host_port(sa, port);
+		return sa;
+	}
+
+	/* check for IPv6 first */
+	if ((!sa->ss_family || sa->ss_family == AF_UNSPEC || sa->ss_family == AF_INET6) &&
+	    inet_pton(AF_INET6, str, &((struct sockaddr_in6 *)sa)->sin6_addr)) {
+		sa->ss_family = AF_INET6;
+		set_host_port(sa, port);
+		return sa;
+	}
+
+	/* then check for IPv4 */
+	if ((!sa->ss_family || sa->ss_family == AF_UNSPEC || sa->ss_family == AF_INET) &&
+	    inet_pton(AF_INET, str, &((struct sockaddr_in *)sa)->sin_addr)) {
+		sa->ss_family = AF_INET;
+		set_host_port(sa, port);
+		return sa;
+	}
+
+	if (!resolve)
+		return NULL;
+
+	if (!dns_hostname_validation(str, NULL))
+		return NULL;
+
+#ifdef USE_GETADDRINFO
+	if (global.tune.options & GTUNE_USE_GAI) {
+		struct addrinfo hints, *result;
+		int success = 0;
+
+		memset(&result, 0, sizeof(result));
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = sa->ss_family ? sa->ss_family : AF_UNSPEC;
+		hints.ai_socktype = SOCK_DGRAM;
+		hints.ai_flags = 0;
+		hints.ai_protocol = 0;
+
+		if (getaddrinfo(str, NULL, &hints, &result) == 0) {
+			if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
+				sa->ss_family = result->ai_family;
+			else if (sa->ss_family != result->ai_family) {
+				freeaddrinfo(result);
+				goto fail;
+			}
+
+			switch (result->ai_family) {
+			case AF_INET:
+				memcpy((struct sockaddr_in *)sa, result->ai_addr, result->ai_addrlen);
+				set_host_port(sa, port);
+				success = 1;
+				break;
+			case AF_INET6:
+				memcpy((struct sockaddr_in6 *)sa, result->ai_addr, result->ai_addrlen);
+				set_host_port(sa, port);
+				success = 1;
+				break;
+			}
+		}
+
+		if (result)
+			freeaddrinfo(result);
+
+		if (success)
+			return sa;
+	}
+#endif
+	/* try to resolve an IPv4/IPv6 hostname */
+	he = gethostbyname(str);
+	if (he) {
+		if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
+			sa->ss_family = he->h_addrtype;
+		else if (sa->ss_family != he->h_addrtype)
+			goto fail;
+
+		switch (sa->ss_family) {
+		case AF_INET:
+			((struct sockaddr_in *)sa)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
+			set_host_port(sa, port);
+			return sa;
+		case AF_INET6:
+			((struct sockaddr_in6 *)sa)->sin6_addr = *(struct in6_addr *) *(he->h_addr_list);
+			set_host_port(sa, port);
+			return sa;
+		}
+	}
+
+	/* unsupported address family */
+ fail:
+	return NULL;
+}
+
+/*
+ * Converts <str> to a locally allocated struct sockaddr_storage *, and a port
+ * range or offset consisting in two integers that the caller will have to
+ * check to find the relevant input format. The following format are supported :
+ *
+ *   String format           | address |  port  |  low   |  high
+ *    addr                   | <addr>  |   0    |   0    |   0
+ *    addr:                  | <addr>  |   0    |   0    |   0
+ *    addr:port              | <addr>  | <port> | <port> | <port>
+ *    addr:pl-ph             | <addr>  |  <pl>  |  <pl>  |  <ph>
+ *    addr:+port             | <addr>  | <port> |   0    | <port>
+ *    addr:-port             | <addr>  |-<port> | <port> |   0
+ *
+ * The detection of a port range or increment by the caller is made by
+ * comparing <low> and <high>. If both are equal, then port 0 means no port
+ * was specified. The caller may pass NULL for <low> and <high> if it is not
+ * interested in retrieving port ranges.
+ *
+ * Note that <addr> above may also be :
+ *    - empty ("")  => family will be AF_INET and address will be INADDR_ANY
+ *    - "*"         => family will be AF_INET and address will be INADDR_ANY
+ *    - "::"        => family will be AF_INET6 and address will be IN6ADDR_ANY
+ *    - a host name => family and address will depend on host name resolving.
+ *
+ * A prefix may be passed in before the address above to force the family :
+ *    - "ipv4@"  => force address to resolve as IPv4 and fail if not possible.
+ *    - "ipv6@"  => force address to resolve as IPv6 and fail if not possible.
+ *    - "unix@"  => force address to be a path to a UNIX socket even if the
+ *                  path does not start with a '/'
+ *    - 'abns@'  -> force address to belong to the abstract namespace (Linux
+ *                  only). These sockets are just like Unix sockets but without
+ *                  the need for an underlying file system. The address is a
+ *                  string. Technically it's like a Unix socket with a zero in
+ *                  the first byte of the address.
+ *    - "fd@"    => an integer must follow, and is a file descriptor number.
+ *
+ * IPv6 addresses can be declared with or without square brackets. When using
+ * square brackets for IPv6 addresses, the port separator (colon) is optional.
+ * If not using square brackets, and in order to avoid any ambiguity with
+ * IPv6 addresses, the last colon ':' is mandatory even when no port is specified.
+ * NULL is returned if the address cannot be parsed. The <low> and <high> ports
+ * are always initialized if non-null, even for non-IP families.
+ *
+ * If <pfx> is non-null, it is used as a string prefix before any path-based
+ * address (typically the path to a unix socket).
+ *
+ * if <fqdn> is non-null, it will be filled with :
+ *   - a pointer to the FQDN of the server name to resolve if there's one, and
+ *     that the caller will have to free(),
+ *   - NULL if there was an explicit address that doesn't require resolution.
+ *
+ * Hostnames are only resolved if <resolve> is non-null. Note that if <resolve>
+ * is null, <fqdn> is still honnored so it is possible for the caller to know
+ * whether a resolution failed by setting <resolve> to null and checking if
+ * <fqdn> was filled, indicating the need for a resolution.
+ *
+ * When a file descriptor is passed, its value is put into the s_addr part of
+ * the address when cast to sockaddr_in and the address family is AF_UNSPEC.
+ */
+struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, char **fqdn, int resolve)
+{
+	static THREAD_LOCAL struct sockaddr_storage ss;
+	struct sockaddr_storage *ret = NULL;
+	char *back, *str2;
+	char *port1, *port2;
+	int portl, porth, porta;
+	int abstract = 0;
+
+	portl = porth = porta = 0;
+	if (fqdn)
+		*fqdn = NULL;
+
+	str2 = back = env_expand(strdup(str));
+	if (str2 == NULL) {
+		memprintf(err, "out of memory in '%s'\n", __FUNCTION__);
+		goto out;
+	}
+
+	if (!*str2) {
+		memprintf(err, "'%s' resolves to an empty address (environment variable missing?)\n", str);
+		goto out;
+	}
+
+	memset(&ss, 0, sizeof(ss));
+
+	if (strncmp(str2, "unix@", 5) == 0) {
+		str2 += 5;
+		abstract = 0;
+		ss.ss_family = AF_UNIX;
+	}
+	else if (strncmp(str2, "abns@", 5) == 0) {
+		str2 += 5;
+		abstract = 1;
+		ss.ss_family = AF_UNIX;
+	}
+	else if (strncmp(str2, "ipv4@", 5) == 0) {
+		str2 += 5;
+		ss.ss_family = AF_INET;
+	}
+	else if (strncmp(str2, "ipv6@", 5) == 0) {
+		str2 += 5;
+		ss.ss_family = AF_INET6;
+	}
+	else if (*str2 == '/') {
+		ss.ss_family = AF_UNIX;
+	}
+	else
+		ss.ss_family = AF_UNSPEC;
+
+	if (ss.ss_family == AF_UNSPEC && strncmp(str2, "sockpair@", 9) == 0) {
+		char *endptr;
+
+		str2 += 9;
+
+		((struct sockaddr_in *)&ss)->sin_addr.s_addr = strtol(str2, &endptr, 10);
+		((struct sockaddr_in *)&ss)->sin_port = 0;
+
+		if (!*str2 || *endptr) {
+			memprintf(err, "file descriptor '%s' is not a valid integer in '%s'\n", str2, str);
+			goto out;
+		}
+
+		ss.ss_family = AF_CUST_SOCKPAIR;
+
+	}
+	else if (ss.ss_family == AF_UNSPEC && strncmp(str2, "fd@", 3) == 0) {
+		char *endptr;
+
+		str2 += 3;
+		((struct sockaddr_in *)&ss)->sin_addr.s_addr = strtol(str2, &endptr, 10);
+		((struct sockaddr_in *)&ss)->sin_port = 0;
+
+		if (!*str2 || *endptr) {
+			memprintf(err, "file descriptor '%s' is not a valid integer in '%s'\n", str2, str);
+			goto out;
+		}
+
+		/* we return AF_UNSPEC if we use a file descriptor number */
+		ss.ss_family = AF_UNSPEC;
+	}
+	else if (ss.ss_family == AF_UNIX) {
+		struct sockaddr_un *un = (struct sockaddr_un *)&ss;
+		int prefix_path_len;
+		int max_path_len;
+		int adr_len;
+
+		/* complete unix socket path name during startup or soft-restart is
+		 * <unix_bind_prefix><path>.<pid>.<bak|tmp>
+		 */
+		prefix_path_len = (pfx && !abstract) ? strlen(pfx) : 0;
+		max_path_len = (sizeof(un->sun_path) - 1) -
+			(abstract ? 0 : prefix_path_len + 1 + 5 + 1 + 3);
+
+		adr_len = strlen(str2);
+		if (adr_len > max_path_len) {
+			memprintf(err, "socket path '%s' too long (max %d)\n", str, max_path_len);
+			goto out;
+		}
+
+		/* when abstract==1, we skip the first zero and copy all bytes except the trailing zero */
+		memset(un->sun_path, 0, sizeof(un->sun_path));
+		if (prefix_path_len)
+			memcpy(un->sun_path, pfx, prefix_path_len);
+		memcpy(un->sun_path + prefix_path_len + abstract, str2, adr_len + 1 - abstract);
+	}
+	else { /* IPv4 and IPv6 */
+		char *end = str2 + strlen(str2);
+		char *chr;
+
+		/* search for : or ] whatever comes first */
+		for (chr = end-1; chr > str2; chr--) {
+			if (*chr == ']' || *chr == ':')
+				break;
+		}
+
+		if (*chr == ':') {
+			/* Found a colon before a closing-bracket, must be a port separator.
+			 * This guarantee backward compatibility.
+			 */
+			*chr++ = '\0';
+			port1 = chr;
+		}
+		else {
+			/* Either no colon and no closing-bracket
+			 * or directly ending with a closing-bracket.
+			 * However, no port.
+			 */
+			port1 = "";
+		}
+
+		if (isdigit((unsigned char)*port1)) {	/* single port or range */
+			port2 = strchr(port1, '-');
+			if (port2)
+				*port2++ = '\0';
+			else
+				port2 = port1;
+			portl = atoi(port1);
+			porth = atoi(port2);
+			porta = portl;
+		}
+		else if (*port1 == '-') { /* negative offset */
+			portl = atoi(port1 + 1);
+			porta = -portl;
+		}
+		else if (*port1 == '+') { /* positive offset */
+			porth = atoi(port1 + 1);
+			porta = porth;
+		}
+		else if (*port1) { /* other any unexpected char */
+			memprintf(err, "invalid character '%c' in port number '%s' in '%s'\n", *port1, port1, str);
+			goto out;
+		}
+
+		/* first try to parse the IP without resolving. If it fails, it
+		 * tells us we need to keep a copy of the FQDN to resolve later
+		 * and to enable DNS. In this case we can proceed if <fqdn> is
+		 * set or if resolve is set, otherwise it's an error.
+		 */
+		if (str2ip2(str2, &ss, 0) == NULL) {
+			if ((!resolve && !fqdn) ||
+				 (resolve && str2ip2(str2, &ss, 1) == NULL)) {
+				memprintf(err, "invalid address: '%s' in '%s'\n", str2, str);
+				goto out;
+			}
+
+			if (fqdn) {
+				if (str2 != back)
+					memmove(back, str2, strlen(str2) + 1);
+				*fqdn = back;
+				back = NULL;
+			}
+		}
+		set_host_port(&ss, porta);
+	}
+
+	ret = &ss;
+ out:
+	if (port)
+		*port = porta;
+	if (low)
+		*low = portl;
+	if (high)
+		*high = porth;
+	free(back);
+	return ret;
+}
+
+/* converts <str> to a struct in_addr containing a network mask. It can be
+ * passed in dotted form (255.255.255.0) or in CIDR form (24). It returns 1
+ * if the conversion succeeds otherwise zero.
+ */
+int str2mask(const char *str, struct in_addr *mask)
+{
+	if (strchr(str, '.') != NULL) {	    /* dotted notation */
+		if (!inet_pton(AF_INET, str, mask))
+			return 0;
+	}
+	else { /* mask length */
+		char *err;
+		unsigned long len = strtol(str, &err, 10);
+
+		if (!*str || (err && *err) || (unsigned)len > 32)
+			return 0;
+
+		len2mask4(len, mask);
+	}
+	return 1;
+}
+
+/* converts <str> to a struct in6_addr containing a network mask. It can be
+ * passed in quadruplet form (ffff:ffff::) or in CIDR form (64). It returns 1
+ * if the conversion succeeds otherwise zero.
+ */
+int str2mask6(const char *str, struct in6_addr *mask)
+{
+	if (strchr(str, ':') != NULL) {	    /* quadruplet notation */
+		if (!inet_pton(AF_INET6, str, mask))
+			return 0;
+	}
+	else { /* mask length */
+		char *err;
+		unsigned long len = strtol(str, &err, 10);
+
+		if (!*str || (err && *err) || (unsigned)len > 128)
+			return 0;
+
+		len2mask6(len, mask);
+	}
+	return 1;
+}
+
+/* convert <cidr> to struct in_addr <mask>. It returns 1 if the conversion
+ * succeeds otherwise zero.
+ */
+int cidr2dotted(int cidr, struct in_addr *mask) {
+
+	if (cidr < 0 || cidr > 32)
+		return 0;
+
+	mask->s_addr = cidr ? htonl(~0UL << (32 - cidr)) : 0;
+	return 1;
+}
+
+/* Convert mask from bit length form to in_addr form.
+ * This function never fails.
+ */
+void len2mask4(int len, struct in_addr *addr)
+{
+	if (len >= 32) {
+		addr->s_addr = 0xffffffff;
+		return;
+	}
+	if (len <= 0) {
+		addr->s_addr = 0x00000000;
+		return;
+	}
+	addr->s_addr = 0xffffffff << (32 - len);
+	addr->s_addr = htonl(addr->s_addr);
+}
+
+/* Convert mask from bit length form to in6_addr form.
+ * This function never fails.
+ */
+void len2mask6(int len, struct in6_addr *addr)
+{
+	len2mask4(len, (struct in_addr *)&addr->s6_addr[0]); /* msb */
+	len -= 32;
+	len2mask4(len, (struct in_addr *)&addr->s6_addr[4]);
+	len -= 32;
+	len2mask4(len, (struct in_addr *)&addr->s6_addr[8]);
+	len -= 32;
+	len2mask4(len, (struct in_addr *)&addr->s6_addr[12]); /* lsb */
+}
+
+/*
+ * converts <str> to two struct in_addr* which must be pre-allocated.
+ * The format is "addr[/mask]", where "addr" cannot be empty, and mask
+ * is optional and either in the dotted or CIDR notation.
+ * Note: "addr" can also be a hostname. Returns 1 if OK, 0 if error.
+ */
+int str2net(const char *str, int resolve, struct in_addr *addr, struct in_addr *mask)
+{
+	__label__ out_free, out_err;
+	char *c, *s;
+	int ret_val;
+
+	s = strdup(str);
+	if (!s)
+		return 0;
+
+	memset(mask, 0, sizeof(*mask));
+	memset(addr, 0, sizeof(*addr));
+
+	if ((c = strrchr(s, '/')) != NULL) {
+		*c++ = '\0';
+		/* c points to the mask */
+		if (!str2mask(c, mask))
+			goto out_err;
+	}
+	else {
+		mask->s_addr = ~0U;
+	}
+	if (!inet_pton(AF_INET, s, addr)) {
+		struct hostent *he;
+
+		if (!resolve)
+			goto out_err;
+
+		if ((he = gethostbyname(s)) == NULL) {
+			goto out_err;
+		}
+		else
+			*addr = *(struct in_addr *) *(he->h_addr_list);
+	}
+
+	ret_val = 1;
+ out_free:
+	free(s);
+	return ret_val;
+ out_err:
+	ret_val = 0;
+	goto out_free;
+}
+
+
+/*
+ * converts <str> to two struct in6_addr* which must be pre-allocated.
+ * The format is "addr[/mask]", where "addr" cannot be empty, and mask
+ * is an optional number of bits (128 being the default).
+ * Returns 1 if OK, 0 if error.
+ */
+int str62net(const char *str, struct in6_addr *addr, unsigned char *mask)
+{
+	char *c, *s;
+	int ret_val = 0;
+	char *err;
+	unsigned long len = 128;
+
+	s = strdup(str);
+	if (!s)
+		return 0;
+
+	memset(mask, 0, sizeof(*mask));
+	memset(addr, 0, sizeof(*addr));
+
+	if ((c = strrchr(s, '/')) != NULL) {
+		*c++ = '\0'; /* c points to the mask */
+		if (!*c)
+			goto out_free;
+
+		len = strtoul(c, &err, 10);
+		if ((err && *err) || (unsigned)len > 128)
+			goto out_free;
+	}
+	*mask = len; /* OK we have a valid mask in <len> */
+
+	if (!inet_pton(AF_INET6, s, addr))
+		goto out_free;
+
+	ret_val = 1;
+ out_free:
+	free(s);
+	return ret_val;
+}
+
+
+/*
+ * Parse IPv4 address found in url.
+ */
+int url2ipv4(const char *addr, struct in_addr *dst)
+{
+	int saw_digit, octets, ch;
+	u_char tmp[4], *tp;
+	const char *cp = addr;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+
+	while (*addr) {
+		unsigned char digit = (ch = *addr++) - '0';
+		if (digit > 9 && ch != '.')
+			break;
+		if (digit <= 9) {
+			u_int new = *tp * 10 + digit;
+			if (new > 255)
+				return 0;
+			*tp = new;
+			if (!saw_digit) {
+				if (++octets > 4)
+					return 0;
+				saw_digit = 1;
+			}
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return 0;
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return 0;
+	}
+
+	if (octets < 4)
+		return 0;
+
+	memcpy(&dst->s_addr, tmp, 4);
+	return addr-cp-1;
+}
+
+/*
+ * Resolve destination server from URL. Convert <str> to a sockaddr_storage.
+ * <out> contain the code of the detected scheme, the start and length of
+ * the hostname. Actually only http and https are supported. <out> can be NULL.
+ * This function returns the consumed length. It is useful if you parse complete
+ * url like http://host:port/path, because the consumed length corresponds to
+ * the first character of the path. If the conversion fails, it returns -1.
+ *
+ * This function tries to resolve the DNS name if haproxy is in starting mode.
+ * So, this function may be used during the configuration parsing.
+ */
+int url2sa(const char *url, int ulen, struct sockaddr_storage *addr, struct split_url *out)
+{
+	const char *curr = url, *cp = url;
+	const char *end;
+	int ret, url_code = 0;
+	unsigned long long int http_code = 0;
+	int default_port;
+	struct hostent *he;
+	char *p;
+
+	/* Firstly, try to find :// pattern */
+	while (curr < url+ulen && url_code != 0x3a2f2f) {
+		url_code = ((url_code & 0xffff) << 8);
+		url_code += (unsigned char)*curr++;
+	}
+
+	/* Secondly, if :// pattern is found, verify parsed stuff
+	 * before pattern is matching our http pattern.
+	 * If so parse ip address and port in uri.
+	 * 
+	 * WARNING: Current code doesn't support dynamic async dns resolver.
+	 */
+	if (url_code != 0x3a2f2f)
+		return -1;
+
+	/* Copy scheme, and utrn to lower case. */
+	while (cp < curr - 3)
+		http_code = (http_code << 8) + *cp++;
+	http_code |= 0x2020202020202020ULL;			/* Turn everything to lower case */
+		
+	/* HTTP or HTTPS url matching */
+	if (http_code == 0x2020202068747470ULL) {
+		default_port = 80;
+		if (out)
+			out->scheme = SCH_HTTP;
+	}
+	else if (http_code == 0x2020206874747073ULL) {
+		default_port = 443;
+		if (out)
+			out->scheme = SCH_HTTPS;
+	}
+	else
+		return -1;
+
+	/* If the next char is '[', the host address is IPv6. */
+	if (*curr == '[') {
+		curr++;
+
+		/* Check trash size */
+		if (trash.size < ulen)
+			return -1;
+
+		/* Look for ']' and copy the address in a trash buffer. */
+		p = trash.area;
+		for (end = curr;
+		     end < url + ulen && *end != ']';
+		     end++, p++)
+			*p = *end;
+		if (*end != ']')
+			return -1;
+		*p = '\0';
+
+		/* Update out. */
+		if (out) {
+			out->host = curr;
+			out->host_len = end - curr;
+		}
+
+		/* Try IPv6 decoding. */
+		if (!inet_pton(AF_INET6, trash.area, &((struct sockaddr_in6 *)addr)->sin6_addr))
+			return -1;
+		end++;
+
+		/* Decode port. */
+		if (*end == ':') {
+			end++;
+			default_port = read_uint(&end, url + ulen);
+		}
+		((struct sockaddr_in6 *)addr)->sin6_port = htons(default_port);
+		((struct sockaddr_in6 *)addr)->sin6_family = AF_INET6;
+		return end - url;
+	}
+	else {
+		/* We are looking for IP address. If you want to parse and
+		 * resolve hostname found in url, you can use str2sa_range(), but
+		 * be warned this can slow down global daemon performances
+		 * while handling lagging dns responses.
+		 */
+		ret = url2ipv4(curr, &((struct sockaddr_in *)addr)->sin_addr);
+		if (ret) {
+			/* Update out. */
+			if (out) {
+				out->host = curr;
+				out->host_len = ret;
+			}
+
+			curr += ret;
+
+			/* Decode port. */
+			if (*curr == ':') {
+				curr++;
+				default_port = read_uint(&curr, url + ulen);
+			}
+			((struct sockaddr_in *)addr)->sin_port = htons(default_port);
+
+			/* Set family. */
+			((struct sockaddr_in *)addr)->sin_family = AF_INET;
+			return curr - url;
+		}
+		else if (global.mode & MODE_STARTING) {
+			/* The IPv4 and IPv6 decoding fails, maybe the url contain name. Try to execute
+			 * synchronous DNS request only if HAProxy is in the start state.
+			 */
+
+			/* look for : or / or end */
+			for (end = curr;
+			     end < url + ulen && *end != '/' && *end != ':';
+			     end++);
+			memcpy(trash.area, curr, end - curr);
+			trash.area[end - curr] = '\0';
+
+			/* try to resolve an IPv4/IPv6 hostname */
+			he = gethostbyname(trash.area);
+			if (!he)
+				return -1;
+
+			/* Update out. */
+			if (out) {
+				out->host = curr;
+				out->host_len = end - curr;
+			}
+
+			/* Decode port. */
+			if (*end == ':') {
+				end++;
+				default_port = read_uint(&end, url + ulen);
+			}
+
+			/* Copy IP address, set port and family. */
+			switch (he->h_addrtype) {
+			case AF_INET:
+				((struct sockaddr_in *)addr)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
+				((struct sockaddr_in *)addr)->sin_port = htons(default_port);
+				((struct sockaddr_in *)addr)->sin_family = AF_INET;
+				return end - url;
+
+			case AF_INET6:
+				((struct sockaddr_in6 *)addr)->sin6_addr = *(struct in6_addr *) *(he->h_addr_list);
+				((struct sockaddr_in6 *)addr)->sin6_port = htons(default_port);
+				((struct sockaddr_in6 *)addr)->sin6_family = AF_INET6;
+				return end - url;
+			}
+		}
+	}
+	return -1;
+}
+
+/* Tries to convert a sockaddr_storage address to text form. Upon success, the
+ * address family is returned so that it's easy for the caller to adapt to the
+ * output format. Zero is returned if the address family is not supported. -1
+ * is returned upon error, with errno set. AF_INET, AF_INET6 and AF_UNIX are
+ * supported.
+ */
+int addr_to_str(const struct sockaddr_storage *addr, char *str, int size)
+{
+
+	const void *ptr;
+
+	if (size < 5)
+		return 0;
+	*str = '\0';
+
+	switch (addr->ss_family) {
+	case AF_INET:
+		ptr = &((struct sockaddr_in *)addr)->sin_addr;
+		break;
+	case AF_INET6:
+		ptr = &((struct sockaddr_in6 *)addr)->sin6_addr;
+		break;
+	case AF_UNIX:
+		memcpy(str, "unix", 5);
+		return addr->ss_family;
+	default:
+		return 0;
+	}
+
+	if (inet_ntop(addr->ss_family, ptr, str, size))
+		return addr->ss_family;
+
+	/* failed */
+	return -1;
+}
+
+/* Tries to convert a sockaddr_storage port to text form. Upon success, the
+ * address family is returned so that it's easy for the caller to adapt to the
+ * output format. Zero is returned if the address family is not supported. -1
+ * is returned upon error, with errno set. AF_INET, AF_INET6 and AF_UNIX are
+ * supported.
+ */
+int port_to_str(const struct sockaddr_storage *addr, char *str, int size)
+{
+
+	uint16_t port;
+
+
+	if (size < 6)
+		return 0;
+	*str = '\0';
+
+	switch (addr->ss_family) {
+	case AF_INET:
+		port = ((struct sockaddr_in *)addr)->sin_port;
+		break;
+	case AF_INET6:
+		port = ((struct sockaddr_in6 *)addr)->sin6_port;
+		break;
+	case AF_UNIX:
+		memcpy(str, "unix", 5);
+		return addr->ss_family;
+	default:
+		return 0;
+	}
+
+	snprintf(str, size, "%u", ntohs(port));
+	return addr->ss_family;
+}
+
+/* check if the given address is local to the system or not. It will return
+ * -1 when it's not possible to know, 0 when the address is not local, 1 when
+ * it is. We don't want to iterate over all interfaces for this (and it is not
+ * portable). So instead we try to bind in UDP to this address on a free non
+ * privileged port and to connect to the same address, port 0 (connect doesn't
+ * care). If it succeeds, we own the address. Note that non-inet addresses are
+ * considered local since they're most likely AF_UNIX.
+ */
+int addr_is_local(const struct netns_entry *ns,
+                  const struct sockaddr_storage *orig)
+{
+	struct sockaddr_storage addr;
+	int result;
+	int fd;
+
+	if (!is_inet_addr(orig))
+		return 1;
+
+	memcpy(&addr, orig, sizeof(addr));
+	set_host_port(&addr, 0);
+
+	fd = my_socketat(ns, addr.ss_family, SOCK_DGRAM, IPPROTO_UDP);
+	if (fd < 0)
+		return -1;
+
+	result = -1;
+	if (bind(fd, (struct sockaddr *)&addr, get_addr_len(&addr)) == 0) {
+		if (connect(fd, (struct sockaddr *)&addr, get_addr_len(&addr)) == -1)
+			result = 0; // fail, non-local address
+		else
+			result = 1; // success, local address
+	}
+	else {
+		if (errno == EADDRNOTAVAIL)
+			result = 0; // definitely not local :-)
+	}
+	close(fd);
+
+	return result;
+}
+
+/* will try to encode the string <string> replacing all characters tagged in
+ * <map> with the hexadecimal representation of their ASCII-code (2 digits)
+ * prefixed by <escape>, and will store the result between <start> (included)
+ * and <stop> (excluded), and will always terminate the string with a '\0'
+ * before <stop>. The position of the '\0' is returned if the conversion
+ * completes. If bytes are missing between <start> and <stop>, then the
+ * conversion will be incomplete and truncated. If <stop> <= <start>, the '\0'
+ * cannot even be stored so we return <start> without writing the 0.
+ * The input string must also be zero-terminated.
+ */
+const char hextab[16] = "0123456789ABCDEF";
+char *encode_string(char *start, char *stop,
+		    const char escape, const long *map,
+		    const char *string)
+{
+	if (start < stop) {
+		stop--; /* reserve one byte for the final '\0' */
+		while (start < stop && *string != '\0') {
+			if (!ha_bit_test((unsigned char)(*string), map))
+				*start++ = *string;
+			else {
+				if (start + 3 >= stop)
+					break;
+				*start++ = escape;
+				*start++ = hextab[(*string >> 4) & 15];
+				*start++ = hextab[*string & 15];
+			}
+			string++;
+		}
+		*start = '\0';
+	}
+	return start;
+}
+
+/*
+ * Same behavior as encode_string() above, except that it encodes chunk
+ * <chunk> instead of a string.
+ */
+char *encode_chunk(char *start, char *stop,
+		    const char escape, const long *map,
+		    const struct buffer *chunk)
+{
+	char *str = chunk->area;
+	char *end = chunk->area + chunk->data;
+
+	if (start < stop) {
+		stop--; /* reserve one byte for the final '\0' */
+		while (start < stop && str < end) {
+			if (!ha_bit_test((unsigned char)(*str), map))
+				*start++ = *str;
+			else {
+				if (start + 3 >= stop)
+					break;
+				*start++ = escape;
+				*start++ = hextab[(*str >> 4) & 15];
+				*start++ = hextab[*str & 15];
+			}
+			str++;
+		}
+		*start = '\0';
+	}
+	return start;
+}
+
+/*
+ * Tries to prefix characters tagged in the <map> with the <escape>
+ * character. The input <string> must be zero-terminated. The result will
+ * be stored between <start> (included) and <stop> (excluded). This
+ * function will always try to terminate the resulting string with a '\0'
+ * before <stop>, and will return its position if the conversion
+ * completes.
+ */
+char *escape_string(char *start, char *stop,
+		    const char escape, const long *map,
+		    const char *string)
+{
+	if (start < stop) {
+		stop--; /* reserve one byte for the final '\0' */
+		while (start < stop && *string != '\0') {
+			if (!ha_bit_test((unsigned char)(*string), map))
+				*start++ = *string;
+			else {
+				if (start + 2 >= stop)
+					break;
+				*start++ = escape;
+				*start++ = *string;
+			}
+			string++;
+		}
+		*start = '\0';
+	}
+	return start;
+}
+
+/*
+ * Tries to prefix characters tagged in the <map> with the <escape>
+ * character. <chunk> contains the input to be escaped. The result will be
+ * stored between <start> (included) and <stop> (excluded). The function
+ * will always try to terminate the resulting string with a '\0' before
+ * <stop>, and will return its position if the conversion completes.
+ */
+char *escape_chunk(char *start, char *stop,
+		   const char escape, const long *map,
+		   const struct buffer *chunk)
+{
+	char *str = chunk->area;
+	char *end = chunk->area + chunk->data;
+
+	if (start < stop) {
+		stop--; /* reserve one byte for the final '\0' */
+		while (start < stop && str < end) {
+			if (!ha_bit_test((unsigned char)(*str), map))
+				*start++ = *str;
+			else {
+				if (start + 2 >= stop)
+					break;
+				*start++ = escape;
+				*start++ = *str;
+			}
+			str++;
+		}
+		*start = '\0';
+	}
+	return start;
+}
+
+/* Check a string for using it in a CSV output format. If the string contains
+ * one of the following four char <">, <,>, CR or LF, the string is
+ * encapsulated between <"> and the <"> are escaped by a <""> sequence.
+ * <str> is the input string to be escaped. The function assumes that
+ * the input string is null-terminated.
+ *
+ * If <quote> is 0, the result is returned escaped but without double quote.
+ * It is useful if the escaped string is used between double quotes in the
+ * format.
+ *
+ *    printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash));
+ *
+ * If <quote> is 1, the converter puts the quotes only if any reserved character
+ * is present. If <quote> is 2, the converter always puts the quotes.
+ *
+ * <output> is a struct buffer used for storing the output string.
+ *
+ * The function returns the converted string on its output. If an error
+ * occurs, the function returns an empty string. This type of output is useful
+ * for using the function directly as printf() argument.
+ *
+ * If the output buffer is too short to contain the input string, the result
+ * is truncated.
+ *
+ * This function appends the encoding to the existing output chunk, and it
+ * guarantees that it starts immediately at the first available character of
+ * the chunk. Please use csv_enc() instead if you want to replace the output
+ * chunk.
+ */
+const char *csv_enc_append(const char *str, int quote, struct buffer *output)
+{
+	char *end = output->area + output->size;
+	char *out = output->area + output->data;
+	char *ptr = out;
+
+	if (quote == 1) {
+		/* automatic quoting: first verify if we'll have to quote the string */
+		if (!strpbrk(str, "\n\r,\""))
+			quote = 0;
+	}
+
+	if (quote)
+		*ptr++ = '"';
+
+	while (*str && ptr < end - 2) { /* -2 for reserving space for <"> and \0. */
+		*ptr = *str;
+		if (*str == '"') {
+			ptr++;
+			if (ptr >= end - 2) {
+				ptr--;
+				break;
+			}
+			*ptr = '"';
+		}
+		ptr++;
+		str++;
+	}
+
+	if (quote)
+		*ptr++ = '"';
+
+	*ptr = '\0';
+	output->data = ptr - output->area;
+	return out;
+}
+
+/* Decode an URL-encoded string in-place. The resulting string might
+ * be shorter. If some forbidden characters are found, the conversion is
+ * aborted, the string is truncated before the issue and a negative value is
+ * returned, otherwise the operation returns the length of the decoded string.
+ * If the 'in_form' argument is non-nul the string is assumed to be part of
+ * an "application/x-www-form-urlencoded" encoded string, and the '+' will be
+ * turned to a space. If it's zero, this will only be done after a question
+ * mark ('?').
+ */
+int url_decode(char *string, int in_form)
+{
+	char *in, *out;
+	int ret = -1;
+
+	in = string;
+	out = string;
+	while (*in) {
+		switch (*in) {
+		case '+' :
+			*out++ = in_form ? ' ' : *in;
+			break;
+		case '%' :
+			if (!ishex(in[1]) || !ishex(in[2]))
+				goto end;
+			*out++ = (hex2i(in[1]) << 4) + hex2i(in[2]);
+			in += 2;
+			break;
+		case '?':
+			in_form = 1;
+			/* fall through */
+		default:
+			*out++ = *in;
+			break;
+		}
+		in++;
+	}
+	ret = out - string; /* success */
+ end:
+	*out = 0;
+	return ret;
+}
+
+unsigned int str2ui(const char *s)
+{
+	return __str2ui(s);
+}
+
+unsigned int str2uic(const char *s)
+{
+	return __str2uic(s);
+}
+
+unsigned int strl2ui(const char *s, int len)
+{
+	return __strl2ui(s, len);
+}
+
+unsigned int strl2uic(const char *s, int len)
+{
+	return __strl2uic(s, len);
+}
+
+unsigned int read_uint(const char **s, const char *end)
+{
+	return __read_uint(s, end);
+}
+
+/* This function reads an unsigned integer from the string pointed to by <s> and
+ * returns it. The <s> pointer is adjusted to point to the first unread char. The
+ * function automatically stops at <end>. If the number overflows, the 2^64-1
+ * value is returned.
+ */
+unsigned long long int read_uint64(const char **s, const char *end)
+{
+	const char *ptr = *s;
+	unsigned long long int i = 0, tmp;
+	unsigned int j;
+
+	while (ptr < end) {
+
+		/* read next char */
+		j = *ptr - '0';
+		if (j > 9)
+			goto read_uint64_end;
+
+		/* add char to the number and check overflow. */
+		tmp = i * 10;
+		if (tmp / 10 != i) {
+			i = ULLONG_MAX;
+			goto read_uint64_eat;
+		}
+		if (ULLONG_MAX - tmp < j) {
+			i = ULLONG_MAX;
+			goto read_uint64_eat;
+		}
+		i = tmp + j;
+		ptr++;
+	}
+read_uint64_eat:
+	/* eat each numeric char */
+	while (ptr < end) {
+		if ((unsigned int)(*ptr - '0') > 9)
+			break;
+		ptr++;
+	}
+read_uint64_end:
+	*s = ptr;
+	return i;
+}
+
+/* This function reads an integer from the string pointed to by <s> and returns
+ * it. The <s> pointer is adjusted to point to the first unread char. The function
+ * automatically stops at <end>. Il the number is bigger than 2^63-2, the 2^63-1
+ * value is returned. If the number is lowest than -2^63-1, the -2^63 value is
+ * returned.
+ */
+long long int read_int64(const char **s, const char *end)
+{
+	unsigned long long int i = 0;
+	int neg = 0;
+
+	/* Look for minus char. */
+	if (**s == '-') {
+		neg = 1;
+		(*s)++;
+	}
+	else if (**s == '+')
+		(*s)++;
+
+	/* convert as positive number. */
+	i = read_uint64(s, end);
+
+	if (neg) {
+		if (i > 0x8000000000000000ULL)
+			return LLONG_MIN;
+		return -i;
+	}
+	if (i > 0x7fffffffffffffffULL)
+		return LLONG_MAX;
+	return i;
+}
+
+/* This one is 7 times faster than strtol() on athlon with checks.
+ * It returns the value of the number composed of all valid digits read,
+ * and can process negative numbers too.
+ */
+int strl2ic(const char *s, int len)
+{
+	int i = 0;
+	int j, k;
+
+	if (len > 0) {
+		if (*s != '-') {
+			/* positive number */
+			while (len-- > 0) {
+				j = (*s++) - '0';
+				k = i * 10;
+				if (j > 9)
+					break;
+				i = k + j;
+			}
+		} else {
+			/* negative number */
+			s++;
+			while (--len > 0) {
+				j = (*s++) - '0';
+				k = i * 10;
+				if (j > 9)
+					break;
+				i = k - j;
+			}
+		}
+	}
+	return i;
+}
+
+
+/* This function reads exactly <len> chars from <s> and converts them to a
+ * signed integer which it stores into <ret>. It accurately detects any error
+ * (truncated string, invalid chars, overflows). It is meant to be used in
+ * applications designed for hostile environments. It returns zero when the
+ * number has successfully been converted, non-zero otherwise. When an error
+ * is returned, the <ret> value is left untouched. It is yet 5 to 40 times
+ * faster than strtol().
+ */
+int strl2irc(const char *s, int len, int *ret)
+{
+	int i = 0;
+	int j;
+
+	if (!len)
+		return 1;
+
+	if (*s != '-') {
+		/* positive number */
+		while (len-- > 0) {
+			j = (*s++) - '0';
+			if (j > 9)            return 1; /* invalid char */
+			if (i > INT_MAX / 10) return 1; /* check for multiply overflow */
+			i = i * 10;
+			if (i + j < i)        return 1; /* check for addition overflow */
+			i = i + j;
+		}
+	} else {
+		/* negative number */
+		s++;
+		while (--len > 0) {
+			j = (*s++) - '0';
+			if (j > 9)             return 1; /* invalid char */
+			if (i < INT_MIN / 10)  return 1; /* check for multiply overflow */
+			i = i * 10;
+			if (i - j > i)         return 1; /* check for subtract overflow */
+			i = i - j;
+		}
+	}
+	*ret = i;
+	return 0;
+}
+
+
+/* This function reads exactly <len> chars from <s> and converts them to a
+ * signed integer which it stores into <ret>. It accurately detects any error
+ * (truncated string, invalid chars, overflows). It is meant to be used in
+ * applications designed for hostile environments. It returns zero when the
+ * number has successfully been converted, non-zero otherwise. When an error
+ * is returned, the <ret> value is left untouched. It is about 3 times slower
+ * than str2irc().
+ */
+
+int strl2llrc(const char *s, int len, long long *ret)
+{
+	long long i = 0;
+	int j;
+
+	if (!len)
+		return 1;
+
+	if (*s != '-') {
+		/* positive number */
+		while (len-- > 0) {
+			j = (*s++) - '0';
+			if (j > 9)              return 1; /* invalid char */
+			if (i > LLONG_MAX / 10LL) return 1; /* check for multiply overflow */
+			i = i * 10LL;
+			if (i + j < i)          return 1; /* check for addition overflow */
+			i = i + j;
+		}
+	} else {
+		/* negative number */
+		s++;
+		while (--len > 0) {
+			j = (*s++) - '0';
+			if (j > 9)              return 1; /* invalid char */
+			if (i < LLONG_MIN / 10LL) return 1; /* check for multiply overflow */
+			i = i * 10LL;
+			if (i - j > i)          return 1; /* check for subtract overflow */
+			i = i - j;
+		}
+	}
+	*ret = i;
+	return 0;
+}
+
+/* This function is used with pat_parse_dotted_ver(). It converts a string
+ * composed by two number separated by a dot. Each part must contain in 16 bits
+ * because internally they will be represented as a 32-bit quantity stored in
+ * a 64-bit integer. It returns zero when the number has successfully been
+ * converted, non-zero otherwise. When an error is returned, the <ret> value
+ * is left untouched.
+ *
+ *    "1.3"         -> 0x0000000000010003
+ *    "65535.65535" -> 0x00000000ffffffff
+ */
+int strl2llrc_dotted(const char *text, int len, long long *ret)
+{
+	const char *end = &text[len];
+	const char *p;
+	long long major, minor;
+
+	/* Look for dot. */
+	for (p = text; p < end; p++)
+		if (*p == '.')
+			break;
+
+	/* Convert major. */
+	if (strl2llrc(text, p - text, &major) != 0)
+		return 1;
+
+	/* Check major. */
+	if (major >= 65536)
+		return 1;
+
+	/* Convert minor. */
+	minor = 0;
+	if (p < end)
+		if (strl2llrc(p + 1, end - (p + 1), &minor) != 0)
+			return 1;
+
+	/* Check minor. */
+	if (minor >= 65536)
+		return 1;
+
+	/* Compose value. */
+	*ret = (major << 16) | (minor & 0xffff);
+	return 0;
+}
+
+/* This function parses a time value optionally followed by a unit suffix among
+ * "d", "h", "m", "s", "ms" or "us". It converts the value into the unit
+ * expected by the caller. The computation does its best to avoid overflows.
+ * The value is returned in <ret> if everything is fine, and a NULL is returned
+ * by the function. In case of error, a pointer to the error is returned and
+ * <ret> is left untouched. Values are automatically rounded up when needed.
+ * Values resulting in values larger than or equal to 2^31 after conversion are
+ * reported as an overflow as value PARSE_TIME_OVER. Non-null values resulting
+ * in an underflow are reported as an underflow as value PARSE_TIME_UNDER.
+ */
+const char *parse_time_err(const char *text, unsigned *ret, unsigned unit_flags)
+{
+	unsigned long long imult, idiv;
+	unsigned long long omult, odiv;
+	unsigned long long value, result;
+
+	omult = odiv = 1;
+
+	switch (unit_flags & TIME_UNIT_MASK) {
+	case TIME_UNIT_US:   omult = 1000000; break;
+	case TIME_UNIT_MS:   omult = 1000; break;
+	case TIME_UNIT_S:    break;
+	case TIME_UNIT_MIN:  odiv = 60; break;
+	case TIME_UNIT_HOUR: odiv = 3600; break;
+	case TIME_UNIT_DAY:  odiv = 86400; break;
+	default: break;
+	}
+
+	value = 0;
+
+	while (1) {
+		unsigned int j;
+
+		j = *text - '0';
+		if (j > 9)
+			break;
+		text++;
+		value *= 10;
+		value += j;
+	}
+
+	imult = idiv = 1;
+	switch (*text) {
+	case '\0': /* no unit = default unit */
+		imult = omult = idiv = odiv = 1;
+		break;
+	case 's': /* second = unscaled unit */
+		break;
+	case 'u': /* microsecond : "us" */
+		if (text[1] == 's') {
+			idiv = 1000000;
+			text++;
+		}
+		break;
+	case 'm': /* millisecond : "ms" or minute: "m" */
+		if (text[1] == 's') {
+			idiv = 1000;
+			text++;
+		} else
+			imult = 60;
+		break;
+	case 'h': /* hour : "h" */
+		imult = 3600;
+		break;
+	case 'd': /* day : "d" */
+		imult = 86400;
+		break;
+	default:
+		return text;
+		break;
+	}
+
+	if (omult % idiv == 0) { omult /= idiv; idiv = 1; }
+	if (idiv % omult == 0) { idiv /= omult; omult = 1; }
+	if (imult % odiv == 0) { imult /= odiv; odiv = 1; }
+	if (odiv % imult == 0) { odiv /= imult; imult = 1; }
+
+	result = (value * (imult * omult) + (idiv * odiv - 1)) / (idiv * odiv);
+	if (result >= 0x80000000)
+		return PARSE_TIME_OVER;
+	if (!result && value)
+		return PARSE_TIME_UNDER;
+	*ret = result;
+	return NULL;
+}
+
+/* this function converts the string starting at <text> to an unsigned int
+ * stored in <ret>. If an error is detected, the pointer to the unexpected
+ * character is returned. If the conversion is successful, NULL is returned.
+ */
+const char *parse_size_err(const char *text, unsigned *ret) {
+	unsigned value = 0;
+
+	while (1) {
+		unsigned int j;
+
+		j = *text - '0';
+		if (j > 9)
+			break;
+		if (value > ~0U / 10)
+			return text;
+		value *= 10;
+		if (value > (value + j))
+			return text;
+		value += j;
+		text++;
+	}
+
+	switch (*text) {
+	case '\0':
+		break;
+	case 'K':
+	case 'k':
+		if (value > ~0U >> 10)
+			return text;
+		value = value << 10;
+		break;
+	case 'M':
+	case 'm':
+		if (value > ~0U >> 20)
+			return text;
+		value = value << 20;
+		break;
+	case 'G':
+	case 'g':
+		if (value > ~0U >> 30)
+			return text;
+		value = value << 30;
+		break;
+	default:
+		return text;
+	}
+
+	if (*text != '\0' && *++text != '\0')
+		return text;
+
+	*ret = value;
+	return NULL;
+}
+
+/*
+ * Parse binary string written in hexadecimal (source) and store the decoded
+ * result into binstr and set binstrlen to the length of binstr. Memory for
+ * binstr is allocated by the function. In case of error, returns 0 with an
+ * error message in err. In success case, it returns the consumed length.
+ */
+int parse_binary(const char *source, char **binstr, int *binstrlen, char **err)
+{
+	int len;
+	const char *p = source;
+	int i,j;
+	int alloc;
+
+	len = strlen(source);
+	if (len % 2) {
+		memprintf(err, "an even number of hex digit is expected");
+		return 0;
+	}
+
+	len = len >> 1;
+
+	if (!*binstr) {
+		*binstr = calloc(len, sizeof(char));
+		if (!*binstr) {
+			memprintf(err, "out of memory while loading string pattern");
+			return 0;
+		}
+		alloc = 1;
+	}
+	else {
+		if (*binstrlen < len) {
+			memprintf(err, "no space available in the buffer. expect %d, provides %d",
+			          len, *binstrlen);
+			return 0;
+		}
+		alloc = 0;
+	}
+	*binstrlen = len;
+
+	i = j = 0;
+	while (j < len) {
+		if (!ishex(p[i++]))
+			goto bad_input;
+		if (!ishex(p[i++]))
+			goto bad_input;
+		(*binstr)[j++] =  (hex2i(p[i-2]) << 4) + hex2i(p[i-1]);
+	}
+	return len << 1;
+
+bad_input:
+	memprintf(err, "an hex digit is expected (found '%c')", p[i-1]);
+	if (alloc) {
+		free(*binstr);
+		*binstr = NULL;
+	}
+	return 0;
+}
+
+/* copies at most <n> characters from <src> and always terminates with '\0' */
+char *my_strndup(const char *src, int n)
+{
+	int len = 0;
+	char *ret;
+
+	while (len < n && src[len])
+		len++;
+
+	ret = malloc(len + 1);
+	if (!ret)
+		return ret;
+	memcpy(ret, src, len);
+	ret[len] = '\0';
+	return ret;
+}
+
+/*
+ * search needle in haystack
+ * returns the pointer if found, returns NULL otherwise
+ */
+const void *my_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
+{
+	const void *c = NULL;
+	unsigned char f;
+
+	if ((haystack == NULL) || (needle == NULL) || (haystacklen < needlelen))
+		return NULL;
+
+	f = *(char *)needle;
+	c = haystack;
+	while ((c = memchr(c, f, haystacklen - (c - haystack))) != NULL) {
+		if ((haystacklen - (c - haystack)) < needlelen)
+			return NULL;
+
+		if (memcmp(c, needle, needlelen) == 0)
+			return c;
+		++c;
+	}
+	return NULL;
+}
+
+/* get length of the initial segment consisting entirely of bytes in <accept> */
+size_t my_memspn(const void *str, size_t len, const void *accept, size_t acceptlen)
+{
+	size_t ret = 0;
+
+	while (ret < len && memchr(accept, *((int *)str), acceptlen)) {
+		str++;
+		ret++;
+	}
+	return ret;
+}
+
+/* get length of the initial segment consisting entirely of bytes not in <rejcet> */
+size_t my_memcspn(const void *str, size_t len, const void *reject, size_t rejectlen)
+{
+	size_t ret = 0;
+
+	while (ret < len) {
+		if(memchr(reject, *((int *)str), rejectlen))
+			return ret;
+		str++;
+		ret++;
+	}
+	return ret;
+}
+
+/* This function returns the first unused key greater than or equal to <key> in
+ * ID tree <root>. Zero is returned if no place is found.
+ */
+unsigned int get_next_id(struct eb_root *root, unsigned int key)
+{
+	struct eb32_node *used;
+
+	do {
+		used = eb32_lookup_ge(root, key);
+		if (!used || used->key > key)
+			return key; /* key is available */
+		key++;
+	} while (key);
+	return key;
+}
+
+/* dump the full tree to <file> in DOT format for debugging purposes. Will
+ * optionally highlight node <subj> if found, depending on operation <op> :
+ *    0 : nothing
+ *   >0 : insertion, node/leaf are surrounded in red
+ *   <0 : removal, node/leaf are dashed with no background
+ * Will optionally add "desc" as a label on the graph if set and non-null.
+ */
+void eb32sc_to_file(FILE *file, struct eb_root *root, const struct eb32sc_node *subj, int op, const char *desc)
+{
+	struct eb32sc_node *node;
+	unsigned long scope = -1;
+
+	fprintf(file, "digraph ebtree {\n");
+
+	if (desc && *desc) {
+		fprintf(file,
+			"  fontname=\"fixed\";\n"
+			"  fontsize=8;\n"
+			"  label=\"%s\";\n", desc);
+	}
+
+	fprintf(file,
+		"  node [fontname=\"fixed\" fontsize=8 shape=\"box\" style=\"filled\" color=\"black\" fillcolor=\"white\"];\n"
+		"  edge [fontname=\"fixed\" fontsize=8 style=\"solid\" color=\"magenta\" dir=\"forward\"];\n"
+		"  \"%lx_n\" [label=\"root\\n%lx\"]\n", (long)eb_root_to_node(root), (long)root
+		);
+
+	fprintf(file, "  \"%lx_n\" -> \"%lx_%c\" [taillabel=\"L\"];\n",
+		(long)eb_root_to_node(root),
+		(long)eb_root_to_node(eb_clrtag(root->b[0])),
+		eb_gettag(root->b[0]) == EB_LEAF ? 'l' : 'n');
+
+	node = eb32sc_first(root, scope);
+	while (node) {
+		if (node->node.node_p) {
+			/* node part is used */
+			fprintf(file, "  \"%lx_n\" [label=\"%lx\\nkey=%u\\nscope=%lx\\nbit=%d\" fillcolor=\"lightskyblue1\" %s];\n",
+				(long)node, (long)node, node->key, node->node_s, node->node.bit,
+				(node == subj) ? (op < 0 ? "color=\"red\" style=\"dashed\"" : op > 0 ? "color=\"red\"" : "") : "");
+
+			fprintf(file, "  \"%lx_n\" -> \"%lx_n\" [taillabel=\"%c\"];\n",
+				(long)node,
+				(long)eb_root_to_node(eb_clrtag(node->node.node_p)),
+				eb_gettag(node->node.node_p) ? 'R' : 'L');
+
+			fprintf(file, "  \"%lx_n\" -> \"%lx_%c\" [taillabel=\"L\"];\n",
+				(long)node,
+				(long)eb_root_to_node(eb_clrtag(node->node.branches.b[0])),
+				eb_gettag(node->node.branches.b[0]) == EB_LEAF ? 'l' : 'n');
+
+			fprintf(file, "  \"%lx_n\" -> \"%lx_%c\" [taillabel=\"R\"];\n",
+				(long)node,
+				(long)eb_root_to_node(eb_clrtag(node->node.branches.b[1])),
+				eb_gettag(node->node.branches.b[1]) == EB_LEAF ? 'l' : 'n');
+		}
+
+		fprintf(file, "  \"%lx_l\" [label=\"%lx\\nkey=%u\\nscope=%lx\\npfx=%u\" fillcolor=\"yellow\" %s];\n",
+			(long)node, (long)node, node->key, node->leaf_s, node->node.pfx,
+			(node == subj) ? (op < 0 ? "color=\"red\" style=\"dashed\"" : op > 0 ? "color=\"red\"" : "") : "");
+
+		fprintf(file, "  \"%lx_l\" -> \"%lx_n\" [taillabel=\"%c\"];\n",
+			(long)node,
+			(long)eb_root_to_node(eb_clrtag(node->node.leaf_p)),
+			eb_gettag(node->node.leaf_p) ? 'R' : 'L');
+		node = eb32sc_next(node, scope);
+	}
+	fprintf(file, "}\n");
+}
+
+/* This function compares a sample word possibly followed by blanks to another
+ * clean word. The compare is case-insensitive. 1 is returned if both are equal,
+ * otherwise zero. This intends to be used when checking HTTP headers for some
+ * values. Note that it validates a word followed only by blanks but does not
+ * validate a word followed by blanks then other chars.
+ */
+int word_match(const char *sample, int slen, const char *word, int wlen)
+{
+	if (slen < wlen)
+		return 0;
+
+	while (wlen) {
+		char c = *sample ^ *word;
+		if (c && c != ('A' ^ 'a'))
+			return 0;
+		sample++;
+		word++;
+		slen--;
+		wlen--;
+	}
+
+	while (slen) {
+		if (*sample != ' ' && *sample != '\t')
+			return 0;
+		sample++;
+		slen--;
+	}
+	return 1;
+}
+
+/* Converts any text-formatted IPv4 address to a host-order IPv4 address. It
+ * is particularly fast because it avoids expensive operations such as
+ * multiplies, which are optimized away at the end. It requires a properly
+ * formatted address though (3 points).
+ */
+unsigned int inetaddr_host(const char *text)
+{
+	const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0';
+	register unsigned int dig100, dig10, dig1;
+	int s;
+	const char *p, *d;
+
+	dig1 = dig10 = dig100 = ascii_zero;
+	s = 24;
+
+	p = text;
+	while (1) {
+		if (((unsigned)(*p - '0')) <= 9) {
+			p++;
+			continue;
+		}
+
+		/* here, we have a complete byte between <text> and <p> (exclusive) */
+		if (p == text)
+			goto end;
+
+		d = p - 1;
+		dig1   |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig10  |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig100 |= (unsigned int)(*d << s);
+	end:
+		if (!s || *p != '.')
+			break;
+
+		s -= 8;
+		text = ++p;
+	}
+
+	dig100 -= ascii_zero;
+	dig10  -= ascii_zero;
+	dig1   -= ascii_zero;
+	return ((dig100 * 10) + dig10) * 10 + dig1;
+}
+
+/*
+ * Idem except the first unparsed character has to be passed in <stop>.
+ */
+unsigned int inetaddr_host_lim(const char *text, const char *stop)
+{
+	const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0';
+	register unsigned int dig100, dig10, dig1;
+	int s;
+	const char *p, *d;
+
+	dig1 = dig10 = dig100 = ascii_zero;
+	s = 24;
+
+	p = text;
+	while (1) {
+		if (((unsigned)(*p - '0')) <= 9 && p < stop) {
+			p++;
+			continue;
+		}
+
+		/* here, we have a complete byte between <text> and <p> (exclusive) */
+		if (p == text)
+			goto end;
+
+		d = p - 1;
+		dig1   |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig10  |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig100 |= (unsigned int)(*d << s);
+	end:
+		if (!s || p == stop || *p != '.')
+			break;
+
+		s -= 8;
+		text = ++p;
+	}
+
+	dig100 -= ascii_zero;
+	dig10  -= ascii_zero;
+	dig1   -= ascii_zero;
+	return ((dig100 * 10) + dig10) * 10 + dig1;
+}
+
+/*
+ * Idem except the pointer to first unparsed byte is returned into <ret> which
+ * must not be NULL.
+ */
+unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret)
+{
+	const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0';
+	register unsigned int dig100, dig10, dig1;
+	int s;
+	char *p, *d;
+
+	dig1 = dig10 = dig100 = ascii_zero;
+	s = 24;
+
+	p = text;
+	while (1) {
+		if (((unsigned)(*p - '0')) <= 9 && p < stop) {
+			p++;
+			continue;
+		}
+
+		/* here, we have a complete byte between <text> and <p> (exclusive) */
+		if (p == text)
+			goto end;
+
+		d = p - 1;
+		dig1   |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig10  |= (unsigned int)(*d << s);
+		if (d == text)
+			goto end;
+
+		d--;
+		dig100 |= (unsigned int)(*d << s);
+	end:
+		if (!s || p == stop || *p != '.')
+			break;
+
+		s -= 8;
+		text = ++p;
+	}
+
+	*ret = p;
+	dig100 -= ascii_zero;
+	dig10  -= ascii_zero;
+	dig1   -= ascii_zero;
+	return ((dig100 * 10) + dig10) * 10 + dig1;
+}
+
+/* Convert a fixed-length string to an IP address. Returns 0 in case of error,
+ * or the number of chars read in case of success. Maybe this could be replaced
+ * by one of the functions above. Also, apparently this function does not support
+ * hosts above 255 and requires exactly 4 octets.
+ * The destination is only modified on success.
+ */
+int buf2ip(const char *buf, size_t len, struct in_addr *dst)
+{
+	const char *addr;
+	int saw_digit, octets, ch;
+	u_char tmp[4], *tp;
+	const char *cp = buf;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+
+	for (addr = buf; addr - buf < len; addr++) {
+		unsigned char digit = (ch = *addr) - '0';
+
+		if (digit > 9 && ch != '.')
+			break;
+
+		if (digit <= 9) {
+			u_int new = *tp * 10 + digit;
+
+			if (new > 255)
+				return 0;
+
+			*tp = new;
+
+			if (!saw_digit) {
+				if (++octets > 4)
+					return 0;
+				saw_digit = 1;
+			}
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return 0;
+
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return 0;
+	}
+
+	if (octets < 4)
+		return 0;
+
+	memcpy(&dst->s_addr, tmp, 4);
+	return addr - cp;
+}
+
+/* This function converts the string in <buf> of the len <len> to
+ * struct in6_addr <dst> which must be allocated by the caller.
+ * This function returns 1 in success case, otherwise zero.
+ * The destination is only modified on success.
+ */
+int buf2ip6(const char *buf, size_t len, struct in6_addr *dst)
+{
+	char null_term_ip6[INET6_ADDRSTRLEN + 1];
+	struct in6_addr out;
+
+	if (len > INET6_ADDRSTRLEN)
+		return 0;
+
+	memcpy(null_term_ip6, buf, len);
+	null_term_ip6[len] = '\0';
+
+	if (!inet_pton(AF_INET6, null_term_ip6, &out))
+		return 0;
+
+	*dst = out;
+	return 1;
+}
+
+/* To be used to quote config arg positions. Returns the short string at <ptr>
+ * surrounded by simple quotes if <ptr> is valid and non-empty, or "end of line"
+ * if ptr is NULL or empty. The string is locally allocated.
+ */
+const char *quote_arg(const char *ptr)
+{
+	static THREAD_LOCAL char val[32];
+	int i;
+
+	if (!ptr || !*ptr)
+		return "end of line";
+	val[0] = '\'';
+	for (i = 1; i < sizeof(val) - 2 && *ptr; i++)
+		val[i] = *ptr++;
+	val[i++] = '\'';
+	val[i] = '\0';
+	return val;
+}
+
+/* returns an operator among STD_OP_* for string <str> or < 0 if unknown */
+int get_std_op(const char *str)
+{
+	int ret = -1;
+
+	if (*str == 'e' && str[1] == 'q')
+		ret = STD_OP_EQ;
+	else if (*str == 'n' && str[1] == 'e')
+		ret = STD_OP_NE;
+	else if (*str == 'l') {
+		if (str[1] == 'e') ret = STD_OP_LE;
+		else if (str[1] == 't') ret = STD_OP_LT;
+	}
+	else if (*str == 'g') {
+		if (str[1] == 'e') ret = STD_OP_GE;
+		else if (str[1] == 't') ret = STD_OP_GT;
+	}
+
+	if (ret == -1 || str[2] != '\0')
+		return -1;
+	return ret;
+}
+
+/* hash a 32-bit integer to another 32-bit integer */
+unsigned int full_hash(unsigned int a)
+{
+	return __full_hash(a);
+}
+
+/* Return the bit position in mask <m> of the nth bit set of rank <r>, between
+ * 0 and LONGBITS-1 included, starting from the left. For example ranks 0,1,2,3
+ * for mask 0x55 will be 6, 4, 2 and 0 respectively. This algorithm is based on
+ * a popcount variant and is described here :
+ *   https://graphics.stanford.edu/~seander/bithacks.html
+ */
+unsigned int mask_find_rank_bit(unsigned int r, unsigned long m)
+{
+	unsigned long a, b, c, d;
+	unsigned int s;
+	unsigned int t;
+
+	a =  m - ((m >> 1) & ~0UL/3);
+	b = (a & ~0UL/5) + ((a >> 2) & ~0UL/5);
+	c = (b + (b >> 4)) & ~0UL/0x11;
+	d = (c + (c >> 8)) & ~0UL/0x101;
+
+	r++; // make r be 1..64
+
+	t = 0;
+	s = LONGBITS;
+	if (s > 32) {
+		unsigned long d2 = (d >> 16) >> 16;
+		t = d2 + (d2 >> 16);
+		s -= ((t - r) & 256) >> 3; r -= (t & ((t - r) >> 8));
+	}
+
+	t  = (d >> (s - 16)) & 0xff;
+	s -= ((t - r) & 256) >> 4; r -= (t & ((t - r) >> 8));
+	t  = (c >> (s - 8)) & 0xf;
+	s -= ((t - r) & 256) >> 5; r -= (t & ((t - r) >> 8));
+	t  = (b >> (s - 4)) & 0x7;
+	s -= ((t - r) & 256) >> 6; r -= (t & ((t - r) >> 8));
+	t  = (a >> (s - 2)) & 0x3;
+	s -= ((t - r) & 256) >> 7; r -= (t & ((t - r) >> 8));
+	t  = (m >> (s - 1)) & 0x1;
+	s -= ((t - r) & 256) >> 8;
+
+       return s - 1;
+}
+
+/* Same as mask_find_rank_bit() above but makes use of pre-computed bitmaps
+ * based on <m>, in <a..d>. These ones must be updated whenever <m> changes
+ * using mask_prep_rank_map() below.
+ */
+unsigned int mask_find_rank_bit_fast(unsigned int r, unsigned long m,
+                                     unsigned long a, unsigned long b,
+                                     unsigned long c, unsigned long d)
+{
+	unsigned int s;
+	unsigned int t;
+
+	r++; // make r be 1..64
+
+	t = 0;
+	s = LONGBITS;
+	if (s > 32) {
+		unsigned long d2 = (d >> 16) >> 16;
+		t = d2 + (d2 >> 16);
+		s -= ((t - r) & 256) >> 3; r -= (t & ((t - r) >> 8));
+	}
+
+	t  = (d >> (s - 16)) & 0xff;
+	s -= ((t - r) & 256) >> 4; r -= (t & ((t - r) >> 8));
+	t  = (c >> (s - 8)) & 0xf;
+	s -= ((t - r) & 256) >> 5; r -= (t & ((t - r) >> 8));
+	t  = (b >> (s - 4)) & 0x7;
+	s -= ((t - r) & 256) >> 6; r -= (t & ((t - r) >> 8));
+	t  = (a >> (s - 2)) & 0x3;
+	s -= ((t - r) & 256) >> 7; r -= (t & ((t - r) >> 8));
+	t  = (m >> (s - 1)) & 0x1;
+	s -= ((t - r) & 256) >> 8;
+
+	return s - 1;
+}
+
+/* Prepare the bitmaps used by the fast implementation of the find_rank_bit()
+ * above.
+ */
+void mask_prep_rank_map(unsigned long m,
+                        unsigned long *a, unsigned long *b,
+                        unsigned long *c, unsigned long *d)
+{
+	*a =  m - ((m >> 1) & ~0UL/3);
+	*b = (*a & ~0UL/5) + ((*a >> 2) & ~0UL/5);
+	*c = (*b + (*b >> 4)) & ~0UL/0x11;
+	*d = (*c + (*c >> 8)) & ~0UL/0x101;
+}
+
+/* Return non-zero if IPv4 address is part of the network,
+ * otherwise zero. Note that <addr> may not necessarily be aligned
+ * while the two other ones must.
+ */
+int in_net_ipv4(const void *addr, const struct in_addr *mask, const struct in_addr *net)
+{
+	struct in_addr addr_copy;
+
+	memcpy(&addr_copy, addr, sizeof(addr_copy));
+	return((addr_copy.s_addr & mask->s_addr) == (net->s_addr & mask->s_addr));
+}
+
+/* Return non-zero if IPv6 address is part of the network,
+ * otherwise zero. Note that <addr> may not necessarily be aligned
+ * while the two other ones must.
+ */
+int in_net_ipv6(const void *addr, const struct in6_addr *mask, const struct in6_addr *net)
+{
+	int i;
+	struct in6_addr addr_copy;
+
+	memcpy(&addr_copy, addr, sizeof(addr_copy));
+	for (i = 0; i < sizeof(struct in6_addr) / sizeof(int); i++)
+		if (((((int *)&addr_copy)[i] & ((int *)mask)[i])) !=
+		    (((int *)net)[i] & ((int *)mask)[i]))
+			return 0;
+	return 1;
+}
+
+/* RFC 4291 prefix */
+const char rfc4291_pfx[] = { 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0xFF, 0xFF };
+
+/* Map IPv4 address on IPv6 address, as specified in RFC 3513.
+ * Input and output may overlap.
+ */
+void v4tov6(struct in6_addr *sin6_addr, struct in_addr *sin_addr)
+{
+	struct in_addr tmp_addr;
+
+	tmp_addr.s_addr = sin_addr->s_addr;
+	memcpy(sin6_addr->s6_addr, rfc4291_pfx, sizeof(rfc4291_pfx));
+	memcpy(sin6_addr->s6_addr+12, &tmp_addr.s_addr, 4);
+}
+
+/* Map IPv6 address on IPv4 address, as specified in RFC 3513.
+ * Return true if conversion is possible and false otherwise.
+ */
+int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr)
+{
+	if (memcmp(sin6_addr->s6_addr, rfc4291_pfx, sizeof(rfc4291_pfx)) == 0) {
+		memcpy(&(sin_addr->s_addr), &(sin6_addr->s6_addr[12]),
+			sizeof(struct in_addr));
+		return 1;
+	}
+
+	return 0;
+}
+
+/* compare two struct sockaddr_storage and return:
+ *  0 (true)  if the addr is the same in both
+ *  1 (false) if the addr is not the same in both
+ *  -1 (unable) if one of the addr is not AF_INET*
+ */
+int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
+{
+	if ((ss1->ss_family != AF_INET) && (ss1->ss_family != AF_INET6))
+		return -1;
+
+	if ((ss2->ss_family != AF_INET) && (ss2->ss_family != AF_INET6))
+		return -1;
+
+	if (ss1->ss_family != ss2->ss_family)
+		return 1;
+
+	switch (ss1->ss_family) {
+		case AF_INET:
+			return memcmp(&((struct sockaddr_in *)ss1)->sin_addr,
+				      &((struct sockaddr_in *)ss2)->sin_addr,
+				      sizeof(struct in_addr)) != 0;
+		case AF_INET6:
+			return memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr,
+				      &((struct sockaddr_in6 *)ss2)->sin6_addr,
+				      sizeof(struct in6_addr)) != 0;
+	}
+
+	return 1;
+}
+
+/* copy IP address from <source> into <dest>
+ * The caller must allocate and clear <dest> before calling.
+ * The source must be in either AF_INET or AF_INET6 family, or the destination
+ * address will be undefined. If the destination address used to hold a port,
+ * it is preserved, so that this function can be used to switch to another
+ * address family with no risk. Returns a pointer to the destination.
+ */
+struct sockaddr_storage *ipcpy(struct sockaddr_storage *source, struct sockaddr_storage *dest)
+{
+	int prev_port;
+
+	prev_port = get_net_port(dest);
+	memset(dest, 0, sizeof(*dest));
+	dest->ss_family = source->ss_family;
+
+	/* copy new addr and apply it */
+	switch (source->ss_family) {
+		case AF_INET:
+			((struct sockaddr_in *)dest)->sin_addr.s_addr = ((struct sockaddr_in *)source)->sin_addr.s_addr;
+			((struct sockaddr_in *)dest)->sin_port = prev_port;
+			break;
+		case AF_INET6:
+			memcpy(((struct sockaddr_in6 *)dest)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)source)->sin6_addr.s6_addr, sizeof(struct in6_addr));
+			((struct sockaddr_in6 *)dest)->sin6_port = prev_port;
+			break;
+	}
+
+	return dest;
+}
+
+char *human_time(int t, short hz_div) {
+	static char rv[sizeof("24855d23h")+1];	// longest of "23h59m" and "59m59s"
+	char *p = rv;
+	char *end = rv + sizeof(rv);
+	int cnt=2;				// print two numbers
+
+	if (unlikely(t < 0 || hz_div <= 0)) {
+		snprintf(p, end - p, "?");
+		return rv;
+	}
+
+	if (unlikely(hz_div > 1))
+		t /= hz_div;
+
+	if (t >= DAY) {
+		p += snprintf(p, end - p, "%dd", t / DAY);
+		cnt--;
+	}
+
+	if (cnt && t % DAY / HOUR) {
+		p += snprintf(p, end - p, "%dh", t % DAY / HOUR);
+		cnt--;
+	}
+
+	if (cnt && t % HOUR / MINUTE) {
+		p += snprintf(p, end - p, "%dm", t % HOUR / MINUTE);
+		cnt--;
+	}
+
+	if ((cnt && t % MINUTE) || !t)					// also display '0s'
+		p += snprintf(p, end - p, "%ds", t % MINUTE / SEC);
+
+	return rv;
+}
+
+const char *monthname[12] = {
+	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* date2str_log: write a date in the format :
+ * 	sprintf(str, "%02d/%s/%04d:%02d:%02d:%02d.%03d",
+ *		tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
+ *		tm.tm_hour, tm.tm_min, tm.tm_sec, (int)date.tv_usec/1000);
+ *
+ * without using sprintf. return a pointer to the last char written (\0) or
+ * NULL if there isn't enough space.
+ */
+char *date2str_log(char *dst, const struct tm *tm, const struct timeval *date, size_t size)
+{
+
+	if (size < 25) /* the size is fixed: 24 chars + \0 */
+		return NULL;
+
+	dst = utoa_pad((unsigned int)tm->tm_mday, dst, 3); // day
+	if (!dst)
+		return NULL;
+	*dst++ = '/';
+
+	memcpy(dst, monthname[tm->tm_mon], 3); // month
+	dst += 3;
+	*dst++ = '/';
+
+	dst = utoa_pad((unsigned int)tm->tm_year+1900, dst, 5); // year
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_hour, dst, 3); // hour
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_min, dst, 3); // minutes
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_sec, dst, 3); // secondes
+	if (!dst)
+		return NULL;
+	*dst++ = '.';
+
+	dst = utoa_pad((unsigned int)(date->tv_usec/1000)%1000, dst, 4); // milliseconds
+	if (!dst)
+		return NULL;
+	*dst = '\0';
+
+	return dst;
+}
+
+/* Base year used to compute leap years */
+#define TM_YEAR_BASE 1900
+
+/* Return the difference in seconds between two times (leap seconds are ignored).
+ * Retrieved from glibc 2.18 source code.
+ */
+static int my_tm_diff(const struct tm *a, const struct tm *b)
+{
+	/* Compute intervening leap days correctly even if year is negative.
+	 * Take care to avoid int overflow in leap day calculations,
+	 * but it's OK to assume that A and B are close to each other.
+	 */
+	int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+	int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+	int a100 = a4 / 25 - (a4 % 25 < 0);
+	int b100 = b4 / 25 - (b4 % 25 < 0);
+	int a400 = a100 >> 2;
+	int b400 = b100 >> 2;
+	int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+	int years = a->tm_year - b->tm_year;
+	int days = (365 * years + intervening_leap_days
+	         + (a->tm_yday - b->tm_yday));
+	return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+	       + (a->tm_min - b->tm_min))
+	       + (a->tm_sec - b->tm_sec));
+}
+
+/* Return the GMT offset for a specific local time.
+ * Both t and tm must represent the same time.
+ * The string returned has the same format as returned by strftime(... "%z", tm).
+ * Offsets are kept in an internal cache for better performances.
+ */
+const char *get_gmt_offset(time_t t, struct tm *tm)
+{
+	/* Cache offsets from GMT (depending on whether DST is active or not) */
+	static THREAD_LOCAL char gmt_offsets[2][5+1] = { "", "" };
+
+	char *gmt_offset;
+	struct tm tm_gmt;
+	int diff;
+	int isdst = tm->tm_isdst;
+
+	/* Pretend DST not active if its status is unknown */
+	if (isdst < 0)
+		isdst = 0;
+
+	/* Fetch the offset and initialize it if needed */
+	gmt_offset = gmt_offsets[isdst & 0x01];
+	if (unlikely(!*gmt_offset)) {
+		get_gmtime(t, &tm_gmt);
+		diff = my_tm_diff(tm, &tm_gmt);
+		if (diff < 0) {
+			diff = -diff;
+			*gmt_offset = '-';
+		} else {
+			*gmt_offset = '+';
+		}
+		diff %= 86400U;
+		diff /= 60; /* Convert to minutes */
+		snprintf(gmt_offset+1, 4+1, "%02d%02d", diff/60, diff%60);
+	}
+
+	return gmt_offset;
+}
+
+/* gmt2str_log: write a date in the format :
+ * "%02d/%s/%04d:%02d:%02d:%02d +0000" without using snprintf
+ * return a pointer to the last char written (\0) or
+ * NULL if there isn't enough space.
+ */
+char *gmt2str_log(char *dst, struct tm *tm, size_t size)
+{
+	if (size < 27) /* the size is fixed: 26 chars + \0 */
+		return NULL;
+
+	dst = utoa_pad((unsigned int)tm->tm_mday, dst, 3); // day
+	if (!dst)
+		return NULL;
+	*dst++ = '/';
+
+	memcpy(dst, monthname[tm->tm_mon], 3); // month
+	dst += 3;
+	*dst++ = '/';
+
+	dst = utoa_pad((unsigned int)tm->tm_year+1900, dst, 5); // year
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_hour, dst, 3); // hour
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_min, dst, 3); // minutes
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_sec, dst, 3); // secondes
+	if (!dst)
+		return NULL;
+	*dst++ = ' ';
+	*dst++ = '+';
+	*dst++ = '0';
+	*dst++ = '0';
+	*dst++ = '0';
+	*dst++ = '0';
+	*dst = '\0';
+
+	return dst;
+}
+
+/* localdate2str_log: write a date in the format :
+ * "%02d/%s/%04d:%02d:%02d:%02d +0000(local timezone)" without using snprintf
+ * Both t and tm must represent the same time.
+ * return a pointer to the last char written (\0) or
+ * NULL if there isn't enough space.
+ */
+char *localdate2str_log(char *dst, time_t t, struct tm *tm, size_t size)
+{
+	const char *gmt_offset;
+	if (size < 27) /* the size is fixed: 26 chars + \0 */
+		return NULL;
+
+	gmt_offset = get_gmt_offset(t, tm);
+
+	dst = utoa_pad((unsigned int)tm->tm_mday, dst, 3); // day
+	if (!dst)
+		return NULL;
+	*dst++ = '/';
+
+	memcpy(dst, monthname[tm->tm_mon], 3); // month
+	dst += 3;
+	*dst++ = '/';
+
+	dst = utoa_pad((unsigned int)tm->tm_year+1900, dst, 5); // year
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_hour, dst, 3); // hour
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_min, dst, 3); // minutes
+	if (!dst)
+		return NULL;
+	*dst++ = ':';
+
+	dst = utoa_pad((unsigned int)tm->tm_sec, dst, 3); // secondes
+	if (!dst)
+		return NULL;
+	*dst++ = ' ';
+
+	memcpy(dst, gmt_offset, 5); // Offset from local time to GMT
+	dst += 5;
+	*dst = '\0';
+
+	return dst;
+}
+
+/* Returns the number of seconds since 01/01/1970 0:0:0 GMT for GMT date <tm>.
+ * It is meant as a portable replacement for timegm() for use with valid inputs.
+ * Returns undefined results for invalid dates (eg: months out of range 0..11).
+ */
+time_t my_timegm(const struct tm *tm)
+{
+	/* Each month has 28, 29, 30 or 31 days, or 28+N. The date in the year
+	 * is thus (current month - 1)*28 + cumulated_N[month] to count the
+	 * sum of the extra N days for elapsed months. The sum of all these N
+	 * days doesn't exceed 30 for a complete year (366-12*28) so it fits
+	 * in a 5-bit word. This means that with 60 bits we can represent a
+	 * matrix of all these values at once, which is fast and efficient to
+	 * access. The extra February day for leap years is not counted here.
+	 *
+	 * Jan : none      =  0 (0)
+	 * Feb : Jan       =  3 (3)
+	 * Mar : Jan..Feb  =  3 (3 + 0)
+	 * Apr : Jan..Mar  =  6 (3 + 0 + 3)
+	 * May : Jan..Apr  =  8 (3 + 0 + 3 + 2)
+	 * Jun : Jan..May  = 11 (3 + 0 + 3 + 2 + 3)
+	 * Jul : Jan..Jun  = 13 (3 + 0 + 3 + 2 + 3 + 2)
+	 * Aug : Jan..Jul  = 16 (3 + 0 + 3 + 2 + 3 + 2 + 3)
+	 * Sep : Jan..Aug  = 19 (3 + 0 + 3 + 2 + 3 + 2 + 3 + 3)
+	 * Oct : Jan..Sep  = 21 (3 + 0 + 3 + 2 + 3 + 2 + 3 + 3 + 2)
+	 * Nov : Jan..Oct  = 24 (3 + 0 + 3 + 2 + 3 + 2 + 3 + 3 + 2 + 3)
+	 * Dec : Jan..Nov  = 26 (3 + 0 + 3 + 2 + 3 + 2 + 3 + 3 + 2 + 3 + 2)
+	 */
+	uint64_t extra =
+		( 0ULL <<  0*5) + ( 3ULL <<  1*5) + ( 3ULL <<  2*5) + /* Jan, Feb, Mar, */
+		( 6ULL <<  3*5) + ( 8ULL <<  4*5) + (11ULL <<  5*5) + /* Apr, May, Jun, */
+		(13ULL <<  6*5) + (16ULL <<  7*5) + (19ULL <<  8*5) + /* Jul, Aug, Sep, */
+		(21ULL <<  9*5) + (24ULL << 10*5) + (26ULL << 11*5);  /* Oct, Nov, Dec, */
+
+	unsigned int y = tm->tm_year + 1900;
+	unsigned int m = tm->tm_mon;
+	unsigned long days = 0;
+
+	/* days since 1/1/1970 for full years */
+	days += days_since_zero(y) - days_since_zero(1970);
+
+	/* days for full months in the current year */
+	days += 28 * m + ((extra >> (m * 5)) & 0x1f);
+
+	/* count + 1 after March for leap years. A leap year is a year multiple
+	 * of 4, unless it's multiple of 100 without being multiple of 400. 2000
+	 * is leap, 1900 isn't, 1904 is.
+	 */
+	if ((m > 1) && !(y & 3) && ((y % 100) || !(y % 400)))
+		days++;
+
+	days += tm->tm_mday - 1;
+	return days * 86400ULL + tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+}
+
+/* This function check a char. It returns true and updates
+ * <date> and <len> pointer to the new position if the
+ * character is found.
+ */
+static inline int parse_expect_char(const char **date, int *len, char c)
+{
+	if (*len < 1 || **date != c)
+		return 0;
+	(*len)--;
+	(*date)++;
+	return 1;
+}
+
+/* This function expects a string <str> of len <l>. It return true and updates.
+ * <date> and <len> if the string matches, otherwise, it returns false.
+ */
+static inline int parse_strcmp(const char **date, int *len, char *str, int l)
+{
+	if (*len < l || strncmp(*date, str, l) != 0)
+		return 0;
+	(*len) -= l;
+	(*date) += l;
+	return 1;
+}
+
+/* This macro converts 3 chars name in integer. */
+#define STR2I3(__a, __b, __c) ((__a) * 65536 + (__b) * 256 + (__c))
+
+/* day-name     = %x4D.6F.6E ; "Mon", case-sensitive
+ *              / %x54.75.65 ; "Tue", case-sensitive
+ *              / %x57.65.64 ; "Wed", case-sensitive
+ *              / %x54.68.75 ; "Thu", case-sensitive
+ *              / %x46.72.69 ; "Fri", case-sensitive
+ *              / %x53.61.74 ; "Sat", case-sensitive
+ *              / %x53.75.6E ; "Sun", case-sensitive
+ *
+ * This array must be alphabetically sorted
+ */
+static inline int parse_http_dayname(const char **date, int *len, struct tm *tm)
+{
+	if (*len < 3)
+		return 0;
+	switch (STR2I3((*date)[0], (*date)[1], (*date)[2])) {
+	case STR2I3('M','o','n'): tm->tm_wday = 1;  break;
+	case STR2I3('T','u','e'): tm->tm_wday = 2;  break;
+	case STR2I3('W','e','d'): tm->tm_wday = 3;  break;
+	case STR2I3('T','h','u'): tm->tm_wday = 4;  break;
+	case STR2I3('F','r','i'): tm->tm_wday = 5;  break;
+	case STR2I3('S','a','t'): tm->tm_wday = 6;  break;
+	case STR2I3('S','u','n'): tm->tm_wday = 7;  break;
+	default: return 0;
+	}
+	*len -= 3;
+	*date  += 3;
+	return 1;
+}
+
+/* month        = %x4A.61.6E ; "Jan", case-sensitive
+ *              / %x46.65.62 ; "Feb", case-sensitive
+ *              / %x4D.61.72 ; "Mar", case-sensitive
+ *              / %x41.70.72 ; "Apr", case-sensitive
+ *              / %x4D.61.79 ; "May", case-sensitive
+ *              / %x4A.75.6E ; "Jun", case-sensitive
+ *              / %x4A.75.6C ; "Jul", case-sensitive
+ *              / %x41.75.67 ; "Aug", case-sensitive
+ *              / %x53.65.70 ; "Sep", case-sensitive
+ *              / %x4F.63.74 ; "Oct", case-sensitive
+ *              / %x4E.6F.76 ; "Nov", case-sensitive
+ *              / %x44.65.63 ; "Dec", case-sensitive
+ *
+ * This array must be alphabetically sorted
+ */
+static inline int parse_http_monthname(const char **date, int *len, struct tm *tm)
+{
+	if (*len < 3)
+		return 0;
+	switch (STR2I3((*date)[0], (*date)[1], (*date)[2])) {
+	case STR2I3('J','a','n'): tm->tm_mon = 0;  break;
+	case STR2I3('F','e','b'): tm->tm_mon = 1;  break;
+	case STR2I3('M','a','r'): tm->tm_mon = 2;  break;
+	case STR2I3('A','p','r'): tm->tm_mon = 3;  break;
+	case STR2I3('M','a','y'): tm->tm_mon = 4;  break;
+	case STR2I3('J','u','n'): tm->tm_mon = 5;  break;
+	case STR2I3('J','u','l'): tm->tm_mon = 6;  break;
+	case STR2I3('A','u','g'): tm->tm_mon = 7;  break;
+	case STR2I3('S','e','p'): tm->tm_mon = 8;  break;
+	case STR2I3('O','c','t'): tm->tm_mon = 9;  break;
+	case STR2I3('N','o','v'): tm->tm_mon = 10; break;
+	case STR2I3('D','e','c'): tm->tm_mon = 11; break;
+	default: return 0;
+	}
+	*len -= 3;
+	*date  += 3;
+	return 1;
+}
+
+/* day-name-l   = %x4D.6F.6E.64.61.79    ; "Monday", case-sensitive
+ *        / %x54.75.65.73.64.61.79       ; "Tuesday", case-sensitive
+ *        / %x57.65.64.6E.65.73.64.61.79 ; "Wednesday", case-sensitive
+ *        / %x54.68.75.72.73.64.61.79    ; "Thursday", case-sensitive
+ *        / %x46.72.69.64.61.79          ; "Friday", case-sensitive
+ *        / %x53.61.74.75.72.64.61.79    ; "Saturday", case-sensitive
+ *        / %x53.75.6E.64.61.79          ; "Sunday", case-sensitive
+ *
+ * This array must be alphabetically sorted
+ */
+static inline int parse_http_ldayname(const char **date, int *len, struct tm *tm)
+{
+	if (*len < 6) /* Minimum length. */
+		return 0;
+	switch (STR2I3((*date)[0], (*date)[1], (*date)[2])) {
+	case STR2I3('M','o','n'):
+		RET0_UNLESS(parse_strcmp(date, len, "Monday", 6));
+		tm->tm_wday = 1;
+		return 1;
+	case STR2I3('T','u','e'):
+		RET0_UNLESS(parse_strcmp(date, len, "Tuesday", 7));
+		tm->tm_wday = 2;
+		return 1;
+	case STR2I3('W','e','d'):
+		RET0_UNLESS(parse_strcmp(date, len, "Wednesday", 9));
+		tm->tm_wday = 3;
+		return 1;
+	case STR2I3('T','h','u'):
+		RET0_UNLESS(parse_strcmp(date, len, "Thursday", 8));
+		tm->tm_wday = 4;
+		return 1;
+	case STR2I3('F','r','i'):
+		RET0_UNLESS(parse_strcmp(date, len, "Friday", 6));
+		tm->tm_wday = 5;
+		return 1;
+	case STR2I3('S','a','t'):
+		RET0_UNLESS(parse_strcmp(date, len, "Saturday", 8));
+		tm->tm_wday = 6;
+		return 1;
+	case STR2I3('S','u','n'):
+		RET0_UNLESS(parse_strcmp(date, len, "Sunday", 6));
+		tm->tm_wday = 7;
+		return 1;
+	}
+	return 0;
+}
+
+/* This function parses exactly 1 digit and returns the numeric value in "digit". */
+static inline int parse_digit(const char **date, int *len, int *digit)
+{
+	if (*len < 1 || **date < '0' || **date > '9')
+		return 0;
+	*digit = (**date - '0');
+	(*date)++;
+	(*len)--;
+	return 1;
+}
+
+/* This function parses exactly 2 digits and returns the numeric value in "digit". */
+static inline int parse_2digit(const char **date, int *len, int *digit)
+{
+	int value;
+
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) = value * 10;
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) += value;
+
+	return 1;
+}
+
+/* This function parses exactly 4 digits and returns the numeric value in "digit". */
+static inline int parse_4digit(const char **date, int *len, int *digit)
+{
+	int value;
+
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) = value * 1000;
+
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) += value * 100;
+
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) += value * 10;
+
+	RET0_UNLESS(parse_digit(date, len, &value));
+	(*digit) += value;
+
+	return 1;
+}
+
+/* time-of-day  = hour ":" minute ":" second
+ *              ; 00:00:00 - 23:59:60 (leap second)
+ *
+ * hour         = 2DIGIT
+ * minute       = 2DIGIT
+ * second       = 2DIGIT
+ */
+static inline int parse_http_time(const char **date, int *len, struct tm *tm)
+{
+	RET0_UNLESS(parse_2digit(date, len, &tm->tm_hour)); /* hour 2DIGIT */
+	RET0_UNLESS(parse_expect_char(date, len, ':'));     /* expect ":"  */
+	RET0_UNLESS(parse_2digit(date, len, &tm->tm_min));  /* min 2DIGIT  */
+	RET0_UNLESS(parse_expect_char(date, len, ':'));     /* expect ":"  */
+	RET0_UNLESS(parse_2digit(date, len, &tm->tm_sec));  /* sec 2DIGIT  */
+	return 1;
+}
+
+/* From RFC7231
+ * https://tools.ietf.org/html/rfc7231#section-7.1.1.1
+ *
+ * IMF-fixdate  = day-name "," SP date1 SP time-of-day SP GMT
+ * ; fixed length/zone/capitalization subset of the format
+ * ; see Section 3.3 of [RFC5322]
+ *
+ *
+ * date1        = day SP month SP year
+ *              ; e.g., 02 Jun 1982
+ *
+ * day          = 2DIGIT
+ * year         = 4DIGIT
+ *
+ * GMT          = %x47.4D.54 ; "GMT", case-sensitive
+ *
+ * time-of-day  = hour ":" minute ":" second
+ *              ; 00:00:00 - 23:59:60 (leap second)
+ *
+ * hour         = 2DIGIT
+ * minute       = 2DIGIT
+ * second       = 2DIGIT
+ *
+ * DIGIT        = decimal 0-9
+ */
+int parse_imf_date(const char *date, int len, struct tm *tm)
+{
+	/* tm_gmtoff, if present, ought to be zero'ed */
+	memset(tm, 0, sizeof(*tm));
+
+	RET0_UNLESS(parse_http_dayname(&date, &len, tm));     /* day-name */
+	RET0_UNLESS(parse_expect_char(&date, &len, ','));     /* expect "," */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_2digit(&date, &len, &tm->tm_mday)); /* day 2DIGIT */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_http_monthname(&date, &len, tm));   /* Month */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_4digit(&date, &len, &tm->tm_year)); /* year = 4DIGIT */
+	tm->tm_year -= 1900;
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_http_time(&date, &len, tm));        /* Parse time. */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_strcmp(&date, &len, "GMT", 3));     /* GMT = %x47.4D.54 ; "GMT", case-sensitive */
+	tm->tm_isdst = -1;
+	return 1;
+}
+
+/* From RFC7231
+ * https://tools.ietf.org/html/rfc7231#section-7.1.1.1
+ *
+ * rfc850-date  = day-name-l "," SP date2 SP time-of-day SP GMT
+ * date2        = day "-" month "-" 2DIGIT
+ *              ; e.g., 02-Jun-82
+ *
+ * day          = 2DIGIT
+ */
+int parse_rfc850_date(const char *date, int len, struct tm *tm)
+{
+	int year;
+
+	/* tm_gmtoff, if present, ought to be zero'ed */
+	memset(tm, 0, sizeof(*tm));
+
+	RET0_UNLESS(parse_http_ldayname(&date, &len, tm));    /* Read the day name */
+	RET0_UNLESS(parse_expect_char(&date, &len, ','));     /* expect "," */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_2digit(&date, &len, &tm->tm_mday)); /* day 2DIGIT */
+	RET0_UNLESS(parse_expect_char(&date, &len, '-'));     /* expect "-" */
+	RET0_UNLESS(parse_http_monthname(&date, &len, tm));   /* Month */
+	RET0_UNLESS(parse_expect_char(&date, &len, '-'));     /* expect "-" */
+
+	/* year = 2DIGIT
+	 *
+	 * Recipients of a timestamp value in rfc850-(*date) format, which uses a
+	 * two-digit year, MUST interpret a timestamp that appears to be more
+	 * than 50 years in the future as representing the most recent year in
+	 * the past that had the same last two digits.
+	 */
+	RET0_UNLESS(parse_2digit(&date, &len, &tm->tm_year));
+
+	/* expect SP */
+	if (!parse_expect_char(&date, &len, ' ')) {
+		/* Maybe we have the date with 4 digits. */
+		RET0_UNLESS(parse_2digit(&date, &len, &year));
+		tm->tm_year = (tm->tm_year * 100 + year) - 1900;
+		/* expect SP */
+		RET0_UNLESS(parse_expect_char(&date, &len, ' '));
+	} else {
+		/* I fix 60 as pivot: >60: +1900, <60: +2000. Note that the
+		 * tm_year is the number of year since 1900, so for +1900, we
+		 * do nothing, and for +2000, we add 100.
+		 */
+		if (tm->tm_year <= 60)
+			tm->tm_year += 100;
+	}
+
+	RET0_UNLESS(parse_http_time(&date, &len, tm));    /* Parse time. */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' ')); /* expect SP */
+	RET0_UNLESS(parse_strcmp(&date, &len, "GMT", 3)); /* GMT = %x47.4D.54 ; "GMT", case-sensitive */
+	tm->tm_isdst = -1;
+
+	return 1;
+}
+
+/* From RFC7231
+ * https://tools.ietf.org/html/rfc7231#section-7.1.1.1
+ *
+ * asctime-date = day-name SP date3 SP time-of-day SP year
+ * date3        = month SP ( 2DIGIT / ( SP 1DIGIT ))
+ *              ; e.g., Jun  2
+ *
+ * HTTP-date is case sensitive.  A sender MUST NOT generate additional
+ * whitespace in an HTTP-date beyond that specifically included as SP in
+ * the grammar.
+ */
+int parse_asctime_date(const char *date, int len, struct tm *tm)
+{
+	/* tm_gmtoff, if present, ought to be zero'ed */
+	memset(tm, 0, sizeof(*tm));
+
+	RET0_UNLESS(parse_http_dayname(&date, &len, tm));   /* day-name */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));   /* expect SP */
+	RET0_UNLESS(parse_http_monthname(&date, &len, tm)); /* expect month */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));   /* expect SP */
+
+	/* expect SP and 1DIGIT or 2DIGIT */
+	if (parse_expect_char(&date, &len, ' '))
+		RET0_UNLESS(parse_digit(&date, &len, &tm->tm_mday));
+	else
+		RET0_UNLESS(parse_2digit(&date, &len, &tm->tm_mday));
+
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_http_time(&date, &len, tm));        /* Parse time. */
+	RET0_UNLESS(parse_expect_char(&date, &len, ' '));     /* expect SP */
+	RET0_UNLESS(parse_4digit(&date, &len, &tm->tm_year)); /* year = 4DIGIT */
+	tm->tm_year -= 1900;
+	tm->tm_isdst = -1;
+	return 1;
+}
+
+/* From RFC7231
+ * https://tools.ietf.org/html/rfc7231#section-7.1.1.1
+ *
+ * HTTP-date    = IMF-fixdate / obs-date
+ * obs-date     = rfc850-date / asctime-date
+ *
+ * parses an HTTP date in the RFC format and is accepted
+ * alternatives. <date> is the strinf containing the date,
+ * len is the len of the string. <tm> is filled with the
+ * parsed time. We must considers this time as GMT.
+ */
+int parse_http_date(const char *date, int len, struct tm *tm)
+{
+	if (parse_imf_date(date, len, tm))
+		return 1;
+
+	if (parse_rfc850_date(date, len, tm))
+		return 1;
+
+	if (parse_asctime_date(date, len, tm))
+		return 1;
+
+	return 0;
+}
+
+/* Dynamically allocates a string of the proper length to hold the formatted
+ * output. NULL is returned on error. The caller is responsible for freeing the
+ * memory area using free(). The resulting string is returned in <out> if the
+ * pointer is not NULL. A previous version of <out> might be used to build the
+ * new string, and it will be freed before returning if it is not NULL, which
+ * makes it possible to build complex strings from iterative calls without
+ * having to care about freeing intermediate values, as in the example below :
+ *
+ *     memprintf(&err, "invalid argument: '%s'", arg);
+ *     ...
+ *     memprintf(&err, "parser said : <%s>\n", *err);
+ *     ...
+ *     free(*err);
+ *
+ * This means that <err> must be initialized to NULL before first invocation.
+ * The return value also holds the allocated string, which eases error checking
+ * and immediate consumption. If the output pointer is not used, NULL must be
+ * passed instead and it will be ignored. The returned message will then also
+ * be NULL so that the caller does not have to bother with freeing anything.
+ *
+ * It is also convenient to use it without any free except the last one :
+ *    err = NULL;
+ *    if (!fct1(err)) report(*err);
+ *    if (!fct2(err)) report(*err);
+ *    if (!fct3(err)) report(*err);
+ *    free(*err);
+ *
+ * memprintf relies on memvprintf. This last version can be called from any
+ * function with variadic arguments.
+ */
+char *memvprintf(char **out, const char *format, va_list orig_args)
+{
+	va_list args;
+	char *ret = NULL;
+	int allocated = 0;
+	int needed = 0;
+
+	if (!out)
+		return NULL;
+
+	do {
+		char buf1;
+
+		/* vsnprintf() will return the required length even when the
+		 * target buffer is NULL. We do this in a loop just in case
+		 * intermediate evaluations get wrong.
+		 */
+		va_copy(args, orig_args);
+		needed = vsnprintf(ret ? ret : &buf1, allocated, format, args);
+		va_end(args);
+		if (needed < allocated) {
+			/* Note: on Solaris 8, the first iteration always
+			 * returns -1 if allocated is zero, so we force a
+			 * retry.
+			 */
+			if (!allocated)
+				needed = 0;
+			else
+				break;
+		}
+
+		allocated = needed + 1;
+		ret = my_realloc2(ret, allocated);
+	} while (ret);
+
+	if (needed < 0) {
+		/* an error was encountered */
+		free(ret);
+		ret = NULL;
+	}
+
+	if (out) {
+		free(*out);
+		*out = ret;
+	}
+
+	return ret;
+}
+
+char *memprintf(char **out, const char *format, ...)
+{
+	va_list args;
+	char *ret = NULL;
+
+	va_start(args, format);
+	ret = memvprintf(out, format, args);
+	va_end(args);
+
+	return ret;
+}
+
+/* Used to add <level> spaces before each line of <out>, unless there is only one line.
+ * The input argument is automatically freed and reassigned. The result will have to be
+ * freed by the caller. It also supports being passed a NULL which results in the same
+ * output.
+ * Example of use :
+ *   parse(cmd, &err); (callee: memprintf(&err, ...))
+ *   fprintf(stderr, "Parser said: %s\n", indent_error(&err));
+ *   free(err);
+ */
+char *indent_msg(char **out, int level)
+{
+	char *ret, *in, *p;
+	int needed = 0;
+	int lf = 0;
+	int lastlf = 0;
+	int len;
+
+	if (!out || !*out)
+		return NULL;
+
+	in = *out - 1;
+	while ((in = strchr(in + 1, '\n')) != NULL) {
+		lastlf = in - *out;
+		lf++;
+	}
+
+	if (!lf) /* single line, no LF, return it as-is */
+		return *out;
+
+	len = strlen(*out);
+
+	if (lf == 1 && lastlf == len - 1) {
+		/* single line, LF at end, strip it and return as-is */
+		(*out)[lastlf] = 0;
+		return *out;
+	}
+
+	/* OK now we have at least one LF, we need to process the whole string
+	 * as a multi-line string. What we'll do :
+	 *   - prefix with an LF if there is none
+	 *   - add <level> spaces before each line
+	 * This means at most ( 1 + level + (len-lf) + lf*<1+level) ) =
+	 *   1 + level + len + lf * level = 1 + level * (lf + 1) + len.
+	 */
+
+	needed = 1 + level * (lf + 1) + len + 1;
+	p = ret = malloc(needed);
+	in = *out;
+
+	/* skip initial LFs */
+	while (*in == '\n')
+		in++;
+
+	/* copy each line, prefixed with LF and <level> spaces, and without the trailing LF */
+	while (*in) {
+		*p++ = '\n';
+		memset(p, ' ', level);
+		p += level;
+		do {
+			*p++ = *in++;
+		} while (*in && *in != '\n');
+		if (*in)
+			in++;
+	}
+	*p = 0;
+
+	free(*out);
+	*out = ret;
+
+	return ret;
+}
+
+/* makes a copy of message <in> into <out>, with each line prefixed with <pfx>
+ * and end of lines replaced with <eol> if not 0. The first line to indent has
+ * to be indicated in <first> (starts at zero), so that it is possible to skip
+ * indenting the first line if it has to be appended after an existing message.
+ * Empty strings are never indented, and NULL strings are considered empty both
+ * for <in> and <pfx>. It returns non-zero if an EOL was appended as the last
+ * character, non-zero otherwise.
+ */
+int append_prefixed_str(struct buffer *out, const char *in, const char *pfx, char eol, int first)
+{
+	int bol, lf;
+	int pfxlen = pfx ? strlen(pfx) : 0;
+
+	if (!in)
+		return 0;
+
+	bol = 1;
+	lf = 0;
+	while (*in) {
+		if (bol && pfxlen) {
+			if (first > 0)
+				first--;
+			else
+				b_putblk(out, pfx, pfxlen);
+			bol = 0;
+		}
+
+		lf = (*in == '\n');
+		bol |= lf;
+		b_putchr(out, (lf && eol) ? eol : *in);
+		in++;
+	}
+	return lf;
+}
+
+/* removes environment variable <name> from the environment as found in
+ * environ. This is only provided as an alternative for systems without
+ * unsetenv() (old Solaris and AIX versions). THIS IS NOT THREAD SAFE.
+ * The principle is to scan environ for each occurrence of variable name
+ * <name> and to replace the matching pointers with the last pointer of
+ * the array (since variables are not ordered).
+ * It always returns 0 (success).
+ */
+int my_unsetenv(const char *name)
+{
+	extern char **environ;
+	char **p = environ;
+	int vars;
+	int next;
+	int len;
+
+	len = strlen(name);
+	for (vars = 0; p[vars]; vars++)
+		;
+	next = 0;
+	while (next < vars) {
+		if (strncmp(p[next], name, len) != 0 || p[next][len] != '=') {
+			next++;
+			continue;
+		}
+		if (next < vars - 1)
+			p[next] = p[vars - 1];
+		p[--vars] = NULL;
+	}
+	return 0;
+}
+
+/* Convert occurrences of environment variables in the input string to their
+ * corresponding value. A variable is identified as a series of alphanumeric
+ * characters or underscores following a '$' sign. The <in> string must be
+ * free()able. NULL returns NULL. The resulting string might be reallocated if
+ * some expansion is made. Variable names may also be enclosed into braces if
+ * needed (eg: to concatenate alphanum characters).
+ */
+char *env_expand(char *in)
+{
+	char *txt_beg;
+	char *out;
+	char *txt_end;
+	char *var_beg;
+	char *var_end;
+	char *value;
+	char *next;
+	int out_len;
+	int val_len;
+
+	if (!in)
+		return in;
+
+	value = out = NULL;
+	out_len = 0;
+
+	txt_beg = in;
+	do {
+		/* look for next '$' sign in <in> */
+		for (txt_end = txt_beg; *txt_end && *txt_end != '$'; txt_end++);
+
+		if (!*txt_end && !out) /* end and no expansion performed */
+			return in;
+
+		val_len = 0;
+		next = txt_end;
+		if (*txt_end == '$') {
+			char save;
+
+			var_beg = txt_end + 1;
+			if (*var_beg == '{')
+				var_beg++;
+
+			var_end = var_beg;
+			while (isalnum((unsigned char)*var_end) || *var_end == '_') {
+				var_end++;
+			}
+
+			next = var_end;
+			if (*var_end == '}' && (var_beg > txt_end + 1))
+				next++;
+
+			/* get value of the variable name at this location */
+			save = *var_end;
+			*var_end = '\0';
+			value = getenv(var_beg);
+			*var_end = save;
+			val_len = value ? strlen(value) : 0;
+		}
+
+		out = my_realloc2(out, out_len + (txt_end - txt_beg) + val_len + 1);
+		if (txt_end > txt_beg) {
+			memcpy(out + out_len, txt_beg, txt_end - txt_beg);
+			out_len += txt_end - txt_beg;
+		}
+		if (val_len) {
+			memcpy(out + out_len, value, val_len);
+			out_len += val_len;
+		}
+		out[out_len] = 0;
+		txt_beg = next;
+	} while (*txt_beg);
+
+	/* here we know that <out> was allocated and that we don't need <in> anymore */
+	free(in);
+	return out;
+}
+
+
+/* same as strstr() but case-insensitive and with limit length */
+const char *strnistr(const char *str1, int len_str1, const char *str2, int len_str2)
+{
+	char *pptr, *sptr, *start;
+	unsigned int slen, plen;
+	unsigned int tmp1, tmp2;
+
+	if (str1 == NULL || len_str1 == 0) // search pattern into an empty string => search is not found
+		return NULL;
+
+	if (str2 == NULL || len_str2 == 0) // pattern is empty => every str1 match
+		return str1;
+
+	if (len_str1 < len_str2) // pattern is longer than string => search is not found
+		return NULL;
+
+	for (tmp1 = 0, start = (char *)str1, pptr = (char *)str2, slen = len_str1, plen = len_str2; slen >= plen; start++, slen--) {
+		while (toupper(*start) != toupper(*str2)) {
+			start++;
+			slen--;
+			tmp1++;
+
+			if (tmp1 >= len_str1)
+				return NULL;
+
+			/* if pattern longer than string */
+			if (slen < plen)
+				return NULL;
+		}
+
+		sptr = start;
+		pptr = (char *)str2;
+
+		tmp2 = 0;
+		while (toupper(*sptr) == toupper(*pptr)) {
+			sptr++;
+			pptr++;
+			tmp2++;
+
+			if (*pptr == '\0' || tmp2 == len_str2) /* end of pattern found */
+				return start;
+			if (*sptr == '\0' || tmp2 == len_str1) /* end of string found and the pattern is not fully found */
+				return NULL;
+		}
+	}
+	return NULL;
+}
+
+/* This function read the next valid utf8 char.
+ * <s> is the byte srray to be decode, <len> is its length.
+ * The function returns decoded char encoded like this:
+ * The 4 msb are the return code (UTF8_CODE_*), the 4 lsb
+ * are the length read. The decoded character is stored in <c>.
+ */
+unsigned char utf8_next(const char *s, int len, unsigned int *c)
+{
+	const unsigned char *p = (unsigned char *)s;
+	int dec;
+	unsigned char code = UTF8_CODE_OK;
+
+	if (len < 1)
+		return UTF8_CODE_OK;
+
+	/* Check the type of UTF8 sequence
+	 *
+	 * 0... ....  0x00 <= x <= 0x7f : 1 byte: ascii char
+	 * 10.. ....  0x80 <= x <= 0xbf : invalid sequence
+	 * 110. ....  0xc0 <= x <= 0xdf : 2 bytes
+	 * 1110 ....  0xe0 <= x <= 0xef : 3 bytes
+	 * 1111 0...  0xf0 <= x <= 0xf7 : 4 bytes
+	 * 1111 10..  0xf8 <= x <= 0xfb : 5 bytes
+	 * 1111 110.  0xfc <= x <= 0xfd : 6 bytes
+	 * 1111 111.  0xfe <= x <= 0xff : invalid sequence
+	 */
+	switch (*p) {
+	case 0x00 ... 0x7f:
+		*c = *p;
+		return UTF8_CODE_OK | 1;
+
+	case 0x80 ... 0xbf:
+		*c = *p;
+		return UTF8_CODE_BADSEQ | 1;
+
+	case 0xc0 ... 0xdf:
+		if (len < 2) {
+			*c = *p;
+			return UTF8_CODE_BADSEQ | 1;
+		}
+		*c = *p & 0x1f;
+		dec = 1;
+		break;
+
+	case 0xe0 ... 0xef:
+		if (len < 3) {
+			*c = *p;
+			return UTF8_CODE_BADSEQ | 1;
+		}
+		*c = *p & 0x0f;
+		dec = 2;
+		break;
+
+	case 0xf0 ... 0xf7:
+		if (len < 4) {
+			*c = *p;
+			return UTF8_CODE_BADSEQ | 1;
+		}
+		*c = *p & 0x07;
+		dec = 3;
+		break;
+
+	case 0xf8 ... 0xfb:
+		if (len < 5) {
+			*c = *p;
+			return UTF8_CODE_BADSEQ | 1;
+		}
+		*c = *p & 0x03;
+		dec = 4;
+		break;
+
+	case 0xfc ... 0xfd:
+		if (len < 6) {
+			*c = *p;
+			return UTF8_CODE_BADSEQ | 1;
+		}
+		*c = *p & 0x01;
+		dec = 5;
+		break;
+
+	case 0xfe ... 0xff:
+	default:
+		*c = *p;
+		return UTF8_CODE_BADSEQ | 1;
+	}
+
+	p++;
+
+	while (dec > 0) {
+
+		/* need 0x10 for the 2 first bits */
+		if ( ( *p & 0xc0 ) != 0x80 )
+			return UTF8_CODE_BADSEQ | ((p-(unsigned char *)s)&0xffff);
+
+		/* add data at char */
+		*c = ( *c << 6 ) | ( *p & 0x3f );
+
+		dec--;
+		p++;
+	}
+
+	/* Check ovelong encoding.
+	 * 1 byte  : 5 + 6         : 11 : 0x80    ... 0x7ff
+	 * 2 bytes : 4 + 6 + 6     : 16 : 0x800   ... 0xffff
+	 * 3 bytes : 3 + 6 + 6 + 6 : 21 : 0x10000 ... 0x1fffff
+	 */
+	if ((                 *c <= 0x7f     && (p-(unsigned char *)s) > 1) ||
+	    (*c >= 0x80    && *c <= 0x7ff    && (p-(unsigned char *)s) > 2) ||
+	    (*c >= 0x800   && *c <= 0xffff   && (p-(unsigned char *)s) > 3) ||
+	    (*c >= 0x10000 && *c <= 0x1fffff && (p-(unsigned char *)s) > 4))
+		code |= UTF8_CODE_OVERLONG;
+
+	/* Check invalid UTF8 range. */
+	if ((*c >= 0xd800 && *c <= 0xdfff) ||
+	    (*c >= 0xfffe && *c <= 0xffff))
+		code |= UTF8_CODE_INVRANGE;
+
+	return code | ((p-(unsigned char *)s)&0x0f);
+}
+
+/* append a copy of string <str> (in a wordlist) at the end of the list <li>
+ * On failure : return 0 and <err> filled with an error message.
+ * The caller is responsible for freeing the <err> and <str> copy
+ * memory area using free()
+ */
+int list_append_word(struct list *li, const char *str, char **err)
+{
+	struct wordlist *wl;
+
+	wl = calloc(1, sizeof(*wl));
+	if (!wl) {
+		memprintf(err, "out of memory");
+		goto fail_wl;
+	}
+
+	wl->s = strdup(str);
+	if (!wl->s) {
+		memprintf(err, "out of memory");
+		goto fail_wl_s;
+	}
+
+	LIST_ADDQ(li, &wl->list);
+
+	return 1;
+
+fail_wl_s:
+	free(wl->s);
+fail_wl:
+	free(wl);
+	return 0;
+}
+
+/* indicates if a memory location may safely be read or not. The trick consists
+ * in performing a harmless syscall using this location as an input and letting
+ * the operating system report whether it's OK or not. For this we have the
+ * stat() syscall, which will return EFAULT when the memory location supposed
+ * to contain the file name is not readable. If it is readable it will then
+ * either return 0 if the area contains an existing file name, or -1 with
+ * another code. This must not be abused, and some audit systems might detect
+ * this as abnormal activity. It's used only for unsafe dumps.
+ */
+int may_access(const void *ptr)
+{
+	struct stat buf;
+
+	if (stat(ptr, &buf) == 0)
+		return 1;
+	if (errno == EFAULT)
+		return 0;
+	return 1;
+}
+
+/* print a string of text buffer to <out>. The format is :
+ * Non-printable chars \t, \n, \r and \e are * encoded in C format.
+ * Other non-printable chars are encoded "\xHH". Space, '\', and '=' are also escaped.
+ * Print stopped if null char or <bsize> is reached, or if no more place in the chunk.
+ */
+int dump_text(struct buffer *out, const char *buf, int bsize)
+{
+	unsigned char c;
+	int ptr = 0;
+
+	while (buf[ptr] && ptr < bsize) {
+		c = buf[ptr];
+		if (isprint((unsigned char)c) && isascii((unsigned char)c) && c != '\\' && c != ' ' && c != '=') {
+			if (out->data > out->size - 1)
+				break;
+			out->area[out->data++] = c;
+		}
+		else if (c == '\t' || c == '\n' || c == '\r' || c == '\e' || c == '\\' || c == ' ' || c == '=') {
+			if (out->data > out->size - 2)
+				break;
+			out->area[out->data++] = '\\';
+			switch (c) {
+			case ' ': c = ' '; break;
+			case '\t': c = 't'; break;
+			case '\n': c = 'n'; break;
+			case '\r': c = 'r'; break;
+			case '\e': c = 'e'; break;
+			case '\\': c = '\\'; break;
+			case '=': c = '='; break;
+			}
+			out->area[out->data++] = c;
+		}
+		else {
+			if (out->data > out->size - 4)
+				break;
+			out->area[out->data++] = '\\';
+			out->area[out->data++] = 'x';
+			out->area[out->data++] = hextab[(c >> 4) & 0xF];
+			out->area[out->data++] = hextab[c & 0xF];
+		}
+		ptr++;
+	}
+
+	return ptr;
+}
+
+/* print a buffer in hexa.
+ * Print stopped if <bsize> is reached, or if no more place in the chunk.
+ */
+int dump_binary(struct buffer *out, const char *buf, int bsize)
+{
+	unsigned char c;
+	int ptr = 0;
+
+	while (ptr < bsize) {
+		c = buf[ptr];
+
+		if (out->data > out->size - 2)
+			break;
+		out->area[out->data++] = hextab[(c >> 4) & 0xF];
+		out->area[out->data++] = hextab[c & 0xF];
+
+		ptr++;
+	}
+	return ptr;
+}
+
+/* Appends into buffer <out> a hex dump of memory area <buf> for <len> bytes,
+ * prepending each line with prefix <pfx>. The output is *not* initialized.
+ * The output will not wrap pas the buffer's end so it is more optimal if the
+ * caller makes sure the buffer is aligned first. A trailing zero will always
+ * be appended (and not counted) if there is room for it. The caller must make
+ * sure that the area is dumpable first. If <unsafe> is non-null, the memory
+ * locations are checked first for being readable.
+ */
+void dump_hex(struct buffer *out, const char *pfx, const void *buf, int len, int unsafe)
+{
+	const unsigned char *d = buf;
+	int i, j, start;
+
+	d = (const unsigned char *)(((unsigned long)buf) & -16);
+	start = ((unsigned long)buf) & 15;
+
+	for (i = 0; i < start + len; i += 16) {
+		chunk_appendf(out, (sizeof(void *) == 4) ? "%s%8p: " : "%s%16p: ", pfx, d + i);
+
+		// 0: unchecked, 1: checked safe, 2: danger
+		unsafe = !!unsafe;
+		if (unsafe && !may_access(d + i))
+			unsafe = 2;
+
+		for (j = 0; j < 16; j++) {
+			if ((i + j < start) || (i + j >= start + len))
+				chunk_strcat(out, "'' ");
+			else if (unsafe > 1)
+				chunk_strcat(out, "** ");
+			else
+				chunk_appendf(out, "%02x ", d[i + j]);
+
+			if (j == 7)
+				chunk_strcat(out, "- ");
+		}
+		chunk_strcat(out, "  ");
+		for (j = 0; j < 16; j++) {
+			if ((i + j < start) || (i + j >= start + len))
+				chunk_strcat(out, "'");
+			else if (unsafe > 1)
+				chunk_strcat(out, "*");
+			else if (isprint((unsigned char)d[i + j]))
+				chunk_appendf(out, "%c", d[i + j]);
+			else
+				chunk_strcat(out, ".");
+		}
+		chunk_strcat(out, "\n");
+	}
+}
+
+/* dumps <pfx> followed by <n> bytes from <addr> in hex form into buffer <buf>
+ * enclosed in brackets after the address itself, formatted on 14 chars
+ * including the "0x" prefix. This is meant to be used as a prefix for code
+ * areas. For example:
+ *    "0x7f10b6557690 [48 c7 c0 0f 00 00 00 0f]"
+ * It relies on may_access() to know if the bytes are dumpable, otherwise "--"
+ * is emitted. A NULL <pfx> will be considered empty.
+ */
+void dump_addr_and_bytes(struct buffer *buf, const char *pfx, const void *addr, int n)
+{
+	int ok = 0;
+	int i;
+
+	chunk_appendf(buf, "%s%#14lx [", pfx ? pfx : "", (long)addr);
+
+	for (i = 0; i < n; i++) {
+		if (i == 0 || (((long)(addr + i) ^ (long)(addr)) & 4096))
+			ok = may_access(addr + i);
+		if (ok)
+			chunk_appendf(buf, "%02x%s", ((uint8_t*)addr)[i], (i<n-1) ? " " : "]");
+		else
+			chunk_appendf(buf, "--%s", (i<n-1) ? " " : "]");
+	}
+}
+
+/* print a line of text buffer (limited to 70 bytes) to <out>. The format is :
+ * <2 spaces> <offset=5 digits> <space or plus> <space> <70 chars max> <\n>
+ * which is 60 chars per line. Non-printable chars \t, \n, \r and \e are
+ * encoded in C format. Other non-printable chars are encoded "\xHH". Original
+ * lines are respected within the limit of 70 output chars. Lines that are
+ * continuation of a previous truncated line begin with "+" instead of " "
+ * after the offset. The new pointer is returned.
+ */
+int dump_text_line(struct buffer *out, const char *buf, int bsize, int len,
+                   int *line, int ptr)
+{
+	int end;
+	unsigned char c;
+
+	end = out->data + 80;
+	if (end > out->size)
+		return ptr;
+
+	chunk_appendf(out, "  %05d%c ", ptr, (ptr == *line) ? ' ' : '+');
+
+	while (ptr < len && ptr < bsize) {
+		c = buf[ptr];
+		if (isprint((unsigned char)c) && isascii((unsigned char)c) && c != '\\') {
+			if (out->data > end - 2)
+				break;
+			out->area[out->data++] = c;
+		} else if (c == '\t' || c == '\n' || c == '\r' || c == '\e' || c == '\\') {
+			if (out->data > end - 3)
+				break;
+			out->area[out->data++] = '\\';
+			switch (c) {
+			case '\t': c = 't'; break;
+			case '\n': c = 'n'; break;
+			case '\r': c = 'r'; break;
+			case '\e': c = 'e'; break;
+			case '\\': c = '\\'; break;
+			}
+			out->area[out->data++] = c;
+		} else {
+			if (out->data > end - 5)
+				break;
+			out->area[out->data++] = '\\';
+			out->area[out->data++] = 'x';
+			out->area[out->data++] = hextab[(c >> 4) & 0xF];
+			out->area[out->data++] = hextab[c & 0xF];
+		}
+		if (buf[ptr++] == '\n') {
+			/* we had a line break, let's return now */
+			out->area[out->data++] = '\n';
+			*line = ptr;
+			return ptr;
+		}
+	}
+	/* we have an incomplete line, we return it as-is */
+	out->area[out->data++] = '\n';
+	return ptr;
+}
+
+/* displays a <len> long memory block at <buf>, assuming first byte of <buf>
+ * has address <baseaddr>. String <pfx> may be placed as a prefix in front of
+ * each line. It may be NULL if unused. The output is emitted to file <out>.
+ */
+void debug_hexdump(FILE *out, const char *pfx, const char *buf,
+                   unsigned int baseaddr, int len)
+{
+	unsigned int i;
+	int b, j;
+
+	for (i = 0; i < (len + (baseaddr & 15)); i += 16) {
+		b = i - (baseaddr & 15);
+		fprintf(out, "%s%08x: ", pfx ? pfx : "", i + (baseaddr & ~15));
+		for (j = 0; j < 8; j++) {
+			if (b + j >= 0 && b + j < len)
+				fprintf(out, "%02x ", (unsigned char)buf[b + j]);
+			else
+				fprintf(out, "   ");
+		}
+
+		if (b + j >= 0 && b + j < len)
+			fputc('-', out);
+		else
+			fputc(' ', out);
+
+		for (j = 8; j < 16; j++) {
+			if (b + j >= 0 && b + j < len)
+				fprintf(out, " %02x", (unsigned char)buf[b + j]);
+			else
+				fprintf(out, "   ");
+		}
+
+		fprintf(out, "   ");
+		for (j = 0; j < 16; j++) {
+			if (b + j >= 0 && b + j < len) {
+				if (isprint((unsigned char)buf[b + j]))
+					fputc((unsigned char)buf[b + j], out);
+				else
+					fputc('.', out);
+			}
+			else
+				fputc(' ', out);
+		}
+		fputc('\n', out);
+	}
+}
+
+/* Tries to report the executable path name on platforms supporting this. If
+ * not found or not possible, returns NULL.
+ */
+const char *get_exec_path()
+{
+	const char *ret = NULL;
+
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
+	long execfn = getauxval(AT_EXECFN);
+
+	if (execfn && execfn != ENOENT)
+		ret = (const char *)execfn;
+#endif
+	return ret;
+}
+
+#ifdef __ELF__
+/* calls dladdr() or dladdr1() on <addr> and <dli>. If dladdr1 is available,
+ * also returns the symbol size in <size>, otherwise returns 0 there.
+ */
+static int dladdr_and_size(const void *addr, Dl_info *dli, size_t *size)
+{
+	int ret;
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) // most detailed one
+	const ElfW(Sym) *sym;
+
+	ret = dladdr1(addr, dli, (void **)&sym, RTLD_DL_SYMENT);
+	if (ret)
+		*size = sym ? sym->st_size : 0;
+#else
+	ret = dladdr(addr, dli);
+	*size = 0;
+#endif
+	return ret;
+}
+#endif
+
+/* Tries to append to buffer <buf> some indications about the symbol at address
+ * <addr> using the following form:
+ *   lib:+0xoffset              (unresolvable address from lib's base)
+ *   main+0xoffset              (unresolvable address from main (+/-))
+ *   lib:main+0xoffset          (unresolvable lib address from main (+/-))
+ *   name                       (resolved exact exec address)
+ *   lib:name                   (resolved exact lib address)
+ *   name+0xoffset/0xsize       (resolved address within exec symbol)
+ *   lib:name+0xoffset/0xsize   (resolved address within lib symbol)
+ *
+ * The file name (lib or executable) is limited to what lies between the last
+ * '/' and the first following '.'. An optional prefix <pfx> is prepended before
+ * the output if not null. The file is not dumped when it's the same as the one
+ * that contains the "main" symbol, or when __ELF__ is not set.
+ *
+ * The symbol's base address is returned, or NULL when unresolved, in order to
+ * allow the caller to match it against known ones.
+ */
+void *resolve_sym_name(struct buffer *buf, const char *pfx, void *addr)
+{
+	const struct {
+		const void *func;
+		const char *name;
+	} fcts[] = {
+		{ .func = process_stream, .name = "process_stream" },
+		{ .func = task_run_applet, .name = "task_run_applet" },
+		{ .func = si_cs_io_cb, .name = "si_cs_io_cb" },
+		{ .func = conn_fd_handler, .name = "conn_fd_handler" },
+		{ .func = dgram_fd_handler, .name = "dgram_fd_handler" },
+		{ .func = listener_accept, .name = "listener_accept" },
+		{ .func = poller_pipe_io_handler, .name = "poller_pipe_io_handler" },
+		{ .func = mworker_accept_wrapper, .name = "mworker_accept_wrapper" },
+#ifdef USE_LUA
+		{ .func = hlua_process_task, .name = "hlua_process_task" },
+#endif
+#if defined(USE_OPENSSL) && (HA_OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
+		{ .func = ssl_async_fd_free, .name = "ssl_async_fd_free" },
+		{ .func = ssl_async_fd_handler, .name = "ssl_async_fd_handler" },
+#endif
+	};
+
+#ifdef __ELF__
+	Dl_info dli, dli_main;
+	size_t size;
+	const char *fname, *p;
+#endif
+	int i;
+
+	if (pfx)
+		chunk_appendf(buf, "%s", pfx);
+
+	for (i = 0; i < sizeof(fcts) / sizeof(fcts[0]); i++) {
+		if (addr == fcts[i].func) {
+			chunk_appendf(buf, "%s", fcts[i].name);
+			return addr;
+		}
+	}
+
+#ifdef __ELF__
+	/* Now let's try to be smarter */
+	if (!dladdr_and_size(addr, &dli, &size))
+		goto unknown;
+
+	/* 1. prefix the library name if it's not the same object as the one
+	 * that contains the main function. The name is picked between last '/'
+	 * and first following '.'.
+	 */
+	if (!dladdr(main, &dli_main))
+		dli_main.dli_fbase = NULL;
+
+	if (dli_main.dli_fbase != dli.dli_fbase) {
+		fname = dli.dli_fname;
+		p = strrchr(fname, '/');
+		if (p++)
+			fname = p;
+		p = strchr(fname, '.');
+		if (!p)
+			p = fname + strlen(fname);
+
+		chunk_appendf(buf, "%.*s:", (int)(long)(p - fname), fname);
+	}
+
+	/* 2. symbol name */
+	if (dli.dli_sname) {
+		/* known, dump it and return symbol's address (exact or relative) */
+		chunk_appendf(buf, "%s", dli.dli_sname);
+		if (addr != dli.dli_saddr) {
+			chunk_appendf(buf, "+%#lx", (long)(addr - dli.dli_saddr));
+			if (size)
+				chunk_appendf(buf, "/%#lx", (long)size);
+		}
+		return dli.dli_saddr;
+	}
+	else if (dli_main.dli_fbase != dli.dli_fbase) {
+		/* unresolved symbol from a known library, report relative offset */
+		chunk_appendf(buf, "+%#lx", (long)(addr - dli.dli_fbase));
+		return NULL;
+	}
+#endif /* __ELF__ */
+ unknown:
+	/* unresolved symbol from the main file, report relative offset to main */
+	if ((void*)addr < (void*)main)
+		chunk_appendf(buf, "main-%#lx", (long)((void*)main - addr));
+	else
+		chunk_appendf(buf, "main+%#lx", (long)(addr - (void*)main));
+	return NULL;
+}
+
+/*
+ * Allocate an array of unsigned int with <nums> as address from <str> string
+ * made of integer sepereated by dot characters.
+ *
+ * First, initializes the value with <sz> as address to 0 and initializes the
+ * array with <nums> as address to NULL. Then allocates the array with <nums> as
+ * address updating <sz> pointed value to the size of this array.
+ *
+ * Returns 1 if succeeded, 0 if not.
+ */
+int parse_dotted_uints(const char *str, unsigned int **nums, size_t *sz)
+{
+	unsigned int *n;
+	const char *s, *end;
+
+	s = str;
+	*sz = 0;
+	end = str + strlen(str);
+	*nums = n = NULL;
+
+	while (1) {
+		unsigned int r;
+
+		if (s >= end)
+			break;
+
+		r = read_uint(&s, end);
+		/* Expected characters after having read an uint: '\0' or '.',
+		 * if '.', must not be terminal.
+		 */
+		if (*s != '\0'&& (*s++ != '.' || s == end))
+			return 0;
+
+		n = my_realloc2(n, (*sz + 1) * sizeof *n);
+		if (!n)
+			return 0;
+
+		n[(*sz)++] = r;
+	}
+	*nums = n;
+
+	return 1;
+}
+
+
+/* returns the number of bytes needed to encode <v> as a varint. An inline
+ * version exists for use with constants (__varint_bytes()).
+ */
+int varint_bytes(uint64_t v)
+{
+	int len = 1;
+
+	if (v >= 240) {
+		v = (v - 240) >> 4;
+		while (1) {
+			len++;
+			if (v < 128)
+				break;
+			v = (v - 128) >> 7;
+		}
+	}
+	return len;
+}
+
+
+/* Random number generator state, see below */
+static uint64_t ha_random_state[2] ALIGNED(2*sizeof(uint64_t));
+
+/* This is a thread-safe implementation of xoroshiro128** described below:
+ *     http://prng.di.unimi.it/
+ * It features a 2^128 long sequence, returns 64 high-quality bits on each call,
+ * supports fast jumps and passes all common quality tests. It is thread-safe,
+ * uses a double-cas on 64-bit architectures supporting it, and falls back to a
+ * local lock on other ones.
+ */
+uint64_t ha_random64()
+{
+	uint64_t result;
+	uint64_t old[2] ALIGNED(2*sizeof(uint64_t));
+	uint64_t new[2] ALIGNED(2*sizeof(uint64_t));
+
+#if defined(USE_THREAD) && (!defined(HA_CAS_IS_8B) || !defined(HA_HAVE_CAS_DW))
+	static HA_SPINLOCK_T rand_lock;
+
+	HA_SPIN_LOCK(OTHER_LOCK, &rand_lock);
+#endif
+
+	old[0] = ha_random_state[0];
+	old[1] = ha_random_state[1];
+
+#if defined(USE_THREAD) && defined(HA_CAS_IS_8B) && defined(HA_HAVE_CAS_DW)
+	do {
+#endif
+		result = rotl64(old[0] * 5, 7) * 9;
+		new[1] = old[0] ^ old[1];
+		new[0] = rotl64(old[0], 24) ^ new[1] ^ (new[1] << 16); // a, b
+		new[1] = rotl64(new[1], 37); // c
+
+#if defined(USE_THREAD) && defined(HA_CAS_IS_8B) && defined(HA_HAVE_CAS_DW)
+	} while (unlikely(!_HA_ATOMIC_DWCAS(ha_random_state, old, new)));
+#else
+	ha_random_state[0] = new[0];
+	ha_random_state[1] = new[1];
+#if defined(USE_THREAD)
+	HA_SPIN_UNLOCK(OTHER_LOCK, &rand_lock);
+#endif
+#endif
+	return result;
+}
+
+/* seeds the random state using up to <len> bytes from <seed>, starting with
+ * the first non-zero byte.
+ */
+void ha_random_seed(const unsigned char *seed, size_t len)
+{
+	size_t pos;
+
+	/* the seed must not be all zeroes, so we pre-fill it with alternating
+	 * bits and overwrite part of them with the block starting at the first
+	 * non-zero byte from the seed.
+	 */
+	memset(ha_random_state, 0x55, sizeof(ha_random_state));
+
+	for (pos = 0; pos < len; pos++)
+		if (seed[pos] != 0)
+			break;
+
+	if (pos == len)
+		return;
+
+	seed += pos;
+	len -= pos;
+
+	if (len > sizeof(ha_random_state))
+		len = sizeof(ha_random_state);
+
+	memcpy(ha_random_state, seed, len);
+}
+
+/* This causes a jump to (dist * 2^96) places in the pseudo-random sequence,
+ * and is equivalent to calling ha_random64() as many times. It is used to
+ * provide non-overlapping sequences of 2^96 numbers (~7*10^28) to up to 2^32
+ * different generators (i.e. different processes after a fork). The <dist>
+ * argument is the distance to jump to and is used in a loop so it rather not
+ * be too large if the processing time is a concern.
+ *
+ * BEWARE: this function is NOT thread-safe and must not be called during
+ * concurrent accesses to ha_random64().
+ */
+void ha_random_jump96(uint32_t dist)
+{
+	while (dist--) {
+		uint64_t s0 = 0;
+		uint64_t s1 = 0;
+		int b;
+
+		for (b = 0; b < 64; b++) {
+			if ((0xd2a98b26625eee7bULL >> b) & 1) {
+				s0 ^= ha_random_state[0];
+				s1 ^= ha_random_state[1];
+			}
+			ha_random64();
+		}
+
+		for (b = 0; b < 64; b++) {
+			if ((0xdddf9b1090aa7ac1ULL >> b) & 1) {
+				s0 ^= ha_random_state[0];
+				s1 ^= ha_random_state[1];
+			}
+			ha_random64();
+		}
+		ha_random_state[0] = s0;
+		ha_random_state[1] = s1;
+	}
+}
+
+/* Generates an RFC4122 UUID into chunk <output> which must be at least 37
+ * bytes large.
+ */
+void ha_generate_uuid(struct buffer *output)
+{
+	uint32_t rnd[4];
+	uint64_t last;
+
+	last = ha_random64();
+	rnd[0] = last;
+	rnd[1] = last >> 32;
+
+	last = ha_random64();
+	rnd[2] = last;
+	rnd[3] = last >> 32;
+
+	chunk_printf(output, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
+	             rnd[0],
+	             rnd[1] & 0xFFFF,
+	             ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 bits indicate the uuid version
+	             (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits indicate the UUID variant (10),
+	             (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull);
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
