diff --git a/cli/src/common.c b/cli/src/common.c index 1a63504eff..869ffe65e4 100644 --- a/cli/src/common.c +++ b/cli/src/common.c @@ -16,16 +16,20 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2012 Red Hat, Inc. + * (C) Copyright 2012 - 2014 Red Hat, Inc. */ #include "config.h" #include #include +#include #include #include +#include +#include + #include "common.h" #include "utils.h" @@ -1026,3 +1030,74 @@ nmc_find_connection (GSList *list, return found; } +/** + * nmc_cleanup_readline: + * + * Cleanup readline when nmcli is terminated with a signal. + * It makes sure the terminal is not garbled. + */ +void +nmc_cleanup_readline (void) +{ + rl_free_line_state (); + rl_cleanup_after_signal (); +} + +/** + * nmc_readline: + * @prompt: prompt to print (telling user what to enter) + * @add_to_history: whether the user input should be added to history + * + * Wrapper around libreadline's readline() function. + * + * Returns: the user provided string. In case the user entered empty string, + * this function returns NULL. + */ +char * +nmc_readline (const char *prompt, gboolean add_to_history) +{ + char *str; + + str = readline (prompt); + /* Return NULL, not empty string */ + if (str && *str == '\0') { + g_free (str); + str = NULL; + } + + if (add_to_history && str && *str) + add_history (str); + + return str; +} + +/** + * nmc_rl_gen_func_basic: + * @text: text to complete + * @state: readline state; says whether start from scratch (state == 0) + * @words: strings for completion + * + * Basic function generating list of completion strings for readline. + * See e.g. http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC49 + */ +char * +nmc_rl_gen_func_basic (char *text, int state, const char **words) +{ + static int list_idx, len; + const char *name; + + if (!state) { + list_idx = 0; + len = strlen (text); + } + + /* Return the next name which partially matches one from the 'words' list. */ + while ((name = words[list_idx])) { + list_idx++; + + if (strncmp (name, text, len) == 0) + return g_strdup (name); + } + return NULL; +} + diff --git a/cli/src/common.h b/cli/src/common.h index 3b5f9986dc..58597472b9 100644 --- a/cli/src/common.h +++ b/cli/src/common.h @@ -59,4 +59,8 @@ NMConnection *nmc_find_connection (GSList *list, const char *filter_val, GSList **start); +void nmc_cleanup_readline (void); +char *nmc_readline (const char *prompt, gboolean add_to_history); +char *nmc_rl_gen_func_basic (char *text, int state, const char **words); + #endif /* NMC_COMMON_H */ diff --git a/cli/src/connections.c b/cli/src/connections.c index 835a9728e7..ac05d32293 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -5255,34 +5255,13 @@ set_deftext (void) return 0; } -static char * -gen_func_basic (char *text, int state, const char **words) -{ - static int list_idx, len; - const char *name; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - /* Return the next name which partially matches one from the 'words' list. */ - while ((name = words[list_idx])) { - list_idx++; - - if (strncmp (name, text, len) == 0) - return g_strdup (name); - } - return NULL; -} - static char * gen_nmcli_cmds_menu (char *text, int state) { const char *words[] = { "goto", "set", "remove", "describe", "print", "verify", "save", "activate", "back", "help", "quit", "nmcli", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * @@ -5291,49 +5270,49 @@ gen_nmcli_cmds_submenu (char *text, int state) const char *words[] = { "set", "add", "change", "remove", "describe", "print", "back", "help", "quit", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_cmd_nmcli (char *text, int state) { const char *words[] = { "status-line", "save-confirmation", "prompt-color", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_cmd_nmcli_prompt_color (char *text, int state) { const char *words[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_func_bool_values (char *text, int state) { const char *words[] = { "yes", "no", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_cmd_verify0 (char *text, int state) { const char *words[] = { "all", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_cmd_print2 (char *text, int state) { const char *words[] = { "setting", "connection", "all", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * gen_cmd_save (char *text, int state) { const char *words[] = { "persistent", "temporary", NULL }; - return gen_func_basic (text, state, words); + return nmc_rl_gen_func_basic (text, state, words); } static char * @@ -5419,7 +5398,7 @@ gen_property_names (char *text, int state) if (setting) { valid_props = nmc_setting_get_valid_properties (setting); - ret = gen_func_basic (text, state, (const char **) valid_props); + ret = nmc_rl_gen_func_basic (text, state, (const char **) valid_props); } g_strfreev (strv); @@ -5455,7 +5434,7 @@ gen_compat_devices (char *text, int state) } compatible_devices[j] = NULL; - ret = gen_func_basic (text, state, compatible_devices); + ret = nmc_rl_gen_func_basic (text, state, compatible_devices); g_free (compatible_devices); return ret; @@ -5483,7 +5462,7 @@ gen_vpn_uuids (char *text, int state) } uuids[i] = NULL; - ret = gen_func_basic (text, state, uuids); + ret = nmc_rl_gen_func_basic (text, state, uuids); g_free (uuids); return ret; @@ -5811,32 +5790,6 @@ nmcli_editor_tab_completion (char *text, int start, int end) return match_array; } -void -nmc_cleanup_readline (void) -{ - rl_free_line_state (); - rl_cleanup_after_signal (); -} - -/* Reads data from user and adds it to history */ -static char * -readline_x (const char *prompt, gboolean add_to_history) -{ - char *str; - - str = readline (prompt); - /* Return NULL, not empty string */ - if (str && *str == '\0') { - g_free (str); - str = NULL; - } - - if (add_to_history && str && *str) - add_history (str); - - return str; -} - #define NMCLI_EDITOR_HISTORY ".nmcli-history" static void @@ -6513,7 +6466,7 @@ property_edit_submenu (NmCli *nmc, if (nmc->editor_status_line) editor_show_status_line (connection, dirty, temp_changes); - cmd_property_user = readline_x (prompt, TRUE); + cmd_property_user = nmc_readline (prompt, TRUE); if (!cmd_property_user || *cmd_property_user == '\0') continue; cmdsub = parse_editor_sub_cmd (g_strstrip (cmd_property_user), &cmd_property_arg); @@ -6527,7 +6480,7 @@ property_edit_submenu (NmCli *nmc, */ if (!cmd_property_arg) { tmp_prompt = g_strdup_printf (_("Enter '%s' value: "), prop_name); - prop_val_user = readline_x (tmp_prompt, TRUE); + prop_val_user = nmc_readline (tmp_prompt, TRUE); g_free (tmp_prompt); } else prop_val_user = g_strdup (cmd_property_arg); @@ -6556,7 +6509,7 @@ property_edit_submenu (NmCli *nmc, rl_startup_hook = set_deftext; pre_input_deftext = nmc_setting_get_property_out2in (curr_setting, prop_name, NULL); tmp_prompt = g_strdup_printf (_("Edit '%s' value: "), prop_name); - prop_val_user = readline_x (tmp_prompt, TRUE); + prop_val_user = nmc_readline (tmp_prompt, TRUE); nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value); nmc_property_set_default_value (curr_setting, prop_name); @@ -6744,7 +6697,7 @@ ask_check_setting (const char *arg, if (!arg) { printf (_("Available settings: %s\n"), valid_settings_str); - setting_name_user = readline_x (EDITOR_PROMPT_SETTING, TRUE); + setting_name_user = nmc_readline (EDITOR_PROMPT_SETTING, TRUE); } else setting_name_user = g_strdup (arg); @@ -6770,7 +6723,7 @@ ask_check_property (const char *arg, if (!arg) { printf (_("Available properties: %s\n"), valid_props_str); - prop_name_user = readline_x (EDITOR_PROMPT_PROPERTY, TRUE); + prop_name_user = nmc_readline (EDITOR_PROMPT_PROPERTY, TRUE); if (prop_name_user) g_strstrip (prop_name_user); } else @@ -6914,7 +6867,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t editor_show_status_line (connection, dirty, temp_changes); /* Read user input */ - cmd_user = readline_x (menu_ctx.main_prompt, TRUE); + cmd_user = nmc_readline (menu_ctx.main_prompt, TRUE); /* Get the remote connection again, it may have disapeared */ removed = refresh_remote_connection (&weak, &rem_con); @@ -6952,7 +6905,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t printf (_("Allowed values for '%s' property: %s\n"), prop_name, avals); tmp_prompt = g_strdup_printf (_("Enter '%s' value: "), prop_name); - prop_val_user = readline_x (tmp_prompt, TRUE); + prop_val_user = nmc_readline (tmp_prompt, TRUE); g_free (tmp_prompt); /* Set property value */ @@ -7010,7 +6963,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t printf (_("Allowed values for '%s' property: %s\n"), prop_name, avals); tmp_prompt = g_strdup_printf (_("Enter '%s' value: "), prop_name); - cmd_arg_v = readline_x (tmp_prompt, TRUE); + cmd_arg_v = nmc_readline (tmp_prompt, TRUE); g_free (tmp_prompt); } @@ -7790,7 +7743,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) printf (_("Error: invalid connection type; %s\n"), err1->message); g_clear_error (&err1); - type_ask = readline_x (EDITOR_PROMPT_CON_TYPE, TRUE); + type_ask = nmc_readline (EDITOR_PROMPT_CON_TYPE, TRUE); type = type_ask = type_ask ? g_strstrip (type_ask) : NULL; connection_type = check_valid_name (type_ask, nmc_valid_connection_types, &err1); g_free (type_ask); diff --git a/cli/src/connections.h b/cli/src/connections.h index 4ccd8c81cc..c736859799 100644 --- a/cli/src/connections.h +++ b/cli/src/connections.h @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 Red Hat, Inc. + * (C) Copyright 2010 - 2014 Red Hat, Inc. */ #ifndef NMC_CONNECTIONS_H @@ -24,6 +24,4 @@ NMCResultCode do_connections (NmCli *nmc, int argc, char **argv); -void nmc_cleanup_readline (void); - #endif /* NMC_CONNECTIONS_H */ diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c index 1e447485ba..66288c20ac 100644 --- a/cli/src/nmcli.c +++ b/cli/src/nmcli.c @@ -37,6 +37,7 @@ #include "nmcli.h" #include "utils.h" +#include "common.h" #include "connections.h" #include "devices.h" #include "network-manager.h"