]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: acl: Extract the pattern parsing and indexation from the "acl_read_patterns_fr...
authorThierry FOURNIER <tfournier@exceliance.fr>
Fri, 22 Nov 2013 16:33:27 +0000 (17:33 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 2 Dec 2013 22:31:33 +0000 (23:31 +0100)
With this split, the pattern indexation can apply to any source. The map
feature needs this functionality because the map cannot be loaded with the
same file format as the ones supported by acl_read_patterns_from_file().

The code was only moved to its own function, no functional changes were made.

include/proto/acl.h
src/acl.c

index 6859b3d1c4ad265e38cbddc66829c69b993ab3ae..f50c289677e21c685fa2f1a876d493c73e982d6e 100644 (file)
@@ -112,6 +112,21 @@ const struct acl *acl_cond_conflicts(const struct acl_cond *cond, unsigned int w
  */
 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 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.
index 5c28e27a2639098862742314940bfd9a64d1be3a..7b06e85903e4a5c7221fdf0d63c5db581c55f0fb 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -900,6 +900,50 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
        return expr;
 }
 
+/* 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 acl_register_pattern(struct acl_expr *expr, char *text,
+                         struct acl_pattern **pattern,
+                         int patflags, char **err)
+{
+       const char *args[2];
+       int opaque = 0;
+
+       args[0] = text;
+       args[1] = "";
+
+       /* we keep the previous pattern along iterations as long as it's not used */
+       if (!*pattern)
+               *pattern = (struct acl_pattern *)malloc(sizeof(**pattern));
+       if (!*pattern)
+               return -1;
+
+       memset(*pattern, 0, sizeof(**pattern));
+       (*pattern)->flags = patflags;
+
+       if (!((*pattern)->flags & ACL_PAT_F_IGNORE_CASE) &&
+           (expr->match == acl_match_str || expr->match == acl_match_ip)) {
+               /* 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.
+                */
+               (*pattern)->flags |= ACL_PAT_F_TREE_OK;
+               (*pattern)->val.tree = &expr->pattern_tree;
+       }
+
+       (*pattern)->type = SMP_TYPES; /* unspecified type by default */
+       if (!expr->parse(args, *pattern, &opaque, err))
+               return -1;
+
+       /* if the parser did not feed the tree, let's chain the pattern to the list */
+       if (!((*pattern)->flags & ACL_PAT_F_TREE)) {
+               LIST_ADDQ(&expr->patterns, &(*pattern)->list);
+               *pattern = NULL; /* get a new one */
+       }
+
+       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.
@@ -910,11 +954,11 @@ static int acl_read_patterns_from_file(struct acl_expr *expr,
 {
        FILE *file;
        char *c;
-       const char *args[2];
+       char *arg;
        struct acl_pattern *pattern;
-       int opaque;
        int ret = 0;
        int line = 0;
+       int code;
 
        file = fopen(filename, "r");
        if (!file) {
@@ -926,9 +970,7 @@ static int acl_read_patterns_from_file(struct acl_expr *expr,
         * line. If the line contains spaces, they will be part of the pattern.
         * The pattern stops at the first CR, LF or EOF encountered.
         */
-       opaque = 0;
        pattern = NULL;
-       args[1] = "";
        while (fgets(trash.str, trash.size, file) != NULL) {
                line++;
                c = trash.str;
@@ -942,43 +984,23 @@ static int acl_read_patterns_from_file(struct acl_expr *expr,
                        c++;
 
 
-               args[0] = c;
+               arg = c;
                while (*c && *c != '\n' && *c != '\r')
                        c++;
                *c = 0;
 
                /* empty lines are ignored too */
-               if (c == args[0])
+               if (c == arg)
                        continue;
 
-               /* we keep the previous pattern along iterations as long as it's not used */
-               if (!pattern)
-                       pattern = (struct acl_pattern *)malloc(sizeof(*pattern));
-               if (!pattern) {
+               code = acl_register_pattern(expr, arg, &pattern, patflags, err);
+               if (code == -2) {
                        memprintf(err, "out of memory when loading patterns from file <%s>", filename);
                        goto out_close;
                }
-
-               memset(pattern, 0, sizeof(*pattern));
-               pattern->flags = patflags;
-
-               if (!(pattern->flags & ACL_PAT_F_IGNORE_CASE) &&
-                   (expr->match == acl_match_str || expr->match == acl_match_ip)) {
-                       /* 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.
-                        */
-                       pattern->flags |= ACL_PAT_F_TREE_OK;
-                       pattern->val.tree = &expr->pattern_tree;
-               }
-
-               pattern->type = SMP_TYPES; /* unspecified type by default */
-               if (!expr->parse(args, pattern, &opaque, err))
+               else if (code < 0) {
+                       memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
                        goto out_free_pattern;
-
-               /* if the parser did not feed the tree, let's chain the pattern to the list */
-               if (!(pattern->flags & ACL_PAT_F_TREE)) {
-                       LIST_ADDQ(&expr->patterns, &pattern->list);
-                       pattern = NULL; /* get a new one */
                }
        }