diff options
Diffstat (limited to 'src/cli.c')
-rw-r--r-- | src/cli.c | 41 |
1 files changed, 24 insertions, 17 deletions
@@ -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; } } |