MEDIUM: cli: Add payload support
authorAurélien Nephtali <aurelien.nephtali@corp.ovh.com>
Wed, 18 Apr 2018 11:26:46 +0000 (13:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 26 Apr 2018 12:19:33 +0000 (14:19 +0200)
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: Aurélien Nephtali <aurelien.nephtali@corp.ovh.com>

17 files changed:
doc/management.txt
include/proto/applet.h
include/proto/cli.h
include/types/applet.h
include/types/cli.h
src/cache.c
src/cli.c
src/dns.c
src/hlua.c
src/map.c
src/proto_http.c
src/proxy.c
src/server.c
src/ssl_sock.c
src/stats.c
src/stick_table.c
src/stream.c

index 4b69018..bca0fd4 100644 (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
 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
 on the same sockets, any process may pick up the request and will output its
 own stats.
index cdd4d90..7cc2c0a 100644 (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
  * 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)
 {
        appctx->st0 = appctx->st1 = appctx->st2 = 0;
+       appctx->chunk = NULL;
        appctx->io_release = NULL;
        appctx->thread_mask = thread_mask;
        appctx->state = APPLET_SLEEPING;
index d5feb86..da80af7 100644 (file)
@@ -24,7 +24,6 @@
 #define _PROTO_CLI_H
 
 
-struct cli_kw* cli_find_kw(char **args);
 void cli_register_kw(struct cli_kw_list *kw_list);
 
 int cli_has_level(struct appctx *appctx, int level);
index 89c318c..b071586 100644 (file)
@@ -50,6 +50,9 @@ struct applet {
 #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 APPCTX_CLI_ST1_PROMPT  (1 << 0)
+#define APPCTX_CLI_ST1_PAYLOAD (1 << 1)
+
 /* Context of a running applet. */
 struct appctx {
        struct list runq;          /* chaining in the applet run queue */
@@ -57,7 +60,8 @@ struct appctx {
        /* 3 unused bytes here */
        unsigned short state;      /* Internal appctx state */
        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  */
        struct applet *applet;     /* applet this context refers to */
        void *owner;               /* pointer to upper layer's entity (eg: stream interface) */
index 63e0e9d..4e7e6b1 100644 (file)
@@ -27,7 +27,7 @@ struct cli_kw {
        const char *str_kw[5];   /* keywords ended by NULL, limited to 5
                                 separated keywords combination */
        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);
        void (*io_release)(struct appctx *appctx);
        void *private;
index 39e0bad..c72d9de 100644 (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))
                return 1;
index 965709e..38d715f 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -67,6 +67,8 @@
 #include <proto/task.h>
 #include <proto/proto_udp.h>
 
+#define PAYLOAD_PATTERN "<<"
+
 static struct applet cli_applet;
 
 static const char stats_sock_usage_msg[] =
@@ -90,7 +92,7 @@ static struct cli_kw_list cli_keywords = {
 
 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 *kw;
@@ -101,7 +103,7 @@ char *cli_gen_usage_msg()
        dynamic_usage_msg = NULL;
 
        if (LIST_ISEMPTY(&cli_keywords.list))
-               return NULL;
+               goto end;
 
        chunk_reset(tmp);
        chunk_strcat(tmp, stats_sock_usage_msg);
@@ -115,6 +117,18 @@ char *cli_gen_usage_msg()
        chunk_init(&out, NULL, 0);
        chunk_dup(&out, tmp);
        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;
 }
 
@@ -379,61 +393,69 @@ 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
  * 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;
-       int arg;
-       int i, j;
 
-       while (isspace((unsigned char)*line))
-               line++;
+       appctx->st2 = 0;
+       memset(&appctx->ctx.cli, 0, sizeof(appctx->ctx.cli));
 
-       arg = 0;
-       args[arg] = line;
+       p = appctx->chunk->str;
+       end = p + appctx->chunk->len;
 
-       while (*line && arg < MAX_STATS_ARGS) {
-               if (*line == '\\') {
-                       line++;
-                       if (*line == '\0')
-                               break;
-               }
-               else if (isspace((unsigned char)*line)) {
-                       *line++ = '\0';
+       /*
+        * 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);
+       }
 
-                       while (isspace((unsigned char)*line))
-                               line++;
+       /*
+        * 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;
 
-                       args[++arg] = line;
-                       continue;
-               }
+               /* skip leading spaces/tabs */
+               p += strspn(p, " \t");
+               if (!*p)
+                       break;
 
-               line++;
-       }
+               args[i] = p;
+               p += strcspn(p, " \t");
+               *p++ = 0;
 
-       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++;
+               /* unescape backslashes (\) */
+               for (j = 0, k = 0; args[i][k]; k++) {
+                       if (args[i][k] == '\\') {
+                               if (args[i][k + 1] == '\\')
+                                       k++;
                                else
                                        continue;
                        }
-                       args[arg][j] = args[arg][i];
+                       args[i][j] = args[i][k];
                        j++;
                }
-               args[arg][j] = '\0';
-               arg++;
-       }
+               args[i][j] = 0;
 
-       appctx->st2 = 0;
-       memset(&appctx->ctx.cli, 0, sizeof(appctx->ctx.cli));
+               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);
        if (!kw)
@@ -442,7 +464,7 @@ static int cli_parse_request(struct appctx *appctx, char *line)
        appctx->io_handler = kw->io_handler;
        appctx->io_release = kw->io_release;
        /* 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;
        }
        return 1;
@@ -519,9 +541,23 @@ static void cli_io_handler(struct appctx *appctx)
                         * side, the conditions below will complete if needed.
                         */
                        si_shutw(si);
+                       free_trash_chunk(appctx->chunk);
                        break;
                }
                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
                         * would want to return some info right after parsing.
                         */
@@ -530,7 +566,8 @@ static void cli_io_handler(struct appctx *appctx)
                                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)
                                        break;
@@ -538,18 +575,20 @@ static void cli_io_handler(struct appctx *appctx)
                                continue;
                        }
 
-                       /* 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] == '\\') {
-                                       len++;
-                                       continue;
-                               }
-                               if (trash.str[len] == ';') {
-                                       trash.str[len] = '\n';
-                                       reql = len + 1;
-                                       break;
+                       if (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)) {
+                               /* 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 (str[len] == '\\') {
+                                               len++;
+                                               continue;
+                                       }
+                                       if (str[len] == ';') {
+                                               str[len] = '\n';
+                                               reql = len + 1;
+                                               break;
+                                       }
                                }
                        }
 
@@ -558,56 +597,58 @@ static void cli_io_handler(struct appctx *appctx)
                         * line.
                         */
                        len = reql - 1;
-                       if (trash.str[len] != '\n') {
+                       if (str[len] != '\n') {
                                appctx->st0 = CLI_ST_END;
                                continue;
                        }
 
-                       if (len && trash.str[len-1] == '\r')
+                       if (len && str[len-1] == '\r')
                                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;
-                       if (len) {
-                               if (strcmp(trash.str, "quit") == 0) {
-                                       appctx->st0 = CLI_ST_END;
-                                       continue;
-                               }
-                               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;
+
+                       if (appctx->st1 & APPCTX_CLI_ST1_PAYLOAD) {
+                               /* empty line */
+                               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;
                                }
-                               /* NB: stats_sock_parse_request() may have put
-                                * another CLI_ST_O_* into appctx->st0.
-                                */
                        }
-                       else if (!appctx->st1) {
-                               /* if prompt is disabled, print help on empty lines,
-                                * so that the user at least knows how to enable
-                                * prompt and find help.
+                       else {
+                               /*
+                                * Look for the "payload start" pattern at the end of a line
+                                * Its location is not remembered here, this is just to switch
+                                * to a gathering mode.
                                 */
-                               cli_gen_usage_msg();
-                               if (dynamic_usage_msg) {
-                                       appctx->ctx.cli.severity = LOG_INFO;
-                                       appctx->ctx.cli.msg = dynamic_usage_msg;
-                               }
+                               if (!strcmp(appctx->chunk->str + appctx->chunk->len - strlen(PAYLOAD_PATTERN), PAYLOAD_PATTERN))
+                                       appctx->st1 |= APPCTX_CLI_ST1_PAYLOAD;
                                else {
-                                       appctx->ctx.cli.severity = LOG_INFO;
-                                       appctx->ctx.cli.msg = stats_sock_usage_msg;
+                                       /* no payload, the command is complete: parse the request */
+                                       if (!cli_parse_request(appctx))
+                                               cli_gen_usage_msg(appctx);
+
+                                       chunk_reset(appctx->chunk);
                                }
-                               appctx->st0 = CLI_ST_PRINT;
                        }
 
                        /* 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 */
                        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;
                                else
                                        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
                         * 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;
                                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
  * 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;
        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
  * 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))
                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. */
-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 *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. */
-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;
 
@@ -1159,7 +1217,7 @@ static int set_severity_output(int *target, char *argument)
 }
 
 /* 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]))
                return 0;
@@ -1170,13 +1228,13 @@ static int cli_parse_set_severity_output(char **args, struct appctx *appctx, voi
        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;
 }
 
 /* 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 *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 */
-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;
        unsigned char *tmpbuf = NULL;
@@ -1474,6 +1532,20 @@ out:
        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 = {
@@ -1485,6 +1557,9 @@ static struct applet cli_applet = {
 
 /* register cli keywords */
 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", "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 },
index 5fe44d4..385ecbb 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -1948,7 +1948,7 @@ static int dns_finalize_config(void)
 }
 
 /* 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;
 
index 5096768..da56110 100644 (file)
@@ -6926,7 +6926,7 @@ __LJMP static int hlua_register_service(lua_State *L)
 /* This function initialises Lua cli handler. It copies the
  * 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_function *fcn;
index 7953c2a..d02a025 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -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) {
                /* 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 ||
            strcmp(args[1], "acl") == 0) {
@@ -672,7 +672,7 @@ static int cli_parse_show_map(char **args, struct appctx *appctx, void *private)
        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) {
                char *err;
@@ -772,7 +772,7 @@ static int cli_parse_set_map(char **args, struct appctx *appctx, void *private)
        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 ||
            strcmp(args[1], "acl") == 0) {
@@ -862,7 +862,7 @@ static int cli_parse_add_map(char **args, struct appctx *appctx, void *private)
        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')
                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) {
                /* Set ACL or MAP flags. */
index 6730375..f2a7682 100644 (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
  * 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))
                return 1;
index 89f679f..31253f1 100644 (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
  * 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;
 
@@ -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 */
-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 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 */
-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 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 */
-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 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 */
-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 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 */
-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;
 
@@ -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 */
-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;
 
@@ -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 */
-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;
 
index 28cc741..ebac357 100644 (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;
        const char *warning;
@@ -4271,7 +4271,7 @@ static int cli_parse_set_server(char **args, struct appctx *appctx, void *privat
        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 proxy *px;
@@ -4309,7 +4309,7 @@ static int cli_parse_get_weight(char **args, struct appctx *appctx, void *privat
        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;
        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. */
-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;
        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. */
-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;
 
@@ -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. */
-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;
 
@@ -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. */
-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;
 
@@ -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. */
-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;
 
@@ -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. */
-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;
 
@@ -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. */
-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;
 
index 23ad35b..70bf660 100644 (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 */
-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 */
        if (!*args[2]) {
@@ -8525,7 +8525,7 @@ static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *priv
        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;
 
@@ -8561,7 +8561,7 @@ static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *priva
 }
 #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)
        char *err = NULL;
index b592ced..7ad30a1 100644 (file)
@@ -3524,7 +3524,7 @@ static int stats_dump_json_schema_to_buffer(struct stream_interface *si)
        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 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_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_len = 0;
index 73c70d3..3e44747 100644 (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 */
-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.target = NULL;
index 2d8f278..1d0b22c 100644 (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))
                return 1;
@@ -3280,7 +3280,7 @@ static void cli_release_show_sess(struct appctx *appctx)
 }
 
 /* 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;
 
@@ -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 */
-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 stream *strm, *strm_bck;