From 94bb83a370648dd5e3cd815e0d48125d7a491e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 10 Dec 2013 12:00:53 +0100 Subject: [PATCH] cli: allow specifying 'group.name' syntax for '--fields' and use it for 'nmcli device show'. This allows filtering output not only for whole groups, but also for individual fields in commands that print data in groups (sections). Example: $ nmcli -f general.device,general.driver,ipv4,ipv6.address device show eth0 GENERAL.DEVICE: eth0 GENERAL.DRIVER: e1000e IP4.ADDRESS[1]: ip = 10.0.5.228/23, gw = 10.0.5.254 IP4.ADDRESS[2]: ip = 5.5.5.5/32, gw = 5.5.5.1 IP4.DNS[1]: 192.168.122.1 IP4.DNS[2]: 8.8.8.8 IP4.DOMAIN[1]: mycompany.com --- cli/src/common.c | 40 +++++++---- cli/src/common.h | 8 +-- cli/src/connections.c | 47 +++++-------- cli/src/devices.c | 136 ++++++++++++++++++++------------------ cli/src/network-manager.c | 23 ++----- cli/src/nmcli.h | 17 ++--- cli/src/settings.c | 50 +++++++------- cli/src/utils.c | 113 +++++++++++++++++++++++++++---- cli/src/utils.h | 6 +- 9 files changed, 262 insertions(+), 178 deletions(-) diff --git a/cli/src/common.c b/cli/src/common.c index 33c42b5f4a..8fadbc1d1f 100644 --- a/cli/src/common.c +++ b/cli/src/common.c @@ -30,7 +30,7 @@ #include "utils.h" /* Available fields for IPv4 group */ -static NmcOutputField nmc_fields_ip4_config[] = { +NmcOutputField nmc_fields_ip4_config[] = { {"GROUP", N_("GROUP"), 15}, /* 0 */ {"ADDRESS", N_("ADDRESS"), 68}, /* 1 */ {"ROUTE", N_("ROUTE"), 68}, /* 2 */ @@ -42,7 +42,7 @@ static NmcOutputField nmc_fields_ip4_config[] = { #define NMC_FIELDS_IP4_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN,WINS" /* Available fields for DHCPv4 group */ -static NmcOutputField nmc_fields_dhcp4_config[] = { +NmcOutputField nmc_fields_dhcp4_config[] = { {"GROUP", N_("GROUP"), 15}, /* 0 */ {"OPTION", N_("OPTION"), 80}, /* 1 */ {NULL, NULL, 0} @@ -50,7 +50,7 @@ static NmcOutputField nmc_fields_dhcp4_config[] = { #define NMC_FIELDS_DHCP4_CONFIG_ALL "GROUP,OPTION" /* Available fields for IPv6 group */ -static NmcOutputField nmc_fields_ip6_config[] = { +NmcOutputField nmc_fields_ip6_config[] = { {"GROUP", N_("GROUP"), 15}, /* 0 */ {"ADDRESS", N_("ADDRESS"), 95}, /* 1 */ {"ROUTE", N_("ROUTE"), 95}, /* 2 */ @@ -61,7 +61,7 @@ static NmcOutputField nmc_fields_ip6_config[] = { #define NMC_FIELDS_IP6_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN" /* Available fields for DHCPv6 group */ -static NmcOutputField nmc_fields_dhcp6_config[] = { +NmcOutputField nmc_fields_dhcp6_config[] = { {"GROUP", N_("GROUP"), 15}, /* 0 */ {"OPTION", N_("OPTION"), 80}, /* 1 */ {NULL, NULL, 0} @@ -70,7 +70,10 @@ static NmcOutputField nmc_fields_dhcp6_config[] = { gboolean -print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix) +print_ip4_config (NMIP4Config *cfg4, + NmCli *nmc, + const char *group_prefix, + const char *one_field) { GSList *list, *iter; const GArray *array; @@ -89,7 +92,8 @@ print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix) tmpl = nmc_fields_ip4_config; tmpl_len = sizeof (nmc_fields_ip4_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_IP4_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP4_CONFIG_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -179,7 +183,10 @@ print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix) } gboolean -print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix) +print_ip6_config (NMIP6Config *cfg6, + NmCli *nmc, + const char *group_prefix, + const char *one_field) { GSList *list, *iter; const GPtrArray *ptr_array; @@ -196,7 +203,8 @@ print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix) tmpl = nmc_fields_ip6_config; tmpl_len = sizeof (nmc_fields_ip6_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_IP6_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP6_CONFIG_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -274,7 +282,10 @@ print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix) } gboolean -print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix) +print_dhcp4_config (NMDHCP4Config *dhcp4, + NmCli *nmc, + const char *group_prefix, + const char *one_field) { GHashTable *table; NmcOutputField *tmpl, *arr; @@ -292,7 +303,8 @@ print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix) tmpl = nmc_fields_dhcp4_config; tmpl_len = sizeof (nmc_fields_dhcp4_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DHCP4_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP4_CONFIG_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -318,7 +330,10 @@ print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix) } gboolean -print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix) +print_dhcp6_config (NMDHCP6Config *dhcp6, + NmCli *nmc, + const char *group_prefix, + const char *one_field) { GHashTable *table; NmcOutputField *tmpl, *arr; @@ -336,7 +351,8 @@ print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix) tmpl = nmc_fields_dhcp6_config; tmpl_len = sizeof (nmc_fields_dhcp6_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DHCP6_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP6_CONFIG_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); diff --git a/cli/src/common.h b/cli/src/common.h index 6683502805..bb5ea5a964 100644 --- a/cli/src/common.h +++ b/cli/src/common.h @@ -32,10 +32,10 @@ #include "nmcli.h" -gboolean print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix); -gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix); -gboolean print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix); -gboolean print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix); +gboolean print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix, const char *one_field); +gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix, const char *one_field); +gboolean print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix, const char *one_field); +gboolean print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix, const char *one_field); NMIP4Address *nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error); NMIP6Address *nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error); diff --git a/cli/src/connections.c b/cli/src/connections.c index 0141b36530..f837d009d4 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -351,13 +351,9 @@ nmc_connection_detail (NMConnection *connection, NmCli *nmc) else fields_str = nmc->required_fields; - print_settings_array = parse_output_fields (fields_str, nmc_fields_settings_names, &error); + print_settings_array = parse_output_fields (fields_str, nmc_fields_settings_names, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'list configured': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'list configured': %s; allowed fields: %s"), - error->message, NMC_FIELDS_SETTINGS_NAMES_ALL); + g_string_printf (nmc->return_text, _("Error: 'list configured': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; @@ -367,7 +363,7 @@ nmc_connection_detail (NMConnection *connection, NmCli *nmc) /* Main header */ nmc->print_fields.header_name = _("Connection details"); nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTINGS_NAMES_ALL, - nmc_fields_settings_names, NULL); + nmc_fields_settings_names, FALSE, NULL, NULL); nmc_fields_settings_names[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; print_required_fields (nmc, nmc_fields_settings_names); @@ -499,7 +495,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) tmpl = nmc_fields_con_show; tmpl_len = sizeof (nmc_fields_con_show); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error1); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error1); if (error1) goto error; if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2)) @@ -549,11 +545,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) error: if (error1) { - if (error1->code == 0) - g_string_printf (nmc->return_text, _("Error: 'show configured': %s"), error1->message); - else - g_string_printf (nmc->return_text, _("Error: 'show configured': %s; allowed fields: %s"), - error1->message, NMC_FIELDS_CON_SHOW_ALL); + g_string_printf (nmc->return_text, _("Error: 'show configured': %s"), error1->message); g_error_free (error1); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; } @@ -852,13 +844,9 @@ nmc_active_connection_detail (NMActiveConnection *acon, NmCli *nmc) else fields_str = nmc->required_fields; - print_groups = parse_output_fields (fields_str, nmc_fields_con_active_details_groups, &error); + print_groups = parse_output_fields (fields_str, nmc_fields_con_active_details_groups, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'list active': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'list active': %s; allowed fields: %s"), - error->message, NMC_FIELDS_CON_ACTIVE_DETAILS_ALL); + g_string_printf (nmc->return_text, _("Error: 'list active': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; @@ -868,7 +856,7 @@ nmc_active_connection_detail (NMActiveConnection *acon, NmCli *nmc) /* Main header */ nmc->print_fields.header_name = _("Active connection details"); nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_ALL, - nmc_fields_con_active_details_groups, NULL); + nmc_fields_con_active_details_groups, FALSE, NULL, NULL); nmc_fields_con_active_details_groups[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; print_required_fields (nmc, nmc_fields_con_active_details_groups); @@ -890,7 +878,7 @@ nmc_active_connection_detail (NMActiveConnection *acon, NmCli *nmc) /* Add field names */ tmpl = nmc_fields_con_show_active; tmpl_len = sizeof (nmc_fields_con_show_active); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -916,10 +904,10 @@ nmc_active_connection_detail (NMActiveConnection *acon, NmCli *nmc) NMDHCP4Config *dhcp4 = nm_device_get_dhcp4_config (device); NMDHCP6Config *dhcp6 = nm_device_get_dhcp6_config (device); - b1 = print_ip4_config (cfg4, nmc, "IP4"); - b2 = print_dhcp4_config (dhcp4, nmc, "DHCP4"); - b3 = print_ip6_config (cfg6, nmc, "IP6"); - b4 = print_dhcp6_config (dhcp6, nmc, "DHCP6"); + b1 = print_ip4_config (cfg4, nmc, "IP4", NULL); + b2 = print_dhcp4_config (dhcp4, nmc, "DHCP4", NULL); + b3 = print_ip6_config (cfg6, nmc, "IP6", NULL); + b4 = print_dhcp6_config (dhcp6, nmc, "DHCP6", NULL); was_output = was_output || b1 || b2 || b3 || b4; } } @@ -943,7 +931,7 @@ nmc_active_connection_detail (NMActiveConnection *acon, NmCli *nmc) tmpl = nmc_fields_con_active_details_vpn; tmpl_len = sizeof (nmc_fields_con_active_details_vpn); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -1025,7 +1013,7 @@ do_connections_show_active (NmCli *nmc, int argc, char **argv) tmpl = nmc_fields_con_show_active + 1; tmpl_len = sizeof (nmc_fields_con_show_active) - sizeof (NmcOutputField); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &err1); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &err1); if (err1) goto error; @@ -1078,10 +1066,7 @@ do_connections_show_active (NmCli *nmc, int argc, char **argv) error: if (err1) { - if (err1->code == 0) - g_string_printf (nmc->return_text, _("Error: 'show active': %s"), err1->message); - else - g_string_printf (nmc->return_text, _("Error: 'show active': %s; allowed fields: %s"), err1->message, NMC_FIELDS_CON_ACTIVE_ALL); + g_string_printf (nmc->return_text, _("Error: 'show active': %s"), err1->message); g_error_free (err1); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; } diff --git a/cli/src/devices.c b/cli/src/devices.c index 39802b63c9..037d8809c3 100644 --- a/cli/src/devices.c +++ b/cli/src/devices.c @@ -81,32 +81,6 @@ static NmcOutputField nmc_fields_dev_status[] = { #define NMC_FIELDS_DEV_STATUS_COMMON "DEVICE,TYPE,STATE,CONNECTION" -/* Available sections for 'device show' */ -static NmcOutputField nmc_fields_dev_show_sections[] = { - {"GENERAL", N_("GENERAL"), 0}, /* 0 */ - {"CAPABILITIES", N_("CAPABILITIES"), 0}, /* 1 */ - {"WIFI-PROPERTIES", N_("WIFI-PROPERTIES"), 0}, /* 2 */ - {"AP", N_("AP"), 0}, /* 3 */ - {"WIRED-PROPERTIES", N_("WIRED-PROPERTIES"), 0}, /* 4 */ - {"WIMAX-PROPERTIES", N_("WIMAX-PROPERTIES"), 0}, /* 5 */ - {"NSP", N_("NSP"), 0}, /* 6 */ - {"IP4", N_("IP4"), 0}, /* 7 */ - {"DHCP4", N_("DHCP4"), 0}, /* 8 */ - {"IP6", N_("IP6"), 0}, /* 9 */ - {"DHCP6", N_("DHCP6"), 0}, /* 10 */ - {"BOND", N_("BOND"), 0}, /* 11 */ - {"VLAN", N_("VLAN"), 0}, /* 12 */ - {"CONNECTIONS", N_("CONNECTIONS"), 0}, /* 13 */ - {NULL, NULL, 0} -}; -#if WITH_WIMAX -#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6" -#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6" -#else -#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6" -#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6" -#endif - /* Available fields for 'device show' - GENERAL part */ static NmcOutputField nmc_fields_dev_show_general[] = { {"NAME", N_("NAME"), 10}, /* 0 */ @@ -161,7 +135,6 @@ static NmcOutputField nmc_fields_dev_show_wired_prop[] = { #define NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL "NAME,CARRIER" #define NMC_FIELDS_DEV_SHOW_WIRED_PROP_COMMON "NAME,CARRIER" - /* Available fields for 'device show' - wireless properties part */ static NmcOutputField nmc_fields_dev_show_wifi_prop[] = { {"NAME", N_("NAME"), 18}, /* 0 */ @@ -192,6 +165,7 @@ static NmcOutputField nmc_fields_dev_show_wimax_prop[] = { #define NMC_FIELDS_DEV_SHOW_WIMAX_PROP_COMMON "NAME,CTR-FREQ,RSSI,CINR,TX-POW,BSID" #endif + /* Available fields for 'device wifi list' */ static NmcOutputField nmc_fields_dev_wifi_list[] = { {"NAME", N_("NAME"), 15}, /* 0 */ @@ -253,6 +227,38 @@ static NmcOutputField nmc_fields_dev_show_vlan_prop[] = { #define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL "NAME,ID" #define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON "NAME,ID" +/* defined in common.c */ +extern NmcOutputField nmc_fields_ip4_config[]; +extern NmcOutputField nmc_fields_ip6_config[]; +extern NmcOutputField nmc_fields_dhcp4_config[]; +extern NmcOutputField nmc_fields_dhcp6_config[]; + +/* Available sections for 'device show' */ +static NmcOutputField nmc_fields_dev_show_sections[] = { + {"GENERAL", N_("GENERAL"), 0, nmc_fields_dev_show_general + 1 }, /* 0 */ + {"CAPABILITIES", N_("CAPABILITIES"), 0, nmc_fields_dev_show_cap + 1 }, /* 1 */ + {"WIFI-PROPERTIES", N_("WIFI-PROPERTIES"), 0, nmc_fields_dev_show_wifi_prop + 1 }, /* 2 */ + {"AP", N_("AP"), 0, nmc_fields_dev_wifi_list + 1 }, /* 3 */ + {"WIRED-PROPERTIES", N_("WIRED-PROPERTIES"), 0, nmc_fields_dev_show_wired_prop + 1 }, /* 4 */ + {"WIMAX-PROPERTIES", N_("WIMAX-PROPERTIES"), 0, nmc_fields_dev_show_wimax_prop + 1 }, /* 5 */ + {"NSP", N_("NSP"), 0, nmc_fields_dev_wimax_list + 1 }, /* 6 */ + {"IP4", N_("IP4"), 0, nmc_fields_ip4_config + 1 }, /* 7 */ + {"DHCP4", N_("DHCP4"), 0, nmc_fields_dhcp4_config + 1 }, /* 8 */ + {"IP6", N_("IP6"), 0, nmc_fields_ip6_config + 1 }, /* 9 */ + {"DHCP6", N_("DHCP6"), 0, nmc_fields_dhcp6_config + 1 }, /* 10 */ + {"BOND", N_("BOND"), 0, nmc_fields_dev_show_bond_prop + 1 }, /* 11 */ + {"VLAN", N_("VLAN"), 0, nmc_fields_dev_show_vlan_prop + 1 }, /* 12 */ + {"CONNECTIONS", N_("CONNECTIONS"), 0, nmc_fields_dev_show_connections + 1 }, /* 13 */ + {NULL, NULL, 0, NULL } +}; +#if WITH_WIMAX +#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6" +#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4,DHCP4,IP6,DHCP6" +#else +#define NMC_FIELDS_DEV_SHOW_SECTIONS_ALL "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6" +#define NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON "GENERAL,CAPABILITIES,BOND,VLAN,CONNECTIONS,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4,DHCP4,IP6,DHCP6" +#endif + /* glib main loop variable - defined in nmcli.c */ extern GMainLoop *loop; @@ -590,6 +596,7 @@ show_device_info (NMDevice *device, NmCli *nmc) NMDHCP4Config *dhcp4; NMDHCP6Config *dhcp6; const char *base_hdr = _("Device details"); + GPtrArray *fields_in_section = NULL; if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) fields_str = fields_common; @@ -598,13 +605,9 @@ show_device_info (NMDevice *device, NmCli *nmc) else fields_str = nmc->required_fields; - sections_array = parse_output_fields (fields_str, nmc_fields_dev_show_sections, &error); + sections_array = parse_output_fields (fields_str, nmc_fields_dev_show_sections, TRUE, &fields_in_section, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'device show': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'device show': %s; allowed fields: %s"), - error->message, NMC_FIELDS_DEV_SHOW_SECTIONS_ALL); + g_string_printf (nmc->return_text, _("Error: 'device show': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return; @@ -613,7 +616,7 @@ show_device_info (NMDevice *device, NmCli *nmc) /* Main header */ nmc->print_fields.header_name = (char *) construct_header_name (base_hdr, nm_device_get_iface (device)); nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_GENERAL_ALL, - nmc_fields_dev_show_general, NULL); + nmc_fields_dev_show_general, FALSE, NULL, NULL); nmc_fields_dev_show_general[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; print_required_fields (nmc, nmc_fields_dev_show_general); @@ -621,6 +624,7 @@ show_device_info (NMDevice *device, NmCli *nmc) /* Loop through the required sections and print them. */ for (k = 0; k < sections_array->len; k++) { int section_idx = g_array_index (sections_array, int, k); + char *section_fld = (char *) g_ptr_array_index (fields_in_section, k); if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output) printf ("\n"); /* Print empty line between groups in tabular mode */ @@ -636,7 +640,8 @@ show_device_info (NMDevice *device, NmCli *nmc) if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[0].name)) { tmpl = nmc_fields_dev_show_general; tmpl_len = sizeof (nmc_fields_dev_show_general); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_GENERAL_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_GENERAL_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -689,7 +694,8 @@ show_device_info (NMDevice *device, NmCli *nmc) if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[1].name)) { tmpl = nmc_fields_dev_show_cap; tmpl_len = sizeof (nmc_fields_dev_show_cap); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_CAP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_CAP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -728,7 +734,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_show_wifi_prop; tmpl_len = sizeof (nmc_fields_dev_show_wifi_prop); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -757,7 +764,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_wifi_list; tmpl_len = sizeof (nmc_fields_dev_wifi_list); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -779,7 +787,8 @@ show_device_info (NMDevice *device, NmCli *nmc) if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[4].name)) { tmpl = nmc_fields_dev_show_wired_prop; tmpl_len = sizeof (nmc_fields_dev_show_wired_prop); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -804,7 +813,8 @@ show_device_info (NMDevice *device, NmCli *nmc) /* Field names */ tmpl = nmc_fields_dev_show_wimax_prop; tmpl_len = sizeof (nmc_fields_dev_show_wimax_prop); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_WIMAX_PROP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_WIMAX_PROP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -848,7 +858,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_wimax_list; tmpl_len = sizeof (nmc_fields_dev_wimax_list); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -872,19 +883,19 @@ show_device_info (NMDevice *device, NmCli *nmc) /* IP4 */ if (cfg4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[7].name)) - was_output = print_ip4_config (cfg4, nmc, nmc_fields_dev_show_sections[7].name); + was_output = print_ip4_config (cfg4, nmc, nmc_fields_dev_show_sections[7].name, section_fld); /* DHCP4 */ if (dhcp4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[8].name)) - was_output = print_dhcp4_config (dhcp4, nmc, nmc_fields_dev_show_sections[8].name); + was_output = print_dhcp4_config (dhcp4, nmc, nmc_fields_dev_show_sections[8].name, section_fld); /* IP6 */ if (cfg6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[9].name)) - was_output = print_ip6_config (cfg6, nmc, nmc_fields_dev_show_sections[9].name); + was_output = print_ip6_config (cfg6, nmc, nmc_fields_dev_show_sections[9].name, section_fld); /* DHCP6 */ if (dhcp6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[10].name)) - was_output = print_dhcp6_config (dhcp6, nmc, nmc_fields_dev_show_sections[10].name); + was_output = print_dhcp6_config (dhcp6, nmc, nmc_fields_dev_show_sections[10].name, section_fld); /* Bond-specific information */ if ((NM_IS_DEVICE_BOND (device))) { @@ -909,7 +920,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_show_bond_prop; tmpl_len = sizeof (nmc_fields_dev_show_bond_prop); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_BOND_PROP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_BOND_PROP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -932,7 +944,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_show_vlan_prop; tmpl_len = sizeof (nmc_fields_dev_show_vlan_prop); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -956,7 +969,8 @@ show_device_info (NMDevice *device, NmCli *nmc) tmpl = nmc_fields_dev_show_connections; tmpl_len = sizeof (nmc_fields_dev_show_connections); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_SHOW_CONNECTIONS_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (section_fld ? section_fld : NMC_FIELDS_DEV_SHOW_CONNECTIONS_ALL, + tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -999,6 +1013,8 @@ show_device_info (NMDevice *device, NmCli *nmc) if (sections_array) g_array_free (sections_array, TRUE); + if (fields_in_section) + g_ptr_array_free (fields_in_section, TRUE); } static const char * @@ -1073,14 +1089,10 @@ do_devices_status (NmCli *nmc, int argc, char **argv) tmpl = nmc_fields_dev_status; tmpl_len = sizeof (nmc_fields_dev_status); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'device status': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'device status': %s; allowed fields: %s"), - error->message, NMC_FIELDS_DEV_STATUS_ALL); + g_string_printf (nmc->return_text, _("Error: 'device status': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto error; @@ -1552,14 +1564,10 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) tmpl = nmc_fields_dev_wifi_list; tmpl_len = sizeof (nmc_fields_dev_wifi_list); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'device wifi': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'device wifi': %s; allowed fields: %s"), - error->message, NMC_FIELDS_DEV_WIFI_LIST_ALL); + g_string_printf (nmc->return_text, _("Error: 'device wifi': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto error; @@ -2295,14 +2303,10 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv) tmpl = nmc_fields_dev_wimax_list; tmpl_len = sizeof (nmc_fields_dev_wimax_list); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'device wimax': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'device wimax': %s; allowed fields: %s"), - error->message, NMC_FIELDS_DEV_WIMAX_LIST_ALL); + g_string_printf (nmc->return_text, _("Error: 'device wimax': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto error; diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c index 8d59566f58..20df4dde2d 100644 --- a/cli/src/network-manager.c +++ b/cli/src/network-manager.c @@ -205,13 +205,10 @@ show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_fl tmpl = nmc_fields_nm_status; tmpl_len = sizeof (nmc_fields_nm_status); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: %s (allowed fields: %s)"), error->message, fields_all); + g_string_printf (nmc->return_text, _("Error: only these fields are allowed: %s"), fields_all); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; @@ -351,14 +348,10 @@ show_nm_permissions (NmCli *nmc) tmpl = nmc_fields_nm_permissions; tmpl_len = sizeof (nmc_fields_nm_permissions); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'general permissions': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'general permissions': %s; allowed fields: %s"), - error->message, NMC_FIELDS_NM_PERMISSIONS_ALL); + g_string_printf (nmc->return_text, _("Error: 'general permissions': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; @@ -410,14 +403,10 @@ show_general_logging (NmCli *nmc) tmpl = nmc_fields_nm_logging; tmpl_len = sizeof (nmc_fields_nm_logging); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, &error); + nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); if (error) { - if (error->code == 0) - g_string_printf (nmc->return_text, _("Error: 'general logging': %s"), error->message); - else - g_string_printf (nmc->return_text, _("Error: 'general logging': %s; allowed fields: %s"), - error->message, NMC_FIELDS_NM_LOGGING_ALL); + g_string_printf (nmc->return_text, _("Error: 'general logging': %s"), error->message); g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; diff --git a/cli/src/nmcli.h b/cli/src/nmcli.h index c80c4fd4f7..b300c6d390 100644 --- a/cli/src/nmcli.h +++ b/cli/src/nmcli.h @@ -74,14 +74,15 @@ typedef enum { #define NMC_OF_FLAG_MAIN_HEADER_ADD 0x00000004 /* Print main header in addition to values/field names */ #define NMC_OF_FLAG_MAIN_HEADER_ONLY 0x00000008 /* Print main header only */ -typedef struct { - const char *name; /* Field's name */ - const char *name_l10n; /* Field's name for translation */ - int width; /* Width in screen columns */ - void *value; /* Value of current field - char* or char** (NULL-terminated array) */ - 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 */ +typedef struct _NmcOutputField { + const char *name; /* Field's name */ + const char *name_l10n; /* Field's name for translation */ + int width; /* Width in screen columns */ + struct _NmcOutputField *group; /* Points to an array with available section field names if this is a section (group) field */ + void *value; /* Value of current field - char* or char** (NULL-terminated array) */ + 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 */ } NmcOutputField; typedef struct { diff --git a/cli/src/settings.c b/cli/src/settings.c index cf56cfbe98..baee67250d 100644 --- a/cli/src/settings.c +++ b/cli/src/settings.c @@ -5840,7 +5840,7 @@ setting_connection_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_connection; tmpl_len = sizeof (nmc_fields_setting_connection); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CONNECTION_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CONNECTION_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -5877,7 +5877,7 @@ setting_wired_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_wired; tmpl_len = sizeof (nmc_fields_setting_wired); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRED_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRED_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -5912,7 +5912,7 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_8021X; tmpl_len = sizeof (nmc_fields_setting_8021X); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_802_1X_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_802_1X_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -5968,7 +5968,7 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_wireless; tmpl_len = sizeof (nmc_fields_setting_wireless); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6005,7 +6005,7 @@ setting_wireless_security_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_wireless_security; tmpl_len = sizeof (nmc_fields_setting_wireless_security); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_SECURITY_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIRELESS_SECURITY_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6046,7 +6046,7 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_ip4_config; tmpl_len = sizeof (nmc_fields_setting_ip4_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP4_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP4_CONFIG_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6082,7 +6082,7 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_ip6_config; tmpl_len = sizeof (nmc_fields_setting_ip6_config); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP6_CONFIG_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_IP6_CONFIG_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6117,7 +6117,7 @@ setting_serial_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_serial; tmpl_len = sizeof (nmc_fields_setting_serial); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_SERIAL_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_SERIAL_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6146,7 +6146,7 @@ setting_ppp_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_ppp; tmpl_len = sizeof (nmc_fields_setting_ppp); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPP_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPP_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6188,7 +6188,7 @@ setting_pppoe_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_pppoe; tmpl_len = sizeof (nmc_fields_setting_pppoe); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPPOE_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_PPPOE_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6216,7 +6216,7 @@ setting_gsm_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_gsm; tmpl_len = sizeof (nmc_fields_setting_gsm); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_GSM_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_GSM_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6251,7 +6251,7 @@ setting_cdma_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_cdma; tmpl_len = sizeof (nmc_fields_setting_cdma); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CDMA_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_CDMA_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6279,7 +6279,7 @@ setting_bluetooth_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_bluetooth; tmpl_len = sizeof (nmc_fields_setting_bluetooth); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BLUETOOTH_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BLUETOOTH_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6305,7 +6305,7 @@ setting_olpc_mesh_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_olpc_mesh; tmpl_len = sizeof (nmc_fields_setting_olpc_mesh); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_OLPC_MESH_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_OLPC_MESH_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6332,7 +6332,7 @@ setting_vpn_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_vpn; tmpl_len = sizeof (nmc_fields_setting_vpn); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_VPN_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_VPN_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6360,7 +6360,7 @@ setting_wimax_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_wimax; tmpl_len = sizeof (nmc_fields_setting_wimax); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIMAX_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIMAX_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6386,7 +6386,7 @@ setting_infiniband_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_infiniband; tmpl_len = sizeof (nmc_fields_setting_infiniband); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_INFINIBAND_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_INFINIBAND_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6415,7 +6415,7 @@ setting_bond_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_bond; tmpl_len = sizeof (nmc_fields_setting_bond); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BOND_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BOND_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6441,7 +6441,7 @@ setting_vlan_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_vlan; tmpl_len = sizeof (nmc_fields_setting_vlan); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_VLAN_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_VLAN_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6471,7 +6471,7 @@ setting_adsl_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_adsl; tmpl_len = sizeof (nmc_fields_setting_adsl); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_ADSL_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_ADSL_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6502,7 +6502,7 @@ setting_bridge_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_bridge; tmpl_len = sizeof (nmc_fields_setting_bridge); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BRIDGE_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BRIDGE_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6533,7 +6533,7 @@ setting_bridge_port_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_bridge_port; tmpl_len = sizeof (nmc_fields_setting_bridge_port); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BRIDGE_PORT_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_BRIDGE_PORT_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6560,7 +6560,7 @@ setting_team_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_team; tmpl_len = sizeof (nmc_fields_setting_team); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_TEAM_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_TEAM_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6586,7 +6586,7 @@ setting_team_port_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_team_port; tmpl_len = sizeof (nmc_fields_setting_team_port); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_TEAM_PORT_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_TEAM_PORT_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); @@ -6611,7 +6611,7 @@ setting_dcb_details (NMSetting *setting, NmCli *nmc) tmpl = nmc_fields_setting_dcb; tmpl_len = sizeof (nmc_fields_setting_dcb); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_DCB_ALL, tmpl, NULL); + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_DCB_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); diff --git a/cli/src/utils.c b/cli/src/utils.c index de246d66a5..4ea62530b9 100644 --- a/cli/src/utils.c +++ b/cli/src/utils.c @@ -608,41 +608,126 @@ nmc_free_output_field_values (NmcOutputField fields_array[]) } } -/* - * Parse comma separated fields in 'fields_str' according to 'fields_array'. - * IN: 'field_str': comma-separated fields names - * 'fields_array': array of allowed fields - * RETURN: GArray with indices representing fields in 'fields_array'. - * Caller is responsible to free it. +/** + * parse_output_fields: + * @field_str: comma-separated field names to parse + * @fields_array: array of allowed fields + * @parse_groups: whether the fields can contain group prefix (e.g. general.driver) + * @group_fields: (out) (allow-none): array of field names for particular groups + * @error: (out) (allow-none): location to store error, or %NULL + * + * Parses comma separated fields in @fields_str according to @fields_array. + * When @parse_groups is %TRUE, fields can be in the form 'group.field'. Then + * @group_fields will be filled with the required field for particular group. + * @group_fields array corresponds to the returned array. + * Examples: + * @field_str: "type,name,uuid" | "ip4,general.device" | "ip4.address,ip6" + * returned array: 2 0 1 | 7 0 | 7 9 + * @group_fields: NULL NULL NULL | NULL "device" | "address" NULL + * + * Returns: #GArray with indices representing fields in @fields_array. + * Caller is responsible for freeing the array. */ GArray * -parse_output_fields (const char *fields_str, const NmcOutputField fields_array[], GError **error) +parse_output_fields (const char *fields_str, + const NmcOutputField fields_array[], + gboolean parse_groups, + GPtrArray **group_fields, + GError **error) { char **fields, **iter; GArray *array; - int i; + int i, j; g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (group_fields == NULL || *group_fields == NULL, NULL); array = g_array_new (FALSE, FALSE, sizeof (int)); + if (parse_groups && group_fields) + *group_fields = g_ptr_array_new_full (20, (GDestroyNotify) g_free); /* Split supplied fields string */ fields = g_strsplit_set (fields_str, ",", -1); for (iter = fields; iter && *iter; iter++) { - for (i = 0; fields_array[i].name; i++) { - if (strcasecmp (*iter, fields_array[i].name) == 0) { - g_array_append_val (array, i); - break; + int idx = -1; + + g_strstrip (*iter); + if (parse_groups) { + /* e.g. "general.device,general.driver,ip4,ip6" */ + gboolean found = FALSE; + char *left = *iter; + char *right = strchr (*iter, '.'); + + if (right) + *right++ = '\0'; + + for (i = 0; fields_array[i].name; i++) { + if (strcasecmp (left, fields_array[i].name) == 0) { + NmcOutputField *valid_names = fields_array[i].group; + idx = i; + if (!right && !valid_names) { + found = TRUE; + break; + } + for (j = 0; valid_names && valid_names[j].name; j++) { + if (!right || strcasecmp (right, valid_names[j].name) == 0) { + found = TRUE; + break; + } + } + } + if (found) + break; + } + if (found) { + /* Add index to array, and field name (or NULL) to group_fields array */ + g_array_append_val (array, idx); + if (*group_fields) + g_ptr_array_add (*group_fields, g_strdup (right)); + } + if (right) + *(right-1) = '.'; /* Restore the original string */ + } else { + /* e.g. "general,ip4,ip6" */ + for (i = 0; fields_array[i].name; i++) { + if (strcasecmp (*iter, fields_array[i].name) == 0) { + g_array_append_val (array, i); + break; + } } } + + /* Field was not found - error case */ if (fields_array[i].name == NULL) { + GString *allowed_fields = g_string_sized_new (256); + int k; + + /* Set GError */ + if (idx != -1 && fields_array[idx].group) { + NmcOutputField *second_level = fields_array[idx].group; + for (k = 0; second_level[k].name; k++) + g_string_append_printf (allowed_fields, "%s.%s,", + fields_array[idx].name, second_level[k].name); + } else { + for (k = 0; fields_array[k].name; k++) + g_string_append_printf (allowed_fields, "%s,", fields_array[k].name); + } + g_string_truncate (allowed_fields, allowed_fields->len - 1); + if (!strcasecmp (*iter, "all") || !strcasecmp (*iter, "common")) g_set_error (error, NMCLI_ERROR, 0, _("field '%s' has to be alone"), *iter); - else - g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s'"), *iter); + g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s'; allowed fields: %s"), + *iter, allowed_fields->str); + g_string_free (allowed_fields, TRUE); + + /* Free arrays on error */ g_array_free (array, TRUE); array = NULL; + if (group_fields && *group_fields) { + g_ptr_array_free (*group_fields, TRUE); + *group_fields = NULL; + } goto done; } } diff --git a/cli/src/utils.h b/cli/src/utils.h index c1c8824144..2d3292bd36 100644 --- a/cli/src/utils.h +++ b/cli/src/utils.h @@ -80,7 +80,11 @@ void set_val_strc (NmcOutputField fields_array[], guint32 index, const char *val void set_val_arr (NmcOutputField fields_array[], guint32 index, char **value); void set_val_arrc (NmcOutputField fields_array[], guint32 index, const char **value); void nmc_free_output_field_values (NmcOutputField fields_array[]); -GArray *parse_output_fields (const char *fields_str, const NmcOutputField fields_array[], GError **error); +GArray *parse_output_fields (const char *fields_str, + const NmcOutputField fields_array[], + gboolean parse_groups, + GPtrArray **group_fields, + GError **error); gboolean nmc_terse_option_check (NMCPrintOutput print_output, const char *fields, GError **error); NmcOutputField *nmc_dup_fields_array (NmcOutputField fields[], size_t size, guint32 flags); void nmc_empty_output_fields (NmCli *nmc);