diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /clients/cli/nmcli.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'clients/cli/nmcli.c')
| -rw-r--r-- | clients/cli/nmcli.c | 1654 |
1 files changed, 824 insertions, 830 deletions
diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 0ae4a4de..740cc604 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Jiri Klimes <jklimes@redhat.com> * Copyright (C) 2010 - 2018 Red Hat, Inc. @@ -28,985 +28,979 @@ #include "settings.h" #if defined(NM_DIST_VERSION) -# define NMCLI_VERSION NM_DIST_VERSION + #define NMCLI_VERSION NM_DIST_VERSION #else -# define NMCLI_VERSION VERSION + #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_CONNECTION_EXTERNAL] = "32;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_DEVICE_DISABLED] = "31", \ - [NM_META_COLOR_DEVICE_EXTERNAL] = "32;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", \ +#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_CONNECTION_EXTERNAL] = "32;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_DEVICE_DISABLED] = "31", \ + [NM_META_COLOR_DEVICE_EXTERNAL] = "32;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", static NmCli nm_cli = { - .client = NULL, - - .return_value = NMC_RESULT_SUCCESS, - - .timeout = -1, - - .secret_agent = NULL, - .pwds_hash = NULL, - .pk_listener = NULL, - - .should_wait = 0, - .nowait_flag = TRUE, - .nmc_config.print_output = NMC_PRINT_NORMAL, - .nmc_config.multiline_output = FALSE, - .mode_specified = FALSE, - .nmc_config.escape_values = TRUE, - .required_fields = NULL, - .ask = FALSE, - .complete = FALSE, - .nmc_config.show_secrets = FALSE, - .nmc_config.in_editor = FALSE, - .nmc_config.palette = { - DEFAULT_PALETTE_INIT - }, - .editor_status_line = FALSE, - .editor_save_confirmation = TRUE, + .client = NULL, + + .return_value = NMC_RESULT_SUCCESS, + + .timeout = -1, + + .secret_agent = NULL, + .pwds_hash = NULL, + .pk_listener = NULL, + + .should_wait = 0, + .nowait_flag = TRUE, + .nmc_config.print_output = NMC_PRINT_NORMAL, + .nmc_config.multiline_output = FALSE, + .mode_specified = FALSE, + .nmc_config.escape_values = TRUE, + .required_fields = NULL, + .ask = FALSE, + .complete = FALSE, + .nmc_config.show_secrets = FALSE, + .nmc_config.in_editor = FALSE, + .nmc_config.palette = {DEFAULT_PALETTE_INIT}, + .editor_status_line = FALSE, + .editor_save_confirmation = TRUE, }; -const NmCli *const nm_cli_global_readline = &nm_cli; +const NmCli *const nm_cli_global_readline = &nm_cli; const NmCli *const nmc_meta_environment_arg = &nm_cli; /*****************************************************************************/ typedef struct { - NmCli *nmc; - int argc; - char **argv; + NmCli *nmc; + int argc; + char **argv; } ArgsInfo; /* --- Global variables --- */ -GMainLoop *loop = NULL; +GMainLoop * loop = NULL; struct termios termios_orig; -NM_CACHED_QUARK_FCN ("nmcli-error-quark", nmcli_error_quark) +NM_CACHED_QUARK_FCN("nmcli-error-quark", nmcli_error_quark); static void -complete_field_setting (GHashTable *h, NMMetaSettingType setting_type) +complete_field_setting(GHashTable *h, NMMetaSettingType setting_type) { - const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[setting_type]; - guint i; - - for (i = 0; i < setting_info->properties_num; i++) { - g_hash_table_add (h, g_strdup_printf ("%s.%s", - setting_info->general->setting_name, - setting_info->properties[i]->property_name)); - } + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[setting_type]; + guint i; + + for (i = 0; i < setting_info->properties_num; i++) { + g_hash_table_add(h, + g_strdup_printf("%s.%s", + setting_info->general->setting_name, + setting_info->properties[i]->property_name)); + } } static void -complete_field (GHashTable *h, const NmcMetaGenericInfo *const*field) +complete_field(GHashTable *h, const NmcMetaGenericInfo *const *field) { - int i; + int i; - for (i = 0; field[i]; i++) - g_hash_table_add (h, g_strdup (field[i]->name)); + for (i = 0; field[i]; i++) + g_hash_table_add(h, g_strdup(field[i]->name)); } static void -complete_one (gpointer key, gpointer value, gpointer user_data) +complete_one(gpointer key, gpointer value, gpointer user_data) { - const char **option_with_value = user_data; - const char *option = option_with_value[0]; - const char *prefix = option_with_value[1]; - const char *name = key; - const char *last; - - last = strrchr (prefix, ','); - if (last) - last++; - else - last = prefix; - - if ((!*last && !strchr (name, '.')) || matches (last, name)) { - if (option != prefix) { - /* value prefix was not a standalone argument, - * it was part of --option=<value> argument. - * Repeat the part leading to "=". */ - g_print ("%s=", option); - } - g_print ("%.*s%s%s\n", (int)(last-prefix), prefix, name, - strcmp (last, name) == 0 ? "," : ""); - } + const char **option_with_value = user_data; + const char * option = option_with_value[0]; + const char * prefix = option_with_value[1]; + const char * name = key; + const char * last; + + last = strrchr(prefix, ','); + if (last) + last++; + else + last = prefix; + + if ((!*last && !strchr(name, '.')) || matches(last, name)) { + if (option != prefix) { + /* value prefix was not a standalone argument, + * it was part of --option=<value> argument. + * Repeat the part leading to "=". */ + g_print("%s=", option); + } + g_print("%.*s%s%s\n", + (int) (last - prefix), + prefix, + name, + strcmp(last, name) == 0 ? "," : ""); + } } static void -complete_fields (const char *option, const char *prefix) +complete_fields(const char *option, const char *prefix) { - guint i; - GHashTable *h; - const char *option_with_value[2] = { option, prefix }; - - h = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - - complete_field (h, metagen_ip4_config); - complete_field (h, metagen_dhcp_config); - complete_field (h, metagen_ip6_config); - complete_field (h, metagen_con_show); - complete_field (h, metagen_con_active_general); - complete_field (h, metagen_con_active_vpn); - complete_field (h, nmc_fields_con_active_details_groups); - complete_field (h, metagen_device_status); - complete_field (h, metagen_device_detail_general); - complete_field (h, metagen_device_detail_connections); - complete_field (h, metagen_device_detail_capabilities); - complete_field (h, metagen_device_detail_wired_properties); - complete_field (h, metagen_device_detail_wifi_properties); - complete_field (h, metagen_device_detail_wimax_properties); - complete_field (h, nmc_fields_dev_wifi_list); - complete_field (h, nmc_fields_dev_wimax_list); - complete_field (h, nmc_fields_dev_show_master_prop); - complete_field (h, nmc_fields_dev_show_team_prop); - complete_field (h, nmc_fields_dev_show_vlan_prop); - complete_field (h, nmc_fields_dev_show_bluetooth); - complete_field (h, nmc_fields_dev_show_sections); - complete_field (h, nmc_fields_dev_lldp_list); - - for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) - complete_field_setting (h, i); - - g_hash_table_foreach (h, complete_one, (gpointer) &option_with_value[0]); - g_hash_table_destroy (h); + guint i; + GHashTable *h; + const char *option_with_value[2] = {option, prefix}; + + h = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + + complete_field(h, metagen_ip4_config); + complete_field(h, metagen_dhcp_config); + complete_field(h, metagen_ip6_config); + complete_field(h, metagen_con_show); + complete_field(h, metagen_con_active_general); + complete_field(h, metagen_con_active_vpn); + complete_field(h, nmc_fields_con_active_details_groups); + complete_field(h, metagen_device_status); + complete_field(h, metagen_device_detail_general); + complete_field(h, metagen_device_detail_connections); + complete_field(h, metagen_device_detail_capabilities); + complete_field(h, metagen_device_detail_wired_properties); + complete_field(h, metagen_device_detail_wifi_properties); + complete_field(h, metagen_device_detail_wimax_properties); + complete_field(h, nmc_fields_dev_wifi_list); + complete_field(h, nmc_fields_dev_wimax_list); + complete_field(h, nmc_fields_dev_show_master_prop); + complete_field(h, nmc_fields_dev_show_team_prop); + complete_field(h, nmc_fields_dev_show_vlan_prop); + complete_field(h, nmc_fields_dev_show_bluetooth); + complete_field(h, nmc_fields_dev_show_sections); + complete_field(h, nmc_fields_dev_lldp_list); + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + complete_field_setting(h, i); + + g_hash_table_foreach(h, complete_one, (gpointer) &option_with_value[0]); + g_hash_table_destroy(h); } static void -complete_option_with_value (const char *option, const char *prefix, ...) +complete_option_with_value(const char *option, const char *prefix, ...) { - va_list args; - const char *candidate; - - va_start (args, prefix); - while ((candidate = va_arg (args, const char *))) { - if (!*prefix || matches (prefix, candidate)) { - if (option != prefix) { - /* value prefix was not a standalone argument, - * it was part of --option=<value> argument. - * Repeat the part leading to "=". */ - g_print ("%s=", option); - } - g_print ("%s\n", candidate); - } - } - va_end (args); + va_list args; + const char *candidate; + + va_start(args, prefix); + while ((candidate = va_arg(args, const char *))) { + if (!*prefix || matches(prefix, candidate)) { + if (option != prefix) { + /* value prefix was not a standalone argument, + * it was part of --option=<value> argument. + * Repeat the part leading to "=". */ + g_print("%s=", option); + } + g_print("%s\n", candidate); + } + } + va_end(args); } static void -usage (void) +usage(void) { - g_printerr (_("Usage: nmcli [OPTIONS] OBJECT { COMMAND | help }\n" - "\n" - "OPTIONS\n" - " -a, --ask ask for missing parameters\n" - " -c, --colors auto|yes|no whether to use colors in output\n" - " -e, --escape yes|no escape columns separators in values\n" - " -f, --fields <field,...>|all|common specify fields to output\n" - " -g, --get-values <field,...>|all|common shortcut for -m tabular -t -f\n" - " -h, --help print this help\n" - " -m, --mode tabular|multiline output mode\n" - " -o, --overview overview mode\n" - " -p, --pretty pretty output\n" - " -s, --show-secrets allow displaying passwords\n" - " -t, --terse terse output\n" - " -v, --version show program version\n" - " -w, --wait <seconds> set timeout waiting for finishing operations\n" - "\n" - "OBJECT\n" - " g[eneral] NetworkManager's general status and operations\n" - " n[etworking] overall networking control\n" - " r[adio] NetworkManager radio switches\n" - " c[onnection] NetworkManager's connections\n" - " d[evice] devices managed by NetworkManager\n" - " a[gent] NetworkManager secret agent or polkit agent\n" - " m[onitor] monitor NetworkManager changes\n" - "\n")); + g_printerr(_( + "Usage: nmcli [OPTIONS] OBJECT { COMMAND | help }\n" + "\n" + "OPTIONS\n" + " -a, --ask ask for missing parameters\n" + " -c, --colors auto|yes|no whether to use colors in output\n" + " -e, --escape yes|no escape columns separators in values\n" + " -f, --fields <field,...>|all|common specify fields to output\n" + " -g, --get-values <field,...>|all|common shortcut for -m tabular -t -f\n" + " -h, --help print this help\n" + " -m, --mode tabular|multiline output mode\n" + " -o, --overview overview mode\n" + " -p, --pretty pretty output\n" + " -s, --show-secrets allow displaying passwords\n" + " -t, --terse terse output\n" + " -v, --version show program version\n" + " -w, --wait <seconds> set timeout waiting for finishing operations\n" + "\n" + "OBJECT\n" + " g[eneral] NetworkManager's general status and operations\n" + " n[etworking] overall networking control\n" + " r[adio] NetworkManager radio switches\n" + " c[onnection] NetworkManager's connections\n" + " d[evice] devices managed by NetworkManager\n" + " a[gent] NetworkManager secret agent or polkit agent\n" + " m[onitor] monitor NetworkManager changes\n" + "\n")); } static gboolean -matches_arg (NmCli *nmc, - int *argc, - const char *const**argv, - const char *pattern, - char **arg) +matches_arg(NmCli *nmc, int *argc, const char *const **argv, const char *pattern, char **arg) { - gs_free char *opt_free = NULL; - const char *opt = (*argv)[0]; - gs_free char *arg_tmp = NULL; - const char *s; - - nm_assert (opt); - nm_assert (opt[0] == '-'); - nm_assert (!arg || !*arg); - - if (nmc->return_value != NMC_RESULT_SUCCESS) { - /* Don't process further matches if there has been an error. */ - return FALSE; - } - - if (opt[1] == '-') { - /* We know one '-' was already seen by the caller. - * Skip it if there's a second one*/ - opt++; - } - - if (arg) { - /* If there's a "=" separator, replace it with NUL so that matches() - * works and consider the part after it to be the arguemnt's value. */ - s = strchr (opt, '='); - if (s) { - opt = nm_strndup_a (300, opt, s - opt, &opt_free); - arg_tmp = g_strdup (&s[1]); - } - } - - if (!matches (opt, pattern)) - return FALSE; - - if (arg) { - if (arg_tmp) - *arg = g_steal_pointer (&arg_tmp); - else { - /* We need a value, but the option didn't contain a "=<value>" part. - * Proceed to the next argument. */ - if (*argc <= 1) { - g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - (*argc)--; - (*argv)++; - *arg = g_strdup (*argv[0]); - } - } - - return TRUE; + gs_free char *opt_free = NULL; + const char * opt = (*argv)[0]; + gs_free char *arg_tmp = NULL; + const char * s; + + nm_assert(opt); + nm_assert(opt[0] == '-'); + nm_assert(!arg || !*arg); + + if (nmc->return_value != NMC_RESULT_SUCCESS) { + /* Don't process further matches if there has been an error. */ + return FALSE; + } + + if (opt[1] == '-') { + /* We know one '-' was already seen by the caller. + * Skip it if there's a second one*/ + opt++; + } + + if (arg) { + /* If there's a "=" separator, replace it with NUL so that matches() + * works and consider the part after it to be the argument's value. */ + s = strchr(opt, '='); + if (s) { + opt = nm_strndup_a(300, opt, s - opt, &opt_free); + arg_tmp = g_strdup(&s[1]); + } + } + + if (!matches(opt, pattern)) + return FALSE; + + if (arg) { + if (arg_tmp) + *arg = g_steal_pointer(&arg_tmp); + else { + /* We need a value, but the option didn't contain a "=<value>" part. + * Proceed to the next argument. */ + if (*argc <= 1) { + g_string_printf(nmc->return_text, + _("Error: missing argument for '%s' option."), + opt); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } + (*argc)--; + (*argv)++; + *arg = g_strdup(*argv[0]); + } + } + + return TRUE; } /*************************************************************************************/ typedef enum { - NMC_USE_COLOR_AUTO, - NMC_USE_COLOR_YES, - NMC_USE_COLOR_NO, + NMC_USE_COLOR_AUTO, + NMC_USE_COLOR_YES, + NMC_USE_COLOR_NO, } NmcColorOption; static char * -check_colors_construct_filename (const char *base_dir, - const char *name, - const char *term, - const char *type) +check_colors_construct_filename(const char *base_dir, + const char *name, + const char *term, + const char *type) { - return g_strdup_printf ("%s/terminal-colors.d/%s%s%s%s%s", - base_dir, - name ? name : "", - term ? "@" : "", term ? term : "", - (name || term) ? "." : "", - type); + 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) +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; + 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_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; + 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 NMC_USE_COLOR_AUTO; + return NMC_USE_COLOR_AUTO; } static char * -check_colors_check_palette_one_file (const char *base_dir, - const char *name, - const char *term) +check_colors_check_palette_one_file(const char *base_dir, const char *name, const char *term) { - gs_free char *filename = check_colors_construct_filename (base_dir, name, term, "schem"); - char *contents; + gs_free char *filename = check_colors_construct_filename(base_dir, name, term, "schem"); + char * contents; - if (g_file_get_contents (filename, &contents, NULL, NULL)) - return contents; - return NULL; + if (g_file_get_contents(filename, &contents, NULL, NULL)) + return contents; + return NULL; } static gboolean -check_colors_check_enabled (const char *base_dir_1, const char *base_dir_2, const char *name, const char *term) +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 (!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)); - } + 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 (!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; + return TRUE; } static char * -check_colors_check_palette (const char *base_dir_1, const char *base_dir_2, const char *name, const char *term) +check_colors_check_palette(const char *base_dir_1, + const char *base_dir_2, + const char *name, + const char *term) { - int i; + int i; - if (term && strchr (term, '/')) - term = NULL; + if (term && strchr(term, '/')) + term = 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)); - } + 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; + return NULL; } static gboolean -check_colors (NmcColorOption color_option, - char **out_palette_str) +check_colors(NmcColorOption color_option, char **out_palette_str) { - 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; - } - - if ( color_option == NMC_USE_COLOR_AUTO - && g_getenv ("NO_COLOR")) { - /* https://no-color.org/ */ - 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; + 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; + } + + if (color_option == NMC_USE_COLOR_AUTO && g_getenv("NO_COLOR")) { + /* https://no-color.org/ */ + 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 * -resolve_color_alias (const char *color) +resolve_color_alias(const char *color) { - static const struct { - const char *name; - const char *alias; - } aliases[] = { - { "reset", "0" }, - { "bold", "1" }, - { "white", "1;37" }, - { "halfbright", "2" }, - { "underscore", "4" }, - { "blink", "5" }, - { "reverse", "7" }, - { "black", "30" }, - { "red", "31" }, - { "green", "32" }, - { "brown", "33" }, - { "yellow", "33" }, /* well, yellow */ - { "blue", "34" }, - { "magenta", "35" }, - { "cyan", "36" }, - { "gray", "37" }, - { "darkgray", "90" }, - { "lightred", "91" }, - { "lightgreen", "92" }, - { "lightblue", "94" }, - { "lightmagenta", "95" }, - { "lightcyan", "96" }, - { "lightgray", "97" }, - }; - int i; - - /* Shortcut literal sequences. */ - if (g_ascii_isdigit (*color)) - return color; - - for (i = 0; i < G_N_ELEMENTS (aliases); i++) { - if (strcmp (color, aliases[i].name) == 0) - return aliases[i].alias; - } - - return color; + static const struct { + const char *name; + const char *alias; + } aliases[] = { + {"reset", "0"}, {"bold", "1"}, {"white", "1;37"}, + {"halfbright", "2"}, {"underscore", "4"}, {"blink", "5"}, + {"reverse", "7"}, {"black", "30"}, {"red", "31"}, + {"green", "32"}, {"brown", "33"}, {"yellow", "33"}, /* well, yellow */ + {"blue", "34"}, {"magenta", "35"}, {"cyan", "36"}, + {"gray", "37"}, {"darkgray", "90"}, {"lightred", "91"}, + {"lightgreen", "92"}, {"lightblue", "94"}, {"lightmagenta", "95"}, + {"lightcyan", "96"}, {"lightgray", "97"}, + }; + int i; + + /* Shortcut literal sequences. */ + if (g_ascii_isdigit(*color)) + return color; + + for (i = 0; i < G_N_ELEMENTS(aliases); i++) { + if (strcmp(color, aliases[i].name) == 0) + return aliases[i].alias; + } + + return color; } static gboolean -parse_color_scheme (char *palette_buffer, - const char **palette /* _NM_META_COLOR_NUM elements */, - GError **error) +parse_color_scheme(char * palette_buffer, + const char **palette /* _NM_META_COLOR_NUM elements */, + GError ** error) { - char *p = palette_buffer; - const char *name; - const char *color; - 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", - [NM_META_COLOR_CONNECTION_DISCONNECTING] = "connection-disconnecting", - [NM_META_COLOR_CONNECTION_INVISIBLE] = "connection-invisible", - [NM_META_COLOR_CONNECTION_EXTERNAL] = "connection-external", - [NM_META_COLOR_CONNECTION_UNKNOWN] = "connection-unknown", - [NM_META_COLOR_CONNECTIVITY_FULL] = "connectivity-full", - [NM_META_COLOR_CONNECTIVITY_LIMITED] = "connectivity-limited", - [NM_META_COLOR_CONNECTIVITY_NONE] = "connectivity-none", - [NM_META_COLOR_CONNECTIVITY_PORTAL] = "connectivity-portal", - [NM_META_COLOR_CONNECTIVITY_UNKNOWN] = "connectivity-unknown", - [NM_META_COLOR_DEVICE_ACTIVATED] = "device-activated", - [NM_META_COLOR_DEVICE_ACTIVATING] = "device-activating", - [NM_META_COLOR_DEVICE_DISCONNECTED] = "device-disconnected", - [NM_META_COLOR_DEVICE_FIRMWARE_MISSING] = "device-firmware-missing", - [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "device-plugin-missing", - [NM_META_COLOR_DEVICE_UNAVAILABLE] = "device-unavailable", - [NM_META_COLOR_DEVICE_DISABLED] = "device-disabled", - [NM_META_COLOR_DEVICE_EXTERNAL] = "device-external", - [NM_META_COLOR_DEVICE_UNKNOWN] = "device-unknown", - [NM_META_COLOR_MANAGER_RUNNING] = "manager-running", - [NM_META_COLOR_MANAGER_STARTING] = "manager-starting", - [NM_META_COLOR_MANAGER_STOPPED] = "manager-stopped", - [NM_META_COLOR_PERMISSION_AUTH] = "permission-auth", - [NM_META_COLOR_PERMISSION_NO] = "permission-no", - [NM_META_COLOR_PERMISSION_UNKNOWN] = "permission-unknown", - [NM_META_COLOR_PERMISSION_YES] = "permission-yes", - [NM_META_COLOR_PROMPT] = "prompt", - [NM_META_COLOR_STATE_ASLEEP] = "state-asleep", - [NM_META_COLOR_STATE_CONNECTED_GLOBAL] = "state-connected-global", - [NM_META_COLOR_STATE_CONNECTED_LOCAL] = "state-connected-local", - [NM_META_COLOR_STATE_CONNECTED_SITE] = "state-connected-site", - [NM_META_COLOR_STATE_CONNECTING] = "state-connecting", - [NM_META_COLOR_STATE_DISCONNECTED] = "state-disconnected", - [NM_META_COLOR_STATE_DISCONNECTING] = "state-disconnecting", - [NM_META_COLOR_STATE_UNKNOWN] = "state-unknown", - [NM_META_COLOR_WIFI_SIGNAL_EXCELLENT] = "wifi-signal-excellent", - [NM_META_COLOR_WIFI_SIGNAL_FAIR] = "wifi-signal-fair", - [NM_META_COLOR_WIFI_SIGNAL_GOOD] = "wifi-signal-good", - [NM_META_COLOR_WIFI_SIGNAL_POOR] = "wifi-signal-poor", - [NM_META_COLOR_WIFI_SIGNAL_UNKNOWN] = "wifi-signal-unknown", - [NM_META_COLOR_DISABLED] = "disabled", - [NM_META_COLOR_ENABLED] = "enabled", - }; - int i; - - /* This reads through the raw color scheme file contents, identifying the - * color names and sequences, putting in terminating NULs in place, so that - * pointers into the buffer can readily be used as strings in the palette. */ - while (1) { - /* Leading whitespace. */ - while (nm_utils_is_separator (*p) || *p == '\n') - p++; - - if (*p == '\0') - break; - - /* Comments. */ - if (*p == '#') { - while (*p != '\n' && *p != '\0') - p++; - continue; - } - - /* Color name. */ - name = p; - while (g_ascii_isgraph (*p)) - p++; - if (*p == '\0') { - g_set_error (error, NMCLI_ERROR, 0, - _("Unexpected end of file following '%s'\n"), name); - return FALSE; - } - - /* Separating whitespace. */ - if (!nm_utils_is_separator (*p)) { - *p = '\0'; - g_set_error (error, NMCLI_ERROR, 0, - _("Expected whitespace following '%s'\n"), name); - return FALSE; - } - while (nm_utils_is_separator (*p)) { - *p = '\0'; - p++; - } - - /* Color sequence. */ - color = p; - if (!g_ascii_isgraph (*p)) { - g_set_error (error, NMCLI_ERROR, 0, - _("Expected a value for '%s'\n"), name); - return FALSE; - } - while (g_ascii_isgraph (*p)) - p++; - - /* Trailing whitespace. */ - while (nm_utils_is_separator (*p)) { - *p = '\0'; - p++; - } - if (*p != '\0') { - if (*p != '\n') { - g_set_error (error, NMCLI_ERROR, 0, - _("Expected a line break following '%s'\n"), color); - return FALSE; - } - *p = '\0'; - p++; - } - - /* 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) { - tmp_palette[i] = resolve_color_alias (color); - break; - } - } - if (i == _NM_META_COLOR_NUM) - g_debug ("Ignoring an unrecognized color: '%s'\n", name); - } - - memcpy (palette, tmp_palette, sizeof (tmp_palette)); - return TRUE; + char * p = palette_buffer; + const char * name; + const char * color; + 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", + [NM_META_COLOR_CONNECTION_DISCONNECTING] = "connection-disconnecting", + [NM_META_COLOR_CONNECTION_INVISIBLE] = "connection-invisible", + [NM_META_COLOR_CONNECTION_EXTERNAL] = "connection-external", + [NM_META_COLOR_CONNECTION_UNKNOWN] = "connection-unknown", + [NM_META_COLOR_CONNECTIVITY_FULL] = "connectivity-full", + [NM_META_COLOR_CONNECTIVITY_LIMITED] = "connectivity-limited", + [NM_META_COLOR_CONNECTIVITY_NONE] = "connectivity-none", + [NM_META_COLOR_CONNECTIVITY_PORTAL] = "connectivity-portal", + [NM_META_COLOR_CONNECTIVITY_UNKNOWN] = "connectivity-unknown", + [NM_META_COLOR_DEVICE_ACTIVATED] = "device-activated", + [NM_META_COLOR_DEVICE_ACTIVATING] = "device-activating", + [NM_META_COLOR_DEVICE_DISCONNECTED] = "device-disconnected", + [NM_META_COLOR_DEVICE_FIRMWARE_MISSING] = "device-firmware-missing", + [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "device-plugin-missing", + [NM_META_COLOR_DEVICE_UNAVAILABLE] = "device-unavailable", + [NM_META_COLOR_DEVICE_DISABLED] = "device-disabled", + [NM_META_COLOR_DEVICE_EXTERNAL] = "device-external", + [NM_META_COLOR_DEVICE_UNKNOWN] = "device-unknown", + [NM_META_COLOR_MANAGER_RUNNING] = "manager-running", + [NM_META_COLOR_MANAGER_STARTING] = "manager-starting", + [NM_META_COLOR_MANAGER_STOPPED] = "manager-stopped", + [NM_META_COLOR_PERMISSION_AUTH] = "permission-auth", + [NM_META_COLOR_PERMISSION_NO] = "permission-no", + [NM_META_COLOR_PERMISSION_UNKNOWN] = "permission-unknown", + [NM_META_COLOR_PERMISSION_YES] = "permission-yes", + [NM_META_COLOR_PROMPT] = "prompt", + [NM_META_COLOR_STATE_ASLEEP] = "state-asleep", + [NM_META_COLOR_STATE_CONNECTED_GLOBAL] = "state-connected-global", + [NM_META_COLOR_STATE_CONNECTED_LOCAL] = "state-connected-local", + [NM_META_COLOR_STATE_CONNECTED_SITE] = "state-connected-site", + [NM_META_COLOR_STATE_CONNECTING] = "state-connecting", + [NM_META_COLOR_STATE_DISCONNECTED] = "state-disconnected", + [NM_META_COLOR_STATE_DISCONNECTING] = "state-disconnecting", + [NM_META_COLOR_STATE_UNKNOWN] = "state-unknown", + [NM_META_COLOR_WIFI_SIGNAL_EXCELLENT] = "wifi-signal-excellent", + [NM_META_COLOR_WIFI_SIGNAL_FAIR] = "wifi-signal-fair", + [NM_META_COLOR_WIFI_SIGNAL_GOOD] = "wifi-signal-good", + [NM_META_COLOR_WIFI_SIGNAL_POOR] = "wifi-signal-poor", + [NM_META_COLOR_WIFI_SIGNAL_UNKNOWN] = "wifi-signal-unknown", + [NM_META_COLOR_DISABLED] = "disabled", + [NM_META_COLOR_ENABLED] = "enabled", + }; + int i; + + /* This reads through the raw color scheme file contents, identifying the + * color names and sequences, putting in terminating NULs in place, so that + * pointers into the buffer can readily be used as strings in the palette. */ + while (1) { + /* Leading whitespace. */ + while (nm_utils_is_separator(*p) || *p == '\n') + p++; + + if (*p == '\0') + break; + + /* Comments. */ + if (*p == '#') { + while (*p != '\n' && *p != '\0') + p++; + continue; + } + + /* Color name. */ + name = p; + while (g_ascii_isgraph(*p)) + p++; + if (*p == '\0') { + g_set_error(error, NMCLI_ERROR, 0, _("Unexpected end of file following '%s'\n"), name); + return FALSE; + } + + /* Separating whitespace. */ + if (!nm_utils_is_separator(*p)) { + *p = '\0'; + g_set_error(error, NMCLI_ERROR, 0, _("Expected whitespace following '%s'\n"), name); + return FALSE; + } + while (nm_utils_is_separator(*p)) { + *p = '\0'; + p++; + } + + /* Color sequence. */ + color = p; + if (!g_ascii_isgraph(*p)) { + g_set_error(error, NMCLI_ERROR, 0, _("Expected a value for '%s'\n"), name); + return FALSE; + } + while (g_ascii_isgraph(*p)) + p++; + + /* Trailing whitespace. */ + while (nm_utils_is_separator(*p)) { + *p = '\0'; + p++; + } + if (*p != '\0') { + if (*p != '\n') { + g_set_error(error, + NMCLI_ERROR, + 0, + _("Expected a line break following '%s'\n"), + color); + return FALSE; + } + *p = '\0'; + p++; + } + + /* 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) { + tmp_palette[i] = resolve_color_alias(color); + break; + } + } + if (i == _NM_META_COLOR_NUM) + g_debug("Ignoring an unrecognized color: '%s'\n", name); + } + + memcpy(palette, tmp_palette, sizeof(tmp_palette)); + return TRUE; } static void -set_colors (NmcColorOption color_option, - bool *out_use_colors, - char **out_palette_buffer, - const char **palette /* _NM_META_COLOR_NUM elements */) +set_colors(NmcColorOption color_option, + bool * out_use_colors, + char ** out_palette_buffer, + const char ** palette /* _NM_META_COLOR_NUM elements */) { - gs_free char *palette_str = NULL; - gboolean use_colors; + gs_free char *palette_str = NULL; + gboolean use_colors; - use_colors = check_colors (color_option, &palette_str); + use_colors = check_colors(color_option, &palette_str); - *out_use_colors = use_colors; - if (use_colors && palette_str) { - GError *error = NULL; + *out_use_colors = use_colors; + if (use_colors && palette_str) { + GError *error = NULL; - 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); - } + 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); + } } /*************************************************************************************/ static gboolean -process_command_line (NmCli *nmc, int argc, char **argv_orig) +process_command_line(NmCli *nmc, int argc, char **argv_orig) { - static const NMCCommand nmcli_cmds[] = { - { "general", nmc_command_func_general, NULL, FALSE, FALSE }, - { "monitor", nmc_command_func_monitor, NULL, TRUE, FALSE }, - { "networking", nmc_command_func_networking, NULL, FALSE, FALSE }, - { "radio", nmc_command_func_radio, NULL, FALSE, FALSE }, - { "connection", nmc_command_func_connection, NULL, FALSE, FALSE }, - { "device", nmc_command_func_device, NULL, FALSE, FALSE }, - { "agent", nmc_command_func_agent, NULL, FALSE, FALSE }, - { NULL, nmc_command_func_overview, usage, TRUE, TRUE }, - }; - NmcColorOption colors = NMC_USE_COLOR_AUTO; - const char *base; - const char *const*argv; - - base = strrchr (argv_orig[0], '/'); - if (base == NULL) - base = argv_orig[0]; - else - base++; - - if ( argc > 1 - && nm_streq (argv_orig[1], "--complete-args")) { - nmc->complete = TRUE; - argv_orig[1] = argv_orig[0]; - argc--; - argv_orig++; - } - - argv = (const char *const*) argv_orig; - - next_arg (nmc, &argc, &argv, NULL); - - /* parse options */ - while (argc) { - gs_free char *value = NULL; - - if (argv[0][0] != '-') - break; - - if (argc == 1 && nmc->complete) { - nmc_complete_strings (argv[0], "--terse", "--pretty", "--mode", "--overview", - "--colors", "--escape", - "--fields", "--nocheck", "--get-values", - "--wait", "--version", "--help"); - } - - if (argv[0][1] == '-' && argv[0][2] == '\0') { - /* '--' ends options */ - next_arg (nmc, &argc, &argv, NULL); - break; - } - - if (matches_arg (nmc, &argc, &argv, "-overview", NULL)) { - nmc->nmc_config_mutable.overview = TRUE; - } else if (matches_arg (nmc, &argc, &argv, "-terse", NULL)) { - if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) { - g_string_printf (nmc->return_text, _("Error: Option '--terse' is specified the second time.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - else if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { - g_string_printf (nmc->return_text, _("Error: Option '--terse' is mutually exclusive with '--pretty'.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - else - nmc->nmc_config_mutable.print_output = NMC_PRINT_TERSE; - } else if (matches_arg (nmc, &argc, &argv, "-pretty", NULL)) { - if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { - g_string_printf (nmc->return_text, _("Error: Option '--pretty' is specified the second time.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - else if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) { - g_string_printf (nmc->return_text, _("Error: Option '--pretty' is mutually exclusive with '--terse'.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - else - nmc->nmc_config_mutable.print_output = NMC_PRINT_PRETTY; - } else if (matches_arg (nmc, &argc, &argv, "-mode", &value)) { - nmc->mode_specified = TRUE; - if (argc == 1 && nmc->complete) - complete_option_with_value (argv[0], value, "tabular", "multiline", NULL); - if (matches (value, "tabular")) - nmc->nmc_config_mutable.multiline_output = FALSE; - else if (matches (value, "multiline")) - nmc->nmc_config_mutable.multiline_output = TRUE; - else { - g_string_printf (nmc->return_text, _("Error: '%s' is not a valid argument for '%s' option."), value, argv[0]); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - } else if (matches_arg (nmc, &argc, &argv, "-colors", &value)) { - if (argc == 1 && nmc->complete) - complete_option_with_value (argv[0], value, "yes", "no", "auto", NULL); - if (matches (value, "auto")) - colors = NMC_USE_COLOR_AUTO; - else if (matches (value, "yes")) - colors = NMC_USE_COLOR_YES; - else if (matches (value, "no")) - colors = NMC_USE_COLOR_NO; - else { - g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), value, argv[0]); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - } else if (matches_arg (nmc, &argc, &argv, "-escape", &value)) { - if (argc == 1 && nmc->complete) - complete_option_with_value (argv[0], value, "yes", "no", NULL); - if (matches (value, "yes")) - nmc->nmc_config_mutable.escape_values = TRUE; - else if (matches (value, "no")) - nmc->nmc_config_mutable.escape_values = FALSE; - else { - g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), value, argv[0]); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - } else if (matches_arg (nmc, &argc, &argv, "-fields", &value)) { - if (argc == 1 && nmc->complete) - complete_fields (argv[0], value); - nmc->required_fields = g_strdup (value); - } else if (matches_arg (nmc, &argc, &argv, "-get-values", &value)) { - if (argc == 1 && nmc->complete) - complete_fields (argv[0], value); - nmc->required_fields = g_strdup (value); - nmc->nmc_config_mutable.print_output = NMC_PRINT_TERSE; - /* We want fixed tabular mode here, but just set the mode specified and rely on defaults: - * in this way we allow use of "-m multiline" to swap the output mode also if placed - * before the "-g <field>" option (-g may be still more practical and easy to remember than -t -f). - */ - nmc->mode_specified = TRUE; - } else if (matches_arg (nmc, &argc, &argv, "-nocheck", NULL)) { - /* ignore for backward compatibility */ - } else if (matches_arg (nmc, &argc, &argv, "-wait", &value)) { - unsigned long timeout; - - if (!nmc_string_to_uint (value, TRUE, 0, G_MAXINT, &timeout)) { - g_string_printf (nmc->return_text, _("Error: '%s' is not a valid timeout."), value); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - nmc->timeout = (int) timeout; - } else if (matches_arg (nmc, &argc, &argv, "-version", NULL)) { - if (!nmc->complete) - g_print (_("nmcli tool, version %s\n"), NMCLI_VERSION); - return NMC_RESULT_SUCCESS; - } else if (matches_arg (nmc, &argc, &argv, "-help", NULL)) { - if (!nmc->complete) - usage (); - return NMC_RESULT_SUCCESS; - } else { - if (nmc->return_value == NMC_RESULT_SUCCESS) { - g_string_printf (nmc->return_text, _("Error: Option '%s' is unknown, try 'nmcli -help'."), argv[0]); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - } - return FALSE; - } - - next_arg (nmc, &argc, &argv, NULL); - } - - /* Ignore --overview when fields are set explicitly */ - if (nmc->required_fields) - nmc->nmc_config_mutable.overview = FALSE; - - 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); - - return TRUE; + static const NMCCommand nmcli_cmds[] = { + {"general", nmc_command_func_general, NULL, FALSE, FALSE}, + {"monitor", nmc_command_func_monitor, NULL, TRUE, FALSE}, + {"networking", nmc_command_func_networking, NULL, FALSE, FALSE}, + {"radio", nmc_command_func_radio, NULL, FALSE, FALSE}, + {"connection", nmc_command_func_connection, NULL, FALSE, FALSE}, + {"device", nmc_command_func_device, NULL, FALSE, FALSE}, + {"agent", nmc_command_func_agent, NULL, FALSE, FALSE}, + {NULL, nmc_command_func_overview, usage, TRUE, TRUE}, + }; + NmcColorOption colors = NMC_USE_COLOR_AUTO; + const char * base; + const char *const *argv; + + base = strrchr(argv_orig[0], '/'); + if (base == NULL) + base = argv_orig[0]; + else + base++; + + if (argc > 1 && nm_streq(argv_orig[1], "--complete-args")) { + nmc->complete = TRUE; + argv_orig[1] = argv_orig[0]; + argc--; + argv_orig++; + } + + argv = (const char *const *) argv_orig; + + next_arg(nmc, &argc, &argv, NULL); + + /* parse options */ + while (argc) { + gs_free char *value = NULL; + + if (argv[0][0] != '-') + break; + + if (argc == 1 && nmc->complete) { + nmc_complete_strings(argv[0], + "--terse", + "--pretty", + "--mode", + "--overview", + "--colors", + "--escape", + "--fields", + "--nocheck", + "--get-values", + "--wait", + "--version", + "--help"); + } + + if (argv[0][1] == '-' && argv[0][2] == '\0') { + /* '--' ends options */ + next_arg(nmc, &argc, &argv, NULL); + break; + } + + if (matches_arg(nmc, &argc, &argv, "-overview", NULL)) { + nmc->nmc_config_mutable.overview = TRUE; + } else if (matches_arg(nmc, &argc, &argv, "-terse", NULL)) { + if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) { + g_string_printf(nmc->return_text, + _("Error: Option '--terse' is specified the second time.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } else if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { + g_string_printf( + nmc->return_text, + _("Error: Option '--terse' is mutually exclusive with '--pretty'.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } else + nmc->nmc_config_mutable.print_output = NMC_PRINT_TERSE; + } else if (matches_arg(nmc, &argc, &argv, "-pretty", NULL)) { + if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { + g_string_printf(nmc->return_text, + _("Error: Option '--pretty' is specified the second time.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } else if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) { + g_string_printf( + nmc->return_text, + _("Error: Option '--pretty' is mutually exclusive with '--terse'.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } else + nmc->nmc_config_mutable.print_output = NMC_PRINT_PRETTY; + } else if (matches_arg(nmc, &argc, &argv, "-mode", &value)) { + nmc->mode_specified = TRUE; + if (argc == 1 && nmc->complete) + complete_option_with_value(argv[0], value, "tabular", "multiline", NULL); + if (matches(value, "tabular")) + nmc->nmc_config_mutable.multiline_output = FALSE; + else if (matches(value, "multiline")) + nmc->nmc_config_mutable.multiline_output = TRUE; + else { + g_string_printf(nmc->return_text, + _("Error: '%s' is not a valid argument for '%s' option."), + value, + argv[0]); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } + } else if (matches_arg(nmc, &argc, &argv, "-colors", &value)) { + if (argc == 1 && nmc->complete) + complete_option_with_value(argv[0], value, "yes", "no", "auto", NULL); + if (matches(value, "auto")) + colors = NMC_USE_COLOR_AUTO; + else if (matches(value, "yes")) + colors = NMC_USE_COLOR_YES; + else if (matches(value, "no")) + colors = NMC_USE_COLOR_NO; + else { + g_string_printf(nmc->return_text, + _("Error: '%s' is not valid argument for '%s' option."), + value, + argv[0]); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } + } else if (matches_arg(nmc, &argc, &argv, "-escape", &value)) { + if (argc == 1 && nmc->complete) + complete_option_with_value(argv[0], value, "yes", "no", NULL); + if (matches(value, "yes")) + nmc->nmc_config_mutable.escape_values = TRUE; + else if (matches(value, "no")) + nmc->nmc_config_mutable.escape_values = FALSE; + else { + g_string_printf(nmc->return_text, + _("Error: '%s' is not valid argument for '%s' option."), + value, + argv[0]); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } + } else if (matches_arg(nmc, &argc, &argv, "-fields", &value)) { + if (argc == 1 && nmc->complete) + complete_fields(argv[0], value); + nmc->required_fields = g_strdup(value); + } else if (matches_arg(nmc, &argc, &argv, "-get-values", &value)) { + if (argc == 1 && nmc->complete) + complete_fields(argv[0], value); + nmc->required_fields = g_strdup(value); + nmc->nmc_config_mutable.print_output = NMC_PRINT_TERSE; + /* We want fixed tabular mode here, but just set the mode specified and rely on defaults: + * in this way we allow use of "-m multiline" to swap the output mode also if placed + * before the "-g <field>" option (-g may be still more practical and easy to remember than -t -f). + */ + nmc->mode_specified = TRUE; + } else if (matches_arg(nmc, &argc, &argv, "-nocheck", NULL)) { + /* ignore for backward compatibility */ + } else if (matches_arg(nmc, &argc, &argv, "-wait", &value)) { + unsigned long timeout; + + if (!nmc_string_to_uint(value, TRUE, 0, G_MAXINT, &timeout)) { + g_string_printf(nmc->return_text, _("Error: '%s' is not a valid timeout."), value); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return FALSE; + } + nmc->timeout = (int) timeout; + } else if (matches_arg(nmc, &argc, &argv, "-version", NULL)) { + if (!nmc->complete) + g_print(_("nmcli tool, version %s\n"), NMCLI_VERSION); + return NMC_RESULT_SUCCESS; + } else if (matches_arg(nmc, &argc, &argv, "-help", NULL)) { + if (!nmc->complete) + usage(); + return NMC_RESULT_SUCCESS; + } else { + if (nmc->return_value == NMC_RESULT_SUCCESS) { + g_string_printf(nmc->return_text, + _("Error: Option '%s' is unknown, try 'nmcli -help'."), + argv[0]); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + } + return FALSE; + } + + next_arg(nmc, &argc, &argv, NULL); + } + + /* Ignore --overview when fields are set explicitly */ + if (nmc->required_fields) + nmc->nmc_config_mutable.overview = FALSE; + + 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); + + return TRUE; } static gboolean nmcli_sigint = FALSE; gboolean -nmc_seen_sigint (void) +nmc_seen_sigint(void) { - return nmcli_sigint; + return nmcli_sigint; } void -nmc_clear_sigint (void) +nmc_clear_sigint(void) { - nmcli_sigint = FALSE; + nmcli_sigint = FALSE; } -void nmc_exit (void) +void +nmc_exit(void) { - tcsetattr (STDIN_FILENO, TCSADRAIN, &termios_orig); - nmc_cleanup_readline (); - exit (1); + tcsetattr(STDIN_FILENO, TCSADRAIN, &termios_orig); + nmc_cleanup_readline(); + exit(1); } static gboolean -signal_handler (gpointer user_data) +signal_handler(gpointer user_data) { - int signo = GPOINTER_TO_INT (user_data); - - switch (signo) { - case SIGINT: - if (nmc_get_in_readline ()) { - nmcli_sigint = TRUE; - } else { - nm_cli.return_value = 0x80 + signo; - g_string_printf (nm_cli.return_text, _("Error: nmcli terminated by signal %s (%d)"), - strsignal (signo), signo); - g_main_loop_quit (loop); - } - break; - case SIGTERM: - nm_cli.return_value = 0x80 + signo; - g_string_printf (nm_cli.return_text, _("Error: nmcli terminated by signal %s (%d)"), - strsignal (signo), signo); - nmc_exit (); - break; - } - - return G_SOURCE_CONTINUE; + int signo = GPOINTER_TO_INT(user_data); + + switch (signo) { + case SIGINT: + if (nmc_get_in_readline()) { + nmcli_sigint = TRUE; + } else { + nm_cli.return_value = 0x80 + signo; + g_string_printf(nm_cli.return_text, + _("Error: nmcli terminated by signal %s (%d)"), + strsignal(signo), + signo); + g_main_loop_quit(loop); + } + break; + case SIGTERM: + nm_cli.return_value = 0x80 + signo; + g_string_printf(nm_cli.return_text, + _("Error: nmcli terminated by signal %s (%d)"), + strsignal(signo), + signo); + nmc_exit(); + break; + } + + return G_SOURCE_CONTINUE; } void -nm_cli_spawn_pager (const NmcConfig *nmc_config, - NmcPagerData *pager_data) +nm_cli_spawn_pager(const NmcConfig *nmc_config, NmcPagerData *pager_data) { - if (pager_data->pid != 0) - return; - pager_data->pid = nmc_terminal_spawn_pager (nmc_config); + if (pager_data->pid != 0) + return; + pager_data->pid = nmc_terminal_spawn_pager(nmc_config); } static void -nmc_cleanup (NmCli *nmc) +nmc_cleanup(NmCli *nmc) { - pid_t ret; + pid_t ret; - g_clear_object (&nmc->client); + g_clear_object(&nmc->client); - if (nmc->return_text) - g_string_free (g_steal_pointer (&nmc->return_text), TRUE); + if (nmc->return_text) + g_string_free(g_steal_pointer(&nmc->return_text), TRUE); - if (nmc->secret_agent) { - nm_secret_agent_old_unregister (NM_SECRET_AGENT_OLD (nmc->secret_agent), NULL, NULL); - g_clear_object (&nmc->secret_agent); - } + if (nmc->secret_agent) { + nm_secret_agent_old_unregister(NM_SECRET_AGENT_OLD(nmc->secret_agent), NULL, NULL); + g_clear_object(&nmc->secret_agent); + } - nm_clear_pointer (&nmc->pwds_hash, g_hash_table_destroy); + nm_clear_pointer(&nmc->pwds_hash, g_hash_table_destroy); - nm_clear_g_free (&nmc->required_fields); + nm_clear_g_free(&nmc->required_fields); - if (nmc->pager_data.pid != 0) { - pid_t pid = nm_steal_int (&nmc->pager_data.pid); + if (nmc->pager_data.pid != 0) { + pid_t pid = nm_steal_int(&nmc->pager_data.pid); - fclose (stdout); - fclose (stderr); - do { - ret = waitpid (pid, NULL, 0); - } while (ret == -1 && errno == EINTR); - } + fclose(stdout); + fclose(stderr); + do { + ret = waitpid(pid, NULL, 0); + } while (ret == -1 && errno == EINTR); + } - nm_clear_g_free (&nmc->palette_buffer); + nm_clear_g_free(&nmc->palette_buffer); - nmc_polkit_agent_fini (nmc); + nmc_polkit_agent_fini(nmc); } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - /* Set locale to use environment variables */ - setlocale (LC_ALL, ""); + /* Set locale to use environment variables */ + setlocale(LC_ALL, ""); #ifdef GETTEXT_PACKAGE - /* Set i18n stuff */ - bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); + /* Set i18n stuff */ + bindtextdomain(GETTEXT_PACKAGE, NMLOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + textdomain(GETTEXT_PACKAGE); #endif - /* Save terminal settings */ - tcgetattr (STDIN_FILENO, &termios_orig); + /* Save terminal settings */ + tcgetattr(STDIN_FILENO, &termios_orig); - nm_cli.return_text = g_string_new (_("Success")); - loop = g_main_loop_new (NULL, FALSE); + nm_cli.return_text = g_string_new(_("Success")); + loop = g_main_loop_new(NULL, FALSE); - g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM)); - g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT)); + g_unix_signal_add(SIGTERM, signal_handler, GINT_TO_POINTER(SIGTERM)); + g_unix_signal_add(SIGINT, signal_handler, GINT_TO_POINTER(SIGINT)); - if (process_command_line (&nm_cli, argc, argv)) - g_main_loop_run (loop); + if (process_command_line(&nm_cli, argc, argv)) + g_main_loop_run(loop); - if (nm_cli.complete) { - /* Remove error statuses from command completion runs. */ - if (nm_cli.return_value < NMC_RESULT_COMPLETE_FILE) - nm_cli.return_value = NMC_RESULT_SUCCESS; - } else if (nm_cli.return_value != NMC_RESULT_SUCCESS) { - /* Print result descripting text */ - g_printerr ("%s\n", nm_cli.return_text->str); - } + if (nm_cli.complete) { + /* Remove error statuses from command completion runs. */ + if (nm_cli.return_value < NMC_RESULT_COMPLETE_FILE) + nm_cli.return_value = NMC_RESULT_SUCCESS; + } else if (nm_cli.return_value != NMC_RESULT_SUCCESS) { + /* Print result descripting text */ + g_printerr("%s\n", nm_cli.return_text->str); + } - nmc_cleanup (&nm_cli); - g_main_loop_unref (loop); + nmc_cleanup(&nm_cli); + g_main_loop_unref(loop); - return nm_cli.return_value; + return nm_cli.return_value; } |