REORG: acl/pattern: extract pattern matching from the acl file and create pattern.c

This patch just moves code without any change.

The ACL are just the association between sample and pattern. The pattern
contains the match method and the parse method. These two things are
different. This patch cleans the code by splitting it.
diff --git a/include/proto/acl.h b/include/proto/acl.h
index 5e2e9ee..e9add28 100644
--- a/include/proto/acl.h
+++ b/include/proto/acl.h
@@ -112,21 +112,6 @@
  */
 int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, char const **kw);
 
-/* parse the <text> with <expr> compliant parser. <pattern> is a context for
- * the current parsed acl. It must initialized at NULL:
- *
- *    struct acl_pattern *pattern = NULL
- *    acl_register_pattern(..., &pattern, ...);
- *
- * patflag are a combination of 'ACL_PAT_F_*' flags pattern compatible. see
- * <types/acl.h>.
- *
- * The function returns 1 if the processing is ok, return -1 if the parser
- * fails, with <err> message filled. It returns -2 in "out of memory"
- * error case.
- */
-int acl_register_pattern(struct acl_expr *expr, char *text, struct sample_storage *smp, struct acl_pattern **pattern, int patflags, char **err);
-
 /*
  * Find targets for userlist and groups in acl. Function returns the number
  * of errors or OK if everything is fine.
@@ -138,13 +123,6 @@
  */
 struct acl *find_acl_by_name(const char *name, struct list *head);
 
-/* This function execute the match part of the acl. It's applying
- * acl <expr> on sample <smp>. <sample> is filled only if the pointer
- * is not NULL. The function return ACL_PAT_FAIL, ACL_PAT_MISS or
- * ACL_PAT_PASS
- */
-inline int acl_exec_match(struct acl_expr *expr, struct sample *smp, struct sample_storage **sample);
-
 /*
  * Registers the ACL keyword list <kwl> as a list of valid keywords for next
  * parsing sessions.
@@ -161,90 +139,6 @@
  */
 int init_acl();
 
-
-/*
- *
- * The following functions are general purpose ACL matching functions.
- *
- */
-
-
-/* ignore the current line */
-int acl_parse_nothing(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* NB: For two strings to be identical, it is required that their lengths match */
-int acl_match_str(struct sample *smp, struct acl_pattern *pattern);
-
-/* NB: For two binary buffers to be identical, it is required that their lengths match */
-int acl_match_bin(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the length of the pattern in <test> is included between min and max */
-int acl_match_len(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the integer in <test> is included between min and max */
-int acl_match_int(struct sample *smp, struct acl_pattern *pattern);
-
-/* Parse an integer. It is put both in min and max. */
-int acl_parse_int(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse an version. It is put both in min and max. */
-int acl_parse_dotted_ver(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse a range of integers delimited by either ':' or '-'. If only one
- * integer is read, it is set as both min and max.
- */
-int acl_parse_range(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse a string. It is allocated and duplicated. */
-int acl_parse_str(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse a hexa binary definition. It is allocated and duplicated. */
-int acl_parse_bin(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse and concatenate strings into one. It is allocated and duplicated. */
-int acl_parse_strcat(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* Parse a regex. It is allocated. */
-int acl_parse_reg(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* 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.
- */
-int acl_parse_ip(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
-
-/* always return false */
-int acl_match_nothing(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the pattern matches the end of the tested string. */
-int acl_match_end(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the pattern matches the beginning of the tested string. */
-int acl_match_beg(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the pattern is included inside the tested string. */
-int acl_match_sub(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the pattern is included inside the tested string, but enclosed
- * between slashes or at the beginning or end of the string. Slashes at the
- * beginning or end of the pattern are ignored.
- */
-int acl_match_dir(struct sample *smp, struct acl_pattern *pattern);
-
-/* Checks that the pattern is included inside the tested string, but enclosed
- * between dots or at the beginning or end of the string. Dots at the beginning
- * or end of the pattern are ignored.
- */
-int acl_match_dom(struct sample *smp, struct acl_pattern *pattern);
-
-/* Check that the IPv4 address in <test> matches the IP/mask in pattern */
-int acl_match_ip(struct sample *smp, struct acl_pattern *pattern);
-
-/* Executes a regex. It temporarily changes the data to add a trailing zero,
- * and restores the previous character when leaving.
- */
-int acl_match_reg(struct sample *smp, struct acl_pattern *pattern);
 
 #endif /* _PROTO_ACL_H */
 
diff --git a/include/proto/pattern.h b/include/proto/pattern.h
new file mode 100644
index 0000000..9898eb3
--- /dev/null
+++ b/include/proto/pattern.h
@@ -0,0 +1,136 @@
+/*
+ * include/proto/pattern.h
+ * This file provides structures and types for pattern matching.
+ *
+ * Copyright (C) 2000-2013 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _PROTO_PATTERN_H
+#define _PROTO_PATTERN_H
+
+/* parse the <text> with <expr> compliant parser. <pattern> is a context for
+ * the current parsed acl. It must initialized at NULL:
+ *
+ *    struct acl_pattern *pattern = NULL
+ *    acl_register_pattern(..., &pattern, ...);
+ *
+ * patflag are a combination of 'ACL_PAT_F_*' flags pattern compatible. see
+ * <types/acl.h>.
+ *
+ * The function returns 1 if the processing is ok, return -1 if the parser
+ * fails, with <err> message filled. It returns -2 in "out of memory"
+ * error case.
+ */
+int acl_register_pattern(struct acl_expr *expr, char *text, struct sample_storage *smp, struct acl_pattern **pattern, int patflags, char **err);
+
+/* This function executes a pattern match on a sample. It applies pattern <expr>
+ * to sample <smp>. If <sample> is not NULL, a pointer to an optional sample
+ * associated to the matching patterned will be put there. The function returns
+ * ACL_PAT_FAIL, ACL_PAT_MISS or ACL_PAT_PASS.
+ */
+inline int acl_exec_match(struct acl_expr *expr, struct sample *smp, struct sample_storage **sample);
+
+/*
+ *
+ * The following functions are general purpose pattern matching functions.
+ *
+ */
+
+
+/* ignore the current line */
+int acl_parse_nothing(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* NB: For two strings to be identical, it is required that their lengths match */
+int acl_match_str(struct sample *smp, struct acl_pattern *pattern);
+
+/* NB: For two binary buffers to be identical, it is required that their lengths match */
+int acl_match_bin(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the length of the pattern in <test> is included between min and max */
+int acl_match_len(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the integer in <test> is included between min and max */
+int acl_match_int(struct sample *smp, struct acl_pattern *pattern);
+
+/* Parse an integer. It is put both in min and max. */
+int acl_parse_int(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse an version. It is put both in min and max. */
+int acl_parse_dotted_ver(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse a range of integers delimited by either ':' or '-'. If only one
+ * integer is read, it is set as both min and max.
+ */
+int acl_parse_range(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse a string. It is allocated and duplicated. */
+int acl_parse_str(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse a hexa binary definition. It is allocated and duplicated. */
+int acl_parse_bin(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse and concatenate strings into one. It is allocated and duplicated. */
+int acl_parse_strcat(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* Parse a regex. It is allocated. */
+int acl_parse_reg(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* 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.
+ */
+int acl_parse_ip(const char **text, struct acl_pattern *pattern, struct sample_storage *smp, int *opaque, char **err);
+
+/* always return false */
+int acl_match_nothing(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the pattern matches the end of the tested string. */
+int acl_match_end(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the pattern matches the beginning of the tested string. */
+int acl_match_beg(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the pattern is included inside the tested string. */
+int acl_match_sub(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the pattern is included inside the tested string, but enclosed
+ * between slashes or at the beginning or end of the string. Slashes at the
+ * beginning or end of the pattern are ignored.
+ */
+int acl_match_dir(struct sample *smp, struct acl_pattern *pattern);
+
+/* Checks that the pattern is included inside the tested string, but enclosed
+ * between dots or at the beginning or end of the string. Dots at the beginning
+ * or end of the pattern are ignored.
+ */
+int acl_match_dom(struct sample *smp, struct acl_pattern *pattern);
+
+/* Check that the IPv4 address in <test> matches the IP/mask in pattern */
+int acl_match_ip(struct sample *smp, struct acl_pattern *pattern);
+
+/* Executes a regex. It temporarily changes the data to add a trailing zero,
+ * and restores the previous character when leaving.
+ */
+int acl_match_reg(struct sample *smp, struct acl_pattern *pattern);
+
+int acl_read_patterns_from_file(struct acl_expr *expr, const char *filename, int patflags, char **err);
+void free_pattern(struct acl_pattern *pat);
+void free_pattern_list(struct list *head);
+void free_pattern_tree(struct eb_root *root);
+
+#endif
diff --git a/include/types/acl.h b/include/types/acl.h
index 322e74b..e479f9b 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -28,8 +28,8 @@
 
 #include <types/arg.h>
 #include <types/auth.h>
+#include <types/pattern.h>
 #include <types/proxy.h>
-#include <types/sample.h>
 #include <types/server.h>
 #include <types/session.h>
 
@@ -55,12 +55,6 @@
  *
  */
 
-enum {
-	ACL_PAT_FAIL = 0,           /* test failed */
-	ACL_PAT_MISS = 1,           /* test may pass with more info */
-	ACL_PAT_PASS = 3,           /* test passed */
-};
-
 /* Condition polarity. It makes it easier for any option to choose between
  * IF/UNLESS if it can store that information within the condition itself.
  * Those should be interpreted as "IF/UNLESS result == PASS".
@@ -71,90 +65,6 @@
 	ACL_COND_UNLESS,	/* negative condition (after 'unless') */
 };
 
-/* possible flags for expressions or patterns */
-enum {
-	ACL_PAT_F_IGNORE_CASE = 1 << 0,       /* ignore case */
-	ACL_PAT_F_FROM_FILE   = 1 << 1,       /* pattern comes from a file */
-	ACL_PAT_F_TREE_OK     = 1 << 2,       /* the pattern parser is allowed to build a tree */
-	ACL_PAT_F_TREE        = 1 << 3,       /* some patterns are arranged in a tree */
-};
-
-/* ACL match methods */
-enum {
-	ACL_MATCH_FOUND, /* just ensure that fetch found the sample */
-	ACL_MATCH_BOOL,  /* match fetch's integer value as boolean */
-	ACL_MATCH_INT,   /* unsigned integer (int) */
-	ACL_MATCH_IP,    /* IPv4/IPv6 address (IP) */
-	ACL_MATCH_BIN,   /* hex string (bin) */
-	ACL_MATCH_LEN,   /* string length (str -> int) */
-	ACL_MATCH_STR,   /* exact string match (str) */
-	ACL_MATCH_BEG,   /* beginning of string (str) */
-	ACL_MATCH_SUB,   /* substring (str) */
-	ACL_MATCH_DIR,   /* directory-like sub-string (str) */
-	ACL_MATCH_DOM,   /* domain-like sub-string (str) */
-	ACL_MATCH_END,   /* end of string (str) */
-	ACL_MATCH_REG,   /* regex (str -> reg) */
-	/* keep this one last */
-	ACL_MATCH_NUM
-};
-
-/* How to store a time range and the valid days in 29 bits */
-struct acl_time {
-	int dow:7;              /* 1 bit per day of week: 0-6 */
-	int h1:5, m1:6;         /* 0..24:0..60. Use 0:0 for all day. */
-	int h2:5, m2:6;         /* 0..24:0..60. Use 24:0 for all day. */
-};
-
-/* This contain each tree indexed entry. This struct permit to associate
- * "sample" with a tree entry. It is used with maps.
- */
-struct acl_idx_elt {
-	struct sample_storage *smp;
-	struct ebmb_node node;
-};
-
-/* This describes one ACL pattern, which might be a single value or a tree of
- * values. All patterns for a single ACL expression are linked together. Some
- * of them might have a type (eg: IP). Right now, the types are shared with
- * the samples, though it is possible that in the future this will change to
- * accommodate for other types (eg: meth, regex). Unsigned and constant types
- * are preferred when there is a doubt.
- */
-struct acl_pattern {
-	struct list list;                       /* chaining */
-	int type;                               /* type of the ACL pattern (SMP_T_*) */
-	union {
-		int i;                          /* integer value */
-		struct {
-			signed long long min, max;
-			int min_set :1;
-			int max_set :1;
-		} range; /* integer range */
-		struct {
-			struct in_addr addr;
-			struct in_addr mask;
-		} ipv4;                         /* IPv4 address */
-		struct {
-			struct in6_addr addr;
-			unsigned char mask;     /* number of bits */
-		} ipv6;                         /* IPv6 address/mask */
-		struct acl_time time;           /* valid hours and days */
-		unsigned int group_mask;
-		struct eb_root *tree;           /* tree storing all values if any */
-	} val;                                  /* direct value */
-	union {
-		void *ptr;              /* any data */
-		char *str;              /* any string  */
-		regex *reg;             /* a compiled regex */
-	} ptr;                          /* indirect values, allocated */
-	void(*freeptrbuf)(void *ptr);	/* a destructor able to free objects from the ptr */
-	int len;                        /* data length when required  */
-	int flags;                      /* expr or pattern flags. */
-	struct sample_storage *smp;     /* used to store a pointer to sample value associated
-	                                   with the match. It is used with maps */
-
-};
-
 /* some dummy declarations to silent the compiler */
 struct proxy;
 struct session;
@@ -242,10 +152,6 @@
 	int line;                   /* line in the config file where the condition is declared */
 };
 
-extern char *acl_match_names[ACL_MATCH_NUM];
-extern int (*acl_parse_fcts[ACL_MATCH_NUM])(const char **, struct acl_pattern *, struct sample_storage *, int *, char **);
-extern int (*acl_match_fcts[ACL_MATCH_NUM])(struct sample *, struct acl_pattern *);
-
 #endif /* _TYPES_ACL_H */
 
 /*
diff --git a/include/types/pattern.h b/include/types/pattern.h
new file mode 100644
index 0000000..68ed462
--- /dev/null
+++ b/include/types/pattern.h
@@ -0,0 +1,128 @@
+/*
+ * include/types/pattern.h
+ * This file provides structures and types for ACLs.
+ *
+ * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TYPES_PATTERN_H
+#define _TYPES_PATTERN_H
+
+#include <common/compat.h>
+#include <common/config.h>
+#include <common/mini-clist.h>
+#include <common/regex.h>
+
+#include <types/sample.h>
+
+#include <ebmbtree.h>
+
+enum {
+	ACL_PAT_FAIL = 0,           /* test failed */
+	ACL_PAT_MISS = 1,           /* test may pass with more info */
+	ACL_PAT_PASS = 3,           /* test passed */
+};
+
+/* possible flags for expressions or patterns */
+enum {
+	ACL_PAT_F_IGNORE_CASE = 1 << 0,       /* ignore case */
+	ACL_PAT_F_FROM_FILE   = 1 << 1,       /* pattern comes from a file */
+	ACL_PAT_F_TREE_OK     = 1 << 2,       /* the pattern parser is allowed to build a tree */
+	ACL_PAT_F_TREE        = 1 << 3,       /* some patterns are arranged in a tree */
+};
+
+/* ACL match methods */
+enum {
+	ACL_MATCH_FOUND, /* just ensure that fetch found the sample */
+	ACL_MATCH_BOOL,  /* match fetch's integer value as boolean */
+	ACL_MATCH_INT,   /* unsigned integer (int) */
+	ACL_MATCH_IP,    /* IPv4/IPv6 address (IP) */
+	ACL_MATCH_BIN,   /* hex string (bin) */
+	ACL_MATCH_LEN,   /* string length (str -> int) */
+	ACL_MATCH_STR,   /* exact string match (str) */
+	ACL_MATCH_BEG,   /* beginning of string (str) */
+	ACL_MATCH_SUB,   /* substring (str) */
+	ACL_MATCH_DIR,   /* directory-like sub-string (str) */
+	ACL_MATCH_DOM,   /* domain-like sub-string (str) */
+	ACL_MATCH_END,   /* end of string (str) */
+	ACL_MATCH_REG,   /* regex (str -> reg) */
+	/* keep this one last */
+	ACL_MATCH_NUM
+};
+
+/* How to store a time range and the valid days in 29 bits */
+struct acl_time {
+	int dow:7;              /* 1 bit per day of week: 0-6 */
+	int h1:5, m1:6;         /* 0..24:0..60. Use 0:0 for all day. */
+	int h2:5, m2:6;         /* 0..24:0..60. Use 24:0 for all day. */
+};
+
+/* This contain each tree indexed entry. This struct permit to associate
+ * "sample" with a tree entry. It is used with maps.
+ */
+struct acl_idx_elt {
+	struct sample_storage *smp;
+	struct ebmb_node node;
+};
+
+/* This describes one ACL pattern, which might be a single value or a tree of
+ * values. All patterns for a single ACL expression are linked together. Some
+ * of them might have a type (eg: IP). Right now, the types are shared with
+ * the samples, though it is possible that in the future this will change to
+ * accommodate for other types (eg: meth, regex). Unsigned and constant types
+ * are preferred when there is a doubt.
+ */
+struct acl_pattern {
+	struct list list;                       /* chaining */
+	int type;                               /* type of the ACL pattern (SMP_T_*) */
+	union {
+		int i;                          /* integer value */
+		struct {
+			signed long long min, max;
+			int min_set :1;
+			int max_set :1;
+		} range; /* integer range */
+		struct {
+			struct in_addr addr;
+			struct in_addr mask;
+		} ipv4;                         /* IPv4 address */
+		struct {
+			struct in6_addr addr;
+			unsigned char mask;     /* number of bits */
+		} ipv6;                         /* IPv6 address/mask */
+		struct acl_time time;           /* valid hours and days */
+		unsigned int group_mask;
+		struct eb_root *tree;           /* tree storing all values if any */
+	} val;                                  /* direct value */
+	union {
+		void *ptr;              /* any data */
+		char *str;              /* any string  */
+		regex *reg;             /* a compiled regex */
+	} ptr;                          /* indirect values, allocated */
+	void(*freeptrbuf)(void *ptr);	/* a destructor able to free objects from the ptr */
+	int len;                        /* data length when required  */
+	int flags;                      /* expr or pattern flags. */
+	struct sample_storage *smp;     /* used to store a pointer to sample value associated
+	                                   with the match. It is used with maps */
+
+};
+
+extern char *acl_match_names[ACL_MATCH_NUM];
+extern int (*acl_parse_fcts[ACL_MATCH_NUM])(const char **, struct acl_pattern *, struct sample_storage *, int *, char **);
+extern int (*acl_match_fcts[ACL_MATCH_NUM])(struct sample *, struct acl_pattern *);
+
+#endif /* _TYPES_PATTERN_H */