about summary refs log tree commit diff
path: root/clients/cli/nmcli.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-10-01 23:05:04 +0200
committerMichael Biebl <biebl@debian.org>2021-10-01 23:05:04 +0200
commite74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch)
tree3469f17ea9af91f7ff169b890633bda68b0cf76e /clients/cli/nmcli.c
parentbfe522304da217296e2a61040f58e35ec5d6f3f2 (diff)
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'clients/cli/nmcli.c')
-rw-r--r--clients/cli/nmcli.c1051
1 files changed, 0 insertions, 1051 deletions
diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c
deleted file mode 100644
index 39457211..00000000
--- a/clients/cli/nmcli.c
+++ /dev/null
@@ -1,1051 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Jiri Klimes <jklimes@redhat.com>
- * Copyright (C) 2010 - 2018 Red Hat, Inc.
- */
-
-#include "libnm/nm-default-client.h"
-
-#include "nmcli.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <termios.h>
-#include <unistd.h>
-#include <locale.h>
-#include <glib-unix.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
-#include "nm-client-utils.h"
-
-#include "polkit-agent.h"
-#include "utils.h"
-#include "common.h"
-#include "connections.h"
-#include "devices.h"
-#include "settings.h"
-
-#if defined(NM_DIST_VERSION)
-    #define NMCLI_VERSION NM_DIST_VERSION
-#else
-    #define NMCLI_VERSION VERSION
-#endif
-
-#define _NMC_COLOR_PALETTE_INIT()                              \
-    {                                                          \
-        .ansi_seq = {                                          \
-            [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          = _NMC_COLOR_PALETTE_INIT(),
-    .editor_status_line          = FALSE,
-    .editor_save_confirmation    = TRUE,
-};
-
-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;
-} ArgsInfo;
-
-/* --- Global variables --- */
-GMainLoop *    loop = NULL;
-struct termios termios_orig;
-
-NM_CACHED_QUARK_FCN("nmcli-error-quark", nmcli_error_quark);
-
-static void
-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));
-    }
-}
-
-static void
-complete_field(GHashTable *h, const NmcMetaGenericInfo *const *field)
-{
-    int i;
-
-    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)
-{
-    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)
-{
-    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, ...)
-{
-    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)
-{
-    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)
-{
-    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,
-} NmcColorOption;
-
-static char *
-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);
-}
-
-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 NMC_USE_COLOR_AUTO;
-}
-
-static char *
-check_colors_check_palette_one_file(const char *base_dir, const char *name, const char *term)
-{
-    static const char *const extensions[] = {
-        "scheme",
-        "schem",
-    };
-    guint i;
-
-    for (i = 0; i < G_N_ELEMENTS(extensions); i++) {
-        gs_free char *filename = NULL;
-        char *        contents;
-
-        filename = check_colors_construct_filename(base_dir, name, term, extensions[i]);
-        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)
-{
-    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;
-}
-
-static char *
-check_colors_check_palette(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              \
-    {                         \
-        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 gboolean
-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;
-}
-
-static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
-    _resolve_color_alias,
-    const char *,
-    { nm_assert(name); },
-    { return NULL; },
-    {"black", "30"},
-    {"blink", "5"},
-    {"blue", "34"},
-    {"bold", "1"},
-    {"brown", "33"},
-    {"cyan", "36"},
-    {"darkgray", "90"},
-    {"gray", "37"},
-    {"green", "32"},
-    {"halfbright", "2"},
-    {"lightblue", "94"},
-    {"lightcyan", "96"},
-    {"lightgray", "97"},
-    {"lightgreen", "92"},
-    {"lightmagenta", "95"},
-    {"lightred", "91"},
-    {"magenta", "35"},
-    {"red", "31"},
-    {"reset", "0"},
-    {"reverse", "7"},
-    {"underscore", "4"},
-    {"white", "1;37"},
-    {"yellow", "33" /* well, yellow */}, );
-
-static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
-    _nm_meta_color_from_name,
-    NMMetaColor,
-    { nm_assert(name); },
-    { return NM_META_COLOR_NONE; },
-    {"connection-activated", NM_META_COLOR_CONNECTION_ACTIVATED},
-    {"connection-activating", NM_META_COLOR_CONNECTION_ACTIVATING},
-    {"connection-disconnecting", NM_META_COLOR_CONNECTION_DISCONNECTING},
-    {"connection-external", NM_META_COLOR_CONNECTION_EXTERNAL},
-    {"connection-invisible", NM_META_COLOR_CONNECTION_INVISIBLE},
-    {"connection-unknown", NM_META_COLOR_CONNECTION_UNKNOWN},
-    {"connectivity-full", NM_META_COLOR_CONNECTIVITY_FULL},
-    {"connectivity-limited", NM_META_COLOR_CONNECTIVITY_LIMITED},
-    {"connectivity-none", NM_META_COLOR_CONNECTIVITY_NONE},
-    {"connectivity-portal", NM_META_COLOR_CONNECTIVITY_PORTAL},
-    {"connectivity-unknown", NM_META_COLOR_CONNECTIVITY_UNKNOWN},
-    {"device-activated", NM_META_COLOR_DEVICE_ACTIVATED},
-    {"device-activating", NM_META_COLOR_DEVICE_ACTIVATING},
-    {"device-disabled", NM_META_COLOR_DEVICE_DISABLED},
-    {"device-disconnected", NM_META_COLOR_DEVICE_DISCONNECTED},
-    {"device-external", NM_META_COLOR_DEVICE_EXTERNAL},
-    {"device-firmware-missing", NM_META_COLOR_DEVICE_FIRMWARE_MISSING},
-    {"device-plugin-missing", NM_META_COLOR_DEVICE_PLUGIN_MISSING},
-    {"device-unavailable", NM_META_COLOR_DEVICE_UNAVAILABLE},
-    {"device-unknown", NM_META_COLOR_DEVICE_UNKNOWN},
-    {"disabled", NM_META_COLOR_DISABLED},
-    {"enabled", NM_META_COLOR_ENABLED},
-    {"manager-running", NM_META_COLOR_MANAGER_RUNNING},
-    {"manager-starting", NM_META_COLOR_MANAGER_STARTING},
-    {"manager-stopped", NM_META_COLOR_MANAGER_STOPPED},
-    {"permission-auth", NM_META_COLOR_PERMISSION_AUTH},
-    {"permission-no", NM_META_COLOR_PERMISSION_NO},
-    {"permission-unknown", NM_META_COLOR_PERMISSION_UNKNOWN},
-    {"permission-yes", NM_META_COLOR_PERMISSION_YES},
-    {"prompt", NM_META_COLOR_PROMPT},
-    {"state-asleep", NM_META_COLOR_STATE_ASLEEP},
-    {"state-connected-global", NM_META_COLOR_STATE_CONNECTED_GLOBAL},
-    {"state-connected-local", NM_META_COLOR_STATE_CONNECTED_LOCAL},
-    {"state-connected-site", NM_META_COLOR_STATE_CONNECTED_SITE},
-    {"state-connecting", NM_META_COLOR_STATE_CONNECTING},
-    {"state-disconnected", NM_META_COLOR_STATE_DISCONNECTED},
-    {"state-disconnecting", NM_META_COLOR_STATE_DISCONNECTING},
-    {"state-unknown", NM_META_COLOR_STATE_UNKNOWN},
-    {"wifi-signal-excellent", NM_META_COLOR_WIFI_SIGNAL_EXCELLENT},
-    {"wifi-signal-fair", NM_META_COLOR_WIFI_SIGNAL_FAIR},
-    {"wifi-signal-good", NM_META_COLOR_WIFI_SIGNAL_GOOD},
-    {"wifi-signal-poor", NM_META_COLOR_WIFI_SIGNAL_POOR},
-    {"wifi-signal-unknown", NM_META_COLOR_WIFI_SIGNAL_UNKNOWN}, );
-
-static gboolean
-parse_color_scheme(char *palette_buffer, NmcColorPalette *out_palette, GError **error)
-{
-    char *p = palette_buffer;
-
-    nm_assert(out_palette);
-
-    *out_palette = (NmcColorPalette) _NMC_COLOR_PALETTE_INIT();
-
-    /* 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) {
-        NMMetaColor name_idx;
-        const char *name;
-        const char *color;
-
-        /* 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++;
-        }
-
-        name_idx = _nm_meta_color_from_name(name);
-        if (name_idx == NM_META_COLOR_NONE) {
-            g_debug("Ignoring an unrecognized color: '%s'\n", name);
-            continue;
-        }
-
-        out_palette->ansi_seq[name_idx] = _resolve_color_alias(color) ?: color;
-    }
-
-    return TRUE;
-}
-
-static void
-set_colors(NmcColorOption   color_option,
-           bool *           out_use_colors,
-           char **          out_palette_buffer,
-           NmcColorPalette *out_palette)
-{
-    gs_free char *palette_str = NULL;
-    gboolean      use_colors;
-    gboolean      palette_set = FALSE;
-
-    nm_assert(out_use_colors);
-    nm_assert(out_palette);
-    nm_assert(out_palette_buffer && !*out_palette_buffer);
-
-    use_colors = check_colors(color_option, &palette_str);
-
-    *out_use_colors = use_colors;
-
-    if (use_colors && palette_str) {
-        gs_free_error GError *error = NULL;
-        NmcColorPalette       palette;
-
-        if (!parse_color_scheme(palette_str, &palette, &error))
-            g_debug("Error parsing color scheme: %s", error->message);
-        else {
-            *out_palette_buffer = g_steal_pointer(&palette_str);
-            *out_palette        = palette;
-            palette_set         = TRUE;
-        }
-    }
-
-    if (!palette_set)
-        *out_palette = (NmcColorPalette) _NMC_COLOR_PALETTE_INIT();
-}
-
-/*************************************************************************************/
-
-static gboolean
-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 gboolean nmcli_sigint = FALSE;
-
-gboolean
-nmc_seen_sigint(void)
-{
-    return nmcli_sigint;
-}
-
-void
-nmc_clear_sigint(void)
-{
-    nmcli_sigint = FALSE;
-}
-
-void
-nmc_exit(void)
-{
-    tcsetattr(STDIN_FILENO, TCSADRAIN, &termios_orig);
-    nmc_cleanup_readline();
-    exit(1);
-}
-
-static gboolean
-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;
-}
-
-void
-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);
-}
-
-static void
-nmc_cleanup(NmCli *nmc)
-{
-    pid_t ret;
-
-    g_clear_object(&nmc->client);
-
-    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);
-    }
-
-    nm_clear_pointer(&nmc->pwds_hash, g_hash_table_destroy);
-
-    nm_clear_g_free(&nmc->required_fields);
-
-    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);
-    }
-
-    nm_clear_g_free(&nmc->palette_buffer);
-
-    nmc_polkit_agent_fini(nmc);
-}
-
-int
-main(int argc, char *argv[])
-{
-    /* 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);
-#endif
-
-    /* Save terminal settings */
-    tcgetattr(STDIN_FILENO, &termios_orig);
-
-    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));
-
-    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);
-    }
-
-    nmc_cleanup(&nm_cli);
-    g_main_loop_unref(loop);
-
-    return nm_cli.return_value;
-}