From: Thierry FOURNIER Date: Fri, 22 Nov 2013 16:33:27 +0000 (+0100) Subject: MINOR: acl: Extract the pattern parsing and indexation from the "acl_read_patterns_fr... X-Git-Tag: v1.5-dev20~191 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3a103c5a6ba99f856c953ccb9f90e1a8ad95bb57;p=thirdparty%2Fhaproxy.git MINOR: acl: Extract the pattern parsing and indexation from the "acl_read_patterns_from_file()" function 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. --- diff --git a/include/proto/acl.h b/include/proto/acl.h index 6859b3d1c4..f50c289677 100644 --- a/include/proto/acl.h +++ b/include/proto/acl.h @@ -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 with compliant parser. 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 + * . + * + * The function returns 1 if the processing is ok, return -1 if the parser + * fails, with 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. diff --git a/src/acl.c b/src/acl.c index 5c28e27a26..7b06e85903 100644 --- 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 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 */ } }