MEDIUM: cli: Add payload support

In order to use arbitrary data in the CLI (multiple lines or group of words
that must be considered as a whole, for example), it is now possible to add a
payload to the commands. To do so, the first line needs to end with a special
pattern: <<\n. Everything that follows will be left untouched by the CLI parser
and will be passed to the commands parsers.

Per-command support will need to be added to take advantage of this
feature.

Signed-off-by: Aurlien Nephtali <aurelien.nephtali@corp.ovh.com>
This commit is contained in:
Aurlien Nephtali 2018-04-18 13:26:46 +02:00 committed by Willy Tarreau
parent 799f51801a
commit abbf607105
17 changed files with 247 additions and 155 deletions

View File

@ -1298,6 +1298,18 @@ delimiter to mark an end of output for each command, and takes care of ensuring
that no command can emit an empty line on output. A script can thus easily that no command can emit an empty line on output. A script can thus easily
parse the output even when multiple commands were pipelined on a single line. parse the output even when multiple commands were pipelined on a single line.
Some commands may take an optional payload. To add one to a command, the first
line needs to end with the "<<\n" pattern. The next lines will be treated as
the payload and can contain as many lines as needed. To validate a command with
a payload, it needs to end with an empty line.
Limitations do exist: the length of the whole buffer passed to the CLI must
not be greater than tune.bfsize and the pattern "<<" must not be glued to the
last word of the line.
When entering a paylod while in interactive mode, the prompt will change from
"> " to "+ ".
It is important to understand that when multiple haproxy processes are started It is important to understand that when multiple haproxy processes are started
on the same sockets, any process may pick up the request and will output its on the same sockets, any process may pick up the request and will output its
own stats. own stats.

View File

@ -43,11 +43,13 @@ static int inline appctx_res_wakeup(struct appctx *appctx);
/* Initializes all required fields for a new appctx. Note that it does the /* Initializes all required fields for a new appctx. Note that it does the
* minimum acceptable initialization for an appctx. This means only the * minimum acceptable initialization for an appctx. This means only the
* 3 integer states st0, st1, st2 are zeroed. * 3 integer states st0, st1, st2 and the chunk used to gather unfinished
* commands are zeroed
*/ */
static inline void appctx_init(struct appctx *appctx, unsigned long thread_mask) static inline void appctx_init(struct appctx *appctx, unsigned long thread_mask)
{ {
appctx->st0 = appctx->st1 = appctx->st2 = 0; appctx->st0 = appctx->st1 = appctx->st2 = 0;
appctx->chunk = NULL;
appctx->io_release = NULL; appctx->io_release = NULL;
appctx->thread_mask = thread_mask; appctx->thread_mask = thread_mask;
appctx->state = APPLET_SLEEPING; appctx->state = APPLET_SLEEPING;

View File

@ -24,7 +24,6 @@
#define _PROTO_CLI_H #define _PROTO_CLI_H
struct cli_kw* cli_find_kw(char **args);
void cli_register_kw(struct cli_kw_list *kw_list); void cli_register_kw(struct cli_kw_list *kw_list);
int cli_has_level(struct appctx *appctx, int level); int cli_has_level(struct appctx *appctx, int level);

View File

@ -50,6 +50,9 @@ struct applet {
#define APPLET_WOKEN_UP 0x02 /* applet was running and requested to woken up again */ #define APPLET_WOKEN_UP 0x02 /* applet was running and requested to woken up again */
#define APPLET_WANT_DIE 0x04 /* applet was running and requested to die */ #define APPLET_WANT_DIE 0x04 /* applet was running and requested to die */
#define APPCTX_CLI_ST1_PROMPT (1 << 0)
#define APPCTX_CLI_ST1_PAYLOAD (1 << 1)
/* Context of a running applet. */ /* Context of a running applet. */
struct appctx { struct appctx {
struct list runq; /* chaining in the applet run queue */ struct list runq; /* chaining in the applet run queue */
@ -57,7 +60,8 @@ struct appctx {
/* 3 unused bytes here */ /* 3 unused bytes here */
unsigned short state; /* Internal appctx state */ unsigned short state; /* Internal appctx state */
unsigned int st0; /* CLI state for stats, session state for peers */ unsigned int st0; /* CLI state for stats, session state for peers */
unsigned int st1; /* prompt for stats, session error for peers */ unsigned int st1; /* prompt/payload (bitwise OR of APPCTX_CLI_ST1_*) for stats, session error for peers */
struct chunk *chunk; /* used to store unfinished commands */
unsigned int st2; /* output state for stats, unused by peers */ unsigned int st2; /* output state for stats, unused by peers */
struct applet *applet; /* applet this context refers to */ struct applet *applet; /* applet this context refers to */
void *owner; /* pointer to upper layer's entity (eg: stream interface) */ void *owner; /* pointer to upper layer's entity (eg: stream interface) */

View File

@ -27,7 +27,7 @@ struct cli_kw {
const char *str_kw[5]; /* keywords ended by NULL, limited to 5 const char *str_kw[5]; /* keywords ended by NULL, limited to 5
separated keywords combination */ separated keywords combination */
const char *usage; /* usage message */ const char *usage; /* usage message */
int (*parse)(char **args, struct appctx *appctx, void *private); int (*parse)(char **args, char *payload, struct appctx *appctx, void *private);
int (*io_handler)(struct appctx *appctx); int (*io_handler)(struct appctx *appctx);
void (*io_release)(struct appctx *appctx); void (*io_release)(struct appctx *appctx);
void *private; void *private;

View File

@ -952,7 +952,7 @@ struct flt_ops cache_ops = {
}; };
static int cli_parse_show_cache(char **args, struct appctx *appctx, void *private) static int cli_parse_show_cache(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
return 1; return 1;

301
src/cli.c
View File

@ -67,6 +67,8 @@
#include <proto/task.h> #include <proto/task.h>
#include <proto/proto_udp.h> #include <proto/proto_udp.h>
#define PAYLOAD_PATTERN "<<"
static struct applet cli_applet; static struct applet cli_applet;
static const char stats_sock_usage_msg[] = static const char stats_sock_usage_msg[] =
@ -90,7 +92,7 @@ static struct cli_kw_list cli_keywords = {
extern const char *stat_status_codes[]; extern const char *stat_status_codes[];
char *cli_gen_usage_msg() static char *cli_gen_usage_msg(struct appctx *appctx)
{ {
struct cli_kw_list *kw_list; struct cli_kw_list *kw_list;
struct cli_kw *kw; struct cli_kw *kw;
@ -101,7 +103,7 @@ char *cli_gen_usage_msg()
dynamic_usage_msg = NULL; dynamic_usage_msg = NULL;
if (LIST_ISEMPTY(&cli_keywords.list)) if (LIST_ISEMPTY(&cli_keywords.list))
return NULL; goto end;
chunk_reset(tmp); chunk_reset(tmp);
chunk_strcat(tmp, stats_sock_usage_msg); chunk_strcat(tmp, stats_sock_usage_msg);
@ -115,6 +117,18 @@ char *cli_gen_usage_msg()
chunk_init(&out, NULL, 0); chunk_init(&out, NULL, 0);
chunk_dup(&out, tmp); chunk_dup(&out, tmp);
dynamic_usage_msg = out.str; dynamic_usage_msg = out.str;
end:
if (dynamic_usage_msg) {
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = dynamic_usage_msg;
}
else {
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = stats_sock_usage_msg;
}
appctx->st0 = CLI_ST_PRINT;
return dynamic_usage_msg; return dynamic_usage_msg;
} }
@ -379,62 +393,70 @@ static int cli_get_severity_output(struct appctx *appctx)
* If a keyword parser is NULL and an I/O handler is declared, the I/O handler * If a keyword parser is NULL and an I/O handler is declared, the I/O handler
* will automatically be used. * will automatically be used.
*/ */
static int cli_parse_request(struct appctx *appctx, char *line) static int cli_parse_request(struct appctx *appctx)
{ {
char *args[MAX_STATS_ARGS + 1]; char *args[MAX_STATS_ARGS + 1], *p, *end, *payload = NULL;
int i = 0;
struct cli_kw *kw; struct cli_kw *kw;
int arg;
int i, j;
while (isspace((unsigned char)*line))
line++;
arg = 0;
args[arg] = line;
while (*line && arg < MAX_STATS_ARGS) {
if (*line == '\\') {
line++;
if (*line == '\0')
break;
}
else if (isspace((unsigned char)*line)) {
*line++ = '\0';
while (isspace((unsigned char)*line))
line++;
args[++arg] = line;
continue;
}
line++;
}
while (++arg <= MAX_STATS_ARGS)
args[arg] = line;
/* unescape '\' */
arg = 0;
while (arg <= MAX_STATS_ARGS && *args[arg] != '\0') {
j = 0;
for (i=0; args[arg][i] != '\0'; i++) {
if (args[arg][i] == '\\') {
if (args[arg][i+1] == '\\')
i++;
else
continue;
}
args[arg][j] = args[arg][i];
j++;
}
args[arg][j] = '\0';
arg++;
}
appctx->st2 = 0; appctx->st2 = 0;
memset(&appctx->ctx.cli, 0, sizeof(appctx->ctx.cli)); memset(&appctx->ctx.cli, 0, sizeof(appctx->ctx.cli));
p = appctx->chunk->str;
end = p + appctx->chunk->len;
/*
* Get the payload start if there is one.
* For the sake of simplicity, the payload pattern is looked up
* everywhere from the start of the input but it can only be found
* at the end of the first line if APPCTX_CLI_ST1_PAYLOAD is set.
*
* The input string was zero terminated so it is safe to use
* the str*() functions throughout the parsing
*/
if (appctx->st1 & APPCTX_CLI_ST1_PAYLOAD) {
payload = strstr(p, PAYLOAD_PATTERN);
end = payload;
/* skip the pattern */
payload += strlen(PAYLOAD_PATTERN);
}
/*
* Get pointers on words.
* One extra slot is reserved to store a pointer on a null byte.
*/
while (i < MAX_STATS_ARGS && p < end) {
int j, k;
/* skip leading spaces/tabs */
p += strspn(p, " \t");
if (!*p)
break;
args[i] = p;
p += strcspn(p, " \t");
*p++ = 0;
/* unescape backslashes (\) */
for (j = 0, k = 0; args[i][k]; k++) {
if (args[i][k] == '\\') {
if (args[i][k + 1] == '\\')
k++;
else
continue;
}
args[i][j] = args[i][k];
j++;
}
args[i][j] = 0;
i++;
}
/* fill unused slots */
p = appctx->chunk->str + appctx->chunk->len;
for (; i < MAX_STATS_ARGS + 1; i++)
args[i] = p;
kw = cli_find_kw(args); kw = cli_find_kw(args);
if (!kw) if (!kw)
return 0; return 0;
@ -442,7 +464,7 @@ static int cli_parse_request(struct appctx *appctx, char *line)
appctx->io_handler = kw->io_handler; appctx->io_handler = kw->io_handler;
appctx->io_release = kw->io_release; appctx->io_release = kw->io_release;
/* kw->parse could set its own io_handler or ip_release handler */ /* kw->parse could set its own io_handler or ip_release handler */
if ((!kw->parse || kw->parse(args, appctx, kw->private) == 0) && appctx->io_handler) { if ((!kw->parse || kw->parse(args, payload, appctx, kw->private) == 0) && appctx->io_handler) {
appctx->st0 = CLI_ST_CALLBACK; appctx->st0 = CLI_ST_CALLBACK;
} }
return 1; return 1;
@ -519,9 +541,23 @@ static void cli_io_handler(struct appctx *appctx)
* side, the conditions below will complete if needed. * side, the conditions below will complete if needed.
*/ */
si_shutw(si); si_shutw(si);
free_trash_chunk(appctx->chunk);
break; break;
} }
else if (appctx->st0 == CLI_ST_GETREQ) { else if (appctx->st0 == CLI_ST_GETREQ) {
char *str;
/* use a trash chunk to store received data */
if (!appctx->chunk) {
appctx->chunk = alloc_trash_chunk();
if (!appctx->chunk) {
appctx->st0 = CLI_ST_END;
continue;
}
}
str = appctx->chunk->str + appctx->chunk->len;
/* ensure we have some output room left in the event we /* ensure we have some output room left in the event we
* would want to return some info right after parsing. * would want to return some info right after parsing.
*/ */
@ -530,7 +566,8 @@ static void cli_io_handler(struct appctx *appctx)
break; break;
} }
reql = co_getline(si_oc(si), trash.str, trash.size); /* '- 1' is to ensure a null byte can always be inserted at the end */
reql = co_getline(si_oc(si), str, appctx->chunk->size - appctx->chunk->len - 1);
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
break; break;
@ -538,18 +575,20 @@ static void cli_io_handler(struct appctx *appctx)
continue; continue;
} }
/* seek for a possible unescaped semi-colon. If we find if (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)) {
* one, we replace it with an LF and skip only this part. /* seek for a possible unescaped semi-colon. If we find
*/ * one, we replace it with an LF and skip only this part.
for (len = 0; len < reql; len++) { */
if (trash.str[len] == '\\') { for (len = 0; len < reql; len++) {
len++; if (str[len] == '\\') {
continue; len++;
} continue;
if (trash.str[len] == ';') { }
trash.str[len] = '\n'; if (str[len] == ';') {
reql = len + 1; str[len] = '\n';
break; reql = len + 1;
break;
}
} }
} }
@ -558,56 +597,58 @@ static void cli_io_handler(struct appctx *appctx)
* line. * line.
*/ */
len = reql - 1; len = reql - 1;
if (trash.str[len] != '\n') { if (str[len] != '\n') {
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
if (len && trash.str[len-1] == '\r') if (len && str[len-1] == '\r')
len--; len--;
trash.str[len] = '\0'; str[len] = '\0';
appctx->chunk->len += len;
if (appctx->st1 & APPCTX_CLI_ST1_PAYLOAD) {
appctx->chunk->str[appctx->chunk->len] = '\n';
appctx->chunk->str[appctx->chunk->len + 1] = 0;
appctx->chunk->len++;
}
appctx->st0 = CLI_ST_PROMPT; appctx->st0 = CLI_ST_PROMPT;
if (len) {
if (strcmp(trash.str, "quit") == 0) { if (appctx->st1 & APPCTX_CLI_ST1_PAYLOAD) {
appctx->st0 = CLI_ST_END; /* empty line */
continue; if (!len) {
/* remove the last two \n */
appctx->chunk->len -= 2;
appctx->chunk->str[appctx->chunk->len] = 0;
if (!cli_parse_request(appctx))
cli_gen_usage_msg(appctx);
chunk_reset(appctx->chunk);
/* NB: cli_sock_parse_request() may have put
* another CLI_ST_O_* into appctx->st0.
*/
appctx->st1 &= ~APPCTX_CLI_ST1_PAYLOAD;
} }
else if (strcmp(trash.str, "prompt") == 0)
appctx->st1 = !appctx->st1;
else if (strcmp(trash.str, "help") == 0 ||
!cli_parse_request(appctx, trash.str)) {
cli_gen_usage_msg();
if (dynamic_usage_msg) {
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = dynamic_usage_msg;
}
else {
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = stats_sock_usage_msg;
}
appctx->st0 = CLI_ST_PRINT;
}
/* NB: stats_sock_parse_request() may have put
* another CLI_ST_O_* into appctx->st0.
*/
} }
else if (!appctx->st1) { else {
/* if prompt is disabled, print help on empty lines, /*
* so that the user at least knows how to enable * Look for the "payload start" pattern at the end of a line
* prompt and find help. * Its location is not remembered here, this is just to switch
* to a gathering mode.
*/ */
cli_gen_usage_msg(); if (!strcmp(appctx->chunk->str + appctx->chunk->len - strlen(PAYLOAD_PATTERN), PAYLOAD_PATTERN))
if (dynamic_usage_msg) { appctx->st1 |= APPCTX_CLI_ST1_PAYLOAD;
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = dynamic_usage_msg;
}
else { else {
appctx->ctx.cli.severity = LOG_INFO; /* no payload, the command is complete: parse the request */
appctx->ctx.cli.msg = stats_sock_usage_msg; if (!cli_parse_request(appctx))
cli_gen_usage_msg(appctx);
chunk_reset(appctx->chunk);
} }
appctx->st0 = CLI_ST_PRINT;
} }
/* re-adjust req buffer */ /* re-adjust req buffer */
@ -656,7 +697,24 @@ static void cli_io_handler(struct appctx *appctx)
/* The post-command prompt is either LF alone or LF + '> ' in interactive mode */ /* The post-command prompt is either LF alone or LF + '> ' in interactive mode */
if (appctx->st0 == CLI_ST_PROMPT) { if (appctx->st0 == CLI_ST_PROMPT) {
if (ci_putstr(si_ic(si), appctx->st1 ? "\n> " : "\n") != -1) const char *prompt = "";
if (appctx->st1 & APPCTX_CLI_ST1_PROMPT) {
/*
* when entering a payload with interactive mode, change the prompt
* to emphasize that more data can still be sent
*/
if (appctx->chunk->len && appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)
prompt = "+ ";
else
prompt = "\n> ";
}
else {
if (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD))
prompt = "\n";
}
if (ci_putstr(si_ic(si), prompt) != -1)
appctx->st0 = CLI_ST_GETREQ; appctx->st0 = CLI_ST_GETREQ;
else else
si_applet_cant_put(si); si_applet_cant_put(si);
@ -671,7 +729,7 @@ static void cli_io_handler(struct appctx *appctx)
* buffer is empty. This still allows pipelined requests * buffer is empty. This still allows pipelined requests
* to be sent in non-interactive mode. * to be sent in non-interactive mode.
*/ */
if ((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) || (!appctx->st1 && !req->buf->o)) { if ((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) || (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !req->buf->o)) {
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
@ -1020,7 +1078,7 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx)
* wants to stop here. It puts the variable to be dumped into cli.p0 if a single * wants to stop here. It puts the variable to be dumped into cli.p0 if a single
* variable is requested otherwise puts environ there. * variable is requested otherwise puts environ there.
*/ */
static int cli_parse_show_env(char **args, struct appctx *appctx, void *private) static int cli_parse_show_env(char **args, char *payload, struct appctx *appctx, void *private)
{ {
extern char **environ; extern char **environ;
char **var; char **var;
@ -1054,7 +1112,7 @@ static int cli_parse_show_env(char **args, struct appctx *appctx, void *private)
* wants to stop here. It puts the FD number into cli.i0 if a specific FD is * wants to stop here. It puts the FD number into cli.i0 if a specific FD is
* requested and sets st2 to STAT_ST_END, otherwise leaves 0 in i0. * requested and sets st2 to STAT_ST_END, otherwise leaves 0 in i0.
*/ */
static int cli_parse_show_fd(char **args, struct appctx *appctx, void *private) static int cli_parse_show_fd(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (!cli_has_level(appctx, ACCESS_LVL_OPER)) if (!cli_has_level(appctx, ACCESS_LVL_OPER))
return 1; return 1;
@ -1069,7 +1127,7 @@ static int cli_parse_show_fd(char **args, struct appctx *appctx, void *private)
} }
/* parse a "set timeout" CLI request. It always returns 1. */ /* parse a "set timeout" CLI request. It always returns 1. */
static int cli_parse_set_timeout(char **args, struct appctx *appctx, void *private) static int cli_parse_set_timeout(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct stream_interface *si = appctx->owner; struct stream_interface *si = appctx->owner;
struct stream *s = si_strm(si); struct stream *s = si_strm(si);
@ -1106,7 +1164,7 @@ static int cli_parse_set_timeout(char **args, struct appctx *appctx, void *priva
} }
/* parse a "set maxconn global" command. It always returns 1. */ /* parse a "set maxconn global" command. It always returns 1. */
static int cli_parse_set_maxconn_global(char **args, struct appctx *appctx, void *private) static int cli_parse_set_maxconn_global(char **args, char *payload, struct appctx *appctx, void *private)
{ {
int v; int v;
@ -1159,7 +1217,7 @@ static int set_severity_output(int *target, char *argument)
} }
/* parse a "set severity-output" command. */ /* parse a "set severity-output" command. */
static int cli_parse_set_severity_output(char **args, struct appctx *appctx, void *private) static int cli_parse_set_severity_output(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (*args[2] && set_severity_output(&appctx->cli_severity_output, args[2])) if (*args[2] && set_severity_output(&appctx->cli_severity_output, args[2]))
return 0; return 0;
@ -1170,13 +1228,13 @@ static int cli_parse_set_severity_output(char **args, struct appctx *appctx, voi
return 1; return 1;
} }
int cli_parse_default(char **args, struct appctx *appctx, void *private) int cli_parse_default(char **args, char *payload, struct appctx *appctx, void *private)
{ {
return 0; return 0;
} }
/* parse a "set rate-limit" command. It always returns 1. */ /* parse a "set rate-limit" command. It always returns 1. */
static int cli_parse_set_ratelimit(char **args, struct appctx *appctx, void *private) static int cli_parse_set_ratelimit(char **args, char *payload, struct appctx *appctx, void *private)
{ {
int v; int v;
int *res; int *res;
@ -1296,7 +1354,7 @@ static int bind_parse_severity_output(char **args, int cur_arg, struct proxy *px
} }
/* Send all the bound sockets, always returns 1 */ /* Send all the bound sockets, always returns 1 */
static int _getsocks(char **args, struct appctx *appctx, void *private) static int _getsocks(char **args, char *payload, struct appctx *appctx, void *private)
{ {
char *cmsgbuf = NULL; char *cmsgbuf = NULL;
unsigned char *tmpbuf = NULL; unsigned char *tmpbuf = NULL;
@ -1474,6 +1532,20 @@ static int _getsocks(char **args, struct appctx *appctx, void *private)
return 1; return 1;
} }
static int cli_parse_simple(char **args, char *payload, struct appctx *appctx, void *private)
{
if (*args[0] == 'h')
/* help */
cli_gen_usage_msg(appctx);
else if (*args[0] == 'p')
/* prompt */
appctx->st1 ^= APPCTX_CLI_ST1_PROMPT;
else if (*args[0] == 'q')
/* quit */
appctx->st0 = CLI_ST_END;
return 1;
}
static struct applet cli_applet = { static struct applet cli_applet = {
@ -1485,6 +1557,9 @@ static struct applet cli_applet = {
/* register cli keywords */ /* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{ static struct cli_kw_list cli_kws = {{ },{
{ { "help", NULL }, NULL, cli_parse_simple, NULL },
{ { "prompt", NULL }, NULL, cli_parse_simple, NULL },
{ { "quit", NULL }, NULL, cli_parse_simple, NULL },
{ { "set", "maxconn", "global", NULL }, "set maxconn global : change the per-process maxconn setting", cli_parse_set_maxconn_global, NULL }, { { "set", "maxconn", "global", NULL }, "set maxconn global : change the per-process maxconn setting", cli_parse_set_maxconn_global, NULL },
{ { "set", "rate-limit", NULL }, "set rate-limit : change a rate limiting value", cli_parse_set_ratelimit, NULL }, { { "set", "rate-limit", NULL }, "set rate-limit : change a rate limiting value", cli_parse_set_ratelimit, NULL },
{ { "set", "severity-output", NULL }, "set severity-output [none|number|string] : set presence of severity level in feedback information", cli_parse_set_severity_output, NULL, NULL }, { { "set", "severity-output", NULL }, "set severity-output [none|number|string] : set presence of severity level in feedback information", cli_parse_set_severity_output, NULL, NULL },

View File

@ -1948,7 +1948,7 @@ static int dns_finalize_config(void)
} }
/* if an arg is found, it sets the resolvers section pointer into cli.p0 */ /* if an arg is found, it sets the resolvers section pointer into cli.p0 */
static int cli_parse_stat_resolvers(char **args, struct appctx *appctx, void *private) static int cli_parse_stat_resolvers(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct dns_resolvers *presolvers; struct dns_resolvers *presolvers;

View File

@ -6926,7 +6926,7 @@ __LJMP static int hlua_register_service(lua_State *L)
/* This function initialises Lua cli handler. It copies the /* This function initialises Lua cli handler. It copies the
* arguments in the Lua stack and create channel IO objects. * arguments in the Lua stack and create channel IO objects.
*/ */
static int hlua_cli_parse_fct(char **args, struct appctx *appctx, void *private) static int hlua_cli_parse_fct(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct hlua *hlua; struct hlua *hlua;
struct hlua_function *fcn; struct hlua_function *fcn;

View File

@ -565,7 +565,7 @@ static void cli_release_mlook(struct appctx *appctx)
} }
static int cli_parse_get_map(char **args, struct appctx *appctx, void *private) static int cli_parse_get_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) { if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
/* Set flags. */ /* Set flags. */
@ -632,7 +632,7 @@ static void cli_release_show_map(struct appctx *appctx)
} }
} }
static int cli_parse_show_map(char **args, struct appctx *appctx, void *private) static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (strcmp(args[1], "map") == 0 || if (strcmp(args[1], "map") == 0 ||
strcmp(args[1], "acl") == 0) { strcmp(args[1], "acl") == 0) {
@ -672,7 +672,7 @@ static int cli_parse_show_map(char **args, struct appctx *appctx, void *private)
return 0; return 0;
} }
static int cli_parse_set_map(char **args, struct appctx *appctx, void *private) static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (strcmp(args[1], "map") == 0) { if (strcmp(args[1], "map") == 0) {
char *err; char *err;
@ -772,7 +772,7 @@ static int cli_parse_set_map(char **args, struct appctx *appctx, void *private)
return 1; return 1;
} }
static int cli_parse_add_map(char **args, struct appctx *appctx, void *private) static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (strcmp(args[1], "map") == 0 || if (strcmp(args[1], "map") == 0 ||
strcmp(args[1], "acl") == 0) { strcmp(args[1], "acl") == 0) {
@ -862,7 +862,7 @@ static int cli_parse_add_map(char **args, struct appctx *appctx, void *private)
return 0; return 0;
} }
static int cli_parse_del_map(char **args, struct appctx *appctx, void *private) static int cli_parse_del_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (args[1][0] == 'm') if (args[1][0] == 'm')
appctx->ctx.map.display_flags = PAT_REF_MAP; appctx->ctx.map.display_flags = PAT_REF_MAP;
@ -958,7 +958,7 @@ static int cli_parse_del_map(char **args, struct appctx *appctx, void *private)
} }
static int cli_parse_clear_map(char **args, struct appctx *appctx, void *private) static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) { if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
/* Set ACL or MAP flags. */ /* Set ACL or MAP flags. */

View File

@ -12489,7 +12489,7 @@ struct action_kw *action_http_res_custom(const char *kw)
/* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop /* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop
* now. * now.
*/ */
static int cli_parse_show_errors(char **args, struct appctx *appctx, void *private) static int cli_parse_show_errors(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (!cli_has_level(appctx, ACCESS_LVL_OPER)) if (!cli_has_level(appctx, ACCESS_LVL_OPER))
return 1; return 1;

View File

@ -1393,7 +1393,7 @@ struct proxy *cli_find_backend(struct appctx *appctx, const char *arg)
* 1 if it stops immediately. If an argument is specified, it will set the proxy * 1 if it stops immediately. If an argument is specified, it will set the proxy
* pointer into cli.p0 and its ID into cli.i0. * pointer into cli.p0 and its ID into cli.i0.
*/ */
static int cli_parse_show_servers(char **args, struct appctx *appctx, void *private) static int cli_parse_show_servers(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
@ -1558,7 +1558,7 @@ static int cli_io_handler_show_backend(struct appctx *appctx)
} }
/* Parses the "enable dynamic-cookies backend" directive, it always returns 1 */ /* Parses the "enable dynamic-cookies backend" directive, it always returns 1 */
static int cli_parse_enable_dyncookie_backend(char **args, struct appctx *appctx, void *private) static int cli_parse_enable_dyncookie_backend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
struct server *s; struct server *s;
@ -1579,7 +1579,7 @@ static int cli_parse_enable_dyncookie_backend(char **args, struct appctx *appctx
} }
/* Parses the "disable dynamic-cookies backend" directive, it always returns 1 */ /* Parses the "disable dynamic-cookies backend" directive, it always returns 1 */
static int cli_parse_disable_dyncookie_backend(char **args, struct appctx *appctx, void *private) static int cli_parse_disable_dyncookie_backend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
struct server *s; struct server *s;
@ -1604,7 +1604,7 @@ static int cli_parse_disable_dyncookie_backend(char **args, struct appctx *appct
} }
/* Parses the "set dynamic-cookie-key backend" directive, it always returns 1 */ /* Parses the "set dynamic-cookie-key backend" directive, it always returns 1 */
static int cli_parse_set_dyncookie_key_backend(char **args, struct appctx *appctx, void *private) static int cli_parse_set_dyncookie_key_backend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
struct server *s; struct server *s;
@ -1641,7 +1641,7 @@ static int cli_parse_set_dyncookie_key_backend(char **args, struct appctx *appct
} }
/* Parses the "set maxconn frontend" directive, it always returns 1 */ /* Parses the "set maxconn frontend" directive, it always returns 1 */
static int cli_parse_set_maxconn_frontend(char **args, struct appctx *appctx, void *private) static int cli_parse_set_maxconn_frontend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
struct listener *l; struct listener *l;
@ -1686,7 +1686,7 @@ static int cli_parse_set_maxconn_frontend(char **args, struct appctx *appctx, vo
} }
/* Parses the "shutdown frontend" directive, it always returns 1 */ /* Parses the "shutdown frontend" directive, it always returns 1 */
static int cli_parse_shutdown_frontend(char **args, struct appctx *appctx, void *private) static int cli_parse_shutdown_frontend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
@ -1713,7 +1713,7 @@ static int cli_parse_shutdown_frontend(char **args, struct appctx *appctx, void
} }
/* Parses the "disable frontend" directive, it always returns 1 */ /* Parses the "disable frontend" directive, it always returns 1 */
static int cli_parse_disable_frontend(char **args, struct appctx *appctx, void *private) static int cli_parse_disable_frontend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
@ -1748,7 +1748,7 @@ static int cli_parse_disable_frontend(char **args, struct appctx *appctx, void *
} }
/* Parses the "enable frontend" directive, it always returns 1 */ /* Parses the "enable frontend" directive, it always returns 1 */
static int cli_parse_enable_frontend(char **args, struct appctx *appctx, void *private) static int cli_parse_enable_frontend(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;

View File

@ -4088,7 +4088,7 @@ struct server *cli_find_server(struct appctx *appctx, char *arg)
} }
static int cli_parse_set_server(char **args, struct appctx *appctx, void *private) static int cli_parse_set_server(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
const char *warning; const char *warning;
@ -4271,7 +4271,7 @@ static int cli_parse_set_server(char **args, struct appctx *appctx, void *privat
return 1; return 1;
} }
static int cli_parse_get_weight(char **args, struct appctx *appctx, void *private) static int cli_parse_get_weight(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct stream_interface *si = appctx->owner; struct stream_interface *si = appctx->owner;
struct proxy *px; struct proxy *px;
@ -4309,7 +4309,7 @@ static int cli_parse_get_weight(char **args, struct appctx *appctx, void *privat
return 1; return 1;
} }
static int cli_parse_set_weight(char **args, struct appctx *appctx, void *private) static int cli_parse_set_weight(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
const char *warning; const char *warning;
@ -4331,7 +4331,7 @@ static int cli_parse_set_weight(char **args, struct appctx *appctx, void *privat
} }
/* parse a "set maxconn server" command. It always returns 1. */ /* parse a "set maxconn server" command. It always returns 1. */
static int cli_parse_set_maxconn_server(char **args, struct appctx *appctx, void *private) static int cli_parse_set_maxconn_server(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
const char *warning; const char *warning;
@ -4353,7 +4353,7 @@ static int cli_parse_set_maxconn_server(char **args, struct appctx *appctx, void
} }
/* parse a "disable agent" command. It always returns 1. */ /* parse a "disable agent" command. It always returns 1. */
static int cli_parse_disable_agent(char **args, struct appctx *appctx, void *private) static int cli_parse_disable_agent(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
@ -4369,7 +4369,7 @@ static int cli_parse_disable_agent(char **args, struct appctx *appctx, void *pri
} }
/* parse a "disable health" command. It always returns 1. */ /* parse a "disable health" command. It always returns 1. */
static int cli_parse_disable_health(char **args, struct appctx *appctx, void *private) static int cli_parse_disable_health(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
@ -4385,7 +4385,7 @@ static int cli_parse_disable_health(char **args, struct appctx *appctx, void *pr
} }
/* parse a "disable server" command. It always returns 1. */ /* parse a "disable server" command. It always returns 1. */
static int cli_parse_disable_server(char **args, struct appctx *appctx, void *private) static int cli_parse_disable_server(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
@ -4401,7 +4401,7 @@ static int cli_parse_disable_server(char **args, struct appctx *appctx, void *pr
} }
/* parse a "enable agent" command. It always returns 1. */ /* parse a "enable agent" command. It always returns 1. */
static int cli_parse_enable_agent(char **args, struct appctx *appctx, void *private) static int cli_parse_enable_agent(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
@ -4424,7 +4424,7 @@ static int cli_parse_enable_agent(char **args, struct appctx *appctx, void *priv
} }
/* parse a "enable health" command. It always returns 1. */ /* parse a "enable health" command. It always returns 1. */
static int cli_parse_enable_health(char **args, struct appctx *appctx, void *private) static int cli_parse_enable_health(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
@ -4440,7 +4440,7 @@ static int cli_parse_enable_health(char **args, struct appctx *appctx, void *pri
} }
/* parse a "enable server" command. It always returns 1. */ /* parse a "enable server" command. It always returns 1. */
static int cli_parse_enable_server(char **args, struct appctx *appctx, void *private) static int cli_parse_enable_server(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;

View File

@ -8500,7 +8500,7 @@ static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
} }
/* sets cli.i0 to non-zero if only file lists should be dumped */ /* sets cli.i0 to non-zero if only file lists should be dumped */
static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private) static int cli_parse_show_tlskeys(char **args, char *payload, struct appctx *appctx, void *private)
{ {
/* no parameter, shows only file list */ /* no parameter, shows only file list */
if (!*args[2]) { if (!*args[2]) {
@ -8525,7 +8525,7 @@ static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *priv
return 0; return 0;
} }
static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private) static int cli_parse_set_tlskeys(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct tls_keys_ref *ref; struct tls_keys_ref *ref;
@ -8561,7 +8561,7 @@ static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *priva
} }
#endif #endif
static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private) static int cli_parse_set_ocspresponse(char **args, char *payload, struct appctx *appctx, void *private)
{ {
#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) #if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
char *err = NULL; char *err = NULL;

View File

@ -3524,7 +3524,7 @@ static int stats_dump_json_schema_to_buffer(struct stream_interface *si)
return 1; return 1;
} }
static int cli_parse_clear_counters(char **args, struct appctx *appctx, void *private) static int cli_parse_clear_counters(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct proxy *px; struct proxy *px;
struct server *sv; struct server *sv;
@ -3586,7 +3586,7 @@ static int cli_parse_clear_counters(char **args, struct appctx *appctx, void *pr
} }
static int cli_parse_show_info(char **args, struct appctx *appctx, void *private) static int cli_parse_show_info(char **args, char *payload, struct appctx *appctx, void *private)
{ {
appctx->ctx.stats.scope_str = 0; appctx->ctx.stats.scope_str = 0;
appctx->ctx.stats.scope_len = 0; appctx->ctx.stats.scope_len = 0;
@ -3600,7 +3600,7 @@ static int cli_parse_show_info(char **args, struct appctx *appctx, void *private
} }
static int cli_parse_show_stat(char **args, struct appctx *appctx, void *private) static int cli_parse_show_stat(char **args, char *payload, struct appctx *appctx, void *private)
{ {
appctx->ctx.stats.scope_str = 0; appctx->ctx.stats.scope_str = 0;
appctx->ctx.stats.scope_len = 0; appctx->ctx.stats.scope_len = 0;

View File

@ -3375,7 +3375,7 @@ static int table_prepare_data_request(struct appctx *appctx, char **args)
} }
/* returns 0 if wants to be called, 1 if has ended processing */ /* returns 0 if wants to be called, 1 if has ended processing */
static int cli_parse_table_req(char **args, struct appctx *appctx, void *private) static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx, void *private)
{ {
appctx->ctx.table.data_type = -1; appctx->ctx.table.data_type = -1;
appctx->ctx.table.target = NULL; appctx->ctx.table.target = NULL;

View File

@ -3025,7 +3025,7 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st
} }
static int cli_parse_show_sess(char **args, struct appctx *appctx, void *private) static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx, void *private)
{ {
if (!cli_has_level(appctx, ACCESS_LVL_OPER)) if (!cli_has_level(appctx, ACCESS_LVL_OPER))
return 1; return 1;
@ -3280,7 +3280,7 @@ static void cli_release_show_sess(struct appctx *appctx)
} }
/* Parses the "shutdown session" directive, it always returns 1 */ /* Parses the "shutdown session" directive, it always returns 1 */
static int cli_parse_shutdown_session(char **args, struct appctx *appctx, void *private) static int cli_parse_shutdown_session(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct stream *strm, *ptr; struct stream *strm, *ptr;
@ -3315,7 +3315,7 @@ static int cli_parse_shutdown_session(char **args, struct appctx *appctx, void *
} }
/* Parses the "shutdown session server" directive, it always returns 1 */ /* Parses the "shutdown session server" directive, it always returns 1 */
static int cli_parse_shutdown_sessions_server(char **args, struct appctx *appctx, void *private) static int cli_parse_shutdown_sessions_server(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct server *sv; struct server *sv;
struct stream *strm, *strm_bck; struct stream *strm, *strm_bck;