diff options
Diffstat (limited to 'clients/cli/nmcli.c')
-rw-r--r-- | clients/cli/nmcli.c | 321 |
1 files changed, 205 insertions, 116 deletions
diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 6407f50beb..c5e0a03fbd 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -51,6 +51,42 @@ # define NMCLI_VERSION VERSION #endif +#define DEFAULT_PALETTE_INIT \ + [NM_META_COLOR_CONNECTION_ACTIVATED] = "32", \ + [NM_META_COLOR_CONNECTION_ACTIVATING] = "33", \ + [NM_META_COLOR_CONNECTION_DISCONNECTING] = "31", \ + [NM_META_COLOR_CONNECTION_INVISIBLE] = "2", \ + [NM_META_COLOR_CONNECTIVITY_FULL] = "32", \ + [NM_META_COLOR_CONNECTIVITY_LIMITED] = "33", \ + [NM_META_COLOR_CONNECTIVITY_NONE] = "31", \ + [NM_META_COLOR_CONNECTIVITY_PORTAL] = "33", \ + [NM_META_COLOR_DEVICE_ACTIVATED] = "32", \ + [NM_META_COLOR_DEVICE_ACTIVATING] = "33", \ + [NM_META_COLOR_DEVICE_DISCONNECTED] = "31", \ + [NM_META_COLOR_DEVICE_FIRMWARE_MISSING] = "31", \ + [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "31", \ + [NM_META_COLOR_DEVICE_UNAVAILABLE] = "2", \ + [NM_META_COLOR_MANAGER_RUNNING] = "32", \ + [NM_META_COLOR_MANAGER_STARTING] = "33", \ + [NM_META_COLOR_MANAGER_STOPPED] = "31", \ + [NM_META_COLOR_PERMISSION_AUTH] = "33", \ + [NM_META_COLOR_PERMISSION_NO] = "31", \ + [NM_META_COLOR_PERMISSION_YES] = "32", \ + [NM_META_COLOR_STATE_ASLEEP] = "31", \ + [NM_META_COLOR_STATE_CONNECTED_GLOBAL] = "32", \ + [NM_META_COLOR_STATE_CONNECTED_LOCAL] = "32", \ + [NM_META_COLOR_STATE_CONNECTED_SITE] = "32", \ + [NM_META_COLOR_STATE_CONNECTING] = "33", \ + [NM_META_COLOR_STATE_DISCONNECTED] = "31", \ + [NM_META_COLOR_STATE_DISCONNECTING] = "33", \ + [NM_META_COLOR_WIFI_SIGNAL_EXCELLENT] = "32", \ + [NM_META_COLOR_WIFI_SIGNAL_FAIR] = "35", \ + [NM_META_COLOR_WIFI_SIGNAL_GOOD] = "33", \ + [NM_META_COLOR_WIFI_SIGNAL_POOR] = "36", \ + [NM_META_COLOR_WIFI_SIGNAL_UNKNOWN] = "2", \ + [NM_META_COLOR_ENABLED] = "32", \ + [NM_META_COLOR_DISABLED] = "31", \ + NmCli nm_cli = { .client = NULL, @@ -74,40 +110,7 @@ NmCli nm_cli = { .nmc_config.show_secrets = FALSE, .nmc_config.in_editor = FALSE, .nmc_config.palette = { - [NM_META_COLOR_CONNECTION_ACTIVATED] = "32", - [NM_META_COLOR_CONNECTION_ACTIVATING] = "33", - [NM_META_COLOR_CONNECTION_DISCONNECTING] = "31", - [NM_META_COLOR_CONNECTION_INVISIBLE] = "2", - [NM_META_COLOR_CONNECTIVITY_FULL] = "32", - [NM_META_COLOR_CONNECTIVITY_LIMITED] = "33", - [NM_META_COLOR_CONNECTIVITY_NONE] = "31", - [NM_META_COLOR_CONNECTIVITY_PORTAL] = "33", - [NM_META_COLOR_DEVICE_ACTIVATED] = "32", - [NM_META_COLOR_DEVICE_ACTIVATING] = "33", - [NM_META_COLOR_DEVICE_DISCONNECTED] = "31", - [NM_META_COLOR_DEVICE_FIRMWARE_MISSING] = "31", - [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "31", - [NM_META_COLOR_DEVICE_UNAVAILABLE] = "2", - [NM_META_COLOR_MANAGER_RUNNING] = "32", - [NM_META_COLOR_MANAGER_STARTING] = "33", - [NM_META_COLOR_MANAGER_STOPPED] = "31", - [NM_META_COLOR_PERMISSION_AUTH] = "33", - [NM_META_COLOR_PERMISSION_NO] = "31", - [NM_META_COLOR_PERMISSION_YES] = "32", - [NM_META_COLOR_STATE_ASLEEP] = "31", - [NM_META_COLOR_STATE_CONNECTED_GLOBAL] = "32", - [NM_META_COLOR_STATE_CONNECTED_LOCAL] = "32", - [NM_META_COLOR_STATE_CONNECTED_SITE] = "32", - [NM_META_COLOR_STATE_CONNECTING] = "33", - [NM_META_COLOR_STATE_DISCONNECTED] = "31", - [NM_META_COLOR_STATE_DISCONNECTING] = "33", - [NM_META_COLOR_WIFI_SIGNAL_EXCELLENT] = "32", - [NM_META_COLOR_WIFI_SIGNAL_FAIR] = "35", - [NM_META_COLOR_WIFI_SIGNAL_GOOD] = "33", - [NM_META_COLOR_WIFI_SIGNAL_POOR] = "36", - [NM_META_COLOR_WIFI_SIGNAL_UNKNOWN] = "2", - [NM_META_COLOR_ENABLED] = "32", - [NM_META_COLOR_DISABLED] = "31", + DEFAULT_PALETTE_INIT }, .editor_status_line = FALSE, .editor_save_confirmation = TRUE, @@ -337,76 +340,162 @@ typedef enum { NMC_USE_COLOR_NO, } NmcColorOption; -/* Checks whether a particular terminal-colors.d(5) file (.enabled, .disabled or .schem) - * exists. If contents is non-NULL, it returns the content. */ -static gboolean -check_colors_file (NmCli *nmc, NmcColorOption *color_option, - const char *base_dir, const char *name, const char *term, const char *type, - char **contents) +static char * +check_colors_construct_filename (const char *base_dir, + const char *name, + const char *term, + const char *type) { - char *filename; - gboolean exists; - - filename = g_strdup_printf ("%s/terminal-colors.d/%s%s%s%s%s", - base_dir, - name ? name : "", - term ? "@" : "", term ? term : "", - (name || term) ? "." : "", - type); - if (contents) - exists = g_file_get_contents (filename, contents, NULL, NULL); - else - exists = g_file_test (filename, G_FILE_TEST_EXISTS); - g_free (filename); + return g_strdup_printf ("%s/terminal-colors.d/%s%s%s%s%s", + base_dir, + name ? name : "", + term ? "@" : "", term ? term : "", + (name || term) ? "." : "", + type); +} + +static NmcColorOption +check_colors_check_enabled_one_file (const char *base_dir, + const char *name, + const char *term) +{ + gs_free char *filename_e = NULL; + gs_free char *filename_d = NULL; + + filename_e = check_colors_construct_filename (base_dir, name, term, "enable"); + if (g_file_test (filename_e, G_FILE_TEST_EXISTS)) + return NMC_USE_COLOR_YES; + + filename_d = check_colors_construct_filename (base_dir, name, term, "disable"); + if (g_file_test (filename_d, G_FILE_TEST_EXISTS)) + return NMC_USE_COLOR_NO; - return exists; + return NMC_USE_COLOR_AUTO; } -static void -check_colors_files_for_term (NmCli *nmc, NmcColorOption *color_option, - const char *base_dir, const char *name, const char *term) +static char * +check_colors_check_palette_one_file (const char *base_dir, + const char *name, + const char *term) { - if ( *color_option == NMC_USE_COLOR_AUTO - && check_colors_file (nmc, color_option, base_dir, name, term, "enable", NULL)) { - *color_option = NMC_USE_COLOR_YES; - } + gs_free char *filename = check_colors_construct_filename (base_dir, name, term, "schem"); + char *contents; - if ( *color_option == NMC_USE_COLOR_AUTO - && check_colors_file (nmc, color_option, base_dir, name, term, "disable", NULL)) { - *color_option = NMC_USE_COLOR_NO; - } + if (g_file_get_contents (filename, &contents, NULL, NULL)) + return contents; + return NULL; +} - if (*color_option == NMC_USE_COLOR_NO) { - /* No need to bother any further. */ - return; - } +static gboolean +check_colors_check_enabled (const char *base_dir_1, const char *base_dir_2, const char *name, const char *term) +{ + int i; + + if (term && strchr (term, '/')) + term = NULL; + +#define CHECK_AND_RETURN(cmd) \ + G_STMT_START { \ + NmcColorOption _color_option; \ + \ + _color_option = (cmd); \ + if (_color_option != NMC_USE_COLOR_AUTO) \ + return _color_option == NMC_USE_COLOR_YES; \ + } G_STMT_END + + for (i = 0; i < 2; i++) { + const char *base_dir = (i == 0 ? base_dir_1 : base_dir_2); - if (nmc->palette_buffer == NULL) - check_colors_file (nmc, color_option, base_dir, name, term, "schem", &nmc->palette_buffer); + if (!base_dir) + continue; + if (name && term) + CHECK_AND_RETURN (check_colors_check_enabled_one_file (base_dir, name, term)); + if (name) + CHECK_AND_RETURN (check_colors_check_enabled_one_file (base_dir, name, NULL)); + if (term) + CHECK_AND_RETURN (check_colors_check_enabled_one_file (base_dir, NULL, term)); + if (TRUE) + CHECK_AND_RETURN (check_colors_check_enabled_one_file (base_dir, NULL, NULL)); + } +#undef CHECK_AND_RETURN + return TRUE; } -static void -check_colors_files_for_name (NmCli *nmc, NmcColorOption *color_option, - const char *base_dir, const char *name) +static char * +check_colors_check_palette (const char *base_dir_1, const char *base_dir_2, const char *name, const char *term) { - const gchar *term; + int i; - /* Take a shortcut if the directory is not there. */ - if (!g_file_test (base_dir, G_FILE_TEST_EXISTS)) - return; + if (term && strchr (term, '/')) + term = NULL; - term = g_getenv ("TERM"); - if (term) - check_colors_files_for_term (nmc, color_option, base_dir, name, term); - check_colors_files_for_term (nmc, color_option, base_dir, name, NULL); +#define CHECK_AND_RETURN(cmd) \ + G_STMT_START { \ + char *_palette; \ + \ + _palette = (cmd); \ + if (_palette) \ + return _palette; \ + } G_STMT_END + + for (i = 0; i < 2; i++) { + const char *base_dir = (i == 0 ? base_dir_1 : base_dir_2); + + if (!base_dir) + continue; + if (name && term) + CHECK_AND_RETURN (check_colors_check_palette_one_file (base_dir, name, term)); + if (name) + CHECK_AND_RETURN (check_colors_check_palette_one_file (base_dir, name, NULL)); + if (term) + CHECK_AND_RETURN (check_colors_check_palette_one_file (base_dir, NULL, term)); + if (TRUE) + CHECK_AND_RETURN (check_colors_check_palette_one_file (base_dir, NULL, NULL)); + } +#undef CHECK_AND_RETURN + return NULL; } -static void -check_colors_files_for_base_dir (NmCli *nmc, NmcColorOption *color_option, - const char *base_dir) +static gboolean +check_colors (NmcColorOption color_option, + char **out_palette_str) { - check_colors_files_for_name (nmc, color_option, base_dir, "nmcli"); - check_colors_files_for_name (nmc, color_option, base_dir, NULL); + const char *base_dir_1, *base_dir_2; + const char *const NAME = "nmcli"; + const char *term; + + *out_palette_str = NULL; + + if (!NM_IN_SET (color_option, NMC_USE_COLOR_AUTO, NMC_USE_COLOR_YES)) { + /* nothing to do. Colors are disabled. */ + return FALSE; + } + + term = g_getenv ("TERM"); + + if (color_option == NMC_USE_COLOR_AUTO) { + if ( nm_streq0 (term, "dumb") + || !isatty (STDOUT_FILENO)) + return FALSE; + } + + base_dir_1 = g_get_user_config_dir (); + base_dir_2 = ""SYSCONFDIR; + + if (base_dir_1) { + if ( nm_streq (base_dir_1, base_dir_2) + || !g_file_test (base_dir_1, G_FILE_TEST_EXISTS)) + base_dir_1 = NULL; + } + if (!g_file_test (base_dir_2, G_FILE_TEST_EXISTS)) + base_dir_2 = NULL; + + if ( color_option == NMC_USE_COLOR_AUTO + && !check_colors_check_enabled (base_dir_1, base_dir_2, NAME, term)) + return FALSE; + + *out_palette_str = check_colors_check_palette (base_dir_1, base_dir_2, NAME, term); + return TRUE; } static const char * @@ -415,7 +504,7 @@ resolve_color_alias (const char *color) static const struct { const char *name; const char *alias; - } aliases[] = { + } const aliases[] = { { "reset", "0" }, { "bold", "1" }, { "white", "1;37" }, @@ -455,12 +544,17 @@ resolve_color_alias (const char *color) } static gboolean -parse_color_scheme (NmCli *nmc, GError **error) +parse_color_scheme (char *palette_buffer, + const char **palette /* _NM_META_COLOR_NUM elements */, + GError **error) { - char *p = nmc->palette_buffer; + char *p = palette_buffer; const char *name; const char *color; - const char *map[_NM_META_COLOR_NUM] = { + const char *tmp_palette[_NM_META_COLOR_NUM] = { + DEFAULT_PALETTE_INIT + }; + static const char *const map[_NM_META_COLOR_NUM] = { [NM_META_COLOR_NONE] = NULL, [NM_META_COLOR_CONNECTION_ACTIVATED] = "connection-activated", [NM_META_COLOR_CONNECTION_ACTIVATING] = "connection-activating", @@ -573,7 +667,7 @@ parse_color_scheme (NmCli *nmc, GError **error) /* All good, set the palette entry. */ for (i = NM_META_COLOR_NONE + 1; i < _NM_META_COLOR_NUM; i++) { if (strcmp (map[i], name) == 0) { - nmc->nmc_config_mutable.palette[i] = resolve_color_alias (color); + tmp_palette[i] = resolve_color_alias (color); break; } } @@ -581,38 +675,30 @@ parse_color_scheme (NmCli *nmc, GError **error) g_debug ("Ignoring an unrecognized color: '%s'\n", name); } + memcpy (palette, tmp_palette, sizeof (tmp_palette)); return TRUE; } static void -set_colors (NmCli *nmc, NmcColorOption color_option) +set_colors (NmcColorOption color_option, + bool *out_use_colors, + char **out_palette_buffer, + const char **palette /* _NM_META_COLOR_NUM elements */) { - GError *error = NULL; - - if (color_option == NMC_USE_COLOR_AUTO) { - if ( g_strcmp0 (g_getenv ("TERM"), "dumb") == 0 - || !isatty (STDOUT_FILENO)) - color_option = NMC_USE_COLOR_NO; - } + gs_free char *palette_str = NULL; + gboolean use_colors; - check_colors_files_for_base_dir (nmc, &color_option, g_get_user_config_dir ()); - check_colors_files_for_base_dir (nmc, &color_option, SYSCONFDIR); + use_colors = check_colors (color_option, &palette_str); - switch (color_option) { - case NMC_USE_COLOR_YES: - case NMC_USE_COLOR_AUTO: - nmc->nmc_config_mutable.use_colors = TRUE; - break; - case NMC_USE_COLOR_NO: - nmc->nmc_config_mutable.use_colors = FALSE; - break; - } + *out_use_colors = use_colors; + if (use_colors && palette_str) { + GError *error = NULL; - if (nmc->nmc_config_mutable.use_colors && nmc->palette_buffer) { - if (!parse_color_scheme (nmc, &error)) { + if (!parse_color_scheme (palette_str, palette, &error)) { g_debug ("Error parsing color scheme: %s", error->message); g_error_free (error); - } + } else + *out_palette_buffer = g_steal_pointer (&palette_str); } } @@ -771,7 +857,10 @@ process_command_line (NmCli *nmc, int argc, char **argv) if (nmc->required_fields) nmc->nmc_config_mutable.overview = FALSE; - set_colors (nmc, colors); + set_colors (colors, + &nmc->nmc_config_mutable.use_colors, + &nmc->palette_buffer, + nmc->nmc_config_mutable.palette); /* Now run the requested command */ nmc_do_cmd (nmc, nmcli_cmds, *argv, argc, argv); |