MEDIUM: pattern: The function pattern_exec_match() returns "struct pattern" if the patten match.
Before this commit, the pattern_exec_match() function returns the
associate sample, the associate struct pattern or the associate struct
pattern_tree. This is complex to use, because we can check the type of
information returned.
Now the function return always a "struct pattern". If <fill> is not set,
only the value of the pointer can be used as boolean (NULL or other). If
<fill> is set, you can use the <smp> pointer and the pattern
information.
If information must be duplicated, it is stored in trash buffer.
Otherwise, the pattern can point on existing strings.
diff --git a/src/dumpstats.c b/src/dumpstats.c
index afd333c..01f5d37 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -4827,10 +4827,10 @@
struct sample_storage *smp;
struct sample sample;
struct pattern *pat;
- struct pattern_tree *elt;
- enum pat_match_res res;
- struct sockaddr_in addr;
- char addr_str[INET_ADDRSTRLEN];
+ struct sockaddr_storage addr;
+ char s_addr[INET_ADDRSTRLEN];
+ char s_mask[INET_ADDRSTRLEN];
+ char s_addr6[INET6_ADDRSTRLEN];
switch (appctx->st2) {
case STAT_ST_INIT:
@@ -4850,9 +4850,7 @@
sample.flags |= SMP_F_CONST;
sample.data.str.len = appctx->ctx.map.chunk.len;
sample.data.str.str = appctx->ctx.map.chunk.str;
- pat = NULL;
- elt = NULL;
- res = pattern_exec_match(appctx->ctx.map.desc->pat, &sample, &smp, &pat, &elt);
+ pat = pattern_exec_match(appctx->ctx.map.desc->pat, &sample, 1);
/* build return message: set type of match */
/**/ if (appctx->ctx.map.desc->pat->match == NULL)
@@ -4885,9 +4883,8 @@
chunk_appendf(&trash, "unknown(%p), ", appctx->ctx.map.desc->pat->match);
/* Display no match, and set default value */
- if (res == PAT_NOMATCH) {
+ if (!pat) {
chunk_appendf(&trash, "no-match, ");
- smp = appctx->ctx.map.desc->def;
}
/* Display match and match info */
@@ -4895,46 +4892,61 @@
/* display match */
chunk_appendf(&trash, "match, ");
- /* display search mode */
- if (elt)
+ /* display index mode */
+ if (pat->flags & PAT_F_TREE)
chunk_appendf(&trash, "tree, ");
else
chunk_appendf(&trash, "list, ");
- /* display search options */
- if (pat) {
- /* case sensitive */
- if (pat->flags & PAT_F_IGNORE_CASE)
- chunk_appendf(&trash, "case-insensitive, ");
- else
- chunk_appendf(&trash, "case-sensitive, ");
+ /* case sensitive */
+ if (pat->flags & PAT_F_IGNORE_CASE)
+ chunk_appendf(&trash, "case-insensitive, ");
+ else
+ chunk_appendf(&trash, "case-sensitive, ");
- /* display source */
- if (pat->flags & PAT_F_FROM_FILE)
- chunk_appendf(&trash, "from-file, ");
- }
+ /* display source */
+ if (pat->flags & PAT_F_FROM_FILE)
+ chunk_appendf(&trash, "from-file, ");
- /* display match expresion */
- if (elt) {
- if (appctx->ctx.map.desc->pat->match == pat_match_str) {
- chunk_appendf(&trash, "match=\"%s\", ", elt->node.key);
+ /* display string */
+ if (appctx->ctx.map.desc->pat->match == pat_match_str ||
+ appctx->ctx.map.desc->pat->match == pat_match_str ||
+ appctx->ctx.map.desc->pat->match == pat_match_beg ||
+ appctx->ctx.map.desc->pat->match == pat_match_sub ||
+ appctx->ctx.map.desc->pat->match == pat_match_dir ||
+ appctx->ctx.map.desc->pat->match == pat_match_dom ||
+ appctx->ctx.map.desc->pat->match == pat_match_end) {
+ chunk_appendf(&trash, "match=\"%s\", ", pat->ptr.str);
+ }
+ else if (appctx->ctx.map.desc->pat->match == pat_match_ip) {
+ /* display IPv4/v6 */
+ if (pat->type == SMP_T_IPV4) {
+ ((struct sockaddr_in *)&addr)->sin_family = AF_INET;
+ memcpy(&((struct sockaddr_in *)&addr)->sin_addr, &pat->val.ipv4.addr,
+ sizeof(pat->val.ipv4.addr));
+ if (addr_to_str(&addr, s_addr, INET_ADDRSTRLEN)) {
+ memcpy(&((struct sockaddr_in *)&addr)->sin_addr, &pat->val.ipv4.mask,
+ sizeof(pat->val.ipv4.mask));
+ if (addr_to_str(&addr, s_mask, INET_ADDRSTRLEN))
+ chunk_appendf(&trash, "match=\"%s/%s\", ", s_addr, s_mask);
+ }
}
- /* only IPv4 */
- else if (appctx->ctx.map.desc->pat->match == pat_match_ip) {
- /* convert ip */
- memcpy(&addr.sin_addr, elt->node.key, 4);
- addr.sin_family = AF_INET;
- if (addr_to_str((struct sockaddr_storage *)&addr, addr_str, INET_ADDRSTRLEN))
- chunk_appendf(&trash, "match=\"%s/%d\", ", addr_str, elt->node.node.pfx);
+ else if (pat->type == SMP_T_IPV6) {
+ ((struct sockaddr_in6 *)&addr)->sin6_family = AF_INET6;
+ memcpy(&((struct sockaddr_in6 *)&addr)->sin6_addr, &pat->val.ipv6.addr,
+ sizeof(pat->val.ipv6.addr));
+ if (addr_to_str(&addr, s_addr6, INET6_ADDRSTRLEN))
+ chunk_appendf(&trash, "match=\"%s/%d\", ", s_addr6, pat->val.ipv6.mask);
}
}
}
/* display return value */
- if (!smp) {
+ if (!pat || !pat->smp) {
chunk_appendf(&trash, "return=nothing\n");
}
else {
+ smp = pat->smp;
memcpy(&sample.data, &smp->data, sizeof(sample.data));
sample.type = smp->type;
if (sample_casts[sample.type][SMP_T_STR] &&