diff --git a/include/haproxy/cli-t.h b/include/haproxy/cli-t.h index 7570954b2..5d2c07977 100644 --- a/include/haproxy/cli-t.h +++ b/include/haproxy/cli-t.h @@ -58,6 +58,8 @@ enum { CLI_ST_PRINT_ERR, /* display const error in cli->msg */ CLI_ST_PRINT_DYN, /* display dynamic message in cli->err. After the display, free the pointer */ CLI_ST_PRINT_DYNERR, /* display dynamic error in cli->err. After the display, free the pointer */ + CLI_ST_PRINT_UMSG, /* display usermsgs_ctx buffer. After the display, usermsgs_ctx is resetted. */ + CLI_ST_PRINT_UMSGERR, /* display usermsgs_ctx buffer as error. After the display, usermsgs_ctx is resetted. */ CLI_ST_CALLBACK, /* custom callback pointer */ }; diff --git a/include/haproxy/cli.h b/include/haproxy/cli.h index bb5c23c98..6b049b855 100644 --- a/include/haproxy/cli.h +++ b/include/haproxy/cli.h @@ -108,5 +108,31 @@ static inline int cli_dynerr(struct appctx *appctx, char *err) return 1; } +/* updates the CLI's context to log messages stored in thread-local + * usermsgs_ctx at level. usermsgs_ctx will be resetted when done. + * This is for use in CLI parsers to deal with quick response messages. + * + * Always returns 1. + */ +static inline int cli_umsg(struct appctx *appctx, int severity) +{ + struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); + + ctx->severity = severity; + appctx->st0 = CLI_ST_PRINT_UMSG; + return 1; +} + +/* updates the CLI's context to log messages stored in thread-local + * usermsgs_ctx using error level. usermsgs_ctx will be resetted when done. + * This is for use in CLI parsers to deal with quick response messages. + * + * Always returns 1. + */ +static inline int cli_umsgerr(struct appctx *appctx) +{ + appctx->st0 = CLI_ST_PRINT_UMSGERR; + return 1; +} #endif /* _HAPROXY_CLI_H */ diff --git a/src/cli.c b/src/cli.c index 406b850ce..4e7ae1496 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1042,6 +1042,8 @@ static void cli_io_handler(struct appctx *appctx) case CLI_ST_PRINT_ERR: /* print const error in msg */ case CLI_ST_PRINT_DYN: /* print dyn message in msg, free */ case CLI_ST_PRINT_DYNERR: /* print dyn error in err, free */ + case CLI_ST_PRINT_UMSG: /* print usermsgs_ctx and reset it */ + case CLI_ST_PRINT_UMSGERR: /* print usermsgs_ctx as error and reset it */ /* the message is in the svcctx */ ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); if (appctx->st0 == CLI_ST_PRINT || appctx->st0 == CLI_ST_PRINT_ERR) { @@ -1058,6 +1060,12 @@ static void cli_io_handler(struct appctx *appctx) msg = "Out of memory.\n"; } } + else if (appctx->st0 == CLI_ST_PRINT_UMSG || + appctx->st0 == CLI_ST_PRINT_UMSGERR) { + sev = appctx->st0 == CLI_ST_PRINT_UMSGERR ? + LOG_ERR : ctx->severity; + msg = usermsgs_str(); + } else { sev = LOG_ERR; msg = "Internal error.\n"; @@ -1068,6 +1076,10 @@ static void cli_io_handler(struct appctx *appctx) appctx->st0 == CLI_ST_PRINT_DYNERR) { ha_free(&ctx->err); } + else if (appctx->st0 == CLI_ST_PRINT_UMSG || + appctx->st0 == CLI_ST_PRINT_UMSGERR) { + usermsgs_clr(NULL); + } appctx->st0 = CLI_ST_PROMPT; } else @@ -1198,6 +1210,9 @@ static void cli_release_handler(struct appctx *appctx) ha_free(&ctx->err); } + else if (appctx->st0 == CLI_ST_PRINT_UMSG || appctx->st0 == CLI_ST_PRINT_UMSGERR) { + usermsgs_clr(NULL); + } } /* This function dumps all environmnent variables to the buffer. It returns 0