struct pat_ref *pat_ref_newid(int unique_id, const char *display, unsigned int flags);
int pat_ref_append(struct pat_ref *ref, char *pattern, char *sample, int line);
int pat_ref_add(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
-int pat_ref_set(struct pat_ref *ref, const char *pattern, const char *sample);
-int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value);
+int pat_ref_set(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
+int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value, char **err);
int pat_ref_delete(struct pat_ref *ref, const char *key);
int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt);
void pat_ref_prune(struct pat_ref *ref);
STAT_CLI_OUTPUT, /* all states after this one are responses */
STAT_CLI_PROMPT, /* display the prompt (first output, same code) */
STAT_CLI_PRINT, /* display message in cli->msg */
+ STAT_CLI_PRINT_FREE, /* display message in cli->msg. After the display, free the pointer */
STAT_CLI_O_INFO, /* dump info */
STAT_CLI_O_SESS, /* dump sessions */
STAT_CLI_O_ERR, /* dump errors */
stats_sock_table_request(si, args, STAT_CLI_O_SET);
}
else if (strcmp(args[1], "map") == 0) {
+ char *err;
+
/* Set flags. */
appctx->ctx.map.display_flags = PAT_REF_MAP;
}
/* 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;
+ err = NULL;
+ if (!pat_ref_set_by_id(appctx->ctx.map.ref, ref, args[4], &err)) {
+ if (err)
+ memprintf(&err, "%s.\n", err);
+ appctx->ctx.cli.err = err;
+ appctx->st0 = STAT_CLI_PRINT_FREE;
return 1;
}
}
/* 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;
+ err = NULL;
+ if (!pat_ref_set(appctx->ctx.map.ref, args[3], args[4], &err)) {
+ if (err)
+ memprintf(&err, "%s.\n", err);
+ appctx->ctx.cli.err = err;
+ appctx->st0 = STAT_CLI_PRINT_FREE;
return 1;
}
}
if (strcmp(args[1], "map") == 0 ||
strcmp(args[1], "acl") == 0) {
int ret;
+ char *err;
/* Set flags. */
if (args[1][0] == 'm')
}
/* Add value. */
+ err = NULL;
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
- ret = pat_ref_add(appctx->ctx.map.ref, args[3], args[4], NULL);
+ ret = pat_ref_add(appctx->ctx.map.ref, args[3], args[4], &err);
else
- ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, NULL);
+ ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, &err);
if (!ret) {
- appctx->ctx.cli.msg = "Out of memory error.\n";
- appctx->st0 = STAT_CLI_PRINT;
+ if (err)
+ memprintf(&err, "%s.\n", err);
+ appctx->ctx.cli.err = err;
+ appctx->st0 = STAT_CLI_PRINT_FREE;
return 1;
}
if (bi_putstr(si->ib, appctx->ctx.cli.msg) != -1)
appctx->st0 = STAT_CLI_PROMPT;
break;
+ case STAT_CLI_PRINT_FREE:
+ if (bi_putstr(si->ib, appctx->ctx.cli.err) != -1) {
+ free(appctx->ctx.cli.err);
+ appctx->st0 = STAT_CLI_PROMPT;
+ }
+ break;
case STAT_CLI_O_INFO:
if (stats_dump_info_to_buffer(si))
appctx->st0 = STAT_CLI_PROMPT;
if (!LIST_ISEMPTY(&appctx->ctx.sess.bref.users))
LIST_DEL(&appctx->ctx.sess.bref.users);
}
+ else if (appctx->st0 == STAT_CLI_PRINT_FREE) {
+ free(appctx->ctx.cli.err);
+ }
else if (appctx->st0 == STAT_CLI_O_MLOOK) {
free(appctx->ctx.map.chunk.str);
}
/* This function modify the sample of the first pattern that match the <key>. */
static inline int pat_ref_set_elt(struct pat_ref *ref, struct pat_ref_elt *elt,
- const char *value)
+ const char *value, char **err)
{
struct pattern_expr *expr;
struct sample_storage **smp;
/* Modify pattern from reference. */
sample = strdup(value);
- if (!sample)
+ if (!sample) {
+ memprintf(err, "out of memory error");
return 0;
+ }
free(elt->sample);
elt->sample = sample;
smp = pattern_find_smp(expr, elt);
if (smp && *smp) {
if (!expr->pat_head->parse_smp(sample, *smp)) {
+ memprintf(err, "failed to parse sample");
*smp = NULL;
ret = 0;
}
}
/* This function modify the sample of the first pattern that match the <key>. */
-int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value)
+int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value, char **err)
{
struct pat_ref_elt *elt;
/* Look for pattern in the reference. */
list_for_each_entry(elt, &ref->head, list) {
if (elt == refelt) {
- pat_ref_set_elt(ref, elt, value);
+ if (!pat_ref_set_elt(ref, elt, value, err))
+ return 0;
return 1;
}
}
+
+ memprintf(err, "key or pattern not found");
return 0;
}
/* This function modify the sample of the first pattern that match the <key>. */
-int pat_ref_set(struct pat_ref *ref, const char *key, const char *value)
+int pat_ref_set(struct pat_ref *ref, const char *key, const char *value, char **err)
{
struct pat_ref_elt *elt;
- int ret = 0;
+ int found = 0;
+ char *_merr;
+ char **merr;
+
+ if (err) {
+ merr = &_merr;
+ *merr = NULL;
+ }
+ else
+ merr = NULL;
/* Look for pattern in the reference. */
list_for_each_entry(elt, &ref->head, list) {
if (strcmp(key, elt->pattern) == 0) {
- pat_ref_set_elt(ref, elt, value);
- ret = 1;
+ if (!pat_ref_set_elt(ref, elt, value, merr)) {
+ if (!found)
+ *err = *merr;
+ else {
+ memprintf(err, "%s, %s", *err, *merr);
+ free(*merr);
+ *merr = NULL;
+ }
+ }
+ found = 1;
}
}
- return ret;
+
+ if (!found) {
+ memprintf(err, "entry not found");
+ return 0;
+ }
+ return 1;
}
/* This function create new reference. <ref> is the reference name.