/*
 * Pattern management functions.
 *
 * Copyright 2000-2013 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.
 *
 */

#include <ctype.h>
#include <stdio.h>

#include <common/config.h>
#include <common/standard.h>

#include <types/global.h>
#include <types/pattern.h>

#include <proto/pattern.h>
#include <proto/sample.h>

#include <ebsttree.h>

char *pat_match_names[PAT_MATCH_NUM] = {
	[PAT_MATCH_FOUND] = "found",
	[PAT_MATCH_BOOL]  = "bool",
	[PAT_MATCH_INT]   = "int",
	[PAT_MATCH_IP]    = "ip",
	[PAT_MATCH_BIN]   = "bin",
	[PAT_MATCH_LEN]   = "len",
	[PAT_MATCH_STR]   = "str",
	[PAT_MATCH_BEG]   = "beg",
	[PAT_MATCH_SUB]   = "sub",
	[PAT_MATCH_DIR]   = "dir",
	[PAT_MATCH_DOM]   = "dom",
	[PAT_MATCH_END]   = "end",
	[PAT_MATCH_REG]   = "reg",
};

int (*pat_parse_fcts[PAT_MATCH_NUM])(const char **, struct pattern *, enum pat_usage, int *, char **) = {
	[PAT_MATCH_FOUND] = pat_parse_nothing,
	[PAT_MATCH_BOOL]  = pat_parse_nothing,
	[PAT_MATCH_INT]   = pat_parse_int,
	[PAT_MATCH_IP]    = pat_parse_ip,
	[PAT_MATCH_BIN]   = pat_parse_bin,
	[PAT_MATCH_LEN]   = pat_parse_len,
	[PAT_MATCH_STR]   = pat_parse_str,
	[PAT_MATCH_BEG]   = pat_parse_str,
	[PAT_MATCH_SUB]   = pat_parse_str,
	[PAT_MATCH_DIR]   = pat_parse_str,
	[PAT_MATCH_DOM]   = pat_parse_str,
	[PAT_MATCH_END]   = pat_parse_str,
	[PAT_MATCH_REG]   = pat_parse_reg,
};

enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *) = {
	[PAT_MATCH_FOUND] = NULL,
	[PAT_MATCH_BOOL]  = pat_match_nothing,
	[PAT_MATCH_INT]   = pat_match_int,
	[PAT_MATCH_IP]    = pat_match_ip,
	[PAT_MATCH_BIN]   = pat_match_bin,
	[PAT_MATCH_LEN]   = pat_match_len,
	[PAT_MATCH_STR]   = pat_match_str,
	[PAT_MATCH_BEG]   = pat_match_beg,
	[PAT_MATCH_SUB]   = pat_match_sub,
	[PAT_MATCH_DIR]   = pat_match_dir,
	[PAT_MATCH_DOM]   = pat_match_dom,
	[PAT_MATCH_END]   = pat_match_end,
	[PAT_MATCH_REG]   = pat_match_reg,
};

/* Just used for checking configuration compatibility */
int pat_match_types[PAT_MATCH_NUM] = {
	[PAT_MATCH_FOUND] = SMP_T_UINT,
	[PAT_MATCH_BOOL]  = SMP_T_UINT,
	[PAT_MATCH_INT]   = SMP_T_UINT,
	[PAT_MATCH_IP]    = SMP_T_ADDR,
	[PAT_MATCH_BIN]   = SMP_T_CBIN,
	[PAT_MATCH_LEN]   = SMP_T_CSTR,
	[PAT_MATCH_STR]   = SMP_T_CSTR,
	[PAT_MATCH_BEG]   = SMP_T_CSTR,
	[PAT_MATCH_SUB]   = SMP_T_CSTR,
	[PAT_MATCH_DIR]   = SMP_T_CSTR,
	[PAT_MATCH_DOM]   = SMP_T_CSTR,
	[PAT_MATCH_END]   = SMP_T_CSTR,
	[PAT_MATCH_REG]   = SMP_T_CSTR,
};

/*
 * These functions are exported and may be used by any other component.
 */

/* ignore the current line */
int pat_parse_nothing(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	return 1;
}

/* always return false */
enum pat_match_res pat_match_nothing(struct sample *smp, struct pattern *pattern)
{
	return PAT_NOMATCH;
}


/* NB: For two strings to be identical, it is required that their lengths match */
enum pat_match_res pat_match_str(struct sample *smp, struct pattern *pattern)
{
	int icase;

	if (pattern->len != smp->data.str.len)
		return PAT_NOMATCH;

	icase = pattern->flags & PAT_F_IGNORE_CASE;
	if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0) ||
	    (!icase && strncmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0))
		return PAT_MATCH;
	return PAT_NOMATCH;
}

/* NB: For two binaries buf to be identical, it is required that their lengths match */
enum pat_match_res pat_match_bin(struct sample *smp, struct pattern *pattern)
{
	if (pattern->len != smp->data.str.len)
		return PAT_NOMATCH;

	if (memcmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0)
		return PAT_MATCH;
	return PAT_NOMATCH;
}

/* Lookup a string in the expression's pattern tree. The node is returned if it
 * exists, otherwise NULL.
 */
static void *pat_lookup_str(struct sample *smp, struct pattern_expr *expr)
{
	/* data are stored in a tree */
	struct ebmb_node *node;
	char prev;

	/* we may have to force a trailing zero on the test pattern */
	prev = smp->data.str.str[smp->data.str.len];
	if (prev)
		smp->data.str.str[smp->data.str.len] = '\0';
	node = ebst_lookup(&expr->pattern_tree, smp->data.str.str);
	if (prev)
		smp->data.str.str[smp->data.str.len] = prev;
	return node;
}

/* Executes a regex. It temporarily changes the data to add a trailing zero,
 * and restores the previous character when leaving.
 */
enum pat_match_res pat_match_reg(struct sample *smp, struct pattern *pattern)
{
	if (regex_exec(pattern->ptr.reg, smp->data.str.str, smp->data.str.len) == 0)
		return PAT_MATCH;
	return PAT_NOMATCH;
}

/* Checks that the pattern matches the beginning of the tested string. */
enum pat_match_res pat_match_beg(struct sample *smp, struct pattern *pattern)
{
	int icase;

	if (pattern->len > smp->data.str.len)
		return PAT_NOMATCH;

	icase = pattern->flags & PAT_F_IGNORE_CASE;
	if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0) ||
	    (!icase && strncmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0))
		return PAT_NOMATCH;
	return PAT_MATCH;
}

/* Checks that the pattern matches the end of the tested string. */
enum pat_match_res pat_match_end(struct sample *smp, struct pattern *pattern)
{
	int icase;

	if (pattern->len > smp->data.str.len)
		return PAT_NOMATCH;
	icase = pattern->flags & PAT_F_IGNORE_CASE;
	if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0) ||
	    (!icase && strncmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0))
		return PAT_NOMATCH;
	return PAT_MATCH;
}

/* Checks that the pattern is included inside the tested string.
 * NB: Suboptimal, should be rewritten using a Boyer-Moore method.
 */
enum pat_match_res pat_match_sub(struct sample *smp, struct pattern *pattern)
{
	int icase;
	char *end;
	char *c;

	if (pattern->len > smp->data.str.len)
		return PAT_NOMATCH;

	end = smp->data.str.str + smp->data.str.len - pattern->len;
	icase = pattern->flags & PAT_F_IGNORE_CASE;
	if (icase) {
		for (c = smp->data.str.str; c <= end; c++) {
			if (tolower(*c) != tolower(*pattern->ptr.str))
				continue;
			if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0)
				return PAT_MATCH;
		}
	} else {
		for (c = smp->data.str.str; c <= end; c++) {
			if (*c != *pattern->ptr.str)
				continue;
			if (strncmp(pattern->ptr.str, c, pattern->len) == 0)
				return PAT_MATCH;
		}
	}
	return PAT_NOMATCH;
}

/* Background: Fast way to find a zero byte in a word
 * http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
 * hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
 *
 * To look for 4 different byte values, xor the word with those bytes and
 * then check for zero bytes:
 *
 * v = (((unsigned char)c * 0x1010101U) ^ delimiter)
 * where <delimiter> is the 4 byte values to look for (as an uint)
 * and <c> is the character that is being tested
 */
static inline unsigned int is_delimiter(unsigned char c, unsigned int mask)
{
	mask ^= (c * 0x01010101); /* propagate the char to all 4 bytes */
	return (mask - 0x01010101) & ~mask & 0x80808080U;
}

static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4)
{
	return d1 << 24 | d2 << 16 | d3 << 8 | d4;
}

/* This one is used by other real functions. It checks that the pattern is
 * included inside the tested string, but enclosed between the specified
 * delimiters or at the beginning or end of the string. The delimiters are
 * provided as an unsigned int made by make_4delim() and match up to 4 different
 * delimiters. Delimiters are stripped at the beginning and end of the pattern.
 */
static int match_word(struct sample *smp, struct pattern *pattern, unsigned int delimiters)
{
	int may_match, icase;
	char *c, *end;
	char *ps;
	int pl;

	pl = pattern->len;
	ps = pattern->ptr.str;

	while (pl > 0 && is_delimiter(*ps, delimiters)) {
		pl--;
		ps++;
	}

	while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
		pl--;

	if (pl > smp->data.str.len)
		return PAT_NOMATCH;

	may_match = 1;
	icase = pattern->flags & PAT_F_IGNORE_CASE;
	end = smp->data.str.str + smp->data.str.len - pl;
	for (c = smp->data.str.str; c <= end; c++) {
		if (is_delimiter(*c, delimiters)) {
			may_match = 1;
			continue;
		}

		if (!may_match)
			continue;

		if (icase) {
			if ((tolower(*c) == tolower(*ps)) &&
			    (strncasecmp(ps, c, pl) == 0) &&
			    (c == end || is_delimiter(c[pl], delimiters)))
				return PAT_MATCH;
		} else {
			if ((*c == *ps) &&
			    (strncmp(ps, c, pl) == 0) &&
			    (c == end || is_delimiter(c[pl], delimiters)))
				return PAT_MATCH;
		}
		may_match = 0;
	}
	return PAT_NOMATCH;
}

/* Checks that the pattern is included inside the tested string, but enclosed
 * between the delimiters '?' or '/' or at the beginning or end of the string.
 * Delimiters at the beginning or end of the pattern are ignored.
 */
enum pat_match_res pat_match_dir(struct sample *smp, struct pattern *pattern)
{
	return match_word(smp, pattern, make_4delim('/', '?', '?', '?'));
}

/* Checks that the pattern is included inside the tested string, but enclosed
 * between the delmiters '/', '?', '.' or ":" or at the beginning or end of
 * the string. Delimiters at the beginning or end of the pattern are ignored.
 */
enum pat_match_res pat_match_dom(struct sample *smp, struct pattern *pattern)
{
	return match_word(smp, pattern, make_4delim('/', '?', '.', ':'));
}

/* Checks that the integer in <test> is included between min and max */
enum pat_match_res pat_match_int(struct sample *smp, struct pattern *pattern)
{
	if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.uint) &&
	    (!pattern->val.range.max_set || smp->data.uint <= pattern->val.range.max))
		return PAT_MATCH;
	return PAT_NOMATCH;
}

/* Checks that the length of the pattern in <test> is included between min and max */
enum pat_match_res pat_match_len(struct sample *smp, struct pattern *pattern)
{
	if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.str.len) &&
	    (!pattern->val.range.max_set || smp->data.str.len <= pattern->val.range.max))
		return PAT_MATCH;
	return PAT_NOMATCH;
}

enum pat_match_res pat_match_ip(struct sample *smp, struct pattern *pattern)
{
	unsigned int v4; /* in network byte order */
	struct in6_addr *v6;
	int bits, pos;
	struct in6_addr tmp6;

	if (pattern->type == SMP_T_IPV4) {
		if (smp->type == SMP_T_IPV4) {
			v4 = smp->data.ipv4.s_addr;
		}
		else if (smp->type == SMP_T_IPV6) {
			/* v4 match on a V6 sample. We want to check at least for
			 * the following forms :
			 *   - ::ffff:ip:v4 (ipv4 mapped)
			 *   - ::0000:ip:v4 (old ipv4 mapped)
			 *   - 2002:ip:v4:: (6to4)
			 */
			if (*(uint32_t*)&smp->data.ipv6.s6_addr[0] == 0 &&
			    *(uint32_t*)&smp->data.ipv6.s6_addr[4]  == 0 &&
			    (*(uint32_t*)&smp->data.ipv6.s6_addr[8] == 0 ||
			     *(uint32_t*)&smp->data.ipv6.s6_addr[8] == htonl(0xFFFF))) {
				v4 = *(uint32_t*)&smp->data.ipv6.s6_addr[12];
			}
			else if (*(uint16_t*)&smp->data.ipv6.s6_addr[0] == htons(0x2002)) {
				v4 = htonl((ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[2]) << 16) +
				            ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[4]));
			}
			else
				return PAT_NOMATCH;
		}
		else
			return PAT_NOMATCH;

		if (((v4 ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
			return PAT_MATCH;
		else
			return PAT_NOMATCH;
	}
	else if (pattern->type == SMP_T_IPV6) {
		if (smp->type == SMP_T_IPV4) {
			/* Convert the IPv4 sample address to IPv4 with the
			 * mapping method using the ::ffff: prefix.
			 */
			memset(&tmp6, 0, 10);
			*(uint16_t*)&tmp6.s6_addr[10] = htons(0xffff);
			*(uint32_t*)&tmp6.s6_addr[12] = smp->data.ipv4.s_addr;
			v6 = &tmp6;
		}
		else if (smp->type == SMP_T_IPV6) {
			v6 = &smp->data.ipv6;
		}
		else {
			return PAT_NOMATCH;
		}

		bits = pattern->val.ipv6.mask;
		for (pos = 0; bits > 0; pos += 4, bits -= 32) {
			v4 = *(uint32_t*)&v6->s6_addr[pos] ^ *(uint32_t*)&pattern->val.ipv6.addr.s6_addr[pos];
			if (bits < 32)
				v4 &= htonl((~0U) << (32-bits));
			if (v4)
				return PAT_NOMATCH;
		}
		return PAT_MATCH;
	}
	return PAT_NOMATCH;
}

/* Lookup an IPv4 address in the expression's pattern tree using the longest
 * match method. The node is returned if it exists, otherwise NULL.
 */
static void *pat_lookup_ip(struct sample *smp, struct pattern_expr *expr)
{
	struct in_addr *s;

	if (smp->type != SMP_T_IPV4)
		return PAT_NOMATCH;

	s = &smp->data.ipv4;
	return ebmb_lookup_longest(&expr->pattern_tree, &s->s_addr);
}

/* Parse a string. It is allocated and duplicated. */
int pat_parse_str(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	pattern->type = SMP_T_CSTR;
	pattern->expect_type = SMP_T_CSTR;
	if (usage == PAT_U_COMPILE) {
		pattern->ptr.str = strdup(*text);
		if (!pattern->ptr.str) {
			memprintf(err, "out of memory while loading string pattern");
			return 0;
		}
	}
	else
		pattern->ptr.str = (char *)*text;
	pattern->len = strlen(*text);
	return 1;
}

/* Parse a binary written in hexa. It is allocated. */
int pat_parse_bin(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	struct chunk *trash;

	pattern->type = SMP_T_CBIN;
	pattern->expect_type = SMP_T_CBIN;

	if (usage == PAT_U_COMPILE)
		return parse_binary(*text, &pattern->ptr.str, &pattern->len, err);

	trash = get_trash_chunk();
	pattern->len = trash->size;
	pattern->ptr.str = trash->str;
	return parse_binary(*text, &pattern->ptr.str, &pattern->len, err);
}

/* Parse and concatenate all further strings into one. */
int
pat_parse_strcat(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	int len = 0, i;
	char *s;
	struct chunk *trash;

	for (i = 0; *text[i]; i++)
		len += strlen(text[i])+1;

	pattern->type = SMP_T_CSTR;
	if (usage == PAT_U_COMPILE) {
		pattern->ptr.str = calloc(1, len);
		if (!pattern->ptr.str) {
			memprintf(err, "out of memory while loading pattern");
			return 0;
		}
	}
	else {
		trash = get_trash_chunk();
		if (trash->size < len) {
			memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
			          len, trash->size);
			return 0;
		}
		pattern->ptr.str = trash->str;
	}

	s = pattern->ptr.str;

	for (i = 0; *text[i]; i++)
		s += sprintf(s, i?" %s":"%s", text[i]);

	pattern->len = len;

	return i;
}

/* Free data allocated by pat_parse_reg */
static void pat_free_reg(void *ptr)
{
	regex_free(ptr);
}

/* Parse a regex. It is allocated. */
int pat_parse_reg(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	struct my_regex *preg;
	struct chunk *trash;

	if (usage == PAT_U_COMPILE) {

		preg = calloc(1, sizeof(*preg));
		if (!preg) {
			memprintf(err, "out of memory while loading pattern");
			return 0;
		}

		if (!regex_comp(*text, preg, !(pattern->flags & PAT_F_IGNORE_CASE), 0, err)) {
			free(preg);
			return 0;
		}
		pattern->freeptrbuf = &pat_free_reg;
	}
	else {

		trash = get_trash_chunk();
		if (trash->size < sizeof(*preg)) {
			memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
			          (int)sizeof(*preg), trash->size);
			return 0;
		}

		preg = (struct my_regex *)trash->str;
		preg->regstr = (char *)*text;
		pattern->freeptrbuf = NULL;
	}

	pattern->ptr.reg = preg;
	pattern->expect_type = SMP_T_CSTR;
	return 1;
}

/* Parse a range of positive integers delimited by either ':' or '-'. If only
 * one integer is read, it is set as both min and max. An operator may be
 * specified as the prefix, among this list of 5 :
 *
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
 *
 * The default operator is "eq". It supports range matching. Ranges are
 * rejected for other operators. The operator may be changed at any time.
 * The operator is stored in the 'opaque' argument.
 *
 * If err is non-NULL, an error message will be returned there on errors and
 * the caller will have to free it.
 *
 */
int pat_parse_int(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	signed long long i;
	unsigned int j, last, skip = 0;
	const char *ptr = *text;

	pattern->type = SMP_T_UINT;
	pattern->expect_type = SMP_T_UINT;

	while (!isdigit((unsigned char)*ptr)) {
		switch (get_std_op(ptr)) {
		case STD_OP_EQ: *opaque = 0; break;
		case STD_OP_GT: *opaque = 1; break;
		case STD_OP_GE: *opaque = 2; break;
		case STD_OP_LT: *opaque = 3; break;
		case STD_OP_LE: *opaque = 4; break;
		default:
			memprintf(err, "'%s' is neither a number nor a supported operator", ptr);
			return 0;
		}

		skip++;
		ptr = text[skip];
	}

	last = i = 0;
	while (1) {
                j = *ptr++;
		if ((j == '-' || j == ':') && !last) {
			last++;
			pattern->val.range.min = i;
			i = 0;
			continue;
		}
		j -= '0';
                if (j > 9)
			// also catches the terminating zero
                        break;
                i *= 10;
                i += j;
        }

	if (last && *opaque >= 1 && *opaque <= 4) {
		/* having a range with a min or a max is absurd */
		memprintf(err, "integer range '%s' specified with a comparison operator", text[skip]);
		return 0;
	}

	if (!last)
		pattern->val.range.min = i;
	pattern->val.range.max = i;

	switch (*opaque) {
	case 0: /* eq */
		pattern->val.range.min_set = 1;
		pattern->val.range.max_set = 1;
		break;
	case 1: /* gt */
		pattern->val.range.min++; /* gt = ge + 1 */
	case 2: /* ge */
		pattern->val.range.min_set = 1;
		pattern->val.range.max_set = 0;
		break;
	case 3: /* lt */
		pattern->val.range.max--; /* lt = le - 1 */
	case 4: /* le */
		pattern->val.range.min_set = 0;
		pattern->val.range.max_set = 1;
		break;
	}
	return skip + 1;
}

int pat_parse_len(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	int ret;

	ret = pat_parse_int(text, pattern, usage, opaque, err);
	pattern->expect_type = SMP_T_CSTR;
	return ret;
}

/* Parse a range of positive 2-component versions delimited by either ':' or
 * '-'. The version consists in a major and a minor, both of which must be
 * smaller than 65536, because internally they will be represented as a 32-bit
 * integer.
 * If only one version is read, it is set as both min and max. Just like for
 * pure integers, an operator may be specified as the prefix, among this list
 * of 5 :
 *
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
 *
 * The default operator is "eq". It supports range matching. Ranges are
 * rejected for other operators. The operator may be changed at any time.
 * The operator is stored in the 'opaque' argument. This allows constructs
 * such as the following one :
 *
 *    acl obsolete_ssl    ssl_req_proto lt 3
 *    acl unsupported_ssl ssl_req_proto gt 3.1
 *    acl valid_ssl       ssl_req_proto 3.0-3.1
 *
 */
int pat_parse_dotted_ver(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	signed long long i;
	unsigned int j, last, skip = 0;
	const char *ptr = *text;


	while (!isdigit((unsigned char)*ptr)) {
		switch (get_std_op(ptr)) {
		case STD_OP_EQ: *opaque = 0; break;
		case STD_OP_GT: *opaque = 1; break;
		case STD_OP_GE: *opaque = 2; break;
		case STD_OP_LT: *opaque = 3; break;
		case STD_OP_LE: *opaque = 4; break;
		default:
			memprintf(err, "'%s' is neither a number nor a supported operator", ptr);
			return 0;
		}

		skip++;
		ptr = text[skip];
	}

	last = i = 0;
	while (1) {
                j = *ptr++;
		if (j == '.') {
			/* minor part */
			if (i >= 65536)
				return 0;
			i <<= 16;
			continue;
		}
		if ((j == '-' || j == ':') && !last) {
			last++;
			if (i < 65536)
				i <<= 16;
			pattern->val.range.min = i;
			i = 0;
			continue;
		}
		j -= '0';
                if (j > 9)
			// also catches the terminating zero
                        break;
                i = (i & 0xFFFF0000) + (i & 0xFFFF) * 10;
                i += j;
        }

	/* if we only got a major version, let's shift it now */
	if (i < 65536)
		i <<= 16;

	if (last && *opaque >= 1 && *opaque <= 4) {
		/* having a range with a min or a max is absurd */
		memprintf(err, "version range '%s' specified with a comparison operator", text[skip]);
		return 0;
	}

	pattern->expect_type = SMP_T_CSTR;

	if (!last)
		pattern->val.range.min = i;
	pattern->val.range.max = i;

	switch (*opaque) {
	case 0: /* eq */
		pattern->val.range.min_set = 1;
		pattern->val.range.max_set = 1;
		break;
	case 1: /* gt */
		pattern->val.range.min++; /* gt = ge + 1 */
	case 2: /* ge */
		pattern->val.range.min_set = 1;
		pattern->val.range.max_set = 0;
		break;
	case 3: /* lt */
		pattern->val.range.max--; /* lt = le - 1 */
	case 4: /* le */
		pattern->val.range.min_set = 0;
		pattern->val.range.max_set = 1;
		break;
	}
	return skip + 1;
}

/* Parse an IP address and an optional mask in the form addr[/mask].
 * The addr may either be an IPv4 address or a hostname. The mask
 * may either be a dotted mask or a number of bits. Returns 1 if OK,
 * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
 */
int pat_parse_ip(const char **text, struct pattern *pattern, enum pat_usage usage, int *opaque, char **err)
{
	pattern->expect_type = SMP_T_ADDR;
	if (str2net(*text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
		pattern->type = SMP_T_IPV4;
		return 1;
	}
	else if (str62net(*text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
		/* no tree support right now */
		pattern->type = SMP_T_IPV6;
		return 1;
	}
	else {
		memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", *text);
		return 0;
	}
}

/* NB: does nothing if <pat> is NULL */
void pattern_free(struct pattern *pat)
{
	if (!pat)
		return;

	if (pat->ptr.ptr) {
		if (pat->freeptrbuf)
			pat->freeptrbuf(pat->ptr.ptr);

		free(pat->ptr.ptr);
	}

	free(pat);
}

void free_pattern_list(struct list *head)
{
	struct pattern *pat, *tmp;
	list_for_each_entry_safe(pat, tmp, head, list)
		pattern_free(pat);
}

void free_pattern_tree(struct eb_root *root)
{
	struct eb_node *node, *next;
	struct pat_idx_elt *elt;

	node = eb_first(root);
	while (node) {
		next = eb_next(node);
		eb_delete(node);
		elt = container_of(node, struct pat_idx_elt, node);
		free(elt);
		node = next;
	}
}

void pattern_prune_expr(struct pattern_expr *expr)
{
	free_pattern_list(&expr->patterns);
	free_pattern_tree(&expr->pattern_tree);
	LIST_INIT(&expr->patterns);
}

void pattern_init_expr(struct pattern_expr *expr)
{
	LIST_INIT(&expr->patterns);
	expr->pattern_tree = EB_ROOT_UNIQUE;
}

/* return 1 if the process is ok
 * return -1 if the parser fail. The err message is filled.
 * return -2 if out of memory
 */
int pattern_register(struct pattern_expr *expr, const char **args,
                         struct sample_storage *smp,
                         struct pattern **pattern,
                         int patflags, char **err)
{
	int opaque = 0;
	unsigned int mask = 0;
	struct pat_idx_elt *node;
	int len;
	int ret;

	/* eat args */
	while (**args) {

		/* we keep the previous pattern along iterations as long as it's not used */
		if (!*pattern)
			*pattern = (struct pattern *)malloc(sizeof(**pattern));
		if (!*pattern) {
			memprintf(err, "out of memory while loading pattern");
			return 0;
		}

		memset(*pattern, 0, sizeof(**pattern));
		(*pattern)->flags = patflags;

		ret = expr->parse(args, *pattern, PAT_U_COMPILE, &opaque, err);
		if (!ret)
			return 0;

		/* each parser return the number of args eated */
		args += ret;

		/*
		 *
		 * SMP_T_CSTR tree indexation
		 *
		 * The match "pat_match_str()" can use tree.
		 *
		 */
		if (expr->match == pat_match_str) {

			/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
			if ((*pattern)->flags & PAT_F_IGNORE_CASE)
				goto just_chain_the_pattern;

			/* Process the key len */
			len = strlen((*pattern)->ptr.str) + 1;

			/* node memory allocation */
			node = calloc(1, sizeof(*node) + len);
			if (!node) {
				memprintf(err, "out of memory while loading pattern");
				return 0;
			}

			/* copy the pointer to sample associated to this node */
			node->smp = smp;

			/* copy the string */
			memcpy(node->node.key, (*pattern)->ptr.str, len);

			/* the "map_parser_str()" function always duplicate string information */
			free((*pattern)->ptr.str);

			/* we pre-set the data pointer to the tree's head so that functions
			 * which are able to insert in a tree know where to do that.
			 *
			 * because "val" is an "union", the previous data are crushed.
			 */
			(*pattern)->flags |= PAT_F_TREE;
			(*pattern)->val.tree = &expr->pattern_tree;

			/* index the new node */
			if (ebst_insert((*pattern)->val.tree, &node->node) != &node->node)
				free(node); /* was a duplicate */
		}

		/*
		 *
		 * SMP_T_IPV4 tree indexation
		 *
		 * The match "pat_match_ip()" can use tree.
		 *
		 */
		else if (expr->match == pat_match_ip) {

			/* Only IPv4 can be indexed */
			if ((*pattern)->type != SMP_T_IPV4)
				goto just_chain_the_pattern;

			/* in IPv4 case, check if the mask is contiguous so that we can
			 * insert the network into the tree. A continuous mask has only
			 * ones on the left. This means that this mask + its lower bit
			 * added once again is null.
			 */
			mask = ntohl((*pattern)->val.ipv4.mask.s_addr);
			if (mask + (mask & -mask) != 0)
				goto just_chain_the_pattern;
			mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */

			/* node memory allocation */
			node = calloc(1, sizeof(*node) + 4);
			if (!node) {
				memprintf(err, "out of memory while loading pattern");
				return 0;
			}

			/* copy the pointer to sample associated to this node */
			node->smp = smp;

			/* FIXME: insert <addr>/<mask> into the tree here */
			memcpy(node->node.key, &(*pattern)->val.ipv4.addr, 4); /* network byte order */

			/* we pre-set the data pointer to the tree's head so that functions
			 * which are able to insert in a tree know where to do that.
			 *
			 * because "val" is an "union", the previous data are crushed.
			 */
			(*pattern)->flags |= PAT_F_TREE;
			(*pattern)->val.tree = &expr->pattern_tree;

			/* Index the new node
			 * FIXME: insert <addr>/<mask> into the tree here
			 */
			node->node.node.pfx = mask;
			if (ebmb_insert_prefix((*pattern)->val.tree, &node->node, 4) != &node->node)
				free(node); /* was a duplicate */
		}

		/*
		 *
		 * if the parser did not feed the tree, let's chain the pattern to the list
		 *
		 */
		else {

just_chain_the_pattern:

			LIST_ADDQ(&expr->patterns, &(*pattern)->list);

			/* copy the pointer to sample associated to this node */
			(*pattern)->smp = smp;

			/* get a new one */
			*pattern = NULL;
		}
	}

	return 1;
}

/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
 * be returned there on errors and the caller will have to free it.
 */
int pattern_read_from_file(struct pattern_expr *expr,
                                const char *filename, int patflags,
                                char **err)
{
	FILE *file;
	char *c;
	char *arg;
	struct pattern *pattern;
	int ret = 0;
	int line = 0;
	int code;
	const char *args[2];

	file = fopen(filename, "r");
	if (!file) {
		memprintf(err, "failed to open pattern file <%s>", filename);
		return 0;
	}

	/* now parse all patterns. The file may contain only one pattern per
	 * line. If the line contains spaces, they will be part of the pattern.
	 * The pattern stops at the first CR, LF or EOF encountered.
	 */
	pattern = NULL;
	while (fgets(trash.str, trash.size, file) != NULL) {
		line++;
		c = trash.str;

		/* ignore lines beginning with a dash */
		if (*c == '#')
			continue;

		/* strip leading spaces and tabs */
		while (*c == ' ' || *c == '\t')
			c++;


		arg = c;
		while (*c && *c != '\n' && *c != '\r')
			c++;
		*c = 0;

		/* empty lines are ignored too */
		if (c == arg)
			continue;

		args[0] = arg;
		args[1] = "";

		code = pattern_register(expr, args, NULL, &pattern, patflags, err);
		if (code == -2) {
			memprintf(err, "out of memory when loading patterns from file <%s>", filename);
			goto out_close;
		}
		else if (code < 0) {
			memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
			goto out_free_pattern;
		}
	}

	ret = 1; /* success */

 out_free_pattern:
	pattern_free(pattern);
 out_close:
	fclose(file);
	return ret;
}

/* This function matches a sample <smp> against a set of patterns presented in
 * pattern expression <expr>. Upon success, if <sample> is not NULL, it is fed
 * with the pointer associated with the matching pattern. This function returns
 * PAT_NOMATCH or PAT_MATCH.
 */
enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *smp,
                                      struct sample_storage **sample)
{
	enum pat_match_res pat_res = PAT_NOMATCH;
	struct pattern *pattern;
	struct ebmb_node *node = NULL;
	struct pat_idx_elt *elt;

	if (expr->match == pat_match_nothing) {
		if (smp->data.uint)
			pat_res |= PAT_MATCH;
		else
			pat_res |= PAT_NOMATCH;
	}
	else if (!expr->match) {
		/* just check for existence */
		pat_res |= PAT_MATCH;
	}
	else {
		if (!eb_is_empty(&expr->pattern_tree)) {
			/* a tree is present, let's check what type it is */
			if (expr->match == pat_match_str) {
				if (sample_convert(smp, SMP_T_STR))
					node = pat_lookup_str(smp, expr);
			}
			else if (expr->match == pat_match_ip) {
				if (sample_convert(smp, SMP_T_IPV4))
					node = pat_lookup_ip(smp, expr);
			}
			if (node) {
				pat_res |= PAT_MATCH;
				elt = ebmb_entry(node, struct pat_idx_elt, node);
				if (sample)
					*sample = elt->smp;
			}
		}

		/* call the match() function for all tests on this value */
		list_for_each_entry(pattern, &expr->patterns, list) {
			if (pat_res == PAT_MATCH)
				break;
			if (sample_convert(smp, pattern->expect_type))
				pat_res |= expr->match(smp, pattern);
			if (sample)
				*sample = pattern->smp;
		}
	}

	return pat_res;
}

