From: Thierry FOURNIER Date: Tue, 28 Jan 2014 14:55:37 +0000 (+0100) Subject: MEDIUM: dumpstats/pattern: display and use each pointer of each pattern dumped X-Git-Tag: v1.5-dev23~95 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9356c6872716353ad00910920773b5af9434effb;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/dumpstats.c b/src/dumpstats.c index 62b24cc03c..d9632b7697 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