From 9356c6872716353ad00910920773b5af9434effb Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Tue, 28 Jan 2014 15:55:37 +0100 Subject: [PATCH] MEDIUM: dumpstats/pattern: display and use each pointer of each pattern dumped Each pattern displayed is associated to the value of his pattern reference. This value can be used for deleting the entry. It is useful with complex regex: the users are not forced to write the regex with all the amiguous chars and escaped chars on the CLI. --- src/dumpstats.c | 101 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/src/dumpstats.c b/src/dumpstats.c index 62b24cc03..d9632b769 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -1633,11 +1633,46 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) return 1; } - /* Update the value. */ - if (!pat_ref_set(appctx->ctx.map.ref, args[3], args[4])) { - appctx->ctx.cli.msg = "Pattern not found.\n"; - appctx->st0 = STAT_CLI_PRINT; - return 1; + /* If the entry identifier start with a '#', it is considered as + * pointer id + */ + if (args[3][0] == '#' && args[3][1] == '0' && args[3][2] == 'x') { + struct pat_ref_elt *ref; + long long int conv; + char *error; + + /* Convert argument to integer value. */ + conv = strtoll(&args[3][1], &error, 16); + if (*error != '\0') { + appctx->ctx.cli.msg = "Malformed identifier. Please use # or .\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + + /* Convert and check integer to pointer. */ + ref = (struct pat_ref_elt *)(long)conv; + if ((long long int)(long)ref != conv) { + appctx->ctx.cli.msg = "Malformed identifier. Please use # or .\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + + /* Try to delete the entry. */ + if (!pat_ref_set_by_id(appctx->ctx.map.ref, ref, args[4])) { + appctx->ctx.cli.msg = "Pattern not found.\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + } + else { + /* Else, use the entry identifier as pattern + * string, and update the value. + */ + if (!pat_ref_set(appctx->ctx.map.ref, args[3], args[4])) { + appctx->ctx.cli.msg = "Pattern not found.\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } } /* The set is done, send message. */ @@ -1901,12 +1936,48 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) return 1; } - /* Try to delete the entry. */ - if (!pat_ref_delete(appctx->ctx.map.ref, args[3])) { - /* The entry is not found, send message. */ - appctx->ctx.cli.msg = "Key not found.\n"; - appctx->st0 = STAT_CLI_PRINT; - return 1; + /* If the entry identifier start with a '#', it is considered as + * pointer id + */ + if (args[3][0] == '#' && args[3][1] == '0' && args[3][2] == 'x') { + struct pat_ref_elt *ref; + long long int conv; + char *error; + + /* Convert argument to integer value. */ + conv = strtoll(&args[3][1], &error, 16); + if (*error != '\0') { + appctx->ctx.cli.msg = "Malformed identifier. Please use # or .\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + + /* Convert and check integer to pointer. */ + ref = (struct pat_ref_elt *)(long)conv; + if ((long long int)(long)ref != conv) { + appctx->ctx.cli.msg = "Malformed identifier. Please use # or .\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + + /* Try to delete the entry. */ + if (!pat_ref_delete_by_id(appctx->ctx.map.ref, ref)) { + /* The entry is not found, send message. */ + appctx->ctx.cli.msg = "Key not found.\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } + } + else { + /* Else, use the entry identifier as pattern + * string and try to delete the entry. + */ + if (!pat_ref_delete(appctx->ctx.map.ref, args[3])) { + /* The entry is not found, send message. */ + appctx->ctx.cli.msg = "Key not found.\n"; + appctx->st0 = STAT_CLI_PRINT; + return 1; + } } /* The deletion is done, send message. */ @@ -4965,10 +5036,12 @@ static int stats_pat_list(struct stream_interface *si) /* build messages */ if (appctx->ctx.map.elt->sample) - chunk_appendf(&trash, "%s %s\n", - appctx->ctx.map.elt->pattern, appctx->ctx.map.elt->sample); + chunk_appendf(&trash, "%p %s %s\n", + appctx->ctx.map.elt, appctx->ctx.map.elt->pattern, + appctx->ctx.map.elt->sample); else - chunk_appendf(&trash, "%s\n", appctx->ctx.map.elt->pattern); + chunk_appendf(&trash, "%p %s\n", + appctx->ctx.map.elt, appctx->ctx.map.elt->pattern); if (bi_putchk(si->ib, &trash) == -1) { /* let's try again later from this session. We add ourselves into