summaryrefslogtreecommitdiffstats
path: root/src/cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli.c')
-rw-r--r--src/cli.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/cli.c b/src/cli.c
index d0435f7..51f3d77 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -813,6 +813,22 @@ static int cli_parse_request(struct appctx *appctx)
if (!**args)
return 0;
+ if (appctx->st1 & APPCTX_CLI_ST1_SHUT_EXPECTED) {
+ /* The previous command line was finished by a \n in non-interactive mode.
+ * It should not be followed by another command line. In non-interactive mode,
+ * only one line should be processed. Because of a bug, it is not respected.
+ * So emit a warning, only once in the process life, to warn users their script
+ * must be updated.
+ */
+ appctx->st1 &= ~APPCTX_CLI_ST1_SHUT_EXPECTED;
+ if (ONLY_ONCE()) {
+ ha_warning("Commands sent to the CLI were chained using a new line character while in non-interactive mode."
+ " This is not reliable, not officially supported and will not be supported anymore in future versions. "
+ "Please use ';' to delimit commands instead.");
+ }
+ }
+
+
kw = cli_find_kw(args);
if (!kw ||
(kw->level & ~appctx->cli_level & ACCESS_MASTER_ONLY) ||
@@ -916,6 +932,7 @@ static void cli_io_handler(struct appctx *appctx)
struct bind_conf *bind_conf = strm_li(__sc_strm(sc))->bind_conf;
int reql;
int len;
+ int lf = 0;
if (unlikely(se_fl_test(appctx->sedesc, (SE_FL_EOS|SE_FL_ERROR|SE_FL_SHR|SE_FL_SHW)))) {
co_skip(sc_oc(sc), co_data(sc_oc(sc)));
@@ -987,29 +1004,15 @@ static void cli_io_handler(struct appctx *appctx)
continue;
}
- 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;
- }
- }
- }
+ if (str[reql-1] == '\n')
+ lf = 1;
/* now it is time to check that we have a full line,
* remove the trailing \n and possibly \r, then cut the
* line.
*/
len = reql - 1;
- if (str[len] != '\n') {
+ if (str[len] != '\n' && str[len] != ';') {
se_fl_set(appctx->sedesc, SE_FL_ERROR);
appctx->st0 = CLI_ST_END;
continue;
@@ -1044,6 +1047,8 @@ static void cli_io_handler(struct appctx *appctx)
*/
appctx->st1 &= ~APPCTX_CLI_ST1_PAYLOAD;
+ if (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && lf)
+ appctx->st1 |= APPCTX_CLI_ST1_SHUT_EXPECTED;
}
}
}
@@ -1082,6 +1087,8 @@ static void cli_io_handler(struct appctx *appctx)
/* no payload, the command is complete: parse the request */
cli_parse_request(appctx);
chunk_reset(appctx->chunk);
+ if (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && lf)
+ appctx->st1 |= APPCTX_CLI_ST1_SHUT_EXPECTED;
}
}