mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-03 00:47:59 +02:00
merge: nmcli: sort connections and add colors to nmcli output (bgo #738613)
https://bugzilla.gnome.org/show_bug.cgi?id=738613
This commit is contained in:
commit
afe086e763
8 changed files with 658 additions and 141 deletions
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -250,7 +250,8 @@ usage (void)
|
|||
{
|
||||
g_printerr (_("Usage: nmcli connection { COMMAND | help }\n\n"
|
||||
"COMMAND := { show | up | down | add | modify | edit | delete | reload | load }\n\n"
|
||||
" show [--active] [[--show-secrets] [id | uuid | path | apath] <ID>] ...\n\n"
|
||||
" show [--active] [--order <order spec>]\n"
|
||||
" show [--active] [--show-secrets] [id | uuid | path | apath] <ID> ...\n\n"
|
||||
#if WITH_WIMAX
|
||||
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>] [nsp <name>] [passwd-file <file with passwords>]\n\n"
|
||||
#else
|
||||
|
|
@ -271,12 +272,12 @@ usage_connection_show (void)
|
|||
{
|
||||
g_printerr (_("Usage: nmcli connection show { ARGUMENTS | help }\n"
|
||||
"\n"
|
||||
"ARGUMENTS := [--active]\n"
|
||||
"ARGUMENTS := [--active] [--order <order spec>]\n"
|
||||
"\n"
|
||||
"List in-memory and on-disk connection profiles, some of which may also be\n"
|
||||
"active if a device is using that connection profile. Without a parameter, all\n"
|
||||
"profiles are listed. When --active option is specified, only the active\n"
|
||||
"profiles are shown.\n"
|
||||
"profiles are shown. --order allows custom connection ordering (see manual page).\n"
|
||||
"\n"
|
||||
"ARGUMENTS := [--active] [--show-secrets] [id | uuid | path | apath] <ID> ...\n"
|
||||
"\n"
|
||||
|
|
@ -763,10 +764,8 @@ find_active_connection (const GPtrArray *active_cons,
|
|||
}
|
||||
|
||||
static void
|
||||
fill_output_connection (gpointer data, gpointer user_data, gboolean active_only)
|
||||
fill_output_connection (NMConnection *connection, NmCli *nmc, gboolean active_only)
|
||||
{
|
||||
NMConnection *connection = (NMConnection *) data;
|
||||
NmCli *nmc = (NmCli *) user_data;
|
||||
NMSettingConnection *s_con;
|
||||
guint64 timestamp;
|
||||
time_t timestamp_real;
|
||||
|
|
@ -777,6 +776,7 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only)
|
|||
NMActiveConnection *ac = NULL;
|
||||
const char *ac_path = NULL;
|
||||
const char *ac_state = NULL;
|
||||
NMActiveConnectionState ac_state_int;
|
||||
char *ac_dev = NULL;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
|
|
@ -788,7 +788,8 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only)
|
|||
|
||||
if (ac) {
|
||||
ac_path = nm_object_get_path (NM_OBJECT (ac));
|
||||
ac_state = active_connection_state_to_string (nm_active_connection_get_state (ac));
|
||||
ac_state_int = nm_active_connection_get_state (ac);
|
||||
ac_state = active_connection_state_to_string (ac_state_int);
|
||||
ac_dev = get_ac_device_string (ac);
|
||||
}
|
||||
|
||||
|
|
@ -805,6 +806,16 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only)
|
|||
arr = nmc_dup_fields_array (nmc_fields_con_show,
|
||||
sizeof (nmc_fields_con_show),
|
||||
0);
|
||||
/* Show active connections in color */
|
||||
if (ac) {
|
||||
if (ac_state_int == NM_ACTIVE_CONNECTION_STATE_ACTIVATING)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_YELLOW);
|
||||
else if (ac_state_int == NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_GREEN);
|
||||
else if (ac_state_int > NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_RED);
|
||||
}
|
||||
|
||||
set_val_strc (arr, 0, nm_setting_connection_get_id (s_con));
|
||||
set_val_strc (arr, 1, nm_setting_connection_get_uuid (s_con));
|
||||
set_val_strc (arr, 2, nm_setting_connection_get_connection_type (s_con));
|
||||
|
|
@ -828,8 +839,9 @@ fill_output_connection_for_invisible (NMActiveConnection *ac, NmCli *nmc)
|
|||
NmcOutputField *arr;
|
||||
const char *ac_path = NULL;
|
||||
const char *ac_state = NULL;
|
||||
char *ac_dev = NULL;
|
||||
char *name, *ac_dev = NULL;
|
||||
|
||||
name = g_strdup_printf ("<invisible> %s", nm_active_connection_get_id (ac));
|
||||
ac_path = nm_object_get_path (NM_OBJECT (ac));
|
||||
ac_state = active_connection_state_to_string (nm_active_connection_get_state (ac));
|
||||
ac_dev = get_ac_device_string (ac);
|
||||
|
|
@ -837,7 +849,8 @@ fill_output_connection_for_invisible (NMActiveConnection *ac, NmCli *nmc)
|
|||
arr = nmc_dup_fields_array (nmc_fields_con_show,
|
||||
sizeof (nmc_fields_con_show),
|
||||
0);
|
||||
set_val_strc (arr, 0, nm_active_connection_get_id (ac));
|
||||
|
||||
set_val_str (arr, 0, name);
|
||||
set_val_strc (arr, 1, nm_active_connection_get_uuid (ac));
|
||||
set_val_strc (arr, 2, nm_active_connection_get_connection_type (ac));
|
||||
set_val_strc (arr, 3, NULL);
|
||||
|
|
@ -851,6 +864,8 @@ fill_output_connection_for_invisible (NMActiveConnection *ac, NmCli *nmc)
|
|||
set_val_strc (arr, 11, ac_state);
|
||||
set_val_strc (arr, 12, ac_path);
|
||||
|
||||
set_val_color_fmt_all (arr, NMC_TERM_FORMAT_DIM);
|
||||
|
||||
g_ptr_array_add (nmc->output_data, arr);
|
||||
}
|
||||
|
||||
|
|
@ -927,36 +942,6 @@ fill_output_active_connection (NMActiveConnection *active,
|
|||
g_string_free (dev_str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_output_for_all_invisible (NmCli *nmc)
|
||||
{
|
||||
const GPtrArray *acons;
|
||||
int a, c;
|
||||
|
||||
g_return_if_fail (nmc != NULL);
|
||||
|
||||
acons = nm_client_get_active_connections (nmc->client);
|
||||
for (a = 0; a < acons->len; a++) {
|
||||
gboolean found = FALSE;
|
||||
NMActiveConnection *acon = g_ptr_array_index (acons, a);
|
||||
const char *a_uuid = nm_active_connection_get_uuid (acon);
|
||||
|
||||
for (c = 0; c < nmc->connections->len; c++) {
|
||||
NMConnection *con = g_ptr_array_index (nmc->connections, c);
|
||||
const char *c_uuid = nm_connection_get_uuid (con);
|
||||
|
||||
if (strcmp (a_uuid, c_uuid) == 0) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Active connection is not in connections list */
|
||||
if (!found)
|
||||
fill_output_connection_for_invisible (acon, nmc);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char **array;
|
||||
guint32 idx;
|
||||
|
|
@ -1340,12 +1325,174 @@ split_required_fields_for_con_show (const char *input,
|
|||
return success;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
NMC_SORT_ACTIVE = 1,
|
||||
NMC_SORT_ACTIVE_INV = -1,
|
||||
NMC_SORT_NAME = 2,
|
||||
NMC_SORT_NAME_INV = -2,
|
||||
NMC_SORT_TYPE = 3,
|
||||
NMC_SORT_TYPE_INV = -3,
|
||||
NMC_SORT_PATH = 4,
|
||||
NMC_SORT_PATH_INV = -4,
|
||||
} NmcSortOrder;
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
const GArray *order;
|
||||
} NmcSortInfo;
|
||||
|
||||
static int
|
||||
compare_connections (gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
{
|
||||
NMConnection *ca = *(NMConnection **)a;
|
||||
NMConnection *cb = *(NMConnection **)b;
|
||||
NMActiveConnection *aca, *acb;
|
||||
NmcSortInfo *info = (NmcSortInfo *) user_data;
|
||||
GArray *default_order = NULL;
|
||||
const GArray *order;
|
||||
NmcSortOrder item;
|
||||
int cmp = 0, i;
|
||||
const char *tmp1, *tmp2;
|
||||
unsigned long tmp1_int, tmp2_int;
|
||||
|
||||
if (info->order )
|
||||
order = info->order;
|
||||
else {
|
||||
NmcSortOrder def[] = { NMC_SORT_ACTIVE, NMC_SORT_NAME, NMC_SORT_PATH };
|
||||
int num = G_N_ELEMENTS (def);
|
||||
default_order = g_array_sized_new (FALSE, FALSE, sizeof (NmcSortOrder), num);
|
||||
g_array_append_vals (default_order, def, num);
|
||||
order = default_order;
|
||||
}
|
||||
|
||||
for (i = 0; i < order->len; i++) {
|
||||
item = g_array_index (order, NmcSortOrder, i);
|
||||
switch (item) {
|
||||
case NMC_SORT_ACTIVE:
|
||||
case NMC_SORT_ACTIVE_INV:
|
||||
aca = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), ca);
|
||||
acb = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), cb);
|
||||
cmp = (aca && !acb) ? -1 : (!aca && acb) ? 1 : 0;
|
||||
if (item == NMC_SORT_ACTIVE_INV)
|
||||
cmp = -(cmp);
|
||||
break;
|
||||
case NMC_SORT_TYPE:
|
||||
case NMC_SORT_TYPE_INV:
|
||||
cmp = g_strcmp0 (nm_connection_get_connection_type (ca),
|
||||
nm_connection_get_connection_type (cb));
|
||||
if (item == NMC_SORT_TYPE_INV)
|
||||
cmp = -(cmp);
|
||||
break;
|
||||
case NMC_SORT_NAME:
|
||||
case NMC_SORT_NAME_INV:
|
||||
cmp = g_strcmp0 (nm_connection_get_id (ca),
|
||||
nm_connection_get_id (cb));
|
||||
if (item == NMC_SORT_NAME_INV)
|
||||
cmp = -(cmp);
|
||||
break;
|
||||
case NMC_SORT_PATH:
|
||||
case NMC_SORT_PATH_INV:
|
||||
tmp1 = nm_connection_get_path (ca);
|
||||
tmp2 = nm_connection_get_path (cb);
|
||||
tmp1 = tmp1 ? strrchr (tmp1, '/') : "0";
|
||||
tmp2 = tmp2 ? strrchr (tmp2, '/') : "0";
|
||||
nmc_string_to_uint (tmp1 ? tmp1+1 : "0", FALSE, 0, 0, &tmp1_int);
|
||||
nmc_string_to_uint (tmp2 ? tmp2+1 : "0", FALSE, 0, 0, &tmp2_int);
|
||||
cmp = (int) tmp1_int - tmp2_int;
|
||||
if (item == NMC_SORT_PATH_INV)
|
||||
cmp = -(cmp);
|
||||
break;
|
||||
default:
|
||||
cmp = 0;
|
||||
break;
|
||||
}
|
||||
if (cmp != 0)
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
if (default_order)
|
||||
g_array_unref (default_order);
|
||||
return cmp;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
sort_connections (const GPtrArray *cons, NmCli *nmc, const GArray *order)
|
||||
{
|
||||
GPtrArray *sorted;
|
||||
int i;
|
||||
NmcSortInfo compare_info;
|
||||
|
||||
compare_info.nmc = nmc;
|
||||
compare_info.order = order;
|
||||
|
||||
sorted = g_ptr_array_sized_new (cons->len);
|
||||
for (i = 0; cons && i < cons->len; i++)
|
||||
g_ptr_array_add (sorted, cons->pdata[i]);
|
||||
g_ptr_array_sort_with_data (sorted, compare_connections, &compare_info);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_ac_connections (gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
{
|
||||
NMActiveConnection *ca = *(NMActiveConnection **)a;
|
||||
NMActiveConnection *cb = *(NMActiveConnection **)b;
|
||||
int cmp;
|
||||
|
||||
/* Sort states first */
|
||||
cmp = nm_active_connection_get_state (cb) - nm_active_connection_get_state (ca);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
cmp = g_strcmp0 (nm_active_connection_get_id (ca),
|
||||
nm_active_connection_get_id (cb));
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
return g_strcmp0 (nm_active_connection_get_connection_type (ca),
|
||||
nm_active_connection_get_connection_type (cb));
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
get_invisible_active_connections (NmCli *nmc)
|
||||
{
|
||||
const GPtrArray *acons;
|
||||
GPtrArray *invisibles;
|
||||
int a, c;
|
||||
|
||||
g_return_val_if_fail (nmc != NULL, NULL);
|
||||
|
||||
invisibles = g_ptr_array_new ();
|
||||
acons = nm_client_get_active_connections (nmc->client);
|
||||
for (a = 0; a < acons->len; a++) {
|
||||
gboolean found = FALSE;
|
||||
NMActiveConnection *acon = g_ptr_array_index (acons, a);
|
||||
const char *a_uuid = nm_active_connection_get_uuid (acon);
|
||||
|
||||
for (c = 0; c < nmc->connections->len; c++) {
|
||||
NMConnection *con = g_ptr_array_index (nmc->connections, c);
|
||||
const char *c_uuid = nm_connection_get_uuid (con);
|
||||
|
||||
if (strcmp (a_uuid, c_uuid) == 0) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Active connection is not in connections array, add it to */
|
||||
if (!found)
|
||||
g_ptr_array_add (invisibles, acon);
|
||||
}
|
||||
g_ptr_array_sort_with_data (invisibles, compare_ac_connections, NULL);
|
||||
return invisibles;
|
||||
}
|
||||
|
||||
static NMCResultCode
|
||||
do_connections_show (NmCli *nmc, gboolean active_only, gboolean show_secrets,
|
||||
int argc, char **argv)
|
||||
const GArray *order, int argc, char **argv)
|
||||
{
|
||||
GError *err = NULL;
|
||||
char *profile_flds = NULL, *active_flds = NULL;
|
||||
GPtrArray *invisibles, *sorted_cons;
|
||||
|
||||
nmc->should_wait = FALSE;
|
||||
|
||||
|
|
@ -1379,13 +1526,19 @@ do_connections_show (NmCli *nmc, gboolean active_only, gboolean show_secrets,
|
|||
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES);
|
||||
g_ptr_array_add (nmc->output_data, arr);
|
||||
|
||||
/* Add values */
|
||||
for (i = 0; i < nmc->connections->len; i++) {
|
||||
NMConnection *con = NM_CONNECTION (nmc->connections->pdata[i]);
|
||||
fill_output_connection (con, nmc, active_only);
|
||||
}
|
||||
/* Some active connections may not be in connection list, show them here. */
|
||||
fill_output_for_all_invisible (nmc);
|
||||
/* There might be active connections not present in connection list
|
||||
* (e.g. private connections of a different user). Show them as well. */
|
||||
invisibles = get_invisible_active_connections (nmc);
|
||||
for (i = 0; i < invisibles->len; i++)
|
||||
fill_output_connection_for_invisible (invisibles->pdata[i], nmc);
|
||||
g_ptr_array_free (invisibles, FALSE);
|
||||
|
||||
/* Sort the connections and fill the output data */
|
||||
sorted_cons = sort_connections (nmc->connections, nmc, order);
|
||||
for (i = 0; i < sorted_cons->len; i++)
|
||||
fill_output_connection (sorted_cons->pdata[i], nmc, active_only);
|
||||
g_ptr_array_free (sorted_cons, FALSE);
|
||||
|
||||
print_data (nmc); /* Print all data */
|
||||
} else {
|
||||
gboolean new_line = FALSE;
|
||||
|
|
@ -6190,11 +6343,8 @@ nmcli_editor_tab_completion (const char *text, int start, int end)
|
|||
{
|
||||
char **match_array = NULL;
|
||||
const char *line = rl_line_buffer;
|
||||
const char *prompt = rl_prompt;
|
||||
rl_compentry_func_t *generator_func = NULL;
|
||||
gboolean copy_char;
|
||||
const char *p1;
|
||||
char *p2, *prompt_tmp;
|
||||
char *prompt_tmp;
|
||||
char *word = NULL;
|
||||
size_t n1;
|
||||
int num;
|
||||
|
|
@ -6212,19 +6362,7 @@ nmcli_editor_tab_completion (const char *text, int start, int end)
|
|||
rl_complete_with_tilde_expansion = 1;
|
||||
|
||||
/* Filter out possible ANSI color escape sequences */
|
||||
p1 = prompt;
|
||||
p2 = prompt_tmp = g_strdup (prompt);
|
||||
copy_char = TRUE;
|
||||
while (*p1) {
|
||||
if (*p1 == '\33')
|
||||
copy_char = FALSE;
|
||||
if (copy_char)
|
||||
*p2++ = *p1;
|
||||
if (!copy_char && *p1 == 'm')
|
||||
copy_char = TRUE;
|
||||
p1++;
|
||||
}
|
||||
*p2 = '\0';
|
||||
prompt_tmp = nmc_filter_out_colors ((const char *) rl_prompt);
|
||||
|
||||
/* Find the first non-space character */
|
||||
n1 = strspn (line, " \t");
|
||||
|
|
@ -7020,7 +7158,8 @@ property_edit_submenu (NmCli *nmc,
|
|||
gboolean temp_changes;
|
||||
gboolean removed;
|
||||
|
||||
prompt = nmc_colorize (nmc->editor_prompt_color, "nmcli %s.%s> ",
|
||||
prompt = nmc_colorize (nmc->editor_prompt_color, NMC_TERM_FORMAT_NORMAL,
|
||||
"nmcli %s.%s> ",
|
||||
nm_setting_get_name (curr_setting), prop_name);
|
||||
|
||||
while (cmd_property_loop) {
|
||||
|
|
@ -7368,7 +7507,7 @@ menu_switch_to_level0 (NmcEditorMenuContext *menu_ctx,
|
|||
{
|
||||
menu_ctx->level = 0;
|
||||
g_free (menu_ctx->main_prompt);
|
||||
menu_ctx->main_prompt = nmc_colorize (prompt_color, "%s", prompt);
|
||||
menu_ctx->main_prompt = nmc_colorize (prompt_color, NMC_TERM_FORMAT_NORMAL, "%s", prompt);
|
||||
menu_ctx->curr_setting = NULL;
|
||||
g_strfreev (menu_ctx->valid_props);
|
||||
menu_ctx->valid_props = NULL;
|
||||
|
|
@ -7384,7 +7523,8 @@ menu_switch_to_level1 (NmcEditorMenuContext *menu_ctx,
|
|||
{
|
||||
menu_ctx->level = 1;
|
||||
g_free (menu_ctx->main_prompt);
|
||||
menu_ctx->main_prompt = nmc_colorize (prompt_color, "nmcli %s> ", setting_name);
|
||||
menu_ctx->main_prompt = nmc_colorize (prompt_color, NMC_TERM_FORMAT_NORMAL,
|
||||
"nmcli %s> ", setting_name);
|
||||
menu_ctx->curr_setting = setting;
|
||||
g_strfreev (menu_ctx->valid_props);
|
||||
menu_ctx->valid_props = nmc_setting_get_valid_properties (menu_ctx->curr_setting);
|
||||
|
|
@ -7418,7 +7558,8 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
g_print (_("You may edit the following settings: %s\n"), valid_settings_str);
|
||||
|
||||
menu_ctx.level = 0;
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, BASE_PROMPT);
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, NMC_TERM_FORMAT_NORMAL,
|
||||
BASE_PROMPT);
|
||||
menu_ctx.curr_setting = NULL;
|
||||
menu_ctx.valid_props = NULL;
|
||||
menu_ctx.valid_props_str = NULL;
|
||||
|
|
@ -8054,9 +8195,11 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
nmc->editor_prompt_color = color;
|
||||
g_free (menu_ctx.main_prompt);
|
||||
if (menu_ctx.level == 0)
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, BASE_PROMPT);
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, NMC_TERM_FORMAT_NORMAL,
|
||||
BASE_PROMPT);
|
||||
else
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, "nmcli %s> ",
|
||||
menu_ctx.main_prompt = nmc_colorize (nmc->editor_prompt_color, NMC_TERM_FORMAT_NORMAL,
|
||||
"nmcli %s> ",
|
||||
nm_setting_get_name (menu_ctx.curr_setting));
|
||||
}
|
||||
} else if (!cmd_arg_p) {
|
||||
|
|
@ -8918,6 +9061,67 @@ nmcli_con_tab_completion (const char *text, int start, int end)
|
|||
return match_array;
|
||||
}
|
||||
|
||||
static GArray *
|
||||
parse_preferred_connection_order (const char *order, GError **error)
|
||||
{
|
||||
char **strv, **iter;
|
||||
const char *str;
|
||||
GArray *order_arr;
|
||||
NmcSortOrder val;
|
||||
gboolean inverse;
|
||||
int i;
|
||||
|
||||
strv = nmc_strsplit_set (order, ":", -1);
|
||||
if (!strv || !*strv) {
|
||||
g_set_error (error, NMCLI_ERROR, 0,
|
||||
_("incorrect string '%s' of '--order' option"), order);
|
||||
g_strfreev (strv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
order_arr = g_array_sized_new (FALSE, FALSE, sizeof (NmcSortOrder), 4);
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
str = *iter;
|
||||
inverse = FALSE;
|
||||
if (str[0] == '-')
|
||||
inverse = TRUE;
|
||||
if (str[0] == '+' || str[0] == '-')
|
||||
str++;
|
||||
|
||||
if (matches (str, "active") == 0)
|
||||
val = inverse ? NMC_SORT_ACTIVE_INV : NMC_SORT_ACTIVE;
|
||||
else if (matches (str, "name") == 0)
|
||||
val = inverse ? NMC_SORT_NAME_INV : NMC_SORT_NAME;
|
||||
else if (matches (str, "type") == 0)
|
||||
val = inverse ? NMC_SORT_TYPE_INV : NMC_SORT_TYPE;
|
||||
else if (matches (str, "path") == 0)
|
||||
val = inverse ? NMC_SORT_PATH_INV : NMC_SORT_PATH;
|
||||
else {
|
||||
g_array_unref (order_arr);
|
||||
order_arr = NULL;
|
||||
g_set_error (error, NMCLI_ERROR, 0,
|
||||
_("incorrect item '%s' in '--order' option"), *iter);
|
||||
break;
|
||||
}
|
||||
/* Check duplicates*/
|
||||
for (i = 0; i < order_arr->len; i++) {
|
||||
if (abs (g_array_index (order_arr, NmcSortOrder, i)) - abs (val) == 0) {
|
||||
g_array_unref (order_arr);
|
||||
order_arr = NULL;
|
||||
g_set_error (error, NMCLI_ERROR, 0,
|
||||
_("'%s' repeats in '--order' option"), str);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Value is ok and unique, add it to the array */
|
||||
g_array_append_val (order_arr, val);
|
||||
}
|
||||
end:
|
||||
g_strfreev (strv);
|
||||
return order_arr;
|
||||
}
|
||||
|
||||
/* Entry point function for connections-related commands: 'nmcli connection' */
|
||||
NMCResultCode
|
||||
do_connections (NmCli *nmc, int argc, char **argv)
|
||||
|
|
@ -8960,16 +9164,17 @@ do_connections (NmCli *nmc, int argc, char **argv)
|
|||
if (argc == 0) {
|
||||
if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error))
|
||||
goto opt_error;
|
||||
nmc->return_value = do_connections_show (nmc, FALSE, FALSE, argc, argv);
|
||||
nmc->return_value = do_connections_show (nmc, FALSE, FALSE, NULL, argc, argv);
|
||||
} else {
|
||||
if (matches (*argv, "show") == 0) {
|
||||
gboolean active = FALSE;
|
||||
gboolean show_secrets = FALSE;
|
||||
GArray *order = NULL;
|
||||
int i;
|
||||
|
||||
next_arg (&argc, &argv);
|
||||
/* check connection show options [--active] [--show-secrets] */
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!active && nmc_arg_is_option (*argv, "active")) {
|
||||
active = TRUE;
|
||||
next_arg (&argc, &argv);
|
||||
|
|
@ -8978,8 +9183,21 @@ do_connections (NmCli *nmc, int argc, char **argv)
|
|||
show_secrets = TRUE;
|
||||
next_arg (&argc, &argv);
|
||||
}
|
||||
if (!order && nmc_arg_is_option (*argv, "order")) {
|
||||
if (next_arg (&argc, &argv) != 0) {
|
||||
g_set_error_literal (&error, NMCLI_ERROR, 0,
|
||||
_("'--order' argument is missing"));
|
||||
goto opt_error;
|
||||
}
|
||||
order = parse_preferred_connection_order (*argv, &error);
|
||||
if (error)
|
||||
goto opt_error;
|
||||
next_arg (&argc, &argv);
|
||||
}
|
||||
}
|
||||
nmc->return_value = do_connections_show (nmc, active, show_secrets, argc, argv);
|
||||
nmc->return_value = do_connections_show (nmc, active, show_secrets, order, argc, argv);
|
||||
if (order)
|
||||
g_array_unref (order);
|
||||
} else if (matches(*argv, "up") == 0) {
|
||||
nmc->return_value = do_connection_up (nmc, argc-1, argv+1);
|
||||
} else if (matches(*argv, "down") == 0) {
|
||||
|
|
|
|||
|
|
@ -1188,15 +1188,27 @@ static void
|
|||
fill_output_device_status (NMDevice *device, NmCli *nmc)
|
||||
{
|
||||
NMActiveConnection *ac;
|
||||
NMDeviceState state;
|
||||
NmcOutputField *arr = nmc_dup_fields_array (nmc_fields_dev_status,
|
||||
sizeof (nmc_fields_dev_status),
|
||||
0);
|
||||
|
||||
state = nm_device_get_state (device);
|
||||
ac = nm_device_get_active_connection (device);
|
||||
|
||||
/* Show devices in color */
|
||||
if (state <= NM_DEVICE_STATE_UNAVAILABLE)
|
||||
set_val_color_fmt_all (arr, NMC_TERM_FORMAT_DIM);
|
||||
else if (state == NM_DEVICE_STATE_DISCONNECTED)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_RED);
|
||||
else if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_YELLOW);
|
||||
else if (state == NM_DEVICE_STATE_ACTIVATED)
|
||||
set_val_color_all (arr, NMC_TERM_COLOR_GREEN);
|
||||
|
||||
set_val_strc (arr, 0, nm_device_get_iface (device));
|
||||
set_val_strc (arr, 1, nm_device_get_type_description (device));
|
||||
set_val_strc (arr, 2, nmc_device_state_to_string (nm_device_get_state (device)));
|
||||
set_val_strc (arr, 2, nmc_device_state_to_string (state));
|
||||
set_val_strc (arr, 3, nm_object_get_path (NM_OBJECT (device)));
|
||||
set_val_strc (arr, 4, get_active_connection_id (device));
|
||||
set_val_strc (arr, 5, ac ? nm_active_connection_get_uuid (ac) : NULL);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -264,6 +264,26 @@ nm_state_to_string (NMState state)
|
|||
}
|
||||
}
|
||||
|
||||
static NmcTermColor
|
||||
state_to_color (NMState state)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_STATE_CONNECTING:
|
||||
return NMC_TERM_COLOR_YELLOW;
|
||||
case NM_STATE_CONNECTED_LOCAL:
|
||||
case NM_STATE_CONNECTED_SITE:
|
||||
case NM_STATE_CONNECTED_GLOBAL:
|
||||
return NMC_TERM_COLOR_GREEN;
|
||||
case NM_STATE_DISCONNECTING:
|
||||
return NMC_TERM_COLOR_YELLOW;
|
||||
case NM_STATE_ASLEEP:
|
||||
case NM_STATE_DISCONNECTED:
|
||||
return NMC_TERM_COLOR_RED;
|
||||
default:
|
||||
return NMC_TERM_COLOR_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
nm_connectivity_to_string (NMConnectivityState connectivity)
|
||||
{
|
||||
|
|
@ -282,17 +302,33 @@ nm_connectivity_to_string (NMConnectivityState connectivity)
|
|||
}
|
||||
}
|
||||
|
||||
static NmcTermColor
|
||||
connectivity_to_color (NMConnectivityState connectivity)
|
||||
{
|
||||
switch (connectivity) {
|
||||
case NM_CONNECTIVITY_NONE:
|
||||
return NMC_TERM_COLOR_RED;
|
||||
case NM_CONNECTIVITY_PORTAL:
|
||||
case NM_CONNECTIVITY_LIMITED:
|
||||
return NMC_TERM_COLOR_YELLOW;
|
||||
case NM_CONNECTIVITY_FULL:
|
||||
return NMC_TERM_COLOR_GREEN;
|
||||
default:
|
||||
return NMC_TERM_COLOR_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_flds)
|
||||
{
|
||||
gboolean startup = FALSE;
|
||||
NMState state = NM_STATE_UNKNOWN;
|
||||
NMConnectivityState connectivity = NM_CONNECTIVITY_UNKNOWN;
|
||||
const char *net_enabled_str;
|
||||
const char *wireless_hw_enabled_str, *wireless_enabled_str;
|
||||
const char *wwan_hw_enabled_str, *wwan_enabled_str;
|
||||
gboolean net_enabled;
|
||||
gboolean wireless_hw_enabled, wireless_enabled;
|
||||
gboolean wwan_hw_enabled, wwan_enabled;
|
||||
#if WITH_WIMAX
|
||||
const char *wimax_hw_enabled_str, *wimax_enabled_str;
|
||||
gboolean wimax_hw_enabled, wimax_enabled;
|
||||
#endif
|
||||
GError *error = NULL;
|
||||
const char *fields_str;
|
||||
|
|
@ -333,14 +369,14 @@ show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_fl
|
|||
state = nm_client_get_state (nmc->client);
|
||||
startup = nm_client_get_startup (nmc->client);
|
||||
connectivity = nm_client_get_connectivity (nmc->client);
|
||||
net_enabled_str = nm_client_networking_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wireless_hw_enabled_str = nm_client_wireless_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wireless_enabled_str = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wwan_hw_enabled_str = nm_client_wwan_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wwan_enabled_str = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
net_enabled = nm_client_networking_get_enabled (nmc->client);
|
||||
wireless_hw_enabled = nm_client_wireless_hardware_get_enabled (nmc->client);
|
||||
wireless_enabled = nm_client_wireless_get_enabled (nmc->client);
|
||||
wwan_hw_enabled = nm_client_wwan_hardware_get_enabled (nmc->client);
|
||||
wwan_enabled = nm_client_wwan_get_enabled (nmc->client);
|
||||
#if WITH_WIMAX
|
||||
wimax_hw_enabled_str = nm_client_wimax_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wimax_enabled_str = nm_client_wimax_get_enabled (nmc->client) ? _("enabled") : _("disabled");
|
||||
wimax_hw_enabled = nm_client_wimax_hardware_get_enabled (nmc->client);
|
||||
wimax_enabled = nm_client_wimax_get_enabled (nmc->client);
|
||||
#endif
|
||||
|
||||
nmc->print_fields.header_name = pretty_header_name ? (char *) pretty_header_name : _("NetworkManager status");
|
||||
|
|
@ -353,15 +389,30 @@ show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_fl
|
|||
set_val_strc (arr, 2, nm_state_to_string (state));
|
||||
set_val_strc (arr, 3, startup ? _("starting") : _("started"));
|
||||
set_val_strc (arr, 4, nm_connectivity_to_string (connectivity));
|
||||
set_val_strc (arr, 5, net_enabled_str);
|
||||
set_val_strc (arr, 6, wireless_hw_enabled_str);
|
||||
set_val_strc (arr, 7, wireless_enabled_str);
|
||||
set_val_strc (arr, 8, wwan_hw_enabled_str);
|
||||
set_val_strc (arr, 9, wwan_enabled_str);
|
||||
set_val_strc (arr, 5, net_enabled ? _("enabled") : _("disabled"));
|
||||
set_val_strc (arr, 6, wireless_hw_enabled ? _("enabled") : _("disabled"));
|
||||
set_val_strc (arr, 7, wireless_enabled ? _("enabled") : _("disabled"));
|
||||
set_val_strc (arr, 8, wwan_hw_enabled ? _("enabled") : _("disabled"));
|
||||
set_val_strc (arr, 9, wwan_enabled ? _("enabled") : _("disabled"));
|
||||
#if WITH_WIMAX
|
||||
set_val_strc (arr, 10, wimax_hw_enabled_str);
|
||||
set_val_strc (arr, 11, wimax_enabled_str);
|
||||
set_val_strc (arr, 10, wimax_hw_enabled ? _("enabled") : _("disabled"));
|
||||
set_val_strc (arr, 11, wimax_enabled ? _("enabled") : _("disabled"));
|
||||
#endif
|
||||
|
||||
/* Set colors */
|
||||
arr[2].color = state_to_color (state);
|
||||
arr[3].color = startup ? NMC_TERM_COLOR_YELLOW : NMC_TERM_COLOR_GREEN;
|
||||
arr[4].color = connectivity_to_color (connectivity);
|
||||
arr[5].color = net_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
arr[6].color = wireless_hw_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
arr[7].color = wireless_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
arr[8].color = wwan_hw_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
arr[9].color = wwan_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
#if WITH_WIMAX
|
||||
arr[10].color = wimax_hw_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
arr[11].color = wimax_enabled ? NMC_TERM_COLOR_GREEN : NMC_TERM_COLOR_RED;
|
||||
#endif
|
||||
|
||||
g_ptr_array_add (nmc->output_data, arr);
|
||||
|
||||
print_data (nmc); /* Print all data */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
/* Generated configuration file */
|
||||
|
|
@ -89,6 +89,7 @@ usage (const char *prog_name)
|
|||
" -t[erse] terse output\n"
|
||||
" -p[retty] pretty output\n"
|
||||
" -m[ode] tabular|multiline output mode\n"
|
||||
" -c[olors] auto|yes|no whether to use colors in output\n"
|
||||
" -f[ields] <field1,field2,...>|all|common specify fields to output\n"
|
||||
" -e[scape] yes|no escape columns separators in values\n"
|
||||
" -n[ocheck] don't check nmcli and NetworkManager versions\n"
|
||||
|
|
@ -210,6 +211,24 @@ parse_command_line (NmCli *nmc, int argc, char **argv)
|
|||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
return nmc->return_value;
|
||||
}
|
||||
} else if (matches (opt, "-colors") == 0) {
|
||||
next_arg (&argc, &argv);
|
||||
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 nmc->return_value;
|
||||
}
|
||||
if (matches (argv[1], "auto") == 0)
|
||||
nmc->use_colors = NMC_USE_COLOR_AUTO;
|
||||
else if (matches (argv[1], "yes") == 0)
|
||||
nmc->use_colors = NMC_USE_COLOR_YES;
|
||||
else if (matches (argv[1], "no") == 0)
|
||||
nmc->use_colors = NMC_USE_COLOR_NO;
|
||||
else {
|
||||
g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt);
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
return nmc->return_value;
|
||||
}
|
||||
} else if (matches (opt, "-escape") == 0) {
|
||||
next_arg (&argc, &argv);
|
||||
if (argc <= 1) {
|
||||
|
|
@ -526,6 +545,7 @@ nmc_init (NmCli *nmc)
|
|||
memset (&nmc->print_fields, '\0', sizeof (NmcPrintFields));
|
||||
nmc->nocheck_ver = FALSE;
|
||||
nmc->ask = FALSE;
|
||||
nmc->use_colors = NMC_USE_COLOR_AUTO;
|
||||
nmc->in_editor = FALSE;
|
||||
nmc->editor_status_line = FALSE;
|
||||
nmc->editor_save_confirmation = TRUE;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NMC_NMCLI_H
|
||||
|
|
@ -68,6 +68,28 @@ typedef enum {
|
|||
NMC_RESULT_ERROR_NOT_FOUND = 10
|
||||
} NMCResultCode;
|
||||
|
||||
typedef enum {
|
||||
NMC_TERM_COLOR_NORMAL = 0,
|
||||
NMC_TERM_COLOR_BLACK = 1,
|
||||
NMC_TERM_COLOR_RED = 2,
|
||||
NMC_TERM_COLOR_GREEN = 3,
|
||||
NMC_TERM_COLOR_YELLOW = 4,
|
||||
NMC_TERM_COLOR_BLUE = 5,
|
||||
NMC_TERM_COLOR_MAGENTA = 6,
|
||||
NMC_TERM_COLOR_CYAN = 7,
|
||||
NMC_TERM_COLOR_WHITE = 8
|
||||
} NmcTermColor;
|
||||
|
||||
typedef enum {
|
||||
NMC_TERM_FORMAT_NORMAL,
|
||||
NMC_TERM_FORMAT_BOLD,
|
||||
NMC_TERM_FORMAT_DIM,
|
||||
NMC_TERM_FORMAT_UNDERLINE,
|
||||
NMC_TERM_FORMAT_BLINK,
|
||||
NMC_TERM_FORMAT_REVERSE,
|
||||
NMC_TERM_FORMAT_HIDDEN,
|
||||
} NmcTermFormat;
|
||||
|
||||
typedef enum {
|
||||
NMC_PRINT_TERSE = 0,
|
||||
NMC_PRINT_NORMAL = 1,
|
||||
|
|
@ -90,6 +112,8 @@ typedef struct _NmcOutputField {
|
|||
gboolean value_is_array; /* Whether value is char** instead of char* */
|
||||
gboolean free_value; /* Whether to free the value */
|
||||
guint32 flags; /* Flags - whether and how to print values/field names/headers */
|
||||
NmcTermColor color; /* Use this color to print value */
|
||||
NmcTermFormat color_fmt; /* Use this terminal format to print value */
|
||||
} NmcOutputField;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -99,16 +123,10 @@ typedef struct {
|
|||
} NmcPrintFields;
|
||||
|
||||
typedef enum {
|
||||
NMC_TERM_COLOR_NORMAL = 0,
|
||||
NMC_TERM_COLOR_BLACK = 1,
|
||||
NMC_TERM_COLOR_RED = 2,
|
||||
NMC_TERM_COLOR_GREEN = 3,
|
||||
NMC_TERM_COLOR_YELLOW = 4,
|
||||
NMC_TERM_COLOR_BLUE = 5,
|
||||
NMC_TERM_COLOR_MAGENTA = 6,
|
||||
NMC_TERM_COLOR_CYAN = 7,
|
||||
NMC_TERM_COLOR_WHITE = 8
|
||||
} NmcTermColor;
|
||||
NMC_USE_COLOR_AUTO,
|
||||
NMC_USE_COLOR_YES,
|
||||
NMC_USE_COLOR_NO,
|
||||
} NmcColorOption;
|
||||
|
||||
/* NmCli - main structure */
|
||||
typedef struct _NmCli {
|
||||
|
|
@ -131,6 +149,7 @@ typedef struct _NmCli {
|
|||
NMCPrintOutput print_output; /* Output mode */
|
||||
gboolean multiline_output; /* Multiline output instead of default tabular */
|
||||
gboolean mode_specified; /* Whether tabular/multiline mode was specified via '--mode' option */
|
||||
NmcColorOption use_colors; /* Whether to use colors for output: option '--color' */
|
||||
gboolean escape_values; /* Whether to escape ':' and '\' in terse tabular mode */
|
||||
char *required_fields; /* Required fields in output: '--fields' option */
|
||||
GPtrArray *output_data; /* GPtrArray of arrays of NmcOutputField structs - accumulates data for output */
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
/* Generated configuration file */
|
||||
|
|
@ -307,28 +307,121 @@ nmc_term_color_sequence (NmcTermColor color)
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
nmc_term_format_sequence (NmcTermFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case NMC_TERM_FORMAT_BOLD:
|
||||
return "\33[1m";
|
||||
break;
|
||||
case NMC_TERM_FORMAT_DIM:
|
||||
return "\33[2m";
|
||||
break;
|
||||
case NMC_TERM_FORMAT_UNDERLINE:
|
||||
return "\33[4m";
|
||||
break;
|
||||
case NMC_TERM_FORMAT_BLINK:
|
||||
return "\33[5m";
|
||||
break;
|
||||
case NMC_TERM_FORMAT_REVERSE:
|
||||
return "\33[7m";
|
||||
break;
|
||||
case NMC_TERM_FORMAT_HIDDEN:
|
||||
return "\33[8m";
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nmc_colorize (NmcTermColor color, const char *fmt, ...)
|
||||
nmc_colorize (NmcTermColor color, NmcTermFormat format, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *str, *colored;
|
||||
const char *ansi_color, *color_end;
|
||||
const char *ansi_color, *color_end, *ansi_fmt, *format_end;
|
||||
static const char *end_seq = "\33[0m";
|
||||
|
||||
va_start (args, fmt);
|
||||
str = g_strdup_vprintf (fmt, args);
|
||||
va_end (args);
|
||||
|
||||
ansi_color = nmc_term_color_sequence (color);
|
||||
if (*ansi_color)
|
||||
color_end = "\33[0m";
|
||||
else
|
||||
color_end = "";
|
||||
ansi_fmt = nmc_term_format_sequence (format);
|
||||
color_end = *ansi_color ? end_seq : "";
|
||||
format_end = *ansi_fmt ? end_seq : "";
|
||||
|
||||
colored = g_strdup_printf ("%s%s%s", ansi_color, str, color_end);
|
||||
colored = g_strdup_printf ("%s%s%s%s%s", ansi_fmt, ansi_color, str, color_end, format_end);
|
||||
g_free (str);
|
||||
return colored;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count characters belonging to terminal color escape sequences.
|
||||
* @start points to beginning of the string, @end points to the end,
|
||||
* or NULL if the string is nul-terminated.
|
||||
*/
|
||||
static int
|
||||
nmc_count_color_escape_chars (const char *start, const char *end)
|
||||
{
|
||||
int num = 0;
|
||||
gboolean inside = FALSE;
|
||||
|
||||
if (end == NULL)
|
||||
end = start + strlen (start);
|
||||
|
||||
while (start < end) {
|
||||
if (*start == '\33' && *(start+1) == '[')
|
||||
inside = TRUE;
|
||||
if (inside)
|
||||
num++;
|
||||
if (*start == 'm')
|
||||
inside = FALSE;
|
||||
start++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Filter out possible ANSI color escape sequences */
|
||||
/* It directly modifies the passed string @str. */
|
||||
void
|
||||
nmc_filter_out_colors_inplace (char *str)
|
||||
{
|
||||
const char *p1;
|
||||
char *p2;
|
||||
gboolean copy_char = TRUE;
|
||||
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
p1 = p2 = str;
|
||||
while (*p1) {
|
||||
if (*p1 == '\33' && *(p1+1) == '[')
|
||||
copy_char = FALSE;
|
||||
if (copy_char)
|
||||
*p2++ = *p1;
|
||||
if (!copy_char && *p1 == 'm')
|
||||
copy_char = TRUE;
|
||||
p1++;
|
||||
}
|
||||
*p2 = '\0';
|
||||
}
|
||||
|
||||
/* Filter out possible ANSI color escape sequences */
|
||||
char *
|
||||
nmc_filter_out_colors (const char *str)
|
||||
{
|
||||
char *filtered;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
filtered = g_strdup (str);
|
||||
nmc_filter_out_colors_inplace (filtered);
|
||||
return filtered;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert string to signed integer.
|
||||
* If required, the resulting number is checked to be in the <min,max> range.
|
||||
|
|
@ -588,21 +681,24 @@ nmc_strsplit_set (const char *str, const char *delimiter, int max_tokens)
|
|||
}
|
||||
|
||||
/*
|
||||
* Find out how many columns an UTF-8 string occupies on the screen
|
||||
* Find out how many columns an UTF-8 string occupies on the screen.
|
||||
*/
|
||||
int
|
||||
nmc_string_screen_width (const char *start, const char *end)
|
||||
{
|
||||
int width = 0;
|
||||
const char *p = start;
|
||||
|
||||
if (end == NULL)
|
||||
end = start + strlen (start);
|
||||
|
||||
while (start < end) {
|
||||
width += g_unichar_iswide (g_utf8_get_char (start)) ? 2 : g_unichar_iszerowidth (g_utf8_get_char (start)) ? 0 : 1;
|
||||
start = g_utf8_next_char (start);
|
||||
while (p < end) {
|
||||
width += g_unichar_iswide (g_utf8_get_char (p)) ? 2 : g_unichar_iszerowidth (g_utf8_get_char (p)) ? 0 : 1;
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
return width;
|
||||
|
||||
/* Subtract color escape sequences as they don't occupy space. */
|
||||
return width - nmc_count_color_escape_chars (start, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -637,6 +733,26 @@ set_val_arrc (NmcOutputField fields_array[], guint32 idx, const char **value)
|
|||
fields_array[idx].free_value = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
set_val_color_all (NmcOutputField fields_array[], NmcTermColor color)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; fields_array[i].name; i++) {
|
||||
fields_array[i].color = color;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_val_color_fmt_all (NmcOutputField fields_array[], NmcTermFormat format)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; fields_array[i].name; i++) {
|
||||
fields_array[i].color_fmt = format;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free 'value' members in array of NmcOutputField
|
||||
*/
|
||||
|
|
@ -855,23 +971,55 @@ nmc_empty_output_fields (NmCli *nmc)
|
|||
}
|
||||
|
||||
static char *
|
||||
get_value_to_print (NmcOutputField *fields,
|
||||
colorize_string (gboolean colorize,
|
||||
NmcTermColor color,
|
||||
NmcTermFormat color_fmt,
|
||||
const char *str,
|
||||
gboolean *dealloc)
|
||||
{
|
||||
char *out;
|
||||
|
||||
if ( colorize
|
||||
&& (color != NMC_TERM_COLOR_NORMAL || color_fmt != NMC_TERM_FORMAT_NORMAL)) {
|
||||
out = nmc_colorize (color, color_fmt, str);
|
||||
*dealloc = TRUE;
|
||||
} else {
|
||||
out = (char *) str;
|
||||
*dealloc = FALSE;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_value_to_print (NmcOutputField *field,
|
||||
gboolean field_name,
|
||||
const char *not_set_str,
|
||||
gboolean *dealloc)
|
||||
gboolean *dealloc,
|
||||
gboolean colorize)
|
||||
{
|
||||
gboolean is_array = fields->value_is_array;
|
||||
char *value;
|
||||
gboolean is_array = field->value_is_array;
|
||||
char *value, *out;
|
||||
gboolean free_value, free_out;
|
||||
|
||||
if (field_name)
|
||||
value = _(fields->name_l10n);
|
||||
value = _(field->name_l10n);
|
||||
else
|
||||
value = fields->value ?
|
||||
(is_array ? g_strjoinv (" | ", (char **) fields->value) :
|
||||
(char *) fields->value) :
|
||||
value = field->value ?
|
||||
(is_array ? g_strjoinv (" | ", (char **) field->value) :
|
||||
(char *) field->value) :
|
||||
(char *) not_set_str;
|
||||
*dealloc = fields->value && is_array && !field_name;
|
||||
return value;
|
||||
free_value = field->value && is_array && !field_name;
|
||||
|
||||
/* colorize the value */
|
||||
out = colorize_string (colorize, field->color, field->color_fmt, value, &free_out);
|
||||
if (free_out) {
|
||||
if (free_value)
|
||||
g_free (value);
|
||||
*dealloc = TRUE;
|
||||
} else
|
||||
*dealloc = free_value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -901,6 +1049,7 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
gboolean field_names = field_values[0].flags & NMC_OF_FLAG_FIELD_NAMES;
|
||||
gboolean section_prefix = field_values[0].flags & NMC_OF_FLAG_SECTION_PREFIX;
|
||||
gboolean main_header = main_header_add || main_header_only;
|
||||
gboolean colorize;
|
||||
|
||||
/* No headers are printed in terse mode:
|
||||
* - neither main header nor field (column) names
|
||||
|
|
@ -908,6 +1057,11 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
if ((main_header_only || field_names) && terse)
|
||||
return;
|
||||
|
||||
/* Only show colors if the output is a terminal */
|
||||
colorize = nmc->use_colors == NMC_USE_COLOR_YES ? TRUE :
|
||||
nmc->use_colors == NMC_USE_COLOR_NO ? FALSE :
|
||||
isatty (fileno (stdout));
|
||||
|
||||
if (multiline) {
|
||||
/* --- Multiline mode --- */
|
||||
enum { ML_HEADER_WIDTH = 79 };
|
||||
|
|
@ -930,6 +1084,7 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
if (!main_header_only && !field_names) {
|
||||
for (i = 0; i < fields.indices->len; i++) {
|
||||
char *tmp;
|
||||
gboolean free_print_val;
|
||||
int idx = g_array_index (fields.indices, int, i);
|
||||
gboolean is_array = field_values[idx].value_is_array;
|
||||
|
||||
|
|
@ -941,10 +1096,14 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
|
||||
if (is_array) {
|
||||
/* value is a null-terminated string array */
|
||||
const char **p;
|
||||
const char **p, *val;
|
||||
char *print_val;
|
||||
int j;
|
||||
|
||||
for (p = (const char **) field_values[idx].value, j = 1; p && *p; p++, j++) {
|
||||
val = *p ? *p : not_set_str;
|
||||
print_val = colorize_string (colorize, field_values[idx].color, field_values[idx].color_fmt,
|
||||
val, &free_print_val);
|
||||
tmp = g_strdup_printf ("%s%s%s[%d]:",
|
||||
section_prefix ? (const char*) field_values[0].value : "",
|
||||
section_prefix ? "." : "",
|
||||
|
|
@ -952,24 +1111,30 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
j);
|
||||
width1 = strlen (tmp);
|
||||
width2 = nmc_string_screen_width (tmp, NULL);
|
||||
g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp,
|
||||
*p ? *p : not_set_str);
|
||||
g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val);
|
||||
g_free (tmp);
|
||||
if (free_print_val)
|
||||
g_free (print_val);
|
||||
}
|
||||
} else {
|
||||
/* value is a string */
|
||||
const char *hdr_name = (const char*) field_values[0].value;
|
||||
const char *val = (const char*) field_values[idx].value;
|
||||
char *print_val;
|
||||
|
||||
val = val ? val : not_set_str;
|
||||
print_val = colorize_string (colorize, field_values[idx].color, field_values[idx].color_fmt,
|
||||
val, &free_print_val);
|
||||
tmp = g_strdup_printf ("%s%s%s:",
|
||||
section_prefix ? hdr_name : "",
|
||||
section_prefix ? "." : "",
|
||||
_(field_values[idx].name_l10n));
|
||||
width1 = strlen (tmp);
|
||||
width2 = nmc_string_screen_width (tmp, NULL);
|
||||
g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp,
|
||||
val ? val : not_set_str);
|
||||
g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val);
|
||||
g_free (tmp);
|
||||
if (free_print_val)
|
||||
g_free (print_val);
|
||||
}
|
||||
}
|
||||
if (pretty) {
|
||||
|
|
@ -987,7 +1152,8 @@ print_required_fields (NmCli *nmc, const NmcOutputField field_values[])
|
|||
for (i = 0; i < fields.indices->len; i++) {
|
||||
int idx = g_array_index (fields.indices, int, i);
|
||||
gboolean dealloc;
|
||||
char *value = get_value_to_print ((NmcOutputField *) field_values+idx, field_names, not_set_str, &dealloc);
|
||||
char *value = get_value_to_print ((NmcOutputField *) field_values+idx, field_names,
|
||||
not_set_str, &dealloc, colorize);
|
||||
|
||||
if (terse) {
|
||||
if (escape) {
|
||||
|
|
@ -1085,7 +1251,7 @@ print_data (NmCli *nmc)
|
|||
char *value;
|
||||
row = g_ptr_array_index (nmc->output_data, j);
|
||||
field_names = row[0].flags & NMC_OF_FLAG_FIELD_NAMES;
|
||||
value = get_value_to_print (row+i, field_names, "--", &dealloc);
|
||||
value = get_value_to_print (row+i, field_names, "--", &dealloc, FALSE);
|
||||
len = nmc_string_screen_width (value, NULL);
|
||||
max_width = len > max_width ? len : max_width;
|
||||
if (dealloc)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2010 - 2014 Red Hat, Inc.
|
||||
* Copyright 2010 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NMC_UTILS_H
|
||||
|
|
@ -67,7 +67,10 @@ char *nmc_ip6_address_as_string (const struct in6_addr *ip, GError **error);
|
|||
void nmc_terminal_erase_line (void);
|
||||
void nmc_terminal_show_progress (const char *str);
|
||||
const char *nmc_term_color_sequence (NmcTermColor color);
|
||||
char *nmc_colorize (NmcTermColor color, const char * fmt, ...);
|
||||
const char *nmc_term_format_sequence (NmcTermFormat format);
|
||||
char *nmc_colorize (NmcTermColor color, NmcTermFormat format, const char * fmt, ...);
|
||||
void nmc_filter_out_colors_inplace (char *str);
|
||||
char *nmc_filter_out_colors (const char *str);
|
||||
char *nmc_get_user_input (const char *ask_str);
|
||||
int nmc_string_to_arg_array (const char *line, const char *delim, char ***argv, int *argc);
|
||||
const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error);
|
||||
|
|
@ -79,6 +82,8 @@ void set_val_str (NmcOutputField fields_array[], guint32 index, char *value);
|
|||
void set_val_strc (NmcOutputField fields_array[], guint32 index, const char *value);
|
||||
void set_val_arr (NmcOutputField fields_array[], guint32 index, char **value);
|
||||
void set_val_arrc (NmcOutputField fields_array[], guint32 index, const char **value);
|
||||
void set_val_color_all (NmcOutputField fields_array[], NmcTermColor color);
|
||||
void set_val_color_fmt_all (NmcOutputField fields_array[], NmcTermFormat format);
|
||||
void nmc_free_output_field_values (NmcOutputField fields_array[]);
|
||||
GArray *parse_output_fields (const char *fields_str,
|
||||
const NmcOutputField fields_array[],
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
.\" with this manual; if not, write to the Free Software Foundation, Inc.,
|
||||
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
.\"
|
||||
.\" Copyright 2010 - 2014 Red Hat, Inc.
|
||||
.\" Copyright 2010 - 2015 Red Hat, Inc.
|
||||
.\"
|
||||
.TH NMCLI "1" "3 December 2014"
|
||||
.TH NMCLI "1" "19 February 2015"
|
||||
|
||||
.SH NAME
|
||||
nmcli \- command\(hyline tool for controlling NetworkManager
|
||||
|
|
@ -45,6 +45,8 @@ nmcli \- command\(hyline tool for controlling NetworkManager
|
|||
.br
|
||||
\fB\-m\fR[\fImode\fR] tabular | multiline
|
||||
.br
|
||||
\fB\-c\fR[\fIcolors\fR] auto | yes | no
|
||||
.br
|
||||
\fB\-f\fR[\fIields\fR] <field1,field2,...> | all | common
|
||||
.br
|
||||
\fB\-e\fR[\fIscape\fR] yes | no
|
||||
|
|
@ -106,6 +108,11 @@ Columns define particular properties of the entry.
|
|||
\fImultiline\fP \(en Each entry comprises multiple lines, each property on its own
|
||||
line. The values are prefixed with the property name.
|
||||
.TP
|
||||
.B \-c, \-\-colors auto|yes|no
|
||||
This option controls color output (using terminal escape sequences). \fIyes\fP
|
||||
enables colors, \fIno\fP disables them, \fIauto\fP only produces colors when
|
||||
standard output is directed to a terminal. The default value is \fIauto\fP.
|
||||
.TP
|
||||
.B \-f, \-\-fields <field1,field2,...> | all | common
|
||||
This option is used to specify what fields (column names) should be printed.
|
||||
Valid field names differ for specific commands. List available fields by
|
||||
|
|
@ -289,12 +296,31 @@ active if a device is using that connection profile. Without a parameter, all
|
|||
profiles are listed. When --active option is specified, only the active profiles
|
||||
are shown.
|
||||
.TP
|
||||
.B show [--active] [--show-secrets] [ id | uuid | path | apath ] <ID> ...
|
||||
.B show [--active] [--order <order spec>] [--show-secrets] [ id | uuid | path | apath ] <ID> ...
|
||||
.br
|
||||
Show details for specified connections. By default, both static configuration
|
||||
and active connection data are displayed. When --active option is specified,
|
||||
only the active profiles are taken into account. When --show-secrets option is
|
||||
specified, secrets associated with the profile will be revealed too.
|
||||
.sp
|
||||
Ordering:
|
||||
.br
|
||||
The --order option can be used to get custom ordering of connections. The
|
||||
connections can be ordered by active status, name, type or D-Bus path. If
|
||||
connections are equal according to a sort order category, an additional
|
||||
category can be specified.
|
||||
The default sorting order is equivalent to "--order active:name:path".
|
||||
.sp
|
||||
<order spec> := category:category:...
|
||||
.br
|
||||
categogy := [+-]active | [+-]name | [+-]type | [+-]path
|
||||
.br
|
||||
\fI+\fP or no prefix means sorting in ascending order (alphabetically or in numbers).
|
||||
.br
|
||||
\fI-\fP means reverse (descending) order.
|
||||
.br
|
||||
The category names can be abbreviated (e.g. --order -a:na)
|
||||
.sp
|
||||
\fIid\fP, \fIuuid\fP, \fIpath\fP and \fIapath\fP keywords can be used if
|
||||
\fI<ID>\fP is ambiguous.
|
||||
.RS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue