diff options
Diffstat (limited to 'src/cli.c')
-rw-r--r-- | src/cli.c | 133 |
1 files changed, 105 insertions, 28 deletions
@@ -12,18 +12,19 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ -#include <config.h> -#include <stdlib.h> +#include <nft.h> + #include <stdio.h> #include <stdarg.h> #include <unistd.h> #include <errno.h> -#include <string.h> #include <ctype.h> #include <limits.h> #ifdef HAVE_LIBREADLINE #include <readline/readline.h> #include <readline/history.h> +#elif defined(HAVE_LIBEDIT) +#include <editline/readline.h> #else #include <linenoise.h> #endif @@ -35,6 +36,15 @@ #define CMDLINE_PROMPT "nft> " #define CMDLINE_QUIT "quit" +static bool cli_quit; +static int cli_rc; + +static void __cli_exit(int rc) +{ + cli_quit = true; + cli_rc = rc; +} + static char histfile[PATH_MAX]; static void @@ -48,7 +58,26 @@ init_histfile(void) snprintf(histfile, sizeof(histfile), "%s/%s", home, CMDLINE_HISTFILE); } -#ifdef HAVE_LIBREADLINE +#if defined(HAVE_LIBREADLINE) +static void nft_rl_prompt_save(void) +{ + rl_save_prompt(); + rl_clear_message(); + rl_set_prompt(".... "); +} +#define nft_rl_prompt_restore rl_restore_prompt +#elif defined(HAVE_LIBEDIT) +static void nft_rl_prompt_save(void) +{ + rl_set_prompt(".... "); +} +static void nft_rl_prompt_restore(void) +{ + rl_set_prompt("nft> "); +} +#endif + +#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) static struct nft_ctx *cli_nft; static char *multiline; @@ -72,17 +101,15 @@ static char *cli_append_multiline(char *line) if (multiline == NULL) { multiline = line; - rl_save_prompt(); - rl_clear_message(); - rl_set_prompt(".... "); + nft_rl_prompt_save(); } else { len += strlen(multiline); s = malloc(len + 1); if (!s) { fprintf(stderr, "%s:%u: Memory allocation failure\n", __FILE__, __LINE__); - cli_exit(); - exit(EXIT_FAILURE); + cli_exit(EXIT_FAILURE); + return NULL; } snprintf(s, len + 1, "%s%s", multiline, line); free(multiline); @@ -93,7 +120,7 @@ static char *cli_append_multiline(char *line) if (complete) { line = multiline; multiline = NULL; - rl_restore_prompt(); + nft_rl_prompt_restore(); } return line; } @@ -106,8 +133,7 @@ static void cli_complete(char *line) if (line == NULL) { printf("\n"); - cli_exit(); - exit(0); + return cli_exit(0); } line = cli_append_multiline(line); @@ -120,10 +146,8 @@ static void cli_complete(char *line) if (*c == '\0') return; - if (!strcmp(line, CMDLINE_QUIT)) { - cli_exit(); - exit(0); - } + if (!strcmp(line, CMDLINE_QUIT)) + return cli_exit(0); /* avoid duplicate history entries */ hist = history_get(history_length); @@ -133,6 +157,9 @@ static void cli_complete(char *line) nft_run_cmd_from_buffer(cli_nft, line); free(line); } +#endif + +#if defined(HAVE_LIBREADLINE) static char **cli_completion(const char *text, int start, int end) { @@ -142,7 +169,7 @@ static char **cli_completion(const char *text, int start, int end) int cli_init(struct nft_ctx *nft) { cli_nft = nft; - rl_readline_name = "nft"; + rl_readline_name = (char *)"nft"; rl_instream = stdin; rl_outstream = stdout; @@ -154,45 +181,95 @@ int cli_init(struct nft_ctx *nft) read_history(histfile); history_set_pos(history_length); - while (true) + while (!cli_quit) rl_callback_read_char(); - return 0; + + return cli_rc; } -void cli_exit(void) +void cli_exit(int rc) { rl_callback_handler_remove(); rl_deprep_terminal(); write_history(histfile); + + __cli_exit(rc); +} + +#elif defined(HAVE_LIBEDIT) + +int cli_init(struct nft_ctx *nft) +{ + char *line; + + cli_nft = nft; + rl_readline_name = (char *)"nft"; + rl_instream = stdin; + rl_outstream = stdout; + + init_histfile(); + + read_history(histfile); + history_set_pos(history_length); + + rl_set_prompt(CMDLINE_PROMPT); + while (!cli_quit) { + line = readline(rl_prompt); + if (!line) { + cli_exit(0); + break; + } + line = cli_append_multiline(line); + if (!line) + continue; + + cli_complete(line); + } + + return cli_rc; +} + +void cli_exit(int rc) +{ + rl_deprep_terminal(); + write_history(histfile); + + __cli_exit(rc); } -#else /* !HAVE_LIBREADLINE */ +#else /* HAVE_LINENOISE */ int cli_init(struct nft_ctx *nft) { - int quit = 0; char *line; init_histfile(); linenoiseHistoryLoad(histfile); linenoiseSetMultiLine(1); - while (!quit && (line = linenoise(CMDLINE_PROMPT)) != NULL) { + while (!cli_quit) { + line = linenoise(CMDLINE_PROMPT); + if (!line) { + cli_exit(0); + break; + } if (strcmp(line, CMDLINE_QUIT) == 0) { - quit = 1; + cli_exit(0); } else if (line[0] != '\0') { linenoiseHistoryAdd(line); nft_run_cmd_from_buffer(nft, line); } linenoiseFree(line); } - cli_exit(); - exit(0); + + return cli_rc; } -void cli_exit(void) +void cli_exit(int rc) { linenoiseHistorySave(histfile); + + __cli_exit(rc); } -#endif /* HAVE_LIBREADLINE */ +#endif /* HAVE_LINENOISE */ |