]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
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 4b6901851179d7351eeb5a2d9783b2cc88311326..bca0fd469db7ef3c3d494af2c9d7182284176116 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 cdd4d90f09e6cbf77e45ae62506ad0bf8aaff343..7cc2c0ad148ef7858a407bf10fd57907acaf28c6 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 d5feb862adf3171e9e6b45f2035e01538abdc75a..da80af7d383982bccfb0259eaf258693412de1a7 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 89c318c1d12f9da34878c00581cb462d9c2cf99e..b0715866e2eda8b817fadcc5d69c4a8cad3ebcc8 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 63e0e9d05de2899c11b0f62fbd4ef09574e0df54..4e7e6b12429053d65edc6f5a961ad64853cfa72f 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 39e0bad44dabbe009aedf407efcd628dc126fc05..c72d9dee9971089e8355d01055ef6bbd0d41c983 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 965709ec83d6405b486beee01c70f5e3159e08f1..38d715f8384218b711a9481d4c9cfc1b6f116e38 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 5fe44d43377b76abc73f20f0d6fae48380a3647d..385ecbb6dd06fea45dfec7bfc920a040caad2c26 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 5096768be019ae4389a06fe25d93c24b30988701..da5611065f1c70469f183c5b7c2804fba690e3ae 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 7953c2a0be3fe58fa02bf3c9f5a6e5cd83fcf49b..d02a0255c7d6dbaf9b57bc3ee2009ef2a43964e9 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 6730375ef91e88ca50f63e9f61c30a696c7bd793..f2a76823a58af7ca279e2b69e500ee1da014fd81 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 89f679ff596c172eda830195e968786f25575ece..31253f14dcd2d497d76d2ae286d217bf5b1158fe 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 28cc7418caa34809851beda047025e9711d9aca0..ebac357fba8ccd40335f5254964d60c98470c45a 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 23ad35b187cda3779d3b386f2548402119636c22..70bf660243ad1130843d7a64321dd058c6fad136 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 b592ced57e7f7bad7391749cd10df7960c7dda02..7ad30a178f51c05cc7051945330f5554e60e0dff 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 73c70d3e2931769b13ecf427e272dafadbcb3435..3e44747c12df17f11cf92d89c943a13b02bd3e42 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 2d8f27834cf50e178a671e459b84b5a6a1585618..1d0b22ca3d6c221b119ea8f159458939ba0ea888 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;