From 31d0d0ef8330294d6c11fd534b0ac0be6061f5d3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 09:47:05 +0200 Subject: [PATCH 01/32] shared: add NM_PTRARRAY_LEN() utility macro I used to use g_strv_length ((char **) p) instead, but that feels ugly because it g_strv_length() is not designed to operate on arbitrary pointer arrays. --- libnm-core/tests/test-general.c | 76 ++++++++++++++++++++++++++++ shared/nm-utils/nm-macros-internal.h | 17 +++++++ 2 files changed, 93 insertions(+) diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 0f65e8f6ae..0d6cb5322d 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -4655,6 +4655,81 @@ test_nm_utils_strstrdictkey (void) /*****************************************************************************/ +static guint +_g_strv_length (gconstpointer arr) +{ + return arr ? g_strv_length ((char **) arr) : 0; +} + +static void +test_nm_ptrarray_len (void) +{ +#define _PTRARRAY_cmp(len, arr) \ + G_STMT_START { \ + g_assert_cmpint (len, ==, NM_PTRARRAY_LEN (arr)); \ + g_assert_cmpint (len, ==, _g_strv_length (arr)); \ + } G_STMT_END +#define _PTRARRAY_LEN0(T) \ + G_STMT_START { \ + T **vnull = NULL; \ + T *const*vnull1 = NULL; \ + T *const*const vnull2 = NULL; \ + T *v0[] = { NULL }; \ + T *const*v01 = v0; \ + T *const*const v02 = v0; \ + T **const v03 = v0; \ + \ + _PTRARRAY_cmp (0, vnull); \ + _PTRARRAY_cmp (0, vnull1); \ + _PTRARRAY_cmp (0, vnull2); \ + _PTRARRAY_cmp (0, v0); \ + _PTRARRAY_cmp (0, v01); \ + _PTRARRAY_cmp (0, v02); \ + _PTRARRAY_cmp (0, v03); \ + } G_STMT_END + + _PTRARRAY_LEN0 (char); + _PTRARRAY_LEN0 (const char); + _PTRARRAY_LEN0 (int); + _PTRARRAY_LEN0 (const int); + _PTRARRAY_LEN0 (void *); + _PTRARRAY_LEN0 (void); + _PTRARRAY_LEN0 (const void); + +#define _PTRARRAY_LENn(T) \ + G_STMT_START { \ + T x[5] = { 0 }; \ + \ + T *v1[] = { &x[0], NULL }; \ + T *const*v11 = v1; \ + T *const*const v12 = v1; \ + T **const v13 = v1; \ + \ + T *v2[] = { &x[0], &x[1], NULL }; \ + T *const*v21 = v2; \ + T *const*const v22 = v2; \ + T **const v23 = v2; \ + \ + _PTRARRAY_cmp (1, v1); \ + _PTRARRAY_cmp (1, v11); \ + _PTRARRAY_cmp (1, v12); \ + _PTRARRAY_cmp (1, v13); \ + \ + _PTRARRAY_cmp (2, v2); \ + _PTRARRAY_cmp (2, v21); \ + _PTRARRAY_cmp (2, v22); \ + _PTRARRAY_cmp (2, v23); \ + } G_STMT_END + + _PTRARRAY_LENn (char); + _PTRARRAY_LENn (const char); + _PTRARRAY_LENn (int); + _PTRARRAY_LENn (const int); + _PTRARRAY_LENn (void *); +} + +/*****************************************************************************/ + static void test_nm_utils_dns_option_validate_do (char *option, gboolean ipv6, const NMUtilsDNSOptionDesc *descs, gboolean exp_result, char *exp_name, gboolean exp_value) @@ -5716,6 +5791,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/_glib_compat_g_hash_table_get_keys_as_array", test_g_hash_table_get_keys_as_array); g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search); g_test_add_func ("/core/general/_nm_utils_strstrdictkey", test_nm_utils_strstrdictkey); + g_test_add_func ("/core/general/nm_ptrarray_len", test_nm_ptrarray_len); g_test_add_func ("/core/general/_nm_utils_dns_option_validate", test_nm_utils_dns_option_validate); g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx); diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index f362968f58..eaf8b9e54d 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -209,6 +209,23 @@ NM_G_ERROR_MSG (GError *error) /* macro to return strlen() of a compile time string. */ #define NM_STRLEN(str) ( sizeof ("" str) - 1 ) +/* returns the length of a NULL terminated array of pointers, + * like g_strv_length() does. The difference is: + * - it operats on arrays of pointers (of any kind, requiring no cast). + * - it accepts NULL to return zero. */ +#define NM_PTRARRAY_LEN(array) \ + ({ \ + typeof (*(array)) *const _array = (array); \ + gsize _n = 0; \ + \ + if (_array) { \ + _nm_unused typeof (*(_array[0])) *_array_check = _array[0]; \ + while (_array[_n]) \ + _n++; \ + } \ + _n; \ + }) + /* Note: @value is only evaluated when *out_val is present. * Thus, * NM_SET_OUT (out_str, g_strdup ("hallo")); From 7861ce75606a5119ba3b7ca96e1a4fd95f5aa128 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 11 Apr 2017 15:17:18 +0200 Subject: [PATCH 02/32] shared: add NM_PTRARRAY_EMPTY() util --- shared/nm-utils/nm-shared-utils.c | 4 ++++ shared/nm-utils/nm-shared-utils.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 1a83cb9da3..8bd81dafda 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -27,6 +27,10 @@ /*****************************************************************************/ +const void *const _NM_PTRARRAY_EMPTY[1] = { NULL }; + +/*****************************************************************************/ + void nm_utils_strbuf_append_c (char **buf, gsize *len, char c) { diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 4d8f300c85..3776c1590e 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -24,6 +24,10 @@ /*****************************************************************************/ +extern const void *const _NM_PTRARRAY_EMPTY[1]; + +#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY) + static inline void _nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len) { From 01b1656f36a478399063066749404aaece27ec53 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 10:46:16 +0200 Subject: [PATCH 03/32] cli: cleanup print_required_fields() Avoid explicit free() calls, but instead have a auto variable own the string. --- clients/cli/utils.c | 87 +++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/clients/cli/utils.c b/clients/cli/utils.c index f67df6a3fd..dc3cfca353 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -35,6 +35,9 @@ #include "common.h" #include "settings.h" +#define ML_HEADER_WIDTH 79 +#define ML_VALUE_INDENT 40 + /*****************************************************************************/ static const char * @@ -1059,35 +1062,30 @@ print_required_fields (const NmcConfig *nmc_config, int indent, const NmcOutputField *field_values) { - GString *str; + nm_auto_free_gstring GString *str = NULL; int width1, width2; int table_width = 0; - char *line = NULL; - char *indent_str; - const char *not_set_str = "--"; + const char *not_set_str; int i; - gboolean multiline = nmc_config->multiline_output; gboolean terse = (nmc_config->print_output == NMC_PRINT_TERSE); gboolean pretty = (nmc_config->print_output == NMC_PRINT_PRETTY); - gboolean escape = nmc_config->escape_values; gboolean main_header_add = of_flags & NMC_OF_FLAG_MAIN_HEADER_ADD; gboolean main_header_only = of_flags & NMC_OF_FLAG_MAIN_HEADER_ONLY; gboolean field_names = of_flags & NMC_OF_FLAG_FIELD_NAMES; gboolean section_prefix = of_flags & NMC_OF_FLAG_SECTION_PREFIX; - enum { ML_HEADER_WIDTH = 79 }; - enum { ML_VALUE_INDENT = 40 }; - - /* --- Main header --- */ if ((main_header_add || main_header_only) && pretty) { - int header_width = nmc_string_screen_width (header_name, NULL) + 4; + gs_free char *line = NULL; + int header_width; - if (multiline) { - table_width = header_width < ML_HEADER_WIDTH ? ML_HEADER_WIDTH : header_width; + header_width = nmc_string_screen_width (header_name, NULL) + 4; + + if (nmc_config->multiline_output) { + table_width = NM_MAX (header_width, ML_HEADER_WIDTH); line = g_strnfill (ML_HEADER_WIDTH, '='); } else { /* tabular */ - table_width = table_width < header_width ? header_width : table_width; + table_width = NM_MAX (table_width, header_width); line = g_strnfill (table_width, '='); } @@ -1096,23 +1094,20 @@ print_required_fields (const NmcConfig *nmc_config, g_print ("%s\n", line); g_print ("%*s\n", (table_width + width2)/2 + width1 - width2, header_name); g_print ("%s\n", line); - g_free (line); } if (main_header_only) return; /* No field headers are printed in terse mode nor for multiline output */ - if ((terse || multiline) && field_names) + if ((terse || nmc_config->multiline_output) && field_names) return; - if (terse) - not_set_str = ""; /* Don't replace empty strings in terse mode */ + /* Don't replace empty strings in terse mode */ + not_set_str = terse ? "" : "--"; - - if (multiline) { + if (nmc_config->multiline_output) { for (i = 0; i < indices->len; i++) { - char *tmp; int idx = g_array_index (indices, int, i); gboolean is_array = field_values[idx].value_is_array; @@ -1123,13 +1118,16 @@ print_required_fields (const NmcConfig *nmc_config, continue; if (is_array) { - /* value is a null-terminated string array */ - const char **p, *val, *print_val; gs_free char *val_to_free = NULL; + const char **p, *val, *print_val; int j; + /* value is a null-terminated string array */ + for (p = (const char **) field_values[idx].value, j = 1; p && *p; p++, j++) { - val = *p ? *p : not_set_str; + gs_free char *tmp = NULL; + + val = *p ?: not_set_str; print_val = colorize_string (nmc_config->use_colors, field_values[idx].color, field_values[idx].color_fmt, val, &val_to_free); tmp = g_strdup_printf ("%s%s%s[%d]:", @@ -1140,14 +1138,15 @@ print_required_fields (const NmcConfig *nmc_config, width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val); - g_free (tmp); } } else { - /* value is a string */ + gs_free char *val_to_free = NULL; + gs_free char *tmp = NULL; const char *hdr_name = (const char*) field_values[0].value; const char *val = (const char*) field_values[idx].value; const char *print_val; - gs_free char *val_to_free = NULL; + + /* value is a string */ val = val && *val ? val : not_set_str; print_val = colorize_string (nmc_config->use_colors, field_values[idx].color, field_values[idx].color_fmt, @@ -1159,13 +1158,12 @@ print_required_fields (const NmcConfig *nmc_config, width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val); - g_free (tmp); } } if (pretty) { - line = g_strnfill (ML_HEADER_WIDTH, '-'); - g_print ("%s\n", line); - g_free (line); + gs_free char *line = NULL; + + g_print ("%s\n", (line = g_strnfill (ML_HEADER_WIDTH, '-'))); } return; @@ -1176,13 +1174,17 @@ print_required_fields (const NmcConfig *nmc_config, str = g_string_new (NULL); for (i = 0; i < indices->len; i++) { - int idx = g_array_index (indices, int, i); gs_free char *val_to_free = NULL; - const char *value = get_value_to_print (nmc_config->use_colors, (NmcOutputField *) field_values+idx, field_names, - not_set_str, &val_to_free); + int idx; + const char *value; + + idx = g_array_index (indices, int, i); + + value = get_value_to_print (nmc_config->use_colors, (NmcOutputField *) field_values+idx, field_names, + not_set_str, &val_to_free); if (terse) { - if (escape) { + if (nmc_config->escape_values) { const char *p = value; while (*p) { if (*p == ':' || *p == '\\') @@ -1207,21 +1209,20 @@ print_required_fields (const NmcConfig *nmc_config, if (str->len > 0) { g_string_truncate (str, str->len-1); /* Chop off last column separator */ if (indent > 0) { - indent_str = g_strnfill (indent, ' '); - g_string_prepend (str, indent_str); - g_free (indent_str); + gs_free char *indent_str = NULL; + + g_string_prepend (str, (indent_str = g_strnfill (indent, ' '))); } + g_print ("%s\n", str->str); /* Print horizontal separator */ if (field_names && pretty) { - line = g_strnfill (table_width, '-'); - g_print ("%s\n", line); - g_free (line); + gs_free char *line = NULL; + + g_print ("%s\n", (line = g_strnfill (table_width, '-'))); } } - - g_string_free (str, TRUE); } void From ce28918dbf117462bdda76aaf3c2703d8ba73e67 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 14:43:44 +0200 Subject: [PATCH 04/32] cli/trivial: move code --- clients/cli/general.c | 160 ++++++++++++++++++++++-------------------- clients/cli/utils.c | 76 ++++++++++---------- 2 files changed, 121 insertions(+), 115 deletions(-) diff --git a/clients/cli/general.c b/clients/cli/general.c index fe29e9947e..8383a9e687 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -35,6 +35,88 @@ #include "devices.h" #include "connections.h" +/*****************************************************************************/ + +static const char * +nm_state_to_string (NMState state) +{ + switch (state) { + case NM_STATE_ASLEEP: + return _("asleep"); + case NM_STATE_CONNECTING: + return _("connecting"); + case NM_STATE_CONNECTED_LOCAL: + return _("connected (local only)"); + case NM_STATE_CONNECTED_SITE: + return _("connected (site only)"); + case NM_STATE_CONNECTED_GLOBAL: + return _("connected"); + case NM_STATE_DISCONNECTING: + return _("disconnecting"); + case NM_STATE_DISCONNECTED: + return _("disconnected"); + case NM_STATE_UNKNOWN: + default: + return _("unknown"); + } +} + +static NMMetaTermColor +state_to_color (NMState state) +{ + switch (state) { + case NM_STATE_CONNECTING: + return NM_META_TERM_COLOR_YELLOW; + case NM_STATE_CONNECTED_LOCAL: + case NM_STATE_CONNECTED_SITE: + case NM_STATE_CONNECTED_GLOBAL: + return NM_META_TERM_COLOR_GREEN; + case NM_STATE_DISCONNECTING: + return NM_META_TERM_COLOR_YELLOW; + case NM_STATE_ASLEEP: + case NM_STATE_DISCONNECTED: + return NM_META_TERM_COLOR_RED; + default: + return NM_META_TERM_COLOR_NORMAL; + } +} + +static const char * +nm_connectivity_to_string (NMConnectivityState connectivity) +{ + switch (connectivity) { + case NM_CONNECTIVITY_NONE: + return _("none"); + case NM_CONNECTIVITY_PORTAL: + return _("portal"); + case NM_CONNECTIVITY_LIMITED: + return _("limited"); + case NM_CONNECTIVITY_FULL: + return _("full"); + case NM_CONNECTIVITY_UNKNOWN: + default: + return _("unknown"); + } +} + +static NMMetaTermColor +connectivity_to_color (NMConnectivityState connectivity) +{ + switch (connectivity) { + case NM_CONNECTIVITY_NONE: + return NM_META_TERM_COLOR_RED; + case NM_CONNECTIVITY_PORTAL: + case NM_CONNECTIVITY_LIMITED: + return NM_META_TERM_COLOR_YELLOW; + case NM_CONNECTIVITY_FULL: + return NM_META_TERM_COLOR_GREEN; + default: + return NM_META_TERM_COLOR_NORMAL; + } +} + +/*****************************************************************************/ + static const NmcMetaGenericInfo *const nmc_fields_nm_status[] = { NMC_META_GENERIC ("RUNNING"), /* 0 */ NMC_META_GENERIC ("VERSION"), /* 1 */ @@ -230,84 +312,6 @@ quit (void) g_main_loop_quit (loop); /* quit main loop */ } -static const char * -nm_state_to_string (NMState state) -{ - switch (state) { - case NM_STATE_ASLEEP: - return _("asleep"); - case NM_STATE_CONNECTING: - return _("connecting"); - case NM_STATE_CONNECTED_LOCAL: - return _("connected (local only)"); - case NM_STATE_CONNECTED_SITE: - return _("connected (site only)"); - case NM_STATE_CONNECTED_GLOBAL: - return _("connected"); - case NM_STATE_DISCONNECTING: - return _("disconnecting"); - case NM_STATE_DISCONNECTED: - return _("disconnected"); - case NM_STATE_UNKNOWN: - default: - return _("unknown"); - } -} - -static NMMetaTermColor -state_to_color (NMState state) -{ - switch (state) { - case NM_STATE_CONNECTING: - return NM_META_TERM_COLOR_YELLOW; - case NM_STATE_CONNECTED_LOCAL: - case NM_STATE_CONNECTED_SITE: - case NM_STATE_CONNECTED_GLOBAL: - return NM_META_TERM_COLOR_GREEN; - case NM_STATE_DISCONNECTING: - return NM_META_TERM_COLOR_YELLOW; - case NM_STATE_ASLEEP: - case NM_STATE_DISCONNECTED: - return NM_META_TERM_COLOR_RED; - default: - return NM_META_TERM_COLOR_NORMAL; - } -} - -static const char * -nm_connectivity_to_string (NMConnectivityState connectivity) -{ - switch (connectivity) { - case NM_CONNECTIVITY_NONE: - return _("none"); - case NM_CONNECTIVITY_PORTAL: - return _("portal"); - case NM_CONNECTIVITY_LIMITED: - return _("limited"); - case NM_CONNECTIVITY_FULL: - return _("full"); - case NM_CONNECTIVITY_UNKNOWN: - default: - return _("unknown"); - } -} - -static NMMetaTermColor -connectivity_to_color (NMConnectivityState connectivity) -{ - switch (connectivity) { - case NM_CONNECTIVITY_NONE: - return NM_META_TERM_COLOR_RED; - case NM_CONNECTIVITY_PORTAL: - case NM_CONNECTIVITY_LIMITED: - return NM_META_TERM_COLOR_YELLOW; - case NM_CONNECTIVITY_FULL: - return NM_META_TERM_COLOR_GREEN; - default: - return NM_META_TERM_COLOR_NORMAL; - } -} - static gboolean show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_flds) { diff --git a/clients/cli/utils.c b/clients/cli/utils.c index dc3cfca353..f24b74ccca 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -98,6 +98,45 @@ const NMMetaType nmc_meta_type_generic_info = { /*****************************************************************************/ +static gboolean +use_colors (NmcColorOption color_option) +{ + if (color_option == NMC_USE_COLOR_AUTO) { + static NmcColorOption cached = NMC_USE_COLOR_AUTO; + + if (G_UNLIKELY (cached == NMC_USE_COLOR_AUTO)) { + if ( g_strcmp0 (g_getenv ("TERM"), "dumb") == 0 + || !isatty (fileno (stdout))) + cached = NMC_USE_COLOR_NO; + else + cached = NMC_USE_COLOR_YES; + } + return cached == NMC_USE_COLOR_YES; + } + + return color_option == NMC_USE_COLOR_YES; +} + +static const char * +colorize_string (NmcColorOption color_option, + NMMetaTermColor color, + NMMetaTermFormat color_fmt, + const char *str, + char **out_to_free) +{ + const char *out = str; + + if ( use_colors (color_option) + && (color != NM_META_TERM_COLOR_NORMAL || color_fmt != NM_META_TERM_FORMAT_NORMAL)) { + *out_to_free = nmc_colorize (color_option, color, color_fmt, "%s", str); + out = *out_to_free; + } + + return out; +} + +/*****************************************************************************/ + static gboolean parse_global_arg (NmCli *nmc, const char *arg) { @@ -422,25 +461,6 @@ nmc_term_format_sequence (NMMetaTermFormat format) } } -static gboolean -use_colors (NmcColorOption color_option) -{ - if (color_option == NMC_USE_COLOR_AUTO) { - static NmcColorOption cached = NMC_USE_COLOR_AUTO; - - if (G_UNLIKELY (cached == NMC_USE_COLOR_AUTO)) { - if ( g_strcmp0 (g_getenv ("TERM"), "dumb") == 0 - || !isatty (fileno (stdout))) - cached = NMC_USE_COLOR_NO; - else - cached = NMC_USE_COLOR_YES; - } - return cached == NMC_USE_COLOR_YES; - } - - return color_option == NMC_USE_COLOR_YES; -} - char * nmc_colorize (NmcColorOption color_option, NMMetaTermColor color, NMMetaTermFormat format, const char *fmt, ...) { @@ -992,24 +1012,6 @@ nmc_empty_output_fields (NmcOutputData *output_data) g_ptr_array_remove_range (output_data->output_data, 0, output_data->output_data->len); } -static const char * -colorize_string (NmcColorOption color_option, - NMMetaTermColor color, - NMMetaTermFormat color_fmt, - const char *str, - char **out_to_free) -{ - const char *out = str; - - if ( use_colors (color_option) - && (color != NM_META_TERM_COLOR_NORMAL || color_fmt != NM_META_TERM_FORMAT_NORMAL)) { - *out_to_free = nmc_colorize (color_option, color, color_fmt, "%s", str); - out = *out_to_free; - } - - return out; -} - static const char * get_value_to_print (NmcColorOption color_option, const NmcOutputField *field, From e79174ca890663b23432b6062f5e69d8bfe39373 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 14:39:46 +0200 Subject: [PATCH 05/32] cli: refactor enum-to-string function to have non-translating version We need both translated and non-translated versions. --- clients/cli/general.c | 55 ++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/clients/cli/general.c b/clients/cli/general.c index 8383a9e687..fd4c326a51 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -37,28 +37,22 @@ /*****************************************************************************/ +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (nm_state_to_string_no_l10n, NMState, + NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_ASLEEP, N_("asleep")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_CONNECTING, N_("connecting")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_CONNECTED_LOCAL, N_("connected (local only)")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_CONNECTED_SITE, N_("connected (site only)")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_CONNECTED_GLOBAL, N_("connected")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_DISCONNECTING, N_("disconnecting")), + NM_UTILS_LOOKUP_ITEM (NM_STATE_DISCONNECTED, N_("disconnected")), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_STATE_UNKNOWN), +); + static const char * nm_state_to_string (NMState state) { - switch (state) { - case NM_STATE_ASLEEP: - return _("asleep"); - case NM_STATE_CONNECTING: - return _("connecting"); - case NM_STATE_CONNECTED_LOCAL: - return _("connected (local only)"); - case NM_STATE_CONNECTED_SITE: - return _("connected (site only)"); - case NM_STATE_CONNECTED_GLOBAL: - return _("connected"); - case NM_STATE_DISCONNECTING: - return _("disconnecting"); - case NM_STATE_DISCONNECTED: - return _("disconnected"); - case NM_STATE_UNKNOWN: - default: - return _("unknown"); - } + return _(nm_state_to_string_no_l10n (state)); } static NMMetaTermColor @@ -81,22 +75,19 @@ state_to_color (NMState state) } } +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (nm_connectivity_to_string_no_l10n, NMConnectivityState, + NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), + NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_NONE, N_("none")), + NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_PORTAL, N_("portal")), + NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_LIMITED, N_("limited")), + NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_FULL, N_("full")), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CONNECTIVITY_UNKNOWN), +); + static const char * nm_connectivity_to_string (NMConnectivityState connectivity) { - switch (connectivity) { - case NM_CONNECTIVITY_NONE: - return _("none"); - case NM_CONNECTIVITY_PORTAL: - return _("portal"); - case NM_CONNECTIVITY_LIMITED: - return _("limited"); - case NM_CONNECTIVITY_FULL: - return _("full"); - case NM_CONNECTIVITY_UNKNOWN: - default: - return _("unknown"); - } + return _(nm_connectivity_to_string_no_l10n (connectivity)); } static NMMetaTermColor From fdd40b6a6821eaced26a08ca6d2ad731ad506071 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 4 Apr 2017 15:23:39 +0200 Subject: [PATCH 06/32] cli: implement new nmc_print() command to generically output cli data We already have - data sources (nm_cli, connections or settings) - meta data information how to access the data sources (NMMetaAbstractInfo, NmcMetaGenericInfo, NMMetaPropertyInfo) Add now a generic way to output cli data using nmc_print(). It gets a list of data-sources (@targets) and a list of available fields (meta data). It also gets cli configuration (NmcConfig) and field selector strings (@field_str). Based on that, it should output the desired data. This is intended to replaces the previous approach, where functions like show_nm_status() have full knowledge about how to access the data and create an intermediate output format (NmcOutputData, NmcOutputField) that was printed via print_data(). show_nm_status() contained both knowledge about the data itself (how to print a value) and intimate knoweledge about the output intermediate format. Also, the intermediate format is hard to understand. For example, sometimes we put the field prefix in NmcOutputField at index 0 and via the NmcOfFlags we control how to output the data. Clearly separate the responsibilities. - The meta data (NmcMetaGenericInfo) is only concerned with converting a data source to a string (or a color format). - the field selection (@field_str) only cares about parsing the list of NMMetaAbstractInfo. - _print_fill() populates a table with output values and header entries. - _print_do() prints the previously prepared table. The advantage is that if you want to change anything, you only need to touch a particular part. This is only a show-case for `nmcli general status`. Parts are still un-implemented and will follow. This changes behavior for --terse mode: the values are now no longer translated: $ LANG=de_DE.utf8 nmcli -t --mode multiline general --- clients/cli/connections.c | 4 +- clients/cli/general.c | 191 +++-- clients/cli/utils.c | 916 ++++++++++++++++++++---- clients/cli/utils.h | 33 +- clients/common/nm-meta-setting-access.c | 24 + clients/common/nm-meta-setting-access.h | 8 + clients/common/nm-meta-setting-desc.h | 27 + 7 files changed, 964 insertions(+), 239 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index c981faecd5..d9ed01c719 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1391,8 +1391,8 @@ split_required_fields_for_con_show (const char *input, else if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_ACTIVE)) group_active = TRUE; else { - char *allowed1 = nmc_get_allowed_fields ((const NMMetaAbstractInfo *const*) nm_meta_setting_infos_editor_p ()); - char *allowed2 = nmc_get_allowed_fields ((const NMMetaAbstractInfo *const*) nmc_fields_con_active_details_groups); + char *allowed1 = nmc_get_allowed_fields ((const NMMetaAbstractInfo *const*) nm_meta_setting_infos_editor_p (), NULL); + char *allowed2 = nmc_get_allowed_fields ((const NMMetaAbstractInfo *const*) nmc_fields_con_active_details_groups, NULL); g_set_error (error, NMCLI_ERROR, 0, _("invalid field '%s'; allowed fields: %s and %s, or %s,%s"), *iter, allowed1, allowed2, CON_SHOW_DETAIL_GROUP_PROFILE, CON_SHOW_DETAIL_GROUP_ACTIVE); g_free (allowed1); diff --git a/clients/cli/general.c b/clients/cli/general.c index fd4c326a51..82f878b692 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -108,20 +108,107 @@ connectivity_to_color (NMConnectivityState connectivity) /*****************************************************************************/ -static const NmcMetaGenericInfo *const nmc_fields_nm_status[] = { - NMC_META_GENERIC ("RUNNING"), /* 0 */ - NMC_META_GENERIC ("VERSION"), /* 1 */ - NMC_META_GENERIC ("STATE"), /* 2 */ - NMC_META_GENERIC ("STARTUP"), /* 3 */ - NMC_META_GENERIC ("CONNECTIVITY"), /* 4 */ - NMC_META_GENERIC ("NETWORKING"), /* 5 */ - NMC_META_GENERIC ("WIFI-HW"), /* 6 */ - NMC_META_GENERIC ("WIFI"), /* 7 */ - NMC_META_GENERIC ("WWAN-HW"), /* 8 */ - NMC_META_GENERIC ("WWAN"), /* 9 */ - NMC_META_GENERIC ("WIMAX-HW"), /* 10 */ - NMC_META_GENERIC ("WIMAX"), /* 11 */ - NULL, +static const NmcMetaGenericInfo *const metagen_general_status[]; + +static gconstpointer +_metagen_general_status_get_fcn (const NMMetaEnvironment *environment, + gpointer environment_user_data, + const NmcMetaGenericInfo *info, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + gpointer *out_to_free) +{ + NmCli *nmc = target; + const char *value; + gboolean v_bool; + NMState state; + NMConnectivityState connectivity; + +#define HANDLE_TERMFORMAT(color) \ + G_STMT_START { \ + if (get_type == NM_META_ACCESSOR_GET_TYPE_TERMFORMAT) \ + return nm_meta_termformat_pack ((color), NM_META_TERM_FORMAT_NORMAL); \ + } G_STMT_END + + switch (info->info_type) { + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING: + HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + value = N_("running"); + goto translate_and_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_VERSION: + HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + value = nm_client_get_version (nmc->client); + goto clone_and_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STATE: + state = nm_client_get_state (nmc->client); + HANDLE_TERMFORMAT (state_to_color (state)); + value = nm_state_to_string_no_l10n (state); + goto translate_and_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STARTUP: + v_bool = nm_client_get_startup (nmc->client); + HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_YELLOW : NM_META_TERM_COLOR_GREEN); + value = v_bool ? N_("starting") : N_("started"); + goto translate_and_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_CONNECTIVITY: + connectivity = nm_client_get_connectivity (nmc->client); + HANDLE_TERMFORMAT (connectivity_to_color (connectivity)); + value = nm_connectivity_to_string_no_l10n (connectivity); + goto translate_and_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NETWORKING: + v_bool = nm_client_networking_get_enabled (nmc->client); + goto enabled_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI_HW: + v_bool = nm_client_wireless_hardware_get_enabled (nmc->client); + goto enabled_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI: + v_bool = nm_client_wireless_get_enabled (nmc->client); + goto enabled_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN_HW: + v_bool = nm_client_wwan_hardware_get_enabled (nmc->client); + goto enabled_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN: + v_bool = nm_client_wwan_get_enabled (nmc->client); + goto enabled_out; + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX_HW: + case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX: + /* deprected fields. Don't return anything. */ + return NULL; + default: + break; + } + + g_return_val_if_reached (NULL); + +enabled_out: + HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED); + value = v_bool ? N_("enabled") : N_("disabled"); + goto translate_and_out; + +clone_and_out: + return (*out_to_free = g_strdup (value)); + +translate_and_out: + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(value); + return value; +} + +static const NmcMetaGenericInfo *const metagen_general_status[_NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NUM + 1] = { +#define _METAGEN_GENERAL_STATUS(type, name) \ + [type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_general_status_get_fcn) + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING, "RUNNING"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_VERSION, "VERSION"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STATE, "STATE"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STARTUP, "STARTUP"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_CONNECTIVITY, "CONNECTIVITY"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NETWORKING, "NETWORKING"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI_HW, "WIFI-HW"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI, "WIFI"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN_HW, "WWAN-HW"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN, "WWAN"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX_HW, "WIMAX-HW"), + _METAGEN_GENERAL_STATUS (NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX, "WIMAX"), }; #define NMC_FIELDS_NM_STATUS_ALL "RUNNING,VERSION,STATE,STARTUP,CONNECTIVITY,NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN" #define NMC_FIELDS_NM_STATUS_SWITCH "NETWORKING,WIFI-HW,WIFI,WWAN-HW,WWAN" @@ -306,19 +393,10 @@ quit (void) 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; - gboolean net_enabled; - gboolean wireless_hw_enabled, wireless_enabled; - gboolean wwan_hw_enabled, wwan_enabled; - GError *error = NULL; + gs_free_error GError *error = NULL; const char *fields_str; const char *fields_all = print_flds ? print_flds : NMC_FIELDS_NM_STATUS_ALL; const char *fields_common = print_flds ? print_flds : NMC_FIELDS_NM_STATUS_COMMON; - const NMMetaAbstractInfo *const*tmpl; - NmcOutputField *arr; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) fields_str = fields_common; @@ -327,57 +405,16 @@ show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_fl else fields_str = nmc->required_fields; - tmpl = (const NMMetaAbstractInfo *const*) nmc_fields_nm_status; - out_indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); - - if (error) { + if (!nmc_print (&nmc->nmc_config, + (gpointer[]) { nmc, NULL }, + pretty_header_name ?: N_("NetworkManager status"), + (const NMMetaAbstractInfo *const*) metagen_general_status, + fields_str, + &error)) { 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; } - - state = nm_client_get_state (nmc->client); - startup = nm_client_get_startup (nmc->client); - connectivity = nm_client_get_connectivity (nmc->client); - 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); - - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); - - arr = nmc_dup_fields_array (tmpl, 0); - set_val_strc (arr, 0, _("running")); - set_val_strc (arr, 1, nm_client_get_version (nmc->client)); - 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 ? _("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")); - - /* Set colors */ - arr[2].color = state_to_color (state); - arr[3].color = startup ? NM_META_TERM_COLOR_YELLOW : NM_META_TERM_COLOR_GREEN; - arr[4].color = connectivity_to_color (connectivity); - arr[5].color = net_enabled ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED; - arr[6].color = wireless_hw_enabled ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED; - arr[7].color = wireless_enabled ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED; - arr[8].color = wwan_hw_enabled ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED; - arr[9].color = wwan_enabled ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED; - - g_ptr_array_add (out.output_data, arr); - - print_data_prepare_width (out.output_data); - print_data (&nmc->nmc_config, out_indices, - pretty_header_name ?: _("NetworkManager status"), - 0, &out); - return TRUE; } @@ -860,7 +897,7 @@ do_networking_connectivity (NmCli *nmc, int argc, char **argv) if (!argc) { /* no arguments -> get current state */ - nmc_switch_show (nmc, NMC_FIELDS_NM_CONNECTIVITY, _("Connectivity")); + nmc_switch_show (nmc, NMC_FIELDS_NM_CONNECTIVITY, N_("Connectivity")); } else if (matches (*argv, "check")) { gs_free_error GError *error = NULL; @@ -872,7 +909,7 @@ do_networking_connectivity (NmCli *nmc, int argc, char **argv) g_string_printf (nmc->return_text, _("Error: %s."), error->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } else - nmc_switch_show (nmc, NMC_FIELDS_NM_CONNECTIVITY, _("Connectivity")); + nmc_switch_show (nmc, NMC_FIELDS_NM_CONNECTIVITY, N_("Connectivity")); } else { usage_networking (); g_string_printf (nmc->return_text, _("Error: 'networking' command '%s' is not valid."), *argv); @@ -889,7 +926,7 @@ do_networking_show (NmCli *nmc, int argc, char **argv) if (nmc->complete) return nmc->return_value; - nmc_switch_show (nmc, NMC_FIELDS_NM_NETWORKING, _("Networking")); + nmc_switch_show (nmc, NMC_FIELDS_NM_NETWORKING, N_("Networking")); return nmc->return_value; } @@ -924,7 +961,7 @@ do_radio_all (NmCli *nmc, int argc, char **argv) return nmc->return_value; /* no argument, show all radio switches */ - show_nm_status (nmc, _("Radio switches"), NMC_FIELDS_NM_STATUS_RADIO); + show_nm_status (nmc, N_("Radio switches"), NMC_FIELDS_NM_STATUS_RADIO); } else { if (nmc->complete) { if (argc == 1) @@ -954,7 +991,7 @@ do_radio_wifi (NmCli *nmc, int argc, char **argv) return nmc->return_value; /* no argument, show current WiFi state */ - nmc_switch_show (nmc, NMC_FIELDS_NM_WIFI, _("Wi-Fi radio switch")); + nmc_switch_show (nmc, NMC_FIELDS_NM_WIFI, N_("Wi-Fi radio switch")); } else { if (nmc->complete) { if (argc == 1) @@ -981,7 +1018,7 @@ do_radio_wwan (NmCli *nmc, int argc, char **argv) return nmc->return_value; /* no argument, show current WWAN (mobile broadband) state */ - nmc_switch_show (nmc, NMC_FIELDS_NM_WWAN, _("WWAN radio switch")); + nmc_switch_show (nmc, NMC_FIELDS_NM_WWAN, N_("WWAN radio switch")); } else { if (nmc->complete) { if (argc == 1) diff --git a/clients/cli/utils.c b/clients/cli/utils.c index f24b74ccca..ddefb4c2a3 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -79,10 +79,19 @@ _meta_type_nmc_generic_info_get_fcn (const NMMetaEnvironment *environment, { const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info; - nm_assert (out_to_free && !*out_to_free); + nm_assert (!out_to_free || !*out_to_free); if (!info->get_fcn) g_return_val_if_reached (NULL); + if (!NM_IN_SET (get_type, + NM_META_ACCESSOR_GET_TYPE_PARSABLE, + NM_META_ACCESSOR_GET_TYPE_PRETTY, + NM_META_ACCESSOR_GET_TYPE_TERMFORMAT)) + g_return_val_if_reached (NULL); + + /* omitting the out_to_free value is only allowed for TERMFORMAT. */ + nm_assert (out_to_free || NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_TERMFORMAT)); + return info->get_fcn (environment, environment_user_data, info, target, get_type, get_flags, @@ -733,26 +742,185 @@ nmc_free_output_field_values (NmcOutputField fields_array[]) } } +/*****************************************************************************/ + typedef struct { guint idx; - gsize offset_plus_1; + gsize self_offset_plus_1; + gsize sub_offset_plus_1; } OutputSelectionItem; -NmcOutputSelection * -nmc_output_selection_create (const NMMetaAbstractInfo *const* fields_array, - const char *fields_str, - GError **error) +static NmcOutputSelection * +_output_selection_pack (const NMMetaAbstractInfo *const* fields_array, + GArray *array, + GString *str) +{ + NmcOutputSelection *result; + guint i; + guint len; + + len = array ? array->len : 0; + + /* re-organize the collected output data in one buffer that can be freed using + * g_free(). This makes allocation more complicated, but saves us from special + * handling for free. */ + result = g_malloc0 (sizeof (NmcOutputSelection) + (len * sizeof (NmcOutputSelectionItem)) + (str ? str->len : 0)); + *((guint *) &result->num) = len; + if (len > 0) { + char *pdata = &((char *) result)[sizeof (NmcOutputSelection) + (len * sizeof (NmcOutputSelectionItem))]; + + if (str) + memcpy (pdata, str->str, str->len); + for (i = 0; i < len; i++) { + const OutputSelectionItem *a = &g_array_index (array, OutputSelectionItem, i); + NmcOutputSelectionItem *p = (NmcOutputSelectionItem *) &result->items[i]; + + p->info = fields_array[a->idx]; + p->idx = a->idx; + if (a->self_offset_plus_1 > 0) + p->self_selection = &pdata[a->self_offset_plus_1 - 1]; + if (a->sub_offset_plus_1 > 0) + p->sub_selection = &pdata[a->sub_offset_plus_1 - 1]; + } + } + + return result; +} + +static gboolean +_output_selection_select_one (const NMMetaAbstractInfo *const* fields_array, + const char *fields_prefix, + const char *fields_str, + gboolean validate_nested, + GArray **p_array, + GString **p_str, + GError **error) +{ + guint i, j; + const char *i_name; + const char *right; + gboolean found = FALSE; + const NMMetaAbstractInfo *fields_array_failure = NULL; + gs_free char *fields_str_clone = NULL; + + nm_assert (fields_str); + nm_assert (p_array); + nm_assert (p_str); + nm_assert (!error || !*error); + + right = strchr (fields_str, '.'); + if (right) { + fields_str_clone = g_strdup (fields_str); + fields_str_clone[right - fields_str] = '\0'; + i_name = fields_str_clone; + right = &fields_str_clone[right - fields_str + 1]; + } else + i_name = fields_str; + + if (!fields_array) + goto not_found; + + for (i = 0; fields_array[i]; i++) { + const NMMetaAbstractInfo *fi = fields_array[i]; + + if (g_ascii_strcasecmp (i_name, nm_meta_abstract_info_get_name (fi)) != 0) + continue; + + if (!right || !validate_nested) { + found = TRUE; + break; + } + + if (fi->meta_type == &nm_meta_type_setting_info_editor) { + const NMMetaSettingInfoEditor *fi_s = &fi->as.setting_info; + + for (j = 1; j < fi_s->properties_num; j++) { + if (g_ascii_strcasecmp (right, fi_s->properties[j].property_name) == 0) { + found = TRUE; + break; + } + } + } else if (fi->meta_type == &nmc_meta_type_generic_info) { + const NmcMetaGenericInfo *fi_g = (const NmcMetaGenericInfo *) fi; + + for (j = 0; fi_g->nested && fi_g->nested[j]; j++) { + if (g_ascii_strcasecmp (right, nm_meta_abstract_info_get_name ((const NMMetaAbstractInfo *) fi_g->nested[j])) == 0) { + found = TRUE; + break; + } + } + } + fields_array_failure = fields_array[i]; + break; + } + + if (!found) { +not_found: + if ( !right + && !fields_prefix + && ( !g_ascii_strcasecmp (i_name, "all") + || !g_ascii_strcasecmp (i_name, "common"))) + g_set_error (error, NMCLI_ERROR, 0, _("field '%s' has to be alone"), i_name); + else { + gs_free char *allowed_fields = NULL; + + if (fields_array_failure) { + gs_free char *p = NULL; + + if (fields_prefix) { + p = g_strdup_printf ("%s.%s", fields_prefix, + nm_meta_abstract_info_get_name (fields_array_failure)); + } + allowed_fields = nmc_get_allowed_fields_nested (fields_array_failure, p); + } else + allowed_fields = nmc_get_allowed_fields (fields_array, NULL); + + g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s%s%s'; %s%s%s"), + fields_prefix ?: "", fields_prefix ? "." : "", + i_name, right ? "." : "", right ?: "", + NM_PRINT_FMT_QUOTED (allowed_fields, "allowed fields: ", allowed_fields, "", "no fields")); + } + return FALSE; + } + + { + GString *str; + OutputSelectionItem s = { + .idx = i, + }; + + if (!*p_str) + *p_str = g_string_sized_new (64); + str = *p_str; + + s.self_offset_plus_1 = str->len + 1; + if (fields_prefix) { + g_string_append (str, fields_prefix); + g_string_append_c (str, '.'); + } + g_string_append_len (str, i_name, strlen (i_name) + 1); + + if (right) { + s.sub_offset_plus_1 = str->len + 1; + g_string_append_len (str, right, strlen (right) + 1); + } + + if (!*p_array) + *p_array = g_array_new (FALSE, FALSE, sizeof (OutputSelectionItem)); + g_array_append_val (*p_array, s); + } + + return TRUE; +} + +static NmcOutputSelection * +_output_selection_create_all (const NMMetaAbstractInfo *const* fields_array) { gs_unref_array GArray *array = NULL; - nm_auto_free_gstring GString *str = NULL; - guint i, j; - NmcOutputSelection *result; + guint i; - g_return_val_if_fail (!error || !*error, NULL); - - array = g_array_new (FALSE, FALSE, sizeof (OutputSelectionItem)); - - if (!fields_str) { + if (fields_array) { + array = g_array_new (FALSE, FALSE, sizeof (OutputSelectionItem)); for (i = 0; fields_array[i]; i++) { OutputSelectionItem s = { .idx = i, @@ -760,131 +928,220 @@ nmc_output_selection_create (const NMMetaAbstractInfo *const* fields_array, g_array_append_val (array, s); } - } else { - gs_free char *fields_str_clone = NULL; - char *fields_str_cur; - char *fields_str_next; - - fields_str_clone = g_strdup (fields_str); - for (fields_str_cur = fields_str_clone; fields_str_cur; fields_str_cur = fields_str_next) { - const char *i_name; - const char *right = NULL; - gboolean found = FALSE; - const NMMetaAbstractInfo *fields_array_failure = NULL; - - fields_str_cur = nm_str_skip_leading_spaces (fields_str_cur); - fields_str_next = strchr (fields_str_cur, ','); - if (fields_str_next) - *fields_str_next++ = '\0'; - - g_strchomp (fields_str_cur); - if (!fields_str_cur[0]) - continue; - - i_name = fields_str_cur; - fields_str_cur = strchr (fields_str_cur, '.'); - if (fields_str_cur) { - right = fields_str_cur + 1; - *fields_str_cur = '\0'; - } - - for (i = 0; fields_array[i]; i++) { - const NMMetaAbstractInfo *fi = fields_array[i]; - - if (g_ascii_strcasecmp (i_name, nm_meta_abstract_info_get_name (fi)) != 0) - continue; - - if (!right) - found = TRUE; - else { - found = FALSE; - if (fi->meta_type == &nm_meta_type_setting_info_editor) { - const NMMetaSettingInfoEditor *fi_s = &fi->as.setting_info; - - for (j = 1; j < fi_s->properties_num; j++) { - if (g_ascii_strcasecmp (right, fi_s->properties[j].property_name) == 0) { - found = TRUE; - break; - } - } - } else if (fi->meta_type == &nmc_meta_type_generic_info) { - const NmcMetaGenericInfo *fi_g = (const NmcMetaGenericInfo *) fi; - - for (j = 0; fi_g->nested && fi_g->nested[j]; j++) { - if (g_ascii_strcasecmp (right, nm_meta_abstract_info_get_name ((const NMMetaAbstractInfo *) fi_g->nested[j])) == 0) { - found = TRUE; - break; - } - } - } - } - - if (found) { - OutputSelectionItem s = { - .idx = i, - }; - - if (right) { - if (!str) - str = g_string_sized_new (32); - - s.offset_plus_1 = str->len + 1; - g_string_append_len (str, right, strlen (right) + 1); - } - - g_array_append_val (array, s); - } - - fields_array_failure = fields_array[i]; - break; - } - - if (!found) { - if ( !right - && ( !g_ascii_strcasecmp (i_name, "all") - || !g_ascii_strcasecmp (i_name, "common"))) - g_set_error (error, NMCLI_ERROR, 0, _("field '%s' has to be alone"), i_name); - else { - gs_free char *allowed_fields = NULL; - - if (fields_array_failure) - allowed_fields = nmc_get_allowed_fields_nested (fields_array_failure); - else - allowed_fields = nmc_get_allowed_fields (fields_array); - - g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s'; allowed fields: %s"), - i_name, right ? "." : "", right ?: "", allowed_fields); - } - - return NULL; - } - } } - /* re-organize the collected output data in one buffer that can be freed using - * g_free(). This makes allocation more complicated, but saves us from special - * handling for free. */ - result = g_malloc0 (sizeof (NmcOutputSelection) + (array->len * sizeof (NmcOutputSelectionItem)) + (str ? str->len : 0)); - *((guint *) &result->num) = array->len; - if (array->len > 0) { - char *pdata = &((char *) result)[sizeof (NmcOutputSelection) + (array->len * sizeof (NmcOutputSelectionItem))]; - - if (str) - memcpy (pdata, str->str, str->len); - for (i = 0; i < array->len; i++) { - const OutputSelectionItem *a = &g_array_index (array, OutputSelectionItem, i); - NmcOutputSelectionItem *p = (NmcOutputSelectionItem *) &result->items[i]; - - p->info = fields_array[a->idx]; - p->idx = a->idx; - if (a->offset_plus_1 > 0) - p->sub_selection = &pdata[a->offset_plus_1 - 1]; - } - } - - return result; + return _output_selection_pack (fields_array, array, NULL); } +static NmcOutputSelection * +_output_selection_create_one (const NMMetaAbstractInfo *const* fields_array, + const char *fields_prefix, + const char *fields_str, /* one field selector (contains not commas) and is alrady stripped of spaces. */ + gboolean validate_nested, + GError **error) +{ + gs_unref_array GArray *array = NULL; + nm_auto_free_gstring GString *str = NULL; + + g_return_val_if_fail (!error || !*error, NULL); + nm_assert (fields_str && !strchr (fields_str, ',')); + + if (!_output_selection_select_one (fields_array, + fields_prefix, + fields_str, + validate_nested, + &array, + &str, + error)) + return NULL; + return _output_selection_pack (fields_array, array, str); + +} + +#define PRINT_DATA_COL_PARENT_NIL (G_MAXUINT) + +typedef struct { + const NmcOutputSelectionItem *selection_item; + guint parent_idx; + guint self_idx; + bool is_leaf; +} PrintDataCol; + +static gboolean +_output_selection_append (GArray *cols, + const char *fields_prefix, + guint parent_idx, + const NmcOutputSelectionItem *selection_item, + GPtrArray *gfree_keeper, + GError **error) +{ + gs_free gpointer nested_to_free = NULL; + guint col_idx; + guint i; + const NMMetaAbstractInfo *const*nested; + NmcOutputSelection *selection; + const NmcOutputSelectionItem *si; + + col_idx = cols->len; + + { + PrintDataCol col = { + .selection_item = selection_item, + .parent_idx = parent_idx, + .self_idx = col_idx, + .is_leaf = TRUE, + }; + g_array_append_val (cols, col); + } + + nested = nm_meta_abstract_info_get_nested (selection_item->info, NULL, &nested_to_free); + + if (selection_item->sub_selection) { + if (!nested) { + gs_free char *allowed_fields = NULL; + + if (parent_idx != PRINT_DATA_COL_PARENT_NIL) { + si = g_array_index (cols, PrintDataCol, parent_idx).selection_item; + allowed_fields = nmc_get_allowed_fields_nested (si->info, si->self_selection); + } + if (!allowed_fields) { + g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s'; no such field"), + selection_item->self_selection ?: "", selection_item->self_selection ? "." : "", + selection_item->sub_selection); + } else { + g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s'; allowed fields: [%s]"), + selection_item->self_selection ?: "", selection_item->self_selection ? "." : "", + selection_item->sub_selection, + allowed_fields); + } + return FALSE; + } + + selection = _output_selection_create_one (nested, selection_item->self_selection, + selection_item->sub_selection, FALSE, error); + if (!selection) + return FALSE; + nm_assert (selection->num == 1); + } else if (nested) { + selection = _output_selection_create_all (nested); + nm_assert (selection && selection->num > 0); + } else + selection = NULL; + + if (selection) { + g_ptr_array_add (gfree_keeper, selection); + + for (i = 0; i < selection->num; i++) { + si = &selection->items[i]; + if (!_output_selection_append (cols, si->self_selection, col_idx, + si, gfree_keeper, error)) + return FALSE; + } + g_array_index (cols, PrintDataCol, col_idx).is_leaf = FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +NmcOutputSelection * +nmc_output_selection_create (const NMMetaAbstractInfo *const* fields_array, + const char *fields_prefix, + const char *fields_str, /* a comma separated list of selectors */ + gboolean validate_nested, + GError **error) +{ + gs_unref_array GArray *array = NULL; + nm_auto_free_gstring GString *str = NULL; + gs_free char *fields_str_clone = NULL; + char *fields_str_cur; + char *fields_str_next; + + g_return_val_if_fail (!error || !*error, NULL); + + if (!fields_str) + return _output_selection_create_all (fields_array); + + fields_str_clone = g_strdup (fields_str); + for (fields_str_cur = fields_str_clone; fields_str_cur; fields_str_cur = fields_str_next) { + fields_str_cur = nm_str_skip_leading_spaces (fields_str_cur); + fields_str_next = strchr (fields_str_cur, ','); + if (fields_str_next) + *fields_str_next++ = '\0'; + + g_strchomp (fields_str_cur); + if (!fields_str_cur[0]) + continue; + if (!_output_selection_select_one (fields_array, + fields_prefix, + fields_str_cur, + validate_nested, + &array, + &str, + error)) + return NULL; + } + + return _output_selection_pack (fields_array, array, str); +} + +/** + * _output_selection_parse: + * @fields: a %NULL terminated array of meta-data fields + * @fields_str: a comma separated selector for fields. Nested fields + * can be specified using '.' notation. + * @out_cols: (transfer full): the result, parsed as an GArray of PrintDataCol items. + * The order of the items is as specified by @fields_str. Meta data + * items that contain nested elements are unpacked (note the is_leaf + * and parent properties of PrintDataCol). + * @out_gfree_keeper: (transfer full): an output GPtrArray that owns + * strings to which @out_cols points to. The lifetime of @out_cols + * and @out_gfree_keeper should correspond. + * @error: + * + * Returns: %TRUE on success. + */ +static gboolean +_output_selection_parse (const NMMetaAbstractInfo *const*fields, + const char *fields_str, + GArray **out_cols, + GPtrArray **out_gfree_keeper, + GError **error) +{ + NmcOutputSelection *selection; + gs_unref_ptrarray GPtrArray *gfree_keeper = NULL; + gs_unref_array GArray *cols = NULL; + guint i; + + selection = nmc_output_selection_create (fields, NULL, fields_str, FALSE, error); + if (!selection) + return FALSE; + + if (!selection->num) { + g_set_error (error, NMCLI_ERROR, 1, _("failure to select field")); + return FALSE; + } + + gfree_keeper = g_ptr_array_new_with_free_func (g_free); + g_ptr_array_add (gfree_keeper, selection); + + cols = g_array_new (FALSE, TRUE, sizeof (PrintDataCol)); + + for (i = 0; i < selection->num; i++) { + const NmcOutputSelectionItem *si = &selection->items[i]; + + if (!_output_selection_append (cols, NULL, PRINT_DATA_COL_PARENT_NIL, + si, gfree_keeper, error)) + return FALSE; + } + + *out_cols = g_steal_pointer (&cols); + *out_gfree_keeper = g_steal_pointer (&gfree_keeper); + return TRUE; +} + +/*****************************************************************************/ /** * parse_output_fields: @@ -921,7 +1178,7 @@ parse_output_fields (const char *fields_str, g_return_val_if_fail (!error || !*error, NULL); g_return_val_if_fail (!out_group_fields || !*out_group_fields, NULL); - selection = nmc_output_selection_create (fields_array, fields_str, error); + selection = nmc_output_selection_create (fields_array, NULL, fields_str, TRUE, error); if (!selection) return NULL; @@ -943,40 +1200,46 @@ parse_output_fields (const char *fields_str, } char * -nmc_get_allowed_fields_nested (const NMMetaAbstractInfo *abstract_info) +nmc_get_allowed_fields_nested (const NMMetaAbstractInfo *abstract_info, const char *name_prefix) { - GString *allowed_fields = g_string_sized_new (256); - int i; - const char *name = nm_meta_abstract_info_get_name (abstract_info); gs_free gpointer nested_to_free = NULL; - const NMMetaAbstractInfo *const*nested = NULL; + guint i; + const NMMetaAbstractInfo *const*nested; + GString *allowed_fields; nested = nm_meta_abstract_info_get_nested (abstract_info, NULL, &nested_to_free); - if (nested) { - for (i = 0; nested && nested[i]; i++) { - g_string_append_printf (allowed_fields, "%s.%s,", - name, nm_meta_abstract_info_get_name (nested[i])); - } - } else - g_string_append_printf (allowed_fields, "%s,", name); + if (!nested) + return NULL; + allowed_fields = g_string_sized_new (256); + + if (!name_prefix) + name_prefix = nm_meta_abstract_info_get_name (abstract_info); + + for (i = 0; nested[i]; i++) { + g_string_append_printf (allowed_fields, "%s.%s,", + name_prefix, nm_meta_abstract_info_get_name (nested[i])); + } g_string_truncate (allowed_fields, allowed_fields->len - 1); - return g_string_free (allowed_fields, FALSE); } char * -nmc_get_allowed_fields (const NMMetaAbstractInfo *const*fields_array) +nmc_get_allowed_fields (const NMMetaAbstractInfo *const*fields_array, const char *name_prefix) { - GString *allowed_fields = g_string_sized_new (256); + GString *allowed_fields; guint i; - for (i = 0; fields_array[i]; i++) + if (!fields_array || !fields_array[0]) + return NULL; + + allowed_fields = g_string_sized_new (256); + for (i = 0; fields_array[i]; i++) { + if (name_prefix) + g_string_append_printf (allowed_fields, "%s.", name_prefix); g_string_append_printf (allowed_fields, "%s,", nm_meta_abstract_info_get_name (fields_array[i])); - - if (allowed_fields->len) - g_string_truncate (allowed_fields, allowed_fields->len - 1); - + } + g_string_truncate (allowed_fields, allowed_fields->len - 1); return g_string_free (allowed_fields, FALSE); } @@ -1012,6 +1275,343 @@ nmc_empty_output_fields (NmcOutputData *output_data) g_ptr_array_remove_range (output_data->output_data, 0, output_data->output_data->len); } +/*****************************************************************************/ + +typedef struct { + guint col_idx; + const PrintDataCol *col; + bool is_nested; + const char *title; + int width; +} PrintDataHeaderCell; + +typedef struct { + guint row_idx; + const PrintDataHeaderCell *header_cell; + NMMetaTermColor term_color; + NMMetaTermFormat term_format; + const char *text; + bool text_to_free:1; +} PrintDataCell; + +static void +_print_data_header_cell_clear (gpointer cell_p) +{ +} + +static void +_print_data_cell_clear_text (PrintDataCell *cell) +{ + if (cell->text_to_free) { + g_free ((char *) cell->text); + cell->text_to_free = FALSE; + } + cell->text = NULL; +} + +static void +_print_data_cell_clear (gpointer cell_p) +{ + PrintDataCell *cell = cell_p; + + _print_data_cell_clear_text (cell); +} + +static void +_print_fill (const NmcConfig *nmc_config, + gpointer const *targets, + const PrintDataCol *cols, + guint cols_len, + GArray **out_header_row, + GArray **out_cells) +{ + GArray *cells; + GArray *header_row; + guint i_row, i_col; + guint targets_len; + gboolean pretty; + NMMetaAccessorGetType text_get_type; + + pretty = (nmc_config->print_output != NMC_PRINT_TERSE); + + header_row = g_array_sized_new (FALSE, TRUE, sizeof (PrintDataHeaderCell), cols_len); + g_array_set_clear_func (header_row, _print_data_header_cell_clear); + + for (i_col = 0; i_col < cols_len; i_col++) { + const PrintDataCol *col; + PrintDataHeaderCell *header_cell; + guint col_idx; + + col = &cols[i_col]; + if (!col->is_leaf) + continue; + + col_idx = header_row->len; + g_array_set_size (header_row, col_idx + 1); + + header_cell = &g_array_index (header_row, PrintDataHeaderCell, col_idx); + + header_cell->col_idx = col_idx; + header_cell->col = col; + header_cell->is_nested = FALSE; + header_cell->title = nm_meta_abstract_info_get_name (col->selection_item->info); + if (pretty) + header_cell->title = _(header_cell->title); + } + + targets_len = NM_PTRARRAY_LEN (targets); + + cells = g_array_sized_new (FALSE, TRUE, sizeof (PrintDataCell), targets_len * header_row->len); + g_array_set_clear_func (cells, _print_data_cell_clear); + g_array_set_size (cells, targets_len * header_row->len); + + text_get_type = pretty + ? NM_META_ACCESSOR_GET_TYPE_PRETTY + : NM_META_ACCESSOR_GET_TYPE_PARSABLE; + + for (i_row = 0; i_row < targets_len; i_row++) { + gpointer target = targets[i_row]; + PrintDataCell *cells_line = &g_array_index (cells, PrintDataCell, i_row * header_row->len); + + for (i_col = 0; i_col < header_row->len; i_col++) { + char *to_free = NULL; + PrintDataCell *cell = &cells_line[i_col]; + const PrintDataHeaderCell *header_cell; + const NMMetaAbstractInfo *info; + + header_cell = &g_array_index (header_row, PrintDataHeaderCell, i_col); + info = header_cell->col->selection_item->info; + + cell->row_idx = i_row; + cell->header_cell = header_cell; + cell->text = nm_meta_abstract_info_get (info, + NULL, + NULL, + target, + text_get_type, + NM_META_ACCESSOR_GET_FLAGS_NONE, + (gpointer *) &to_free); + cell->text_to_free = !!to_free; + + nm_meta_termformat_unpack (nm_meta_abstract_info_get (info, + NULL, + NULL, + target, + NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, + NM_META_ACCESSOR_GET_FLAGS_NONE, + NULL), + &cell->term_color, + &cell->term_format); + + if (pretty && (!cell->text || !cell->text[0])) { + _print_data_cell_clear_text (cell); + cell->text = "--"; + } else if (!cell->text) + cell->text = ""; + } + } + + for (i_col = 0; i_col < header_row->len; i_col++) { + PrintDataHeaderCell *header_cell = &g_array_index (header_row, PrintDataHeaderCell, i_col); + + header_cell->width = nmc_string_screen_width (header_cell->title, NULL); + + for (i_row = 0; i_row < targets_len; i_row++) { + const PrintDataCell *cell = &g_array_index (cells, PrintDataCell, i_row * cols_len + i_col); + + if (header_cell->is_nested) { + g_assert_not_reached (/*TODO*/); + } else { + header_cell->width = NM_MAX (header_cell->width, + nmc_string_screen_width (cell->text, NULL)); + } + } + + header_cell->width += 1; + } + + *out_header_row = header_row; + *out_cells = cells; +} + +static void +_print_do (const NmcConfig *nmc_config, + const char *header_name_no_l10n, + guint col_len, + guint row_len, + const PrintDataHeaderCell *header_row, + const PrintDataCell *cells) +{ + int width1, width2; + int table_width = 0; + gboolean pretty = (nmc_config->print_output == NMC_PRINT_PRETTY); + gboolean terse = (nmc_config->print_output == NMC_PRINT_TERSE); + gboolean multiline = nmc_config->multiline_output; + guint i_row, i_col; + nm_auto_free_gstring GString *str = NULL; + + g_assert (col_len && row_len); + + /* Main header */ + if (pretty) { + gs_free char *line = NULL; + int header_width; + const char *header_name = _(header_name_no_l10n); + + header_width = nmc_string_screen_width (header_name, NULL) + 4; + + if (multiline) { + table_width = NM_MAX (header_width, ML_HEADER_WIDTH); + line = g_strnfill (ML_HEADER_WIDTH, '='); + } else { /* tabular */ + table_width = NM_MAX (table_width, header_width); + line = g_strnfill (table_width, '='); + } + + width1 = strlen (header_name); + width2 = nmc_string_screen_width (header_name, NULL); + g_print ("%s\n", line); + g_print ("%*s\n", (table_width + width2)/2 + width1 - width2, header_name); + g_print ("%s\n", line); + } + + str = !multiline + ? g_string_sized_new (100) + : NULL; + + /* print the header for the tabular form */ + if (!multiline && !terse) { + for (i_col = 0; i_col < col_len; i_col++) { + const PrintDataHeaderCell *header_cell = &header_row[i_col]; + const char *title; + + title = header_cell->title; + + width1 = strlen (title); + width2 = nmc_string_screen_width (title, NULL); /* Width of the string (in screen colums) */ + g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), title); + g_string_append_c (str, ' '); /* Column separator */ + table_width += header_cell->width + width1 - width2 + 1; + } + + if (str->len) + g_string_truncate (str, str->len-1); /* Chop off last column separator */ + g_print ("%s\n", str->str); + g_string_truncate (str, 0); + + /* Print horizontal separator */ + if (pretty) { + gs_free char *line = NULL; + + g_print ("%s\n", (line = g_strnfill (table_width, '-'))); + } + } + + for (i_row = 0; i_row < row_len; i_row++) { + const PrintDataCell *current_line = &cells[i_row * col_len]; + + for (i_col = 0; i_col < col_len; i_col++) { + const PrintDataCell *cell = ¤t_line[i_col]; + gs_free char *text_to_free = NULL; + const char *text; + + if (cell->header_cell->is_nested) { + g_assert_not_reached (/*TODO*/); + } else { + text = colorize_string (nmc_config->use_colors, + cell->term_color, cell->term_format, + cell->text, &text_to_free); + } + + if (multiline) { + gs_free char *prefix = NULL; + + prefix = g_strdup_printf ("%s:", cell->header_cell->title); + width1 = strlen (prefix); + width2 = nmc_string_screen_width (prefix, NULL); + g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), prefix, text); + } else { + nm_assert (str); + if (terse) { + if (nmc_config->escape_values) { + const char *p = text; + while (*p) { + if (*p == ':' || *p == '\\') + g_string_append_c (str, '\\'); /* Escaping by '\' */ + g_string_append_c (str, *p); + p++; + } + } + else + g_string_append_printf (str, "%s", text); + g_string_append_c (str, ':'); /* Column separator */ + } else { + const PrintDataHeaderCell *header_cell = &header_row[i_col]; + + width1 = strlen (text); + width2 = nmc_string_screen_width (text, NULL); /* Width of the string (in screen colums) */ + g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), text); + g_string_append_c (str, ' '); /* Column separator */ + table_width += header_cell->width + width1 - width2 + 1; + } + } + } + + if (!multiline) { + if (str->len) + g_string_truncate (str, str->len-1); /* Chop off last column separator */ + g_print ("%s\n", str->str); + + g_string_truncate (str, 0); + } + + if ( pretty + && ( i_row < row_len - 1 + || multiline)) { + gs_free char *line = NULL; + + g_print ("%s\n", (line = g_strnfill (ML_HEADER_WIDTH, '-'))); + } + } +} + +gboolean +nmc_print (const NmcConfig *nmc_config, + gpointer const *targets, + const char *header_name_no_l10n, + const NMMetaAbstractInfo *const*fields, + const char *fields_str, + GError **error) +{ + gs_unref_ptrarray GPtrArray *gfree_keeper = NULL; + gs_unref_array GArray *cols = NULL; + gs_unref_array GArray *header_row = NULL; + gs_unref_array GArray *cells = NULL; + + if (!_output_selection_parse (fields, fields_str, + &cols, &gfree_keeper, + error)) + return FALSE; + + _print_fill (nmc_config, + targets, + &g_array_index (cols, PrintDataCol, 0), + cols->len, + &header_row, + &cells); + + _print_do (nmc_config, + header_name_no_l10n, + header_row->len, + cells->len / header_row->len, + &g_array_index (header_row, PrintDataHeaderCell, 0), + &g_array_index (cells, PrintDataCell, 0)); + + return TRUE; +} + +/*****************************************************************************/ + static const char * get_value_to_print (NmcColorOption color_option, const NmcOutputField *field, @@ -1139,7 +1739,7 @@ print_required_fields (const NmcConfig *nmc_config, j); width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); - g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val); + g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), tmp, print_val); } } else { gs_free char *val_to_free = NULL; @@ -1159,7 +1759,7 @@ print_required_fields (const NmcConfig *nmc_config, _(nm_meta_abstract_info_get_name (field_values[idx].info))); width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); - g_print ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT+width1-width2, tmp, print_val); + g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), tmp, print_val); } } if (pretty) { diff --git a/clients/cli/utils.h b/clients/cli/utils.h index d212ecb31a..1a4c796539 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -63,6 +63,7 @@ void nmc_free_output_field_values (NmcOutputField fields_array[]); typedef struct { const NMMetaAbstractInfo *info; + const char *self_selection; const char *sub_selection; guint idx; } NmcOutputSelectionItem; @@ -73,7 +74,9 @@ typedef struct { } NmcOutputSelection; NmcOutputSelection *nmc_output_selection_create (const NMMetaAbstractInfo *const* fields_array, + const char *fields_prefix, const char *fields_str, + gboolean validate_nested, GError **error); GArray *parse_output_fields (const char *fields_str, @@ -81,8 +84,8 @@ GArray *parse_output_fields (const char *fields_str, gboolean parse_groups, GPtrArray **group_fields, GError **error); -char *nmc_get_allowed_fields_nested (const NMMetaAbstractInfo *abstract_info); -char *nmc_get_allowed_fields (const NMMetaAbstractInfo *const*fields_array); +char *nmc_get_allowed_fields_nested (const NMMetaAbstractInfo *abstract_info, const char *name_prefix); +char *nmc_get_allowed_fields (const NMMetaAbstractInfo *const*fields_array, const char *name_prefix); NmcOutputField *nmc_dup_fields_array (const NMMetaAbstractInfo *const*fields, NmcOfFlags flags); void nmc_empty_output_fields (NmcOutputData *output_data); void print_required_fields (const NmcConfig *nmc_config, @@ -100,8 +103,25 @@ void print_data (const NmcConfig *nmc_config, /*****************************************************************************/ +typedef enum { + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING = 0, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_VERSION, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STATE, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STARTUP, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_CONNECTIVITY, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NETWORKING, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI_HW, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIFI, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN_HW, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WWAN, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX_HW, + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX, + _NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NUM, +} NmcGenericInfoType; + struct _NmcMetaGenericInfo { const NMMetaType *meta_type; + NmcGenericInfoType info_type; const char *name; const NmcMetaGenericInfo *const*nested; gconstpointer (*get_fcn) (const NMMetaEnvironment *environment, @@ -125,4 +145,13 @@ struct _NmcMetaGenericInfo { /*****************************************************************************/ +gboolean nmc_print (const NmcConfig *nmc_config, + gpointer const *targets, + const char *header_name_no_l10n, + const NMMetaAbstractInfo *const*fields, + const char *fields_str, + GError **error); + +/*****************************************************************************/ + #endif /* NMC_UTILS_H */ diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 6da71448fc..5af55b377b 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -223,3 +223,27 @@ nm_meta_abstract_info_get_nested (const NMMetaAbstractInfo *abstract_info, NM_SET_OUT (out_len, 0); return NULL; } + +gconstpointer +nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + gpointer *out_to_free) +{ + nm_assert (abstract_info); + nm_assert (abstract_info->meta_type); + nm_assert (!out_to_free || !*out_to_free); + + if (!abstract_info->meta_type->get_fcn) + g_return_val_if_reached (NULL); + + return abstract_info->meta_type->get_fcn (environment, environment_user_data, + abstract_info, + target, + get_type, + get_flags, + out_to_free); +} diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 553f41136f..8ed69b29dd 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -50,6 +50,14 @@ const NMMetaAbstractInfo *const*nm_meta_abstract_info_get_nested (const NMMetaAb guint *out_len, gpointer *nested_to_free); +gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + gpointer *out_to_free); + /*****************************************************************************/ #endif /* _NM_META_SETTING_ACCESS_H__ */ diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 37ed367812..73e773b4de 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -49,8 +49,35 @@ typedef enum { typedef enum { NM_META_ACCESSOR_GET_TYPE_PRETTY, NM_META_ACCESSOR_GET_TYPE_PARSABLE, + NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, } NMMetaAccessorGetType; +static inline void +nm_meta_termformat_unpack (gconstpointer value, NMMetaTermColor *out_color, NMMetaTermFormat *out_format) +{ + /* get_fcn() with NM_META_ACCESSOR_GET_TYPE_TERMFORMAT returns a pointer + * that encodes NMMetaTermColor and NMMetaTermFormat. Unpack it. */ + if (!value) { + /* by default, objects that don't support NM_META_ACCESSOR_GET_TYPE_TERMFORMAT + * return NULL. This allows for an explicit fallback value here... */ + NM_SET_OUT (out_color, NM_META_TERM_COLOR_NORMAL); + NM_SET_OUT (out_format, NM_META_TERM_FORMAT_NORMAL); + } else { + NM_SET_OUT (out_color, GPOINTER_TO_UINT (value) & 0xFF); + NM_SET_OUT (out_format, (GPOINTER_TO_UINT (value) & 0xFF00) >> 8); + } +} + +static inline gconstpointer +nm_meta_termformat_pack (NMMetaTermColor color, NMMetaTermFormat format) +{ + /* get_fcn() with NM_META_ACCESSOR_GET_TYPE_TERMFORMAT returns a pointer + * that encodes NMMetaTermColor and NMMetaTermFormat. Pack it. */ + return GUINT_TO_POINTER (((guint) 0x10000) | (((guint) color) & 0xFFu) | ((((guint) format) & 0xFFu) << 8)); +} + +#define NM_META_TERMFORMAT_DEFAULT() (nm_meta_termformat_pack (NM_META_TERM_COLOR_NORMAL, NM_META_TERM_FORMAT_NORMAL)) + typedef enum { NM_META_ACCESSOR_GET_FLAGS_NONE = 0, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS = (1LL << 0), From f0d91455ca70db152ed4c27cf3a9b2dd77868a45 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:26:23 +0200 Subject: [PATCH 07/32] cli: move show_secret field to NmcConfig The show-secret property is basically a part of the current configuration, relevant during printing. It will be passed on to nmc_print(), and hence must be part of NmcConfig. --- clients/cli/common.c | 2 +- clients/cli/connections.c | 4 ++-- clients/cli/devices.c | 4 ++-- clients/cli/nmcli.c | 2 +- clients/cli/nmcli.h | 8 ++++---- clients/cli/utils.c | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index 3656cdbf82..a85d47687b 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -840,7 +840,7 @@ nmc_secrets_requested (NMSecretAgentSimple *agent, } success = get_secrets_from_user (request_id, title, msg, connection, nmc->nmc_config.in_editor || nmc->ask, - nmc->show_secrets, nmc->pwds_hash, secrets); + nmc->nmc_config.show_secrets, nmc->pwds_hash, secrets); if (success) nm_secret_agent_simple_response (agent, request_id, secrets); else { diff --git a/clients/cli/connections.c b/clients/cli/connections.c index d9ed01c719..5199fbcf89 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1873,9 +1873,9 @@ do_connections_show (NmCli *nmc, int argc, char **argv) if (without_fields || profile_flds) { if (con) { nmc->required_fields = profile_flds; - if (nmc->show_secrets) + if (nmc->nmc_config.show_secrets) update_secrets_in_connection (NM_REMOTE_CONNECTION (con), con); - res = nmc_connection_profile_details (con, nmc, nmc->show_secrets); + res = nmc_connection_profile_details (con, nmc, nmc->nmc_config.show_secrets); nmc->required_fields = NULL; if (!res) goto finish; diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 64a75a07d1..aa0ff083f4 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -3110,7 +3110,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) if (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) { /* Ask for missing password when one is expected and '--ask' is used */ if (!password && nmc->ask) - password = passwd_ask = nmc_readline_echo (nmc->show_secrets, _("Password: ")); + password = passwd_ask = nmc_readline_echo (nmc->nmc_config.show_secrets, _("Password: ")); if (password) { if (!connection) @@ -3408,7 +3408,7 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) next_arg (nmc, &argc, &argv, NULL); } - show_password = nmc->show_secrets || show_password; + show_password = nmc->nmc_config.show_secrets || show_password; if (nmc->complete) return nmc->return_value; diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index dcb86fe1dc..a341940e32 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -538,7 +538,7 @@ nmc_init (NmCli *nmc) nmc->required_fields = NULL; nmc->ask = FALSE; nmc->complete = FALSE; - nmc->show_secrets = FALSE; + nmc->nmc_config_mutable.show_secrets = FALSE; nmc->nmc_config_mutable.use_colors = NMC_USE_COLOR_AUTO; nmc->nmc_config_mutable.in_editor = FALSE; nmc->editor_status_line = FALSE; diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index c3949b5f68..1beaf74353 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -111,9 +111,10 @@ typedef enum { typedef struct _NmcConfig { NMCPrintOutput print_output; /* Output mode */ NmcColorOption use_colors; /* Whether to use colors for output: option '--color' */ - gboolean multiline_output; /* Multiline output instead of default tabular */ - gboolean escape_values; /* Whether to escape ':' and '\' in terse tabular mode */ - gboolean in_editor; /* Whether running the editor - nmcli con edit' */ + bool multiline_output; /* Multiline output instead of default tabular */ + bool escape_values; /* Whether to escape ':' and '\' in terse tabular mode */ + bool in_editor; /* Whether running the editor - nmcli con edit' */ + bool show_secrets; /* Whether to display secrets (both input and output): option '--show-secrets' */ } NmcConfig; typedef struct _NmcOutputData { @@ -143,7 +144,6 @@ typedef struct _NmCli { char *required_fields; /* Required fields in output: '--fields' option */ gboolean ask; /* Ask for missing parameters: option '--ask' */ gboolean complete; /* Autocomplete the command line */ - gboolean show_secrets; /* Whether to display secrets (both input and output): option '--show-secrets' */ gboolean editor_status_line; /* Whether to display status line in connection editor */ gboolean editor_save_confirmation; /* Whether to ask for confirmation on saving connections with 'autoconnect=yes' */ gboolean editor_show_secrets; /* Whether to display secrets in the editor' */ diff --git a/clients/cli/utils.c b/clients/cli/utils.c index ddefb4c2a3..4368267dc6 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -152,7 +152,7 @@ parse_global_arg (NmCli *nmc, const char *arg) if (nmc_arg_is_option (arg, "ask")) nmc->ask = TRUE; else if (nmc_arg_is_option (arg, "show-secrets")) - nmc->show_secrets = TRUE; + nmc->nmc_config_mutable.show_secrets = TRUE; else return FALSE; From fdd758112f19a0e29bd1540604d36c1ffe2de1c1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:27:56 +0200 Subject: [PATCH 08/32] cli: merge editor_show_secrets with NmcConfig.show_secrets The show-secrets flag can be toggled in edit mode nmcli> nmcli show-secrets yes There is no point in tracking two separate flags for it. Inside edit mode, when the user toggles the show-secrets flag, it should overwrite the command line option. These two flags can be merged. --- clients/cli/connections.c | 8 ++++---- clients/cli/nmcli.c | 1 - clients/cli/nmcli.h | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 5199fbcf89..ff8c4e97a5 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -5969,7 +5969,7 @@ editor_show_connection (NMConnection *connection, NmCli *nmc) nmc->nmc_config_mutable.multiline_output = TRUE; nmc->nmc_config_mutable.escape_values = 0; - nmc_connection_profile_details (connection, nmc, nmc->editor_show_secrets); + nmc_connection_profile_details (connection, nmc, nmc->nmc_config.show_secrets); } static void @@ -5982,7 +5982,7 @@ editor_show_setting (NMSetting *setting, NmCli *nmc) nmc->nmc_config_mutable.multiline_output = TRUE; nmc->nmc_config_mutable.escape_values = 0; - setting_details (&nmc->nmc_config, setting, NULL, nmc->editor_show_secrets); + setting_details (&nmc->nmc_config, setting, NULL, nmc->nmc_config.show_secrets); } typedef enum { @@ -7646,7 +7646,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t g_print (_("Error: show-secrets: %s\n"), tmp_err->message); g_clear_error (&tmp_err); } else - nmc->editor_show_secrets = bb; + nmc->nmc_config_mutable.show_secrets = bb; } else if (cmd_arg_p && matches (cmd_arg_p, "prompt-color")) { GError *tmp_err = NULL; NMMetaTermColor color; @@ -7673,7 +7673,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t "prompt-color: %d\n", nmc->editor_status_line ? "yes" : "no", nmc->editor_save_confirmation ? "yes" : "no", - nmc->editor_show_secrets ? "yes" : "no", + nmc->nmc_config.show_secrets ? "yes" : "no", nmc->editor_prompt_color); } else g_print (_("Invalid configuration option '%s'; allowed [%s]\n"), diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index a341940e32..2d224cf777 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -543,7 +543,6 @@ nmc_init (NmCli *nmc) nmc->nmc_config_mutable.in_editor = FALSE; nmc->editor_status_line = FALSE; nmc->editor_save_confirmation = TRUE; - nmc->editor_show_secrets = FALSE; nmc->editor_prompt_color = NM_META_TERM_COLOR_NORMAL; } diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 1beaf74353..3e73e5105c 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -146,8 +146,7 @@ typedef struct _NmCli { gboolean complete; /* Autocomplete the command line */ gboolean editor_status_line; /* Whether to display status line in connection editor */ gboolean editor_save_confirmation; /* Whether to ask for confirmation on saving connections with 'autoconnect=yes' */ - gboolean editor_show_secrets; /* Whether to display secrets in the editor' */ - NMMetaTermColor editor_prompt_color; /* Color of prompt in connection editor */ + NMMetaTermColor editor_prompt_color; /* Color of prompt in connection editor */ } NmCli; extern NmCli nm_cli; From 3045daf1276df4e629f3478c3b0302370a926b5c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:14:23 +0200 Subject: [PATCH 09/32] cli: use nmc_print() to output setting data --- clients/cli/connections.c | 24 +++--- clients/cli/nmcli.c | 2 - clients/cli/settings.c | 93 ++++++----------------- clients/cli/settings.h | 2 +- clients/cli/utils.c | 72 ++++++++++++++++-- clients/common/nm-meta-setting-desc.c | 102 ++++++++------------------ clients/common/nm-meta-setting-desc.h | 6 -- clients/common/tests/test-general.c | 5 -- 8 files changed, 127 insertions(+), 179 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index ff8c4e97a5..72eb0f8fd3 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -709,7 +709,7 @@ update_secrets_in_connection (NMRemoteConnection *remote, NMConnection *local) } static gboolean -nmc_connection_profile_details (NMConnection *connection, NmCli *nmc, gboolean secrets) +nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) { GError *error = NULL; GArray *print_settings_array; @@ -771,7 +771,7 @@ nmc_connection_profile_details (NMConnection *connection, NmCli *nmc, gboolean s setting = nm_connection_get_setting_by_name (connection, nm_meta_setting_infos_editor[section_idx].general->setting_name); if (setting) { - setting_details (&nmc->nmc_config, setting, prop_name, secrets); + setting_details (&nmc->nmc_config, setting, prop_name); was_output = TRUE; } } @@ -1875,7 +1875,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) nmc->required_fields = profile_flds; if (nmc->nmc_config.show_secrets) update_secrets_in_connection (NM_REMOTE_CONNECTION (con), con); - res = nmc_connection_profile_details (con, nmc, nmc->nmc_config.show_secrets); + res = nmc_connection_profile_details (con, nmc); nmc->required_fields = NULL; if (!res) goto finish; @@ -1893,7 +1893,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) } } new_line = TRUE; - + /* Take next argument. * But for pos != NULL we have more connections of the same name, * so process the same argument again. @@ -3187,14 +3187,11 @@ get_valid_properties_string (const NameItem *array, /* Search the array with the arguments of the current property */ setting_info = nm_meta_setting_info_editor_find_by_name (iter->name); - j = 0; - while (TRUE) { + for (j = 0; j < setting_info->properties_num; j++) { gchar *new; const char *arg_name; - if (j + 1 >= setting_info->properties_num) - break; - arg_name = setting_info->properties[j + 1].property_name; + arg_name = setting_info->properties[j].property_name; /* If required, expand the alias too */ if (!postfix && iter->alias) { @@ -3207,10 +3204,8 @@ get_valid_properties_string (const NameItem *array, g_free (new); } - if (postfix && !g_str_has_prefix (arg_name, postfix)) { - j++; + if (postfix && !g_str_has_prefix (arg_name, postfix)) continue; - } if (modifier) g_string_append_c (str, modifier); @@ -3219,7 +3214,6 @@ get_valid_properties_string (const NameItem *array, arg_name); g_string_append (str, new); g_free (new); - j++; } iter++; } @@ -5969,7 +5963,7 @@ editor_show_connection (NMConnection *connection, NmCli *nmc) nmc->nmc_config_mutable.multiline_output = TRUE; nmc->nmc_config_mutable.escape_values = 0; - nmc_connection_profile_details (connection, nmc, nmc->nmc_config.show_secrets); + nmc_connection_profile_details (connection, nmc); } static void @@ -5982,7 +5976,7 @@ editor_show_setting (NMSetting *setting, NmCli *nmc) nmc->nmc_config_mutable.multiline_output = TRUE; nmc->nmc_config_mutable.escape_values = 0; - setting_details (&nmc->nmc_config, setting, NULL, nmc->nmc_config.show_secrets); + setting_details (&nmc->nmc_config, setting, NULL); } typedef enum { diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 2d224cf777..df1c59810c 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -75,8 +75,6 @@ complete_field_setting (GHashTable *h, NMMetaSettingType setting_type) guint i; for (i = 0; i < setting_info->properties_num; i++) { - if (setting_info->properties[i].is_name) - continue; g_hash_table_add (h, g_strdup_printf ("%s.%s", setting_info->general->setting_name, setting_info->properties[i].property_name)); diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 99eaa4f700..9792f60c08 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -471,10 +471,7 @@ get_property_val (NMSetting *setting, const char *prop, NMMetaAccessorGetType ge g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->get_fcn) { + if (property_info->property_type->get_fcn) { return property_info->property_type->get_fcn (&meta_environment, NULL, property_info, @@ -549,10 +546,7 @@ nmc_setting_set_property (NMSetting *setting, const char *prop, const char *valu return TRUE; } - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->set_fcn) { + if (property_info->property_type->set_fcn) { switch (property_info->setting_info->general->meta_type) { case NM_META_SETTING_TYPE_CONNECTION: if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) { @@ -613,10 +607,7 @@ nmc_setting_reset_property (NMSetting *setting, const char *prop, GError **error g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->set_fcn) { + if (property_info->property_type->set_fcn) { nmc_property_set_default_value (setting, prop); return TRUE; } @@ -648,10 +639,7 @@ nmc_setting_remove_property_option (NMSetting *setting, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->remove_fcn) { + if (property_info->property_type->remove_fcn) { return property_info->property_type->remove_fcn (&meta_environment, NULL, property_info, @@ -707,10 +695,7 @@ nmc_setting_get_property_allowed_values (NMSetting *setting, const char *prop, c *out_to_free = NULL; if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->values_fcn) { + if (property_info->property_type->values_fcn) { return property_info->property_type->values_fcn (property_info, out_to_free); } else if (property_info->property_typ_data && property_info->property_typ_data->values_static) @@ -751,10 +736,7 @@ nmc_setting_get_property_desc (NMSetting *setting, const char *prop) setting_desc_title = _("[NM property description]"); } - if (property_info->is_name) { - /* Traditionally, the "name" property was not handled here. - * For the moment, skip it from get_property_val(). */ - } else if (property_info->property_type->describe_fcn) { + if (property_info->property_type->describe_fcn) { desc = property_info->property_type->describe_fcn (property_info, &desc_to_free); } else desc = property_info->describe_message; @@ -809,29 +791,12 @@ nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value) /*****************************************************************************/ -static NmcOutputField * -_dup_fields_array (const NMMetaSettingInfoEditor *setting_info, NmcOfFlags flags) -{ - NmcOutputField *row; - gsize l; - - l = setting_info->properties_num; - - row = g_malloc0 ((l + 1) * sizeof (NmcOutputField)); - for (l = 0; l < setting_info->properties_num; l++) - row[l].info = (const NMMetaAbstractInfo *) &setting_info->properties[l]; - row[0].flags = flags; - return row; -} - gboolean -setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop, gboolean show_secrets) +setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop) { const NMMetaSettingInfoEditor *setting_info; - NmcOutputField *arr; - guint i; - NMMetaAccessorGetType type = NM_META_ACCESSOR_GET_TYPE_PRETTY; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + gs_free_error GError *error = NULL; + gs_free char *fields_str = NULL; g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); @@ -839,36 +804,20 @@ setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *on if (!setting_info) return FALSE; - if (nmc_config->print_output == NMC_PRINT_TERSE) - type = NM_META_ACCESSOR_GET_TYPE_PARSABLE; - - out_indices = parse_output_fields (one_prop, - (const NMMetaAbstractInfo *const*) nm_property_infos_for_setting_type (setting_info->general->meta_type), - FALSE, NULL, NULL); - arr = _dup_fields_array (setting_info, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); - - arr = _dup_fields_array (setting_info, NMC_OF_FLAG_SECTION_PREFIX); - for (i = 0; i < setting_info->properties_num; i++) { - const NMMetaPropertyInfo *property_info = &setting_info->properties[i]; - - nm_assert (property_info->setting_info == setting_info); - - if (!property_info->is_secret || show_secrets) { - set_val_str (arr, i, property_info->property_type->get_fcn (&meta_environment, - NULL, - property_info, - setting, - type, - show_secrets ? NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS : 0)); - } else - set_val_str (arr, i, g_strdup (_(NM_META_TEXT_HIDDEN))); + if (one_prop) { + /* hack around setting-details being called for one setting. Must prefix the + * property name with the setting name. Later we should remove setting_details() + * and merge it into the caller. */ + fields_str = g_strdup_printf ("%s.%s", nm_setting_get_name (setting), one_prop); } - g_ptr_array_add (out.output_data, arr); - - print_data_prepare_width (out.output_data); - print_data (nmc_config, out_indices, NULL, 0, &out); + if (!nmc_print (nmc_config, + (gpointer[]) { setting, NULL }, + NULL, + (const NMMetaAbstractInfo *const[]) { (const NMMetaAbstractInfo *) setting_info, NULL }, + fields_str, + &error)) + return FALSE; return TRUE; } diff --git a/clients/cli/settings.h b/clients/cli/settings.h index 2a90753057..0125a78269 100644 --- a/clients/cli/settings.h +++ b/clients/cli/settings.h @@ -60,6 +60,6 @@ void nmc_property_set_default_value (NMSetting *setting, const char *prop); gboolean nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value); gboolean nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value); -gboolean setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop, gboolean secrets); +gboolean setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop); #endif /* NMC_SETTINGS_H */ diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 4368267dc6..84b90c0a10 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -834,7 +834,7 @@ _output_selection_select_one (const NMMetaAbstractInfo *const* fields_array, if (fi->meta_type == &nm_meta_type_setting_info_editor) { const NMMetaSettingInfoEditor *fi_s = &fi->as.setting_info; - for (j = 1; j < fi_s->properties_num; j++) { + for (j = 0; j < fi_s->properties_num; j++) { if (g_ascii_strcasecmp (right, fi_s->properties[j].property_name) == 0) { found = TRUE; break; @@ -1037,7 +1037,9 @@ _output_selection_append (GArray *cols, si, gfree_keeper, error)) return FALSE; } - g_array_index (cols, PrintDataCol, col_idx).is_leaf = FALSE; + + if (selection_item->info->meta_type != &nm_meta_type_setting_info_editor) + g_array_index (cols, PrintDataCol, col_idx).is_leaf = FALSE; } return TRUE; @@ -1282,6 +1284,7 @@ typedef struct { const PrintDataCol *col; bool is_nested; const char *title; + bool title_to_free:1; int width; } PrintDataHeaderCell; @@ -1297,6 +1300,13 @@ typedef struct { static void _print_data_header_cell_clear (gpointer cell_p) { + PrintDataHeaderCell *cell = cell_p; + + if (cell->title_to_free) { + g_free ((char *) cell->title); + cell->title_to_free = FALSE; + } + cell->title = NULL; } static void @@ -1331,6 +1341,7 @@ _print_fill (const NmcConfig *nmc_config, guint targets_len; gboolean pretty; NMMetaAccessorGetType text_get_type; + NMMetaAccessorGetFlags text_get_flags; pretty = (nmc_config->print_output != NMC_PRINT_TERSE); @@ -1341,11 +1352,15 @@ _print_fill (const NmcConfig *nmc_config, const PrintDataCol *col; PrintDataHeaderCell *header_cell; guint col_idx; + const NMMetaAbstractInfo *info; + gboolean translate_title; col = &cols[i_col]; if (!col->is_leaf) continue; + info = col->selection_item->info; + col_idx = header_row->len; g_array_set_size (header_row, col_idx + 1); @@ -1354,8 +1369,23 @@ _print_fill (const NmcConfig *nmc_config, header_cell->col_idx = col_idx; header_cell->col = col; header_cell->is_nested = FALSE; - header_cell->title = nm_meta_abstract_info_get_name (col->selection_item->info); - if (pretty) + + translate_title = pretty; + + if (info->meta_type == &nm_meta_type_property_info) { + header_cell->title = nm_meta_abstract_info_get_name (info); + if (nmc_config->multiline_output) { + header_cell->title = g_strdup_printf ("%s.%s", + ((const NMMetaPropertyInfo *) info)->setting_info->general->setting_name, + header_cell->title); + header_cell->title_to_free = TRUE; + } + } else if (info->meta_type == &nm_meta_type_setting_info_editor) + header_cell->title = N_("name"); + else + header_cell->title = nm_meta_abstract_info_get_name (info); + + if (translate_title) header_cell->title = _(header_cell->title); } @@ -1368,6 +1398,9 @@ _print_fill (const NmcConfig *nmc_config, text_get_type = pretty ? NM_META_ACCESSOR_GET_TYPE_PRETTY : NM_META_ACCESSOR_GET_TYPE_PARSABLE; + text_get_flags = NM_META_ACCESSOR_GET_FLAGS_NONE; + if (nmc_config->show_secrets) + text_get_flags |= NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS; for (i_row = 0; i_row < targets_len; i_row++) { gpointer target = targets[i_row]; @@ -1389,7 +1422,7 @@ _print_fill (const NmcConfig *nmc_config, NULL, target, text_get_type, - NM_META_ACCESSOR_GET_FLAGS_NONE, + text_get_flags, (gpointer *) &to_free); cell->text_to_free = !!to_free; @@ -1434,6 +1467,26 @@ _print_fill (const NmcConfig *nmc_config, *out_cells = cells; } +static gboolean +_print_skip_column (const NmcConfig *nmc_config, + const PrintDataHeaderCell *header_cell) +{ + if (nmc_config->multiline_output) { + if (header_cell->col->selection_item->info->meta_type == &nm_meta_type_setting_info_editor) { + /* we skip the "name" entry for the setting in multiline output. */ + return TRUE; + } + } else { + if ( header_cell->col->selection_item->info->meta_type == &nm_meta_type_setting_info_editor + && header_cell->col->selection_item->sub_selection) { + /* in tabular form, we skip the "name" entry for sections that have sub-selections. + * That is, for "ipv4.may-fail", but not for "ipv4". */ + return TRUE; + } + } + return FALSE; +} + static void _print_do (const NmcConfig *nmc_config, const char *header_name_no_l10n, @@ -1453,7 +1506,7 @@ _print_do (const NmcConfig *nmc_config, g_assert (col_len && row_len); /* Main header */ - if (pretty) { + if (pretty && header_name_no_l10n) { gs_free char *line = NULL; int header_width; const char *header_name = _(header_name_no_l10n); @@ -1485,6 +1538,9 @@ _print_do (const NmcConfig *nmc_config, const PrintDataHeaderCell *header_cell = &header_row[i_col]; const char *title; + if (_print_skip_column (nmc_config, header_cell)) + continue; + title = header_cell->title; width1 = strlen (title); @@ -1515,6 +1571,9 @@ _print_do (const NmcConfig *nmc_config, gs_free char *text_to_free = NULL; const char *text; + if (_print_skip_column (nmc_config, cell->header_cell)) + continue; + if (cell->header_cell->is_nested) { g_assert_not_reached (/*TODO*/); } else { @@ -1522,7 +1581,6 @@ _print_do (const NmcConfig *nmc_config, cell->term_color, cell->term_format, cell->text, &text_to_free); } - if (multiline) { gs_free char *prefix = NULL; diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 1af0dbad8d..1ba417a4e0 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -518,13 +518,6 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free -static char * -_get_fcn_name (ARGS_GET_FCN) -{ - nm_assert (nm_streq0 (nm_setting_get_name (setting), property_info->setting_info->general->setting_name)); - return g_strdup (property_info->setting_info->general->setting_name); -} - static char * _get_fcn_nmc_with_default (ARGS_GET_FCN) { @@ -4473,10 +4466,6 @@ _set_fcn_wireless_security_psk (ARGS_SET_FCN) PROPERTY_TYP_DATA_SUBTYPE (stype, __VA_ARGS__), \ ) -static const NMMetaPropertyType _pt_name = { - .get_fcn = _get_fcn_name, -}; - static const NMMetaPropertyType _pt_gobject_readonly = { .get_fcn = _get_fcn_gobject, }; @@ -4533,18 +4522,6 @@ static const NMMetaPropertyType _pt_gobject_enum = { /*****************************************************************************/ -/* FIXME: it is wrong to have a property-type "name". The name is a regular - * "property" of the setting. Also, this is redundant to the setting_name - * in NMMetaSettingInfo. */ -#define PROPERTY_INFO_NAME() \ - { \ - .meta_type = &nm_meta_type_property_info, \ - .setting_info = &nm_meta_setting_infos_editor[_CURRENT_NM_META_SETTING_TYPE], \ - .property_name = N_ ("name"), \ - .is_name = TRUE, \ - .property_type = &_pt_name, \ - } - #define PROPERTY_INFO(name, doc) \ .meta_type = &nm_meta_type_property_info, \ .setting_info = &nm_meta_setting_infos_editor[_CURRENT_NM_META_SETTING_TYPE], \ @@ -4578,7 +4555,6 @@ static const NMMetaPropertyType _pt_gobject_enum = { #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_802_1X static const NMMetaPropertyInfo property_infos_802_1X[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_EAP), .property_type = DEFINE_PROPERTY_TYPE ( @@ -4866,7 +4842,6 @@ static const NMMetaPropertyInfo property_infos_802_1X[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ADSL static const NMMetaPropertyInfo property_infos_ADSL[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_USERNAME), .property_type = &_pt_gobject_string, @@ -4910,7 +4885,6 @@ static const NMMetaPropertyInfo property_infos_ADSL[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BLUETOOTH static const NMMetaPropertyInfo property_infos_BLUETOOTH[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_BDADDR), .property_type = &_pt_gobject_mac, @@ -4928,7 +4902,6 @@ static const NMMetaPropertyInfo property_infos_BLUETOOTH[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BOND static const NMMetaPropertyInfo property_infos_BOND[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_BOND_OPTIONS), .property_type = DEFINE_PROPERTY_TYPE ( @@ -4944,7 +4917,6 @@ static const NMMetaPropertyInfo property_infos_BOND[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BRIDGE static const NMMetaPropertyInfo property_infos_BRIDGE[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MAC_ADDRESS), .property_type = &_pt_gobject_mac, @@ -4982,7 +4954,6 @@ static const NMMetaPropertyInfo property_infos_BRIDGE[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BRIDGE_PORT static const NMMetaPropertyInfo property_infos_BRIDGE_PORT[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_PRIORITY), .property_type = &_pt_gobject_uint, @@ -5000,7 +4971,6 @@ static const NMMetaPropertyInfo property_infos_BRIDGE_PORT[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_CDMA static const NMMetaPropertyInfo property_infos_CDMA[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_NUMBER), .property_type = &_pt_gobject_string, @@ -5030,7 +5000,6 @@ static const NMMetaPropertyInfo property_infos_CDMA[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_CONNECTION static const NMMetaPropertyInfo property_infos_CONNECTION[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_ID), .property_type = &_pt_gobject_string, @@ -5177,7 +5146,6 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_DCB static const NMMetaPropertyInfo property_infos_DCB[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_FLAGS), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5286,16 +5254,9 @@ static const NMMetaPropertyInfo property_infos_DCB[] = { }, }; -#undef _CURRENT_NM_META_SETTING_TYPE -#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_DUMMY -static const NMMetaPropertyInfo property_infos_DUMMY[] = { - PROPERTY_INFO_NAME(), -}; - #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GSM static const NMMetaPropertyInfo property_infos_GSM[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_NUMBER), .property_type = &_pt_gobject_string, @@ -5361,7 +5322,6 @@ static const NMMetaPropertyInfo property_infos_GSM[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_INFINIBAND static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_MAC_ADDRESS), .property_type = &_pt_gobject_mac, @@ -5402,7 +5362,6 @@ static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP4_CONFIG static const NMMetaPropertyInfo property_infos_IP4_CONFIG[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_METHOD), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5535,7 +5494,6 @@ static const NMMetaPropertyInfo property_infos_IP4_CONFIG[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP6_CONFIG static const NMMetaPropertyInfo property_infos_IP6_CONFIG[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_METHOD), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5677,7 +5635,6 @@ static const NMMetaPropertyInfo property_infos_IP6_CONFIG[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP_TUNNEL static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_MODE), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5740,7 +5697,6 @@ static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MACSEC static const NMMetaPropertyInfo property_infos_MACSEC[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PARENT), .property_type = &_pt_gobject_string, @@ -5793,7 +5749,6 @@ static const NMMetaPropertyInfo property_infos_MACSEC[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MACVLAN static const NMMetaPropertyInfo property_infos_MACVLAN[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_PARENT), .property_type = &_pt_gobject_string, @@ -5824,7 +5779,6 @@ static const NMMetaPropertyInfo property_infos_MACVLAN[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OLPC_MESH static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_SSID), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5848,7 +5802,6 @@ static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPPOE static const NMMetaPropertyInfo property_infos_PPPOE[] = { - PROPERTY_INFO_NAME (), { PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_SERVICE), .property_type = &_pt_gobject_string, @@ -5871,7 +5824,6 @@ static const NMMetaPropertyInfo property_infos_PPPOE[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPP static const NMMetaPropertyInfo property_infos_PPP[] = { - PROPERTY_INFO_NAME (), { PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_NOAUTH), .property_type = &_pt_gobject_bool, @@ -5952,7 +5904,6 @@ static const NMMetaPropertyInfo property_infos_PPP[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PROXY static const NMMetaPropertyInfo property_infos_PROXY[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_METHOD), .property_type = DEFINE_PROPERTY_TYPE ( @@ -5986,7 +5937,6 @@ static const NMMetaPropertyInfo property_infos_PROXY[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TEAM static const NMMetaPropertyInfo property_infos_TEAM[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_CONFIG), .describe_message = N_ (TEAM_DESCRIBE_MESSAGE), @@ -6000,7 +5950,6 @@ static const NMMetaPropertyInfo property_infos_TEAM[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TEAM_PORT static const NMMetaPropertyInfo property_infos_TEAM_PORT[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_CONFIG), .describe_message = N_ (TEAM_DESCRIBE_MESSAGE), @@ -6014,7 +5963,6 @@ static const NMMetaPropertyInfo property_infos_TEAM_PORT[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_SERIAL static const NMMetaPropertyInfo property_infos_SERIAL[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_BAUD), .property_type = &_pt_gobject_uint, @@ -6043,7 +5991,6 @@ static const NMMetaPropertyInfo property_infos_SERIAL[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TUN static const NMMetaPropertyInfo property_infos_TUN[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_MODE), .property_type = DEFINE_PROPERTY_TYPE ( @@ -6076,16 +6023,9 @@ static const NMMetaPropertyInfo property_infos_TUN[] = { }, }; -#undef _CURRENT_NM_META_SETTING_TYPE -#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_USER -static const NMMetaPropertyInfo property_infos_USER[] = { - PROPERTY_INFO_NAME(), -}; - #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VLAN static const NMMetaPropertyInfo property_infos_VLAN[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_PARENT), .property_type = &_pt_gobject_string, @@ -6122,7 +6062,6 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VPN static const NMMetaPropertyInfo property_infos_VPN[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SERVICE_TYPE), .property_type = DEFINE_PROPERTY_TYPE ( @@ -6164,7 +6103,6 @@ static const NMMetaPropertyInfo property_infos_VPN[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VXLAN static const NMMetaPropertyInfo property_infos_VXLAN[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_PARENT), .property_type = &_pt_gobject_string, @@ -6234,7 +6172,6 @@ static const NMMetaPropertyInfo property_infos_VXLAN[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIMAX static const NMMetaPropertyInfo property_infos_WIMAX[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIMAX_MAC_ADDRESS), .property_type = &_pt_gobject_string, @@ -6248,7 +6185,6 @@ static const NMMetaPropertyInfo property_infos_WIMAX[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRED static const NMMetaPropertyInfo property_infos_WIRED[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_PORT), /* Do not allow setting 'port' for now. It is not implemented in @@ -6345,7 +6281,6 @@ static const NMMetaPropertyInfo property_infos_WIRED[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRELESS static const NMMetaPropertyInfo property_infos_WIRELESS[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SSID), .property_type = DEFINE_PROPERTY_TYPE ( @@ -6450,7 +6385,6 @@ static const NMMetaPropertyInfo property_infos_WIRELESS[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRELESS_SECURITY static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { - PROPERTY_INFO_NAME(), { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), .property_type = &_pt_gobject_string, @@ -6576,6 +6510,11 @@ static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { }; const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { +#define SETTING_INFO_EMPTY(type) \ + [NM_META_SETTING_TYPE_##type] = { \ + .meta_type = &nm_meta_type_setting_info_editor, \ + .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ + } #define SETTING_INFO(type) \ [NM_META_SETTING_TYPE_##type] = { \ .meta_type = &nm_meta_type_setting_info_editor, \ @@ -6592,7 +6531,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { SETTING_INFO (CDMA), SETTING_INFO (CONNECTION), SETTING_INFO (DCB), - SETTING_INFO (DUMMY), + SETTING_INFO_EMPTY (DUMMY), SETTING_INFO (GSM), SETTING_INFO (INFINIBAND), SETTING_INFO (IP4_CONFIG), @@ -6608,7 +6547,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { SETTING_INFO (TEAM), SETTING_INFO (TEAM_PORT), SETTING_INFO (TUN), - SETTING_INFO (USER), + SETTING_INFO_EMPTY (USER), SETTING_INFO (VLAN), SETTING_INFO (VPN), SETTING_INFO (VXLAN), @@ -6641,8 +6580,20 @@ _meta_type_setting_info_editor_get_fcn (const NMMetaEnvironment *environment, NMMetaAccessorGetFlags get_flags, gpointer *out_to_free) { - nm_assert (out_to_free && !*out_to_free); - g_return_val_if_reached (NULL); + const NMMetaSettingInfoEditor *info = (const NMMetaSettingInfoEditor *) abstract_info; + + nm_assert (!out_to_free || !*out_to_free); + + if (!NM_IN_SET (get_type, + NM_META_ACCESSOR_GET_TYPE_PARSABLE, + NM_META_ACCESSOR_GET_TYPE_PRETTY)) + return NULL; + + nm_assert (out_to_free); + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(info->general->setting_name); + return info->general->setting_name; } static gconstpointer @@ -6656,13 +6607,22 @@ _meta_type_property_info_get_fcn (const NMMetaEnvironment *environment, { const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; - nm_assert (out_to_free && !*out_to_free); + nm_assert (!out_to_free || !*out_to_free); if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY)) return NULL; + nm_assert (out_to_free); + + if ( info->is_secret + && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) { + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(NM_META_TEXT_HIDDEN); + return NM_META_TEXT_HIDDEN; + } + return (*out_to_free = info->property_type->get_fcn (environment, environment_user_data, info, target, get_type, get_flags)); diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 73e773b4de..6f582949f7 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -167,12 +167,6 @@ struct _NMMetaPropertyInfo { const char *property_name; - /* the property list for now must contain as first field the - * "name", which isn't a regular property. This is required by - * NmcOutputField and this first field is ignored for the - * group_list/setting_info. */ - bool is_name:1; - bool is_secret:1; const char *describe_doc; diff --git a/clients/common/tests/test-general.c b/clients/common/tests/test-general.c index 469dc57a73..b66262e8de 100644 --- a/clients/common/tests/test-general.c +++ b/clients/common/tests/test-general.c @@ -85,11 +85,6 @@ test_client_meta_check (void) g_assert (pi->property_name == pi->meta_type->get_name ((const NMMetaAbstractInfo *) pi)); - if (pi->is_name) - g_assert (p == 0); - else - g_assert (p != 0); - g_assert (pi->property_type); g_assert (pi->property_type->get_fcn); } From 16299e5ac0a8882e13d42122278013b74bc6d34d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:14:23 +0200 Subject: [PATCH 10/32] cli: use nmc_print() to output `nmcli general permissions` Add also colors for the output values. --- clients/cli/general.c | 219 ++++++++++++++++++++++-------------------- clients/cli/utils.c | 4 +- clients/cli/utils.h | 6 ++ 3 files changed, 125 insertions(+), 104 deletions(-) diff --git a/clients/cli/general.c b/clients/cli/general.c index 82f878b692..d94512ea4e 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -106,6 +106,67 @@ connectivity_to_color (NMConnectivityState connectivity) } } +static const char * +permission_to_string (NMClientPermission perm) +{ + switch (perm) { + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX; + case NM_CLIENT_PERMISSION_SLEEP_WAKE: + return NM_AUTH_PERMISSION_SLEEP_WAKE; + case NM_CLIENT_PERMISSION_NETWORK_CONTROL: + return NM_AUTH_PERMISSION_NETWORK_CONTROL; + case NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: + return NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED; + case NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: + return NM_AUTH_PERMISSION_WIFI_SHARE_OPEN; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS; + case NM_CLIENT_PERMISSION_RELOAD: + return NM_AUTH_PERMISSION_RELOAD; + case NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK: + return NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS; + default: + return _("unknown"); + } +} + +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (permission_result_to_string_no_l10n, NMClientPermissionResult, + NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_YES, N_("yes")), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_NO, N_("no")), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_AUTH, N_("auth")), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CLIENT_PERMISSION_RESULT_UNKNOWN), +); + +_NM_UTILS_LOOKUP_DEFINE (static, permission_result_to_color, NMClientPermissionResult, NMMetaTermColor, + NM_UTILS_LOOKUP_DEFAULT (NM_META_TERM_COLOR_NORMAL), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_YES, NM_META_TERM_COLOR_GREEN), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_NO, NM_META_TERM_COLOR_RED), + NM_UTILS_LOOKUP_ITEM (NM_CLIENT_PERMISSION_RESULT_AUTH, NM_META_TERM_COLOR_YELLOW), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CLIENT_PERMISSION_RESULT_UNKNOWN), +); + +#define HANDLE_TERMFORMAT(color) \ + G_STMT_START { \ + if (get_type == NM_META_ACCESSOR_GET_TYPE_TERMFORMAT) \ + return nm_meta_termformat_pack ((color), NM_META_TERM_FORMAT_NORMAL); \ + } G_STMT_END + /*****************************************************************************/ static const NmcMetaGenericInfo *const metagen_general_status[]; @@ -125,12 +186,6 @@ _metagen_general_status_get_fcn (const NMMetaEnvironment *environment, NMState state; NMConnectivityState connectivity; -#define HANDLE_TERMFORMAT(color) \ - G_STMT_START { \ - if (get_type == NM_META_ACCESSOR_GET_TYPE_TERMFORMAT) \ - return nm_meta_termformat_pack ((color), NM_META_TERM_FORMAT_NORMAL); \ - } G_STMT_END - switch (info->info_type) { case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING: HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); @@ -220,15 +275,48 @@ static const NmcMetaGenericInfo *const metagen_general_status[_NMC_GENERIC_INFO_ #define NMC_FIELDS_NM_WIMAX "WIMAX" #define NMC_FIELDS_NM_CONNECTIVITY "CONNECTIVITY" +/*****************************************************************************/ -/* Available fields for 'general permissions' */ -static const NmcMetaGenericInfo *const nmc_fields_nm_permissions[] = { - NMC_META_GENERIC ("PERMISSION"), /* 0 */ - NMC_META_GENERIC ("VALUE"), /* 1 */ - NULL, +static gconstpointer +_metagen_general_permissions_get_fcn (const NMMetaEnvironment *environment, + gpointer environment_user_data, + const NmcMetaGenericInfo *info, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + gpointer *out_to_free) +{ + NMClientPermission perm = GPOINTER_TO_UINT (target); + NmCli *nmc = environment_user_data; + NMClientPermissionResult perm_result; + const char *s; + + switch (info->info_type) { + case NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_PERMISSION: + HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + return permission_to_string (perm); + case NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_VALUE: + perm_result = nm_client_get_permission_result (nmc->client, perm); + HANDLE_TERMFORMAT (permission_result_to_color (perm_result)); + s = permission_result_to_string_no_l10n (perm_result); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(s); + return s; + default: + break; + } + + g_return_val_if_reached (NULL); +} + +static const NmcMetaGenericInfo *const metagen_general_permissions[_NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_NUM + 1] = { +#define _METAGEN_GENERAL_PERMISSIONS(type, name) \ + [type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_general_permissions_get_fcn) + _METAGEN_GENERAL_PERMISSIONS (NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_PERMISSION, "PERMISSION"), + _METAGEN_GENERAL_PERMISSIONS (NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_VALUE, "VALUE"), }; -#define NMC_FIELDS_NM_PERMISSIONS_ALL "PERMISSION,VALUE" -#define NMC_FIELDS_NM_PERMISSIONS_COMMON "PERMISSION,VALUE" + +/*****************************************************************************/ /* Available fields for 'general logging' */ static const NmcMetaGenericInfo *const nmc_fields_nm_logging[] = { @@ -429,60 +517,6 @@ do_general_status (NmCli *nmc, int argc, char **argv) return nmc->return_value; } -static const char * -permission_to_string (NMClientPermission perm) -{ - switch (perm) { - case NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: - return NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK; - case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: - return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI; - case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: - return NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN; - case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: - return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX; - case NM_CLIENT_PERMISSION_SLEEP_WAKE: - return NM_AUTH_PERMISSION_SLEEP_WAKE; - case NM_CLIENT_PERMISSION_NETWORK_CONTROL: - return NM_AUTH_PERMISSION_NETWORK_CONTROL; - case NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: - return NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED; - case NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: - return NM_AUTH_PERMISSION_WIFI_SHARE_OPEN; - case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; - case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME; - case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS: - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS; - case NM_CLIENT_PERMISSION_RELOAD: - return NM_AUTH_PERMISSION_RELOAD; - case NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK: - return NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK; - case NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS: - return NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS; - default: - return _("unknown"); - } -} - -static const char * -permission_result_to_string (NMClientPermissionResult perm_result) -{ - switch (perm_result) { - case NM_CLIENT_PERMISSION_RESULT_YES: - return _("yes"); - case NM_CLIENT_PERMISSION_RESULT_NO: - return _("no"); - case NM_CLIENT_PERMISSION_RESULT_AUTH: - return _("auth"); - default: - return _("unknown"); - } -} - static gboolean timeout_cb (gpointer user_data) { @@ -498,50 +532,31 @@ static int print_permissions (void *user_data) { NmCli *nmc = user_data; + gs_free_error GError *error = NULL; + const char *fields_str = NULL; NMClientPermission perm; - GError *error = NULL; - const char *fields_str; - const char *fields_all = NMC_FIELDS_NM_PERMISSIONS_ALL; - const char *fields_common = NMC_FIELDS_NM_PERMISSIONS_COMMON; - const NMMetaAbstractInfo *const*tmpl; - NmcOutputField *arr; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + guint i; + gpointer permissions[NM_CLIENT_PERMISSION_LAST + 1]; - if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) - fields_str = fields_common; - else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) - fields_str = fields_all; - else + if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) { + } else if (strcasecmp (nmc->required_fields, "all") == 0) { + } else fields_str = nmc->required_fields; - tmpl = (const NMMetaAbstractInfo *const*) nmc_fields_nm_permissions; - out_indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); + for (i = 0, perm = NM_CLIENT_PERMISSION_NONE + 1; perm <= NM_CLIENT_PERMISSION_LAST; perm++) + permissions[i++] = GINT_TO_POINTER (perm); + permissions[i++] = NULL; - if (error) { + if (!nmc_print (&nmc->nmc_config, + permissions, + _("NetworkManager permissions"), + (const NMMetaAbstractInfo *const*) metagen_general_permissions, + fields_str, + &error)) { 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; } - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); - - - for (perm = NM_CLIENT_PERMISSION_NONE + 1; perm <= NM_CLIENT_PERMISSION_LAST; perm++) { - NMClientPermissionResult perm_result = nm_client_get_permission_result (nmc->client, perm); - - arr = nmc_dup_fields_array (tmpl, 0); - set_val_strc (arr, 0, permission_to_string (perm)); - set_val_strc (arr, 1, permission_result_to_string (perm_result)); - g_ptr_array_add (out.output_data, arr); - } - print_data_prepare_width (out.output_data); - print_data (&nmc->nmc_config, - out_indices, - _("NetworkManager permissions"), - 0, &out); - quit (); return G_SOURCE_REMOVE; } diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 84b90c0a10..fab1cc0fb1 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -1419,7 +1419,7 @@ _print_fill (const NmcConfig *nmc_config, cell->header_cell = header_cell; cell->text = nm_meta_abstract_info_get (info, NULL, - NULL, + &nm_cli, target, text_get_type, text_get_flags, @@ -1428,7 +1428,7 @@ _print_fill (const NmcConfig *nmc_config, nm_meta_termformat_unpack (nm_meta_abstract_info_get (info, NULL, - NULL, + &nm_cli, target, NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, NM_META_ACCESSOR_GET_FLAGS_NONE, diff --git a/clients/cli/utils.h b/clients/cli/utils.h index 1a4c796539..adc7bc4368 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -104,6 +104,7 @@ void print_data (const NmcConfig *nmc_config, /*****************************************************************************/ typedef enum { + NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING = 0, NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_VERSION, NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STATE, @@ -117,6 +118,11 @@ typedef enum { NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX_HW, NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_WIMAX, _NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NUM, + + NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_PERMISSION = 0, + NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_VALUE, + _NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_NUM, + } NmcGenericInfoType; struct _NmcMetaGenericInfo { From 03307e3dd6638e77009517824c9ad3b24c7feeb4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:14:23 +0200 Subject: [PATCH 11/32] cli: use nmc_print() to output `nmcli general logging` --- clients/cli/general.c | 114 +++++++++++++++++++++++------------------- clients/cli/utils.h | 4 ++ 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/clients/cli/general.c b/clients/cli/general.c index d94512ea4e..fc819f79a0 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -318,15 +318,51 @@ static const NmcMetaGenericInfo *const metagen_general_permissions[_NMC_GENERIC_ /*****************************************************************************/ -/* Available fields for 'general logging' */ -static const NmcMetaGenericInfo *const nmc_fields_nm_logging[] = { - NMC_META_GENERIC ("LEVEL"), /* 0 */ - NMC_META_GENERIC ("DOMAINS"), /* 1 */ - NULL, -}; -#define NMC_FIELDS_NM_LOGGING_ALL "LEVEL,DOMAINS" -#define NMC_FIELDS_NM_LOGGING_COMMON "LEVEL,DOMAINS" +typedef struct { + bool initialized; + char **level; + char **domains; +} GetGeneralLoggingData; +static gconstpointer +_metagen_general_logging_get_fcn (const NMMetaEnvironment *environment, + gpointer environment_user_data, + const NmcMetaGenericInfo *info, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + gpointer *out_to_free) +{ + NmCli *nmc = environment_user_data; + GetGeneralLoggingData *d = target; + + nm_assert (info->info_type < _NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_NUM); + + HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + + if (!d->initialized) { + d->initialized = TRUE; + if (!nm_client_get_logging (nmc->client, + d->level, + d->domains, + NULL)) + return NULL; + } + + if (info->info_type == NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_LEVEL) + return *d->level; + else + return *d->domains; +} + +static const NmcMetaGenericInfo *const metagen_general_logging[_NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_NUM + 1] = { +#define _METAGEN_GENERAL_LOGGING(type, name) \ + [type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_general_logging_get_fcn) + _METAGEN_GENERAL_LOGGING (NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_LEVEL, "LEVEL"), + _METAGEN_GENERAL_LOGGING (NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_DOMAINS, "DOMAINS"), +}; + +/*****************************************************************************/ /* glib main loop variable - defined in nmcli.c */ extern GMainLoop *loop; @@ -622,58 +658,32 @@ do_general_permissions (NmCli *nmc, int argc, char **argv) return nmc->return_value; } -static gboolean +static void show_general_logging (NmCli *nmc) { - char *level = NULL; - char *domains = NULL; - GError *error = NULL; - const char *fields_str; - const char *fields_all = NMC_FIELDS_NM_LOGGING_ALL; - const char *fields_common = NMC_FIELDS_NM_LOGGING_COMMON; - const NMMetaAbstractInfo *const*tmpl; - NmcOutputField *arr; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + gs_free char *level_cache = NULL; + gs_free char *domains_cache = NULL; + gs_free GError *error = NULL; + const char *fields_str = NULL; + GetGeneralLoggingData d = { + .level = &level_cache, + .domains = &domains_cache, + }; - if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) - fields_str = fields_common; - else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) - fields_str = fields_all; - else + if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) { + } else if (strcasecmp (nmc->required_fields, "all") == 0) { + } else fields_str = nmc->required_fields; - tmpl = (const NMMetaAbstractInfo *const*) nmc_fields_nm_logging; - out_indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &error); - - if (error) { + if (!nmc_print (&nmc->nmc_config, + (gpointer const []) { &d, NULL }, + _("NetworkManager logging"), + (const NMMetaAbstractInfo *const*) metagen_general_logging, + fields_str, + &error)) { 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; } - - nm_client_get_logging (nmc->client, &level, &domains, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: %s."), error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_error_free (error); - return FALSE; - } - - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); - - arr = nmc_dup_fields_array (tmpl, 0); - set_val_str (arr, 0, level); - set_val_str (arr, 1, domains); - g_ptr_array_add (out.output_data, arr); - - print_data_prepare_width (out.output_data); - print_data (&nmc->nmc_config, out_indices, - _("NetworkManager logging"), - 0, &out); - - return TRUE; } static void diff --git a/clients/cli/utils.h b/clients/cli/utils.h index adc7bc4368..cbed4a16fd 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -123,6 +123,10 @@ typedef enum { NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_VALUE, _NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_NUM, + NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_LEVEL = 0, + NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_DOMAINS, + _NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_NUM, + } NmcGenericInfoType; struct _NmcMetaGenericInfo { From c5c48d4f5f4a071a31198cd43a8a7355e5d3e782 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 19:39:36 +0200 Subject: [PATCH 12/32] cli: move global "loop" variable to nmcli.h header --- clients/cli/common.c | 4 ---- clients/cli/connections.c | 6 +----- clients/cli/devices.c | 6 +----- clients/cli/general.c | 7 +------ clients/cli/nmcli.h | 2 ++ 5 files changed, 5 insertions(+), 20 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index a85d47687b..6209b15d8f 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -36,8 +36,6 @@ #include "utils.h" -extern GMainLoop *loop; - const NmcMetaGenericInfo *const nmc_fields_ip4_config[] = { NMC_META_GENERIC ("GROUP"), /* 0 */ NMC_META_GENERIC ("ADDRESS"), /* 1 */ @@ -1170,8 +1168,6 @@ nmc_parse_lldp_capabilities (guint value) return g_string_free (str, FALSE); } -extern GMainLoop *loop; - static void command_done (GObject *object, GAsyncResult *res, gpointer user_data) { diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 72eb0f8fd3..c0661c9c41 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -227,9 +227,6 @@ const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = { #define CON_SHOW_DETAIL_GROUP_PROFILE "profile" #define CON_SHOW_DETAIL_GROUP_ACTIVE "active" -/* glib main loop variable - defined in nmcli.c */ -extern GMainLoop *loop; - static guint progress_id = 0; /* ID of event source for displaying progress */ /* for readline TAB completion in editor */ @@ -571,7 +568,6 @@ nmc_setting_new_for_name (const char *name) return setting; } -/* quit main loop */ static void quit (void) { @@ -581,7 +577,7 @@ quit (void) nmc_terminal_erase_line (); } - g_main_loop_quit (loop); /* quit main loop */ + g_main_loop_quit (loop); } static char * diff --git a/clients/cli/devices.c b/clients/cli/devices.c index aa0ff083f4..8d8457520a 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -245,9 +245,6 @@ const NmcMetaGenericInfo *const nmc_fields_dev_lldp_list[] = { #define NMC_FIELDS_DEV_LLDP_LIST_COMMON "DEVICE,CHASSIS-ID,PORT-ID,PORT-DESCRIPTION,SYSTEM-NAME,SYSTEM-DESCRIPTION," \ "SYSTEM-CAPABILITIES" -/* glib main loop variable - defined in nmcli.c */ -extern GMainLoop *loop; - static guint progress_id = 0; /* ID of event source for displaying progress */ static void @@ -450,7 +447,6 @@ usage_device_lldp (void) "used to list neighbors for a particular interface.\n\n")); } -/* quit main loop */ static void quit (void) { @@ -459,7 +455,7 @@ quit (void) nmc_terminal_erase_line (); } - g_main_loop_quit (loop); /* quit main loop */ + g_main_loop_quit (loop); } static int diff --git a/clients/cli/general.c b/clients/cli/general.c index fc819f79a0..1a32086e08 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -364,10 +364,6 @@ static const NmcMetaGenericInfo *const metagen_general_logging[_NMC_GENERIC_INFO /*****************************************************************************/ -/* glib main loop variable - defined in nmcli.c */ -extern GMainLoop *loop; - - static void usage_general (void) { @@ -507,11 +503,10 @@ usage_monitor (void) "Prints a line whenever a change occurs in NetworkManager\n\n")); } -/* quit main loop */ static void quit (void) { - g_main_loop_quit (loop); /* quit main loop */ + g_main_loop_quit (loop); } static gboolean diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 3e73e5105c..7203b21c8e 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -155,6 +155,8 @@ extern NmCli nm_cli; #define NMCLI_ERROR (nmcli_error_quark ()) GQuark nmcli_error_quark (void); +extern GMainLoop *loop; + gboolean nmc_seen_sigint (void); void nmc_clear_sigint (void); void nmc_set_sigquit_internal (void); From 41b31051f2b99535dfeac064f718c51fd7941d05 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Apr 2017 15:14:23 +0200 Subject: [PATCH 13/32] cli: use nmc_print() to output device's IP4 info The IP4 info adds a new type: to expose strv arguments for addresses, etc. --- clients/cli/common.c | 205 ++++++++++------- clients/cli/common.h | 4 +- clients/cli/connections.c | 4 +- clients/cli/devices.c | 4 +- clients/cli/general.c | 27 +-- clients/cli/nmcli.c | 2 +- clients/cli/utils.c | 282 ++++++++++++++++-------- clients/cli/utils.h | 20 +- clients/common/nm-meta-setting-access.c | 9 +- clients/common/nm-meta-setting-access.h | 3 +- clients/common/nm-meta-setting-desc.c | 10 +- clients/common/nm-meta-setting-desc.h | 11 +- clients/common/tests/test-general.c | 9 +- 13 files changed, 384 insertions(+), 206 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index 6209b15d8f..8738cef7b6 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -36,17 +36,122 @@ #include "utils.h" -const NmcMetaGenericInfo *const nmc_fields_ip4_config[] = { - NMC_META_GENERIC ("GROUP"), /* 0 */ - NMC_META_GENERIC ("ADDRESS"), /* 1 */ - NMC_META_GENERIC ("GATEWAY"), /* 2 */ - NMC_META_GENERIC ("ROUTE"), /* 3 */ - NMC_META_GENERIC ("DNS"), /* 4 */ - NMC_META_GENERIC ("DOMAIN"), /* 5 */ - NMC_META_GENERIC ("WINS"), /* 6 */ +/*****************************************************************************/ + +static gconstpointer +_metagen_ip4_config_get_fcn (const NMMetaEnvironment *environment, + gpointer environment_user_data, + const NmcMetaGenericInfo *info, + gpointer target, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gpointer *out_to_free) +{ + NMIPConfig *cfg4 = target; + GPtrArray *ptr_array; + char **arr; + const char *const*arrc; + guint i = 0; + + nm_assert (info->info_type < _NMC_GENERIC_INFO_TYPE_IP4_CONFIG_NUM); + + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + + switch (info->info_type) { + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ADDRESS: + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV)) + return NULL; + ptr_array = nm_ip_config_get_addresses (cfg4); + if (ptr_array) { + arr = g_new (char *, ptr_array->len + 1); + for (i = 0; i < ptr_array->len; i++) { + NMIPAddress *addr = g_ptr_array_index (ptr_array, i); + + arr[i] = g_strdup_printf ("%s/%u", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); + } + arr[i] = NULL; + } else + arr = NULL; + goto arr_out; + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_GATEWAY: + return nm_ip_config_get_gateway (cfg4); + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ROUTE: + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV)) + return NULL; + ptr_array = nm_ip_config_get_routes (cfg4); + if (ptr_array) { + arr = g_new (char *, ptr_array->len + 1); + for (i = 0; i < ptr_array->len; i++) { + NMIPRoute *route = g_ptr_array_index (ptr_array, i); + const char *next_hop; + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "0.0.0.0"; + + arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s%c mt = %u", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop, + nm_ip_route_get_metric (route) == -1 ? '\0' : ',', + (guint32) nm_ip_route_get_metric (route)); + } + arr[i] = NULL; + } else + arr = NULL; + goto arr_out; + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DNS: + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV)) + return NULL; + arrc = nm_ip_config_get_nameservers (cfg4); + goto arrc_out; + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DOMAIN: + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV)) + return NULL; + arrc = nm_ip_config_get_domains (cfg4); + goto arrc_out; + case NMC_GENERIC_INFO_TYPE_IP4_CONFIG_WINS: + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV)) + return NULL; + arrc = nm_ip_config_get_wins_servers (cfg4); + goto arrc_out; + default: + break; + } + + g_return_val_if_reached (NULL); + +arrc_out: + *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_STRV; + return arrc; + +arr_out: + *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_STRV; + *out_to_free = arr; + return arr; +} + +const NmcMetaGenericInfo *const metagen_ip4_config[_NMC_GENERIC_INFO_TYPE_IP4_CONFIG_NUM + 1] = { +#define _METAGEN_IP4_CONFIG(type, name) \ + [type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_ip4_config_get_fcn) + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ADDRESS, "ADDRESS"), + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_GATEWAY, "GATEWAY"), + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ROUTE, "ROUTE"), + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DNS, "DNS"), + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DOMAIN, "DOMAIN"), + _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_WINS, "WINS"), +}; + +static const NmcMetaGenericInfo *const metagen_ip4_config_group[] = { + NMC_META_GENERIC_WITH_NESTED ("IP4", metagen_ip4_config, .name_header = N_("GROUP")), NULL, }; +/*****************************************************************************/ + const NmcMetaGenericInfo *const nmc_fields_dhcp4_config[] = { NMC_META_GENERIC ("GROUP"), /* 0 */ NMC_META_GENERIC ("OPTION"), /* 1 */ @@ -72,87 +177,25 @@ const NmcMetaGenericInfo *const nmc_fields_dhcp6_config[] = { gboolean print_ip4_config (NMIPConfig *cfg4, const NmcConfig *nmc_config, - const char *group_prefix, const char *one_field) { - GPtrArray *ptr_array; - char **addr_arr = NULL; - char **route_arr = NULL; - char **dns_arr = NULL; - char **domain_arr = NULL; - char **wins_arr = NULL; - int i = 0; - const NMMetaAbstractInfo *const*tmpl; - NmcOutputField *arr; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + gs_free_error GError *error = NULL; + gs_free char *field_str = NULL; if (cfg4 == NULL) return FALSE; - tmpl = (const NMMetaAbstractInfo *const*) nmc_fields_ip4_config; - out_indices = parse_output_fields (one_field, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); + if (one_field) + field_str = g_strdup_printf ("IP4.%s", one_field); - /* addresses */ - ptr_array = nm_ip_config_get_addresses (cfg4); - if (ptr_array) { - addr_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) { - NMIPAddress *addr = (NMIPAddress *) g_ptr_array_index (ptr_array, i); - - addr_arr[i] = g_strdup_printf ("%s/%u", - nm_ip_address_get_address (addr), - nm_ip_address_get_prefix (addr)); - } - addr_arr[i] = NULL; + if (!nmc_print (nmc_config, + (gpointer[]) { cfg4, NULL }, + NULL, + (const NMMetaAbstractInfo *const*) metagen_ip4_config_group, + field_str, + &error)) { + return FALSE; } - - /* routes */ - ptr_array = nm_ip_config_get_routes (cfg4); - if (ptr_array) { - route_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) { - NMIPRoute *route = (NMIPRoute *) g_ptr_array_index (ptr_array, i); - const char *next_hop; - - next_hop = nm_ip_route_get_next_hop (route); - if (!next_hop) - next_hop = "0.0.0.0"; - - route_arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s%c mt = %u", - nm_ip_route_get_dest (route), - nm_ip_route_get_prefix (route), - next_hop, - nm_ip_route_get_metric (route) == -1 ? '\0' : ',', - (guint32) nm_ip_route_get_metric (route)); - } - route_arr[i] = NULL; - } - - /* DNS */ - dns_arr = g_strdupv ((char **) nm_ip_config_get_nameservers (cfg4)); - - /* domains */ - domain_arr = g_strdupv ((char **) nm_ip_config_get_domains (cfg4)); - - /* WINS */ - wins_arr = g_strdupv ((char **) nm_ip_config_get_wins_servers (cfg4)); - - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, addr_arr); - set_val_strc (arr, 2, nm_ip_config_get_gateway (cfg4)); - set_val_arr (arr, 3, route_arr); - set_val_arr (arr, 4, dns_arr); - set_val_arr (arr, 5, domain_arr); - set_val_arr (arr, 6, wins_arr); - g_ptr_array_add (out.output_data, arr); - - print_data_prepare_width (out.output_data); - print_data (nmc_config, out_indices, NULL, 0, &out); - return TRUE; } diff --git a/clients/cli/common.h b/clients/cli/common.h index 2534c4f73f..4f0f1b1ddb 100644 --- a/clients/cli/common.h +++ b/clients/cli/common.h @@ -25,7 +25,7 @@ #include "nmcli.h" #include "nm-secret-agent-simple.h" -gboolean print_ip4_config (NMIPConfig *cfg4, const NmcConfig *nmc_config, const char *group_prefix, const char *one_field); +gboolean print_ip4_config (NMIPConfig *cfg4, const NmcConfig *nmc_config, const char *one_field); gboolean print_ip6_config (NMIPConfig *cfg6, const NmcConfig *nmc_config, const char *group_prefix, const char *one_field); gboolean print_dhcp4_config (NMDhcpConfig *dhcp4, const NmcConfig *nmc_config, const char *group_prefix, const char *one_field); gboolean print_dhcp6_config (NMDhcpConfig *dhcp6, const NmcConfig *nmc_config, const char *group_prefix, const char *one_field); @@ -80,7 +80,7 @@ void nmc_complete_bool (const char *prefix); const char *nmc_error_get_simple_message (GError *error); -extern const NmcMetaGenericInfo *const nmc_fields_ip4_config[]; +extern const NmcMetaGenericInfo *const metagen_ip4_config[]; extern const NmcMetaGenericInfo *const nmc_fields_dhcp4_config[]; extern const NmcMetaGenericInfo *const nmc_fields_ip6_config[]; extern const NmcMetaGenericInfo *const nmc_fields_dhcp6_config[]; diff --git a/clients/cli/connections.c b/clients/cli/connections.c index c0661c9c41..e842d2ba12 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -213,7 +213,7 @@ const NmcMetaGenericInfo *const nmc_fields_con_active_details_vpn[] = { const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = { NMC_META_GENERIC_WITH_NESTED ("GENERAL", nmc_fields_con_active_details_general + 1), /* 0 */ - NMC_META_GENERIC_WITH_NESTED ("IP4", nmc_fields_ip4_config + 1), /* 1 */ + NMC_META_GENERIC_WITH_NESTED ("IP4", metagen_ip4_config), /* 1 */ NMC_META_GENERIC_WITH_NESTED ("DHCP4", nmc_fields_dhcp4_config + 1), /* 2 */ NMC_META_GENERIC_WITH_NESTED ("IP6", nmc_fields_ip6_config + 1), /* 3 */ NMC_META_GENERIC_WITH_NESTED ("DHCP6", nmc_fields_dhcp6_config + 1), /* 4 */ @@ -1215,7 +1215,7 @@ nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) gboolean b1 = FALSE; NMIPConfig *cfg4 = nm_active_connection_get_ip4_config (acon); - b1 = print_ip4_config (cfg4, &nmc->nmc_config, "IP4", group_fld); + b1 = print_ip4_config (cfg4, &nmc->nmc_config, group_fld); was_output = was_output || b1; } diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 8d8457520a..da5650f45e 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -208,7 +208,7 @@ const NmcMetaGenericInfo *const nmc_fields_dev_show_sections[] = { NMC_META_GENERIC_WITH_NESTED ("WIRED-PROPERTIES", nmc_fields_dev_show_wired_prop + 1), /* 4 */ NMC_META_GENERIC_WITH_NESTED ("WIMAX-PROPERTIES", nmc_fields_dev_show_wimax_prop + 1), /* 5 */ NMC_META_GENERIC_WITH_NESTED ("NSP", nmc_fields_dev_wimax_list + 1), /* 6 */ - NMC_META_GENERIC_WITH_NESTED ("IP4", nmc_fields_ip4_config + 1), /* 7 */ + NMC_META_GENERIC_WITH_NESTED ("IP4", metagen_ip4_config), /* 7 */ NMC_META_GENERIC_WITH_NESTED ("DHCP4", nmc_fields_dhcp4_config + 1), /* 8 */ NMC_META_GENERIC_WITH_NESTED ("IP6", nmc_fields_ip6_config + 1), /* 9 */ NMC_META_GENERIC_WITH_NESTED ("DHCP6", nmc_fields_dhcp6_config + 1), /* 10 */ @@ -1269,7 +1269,7 @@ 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_config, nmc_fields_dev_show_sections[7]->name, section_fld); + was_output = print_ip4_config (cfg4, &nmc->nmc_config, section_fld); /* DHCP4 */ if (dhcp4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx]->name, nmc_fields_dev_show_sections[8]->name)) diff --git a/clients/cli/general.c b/clients/cli/general.c index 1a32086e08..84c853aef0 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -161,12 +161,6 @@ _NM_UTILS_LOOKUP_DEFINE (static, permission_result_to_color, NMClientPermissionR NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CLIENT_PERMISSION_RESULT_UNKNOWN), ); -#define HANDLE_TERMFORMAT(color) \ - G_STMT_START { \ - if (get_type == NM_META_ACCESSOR_GET_TYPE_TERMFORMAT) \ - return nm_meta_termformat_pack ((color), NM_META_TERM_FORMAT_NORMAL); \ - } G_STMT_END - /*****************************************************************************/ static const NmcMetaGenericInfo *const metagen_general_status[]; @@ -178,6 +172,7 @@ _metagen_general_status_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { NmCli *nmc = target; @@ -188,26 +183,26 @@ _metagen_general_status_get_fcn (const NMMetaEnvironment *environment, switch (info->info_type) { case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING: - HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); value = N_("running"); goto translate_and_out; case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_VERSION: - HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); value = nm_client_get_version (nmc->client); goto clone_and_out; case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STATE: state = nm_client_get_state (nmc->client); - HANDLE_TERMFORMAT (state_to_color (state)); + NMC_HANDLE_TERMFORMAT (state_to_color (state)); value = nm_state_to_string_no_l10n (state); goto translate_and_out; case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_STARTUP: v_bool = nm_client_get_startup (nmc->client); - HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_YELLOW : NM_META_TERM_COLOR_GREEN); + NMC_HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_YELLOW : NM_META_TERM_COLOR_GREEN); value = v_bool ? N_("starting") : N_("started"); goto translate_and_out; case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_CONNECTIVITY: connectivity = nm_client_get_connectivity (nmc->client); - HANDLE_TERMFORMAT (connectivity_to_color (connectivity)); + NMC_HANDLE_TERMFORMAT (connectivity_to_color (connectivity)); value = nm_connectivity_to_string_no_l10n (connectivity); goto translate_and_out; case NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_NETWORKING: @@ -236,7 +231,7 @@ _metagen_general_status_get_fcn (const NMMetaEnvironment *environment, g_return_val_if_reached (NULL); enabled_out: - HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED); + NMC_HANDLE_TERMFORMAT (v_bool ? NM_META_TERM_COLOR_GREEN : NM_META_TERM_COLOR_RED); value = v_bool ? N_("enabled") : N_("disabled"); goto translate_and_out; @@ -284,6 +279,7 @@ _metagen_general_permissions_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { NMClientPermission perm = GPOINTER_TO_UINT (target); @@ -293,11 +289,11 @@ _metagen_general_permissions_get_fcn (const NMMetaEnvironment *environment, switch (info->info_type) { case NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_PERMISSION: - HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); return permission_to_string (perm); case NMC_GENERIC_INFO_TYPE_GENERAL_PERMISSIONS_VALUE: perm_result = nm_client_get_permission_result (nmc->client, perm); - HANDLE_TERMFORMAT (permission_result_to_color (perm_result)); + NMC_HANDLE_TERMFORMAT (permission_result_to_color (perm_result)); s = permission_result_to_string_no_l10n (perm_result); if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) return _(s); @@ -331,6 +327,7 @@ _metagen_general_logging_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { NmCli *nmc = environment_user_data; @@ -338,7 +335,7 @@ _metagen_general_logging_get_fcn (const NMMetaEnvironment *environment, nm_assert (info->info_type < _NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_NUM); - HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); if (!d->initialized) { d->initialized = TRUE; diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index df1c59810c..4420291719 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -117,7 +117,7 @@ complete_fields (const char *prefix) h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - complete_field (h, nmc_fields_ip4_config); + complete_field (h, metagen_ip4_config); complete_field (h, nmc_fields_dhcp4_config); complete_field (h, nmc_fields_ip6_config); complete_field (h, nmc_fields_dhcp6_config); diff --git a/clients/cli/utils.c b/clients/cli/utils.c index fab1cc0fb1..b98d8d19cb 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -41,9 +41,13 @@ /*****************************************************************************/ static const char * -_meta_type_nmc_generic_info_get_name (const NMMetaAbstractInfo *abstract_info) +_meta_type_nmc_generic_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) { - return ((const NmcMetaGenericInfo *) abstract_info)->name; + const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info; + + if (for_header) + return info->name_header ?: info->name; + return info->name; } static const NMMetaAbstractInfo *const* @@ -75,14 +79,14 @@ _meta_type_nmc_generic_info_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info; nm_assert (!out_to_free || !*out_to_free); + nm_assert (out_flags && !*out_flags); - if (!info->get_fcn) - g_return_val_if_reached (NULL); if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY, @@ -92,10 +96,26 @@ _meta_type_nmc_generic_info_get_fcn (const NMMetaEnvironment *environment, /* omitting the out_to_free value is only allowed for TERMFORMAT. */ nm_assert (out_to_free || NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_TERMFORMAT)); - return info->get_fcn (environment, environment_user_data, - info, target, - get_type, get_flags, - out_to_free); + if (info->get_fcn) { + return info->get_fcn (environment, environment_user_data, + info, target, + get_type, + get_flags, + out_flags, + out_to_free); + } + + if (info->nested) { + const char *s; + + NMC_HANDLE_TERMFORMAT (NM_META_TERM_COLOR_NORMAL); + s = info->name; + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(s); + return s; + } + + g_return_val_if_reached (NULL); } const NMMetaType nmc_meta_type_generic_info = { @@ -823,7 +843,7 @@ _output_selection_select_one (const NMMetaAbstractInfo *const* fields_array, for (i = 0; fields_array[i]; i++) { const NMMetaAbstractInfo *fi = fields_array[i]; - if (g_ascii_strcasecmp (i_name, nm_meta_abstract_info_get_name (fi)) != 0) + if (g_ascii_strcasecmp (i_name, nm_meta_abstract_info_get_name (fi, FALSE)) != 0) continue; if (!right || !validate_nested) { @@ -844,7 +864,7 @@ _output_selection_select_one (const NMMetaAbstractInfo *const* fields_array, const NmcMetaGenericInfo *fi_g = (const NmcMetaGenericInfo *) fi; for (j = 0; fi_g->nested && fi_g->nested[j]; j++) { - if (g_ascii_strcasecmp (right, nm_meta_abstract_info_get_name ((const NMMetaAbstractInfo *) fi_g->nested[j])) == 0) { + if (g_ascii_strcasecmp (right, nm_meta_abstract_info_get_name ((const NMMetaAbstractInfo *) fi_g->nested[j], FALSE)) == 0) { found = TRUE; break; } @@ -869,7 +889,7 @@ not_found: if (fields_prefix) { p = g_strdup_printf ("%s.%s", fields_prefix, - nm_meta_abstract_info_get_name (fields_array_failure)); + nm_meta_abstract_info_get_name (fields_array_failure, FALSE)); } allowed_fields = nmc_get_allowed_fields_nested (fields_array_failure, p); } else @@ -1038,7 +1058,9 @@ _output_selection_append (GArray *cols, return FALSE; } - if (selection_item->info->meta_type != &nm_meta_type_setting_info_editor) + if (!NM_IN_SET(selection_item->info->meta_type, + &nm_meta_type_setting_info_editor, + &nmc_meta_type_generic_info)) g_array_index (cols, PrintDataCol, col_idx).is_leaf = FALSE; } @@ -1216,11 +1238,11 @@ nmc_get_allowed_fields_nested (const NMMetaAbstractInfo *abstract_info, const ch allowed_fields = g_string_sized_new (256); if (!name_prefix) - name_prefix = nm_meta_abstract_info_get_name (abstract_info); + name_prefix = nm_meta_abstract_info_get_name (abstract_info, FALSE); for (i = 0; nested[i]; i++) { g_string_append_printf (allowed_fields, "%s.%s,", - name_prefix, nm_meta_abstract_info_get_name (nested[i])); + name_prefix, nm_meta_abstract_info_get_name (nested[i], FALSE)); } g_string_truncate (allowed_fields, allowed_fields->len - 1); return g_string_free (allowed_fields, FALSE); @@ -1239,7 +1261,7 @@ nmc_get_allowed_fields (const NMMetaAbstractInfo *const*fields_array, const char for (i = 0; fields_array[i]; i++) { if (name_prefix) g_string_append_printf (allowed_fields, "%s.", name_prefix); - g_string_append_printf (allowed_fields, "%s,", nm_meta_abstract_info_get_name (fields_array[i])); + g_string_append_printf (allowed_fields, "%s,", nm_meta_abstract_info_get_name (fields_array[i], FALSE)); } g_string_truncate (allowed_fields, allowed_fields->len - 1); return g_string_free (allowed_fields, FALSE); @@ -1282,18 +1304,26 @@ nmc_empty_output_fields (NmcOutputData *output_data) typedef struct { guint col_idx; const PrintDataCol *col; - bool is_nested; const char *title; bool title_to_free:1; int width; } PrintDataHeaderCell; +typedef enum { + PRINT_DATA_CELL_FORMAT_TYPE_PLAIN = 0, + PRINT_DATA_CELL_FORMAT_TYPE_STRV, +} PrintDataCellFormatType; + typedef struct { guint row_idx; const PrintDataHeaderCell *header_cell; NMMetaTermColor term_color; NMMetaTermFormat term_format; - const char *text; + union { + const char *plain; + const char *const*strv; + } text; + PrintDataCellFormatType text_format:3; bool text_to_free:1; } PrintDataCell; @@ -1313,10 +1343,17 @@ static void _print_data_cell_clear_text (PrintDataCell *cell) { if (cell->text_to_free) { - g_free ((char *) cell->text); + switch (cell->text_format) { + case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN: + g_free ((char *) cell->text.plain); + break; + case PRINT_DATA_CELL_FORMAT_TYPE_STRV: + g_strfreev ((char **) cell->text.strv); + break; + }; cell->text_to_free = FALSE; } - cell->text = NULL; + memset (&cell->text, 0, sizeof (cell->text)); } static void @@ -1368,25 +1405,23 @@ _print_fill (const NmcConfig *nmc_config, header_cell->col_idx = col_idx; header_cell->col = col; - header_cell->is_nested = FALSE; translate_title = pretty; - if (info->meta_type == &nm_meta_type_property_info) { - header_cell->title = nm_meta_abstract_info_get_name (info); - if (nmc_config->multiline_output) { - header_cell->title = g_strdup_printf ("%s.%s", - ((const NMMetaPropertyInfo *) info)->setting_info->general->setting_name, - header_cell->title); - header_cell->title_to_free = TRUE; - } - } else if (info->meta_type == &nm_meta_type_setting_info_editor) - header_cell->title = N_("name"); - else - header_cell->title = nm_meta_abstract_info_get_name (info); - - if (translate_title) - header_cell->title = _(header_cell->title); + header_cell->title = nm_meta_abstract_info_get_name (info, TRUE); + if ( nmc_config->multiline_output + && col->parent_idx != PRINT_DATA_COL_PARENT_NIL + && NM_IN_SET (info->meta_type, + &nm_meta_type_property_info, + &nmc_meta_type_generic_info)) { + header_cell->title = g_strdup_printf ("%s.%s", + nm_meta_abstract_info_get_name (cols[col->parent_idx].selection_item->info, FALSE), + header_cell->title); + header_cell->title_to_free = TRUE; + } else { + if (translate_title) + header_cell->title = _(header_cell->title); + } } targets_len = NM_PTRARRAY_LEN (targets); @@ -1398,7 +1433,7 @@ _print_fill (const NmcConfig *nmc_config, text_get_type = pretty ? NM_META_ACCESSOR_GET_TYPE_PRETTY : NM_META_ACCESSOR_GET_TYPE_PARSABLE; - text_get_flags = NM_META_ACCESSOR_GET_FLAGS_NONE; + text_get_flags = NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV; if (nmc_config->show_secrets) text_get_flags |= NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS; @@ -1411,20 +1446,40 @@ _print_fill (const NmcConfig *nmc_config, PrintDataCell *cell = &cells_line[i_col]; const PrintDataHeaderCell *header_cell; const NMMetaAbstractInfo *info; + NMMetaAccessorGetOutFlags text_out_flags, color_out_flags; + gconstpointer value; header_cell = &g_array_index (header_row, PrintDataHeaderCell, i_col); info = header_cell->col->selection_item->info; cell->row_idx = i_row; cell->header_cell = header_cell; - cell->text = nm_meta_abstract_info_get (info, - NULL, - &nm_cli, - target, - text_get_type, - text_get_flags, - (gpointer *) &to_free); - cell->text_to_free = !!to_free; + + value = nm_meta_abstract_info_get (info, + NULL, + &nm_cli, + target, + text_get_type, + text_get_flags, + &text_out_flags, + (gpointer *) &to_free); + if (NM_FLAGS_HAS (text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_STRV)) { + if (value) { + if (nmc_config->multiline_output) { + cell->text_format = PRINT_DATA_CELL_FORMAT_TYPE_STRV; + cell->text.strv = value; + cell->text_to_free = !!to_free; + } else { + cell->text.plain = g_strjoinv (" | ", (char **) value); + cell->text_to_free = TRUE; + if (to_free) + g_strfreev ((char **) to_free); + } + } + } else { + cell->text.plain = value; + cell->text_to_free = !!to_free; + } nm_meta_termformat_unpack (nm_meta_abstract_info_get (info, NULL, @@ -1432,15 +1487,18 @@ _print_fill (const NmcConfig *nmc_config, target, NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, NM_META_ACCESSOR_GET_FLAGS_NONE, + &color_out_flags, NULL), &cell->term_color, &cell->term_format); - if (pretty && (!cell->text || !cell->text[0])) { - _print_data_cell_clear_text (cell); - cell->text = "--"; - } else if (!cell->text) - cell->text = ""; + if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_PLAIN) { + if (pretty && (!cell->text.plain|| !cell->text.plain[0])) { + _print_data_cell_clear_text (cell); + cell->text.plain = "--"; + } else if (!cell->text.plain) + cell->text.plain = ""; + } } } @@ -1451,12 +1509,22 @@ _print_fill (const NmcConfig *nmc_config, for (i_row = 0; i_row < targets_len; i_row++) { const PrintDataCell *cell = &g_array_index (cells, PrintDataCell, i_row * cols_len + i_col); + const char *const*i_strv; - if (header_cell->is_nested) { - g_assert_not_reached (/*TODO*/); - } else { + switch (cell->text_format) { + case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN: header_cell->width = NM_MAX (header_cell->width, - nmc_string_screen_width (cell->text, NULL)); + nmc_string_screen_width (cell->text.plain, NULL)); + break; + case PRINT_DATA_CELL_FORMAT_TYPE_STRV: + i_strv = cell->text.strv; + if (i_strv) { + for (; *i_strv; i_strv++) { + header_cell->width = NM_MAX (header_cell->width, + nmc_string_screen_width (*i_strv, NULL)); + } + } + break; } } @@ -1471,14 +1539,27 @@ static gboolean _print_skip_column (const NmcConfig *nmc_config, const PrintDataHeaderCell *header_cell) { + const NmcOutputSelectionItem *selection_item; + const NMMetaAbstractInfo *info; + + selection_item = header_cell->col->selection_item; + info = selection_item->info; + if (nmc_config->multiline_output) { - if (header_cell->col->selection_item->info->meta_type == &nm_meta_type_setting_info_editor) { + if (info->meta_type == &nm_meta_type_setting_info_editor) { /* we skip the "name" entry for the setting in multiline output. */ return TRUE; } + if ( info->meta_type == &nmc_meta_type_generic_info + && ((const NmcMetaGenericInfo *) info)->nested) { + /* skip the "name" entry for parent generic-infos */ + return TRUE; + } } else { - if ( header_cell->col->selection_item->info->meta_type == &nm_meta_type_setting_info_editor - && header_cell->col->selection_item->sub_selection) { + if ( NM_IN_SET (info->meta_type, + &nm_meta_type_setting_info_editor, + &nmc_meta_type_generic_info) + && selection_item->sub_selection) { /* in tabular form, we skip the "name" entry for sections that have sub-selections. * That is, for "ipv4.may-fail", but not for "ipv4". */ return TRUE; @@ -1568,49 +1649,66 @@ _print_do (const NmcConfig *nmc_config, for (i_col = 0; i_col < col_len; i_col++) { const PrintDataCell *cell = ¤t_line[i_col]; - gs_free char *text_to_free = NULL; - const char *text; + const char *const*lines = NULL; + guint i_lines, lines_len; if (_print_skip_column (nmc_config, cell->header_cell)) continue; - if (cell->header_cell->is_nested) { - g_assert_not_reached (/*TODO*/); - } else { + lines_len = 0; + switch (cell->text_format) { + case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN: + lines = &cell->text.plain; + lines_len = 1; + break; + case PRINT_DATA_CELL_FORMAT_TYPE_STRV: + nm_assert (multiline); + lines = cell->text.strv; + lines_len = NM_PTRARRAY_LEN (lines); + break; + } + + for (i_lines = 0; i_lines < lines_len; i_lines++) { + gs_free char *text_to_free = NULL; + const char *text; + text = colorize_string (nmc_config->use_colors, cell->term_color, cell->term_format, - cell->text, &text_to_free); - } - if (multiline) { - gs_free char *prefix = NULL; + lines[i_lines], &text_to_free); + if (multiline) { + gs_free char *prefix = NULL; - prefix = g_strdup_printf ("%s:", cell->header_cell->title); - width1 = strlen (prefix); - width2 = nmc_string_screen_width (prefix, NULL); - g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), prefix, text); - } else { - nm_assert (str); - if (terse) { - if (nmc_config->escape_values) { - const char *p = text; - while (*p) { - if (*p == ':' || *p == '\\') - g_string_append_c (str, '\\'); /* Escaping by '\' */ - g_string_append_c (str, *p); - p++; - } - } + if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_STRV) + prefix = g_strdup_printf ("%s[%u]:", cell->header_cell->title, i_lines + 1); else - g_string_append_printf (str, "%s", text); - g_string_append_c (str, ':'); /* Column separator */ + prefix = g_strdup_printf ("%s:", cell->header_cell->title); + width1 = strlen (prefix); + width2 = nmc_string_screen_width (prefix, NULL); + g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), prefix, text); } else { - const PrintDataHeaderCell *header_cell = &header_row[i_col]; + nm_assert (str); + if (terse) { + if (nmc_config->escape_values) { + const char *p = text; + while (*p) { + if (*p == ':' || *p == '\\') + g_string_append_c (str, '\\'); /* Escaping by '\' */ + g_string_append_c (str, *p); + p++; + } + } + else + g_string_append_printf (str, "%s", text); + g_string_append_c (str, ':'); /* Column separator */ + } else { + const PrintDataHeaderCell *header_cell = &header_row[i_col]; - width1 = strlen (text); - width2 = nmc_string_screen_width (text, NULL); /* Width of the string (in screen colums) */ - g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), text); - g_string_append_c (str, ' '); /* Column separator */ - table_width += header_cell->width + width1 - width2 + 1; + width1 = strlen (text); + width2 = nmc_string_screen_width (text, NULL); /* Width of the string (in screen colums) */ + g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), text); + g_string_append_c (str, ' '); /* Column separator */ + table_width += header_cell->width + width1 - width2 + 1; + } } } } @@ -1685,7 +1783,7 @@ get_value_to_print (NmcColorOption color_option, nm_assert (out_to_free && !*out_to_free); if (field_name) - value = _(nm_meta_abstract_info_get_name (field->info)); + value = _(nm_meta_abstract_info_get_name (field->info, FALSE)); else { value = field->value ? (is_array @@ -1793,7 +1891,7 @@ print_required_fields (const NmcConfig *nmc_config, tmp = g_strdup_printf ("%s%s%s[%d]:", section_prefix ? (const char*) field_values[0].value : "", section_prefix ? "." : "", - _(nm_meta_abstract_info_get_name (field_values[idx].info)), + _(nm_meta_abstract_info_get_name (field_values[idx].info, FALSE)), j); width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); @@ -1814,7 +1912,7 @@ print_required_fields (const NmcConfig *nmc_config, tmp = g_strdup_printf ("%s%s%s:", section_prefix ? hdr_name : "", section_prefix ? "." : "", - _(nm_meta_abstract_info_get_name (field_values[idx].info))); + _(nm_meta_abstract_info_get_name (field_values[idx].info, FALSE))); width1 = strlen (tmp); width2 = nmc_string_screen_width (tmp, NULL); g_print ("%-*s%s\n", (int) (terse ? 0 : ML_VALUE_INDENT+width1-width2), tmp, print_val); diff --git a/clients/cli/utils.h b/clients/cli/utils.h index cbed4a16fd..2f8fd0f69c 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -127,12 +127,27 @@ typedef enum { NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_DOMAINS, _NMC_GENERIC_INFO_TYPE_GENERAL_LOGGING_NUM, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ADDRESS = 0, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_GATEWAY, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_ROUTE, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DNS, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_DOMAIN, + NMC_GENERIC_INFO_TYPE_IP4_CONFIG_WINS, + _NMC_GENERIC_INFO_TYPE_IP4_CONFIG_NUM, + } NmcGenericInfoType; +#define NMC_HANDLE_TERMFORMAT(color) \ + G_STMT_START { \ + if (get_type == NM_META_ACCESSOR_GET_TYPE_TERMFORMAT) \ + return nm_meta_termformat_pack ((color), NM_META_TERM_FORMAT_NORMAL); \ + } G_STMT_END + struct _NmcMetaGenericInfo { const NMMetaType *meta_type; NmcGenericInfoType info_type; const char *name; + const char *name_header; const NmcMetaGenericInfo *const*nested; gconstpointer (*get_fcn) (const NMMetaEnvironment *environment, gpointer environment_user_data, @@ -140,6 +155,7 @@ struct _NmcMetaGenericInfo { gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); }; @@ -150,8 +166,8 @@ struct _NmcMetaGenericInfo { __VA_ARGS__ \ })) -#define NMC_META_GENERIC_WITH_NESTED(n, nest) \ - NMC_META_GENERIC (n, .nested = (nest)) +#define NMC_META_GENERIC_WITH_NESTED(n, nest, ...) \ + NMC_META_GENERIC (n, .nested = (nest), __VA_ARGS__) /*****************************************************************************/ diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 5af55b377b..5960c57103 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -186,14 +186,14 @@ nm_meta_setting_infos_editor_p (void) /*****************************************************************************/ const char * -nm_meta_abstract_info_get_name (const NMMetaAbstractInfo *abstract_info) +nm_meta_abstract_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) { const char *n; nm_assert (abstract_info); nm_assert (abstract_info->meta_type); nm_assert (abstract_info->meta_type->get_name); - n = abstract_info->meta_type->get_name (abstract_info); + n = abstract_info->meta_type->get_name (abstract_info, for_header); nm_assert (n && n[0]); return n; } @@ -231,11 +231,15 @@ nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { nm_assert (abstract_info); nm_assert (abstract_info->meta_type); nm_assert (!out_to_free || !*out_to_free); + nm_assert (out_flags); + + *out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE; if (!abstract_info->meta_type->get_fcn) g_return_val_if_reached (NULL); @@ -245,5 +249,6 @@ nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, target, get_type, get_flags, + out_flags, out_to_free); } diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 8ed69b29dd..8aec04aced 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -44,7 +44,7 @@ const NMMetaSettingInfoEditor *const*nm_meta_setting_infos_editor_p (void); /*****************************************************************************/ -const char *nm_meta_abstract_info_get_name (const NMMetaAbstractInfo *abstract_info); +const char *nm_meta_abstract_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header); const NMMetaAbstractInfo *const*nm_meta_abstract_info_get_nested (const NMMetaAbstractInfo *abstract_info, guint *out_len, @@ -56,6 +56,7 @@ gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); /*****************************************************************************/ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 1ba417a4e0..17246f4c56 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -6560,13 +6560,15 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { /*****************************************************************************/ static const char * -_meta_type_setting_info_editor_get_name (const NMMetaAbstractInfo *abstract_info) +_meta_type_setting_info_editor_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) { + if (for_header) + return N_("name"); return ((const NMMetaSettingInfoEditor *) abstract_info)->general->setting_name; } static const char * -_meta_type_property_info_get_name (const NMMetaAbstractInfo *abstract_info) +_meta_type_property_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) { return ((const NMMetaPropertyInfo *) abstract_info)->property_name; } @@ -6578,11 +6580,13 @@ _meta_type_setting_info_editor_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { const NMMetaSettingInfoEditor *info = (const NMMetaSettingInfoEditor *) abstract_info; nm_assert (!out_to_free || !*out_to_free); + nm_assert (out_flags && !*out_flags); if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, @@ -6603,11 +6607,13 @@ _meta_type_property_info_get_fcn (const NMMetaEnvironment *environment, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free) { const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; nm_assert (!out_to_free || !*out_to_free); + nm_assert (out_flags && !*out_flags); if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 6f582949f7..46a4376165 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -80,9 +80,15 @@ nm_meta_termformat_pack (NMMetaTermColor color, NMMetaTermFormat format) typedef enum { NM_META_ACCESSOR_GET_FLAGS_NONE = 0, - NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS = (1LL << 0), + NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV = (1LL << 0), + NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS = (1LL << 1), } NMMetaAccessorGetFlags; +typedef enum { + NM_META_ACCESSOR_GET_OUT_FLAGS_NONE = 0, + NM_META_ACCESSOR_GET_OUT_FLAGS_STRV = (1LL << 0), +} NMMetaAccessorGetOutFlags; + typedef enum { NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC = (1LL << 0), NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX = (1LL << 1), @@ -188,7 +194,7 @@ struct _NMMetaSettingInfoEditor { struct _NMMetaType { const char *type_name; - const char *(*get_name) (const NMMetaAbstractInfo *abstract_info); + const char *(*get_name) (const NMMetaAbstractInfo *abstract_info, gboolean for_header); const NMMetaAbstractInfo *const*(*get_nested) (const NMMetaAbstractInfo *abstract_info, guint *out_len, gpointer *out_to_free); @@ -198,6 +204,7 @@ struct _NMMetaType { gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); }; diff --git a/clients/common/tests/test-general.c b/clients/common/tests/test-general.c index b66262e8de..b5f9af75de 100644 --- a/clients/common/tests/test-general.c +++ b/clients/common/tests/test-general.c @@ -34,6 +34,9 @@ test_client_meta_check (void) NMMetaSettingType m; guint p; + G_STATIC_ASSERT (G_STRUCT_OFFSET (NMMetaAbstractInfo, meta_type) == G_STRUCT_OFFSET (NMMetaSettingInfoEditor, meta_type)); + G_STATIC_ASSERT (G_STRUCT_OFFSET (NMMetaAbstractInfo, meta_type) == G_STRUCT_OFFSET (NMMetaPropertyInfo, meta_type)); + for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) { const NMMetaSettingInfo *info = &nm_meta_setting_infos[m]; GType gtype; @@ -68,7 +71,8 @@ test_client_meta_check (void) g_assert (info->general); g_assert (info->general == &nm_meta_setting_infos[m]); - g_assert (info->general->setting_name == info->meta_type->get_name ((const NMMetaAbstractInfo *) info)); + g_assert_cmpstr (info->general->setting_name, ==, info->meta_type->get_name ((const NMMetaAbstractInfo *) info, FALSE)); + g_assert_cmpstr ("name", ==, info->meta_type->get_name ((const NMMetaAbstractInfo *) info, TRUE)); if (info->properties_num) { gs_unref_hashtable GHashTable *property_names = g_hash_table_new (g_str_hash, g_str_equal); @@ -83,7 +87,8 @@ test_client_meta_check (void) g_assert (nm_g_hash_table_add (property_names, (gpointer) pi->property_name)); - g_assert (pi->property_name == pi->meta_type->get_name ((const NMMetaAbstractInfo *) pi)); + g_assert_cmpstr (pi->property_name, ==, pi->meta_type->get_name ((const NMMetaAbstractInfo *) pi, FALSE)); + g_assert_cmpstr (pi->property_name, ==, pi->meta_type->get_name ((const NMMetaAbstractInfo *) pi, TRUE)); g_assert (pi->property_type); g_assert (pi->property_type->get_fcn); From b7efa627455bef144a36211a2b108360d6d32c23 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 12:58:13 +0200 Subject: [PATCH 14/32] cli: cleanup meta data virtual function arguments - have the "self" argument first, before the environment arguments. It's more idiomatic. - from within cli, always pass nmc_meta_environment and nmc_meta_arg where needed. - drop the union in NMMetaAbstractInfo. I was suppost to make casts nicer, but it doesn't really. --- clients/cli/settings.c | 24 +++++++++-------- clients/cli/utils.c | 14 +++++----- clients/cli/utils.h | 3 +++ clients/common/nm-meta-setting-access.c | 5 ++-- clients/common/nm-meta-setting-desc.c | 36 ++++++++++++++++--------- clients/common/nm-meta-setting-desc.h | 27 ++++++++----------- 6 files changed, 61 insertions(+), 48 deletions(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 9792f60c08..97760d7802 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -458,9 +458,11 @@ _env_warn_fcn_handle (const NMMetaEnvironment *environment, /*****************************************************************************/ -static const NMMetaEnvironment meta_environment = { +const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment) { .warn_fcn = _env_warn_fcn_handle, -}; +}); + +NmCli *const nmc_meta_environment_arg = &nm_cli; static char * get_property_val (NMSetting *setting, const char *prop, NMMetaAccessorGetType get_type, gboolean show_secrets, GError **error) @@ -472,9 +474,9 @@ get_property_val (NMSetting *setting, const char *prop, NMMetaAccessorGetType ge if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { if (property_info->property_type->get_fcn) { - return property_info->property_type->get_fcn (&meta_environment, - NULL, - property_info, + return property_info->property_type->get_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, setting, get_type, show_secrets ? NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS : 0); @@ -514,9 +516,9 @@ _set_fcn_call (const NMMetaPropertyInfo *property_info, const char *value, GError **error) { - return property_info->property_type->set_fcn (&meta_environment, - NULL, - property_info, + return property_info->property_type->set_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, setting, value, error); @@ -640,9 +642,9 @@ nmc_setting_remove_property_option (NMSetting *setting, if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { if (property_info->property_type->remove_fcn) { - return property_info->property_type->remove_fcn (&meta_environment, - NULL, - property_info, + return property_info->property_type->remove_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, setting, option, idx, diff --git a/clients/cli/utils.c b/clients/cli/utils.c index b98d8d19cb..ebafaa127b 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -73,9 +73,9 @@ _meta_type_nmc_generic_info_get_nested (const NMMetaAbstractInfo *abstract_info, } static gconstpointer -_meta_type_nmc_generic_info_get_fcn (const NMMetaEnvironment *environment, +_meta_type_nmc_generic_info_get_fcn (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaAbstractInfo *abstract_info, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, @@ -852,7 +852,7 @@ _output_selection_select_one (const NMMetaAbstractInfo *const* fields_array, } if (fi->meta_type == &nm_meta_type_setting_info_editor) { - const NMMetaSettingInfoEditor *fi_s = &fi->as.setting_info; + const NMMetaSettingInfoEditor *fi_s = (const NMMetaSettingInfoEditor *) fi; for (j = 0; j < fi_s->properties_num; j++) { if (g_ascii_strcasecmp (right, fi_s->properties[j].property_name) == 0) { @@ -1456,8 +1456,8 @@ _print_fill (const NmcConfig *nmc_config, cell->header_cell = header_cell; value = nm_meta_abstract_info_get (info, - NULL, - &nm_cli, + nmc_meta_environment, + nmc_meta_environment_arg, target, text_get_type, text_get_flags, @@ -1482,8 +1482,8 @@ _print_fill (const NmcConfig *nmc_config, } nm_meta_termformat_unpack (nm_meta_abstract_info_get (info, - NULL, - &nm_cli, + nmc_meta_environment, + nmc_meta_environment_arg, target, NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, NM_META_ACCESSOR_GET_FLAGS_NONE, diff --git a/clients/cli/utils.h b/clients/cli/utils.h index 2f8fd0f69c..01ad694ae2 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -103,6 +103,9 @@ void print_data (const NmcConfig *nmc_config, /*****************************************************************************/ +extern const NMMetaEnvironment *const nmc_meta_environment; +extern NmCli *const nmc_meta_environment_arg; + typedef enum { NMC_GENERIC_INFO_TYPE_GENERAL_STATUS_RUNNING = 0, diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 5960c57103..d3843dfef1 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -244,8 +244,9 @@ nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, if (!abstract_info->meta_type->get_fcn) g_return_val_if_reached (NULL); - return abstract_info->meta_type->get_fcn (environment, environment_user_data, - abstract_info, + return abstract_info->meta_type->get_fcn (abstract_info, + environment, + environment_user_data, target, get_type, get_flags, diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 17246f4c56..099ccd84a6 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -507,13 +507,13 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, char **out_to_free #define ARGS_GET_FCN \ - const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaPropertyInfo *property_info, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags #define ARGS_SET_FCN \ - const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaPropertyInfo *property_info, NMSetting *setting, const char *value, GError **error + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error #define ARGS_REMOVE_FCN \ - const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaPropertyInfo *property_info, NMSetting *setting, const char *value, guint32 idx, GError **error + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free @@ -823,7 +823,10 @@ _set_fcn_gobject_int64 (ARGS_SET_FCN) } static gboolean -_set_fcn_gobject_uint (ARGS_SET_FCN) +_set_fcn_gobject_uint_impl (const NMMetaPropertyInfo *property_info, + NMSetting *setting, + const char *value, + GError **error) { unsigned long val_int; @@ -842,12 +845,18 @@ _set_fcn_gobject_uint (ARGS_SET_FCN) return TRUE; } +static gboolean +_set_fcn_gobject_uint (ARGS_SET_FCN) +{ + return _set_fcn_gobject_uint_impl (property_info, setting, value, error); +} + static gboolean _set_fcn_gobject_mtu (ARGS_SET_FCN) { if (nm_streq0 (value, "auto")) value = "0"; - return _set_fcn_gobject_uint (environment, environment_user_data, property_info, setting, value, error); + return _set_fcn_gobject_uint_impl (property_info, setting, value, error); } static gboolean @@ -6574,9 +6583,9 @@ _meta_type_property_info_get_name (const NMMetaAbstractInfo *abstract_info, gboo } static gconstpointer -_meta_type_setting_info_editor_get_fcn (const NMMetaEnvironment *environment, +_meta_type_setting_info_editor_get_fcn (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaAbstractInfo *abstract_info, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, @@ -6601,9 +6610,9 @@ _meta_type_setting_info_editor_get_fcn (const NMMetaEnvironment *environment, } static gconstpointer -_meta_type_property_info_get_fcn (const NMMetaEnvironment *environment, +_meta_type_property_info_get_fcn (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaAbstractInfo *abstract_info, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, @@ -6629,9 +6638,12 @@ _meta_type_property_info_get_fcn (const NMMetaEnvironment *environment, return NM_META_TEXT_HIDDEN; } - return (*out_to_free = info->property_type->get_fcn (environment, environment_user_data, - info, target, - get_type, get_flags)); + return (*out_to_free = info->property_type->get_fcn (info, + environment, + environment_user_data, + target, + get_type, + get_flags)); } static const NMMetaAbstractInfo *const* diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 46a4376165..da236eb7e6 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -118,21 +118,21 @@ struct _NMMetaPropertyType { const char *(*describe_fcn) (const NMMetaPropertyInfo *property_info, char **out_to_free); - char *(*get_fcn) (const NMMetaEnvironment *environment, + char *(*get_fcn) (const NMMetaPropertyInfo *property_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaPropertyInfo *property_info, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags); - gboolean (*set_fcn) (const NMMetaEnvironment *environment, + gboolean (*set_fcn) (const NMMetaPropertyInfo *property_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaPropertyInfo *property_info, NMSetting *setting, const char *value, GError **error); - gboolean (*remove_fcn) (const NMMetaEnvironment *environment, + gboolean (*remove_fcn) (const NMMetaPropertyInfo *property_info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaPropertyInfo *property_info, NMSetting *setting, const char *option, guint32 idx, @@ -194,13 +194,14 @@ struct _NMMetaSettingInfoEditor { struct _NMMetaType { const char *type_name; - const char *(*get_name) (const NMMetaAbstractInfo *abstract_info, gboolean for_header); + const char *(*get_name) (const NMMetaAbstractInfo *abstract_info, + gboolean for_header); const NMMetaAbstractInfo *const*(*get_nested) (const NMMetaAbstractInfo *abstract_info, guint *out_len, gpointer *out_to_free); - gconstpointer (*get_fcn) (const NMMetaEnvironment *environment, + gconstpointer (*get_fcn) (const NMMetaAbstractInfo *info, + const NMMetaEnvironment *environment, gpointer environment_user_data, - const NMMetaAbstractInfo *info, gpointer target, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, @@ -209,13 +210,7 @@ struct _NMMetaType { }; struct _NMMetaAbstractInfo { - union { - const NMMetaType *meta_type; - union { - NMMetaSettingInfoEditor setting_info; - NMMetaPropertyInfo property_info; - } as; - }; + const NMMetaType *meta_type; }; extern const NMMetaType nm_meta_type_setting_info_editor; From ddfff04a457444ee9a7c7e85d08e1d7213b3ab6e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 13:23:31 +0200 Subject: [PATCH 15/32] cli: extend NMMetaSettingInfoEditor's get_fcn() to support different output forms --- clients/cli/settings.c | 25 +- clients/common/nm-meta-setting-desc.c | 449 ++++++++++++++++---------- clients/common/nm-meta-setting-desc.h | 15 +- 3 files changed, 308 insertions(+), 181 deletions(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 97760d7802..c508a139f1 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -469,17 +469,26 @@ get_property_val (NMSetting *setting, const char *prop, NMMetaAccessorGetType ge { const NMMetaPropertyInfo *property_info; - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + g_return_val_if_fail (!error || !*error, NULL); + g_return_val_if_fail (NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY), NULL); if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) { if (property_info->property_type->get_fcn) { - return property_info->property_type->get_fcn (property_info, - nmc_meta_environment, - nmc_meta_environment_arg, - setting, - get_type, - show_secrets ? NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS : 0); + NMMetaAccessorGetOutFlags out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE; + char *to_free = NULL; + const char *value; + + value = property_info->property_type->get_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, + setting, + get_type, + show_secrets ? NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS : 0, + &out_flags, + (gpointer *) &to_free); + nm_assert (!out_flags); + return to_free ?: g_strdup (value); } } diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 099ccd84a6..ad7df3ca62 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -507,7 +507,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, char **out_to_free #define ARGS_GET_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free #define ARGS_SET_FCN \ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error @@ -518,17 +518,35 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free -static char * +#define RETURN_UNSUPPORTED_GET_TYPE() \ + G_STMT_START { \ + if (!NM_IN_SET (get_type, \ + NM_META_ACCESSOR_GET_TYPE_PARSABLE, \ + NM_META_ACCESSOR_GET_TYPE_PRETTY)) { \ + nm_assert_not_reached (); \ + return NULL; \ + } \ + } G_STMT_END; + +#define RETURN_STR_TO_FREE(val) \ + G_STMT_START { \ + char *_val = (val); \ + return ((*(out_to_free)) = _val); \ + } G_STMT_END + +static gconstpointer _get_fcn_nmc_with_default (ARGS_GET_FCN) { const char *s; char *s_full; GValue val = G_VALUE_INIT; + RETURN_UNSUPPORTED_GET_TYPE (); + if (property_info->property_typ_data->subtype.get_with_default.fcn (setting)) { if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup (_("(default)")); - return g_strdup (""); + return _("(default)"); + return ""; } g_value_init (&val, G_TYPE_STRING); @@ -539,19 +557,22 @@ _get_fcn_nmc_with_default (ARGS_GET_FCN) else s_full = g_strdup (s && *s ? s : " "); g_value_unset (&val); - return s_full; + RETURN_STR_TO_FREE (s_full); } -static char * +static gconstpointer _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info, NMSetting *setting, - NMMetaAccessorGetType get_type) + NMMetaAccessorGetType get_type, + gpointer *out_to_free) { char *s; const char *s_c; GType gtype_prop; nm_auto_unset_gvalue GValue val = G_VALUE_INIT; + RETURN_UNSUPPORTED_GET_TYPE (); + gtype_prop = _gobject_property_get_gtype (G_OBJECT (setting), property_info->property_name); if (gtype_prop == G_TYPE_BOOLEAN) { @@ -564,53 +585,57 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info, s_c = b ? _("yes") : _("no"); else s_c = b ? "yes" : "no"; - s = g_strdup (s_c); + return s_c; } else { g_value_init (&val, G_TYPE_STRING); g_object_get_property (G_OBJECT (setting), property_info->property_name, &val); s = g_value_dup_string (&val); + RETURN_STR_TO_FREE (s); } - return s; } -static char * +static gconstpointer _get_fcn_gobject (ARGS_GET_FCN) { - return _get_fcn_gobject_impl (property_info, setting, get_type); + return _get_fcn_gobject_impl (property_info, setting, get_type, out_to_free); } -static char * +static gconstpointer _get_fcn_gobject_mtu (ARGS_GET_FCN) { guint32 mtu; + RETURN_UNSUPPORTED_GET_TYPE (); + if ( !property_info->property_typ_data || !property_info->property_typ_data->subtype.mtu.get_fcn) - return _get_fcn_gobject_impl (property_info, setting, get_type); + return _get_fcn_gobject_impl (property_info, setting, get_type, out_to_free); mtu = property_info->property_typ_data->subtype.mtu.get_fcn (setting); if (mtu == 0) { if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup (_("auto")); - return g_strdup ("auto"); + return _("auto"); + return "auto"; } - return g_strdup_printf ("%u", (unsigned) mtu); + RETURN_STR_TO_FREE (g_strdup_printf ("%u", (unsigned) mtu)); } -static char * +static gconstpointer _get_fcn_gobject_secret_flags (ARGS_GET_FCN) { guint v; GValue val = G_VALUE_INIT; + RETURN_UNSUPPORTED_GET_TYPE (); + g_value_init (&val, G_TYPE_UINT); g_object_get_property (G_OBJECT (setting), property_info->property_name, &val); v = g_value_get_uint (&val); g_value_unset (&val); - return secret_flags_to_string (v, get_type); + RETURN_STR_TO_FREE (secret_flags_to_string (v, get_type)); } -static char * +static gconstpointer _get_fcn_gobject_enum (ARGS_GET_FCN) { GType gtype = 0; @@ -628,6 +653,8 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) gs_free char *s = NULL; char s_numeric[64]; + RETURN_UNSUPPORTED_GET_TYPE (); + if (property_info->property_typ_data) { if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype (); @@ -708,11 +735,12 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) })); if (format_numeric && !format_text) { - return format_numeric_hex - || ( format_numeric_hex_unknown - && !G_IS_ENUM_CLASS (gtype_class ?: (gtype_class = g_type_class_ref (gtype)))) - ? g_strdup_printf ("0x%"G_GINT64_FORMAT, v) - : g_strdup_printf ("%"G_GINT64_FORMAT, v); + s = format_numeric_hex + || ( format_numeric_hex_unknown + && !G_IS_ENUM_CLASS (gtype_class ?: (gtype_class = g_type_class_ref (gtype)))) + ? g_strdup_printf ("0x%"G_GINT64_FORMAT, v) + : g_strdup_printf ("%"G_GINT64_FORMAT, v); + RETURN_STR_TO_FREE (s); } /* the gobject_enum.value_infos are currently ignored for the getter. They @@ -721,7 +749,7 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) s = nm_utils_enum_to_str (gtype, (int) v); if (!format_numeric) - return g_steal_pointer (&s); + RETURN_STR_TO_FREE (g_steal_pointer (&s)); if ( format_numeric_hex || ( format_numeric_hex_unknown @@ -731,12 +759,12 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) nm_sprintf_buf (s_numeric, "%"G_GINT64_FORMAT, v); if (nm_streq0 (s, s_numeric)) - return g_steal_pointer (&s); + RETURN_STR_TO_FREE (g_steal_pointer (&s)); if (format_text_l10n) - return g_strdup_printf (_("%s (%s)"), s_numeric, s); + RETURN_STR_TO_FREE (g_strdup_printf (_("%s (%s)"), s_numeric, s)); else - return g_strdup_printf ("%s (%s)", s_numeric, s); + RETURN_STR_TO_FREE (g_strdup_printf ("%s (%s)", s_numeric, s)); } /*****************************************************************************/ @@ -1611,12 +1639,14 @@ done: /*****************************************************************************/ -static char * +static gconstpointer _get_fcn_802_1x_ca_cert (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *ca_cert_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_ca_cert_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: ca_cert_str = bytes_to_string (nm_setting_802_1x_get_ca_cert_blob (s_8021X)); @@ -1631,21 +1661,23 @@ _get_fcn_802_1x_ca_cert (ARGS_GET_FCN) break; } - return ca_cert_str; + RETURN_STR_TO_FREE (ca_cert_str); } -static char * +static gconstpointer _get_fcn_802_1x_client_cert (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *cert_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_client_cert_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) cert_str = bytes_to_string (nm_setting_802_1x_get_client_cert_blob (s_8021X)); else - cert_str = g_strdup (_(NM_META_TEXT_HIDDEN)); + return _(NM_META_TEXT_HIDDEN); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: cert_str = g_strdup (nm_setting_802_1x_get_client_cert_path (s_8021X)); @@ -1657,15 +1689,17 @@ _get_fcn_802_1x_client_cert (ARGS_GET_FCN) break; } - return cert_str; + RETURN_STR_TO_FREE (cert_str); } -static char * +static gconstpointer _get_fcn_802_1x_phase2_ca_cert (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *phase2_ca_cert_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: phase2_ca_cert_str = bytes_to_string (nm_setting_802_1x_get_phase2_ca_cert_blob (s_8021X)); @@ -1680,21 +1714,23 @@ _get_fcn_802_1x_phase2_ca_cert (ARGS_GET_FCN) break; } - return phase2_ca_cert_str; + RETURN_STR_TO_FREE (phase2_ca_cert_str); } -static char * +static gconstpointer _get_fcn_802_1x_phase2_client_cert (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *cert_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) cert_str = bytes_to_string (nm_setting_802_1x_get_phase2_client_cert_blob (s_8021X)); else - cert_str = g_strdup (_(NM_META_TEXT_HIDDEN)); + return _(NM_META_TEXT_HIDDEN); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: cert_str = g_strdup (nm_setting_802_1x_get_phase2_client_cert_path (s_8021X)); @@ -1706,28 +1742,32 @@ _get_fcn_802_1x_phase2_client_cert (ARGS_GET_FCN) break; } - return cert_str; + RETURN_STR_TO_FREE (cert_str); } -static char * +static gconstpointer _get_fcn_802_1x_password_raw (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); - return bytes_to_string (nm_setting_802_1x_get_password_raw (s_8021X)); + + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (bytes_to_string (nm_setting_802_1x_get_password_raw (s_8021X))); } -static char * +static gconstpointer _get_fcn_802_1x_private_key (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *key_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_private_key_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) key_str = bytes_to_string (nm_setting_802_1x_get_private_key_blob (s_8021X)); else - key_str = g_strdup (_(NM_META_TEXT_HIDDEN)); + return _(NM_META_TEXT_HIDDEN); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: key_str = g_strdup (nm_setting_802_1x_get_private_key_path (s_8021X)); @@ -1739,21 +1779,23 @@ _get_fcn_802_1x_private_key (ARGS_GET_FCN) break; } - return key_str; + RETURN_STR_TO_FREE (key_str); } -static char * +static gconstpointer _get_fcn_802_1x_phase2_private_key (ARGS_GET_FCN) { NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting); char *key_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) key_str = bytes_to_string (nm_setting_802_1x_get_phase2_private_key_blob (s_8021X)); else - key_str = g_strdup (_(NM_META_TEXT_HIDDEN)); + return _(NM_META_TEXT_HIDDEN); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X)); @@ -1765,7 +1807,7 @@ _get_fcn_802_1x_phase2_private_key (ARGS_GET_FCN) break; } - return key_str; + RETURN_STR_TO_FREE (key_str); } #define DEFINE_SETTER_STR_LIST(def_func, set_func) \ @@ -1930,13 +1972,15 @@ _set_fcn_802_1x_password_raw (ARGS_SET_FCN) return nmc_property_set_byte_array (setting, property_info->property_name, value, error); } -static char * +static gconstpointer _get_fcn_bond_options (ARGS_GET_FCN) { NMSettingBond *s_bond = NM_SETTING_BOND (setting); GString *bond_options_s; int i; + RETURN_UNSUPPORTED_GET_TYPE (); + bond_options_s = g_string_new (NULL); for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) { const char *key, *value; @@ -1957,7 +2001,7 @@ _get_fcn_bond_options (ARGS_GET_FCN) } g_string_truncate (bond_options_s, bond_options_s->len-1); /* chop off trailing ',' */ - return g_string_free (bond_options_s, FALSE); + RETURN_STR_TO_FREE (g_string_free (bond_options_s, FALSE)); } /* example: miimon=100,mode=balance-rr, updelay=5 */ @@ -2044,27 +2088,36 @@ _values_fcn_bond_options (ARGS_VALUES_FCN) return nm_setting_bond_get_valid_options (NULL); } -static char * +static gconstpointer _get_fcn_connection_autoconnect_retires (ARGS_GET_FCN) { NMSettingConnection *s_con = NM_SETTING_CONNECTION (setting); gint retries; + char *s; + + RETURN_UNSUPPORTED_GET_TYPE (); retries = nm_setting_connection_get_autoconnect_retries (s_con); if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup_printf ("%d", retries); - - switch (retries) { - case -1: - return g_strdup_printf (_("%d (default)"), retries); - case 0: - return g_strdup_printf (_("%d (forever)"), retries); - default: - return g_strdup_printf ("%d", retries); + s = g_strdup_printf ("%d", retries); + else { + switch (retries) { + case -1: + s = g_strdup_printf (_("%d (default)"), retries); + break; + case 0: + s = g_strdup_printf (_("%d (forever)"), retries); + break; + default: + s = g_strdup_printf ("%d", retries); + break; + } } + + RETURN_STR_TO_FREE (s); } -static char * +static gconstpointer _get_fcn_connection_permissions (ARGS_GET_FCN) { NMSettingConnection *s_con = NM_SETTING_CONNECTION (setting); @@ -2073,6 +2126,8 @@ _get_fcn_connection_permissions (ARGS_GET_FCN) const char *perm_type; int i; + RETURN_UNSUPPORTED_GET_TYPE (); + perm = g_string_new (NULL); for (i = 0; i < nm_setting_connection_get_num_permissions (s_con); i++) { if (nm_setting_connection_get_permission (s_con, i, &perm_type, &perm_item, NULL)) @@ -2080,18 +2135,20 @@ _get_fcn_connection_permissions (ARGS_GET_FCN) } if (perm->len > 0) { g_string_truncate (perm, perm->len-1); /* remove trailing , */ - return g_string_free (perm, FALSE); + RETURN_STR_TO_FREE (g_string_free (perm, FALSE)); } /* No value from get_permission */ - return g_string_free (perm, TRUE); + g_string_free (perm, TRUE); + return NULL; } -static char * +static gconstpointer _get_fcn_connection_autoconnect_slaves (ARGS_GET_FCN) { NMSettingConnection *s_con = NM_SETTING_CONNECTION (setting); - return autoconnect_slaves_to_string (nm_setting_connection_get_autoconnect_slaves (s_con), get_type); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (autoconnect_slaves_to_string (nm_setting_connection_get_autoconnect_slaves (s_con), get_type)); } static gboolean @@ -2248,31 +2305,27 @@ DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_connection_secondaries, nm_setting_connection_remove_secondary, _validate_and_remove_connection_secondary) -static char * +static gconstpointer _get_fcn_connection_metered (ARGS_GET_FCN) { NMSettingConnection *s_conn = NM_SETTING_CONNECTION (setting); + const char *s; + + RETURN_UNSUPPORTED_GET_TYPE (); - if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) { - switch (nm_setting_connection_get_metered (s_conn)) { - case NM_METERED_YES: - return g_strdup ("yes"); - case NM_METERED_NO: - return g_strdup ("no"); - case NM_METERED_UNKNOWN: - default: - return g_strdup ("unknown"); - } - } switch (nm_setting_connection_get_metered (s_conn)) { case NM_METERED_YES: - return g_strdup (_("yes")); + s = N_("yes"); case NM_METERED_NO: - return g_strdup (_("no")); + s = N_("no"); case NM_METERED_UNKNOWN: default: - return g_strdup (_("unknown")); + s = N_("unknown"); + break; } + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(s); + return s; } static gboolean @@ -2331,16 +2384,18 @@ dcb_flags_to_string (NMSettingDcbFlags flags) } #define DEFINE_DCB_FLAGS_GETTER(func_name, property_name) \ - static char * \ + static gconstpointer \ func_name (ARGS_GET_FCN) \ { \ guint v; \ GValue val = G_VALUE_INIT; \ + \ + RETURN_UNSUPPORTED_GET_TYPE (); \ g_value_init (&val, G_TYPE_UINT); \ g_object_get_property (G_OBJECT (setting), property_name, &val); \ v = g_value_get_uint (&val); \ g_value_unset (&val); \ - return dcb_flags_to_string (v); \ + RETURN_STR_TO_FREE (dcb_flags_to_string (v)); \ } static char * @@ -2350,56 +2405,61 @@ dcb_app_priority_to_string (gint priority) } #define DEFINE_DCB_APP_PRIORITY_GETTER(func_name, property_name) \ - static char * \ + static gconstpointer \ func_name (ARGS_GET_FCN) \ { \ int v; \ GValue val = G_VALUE_INIT; \ + \ + RETURN_UNSUPPORTED_GET_TYPE (); \ g_value_init (&val, G_TYPE_INT); \ g_object_get_property (G_OBJECT (setting), property_name, &val); \ v = g_value_get_int (&val); \ g_value_unset (&val); \ - return dcb_app_priority_to_string (v); \ + RETURN_STR_TO_FREE (dcb_app_priority_to_string (v)); \ } #define DEFINE_DCB_BOOL_GETTER(func_name, getter_func_name) \ - static char * \ + static gconstpointer \ func_name (ARGS_GET_FCN) \ { \ NMSettingDcb *s_dcb = NM_SETTING_DCB (setting); \ GString *str; \ guint i; \ -\ + \ + RETURN_UNSUPPORTED_GET_TYPE (); \ + \ str = g_string_new (NULL); \ for (i = 0; i < 8; i++) { \ if (getter_func_name (s_dcb, i)) \ g_string_append_c (str, '1'); \ else \ g_string_append_c (str, '0'); \ -\ if (i < 7) \ g_string_append_c (str, ','); \ } \ -\ - return g_string_free (str, FALSE); \ + \ + RETURN_STR_TO_FREE (g_string_free (str, FALSE)); \ } #define DEFINE_DCB_UINT_GETTER(func_name, getter_func_name) \ - static char * \ + static gconstpointer \ func_name (ARGS_GET_FCN) \ { \ NMSettingDcb *s_dcb = NM_SETTING_DCB (setting); \ GString *str; \ guint i; \ - \ + \ + RETURN_UNSUPPORTED_GET_TYPE (); \ + \ str = g_string_new (NULL); \ for (i = 0; i < 8; i++) { \ g_string_append_printf (str, "%u", getter_func_name (s_dcb, i)); \ if (i < 7) \ g_string_append_c (str, ','); \ } \ -\ - return g_string_free (str, FALSE); \ + \ + RETURN_STR_TO_FREE (g_string_free (str, FALSE)); \ } DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_FLAGS) @@ -2719,30 +2779,34 @@ _set_fcn_infiniband_p_key (ARGS_SET_FCN) } -static char * +static gconstpointer _get_fcn_infiniband_p_key (ARGS_GET_FCN) { NMSettingInfiniband *s_infiniband = NM_SETTING_INFINIBAND (setting); int p_key; + RETURN_UNSUPPORTED_GET_TYPE (); + p_key = nm_setting_infiniband_get_p_key (s_infiniband); if (p_key == -1) { if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup ("default"); + return "default"; else - return g_strdup (_("default")); + return _("default"); } else - return g_strdup_printf ("0x%04x", p_key); + RETURN_STR_TO_FREE (g_strdup_printf ("0x%04x", p_key)); } -static char * +static gconstpointer _get_fcn_ip_tunnel_mode (ARGS_GET_FCN) { NMSettingIPTunnel *s_ip_tunnel = NM_SETTING_IP_TUNNEL (setting); NMIPTunnelMode mode; + RETURN_UNSUPPORTED_GET_TYPE (); + mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); - return nm_utils_enum_to_str (nm_ip_tunnel_mode_get_type (), mode); + RETURN_STR_TO_FREE (nm_utils_enum_to_str (nm_ip_tunnel_mode_get_type (), mode)); } static gboolean @@ -2783,7 +2847,7 @@ _parse_ip_address (int family, const char *address, GError **error) return ipaddr; } -static char * +static gconstpointer _get_fcn_ip_config_addresses (ARGS_GET_FCN) { NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); @@ -2791,6 +2855,8 @@ _get_fcn_ip_config_addresses (ARGS_GET_FCN) guint32 num_addresses, i; NMIPAddress *addr; + RETURN_UNSUPPORTED_GET_TYPE (); + printable = g_string_new (NULL); num_addresses = nm_setting_ip_config_get_num_addresses (s_ip); @@ -2805,10 +2871,10 @@ _get_fcn_ip_config_addresses (ARGS_GET_FCN) nm_ip_address_get_prefix (addr)); } - return g_string_free (printable, FALSE); + RETURN_STR_TO_FREE (g_string_free (printable, FALSE)); } -static char * +static gconstpointer _get_fcn_ip_config_routes (ARGS_GET_FCN) { NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); @@ -2816,6 +2882,8 @@ _get_fcn_ip_config_routes (ARGS_GET_FCN) guint32 num_routes, i; NMIPRoute *route; + RETURN_UNSUPPORTED_GET_TYPE (); + printable = g_string_new (NULL); num_routes = nm_setting_ip_config_get_num_routes (s_ip); @@ -2874,26 +2942,28 @@ _get_fcn_ip_config_routes (ARGS_GET_FCN) } } - return g_string_free (printable, FALSE); + RETURN_STR_TO_FREE (g_string_free (printable, FALSE)); } -static char * +static gconstpointer _get_fcn_ip4_config_dad_timeout (ARGS_GET_FCN) { NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); gint dad_timeout; + RETURN_UNSUPPORTED_GET_TYPE (); + dad_timeout = nm_setting_ip_config_get_dad_timeout (s_ip); if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup_printf ("%d", dad_timeout); + RETURN_STR_TO_FREE (g_strdup_printf ("%d", dad_timeout)); switch (dad_timeout) { case -1: - return g_strdup_printf (_("%d (default)"), dad_timeout); + RETURN_STR_TO_FREE (g_strdup_printf (_("%d (default)"), dad_timeout)); case 0: - return g_strdup_printf (_("%d (off)"), dad_timeout); + RETURN_STR_TO_FREE (g_strdup_printf (_("%d (off)"), dad_timeout)); default: - return g_strdup_printf ("%d", dad_timeout); + RETURN_STR_TO_FREE (g_strdup_printf ("%d", dad_timeout)); } } @@ -3166,11 +3236,12 @@ DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv4_config_routes, nm_setting_ip_config_remove_route, _validate_and_remove_ipv4_route) -static char * +static gconstpointer _get_fcn_ip6_config_ip6_privacy (ARGS_GET_FCN) { NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (setting); - return ip6_privacy_to_string (nm_setting_ip6_config_get_ip6_privacy (s_ip6), get_type); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (ip6_privacy_to_string (nm_setting_ip6_config_get_ip6_privacy (s_ip6), get_type)); } static const char *ipv6_valid_methods[] = { @@ -3465,14 +3536,16 @@ _set_fcn_ip6_config_ip6_privacy (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_macsec_mode (ARGS_GET_FCN) { NMSettingMacsec *s_macsec = NM_SETTING_MACSEC (setting); NMSettingMacsecMode mode; + RETURN_UNSUPPORTED_GET_TYPE (); + mode = nm_setting_macsec_get_mode (s_macsec); - return nm_utils_enum_to_str (nm_setting_macsec_mode_get_type (), mode); + RETURN_STR_TO_FREE (nm_utils_enum_to_str (nm_setting_macsec_mode_get_type (), mode)); } static gboolean @@ -3496,14 +3569,16 @@ _set_fcn_macsec_mode (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_macsec_validation (ARGS_GET_FCN) { NMSettingMacsec *s_macsec = NM_SETTING_MACSEC (setting); NMSettingMacsecValidation validation; + RETURN_UNSUPPORTED_GET_TYPE (); + validation = nm_setting_macsec_get_validation (s_macsec); - return nm_utils_enum_to_str (nm_setting_macsec_validation_get_type (), validation); + RETURN_STR_TO_FREE (nm_utils_enum_to_str (nm_setting_macsec_validation_get_type (), validation)); } static gboolean @@ -3527,23 +3602,26 @@ _set_fcn_macsec_validation (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_macvlan_mode (ARGS_GET_FCN) { NMSettingMacvlan *s_macvlan = NM_SETTING_MACVLAN (setting); NMSettingMacvlanMode mode; char *tmp, *str; + RETURN_UNSUPPORTED_GET_TYPE (); + mode = nm_setting_macvlan_get_mode (s_macvlan); tmp = nm_utils_enum_to_str (nm_setting_macvlan_mode_get_type (), mode); if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - str = g_strdup (tmp ? tmp : ""); - else - str = g_strdup_printf ("%d (%s)", mode, tmp ? tmp : ""); - g_free (tmp); + str = tmp ?: g_strdup (""); + else { + str = g_strdup_printf ("%d (%s)", mode, tmp ?: ""); + g_free (tmp); + } - return str; + RETURN_STR_TO_FREE (str); } static gboolean @@ -3576,20 +3654,22 @@ _set_fcn_macvlan_mode (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_olpc_mesh_ssid (ARGS_GET_FCN) { NMSettingOlpcMesh *s_olpc_mesh = NM_SETTING_OLPC_MESH (setting); GBytes *ssid; char *ssid_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + ssid = nm_setting_olpc_mesh_get_ssid (s_olpc_mesh); if (ssid) { ssid_str = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); } - return ssid_str; + RETURN_STR_TO_FREE (ssid_str); } static gboolean @@ -3607,14 +3687,16 @@ _set_fcn_olpc_mesh_channel (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_proxy_method (ARGS_GET_FCN) { NMSettingProxy *s_proxy = NM_SETTING_PROXY (setting); NMSettingProxyMethod method; + RETURN_UNSUPPORTED_GET_TYPE (); + method = nm_setting_proxy_get_method (s_proxy); - return nm_utils_enum_to_str (nm_setting_proxy_method_get_type (), method); + RETURN_STR_TO_FREE (nm_utils_enum_to_str (nm_setting_proxy_method_get_type (), method)); } static gboolean @@ -3659,19 +3741,21 @@ _set_fcn_proxy_pac_script (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_serial_parity (ARGS_GET_FCN) { NMSettingSerial *s_serial = NM_SETTING_SERIAL (setting); + RETURN_UNSUPPORTED_GET_TYPE (); + switch (nm_setting_serial_get_parity (s_serial)) { case NM_SETTING_SERIAL_PARITY_EVEN: - return g_strdup ("even"); + return "even"; case NM_SETTING_SERIAL_PARITY_ODD: - return g_strdup ("odd"); + return "odd"; default: case NM_SETTING_SERIAL_PARITY_NONE: - return g_strdup ("none"); + return "none"; } } @@ -3710,21 +3794,24 @@ _set_fcn_team_config (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_tun_mode (ARGS_GET_FCN) { NMSettingTun *s_tun = NM_SETTING_TUN (setting); NMSettingTunMode mode; char *tmp, *str; + RETURN_UNSUPPORTED_GET_TYPE (); + mode = nm_setting_tun_get_mode (s_tun); tmp = nm_utils_enum_to_str (nm_setting_tun_mode_get_type (), mode); if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - str = g_strdup_printf ("%s", tmp ? tmp : ""); - else + str = tmp ?: g_strdup (""); + else { str = g_strdup_printf ("%d (%s)", mode, tmp ? tmp : ""); - g_free (tmp); - return str; + g_free (tmp); + } + RETURN_STR_TO_FREE (str); } static gboolean @@ -3751,25 +3838,28 @@ _set_fcn_tun_mode (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_vlan_flags (ARGS_GET_FCN) { NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting); - return vlan_flags_to_string (nm_setting_vlan_get_flags (s_vlan), get_type); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (vlan_flags_to_string (nm_setting_vlan_get_flags (s_vlan), get_type)); } -static char * +static gconstpointer _get_fcn_vlan_ingress_priority_map (ARGS_GET_FCN) { NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting); - return vlan_priorities_to_string (s_vlan, NM_VLAN_INGRESS_MAP); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (vlan_priorities_to_string (s_vlan, NM_VLAN_INGRESS_MAP)); } -static char * +static gconstpointer _get_fcn_vlan_egress_priority_map (ARGS_GET_FCN) { NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting); - return vlan_priorities_to_string (s_vlan, NM_VLAN_EGRESS_MAP); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (vlan_priorities_to_string (s_vlan, NM_VLAN_EGRESS_MAP)); } static gboolean @@ -3882,28 +3972,32 @@ _remove_fcn_vlan_egress_priority_map (ARGS_REMOVE_FCN) error); } -static char * +static gconstpointer _get_fcn_vpn_data (ARGS_GET_FCN) { NMSettingVpn *s_vpn = NM_SETTING_VPN (setting); GString *data_item_str; + RETURN_UNSUPPORTED_GET_TYPE (); + data_item_str = g_string_new (NULL); nm_setting_vpn_foreach_data_item (s_vpn, &vpn_data_item, data_item_str); - return g_string_free (data_item_str, FALSE); + RETURN_STR_TO_FREE (g_string_free (data_item_str, FALSE)); } -static char * +static gconstpointer _get_fcn_vpn_secrets (ARGS_GET_FCN) { NMSettingVpn *s_vpn = NM_SETTING_VPN (setting); GString *secret_str; + RETURN_UNSUPPORTED_GET_TYPE (); + secret_str = g_string_new (NULL); nm_setting_vpn_foreach_secret (s_vpn, &vpn_data_item, secret_str); - return g_string_free (secret_str, FALSE); + RETURN_STR_TO_FREE (g_string_free (secret_str, FALSE)); } static const char * @@ -3938,13 +4032,15 @@ DEFINE_REMOVER_OPTION (_remove_fcn_vpn_secrets, NM_SETTING_VPN, nm_setting_vpn_remove_secret) -static char * +static gconstpointer _get_fcn_wired_wake_on_lan (ARGS_GET_FCN) { NMSettingWired *s_wired = NM_SETTING_WIRED (setting); NMSettingWiredWakeOnLan wol; char *tmp, *str; + RETURN_UNSUPPORTED_GET_TYPE (); + wol = nm_setting_wired_get_wake_on_lan (s_wired); tmp = nm_utils_enum_to_str (nm_setting_wired_wake_on_lan_get_type (), wol); if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) @@ -3952,7 +4048,7 @@ _get_fcn_wired_wake_on_lan (ARGS_GET_FCN) else str = g_strdup_printf ("%d (%s)", wol, tmp && *tmp ? tmp : "none"); g_free (tmp); - return str; + RETURN_STR_TO_FREE (str); } static gboolean @@ -4090,36 +4186,45 @@ _describe_fcn_wired_s390_options (ARGS_DESCRIBE_FCN) } -static char * +static gconstpointer _get_fcn_wireless_ssid (ARGS_GET_FCN) { NMSettingWireless *s_wireless = NM_SETTING_WIRELESS (setting); GBytes *ssid; char *ssid_str = NULL; + RETURN_UNSUPPORTED_GET_TYPE (); + ssid = nm_setting_wireless_get_ssid (s_wireless); if (ssid) { ssid_str = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); } - return ssid_str; + RETURN_STR_TO_FREE (ssid_str); } -static char * +static gconstpointer _get_fcn_wireless_mac_address_randomization (ARGS_GET_FCN) { NMSettingWireless *s_wifi = NM_SETTING_WIRELESS (setting); NMSettingMacRandomization randomization = nm_setting_wireless_get_mac_address_randomization (s_wifi); + const char *s; + + RETURN_UNSUPPORTED_GET_TYPE (); if (randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) - return g_strdup (_("default")); + s = N_("default"); else if (randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER) - return g_strdup (_("never")); + s = N_("never"); else if (randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) - return g_strdup_printf (_("always")); + s = N_("always"); else - return g_strdup_printf (_("unknown")); + s = N_("unknown"); + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(s); + return s; } static gboolean @@ -4202,38 +4307,47 @@ _set_fcn_wireless_mac_address_randomization (ARGS_SET_FCN) return TRUE; } -static char * +static gconstpointer _get_fcn_wireless_security_wep_key0 (ARGS_GET_FCN) { NMSettingWirelessSecurity *s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (setting); - return g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0)); + + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0))); } -static char * +static gconstpointer _get_fcn_wireless_security_wep_key1 (ARGS_GET_FCN) { NMSettingWirelessSecurity *s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (setting); - return g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)); + + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1))); } -static char * +static gconstpointer _get_fcn_wireless_security_wep_key2 (ARGS_GET_FCN) { NMSettingWirelessSecurity *s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (setting); - return g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2)); + + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2))); } -static char * +static gconstpointer _get_fcn_wireless_security_wep_key3 (ARGS_GET_FCN) { NMSettingWirelessSecurity *s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (setting); - return g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3)); + + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (g_strdup (nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3))); } -static char * +static gconstpointer _get_fcn_wireless_security_wep_key_type (ARGS_GET_FCN) { - return wep_key_type_to_string (nm_setting_wireless_security_get_wep_key_type (NM_SETTING_WIRELESS_SECURITY (setting))); + RETURN_UNSUPPORTED_GET_TYPE (); + RETURN_STR_TO_FREE (wep_key_type_to_string (nm_setting_wireless_security_get_wep_key_type (NM_SETTING_WIRELESS_SECURITY (setting)))); } static const char *wifi_sec_valid_protos[] = { "wpa", "rsn", NULL }; @@ -6638,12 +6752,15 @@ _meta_type_property_info_get_fcn (const NMMetaAbstractInfo *abstract_info, return NM_META_TEXT_HIDDEN; } - return (*out_to_free = info->property_type->get_fcn (info, - environment, - environment_user_data, - target, - get_type, - get_flags)); + return info->property_type->get_fcn (info, + environment, + environment_user_data, + target, + get_type, + get_flags, + out_flags, + out_to_free); + } static const NMMetaAbstractInfo *const* diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index da236eb7e6..66bf32272a 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -117,13 +117,14 @@ struct _NMMetaPropertyType { const char *(*describe_fcn) (const NMMetaPropertyInfo *property_info, char **out_to_free); - - char *(*get_fcn) (const NMMetaPropertyInfo *property_info, - const NMMetaEnvironment *environment, - gpointer environment_user_data, - NMSetting *setting, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags); + gconstpointer (*get_fcn) (const NMMetaPropertyInfo *property_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, + NMSetting *setting, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gpointer *out_to_free); gboolean (*set_fcn) (const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, From 2ba39a3b333f42d5278f76b68b11eef0e579f958 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 14:39:20 +0200 Subject: [PATCH 16/32] cli: don't translate text in terse mode --- clients/common/nm-meta-setting-desc.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index ad7df3ca62..69d95c6efc 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -477,6 +477,14 @@ nmc_team_check_config (const char *config, char **out_config, GError **error) return TRUE; } +static const char * +_get_text_hidden (NMMetaAccessorGetType get_type) +{ + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(NM_META_TEXT_HIDDEN); + return NM_META_TEXT_HIDDEN; +} + /*****************************************************************************/ G_GNUC_PRINTF (4, 5) @@ -1677,7 +1685,7 @@ _get_fcn_802_1x_client_cert (ARGS_GET_FCN) if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) cert_str = bytes_to_string (nm_setting_802_1x_get_client_cert_blob (s_8021X)); else - return _(NM_META_TEXT_HIDDEN); + return _get_text_hidden (get_type); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: cert_str = g_strdup (nm_setting_802_1x_get_client_cert_path (s_8021X)); @@ -1730,7 +1738,7 @@ _get_fcn_802_1x_phase2_client_cert (ARGS_GET_FCN) if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) cert_str = bytes_to_string (nm_setting_802_1x_get_phase2_client_cert_blob (s_8021X)); else - return _(NM_META_TEXT_HIDDEN); + return _get_text_hidden (get_type); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: cert_str = g_strdup (nm_setting_802_1x_get_phase2_client_cert_path (s_8021X)); @@ -1767,7 +1775,7 @@ _get_fcn_802_1x_private_key (ARGS_GET_FCN) if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) key_str = bytes_to_string (nm_setting_802_1x_get_private_key_blob (s_8021X)); else - return _(NM_META_TEXT_HIDDEN); + return _get_text_hidden (get_type); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: key_str = g_strdup (nm_setting_802_1x_get_private_key_path (s_8021X)); @@ -1795,7 +1803,7 @@ _get_fcn_802_1x_phase2_private_key (ARGS_GET_FCN) if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) key_str = bytes_to_string (nm_setting_802_1x_get_phase2_private_key_blob (s_8021X)); else - return _(NM_META_TEXT_HIDDEN); + return _get_text_hidden (get_type); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X)); @@ -6746,11 +6754,8 @@ _meta_type_property_info_get_fcn (const NMMetaAbstractInfo *abstract_info, nm_assert (out_to_free); if ( info->is_secret - && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) { - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - return _(NM_META_TEXT_HIDDEN); - return NM_META_TEXT_HIDDEN; - } + && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) + return _get_text_hidden (get_type); return info->property_type->get_fcn (info, environment, From e5ebf7a7ef71e3c2577e0741af8448bc2a3551dd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 16:20:45 +0200 Subject: [PATCH 17/32] cli: move property option flags to nm-meta-settings-desc.h --- clients/cli/connections.c | 244 +++++++++++++------------- clients/common/nm-meta-setting-desc.h | 10 ++ 2 files changed, 128 insertions(+), 126 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index e842d2ba12..6d232dca26 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -47,15 +47,7 @@ struct _OptionInfo { const char *setting_name; const char *property; const char *option; - enum { - OPTION_NONE = 0x00, - OPTION_REQD = 0x01, /* Don't ask to ask. */ - OPTION_DONT_ASK = 0x02, /* Don't ask interactively by default */ - OPTION_MULTI = 0x04, /* Ask multiple times, do an append instead of set. */ - - OPTION_DISABLED = 0x10, /* Don't ask due to runtime decision. */ - OPTION_ENABLED = 0x20, /* Override OPTION_DONT_ASK due to runtime decision. */ - } flags; + NMMetaPropertyInfFlags flags; const char *prompt; const char *def_hint; gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, OptionInfo *option, const char *value, GError **error); @@ -3537,10 +3529,10 @@ enable_options (const gchar *setting_name, const gchar *property, const gchar * for (candidate = option_info; candidate->setting_name; candidate++) { if ( strcmp (candidate->setting_name, setting_name) == 0 && strcmp (candidate->property, property) == 0 - && (candidate->flags & OPTION_DONT_ASK) + && (candidate->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) && candidate->option && g_strv_contains (opts, candidate->option)) { - candidate->flags |= OPTION_ENABLED; + candidate->flags |= NM_META_PROPERTY_INF_FLAG_ENABLED; } } } @@ -3558,7 +3550,7 @@ disable_options (const gchar *setting_name, const gchar *property) for (candidate = option_info; candidate->setting_name; candidate++) { if ( strcmp (candidate->setting_name, setting_name) == 0 && (!property || strcmp (candidate->property, property) == 0)) - candidate->flags |= OPTION_DISABLED; + candidate->flags |= NM_META_PROPERTY_INF_FLAG_DISABLED; } } @@ -3573,8 +3565,8 @@ reset_options (void) OptionInfo *candidate; for (candidate = option_info; candidate->setting_name; candidate++) { - candidate->flags &= ~OPTION_DISABLED; - candidate->flags &= ~OPTION_ENABLED; + candidate->flags &= ~NM_META_PROPERTY_INF_FLAG_DISABLED; + candidate->flags &= ~NM_META_PROPERTY_INF_FLAG_ENABLED; } } @@ -3658,13 +3650,13 @@ set_property (NMConnection *connection, static gboolean set_option (NmCli *nmc, NMConnection *connection, OptionInfo *option, const gchar *value, GError **error) { - option->flags |= OPTION_DISABLED; + option->flags |= NM_META_PROPERTY_INF_FLAG_DISABLED; if (option->check_and_set) { return option->check_and_set (nmc, connection, option, value, error); } else if (value) { return set_property (connection, option->setting_name, option->property, - value, option->flags & OPTION_MULTI ? '+' : '\0', error); - } else if (option->flags & OPTION_REQD) { + value, option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); + } else if (option->flags & NM_META_PROPERTY_INF_FLAG_REQD) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("Error: '%s' is mandatory."), option->option); return FALSE; @@ -4162,7 +4154,7 @@ set_ip4_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char * NULL); } return set_property (con, option->setting_name, option->property, value, - option->flags & OPTION_MULTI ? '+' : '\0', error); + option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); } static gboolean @@ -4182,156 +4174,156 @@ set_ip6_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char * NULL); } return set_property (con, option->setting_name, option->property, value, - option->flags & OPTION_MULTI ? '+' : '\0', error); + option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); } /*----------------------------------------------------------------------------*/ static OptionInfo option_info[] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, "type", OPTION_REQD, PROMPT_CON_TYPE, NULL, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, "type", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_CON_TYPE, NULL, set_connection_type, gen_connection_types }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID, "con-name", OPTION_DONT_ASK, NULL, NULL, NULL, NULL }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", OPTION_DONT_ASK, NULL, NULL, NULL, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID, "con-name", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, NULL }, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, gen_func_bool_values_l10n }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", OPTION_REQD, PROMPT_IFNAME, NULL, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_IFNAME, NULL, set_connection_iface, nmc_rl_gen_func_ifnames }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER, "master", OPTION_DONT_ASK, PROMPT_MASTER, NULL, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER, "master", NM_META_PROPERTY_INF_FLAG_DONT_ASK, PROMPT_MASTER, NULL, set_connection_master, gen_func_master_ifnames }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE, "slave-type", OPTION_DONT_ASK, NULL, NULL, NULL, + { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE, "slave-type", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, gen_func_slave_type }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME, "username", OPTION_REQD, N_("PPPoE username"), NULL, NULL, NULL }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_PASSWORD, "password", OPTION_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_SERVICE, "service", OPTION_NONE, N_("Service [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, "mtu", OPTION_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS, "mac", OPTION_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "cloned-mac", OPTION_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU, "mtu", OPTION_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS, "mac", OPTION_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", OPTION_NONE, PROMPT_IB_MODE, PROMPT_IB_MODE_CHOICES, + { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME, "username", NM_META_PROPERTY_INF_FLAG_REQD, N_("PPPoE username"), NULL, NULL, NULL }, + { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, + { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_SERVICE, "service", NM_META_PROPERTY_INF_FLAG_NONE, N_("Service [none]"), NULL, NULL, NULL }, + { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, + { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "cloned-mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, + { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_IB_MODE, PROMPT_IB_MODE_CHOICES, NULL, gen_func_ib_type }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_PARENT, "parent", OPTION_NONE, N_("Parent interface [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_P_KEY, "p-key", OPTION_NONE, N_("P_KEY [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, "ssid", OPTION_REQD, N_("SSID"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE, "mode", OPTION_NONE, PROMPT_WIFI_MODE, PROMPT_WIFI_MODE_CHOICES, + { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_PARENT, "parent", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent interface [none]"), NULL, NULL, NULL }, + { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_P_KEY, "p-key", NM_META_PROPERTY_INF_FLAG_NONE, N_("P_KEY [none]"), NULL, NULL, NULL }, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, "ssid", NM_META_PROPERTY_INF_FLAG_REQD, N_("SSID"), NULL, NULL, NULL }, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_WIFI_MODE, PROMPT_WIFI_MODE_CHOICES, NULL, gen_func_wifi_mode }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MTU, "mtu", OPTION_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS, "mac", OPTION_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "cloned-mac", OPTION_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_NETWORK_NAME, "nsp", OPTION_REQD, N_("WiMAX NSP name"), NULL, NULL, NULL }, - { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS, "mac", OPTION_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN, "apn", OPTION_REQD, N_("APN"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME, "user", OPTION_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_PASSWORD, "password", OPTION_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_USERNAME, "user", OPTION_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_PASSWORD, "password", OPTION_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR, "addr", OPTION_REQD, N_("Bluetooth device address"), NULL, NULL, NULL }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE, "bt-type", OPTION_NONE, PROMPT_BT_TYPE, PROMPT_BT_TYPE_CHOICES, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "cloned-mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_NETWORK_NAME, "nsp", NM_META_PROPERTY_INF_FLAG_REQD, N_("WiMAX NSP name"), NULL, NULL, NULL }, + { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN, "apn", NM_META_PROPERTY_INF_FLAG_REQD, N_("APN"), NULL, NULL, NULL }, + { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, + { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, + { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_USERNAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, + { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR, "addr", NM_META_PROPERTY_INF_FLAG_REQD, N_("Bluetooth device address"), NULL, NULL, NULL }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE, "bt-type", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_BT_TYPE, PROMPT_BT_TYPE_CHOICES, set_bluetooth_type, gen_func_bt_type }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT, "dev", OPTION_REQD, N_("VLAN parent device or connection UUID"), NULL, + { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("VLAN parent device or connection UUID"), NULL, NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID, "id", OPTION_REQD, N_("VLAN ID (<0-4094>)"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS, "flags", OPTION_NONE, N_("VLAN flags (<0-7>) [none]"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, "ingress", OPTION_NONE, N_("Ingress priority maps [none]"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, "egress", OPTION_NONE, N_("Egress priority maps [none]"), NULL, NULL, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "mode", OPTION_NONE, PROMPT_BOND_MODE, "[balance-rr]", + { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID, "id", NM_META_PROPERTY_INF_FLAG_REQD, N_("VLAN ID (<0-4094>)"), NULL, NULL, NULL }, + { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS, "flags", NM_META_PROPERTY_INF_FLAG_NONE, N_("VLAN flags (<0-7>) [none]"), NULL, NULL, NULL }, + { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, "ingress", NM_META_PROPERTY_INF_FLAG_NONE, N_("Ingress priority maps [none]"), NULL, NULL, NULL }, + { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, "egress", NM_META_PROPERTY_INF_FLAG_NONE, N_("Egress priority maps [none]"), NULL, NULL, NULL }, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_BOND_MODE, "[balance-rr]", set_bond_option, gen_func_bond_mode }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "primary", OPTION_DONT_ASK, N_("Bonding primary interface [none]"), + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "primary", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding primary interface [none]"), NULL, set_bond_option, nmc_rl_gen_func_ifnames }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, NULL, OPTION_NONE, N_("Bonding monitoring mode"), PROMPT_BOND_MON_MODE_CHOICES, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, NULL, NM_META_PROPERTY_INF_FLAG_NONE, N_("Bonding monitoring mode"), PROMPT_BOND_MON_MODE_CHOICES, set_bond_monitoring_mode, gen_func_bond_mon_mode }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "miimon", OPTION_DONT_ASK, N_("Bonding miimon [100]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "downdelay", OPTION_DONT_ASK, N_("Bonding downdelay [0]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "updelay", OPTION_DONT_ASK, N_("Bonding updelay [0]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-interval", OPTION_DONT_ASK, N_("Bonding arp-interval [0]"), NULL, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "miimon", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding miimon [100]"), NULL, set_bond_option, NULL }, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "downdelay", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding downdelay [0]"), NULL, set_bond_option, NULL }, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "updelay", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding updelay [0]"), NULL, set_bond_option, NULL }, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-interval", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding arp-interval [0]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-ip-target", OPTION_DONT_ASK, N_("Bonding arp-ip-target [none]"), + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-ip-target", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding arp-ip-target [none]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "lacp-rate", OPTION_DONT_ASK, N_("LACP rate ('slow' or 'fast') [slow]"), NULL, + { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "lacp-rate", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("LACP rate ('slow' or 'fast') [slow]"), NULL, set_bond_option, gen_func_bond_lacp_rate }, - { NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_CONFIG, "config", OPTION_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, - { NM_SETTING_TEAM_PORT_SETTING_NAME, NM_SETTING_TEAM_PORT_CONFIG, "config", OPTION_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_STP, "stp", OPTION_NONE, N_("Enable STP [no]"), NULL, + { NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_CONFIG, "config", NM_META_PROPERTY_INF_FLAG_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, + { NM_SETTING_TEAM_PORT_SETTING_NAME, NM_SETTING_TEAM_PORT_CONFIG, "config", NM_META_PROPERTY_INF_FLAG_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_STP, "stp", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable STP [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_PRIORITY, "priority", OPTION_NONE, N_("STP priority [32768]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_FORWARD_DELAY, "forward-delay", OPTION_NONE, N_("Forward delay [15]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_HELLO_TIME, "hello-time", OPTION_NONE, N_("Hello time [2]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAX_AGE, "max-age", OPTION_NONE, N_("Max age [20]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_AGEING_TIME, "ageing-time", OPTION_NONE, N_("MAC address ageing time [300]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "multicast-snooping", OPTION_NONE, N_("Enable IGMP snooping [no]"), NULL, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_PRIORITY, "priority", NM_META_PROPERTY_INF_FLAG_NONE, N_("STP priority [32768]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_FORWARD_DELAY, "forward-delay", NM_META_PROPERTY_INF_FLAG_NONE, N_("Forward delay [15]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_HELLO_TIME, "hello-time", NM_META_PROPERTY_INF_FLAG_NONE, N_("Hello time [2]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAX_AGE, "max-age", NM_META_PROPERTY_INF_FLAG_NONE, N_("Max age [20]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_AGEING_TIME, "ageing-time", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC address ageing time [300]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "multicast-snooping", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable IGMP snooping [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS, "mac", OPTION_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PRIORITY, "priority", OPTION_NONE, N_("Bridge port priority [32]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PATH_COST, "path-cost", OPTION_NONE, N_("Bridge port STP path cost [100]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin", OPTION_NONE, N_("Hairpin [no]"), NULL, + { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PRIORITY, "priority", NM_META_PROPERTY_INF_FLAG_NONE, N_("Bridge port priority [32]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PATH_COST, "path-cost", NM_META_PROPERTY_INF_FLAG_NONE, N_("Bridge port STP path cost [100]"), NULL, NULL, NULL }, + { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin", NM_META_PROPERTY_INF_FLAG_NONE, N_("Hairpin [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", OPTION_REQD, PROMPT_VPN_TYPE, NULL, NULL, gen_func_vpn_types }, - { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME, "user", OPTION_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_SSID, "ssid", OPTION_REQD, N_("SSID"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_CHANNEL, "channel", OPTION_NONE, N_("OLPC Mesh channel [1]"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, "dhcp-anycast", OPTION_NONE, N_("DHCP anycast MAC address [none]"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME, "username", OPTION_REQD, N_("Username"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL, "protocol", OPTION_REQD, PROMPT_ADSL_PROTO, PROMPT_ADSL_PROTO_CHOICES, + { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_VPN_TYPE, NULL, NULL, gen_func_vpn_types }, + { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_SSID, "ssid", NM_META_PROPERTY_INF_FLAG_REQD, N_("SSID"), NULL, NULL, NULL }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_CHANNEL, "channel", NM_META_PROPERTY_INF_FLAG_NONE, N_("OLPC Mesh channel [1]"), NULL, NULL, NULL }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, "dhcp-anycast", NM_META_PROPERTY_INF_FLAG_NONE, N_("DHCP anycast MAC address [none]"), NULL, NULL, NULL }, + { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME, "username", NM_META_PROPERTY_INF_FLAG_REQD, N_("Username"), NULL, NULL, NULL }, + { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL, "protocol", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_ADSL_PROTO, PROMPT_ADSL_PROTO_CHOICES, NULL, gen_func_adsl_proto }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD, "password", OPTION_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", OPTION_NONE, PROMPT_ADSL_ENCAP, PROMPT_ADSL_ENCAP_CHOICES, + { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, + { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_ADSL_ENCAP, PROMPT_ADSL_ENCAP_CHOICES, NULL, gen_func_adsl_encap }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT, "dev", OPTION_REQD, N_("MACsec parent device or connection UUID"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MODE, "mode", OPTION_REQD, PROMPT_MACSEC_MODE, PROMPT_MACSEC_MODE_CHOICES, NULL, gen_func_macsec_mode }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_ENCRYPT, "encrypt", OPTION_NONE, N_("Enable encryption [yes]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CAK, "cak", OPTION_NONE, N_("MKA CAK"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CKN, "ckn", OPTION_NONE, N_("MKA_CKN"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT, "port", OPTION_NONE, N_("SCI port [1]"), NULL, NULL, NULL }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("MACsec parent device or connection UUID"), NULL, NULL, NULL }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_MACSEC_MODE, PROMPT_MACSEC_MODE_CHOICES, NULL, gen_func_macsec_mode }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_ENCRYPT, "encrypt", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable encryption [yes]"), NULL, set_yes_no, gen_func_bool_values_l10n }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CAK, "cak", NM_META_PROPERTY_INF_FLAG_NONE, N_("MKA CAK"), NULL, NULL, NULL }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CKN, "ckn", NM_META_PROPERTY_INF_FLAG_NONE, N_("MKA_CKN"), NULL, NULL, NULL }, + { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT, "port", NM_META_PROPERTY_INF_FLAG_NONE, N_("SCI port [1]"), NULL, NULL, NULL }, - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT, "dev", OPTION_REQD, N_("MACVLAN parent device or connection UUID"), NULL, + { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("MACVLAN parent device or connection UUID"), NULL, NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_MODE, "mode", OPTION_REQD, PROMPT_MACVLAN_MODE, NULL, + { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_MACVLAN_MODE, NULL, NULL, gen_func_macvlan_mode }, - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_TAP, "tap", OPTION_NONE, N_("Tap [no]"), NULL, + { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_TAP, "tap", NM_META_PROPERTY_INF_FLAG_NONE, N_("Tap [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_ID, "id", OPTION_REQD, N_("VXLAN ID"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE, "remote", OPTION_REQD, N_("Remote"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_PARENT, "dev", OPTION_NONE, N_("Parent device [none]"), NULL, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_ID, "id", NM_META_PROPERTY_INF_FLAG_REQD, N_("VXLAN ID"), NULL, NULL, NULL }, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE, "remote", NM_META_PROPERTY_INF_FLAG_REQD, N_("Remote"), NULL, NULL, NULL }, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent device [none]"), NULL, NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_LOCAL, "local", OPTION_NONE, N_("Local address [none]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MIN, "source-port-min", OPTION_NONE, N_("Minimum source port [0]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MAX, "source-port-max", OPTION_NONE, N_("Maximum source port [0]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_DESTINATION_PORT, "destination-port", OPTION_NONE, N_("Destination port [8472]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MODE, "mode", OPTION_NONE, PROMPT_TUN_MODE, PROMPT_TUN_MODE_CHOICES, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_LOCAL, "local", NM_META_PROPERTY_INF_FLAG_NONE, N_("Local address [none]"), NULL, NULL, NULL }, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MIN, "source-port-min", NM_META_PROPERTY_INF_FLAG_NONE, N_("Minimum source port [0]"), NULL, NULL, NULL }, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MAX, "source-port-max", NM_META_PROPERTY_INF_FLAG_NONE, N_("Maximum source port [0]"), NULL, NULL, NULL }, + { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_DESTINATION_PORT, "destination-port", NM_META_PROPERTY_INF_FLAG_NONE, N_("Destination port [8472]"), NULL, NULL, NULL }, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MODE, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_TUN_MODE, PROMPT_TUN_MODE_CHOICES, NULL, gen_func_tun_mode }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_OWNER, "owner", OPTION_NONE, N_("User ID [none]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_GROUP, "group", OPTION_NONE, N_("Group ID [none]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_PI, "pi", OPTION_NONE, N_("Enable PI [no]"), NULL, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_OWNER, "owner", NM_META_PROPERTY_INF_FLAG_NONE, N_("User ID [none]"), NULL, NULL, NULL }, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_GROUP, "group", NM_META_PROPERTY_INF_FLAG_NONE, N_("Group ID [none]"), NULL, NULL, NULL }, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_PI, "pi", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable PI [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_VNET_HDR, "vnet-hdr", OPTION_NONE, N_("Enable VNET header [no]"), NULL, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_VNET_HDR, "vnet-hdr", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable VNET header [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MULTI_QUEUE, "multi-queue", OPTION_NONE, N_("Enable multi queue [no]"), NULL, + { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MULTI_QUEUE, "multi-queue", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable multi queue [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE, "mode", OPTION_REQD, PROMPT_IP_TUNNEL_MODE, NULL, NULL, gen_func_ip_tunnel_mode }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL, "local", OPTION_NONE, N_("Local endpoint [none]"), NULL, NULL, NULL }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE, "remote", OPTION_REQD, N_("Remote"), NULL, NULL, NULL }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_PARENT, "dev", OPTION_NONE, N_("Parent device [none]"), NULL, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_IP_TUNNEL_MODE, NULL, NULL, gen_func_ip_tunnel_mode }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL, "local", NM_META_PROPERTY_INF_FLAG_NONE, N_("Local endpoint [none]"), NULL, NULL, NULL }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE, "remote", NM_META_PROPERTY_INF_FLAG_REQD, N_("Remote"), NULL, NULL, NULL }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent device [none]"), NULL, NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", OPTION_MULTI, N_("IPv4 address (IP[/plen]) [none]"), NULL, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", NM_META_PROPERTY_INF_FLAG_MULTI, N_("IPv4 address (IP[/plen]) [none]"), NULL, set_ip4_address, NULL }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw4", OPTION_NONE, N_("IPv4 gateway [none]"), NULL, NULL, NULL }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", OPTION_MULTI, N_("IPv6 address (IP[/plen]) [none]"), NULL, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw4", NM_META_PROPERTY_INF_FLAG_NONE, N_("IPv4 gateway [none]"), NULL, NULL, NULL }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", NM_META_PROPERTY_INF_FLAG_MULTI, N_("IPv6 address (IP[/plen]) [none]"), NULL, set_ip6_address, NULL }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw6", OPTION_NONE, N_("IPv6 gateway [none]"), NULL, NULL, NULL }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_METHOD, "method", OPTION_NONE, PROMPT_PROXY_METHOD, PROMPT_PROXY_METHOD_CHOICES, NULL, gen_func_proxy_method }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_BROWSER_ONLY, "browser-only", OPTION_NONE, N_("Browser only [no]"), NULL, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw6", NM_META_PROPERTY_INF_FLAG_NONE, N_("IPv6 gateway [none]"), NULL, NULL, NULL }, + { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_METHOD, "method", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_PROXY_METHOD, PROMPT_PROXY_METHOD_CHOICES, NULL, gen_func_proxy_method }, + { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_BROWSER_ONLY, "browser-only", NM_META_PROPERTY_INF_FLAG_NONE, N_("Browser only [no]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL, "pac-url", OPTION_NONE, N_("PAC URL"), NULL, NULL, NULL }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT, "pac-script", OPTION_NONE, N_("PAC script"), NULL, NULL, NULL }, - { NULL, NULL, NULL, OPTION_NONE, NULL, NULL, NULL, NULL }, + { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL, "pac-url", NM_META_PROPERTY_INF_FLAG_NONE, N_("PAC URL"), NULL, NULL, NULL }, + { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT, "pac-script", NM_META_PROPERTY_INF_FLAG_NONE, N_("PAC script"), NULL, NULL, NULL }, + { NULL, NULL, NULL, NM_META_PROPERTY_INF_FLAG_NONE, NULL, NULL, NULL, NULL }, }; static gboolean option_relevant (NMConnection *connection, OptionInfo *option) { - if (option->flags & OPTION_DONT_ASK && !(option->flags & OPTION_ENABLED)) + if (option->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK && !(option->flags & NM_META_PROPERTY_INF_FLAG_ENABLED)) return FALSE; - if (option->flags & OPTION_DISABLED) + if (option->flags & NM_META_PROPERTY_INF_FLAG_DISABLED) return FALSE; if (!nm_connection_get_setting_by_name (connection, option->setting_name)) return FALSE; @@ -4724,7 +4716,7 @@ ask_option (NmCli *nmc, NMConnection *connection, OptionInfo *option) gchar *value; GError *error = NULL; gs_free gchar *prompt = NULL; - gboolean multi = option->flags & OPTION_MULTI; + gboolean multi = option->flags & NM_META_PROPERTY_INF_FLAG_MULTI; prompt = g_strjoin ("", gettext (option->prompt), @@ -4760,7 +4752,7 @@ questionnaire_mandatory (NmCli *nmc, NMConnection *connection) for (candidate = option_info; candidate->setting_name; candidate++) { if (!option_relevant (connection, candidate)) continue; - if (candidate->flags & OPTION_REQD || candidate->flags & OPTION_ENABLED) + if (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD || candidate->flags & NM_META_PROPERTY_INF_FLAG_ENABLED) ask_option (nmc, connection, candidate); } } @@ -4999,7 +4991,7 @@ read_properties: for (candidate = option_info; candidate->setting_name; candidate++) { if (!option_relevant (connection, candidate)) continue; - if (candidate->flags & OPTION_REQD) { + if (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD) { g_string_printf (nmc->return_text, _("Error: '%s' argument is required."), candidate->option); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 66bf32272a..9f76445cc7 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -167,6 +167,16 @@ struct _NMMetaPropertyTypData { NMMetaPropertyTypFlags typ_flags; }; +typedef enum { + NM_META_PROPERTY_INF_FLAG_NONE = 0x00, + NM_META_PROPERTY_INF_FLAG_REQD = 0x01, /* Don't ask to ask. */ + NM_META_PROPERTY_INF_FLAG_DONT_ASK = 0x02, /* Don't ask interactively by default */ + NM_META_PROPERTY_INF_FLAG_MULTI = 0x04, /* Ask multiple times, do an append instead of set. */ + + NM_META_PROPERTY_INF_FLAG_DISABLED = 0x10, /* Don't ask due to runtime decision. */ + NM_META_PROPERTY_INF_FLAG_ENABLED = 0x20, /* Override NM_META_PROPERTY_INF_FLAG_DONT_ASK due to runtime decision. */ +} NMMetaPropertyInfFlags; + struct _NMMetaPropertyInfo { const NMMetaType *meta_type; From 6763097cc9d77caaee3c3825c05d299596b15726 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 18:30:12 +0200 Subject: [PATCH 18/32] cli: make OptionInfo immutable Don't mutate global state. For now, hack around it by putting the mutable flags to a separate (global) cache. Obviously, it still uses global data, but it no longer touches the global option_info list. --- clients/cli/connections.c | 117 +++++++++++++++++--------- clients/common/nm-meta-setting-desc.h | 3 - 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 6d232dca26..f454dc4c73 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -42,15 +42,22 @@ #include "devices.h" #include "polkit-agent.h" +typedef enum { + PROPERTY_INF_FLAG_NONE = 0x0, + PROPERTY_INF_FLAG_DISABLED = 0x1, /* Don't ask due to runtime decision. */ + PROPERTY_INF_FLAG_ENABLED = 0x2, /* Override NM_META_PROPERTY_INF_FLAG_DONT_ASK due to runtime decision. */ + PROPERTY_INF_FLAG_ALL = 0x3, +} PropertyInfFlags; + typedef struct _OptionInfo OptionInfo; struct _OptionInfo { const char *setting_name; const char *property; const char *option; - NMMetaPropertyInfFlags flags; + const NMMetaPropertyInfFlags flags; const char *prompt; const char *def_hint; - gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, OptionInfo *option, const char *value, GError **error); + gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, const OptionInfo *option, const char *value, GError **error); rl_compentry_func_t *generator_func; }; @@ -3515,7 +3522,36 @@ set_default_interface_name (NmCli *nmc, NMSettingConnection *s_con) /*----------------------------------------------------------------------------*/ -static OptionInfo option_info[]; +static const OptionInfo option_info[]; + +static PropertyInfFlags +_options_set (const OptionInfo *option, + PropertyInfFlags mask, PropertyInfFlags set) +{ + static GHashTable *cache = NULL; + gpointer p; + PropertyInfFlags v, v2; + + if (G_UNLIKELY (!cache)) + cache = g_hash_table_new (NULL, NULL); + + if (g_hash_table_lookup_extended (cache, (gpointer) option, NULL, &p)) + v = GPOINTER_TO_UINT (p); + else + v = 0; + + v2 = (v & ~mask) | (mask & set); + if (v != v2) + g_hash_table_insert (cache, (gpointer) option, GUINT_TO_POINTER (v2)); + + return v2; +} + +static PropertyInfFlags +_options_get (const OptionInfo *option) +{ + return _options_set (option, 0, 0); +} /* * Mark options in option_info as relevant. @@ -3524,16 +3560,15 @@ static OptionInfo option_info[]; static void enable_options (const gchar *setting_name, const gchar *property, const gchar * const *opts) { - OptionInfo *candidate; + const OptionInfo *candidate; for (candidate = option_info; candidate->setting_name; candidate++) { if ( strcmp (candidate->setting_name, setting_name) == 0 && strcmp (candidate->property, property) == 0 && (candidate->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) && candidate->option - && g_strv_contains (opts, candidate->option)) { - candidate->flags |= NM_META_PROPERTY_INF_FLAG_ENABLED; - } + && g_strv_contains (opts, candidate->option)) + _options_set (candidate, PROPERTY_INF_FLAG_ENABLED, PROPERTY_INF_FLAG_ENABLED); } } @@ -3545,12 +3580,12 @@ enable_options (const gchar *setting_name, const gchar *property, const gchar * static void disable_options (const gchar *setting_name, const gchar *property) { - OptionInfo *candidate; + const OptionInfo *candidate; for (candidate = option_info; candidate->setting_name; candidate++) { if ( strcmp (candidate->setting_name, setting_name) == 0 && (!property || strcmp (candidate->property, property) == 0)) - candidate->flags |= NM_META_PROPERTY_INF_FLAG_DISABLED; + _options_set (candidate, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); } } @@ -3562,12 +3597,10 @@ disable_options (const gchar *setting_name, const gchar *property) static void reset_options (void) { - OptionInfo *candidate; + const OptionInfo *candidate; - for (candidate = option_info; candidate->setting_name; candidate++) { - candidate->flags &= ~NM_META_PROPERTY_INF_FLAG_DISABLED; - candidate->flags &= ~NM_META_PROPERTY_INF_FLAG_ENABLED; - } + for (candidate = option_info; candidate->setting_name; candidate++) + _options_set (candidate, PROPERTY_INF_FLAG_ALL, 0); } static gboolean @@ -3648,9 +3681,9 @@ set_property (NMConnection *connection, } static gboolean -set_option (NmCli *nmc, NMConnection *connection, OptionInfo *option, const gchar *value, GError **error) +set_option (NmCli *nmc, NMConnection *connection, const OptionInfo *option, const gchar *value, GError **error) { - option->flags |= NM_META_PROPERTY_INF_FLAG_DISABLED; + _options_set (option, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); if (option->check_and_set) { return option->check_and_set (nmc, connection, option, value, error); } else if (value) { @@ -3903,7 +3936,7 @@ gen_func_master_ifnames (const char *text, int state) /*----------------------------------------------------------------------------*/ static gboolean -set_connection_type (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { const NameItem *type_settings, *slv_settings; GError *local = NULL; @@ -3965,7 +3998,7 @@ set_connection_type (NmCli *nmc, NMConnection *con, OptionInfo *option, const ch } static gboolean -set_connection_iface (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_connection_iface (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { GError *tmp_error = NULL; @@ -3985,7 +4018,7 @@ set_connection_iface (NmCli *nmc, NMConnection *con, OptionInfo *option, const c } static gboolean -set_connection_master (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_connection_master (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { const GPtrArray *connections; NMSettingConnection *s_con; @@ -4014,7 +4047,7 @@ set_connection_master (NmCli *nmc, NMConnection *con, OptionInfo *option, const } static gboolean -set_bond_option (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_bond_option (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { NMSettingBond *s_bond; gboolean success; @@ -4063,7 +4096,7 @@ set_bond_option (NmCli *nmc, NMConnection *con, OptionInfo *option, const char * } static gboolean -set_bond_monitoring_mode (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_bond_monitoring_mode (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { NMSettingBond *s_bond; gs_free gchar *monitor_mode = NULL; @@ -4095,7 +4128,7 @@ set_bond_monitoring_mode (NmCli *nmc, NMConnection *con, OptionInfo *option, con } static gboolean -set_bluetooth_type (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_bluetooth_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { NMSetting *setting; @@ -4127,7 +4160,7 @@ set_bluetooth_type (NmCli *nmc, NMConnection *con, OptionInfo *option, const cha } static gboolean -set_yes_no (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_yes_no (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { if (g_strcmp0 (value, _(WORD_LOC_YES))) value = WORD_YES; @@ -4138,7 +4171,7 @@ set_yes_no (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value } static gboolean -set_ip4_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_ip4_address (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { NMSettingIPConfig *s_ip4; @@ -4158,7 +4191,7 @@ set_ip4_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char * } static gboolean -set_ip6_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) +set_ip6_address (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { NMSettingIPConfig *s_ip6; @@ -4180,7 +4213,7 @@ set_ip6_address (NmCli *nmc, NMConnection *con, OptionInfo *option, const char * /*----------------------------------------------------------------------------*/ -static OptionInfo option_info[] = { +static const OptionInfo option_info[] = { { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, "type", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_CON_TYPE, NULL, set_connection_type, gen_connection_types }, { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID, "con-name", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, NULL }, @@ -4319,11 +4352,12 @@ static OptionInfo option_info[] = { }; static gboolean -option_relevant (NMConnection *connection, OptionInfo *option) +option_relevant (NMConnection *connection, const OptionInfo *option) { - if (option->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK && !(option->flags & NM_META_PROPERTY_INF_FLAG_ENABLED)) + if ( (option->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) + && !(_options_get (option) & PROPERTY_INF_FLAG_ENABLED)) return FALSE; - if (option->flags & NM_META_PROPERTY_INF_FLAG_DISABLED) + if (_options_get (option) & PROPERTY_INF_FLAG_DISABLED) return FALSE; if (!nm_connection_get_setting_by_name (connection, option->setting_name)) return FALSE; @@ -4334,9 +4368,9 @@ option_relevant (NMConnection *connection, OptionInfo *option) static void complete_property_name (NmCli *nmc, NMConnection *connection, - char modifier, - const gchar *prefix, - const gchar *postfix) + char modifier, + const gchar *prefix, + const gchar *postfix) { NMSettingConnection *s_con; const NameItem *valid_settings_main = NULL; @@ -4345,7 +4379,7 @@ complete_property_name (NmCli *nmc, NMConnection *connection, const char *slave_type = NULL; gs_free char *slv_type = NULL; gs_free char *word_list = NULL; - OptionInfo *candidate; + const OptionInfo *candidate; connection_type = nm_connection_get_connection_type (connection); s_con = nm_connection_get_setting_connection (connection); @@ -4388,7 +4422,7 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix) } static void -complete_option (OptionInfo *option, const gchar *prefix) +complete_option (const OptionInfo *option, const gchar *prefix) { if (option->generator_func) run_rl_generator (option->generator_func, prefix); @@ -4480,8 +4514,8 @@ nmc_read_connection_properties (NmCli *nmc, */ /* Go through arguments and set properties */ do { - OptionInfo *candidate; - OptionInfo *chosen = NULL; + const OptionInfo *candidate; + const OptionInfo *chosen = NULL; gs_strfreev gchar **strv = NULL; const NameItem *type_settings, *slv_settings; char modifier = '\0'; @@ -4711,7 +4745,7 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) } static void -ask_option (NmCli *nmc, NMConnection *connection, OptionInfo *option) +ask_option (NmCli *nmc, NMConnection *connection, const OptionInfo *option) { gchar *value; GError *error = NULL; @@ -4746,13 +4780,14 @@ again: static void questionnaire_mandatory (NmCli *nmc, NMConnection *connection) { - OptionInfo *candidate; + const OptionInfo *candidate; /* Mandatory settings. */ for (candidate = option_info; candidate->setting_name; candidate++) { if (!option_relevant (connection, candidate)) continue; - if (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD || candidate->flags & NM_META_PROPERTY_INF_FLAG_ENABLED) + if ( (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD) + || (_options_get (candidate) & PROPERTY_INF_FLAG_ENABLED)) ask_option (nmc, connection, candidate); } } @@ -4836,7 +4871,7 @@ setting_name_to_name (const char *name) static gboolean questionnaire_one_optional (NmCli *nmc, NMConnection *connection) { - OptionInfo *candidate; + const OptionInfo *candidate; /* Optional settings. */ const gchar *setting_name = NULL; @@ -4880,7 +4915,7 @@ do_connection_add (NmCli *nmc, int argc, char **argv) GError *error = NULL; AddConnectionInfo *info = NULL; gboolean save_bool = TRUE; - OptionInfo *candidate; + const OptionInfo *candidate; gboolean seen_dash_dash = FALSE; next_arg (nmc, &argc, &argv, NULL); diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 9f76445cc7..bd91e6fa03 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -172,9 +172,6 @@ typedef enum { NM_META_PROPERTY_INF_FLAG_REQD = 0x01, /* Don't ask to ask. */ NM_META_PROPERTY_INF_FLAG_DONT_ASK = 0x02, /* Don't ask interactively by default */ NM_META_PROPERTY_INF_FLAG_MULTI = 0x04, /* Ask multiple times, do an append instead of set. */ - - NM_META_PROPERTY_INF_FLAG_DISABLED = 0x10, /* Don't ask due to runtime decision. */ - NM_META_PROPERTY_INF_FLAG_ENABLED = 0x20, /* Override NM_META_PROPERTY_INF_FLAG_DONT_ASK due to runtime decision. */ } NMMetaPropertyInfFlags; struct _NMMetaPropertyInfo { From 4f19c46a1e642c7d5c6ab6de5b57b8256754277b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 7 Apr 2017 16:15:56 +0200 Subject: [PATCH 19/32] cli: move part of setting meta data from "connection.c"'s OptionInfo --- clients/cli/connections.c | 896 +++++++++++++++----------- clients/common/nm-meta-setting-desc.c | 422 ++++++++++++ clients/common/nm-meta-setting-desc.h | 93 +++ 3 files changed, 1018 insertions(+), 393 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index f454dc4c73..38975fb8c6 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -49,16 +49,15 @@ typedef enum { PROPERTY_INF_FLAG_ALL = 0x3, } PropertyInfFlags; +typedef char *(*CompEntryFunc) (const char *, int); + typedef struct _OptionInfo OptionInfo; struct _OptionInfo { - const char *setting_name; + const NMMetaSettingInfoEditor *setting_info; const char *property; const char *option; - const NMMetaPropertyInfFlags flags; - const char *prompt; - const char *def_hint; gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, const OptionInfo *option, const char *value, GError **error); - rl_compentry_func_t *generator_func; + CompEntryFunc generator_func; }; /* define some prompts for connection editor */ @@ -67,59 +66,6 @@ struct _OptionInfo { #define EDITOR_PROMPT_CON_TYPE _("Enter connection type: ") /* define some other prompts */ -#define PROMPT_CON_TYPE N_("Connection type") -#define PROMPT_IFNAME N_("Interface name [*]") -#define PROMPT_VPN_TYPE N_("VPN type") -#define PROMPT_MASTER N_("Master") - -#define PROMPT_IB_MODE N_("Transport mode") -#define WORD_DATAGRAM "datagram" -#define WORD_CONNECTED "connected" -#define PROMPT_IB_MODE_CHOICES "(" WORD_DATAGRAM "/" WORD_CONNECTED ") [" WORD_DATAGRAM "]" - -#define PROMPT_BT_TYPE N_("Bluetooth type") -#define WORD_PANU "panu" -#define WORD_DUN_GSM "dun-gsm" -#define WORD_DUN_CDMA "dun-cdma" -#define PROMPT_BT_TYPE_CHOICES "(" WORD_PANU "/" WORD_DUN_GSM "/" WORD_DUN_CDMA ") [" WORD_PANU "]" - -#define PROMPT_BOND_MODE N_("Bonding mode") - -#define PROMPT_BOND_MON_MODE N_("Bonding monitoring mode") -#define WORD_MIIMON "miimon" -#define WORD_ARP "arp" -#define PROMPT_BOND_MON_MODE_CHOICES "(" WORD_MIIMON "/" WORD_ARP ") [" WORD_MIIMON "]" - -#define PROMPT_ADSL_PROTO N_("Protocol") -#define PROMPT_ADSL_PROTO_CHOICES "(" NM_SETTING_ADSL_PROTOCOL_PPPOA "/" NM_SETTING_ADSL_PROTOCOL_PPPOE "/" NM_SETTING_ADSL_PROTOCOL_IPOATM ")" - -#define PROMPT_WIFI_MODE N_("Wi-Fi mode") -#define WORD_INFRA "infrastructure" -#define WORD_AP "ap" -#define WORD_ADHOC "adhoc" -#define PROMPT_WIFI_MODE_CHOICES "(" WORD_INFRA "/" WORD_AP "/" WORD_ADHOC ") [" WORD_INFRA "]" - -#define PROMPT_ADSL_ENCAP N_("ADSL encapsulation") -#define PROMPT_ADSL_ENCAP_CHOICES "(" NM_SETTING_ADSL_ENCAPSULATION_VCMUX "/" NM_SETTING_ADSL_ENCAPSULATION_LLC ") [none]" - -#define PROMPT_TUN_MODE N_("Tun mode") -#define WORD_TUN "tun" -#define WORD_TAP "tap" -#define PROMPT_TUN_MODE_CHOICES "(" WORD_TUN "/" WORD_TAP ") [" WORD_TUN "]" - -#define PROMPT_IP_TUNNEL_MODE N_("IP Tunnel mode") - -#define PROMPT_MACVLAN_MODE N_("MACVLAN mode") - -#define PROMPT_MACSEC_MODE N_("MACsec mode") -#define WORD_PSK "psk" -#define WORD_EAP "eap" -#define PROMPT_MACSEC_MODE_CHOICES "(" WORD_PSK "/" WORD_EAP ")" - -#define PROMPT_PROXY_METHOD N_("Proxy method") -#define WORD_NONE "none" -#define WORD_AUTO "auto" -#define PROMPT_PROXY_METHOD_CHOICES "(" WORD_NONE "/" WORD_AUTO ") [" WORD_NONE "]" #define PROMPT_CONNECTION _("Connection (name, UUID, or path)") #define PROMPT_VPN_CONNECTION _("VPN connection (name, UUID, or path)") @@ -1834,7 +1780,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) if (acon) con = NM_CONNECTION (nm_active_connection_get_connection (acon)); } - + if (!con && !acon) { g_string_printf (nmc->return_text, _("Error: %s - no such connection profile."), *argv); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; @@ -3520,13 +3466,11 @@ set_default_interface_name (NmCli *nmc, NMSettingConnection *s_con) g_free (ifname); } -/*----------------------------------------------------------------------------*/ - -static const OptionInfo option_info[]; +/*****************************************************************************/ static PropertyInfFlags -_options_set (const OptionInfo *option, - PropertyInfFlags mask, PropertyInfFlags set) +_dynamic_options_set (const NMMetaAbstractInfo *abstract_info, + PropertyInfFlags mask, PropertyInfFlags set) { static GHashTable *cache = NULL; gpointer p; @@ -3535,24 +3479,74 @@ _options_set (const OptionInfo *option, if (G_UNLIKELY (!cache)) cache = g_hash_table_new (NULL, NULL); - if (g_hash_table_lookup_extended (cache, (gpointer) option, NULL, &p)) + if (g_hash_table_lookup_extended (cache, (gpointer) abstract_info, NULL, &p)) v = GPOINTER_TO_UINT (p); else v = 0; v2 = (v & ~mask) | (mask & set); if (v != v2) - g_hash_table_insert (cache, (gpointer) option, GUINT_TO_POINTER (v2)); + g_hash_table_insert (cache, (gpointer) abstract_info, GUINT_TO_POINTER (v2)); return v2; } static PropertyInfFlags -_options_get (const OptionInfo *option) +_dynamic_options_get (const NMMetaAbstractInfo *abstract_info) { - return _options_set (option, 0, 0); + return _dynamic_options_set (abstract_info, 0, 0); } +/*****************************************************************************/ + +static gboolean +_meta_property_needs_bond_hack (const NMMetaPropertyInfo *property_info) +{ + /* hack: the bond property data is handled special and not generically. + * Eventually, get rid of explicitly checking whether we handle a bond. */ + if (!property_info) + g_return_val_if_reached (FALSE); + return property_info->property_typ_data + && property_info->property_typ_data->subtype.nested.data == &nm_meta_property_typ_data_bond; + +} + +static void +_meta_abstract_get (const NMMetaAbstractInfo *abstract_info, + const NMMetaSettingInfoEditor **out_setting_info, + const char **out_setting_name, + const char **out_property_name, + const char **out_option, + NMMetaPropertyInfFlags *out_inf_flags, + const char **out_prompt, + const char **out_def_hint) +{ + /* _meta_property_needs_bond_hack () */ + if (abstract_info->meta_type == &nm_meta_type_nested_property_info) { + const NMMetaNestedPropertyTypeInfo *info = (const NMMetaNestedPropertyTypeInfo *) abstract_info; + + NM_SET_OUT (out_setting_info, info->parent_info->setting_info); + NM_SET_OUT (out_setting_name, info->parent_info->setting_info->general->setting_name); + NM_SET_OUT (out_property_name, info->parent_info->property_name); + NM_SET_OUT (out_option, info->field_name); + NM_SET_OUT (out_inf_flags, info->inf_flags); + NM_SET_OUT (out_prompt, info->prompt); + NM_SET_OUT (out_def_hint, info->def_hint); + } else { + const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; + + NM_SET_OUT (out_setting_info, info->setting_info); + NM_SET_OUT (out_setting_name, info->setting_info->general->setting_name); + NM_SET_OUT (out_property_name, info->property_name); + NM_SET_OUT (out_option, info->property_alias); + NM_SET_OUT (out_inf_flags, info->inf_flags); + NM_SET_OUT (out_prompt, info->prompt); + NM_SET_OUT (out_def_hint, info->def_hint); + } +} + +static const OptionInfo *_meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info); + /* * Mark options in option_info as relevant. * The questionnaire (for --ask) will ask for them. @@ -3560,16 +3554,34 @@ _options_get (const OptionInfo *option) static void enable_options (const gchar *setting_name, const gchar *property, const gchar * const *opts) { - const OptionInfo *candidate; + const NMMetaPropertyInfo *property_info; - for (candidate = option_info; candidate->setting_name; candidate++) { - if ( strcmp (candidate->setting_name, setting_name) == 0 - && strcmp (candidate->property, property) == 0 - && (candidate->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) - && candidate->option - && g_strv_contains (opts, candidate->option)) - _options_set (candidate, PROPERTY_INF_FLAG_ENABLED, PROPERTY_INF_FLAG_ENABLED); + property_info = nm_meta_property_info_find_by_name (setting_name, property); + + if (!property_info) + g_return_if_reached (); + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if ( bi->inf_flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK + && bi->field_name + && g_strv_contains (opts, bi->field_name)) + _dynamic_options_set ((const NMMetaAbstractInfo *) bi, PROPERTY_INF_FLAG_ENABLED, PROPERTY_INF_FLAG_ENABLED); + } + return; } + + if (!property_info->is_cli_option) + g_return_if_reached (); + + if ( property_info->inf_flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK + && property_info->property_alias + && g_strv_contains (opts, property_info->property_alias)) + _dynamic_options_set ((const NMMetaAbstractInfo *) property_info, PROPERTY_INF_FLAG_ENABLED, PROPERTY_INF_FLAG_ENABLED); } /* @@ -3580,12 +3592,47 @@ enable_options (const gchar *setting_name, const gchar *property, const gchar * static void disable_options (const gchar *setting_name, const gchar *property) { - const OptionInfo *candidate; + const NMMetaPropertyInfo *property_infos_local[2]; + const NMMetaPropertyInfo *const*property_infos; + guint p; - for (candidate = option_info; candidate->setting_name; candidate++) { - if ( strcmp (candidate->setting_name, setting_name) == 0 - && (!property || strcmp (candidate->property, property) == 0)) - _options_set (candidate, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); + if (property) { + const NMMetaPropertyInfo *pi; + + pi = nm_meta_property_info_find_by_name (setting_name, property); + if (!pi) + g_return_if_reached (); + if ( !_meta_property_needs_bond_hack (pi) + && !pi->is_cli_option) + return; + property_infos_local[0] = pi; + property_infos_local[1] = NULL; + property_infos = property_infos_local; + } else { + const NMMetaSettingInfoEditor *setting_info; + + setting_info = nm_meta_setting_info_editor_find_by_name (setting_name); + if (!setting_info) + g_return_if_reached (); + property_infos = nm_property_infos_for_setting_type (setting_info->general->meta_type); + } + + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + _dynamic_options_set ((const NMMetaAbstractInfo *) bi, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); + } + nm_assert (p == 0 && !property_infos[1]); + } else { + if (property_info->is_cli_option) + _dynamic_options_set ((const NMMetaAbstractInfo *) property_info, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); + } } } @@ -3597,10 +3644,30 @@ disable_options (const gchar *setting_name, const gchar *property) static void reset_options (void) { - const OptionInfo *candidate; + NMMetaSettingType s; - for (candidate = option_info; candidate->setting_name; candidate++) - _options_set (candidate, PROPERTY_INF_FLAG_ALL, 0); + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + _dynamic_options_set ((const NMMetaAbstractInfo *) bi, PROPERTY_INF_FLAG_ALL, 0); + } + } else { + if (property_info->is_cli_option) + _dynamic_options_set ((const NMMetaAbstractInfo *) property_info, PROPERTY_INF_FLAG_ALL, 0); + } + } + } } static gboolean @@ -3612,10 +3679,13 @@ set_property (NMConnection *connection, NMSetting *setting; GError *local = NULL; + g_assert (setting_name && setting_name[0]); + setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { setting = nmc_setting_new_for_name (setting_name); if (!setting) { + g_assert (FALSE); /* This should really not happen */ g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN, _("Error: don't know how to create '%s' setting."), @@ -3681,17 +3751,25 @@ set_property (NMConnection *connection, } static gboolean -set_option (NmCli *nmc, NMConnection *connection, const OptionInfo *option, const gchar *value, GError **error) +set_option (NmCli *nmc, NMConnection *connection, const NMMetaAbstractInfo *abstract_info, const gchar *value, GError **error) { - _options_set (option, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); - if (option->check_and_set) { + const char *setting_name, *property_name, *option_name; + NMMetaPropertyInfFlags inf_flags; + const OptionInfo *option; + + option = _meta_abstract_get_option_info (abstract_info); + + _dynamic_options_set (abstract_info, PROPERTY_INF_FLAG_DISABLED, PROPERTY_INF_FLAG_DISABLED); + + _meta_abstract_get (abstract_info, NULL, &setting_name, &property_name, &option_name, &inf_flags, NULL, NULL); + if (option && option->check_and_set) { return option->check_and_set (nmc, connection, option, value, error); } else if (value) { - return set_property (connection, option->setting_name, option->property, - value, option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); - } else if (option->flags & NM_META_PROPERTY_INF_FLAG_REQD) { + return set_property (connection, setting_name, property_name, + value, inf_flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); + } else if (inf_flags & NM_META_PROPERTY_INF_FLAG_REQD) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s' is mandatory."), option->option); + _("Error: '%s' is mandatory."), option_name); return FALSE; } @@ -3985,7 +4063,7 @@ set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, co NM_SETTING_CONNECTION_INTERFACE_NAME); } - if (!set_property (con, option->setting_name, option->property, value, '\0', error)) + if (!set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error)) return FALSE; if (!con_settings (con, &type_settings, &slv_settings, error)) @@ -4014,7 +4092,7 @@ set_connection_iface (NmCli *nmc, NMConnection *con, const OptionInfo *option, c } } - return set_property (con, option->setting_name, option->property, value, '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); } static gboolean @@ -4043,7 +4121,7 @@ set_connection_master (NmCli *nmc, NMConnection *con, const OptionInfo *option, return FALSE; } - return set_property (con, option->setting_name, option->property, value, '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); } static gboolean @@ -4110,17 +4188,17 @@ set_bond_monitoring_mode (NmCli *nmc, NMConnection *con, const OptionInfo *optio monitor_mode = g_strdup (value); g_strstrip (monitor_mode); } else { - monitor_mode = g_strdup (WORD_MIIMON); + monitor_mode = g_strdup (NM_META_TEXT_WORD_MIIMON); } - if (matches (monitor_mode, WORD_MIIMON)) + if (matches (monitor_mode, NM_META_TEXT_WORD_MIIMON)) enable_options (NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, miimon_opts); - else if (matches (monitor_mode, WORD_ARP)) + else if (matches (monitor_mode, NM_META_TEXT_WORD_ARP)) enable_options (NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, arp_opts); else { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n"), - monitor_mode, WORD_MIIMON, WORD_ARP); + monitor_mode, NM_META_TEXT_WORD_MIIMON, NM_META_TEXT_WORD_ARP); return FALSE; } @@ -4156,7 +4234,7 @@ set_bluetooth_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, con return FALSE; } - return set_property (con, option->setting_name, option->property, value, '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); } static gboolean @@ -4167,7 +4245,7 @@ set_yes_no (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char if (g_strcmp0 (value, _(WORD_LOC_NO))) value = WORD_NO; - return set_property (con, option->setting_name, option->property, value, '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); } static gboolean @@ -4186,8 +4264,8 @@ set_ip4_address (NmCli *nmc, NMConnection *con, const OptionInfo *option, const NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); } - return set_property (con, option->setting_name, option->property, value, - option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, + '+', error); } static gboolean @@ -4206,160 +4284,96 @@ set_ip6_address (NmCli *nmc, NMConnection *con, const OptionInfo *option, const NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); } - return set_property (con, option->setting_name, option->property, value, - option->flags & NM_META_PROPERTY_INF_FLAG_MULTI ? '+' : '\0', error); + return set_property (con, option->setting_info->general->setting_name, option->property, value, + '+', error); } +/*****************************************************************************/ -/*----------------------------------------------------------------------------*/ +static const OptionInfo * +_meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) +{ + static const OptionInfo option_info[] = { +#define OPTION_INFO(name, property_name_, property_alias_, check_and_set_, generator_func_) \ + { \ + .setting_info = &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_##name], \ + .property = property_name_, \ + .option = property_alias_, \ + .check_and_set = check_and_set_, \ + .generator_func = generator_func_, \ + } + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", NULL, gen_func_bool_values_l10n), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, nmc_rl_gen_func_ifnames), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_SLAVE_TYPE, "slave-type", NULL, gen_func_slave_type), + OPTION_INFO (INFINIBAND, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NULL, gen_func_ib_type), + OPTION_INFO (WIRELESS, NM_SETTING_WIRELESS_MODE, "mode", NULL, gen_func_wifi_mode), + OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), + OPTION_INFO (VLAN, NM_SETTING_VLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "mode", set_bond_option, gen_func_bond_mode), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "primary", set_bond_option, nmc_rl_gen_func_ifnames), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, NULL, set_bond_monitoring_mode, gen_func_bond_mon_mode), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "miimon", set_bond_option, NULL), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "downdelay", set_bond_option, NULL), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "updelay", set_bond_option, NULL), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-interval", set_bond_option, NULL), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-ip-target", set_bond_option, NULL), + OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "lacp-rate", set_bond_option, gen_func_bond_lacp_rate), + OPTION_INFO (BRIDGE, NM_SETTING_BRIDGE_STP, "stp", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (BRIDGE, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "multicast-snooping", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (BRIDGE_PORT, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (VPN, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NULL, gen_func_vpn_types), + OPTION_INFO (ADSL, NM_SETTING_ADSL_PROTOCOL, "protocol", NULL, gen_func_adsl_proto), + OPTION_INFO (ADSL, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NULL, gen_func_adsl_encap), + OPTION_INFO (MACSEC, NM_SETTING_MACSEC_MODE, "mode", NULL, gen_func_macsec_mode), + OPTION_INFO (MACSEC, NM_SETTING_MACSEC_ENCRYPT, "encrypt", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), + OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_MODE, "mode", NULL, gen_func_macvlan_mode), + OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_TAP, "tap", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (VXLAN, NM_SETTING_VXLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), + OPTION_INFO (TUN, NM_SETTING_TUN_MODE, "mode", NULL, gen_func_tun_mode), + OPTION_INFO (TUN, NM_SETTING_TUN_PI, "pi", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (TUN, NM_SETTING_TUN_VNET_HDR, "vnet-hdr", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (TUN, NM_SETTING_TUN_MULTI_QUEUE, "multi-queue", set_yes_no, gen_func_bool_values_l10n), + OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_MODE, "mode", NULL, gen_func_ip_tunnel_mode), + OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), + OPTION_INFO (IP4_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", set_ip4_address, NULL), + OPTION_INFO (IP6_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", set_ip6_address, NULL), + OPTION_INFO (PROXY, NM_SETTING_PROXY_METHOD, "method", NULL, gen_func_proxy_method), + OPTION_INFO (PROXY, NM_SETTING_PROXY_BROWSER_ONLY, "browser-only", set_yes_no, gen_func_bool_values_l10n), + { 0 }, + }; + const char *property_name, *option; + const NMMetaSettingInfoEditor *setting_info; + const OptionInfo *candidate; -static const OptionInfo option_info[] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, "type", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_CON_TYPE, NULL, - set_connection_type, gen_connection_types }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID, "con-name", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, NULL }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, - gen_func_bool_values_l10n }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_IFNAME, NULL, - set_connection_iface, nmc_rl_gen_func_ifnames }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER, "master", NM_META_PROPERTY_INF_FLAG_DONT_ASK, PROMPT_MASTER, NULL, - set_connection_master, gen_func_master_ifnames }, - { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE, "slave-type", NM_META_PROPERTY_INF_FLAG_DONT_ASK, NULL, NULL, NULL, - gen_func_slave_type }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME, "username", NM_META_PROPERTY_INF_FLAG_REQD, N_("PPPoE username"), NULL, NULL, NULL }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_SERVICE, "service", NM_META_PROPERTY_INF_FLAG_NONE, N_("Service [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "cloned-mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_IB_MODE, PROMPT_IB_MODE_CHOICES, - NULL, gen_func_ib_type }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_PARENT, "parent", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent interface [none]"), NULL, NULL, NULL }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_P_KEY, "p-key", NM_META_PROPERTY_INF_FLAG_NONE, N_("P_KEY [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, "ssid", NM_META_PROPERTY_INF_FLAG_REQD, N_("SSID"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_WIFI_MODE, PROMPT_WIFI_MODE_CHOICES, - NULL, gen_func_wifi_mode }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MTU, "mtu", NM_META_PROPERTY_INF_FLAG_NONE, N_("MTU [auto]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "cloned-mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("Cloned MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_NETWORK_NAME, "nsp", NM_META_PROPERTY_INF_FLAG_REQD, N_("WiMAX NSP name"), NULL, NULL, NULL }, - { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN, "apn", NM_META_PROPERTY_INF_FLAG_REQD, N_("APN"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_USERNAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR, "addr", NM_META_PROPERTY_INF_FLAG_REQD, N_("Bluetooth device address"), NULL, NULL, NULL }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE, "bt-type", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_BT_TYPE, PROMPT_BT_TYPE_CHOICES, - set_bluetooth_type, gen_func_bt_type }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("VLAN parent device or connection UUID"), NULL, - NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID, "id", NM_META_PROPERTY_INF_FLAG_REQD, N_("VLAN ID (<0-4094>)"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS, "flags", NM_META_PROPERTY_INF_FLAG_NONE, N_("VLAN flags (<0-7>) [none]"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, "ingress", NM_META_PROPERTY_INF_FLAG_NONE, N_("Ingress priority maps [none]"), NULL, NULL, NULL }, - { NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, "egress", NM_META_PROPERTY_INF_FLAG_NONE, N_("Egress priority maps [none]"), NULL, NULL, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_BOND_MODE, "[balance-rr]", - set_bond_option, gen_func_bond_mode }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "primary", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding primary interface [none]"), - NULL, set_bond_option, nmc_rl_gen_func_ifnames }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, NULL, NM_META_PROPERTY_INF_FLAG_NONE, N_("Bonding monitoring mode"), PROMPT_BOND_MON_MODE_CHOICES, - set_bond_monitoring_mode, gen_func_bond_mon_mode }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "miimon", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding miimon [100]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "downdelay", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding downdelay [0]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "updelay", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding updelay [0]"), NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-interval", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding arp-interval [0]"), NULL, - set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "arp-ip-target", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("Bonding arp-ip-target [none]"), - NULL, set_bond_option, NULL }, - { NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS, "lacp-rate", NM_META_PROPERTY_INF_FLAG_DONT_ASK, N_("LACP rate ('slow' or 'fast') [slow]"), NULL, - set_bond_option, gen_func_bond_lacp_rate }, - { NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_CONFIG, "config", NM_META_PROPERTY_INF_FLAG_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, - { NM_SETTING_TEAM_PORT_SETTING_NAME, NM_SETTING_TEAM_PORT_CONFIG, "config", NM_META_PROPERTY_INF_FLAG_NONE, N_("Team JSON configuration [none]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_STP, "stp", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable STP [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_PRIORITY, "priority", NM_META_PROPERTY_INF_FLAG_NONE, N_("STP priority [32768]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_FORWARD_DELAY, "forward-delay", NM_META_PROPERTY_INF_FLAG_NONE, N_("Forward delay [15]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_HELLO_TIME, "hello-time", NM_META_PROPERTY_INF_FLAG_NONE, N_("Hello time [2]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAX_AGE, "max-age", NM_META_PROPERTY_INF_FLAG_NONE, N_("Max age [20]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_AGEING_TIME, "ageing-time", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC address ageing time [300]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "multicast-snooping", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable IGMP snooping [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS, "mac", NM_META_PROPERTY_INF_FLAG_NONE, N_("MAC [none]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PRIORITY, "priority", NM_META_PROPERTY_INF_FLAG_NONE, N_("Bridge port priority [32]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_PATH_COST, "path-cost", NM_META_PROPERTY_INF_FLAG_NONE, N_("Bridge port STP path cost [100]"), NULL, NULL, NULL }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin", NM_META_PROPERTY_INF_FLAG_NONE, N_("Hairpin [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_VPN_TYPE, NULL, NULL, gen_func_vpn_types }, - { NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME, "user", NM_META_PROPERTY_INF_FLAG_NONE, N_("Username [none]"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_SSID, "ssid", NM_META_PROPERTY_INF_FLAG_REQD, N_("SSID"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_CHANNEL, "channel", NM_META_PROPERTY_INF_FLAG_NONE, N_("OLPC Mesh channel [1]"), NULL, NULL, NULL }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, "dhcp-anycast", NM_META_PROPERTY_INF_FLAG_NONE, N_("DHCP anycast MAC address [none]"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME, "username", NM_META_PROPERTY_INF_FLAG_REQD, N_("Username"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL, "protocol", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_ADSL_PROTO, PROMPT_ADSL_PROTO_CHOICES, - NULL, gen_func_adsl_proto }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD, "password", NM_META_PROPERTY_INF_FLAG_NONE, N_("Password [none]"), NULL, NULL, NULL }, - { NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_ADSL_ENCAP, PROMPT_ADSL_ENCAP_CHOICES, - NULL, gen_func_adsl_encap }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("MACsec parent device or connection UUID"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_MACSEC_MODE, PROMPT_MACSEC_MODE_CHOICES, NULL, gen_func_macsec_mode }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_ENCRYPT, "encrypt", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable encryption [yes]"), NULL, set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CAK, "cak", NM_META_PROPERTY_INF_FLAG_NONE, N_("MKA CAK"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CKN, "ckn", NM_META_PROPERTY_INF_FLAG_NONE, N_("MKA_CKN"), NULL, NULL, NULL }, - { NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT, "port", NM_META_PROPERTY_INF_FLAG_NONE, N_("SCI port [1]"), NULL, NULL, NULL }, + _meta_abstract_get (abstract_info, &setting_info, NULL, &property_name, &option, NULL, NULL, NULL); - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_REQD, N_("MACVLAN parent device or connection UUID"), NULL, - NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_MACVLAN_MODE, NULL, - NULL, gen_func_macvlan_mode }, - { NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_TAP, "tap", NM_META_PROPERTY_INF_FLAG_NONE, N_("Tap [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_ID, "id", NM_META_PROPERTY_INF_FLAG_REQD, N_("VXLAN ID"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE, "remote", NM_META_PROPERTY_INF_FLAG_REQD, N_("Remote"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent device [none]"), NULL, - NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_LOCAL, "local", NM_META_PROPERTY_INF_FLAG_NONE, N_("Local address [none]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MIN, "source-port-min", NM_META_PROPERTY_INF_FLAG_NONE, N_("Minimum source port [0]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MAX, "source-port-max", NM_META_PROPERTY_INF_FLAG_NONE, N_("Maximum source port [0]"), NULL, NULL, NULL }, - { NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_DESTINATION_PORT, "destination-port", NM_META_PROPERTY_INF_FLAG_NONE, N_("Destination port [8472]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MODE, "mode", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_TUN_MODE, PROMPT_TUN_MODE_CHOICES, - NULL, gen_func_tun_mode }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_OWNER, "owner", NM_META_PROPERTY_INF_FLAG_NONE, N_("User ID [none]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_GROUP, "group", NM_META_PROPERTY_INF_FLAG_NONE, N_("Group ID [none]"), NULL, NULL, NULL }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_PI, "pi", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable PI [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_VNET_HDR, "vnet-hdr", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable VNET header [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MULTI_QUEUE, "multi-queue", NM_META_PROPERTY_INF_FLAG_NONE, N_("Enable multi queue [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE, "mode", NM_META_PROPERTY_INF_FLAG_REQD, PROMPT_IP_TUNNEL_MODE, NULL, NULL, gen_func_ip_tunnel_mode }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL, "local", NM_META_PROPERTY_INF_FLAG_NONE, N_("Local endpoint [none]"), NULL, NULL, NULL }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE, "remote", NM_META_PROPERTY_INF_FLAG_REQD, N_("Remote"), NULL, NULL, NULL }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_PARENT, "dev", NM_META_PROPERTY_INF_FLAG_NONE, N_("Parent device [none]"), NULL, - NULL, nmc_rl_gen_func_ifnames }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", NM_META_PROPERTY_INF_FLAG_MULTI, N_("IPv4 address (IP[/plen]) [none]"), NULL, - set_ip4_address, NULL }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw4", NM_META_PROPERTY_INF_FLAG_NONE, N_("IPv4 gateway [none]"), NULL, NULL, NULL }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", NM_META_PROPERTY_INF_FLAG_MULTI, N_("IPv6 address (IP[/plen]) [none]"), NULL, - set_ip6_address, NULL }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY, "gw6", NM_META_PROPERTY_INF_FLAG_NONE, N_("IPv6 gateway [none]"), NULL, NULL, NULL }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_METHOD, "method", NM_META_PROPERTY_INF_FLAG_NONE, PROMPT_PROXY_METHOD, PROMPT_PROXY_METHOD_CHOICES, NULL, gen_func_proxy_method }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_BROWSER_ONLY, "browser-only", NM_META_PROPERTY_INF_FLAG_NONE, N_("Browser only [no]"), NULL, - set_yes_no, gen_func_bool_values_l10n }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL, "pac-url", NM_META_PROPERTY_INF_FLAG_NONE, N_("PAC URL"), NULL, NULL, NULL }, - { NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT, "pac-script", NM_META_PROPERTY_INF_FLAG_NONE, N_("PAC script"), NULL, NULL, NULL }, - { NULL, NULL, NULL, NM_META_PROPERTY_INF_FLAG_NONE, NULL, NULL, NULL, NULL }, -}; + for (candidate = option_info; candidate->setting_info; candidate++) { + if ( candidate->setting_info == setting_info + && nm_streq0 (candidate->property, property_name) + && nm_streq0 (candidate->option, option)) { + return candidate; + } + } + return NULL; +} static gboolean -option_relevant (NMConnection *connection, const OptionInfo *option) +option_relevant (NMConnection *connection, const NMMetaAbstractInfo *abstract_info) { - if ( (option->flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) - && !(_options_get (option) & PROPERTY_INF_FLAG_ENABLED)) + const char *setting_name; + NMMetaPropertyInfFlags inf_flags; + + _meta_abstract_get (abstract_info, NULL, &setting_name, NULL, NULL, &inf_flags, NULL, NULL); + + if ( (inf_flags & NM_META_PROPERTY_INF_FLAG_DONT_ASK) + && !(_dynamic_options_get (abstract_info) & PROPERTY_INF_FLAG_ENABLED)) return FALSE; - if (_options_get (option) & PROPERTY_INF_FLAG_DISABLED) + if (_dynamic_options_get (abstract_info) & PROPERTY_INF_FLAG_DISABLED) return FALSE; - if (!nm_connection_get_setting_by_name (connection, option->setting_name)) + if (!nm_connection_get_setting_by_name (connection, setting_name)) return FALSE; return TRUE; } @@ -4379,7 +4393,7 @@ complete_property_name (NmCli *nmc, NMConnection *connection, const char *slave_type = NULL; gs_free char *slv_type = NULL; gs_free char *word_list = NULL; - const OptionInfo *candidate; + NMMetaSettingType s; connection_type = nm_connection_get_connection_type (connection); s_con = nm_connection_get_setting_connection (connection); @@ -4396,14 +4410,37 @@ complete_property_name (NmCli *nmc, NMConnection *connection, if (modifier != '\0') return; - for (candidate = option_info; candidate->setting_name; candidate++) { - if (!nm_connection_get_setting_by_name (connection, candidate->setting_name)) + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + if (!nm_connection_get_setting_by_name (connection, nm_meta_setting_infos_editor[s].general->setting_name)) continue; - if (!candidate->option) - continue; - if (!g_str_has_prefix (candidate->option, prefix)) - continue; - g_print ("%s\n", candidate->option); + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if ( !bi->field_name + || !g_str_has_prefix (bi->field_name, prefix)) + continue; + g_print ("%s\n", bi->field_name); + } + } else { + if (!property_info->is_cli_option) + continue; + if ( !property_info->property_alias + || !g_str_has_prefix (property_info->property_alias, prefix)) + continue; + g_print ("%s\n", property_info->property_alias); + } + } } } @@ -4422,10 +4459,13 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix) } static void -complete_option (const OptionInfo *option, const gchar *prefix) +complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) { - if (option->generator_func) - run_rl_generator (option->generator_func, prefix); + const OptionInfo *candidate; + + candidate = _meta_abstract_get_option_info (abstract_info); + if (candidate && candidate->generator_func) + run_rl_generator (candidate->generator_func, prefix); } static void @@ -4514,8 +4554,7 @@ nmc_read_connection_properties (NmCli *nmc, */ /* Go through arguments and set properties */ do { - const OptionInfo *candidate; - const OptionInfo *chosen = NULL; + const NMMetaAbstractInfo *chosen = NULL; gs_strfreev gchar **strv = NULL; const NameItem *type_settings, *slv_settings; char modifier = '\0'; @@ -4569,20 +4608,59 @@ nmc_read_connection_properties (NmCli *nmc, if (!set_property (connection, setting_name, strv[1], value, modifier, error)) return FALSE; } else { + NMMetaSettingType s; + const char *chosen_setting_name = NULL; + const char *chosen_option = NULL; + /* Let's see if this is an property alias (such as "id", "mode", "type" or "con-name")*/ - for (candidate = option_info; candidate->setting_name; candidate++) { - if (g_strcmp0 (candidate->option, option)) + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + if (!check_valid_name (nm_meta_setting_infos[s].setting_name, + type_settings, slv_settings, NULL)) continue; - if (!check_valid_name (candidate->setting_name, type_settings, slv_settings, NULL)) - continue; - if (chosen) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s' is ambiguous (%s.%s or %s.%s)."), option, - chosen->setting_name, chosen->property, - candidate->setting_name, candidate->property); - return FALSE; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if (!nm_streq0 (bi->field_name, option)) + continue; + if (chosen) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: '%s' is ambiguous (%s.%s or %s.%s)."), option, + chosen_setting_name, chosen_option, + nm_meta_setting_infos[s].setting_name, option); + return FALSE; + } + chosen_setting_name = nm_meta_setting_infos[s].setting_name; + chosen_option = option; + chosen = (const NMMetaAbstractInfo *) bi; + } + } else { + if (!property_info->is_cli_option) + continue; + if (!nm_streq0 (property_info->property_alias, option)) + continue; + if (chosen) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: '%s' is ambiguous (%s.%s or %s.%s)."), option, + chosen_setting_name, chosen_option, + nm_meta_setting_infos[s].setting_name, option); + return FALSE; + } + chosen_setting_name = nm_meta_setting_infos[s].setting_name; + chosen_option = option; + chosen = (const NMMetaAbstractInfo *) property_info; + } } - chosen = candidate; } if (!chosen) { @@ -4591,7 +4669,7 @@ nmc_read_connection_properties (NmCli *nmc, if (*argc == 1 && nmc->complete) complete_property_name (nmc, connection, modifier, option, NULL); g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: invalid . '%s'."), option); + _("Error: invalid . '%s'."), option); return FALSE; } @@ -4702,37 +4780,37 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) if (!is_single_word (rl_line_buffer)) return NULL; - if (g_str_has_prefix (rl_prompt, PROMPT_CON_TYPE)) + if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) generator_func = gen_connection_types; - else if (g_str_has_prefix (rl_prompt, PROMPT_IFNAME)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IFNAME)) generator_func = nmc_rl_gen_func_ifnames; - else if (g_str_has_prefix (rl_prompt, PROMPT_VPN_TYPE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_VPN_TYPE)) generator_func = gen_func_vpn_types; - else if (g_str_has_prefix (rl_prompt, PROMPT_MASTER)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER)) generator_func = gen_func_master_ifnames; - else if (g_str_has_prefix (rl_prompt, PROMPT_WIFI_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_WIFI_MODE)) generator_func = gen_func_wifi_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_IB_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IB_MODE)) generator_func = gen_func_ib_type; - else if (g_str_has_prefix (rl_prompt, PROMPT_BT_TYPE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) generator_func = gen_func_bt_type; - else if (g_str_has_prefix (rl_prompt, PROMPT_BOND_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE)) generator_func = gen_func_bond_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_BOND_MON_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MON_MODE)) generator_func = gen_func_bond_mon_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_ADSL_PROTO)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_ADSL_PROTO)) generator_func = gen_func_adsl_proto; - else if (g_str_has_prefix (rl_prompt, PROMPT_ADSL_ENCAP)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_ADSL_ENCAP)) generator_func = gen_func_adsl_encap; - else if (g_str_has_prefix (rl_prompt, PROMPT_TUN_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_TUN_MODE)) generator_func = gen_func_tun_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_IP_TUNNEL_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IP_TUNNEL_MODE)) generator_func = gen_func_ip_tunnel_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_MACVLAN_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MACVLAN_MODE)) generator_func = gen_func_macvlan_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_MACSEC_MODE)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MACSEC_MODE)) generator_func = gen_func_macsec_mode; - else if (g_str_has_prefix (rl_prompt, PROMPT_PROXY_METHOD)) + else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_PROXY_METHOD)) generator_func = gen_func_proxy_method; else if ( g_str_has_suffix (rl_prompt, yes) || g_str_has_suffix (rl_prompt, no)) @@ -4745,20 +4823,25 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) } static void -ask_option (NmCli *nmc, NMConnection *connection, const OptionInfo *option) +ask_option (NmCli *nmc, NMConnection *connection, const NMMetaAbstractInfo *abstract_info) { gchar *value; GError *error = NULL; gs_free gchar *prompt = NULL; - gboolean multi = option->flags & NM_META_PROPERTY_INF_FLAG_MULTI; + gboolean multi; + const char *opt_prompt, *opt_def_hint; + NMMetaPropertyInfFlags inf_flags; + _meta_abstract_get (abstract_info, NULL, NULL, NULL, NULL, &inf_flags, &opt_prompt, &opt_def_hint); prompt = g_strjoin ("", - gettext (option->prompt), - option->def_hint ? " " : "", - option->def_hint ? option->def_hint : "", + gettext (opt_prompt), + opt_def_hint ? " " : "", + opt_def_hint ?: "", ": ", NULL); + multi = NM_FLAGS_HAS (inf_flags, NM_META_PROPERTY_INF_FLAG_MULTI); + if (multi) g_print (_("You can specify this option more than once. Press when you're done.\n")); @@ -4767,7 +4850,7 @@ again: if (multi && !value) return; - if (!set_option (nmc, connection, option, value, &error)) { + if (!set_option (nmc, connection, abstract_info, value, &error)) { g_printerr ("%s\n", error->message); g_clear_error (&error); goto again; @@ -4780,15 +4863,39 @@ again: static void questionnaire_mandatory (NmCli *nmc, NMConnection *connection) { - const OptionInfo *candidate; + NMMetaSettingType s; - /* Mandatory settings. */ - for (candidate = option_info; candidate->setting_name; candidate++) { - if (!option_relevant (connection, candidate)) - continue; - if ( (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD) - || (_options_get (candidate) & PROPERTY_INF_FLAG_ENABLED)) - ask_option (nmc, connection, candidate); + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if (!option_relevant (connection, (const NMMetaAbstractInfo *) bi)) + continue; + if ( (bi->inf_flags & NM_META_PROPERTY_INF_FLAG_REQD) + || (_dynamic_options_get ((const NMMetaAbstractInfo *) bi) & PROPERTY_INF_FLAG_ENABLED)) + ask_option (nmc, connection, (const NMMetaAbstractInfo *) bi); + } + } else { + if (!property_info->is_cli_option) + continue; + + if (!option_relevant (connection, (const NMMetaAbstractInfo *) property_info)) + continue; + if ( (property_info->inf_flags & NM_META_PROPERTY_INF_FLAG_REQD) + || (_dynamic_options_get ((const NMMetaAbstractInfo *) property_info) & PROPERTY_INF_FLAG_ENABLED)) + ask_option (nmc, connection, (const NMMetaAbstractInfo *) property_info); + } + } } } @@ -4812,98 +4919,74 @@ want_provide_opt_args (const char *type, int num) return ret; } -static const char * -setting_name_to_name (const char *name) -{ - if (strcmp (name, NM_SETTING_WIRED_SETTING_NAME) == 0) - return _("Wired Ethernet"); - if (strcmp (name, NM_SETTING_INFINIBAND_SETTING_NAME) == 0) - return _("InfiniBand connection"); - if (strcmp (name, NM_SETTING_WIRELESS_SETTING_NAME) == 0) - return _("Wi-Fi connection"); - if (strcmp (name, NM_SETTING_WIMAX_SETTING_NAME) == 0) - return _("WiMAX connection"); - if (strcmp (name, NM_SETTING_PPPOE_SETTING_NAME) == 0) - return _("PPPoE"); - if (strcmp (name, NM_SETTING_CDMA_SETTING_NAME) == 0) - return _("CDMA mobile broadband connection"); - if (strcmp (name, NM_SETTING_GSM_SETTING_NAME) == 0) - return _("GSM mobile broadband connection"); - if (strcmp (name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0) - return _("bluetooth connection"); - if (strcmp (name, NM_SETTING_VLAN_SETTING_NAME) == 0) - return _("VLAN connection"); - if (strcmp (name, NM_SETTING_BOND_SETTING_NAME) == 0) - return _("Bond device"); - if (strcmp (name, NM_SETTING_TEAM_SETTING_NAME) == 0) - return _("Team device"); - if (strcmp (name, NM_SETTING_TEAM_PORT_SETTING_NAME) == 0) - return _("Team port"); - if (strcmp (name, NM_SETTING_BRIDGE_SETTING_NAME) == 0) - return _("Bridge device"); - if (strcmp (name, NM_SETTING_BRIDGE_PORT_SETTING_NAME) == 0) - return _("Bridge port"); - if (strcmp (name, NM_SETTING_VPN_SETTING_NAME) == 0) - return _("VPN connection"); - if (strcmp (name, NM_SETTING_OLPC_MESH_SETTING_NAME) == 0) - return _("OLPC Mesh connection"); - if (strcmp (name, NM_SETTING_ADSL_SETTING_NAME) == 0) - return _("ADSL connection"); - if (strcmp (name, NM_SETTING_MACSEC_SETTING_NAME) == 0) - return _("MACsec connection"); - if (strcmp (name, NM_SETTING_MACVLAN_SETTING_NAME) == 0) - return _("macvlan connection"); - if (strcmp (name, NM_SETTING_VXLAN_SETTING_NAME) == 0) - return _("VXLAN connection"); - if (strcmp (name, NM_SETTING_TUN_SETTING_NAME) == 0) - return _("Tun device"); - if (strcmp (name, NM_SETTING_IP4_CONFIG_SETTING_NAME) == 0) - return _("IPv4 protocol"); - if (strcmp (name, NM_SETTING_IP6_CONFIG_SETTING_NAME) == 0) - return _("IPv6 protocol"); - if (strcmp (name, NM_SETTING_PROXY_SETTING_NAME) == 0) - return _("Proxy"); - - /* Should not happen; but let's still try to be somewhat sensible. */ - return name; -} - static gboolean questionnaire_one_optional (NmCli *nmc, NMConnection *connection) { - const OptionInfo *candidate; + NMMetaSettingType s; + gs_unref_ptrarray GPtrArray *infos = NULL; + guint i; + gboolean already_confirmed = FALSE; + NMMetaSettingType s_asking = NM_META_SETTING_TYPE_UNKNOWN; - /* Optional settings. */ - const gchar *setting_name = NULL; - int count = 0; + infos = g_ptr_array_new (); /* Find first setting with relevant options and count them. */ - for (candidate = option_info; candidate->setting_name; candidate++) { - if (!option_relevant (connection, candidate)) - continue; - if (!setting_name) - setting_name = candidate->setting_name; - else if (strcmp (setting_name, candidate->setting_name)) - break; - count++; - } - if (!setting_name) - return FALSE; +again: + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; - /* Now ask for the settings. */ - if (want_provide_opt_args (setting_name_to_name (setting_name), count)) { - for (candidate = option_info; candidate->setting_name; candidate++) { - if (!option_relevant (connection, candidate)) - continue; - if (strcmp (setting_name, candidate->setting_name)) - continue; - ask_option (nmc, connection, candidate); + if ( s_asking != NM_META_SETTING_TYPE_UNKNOWN + && s != s_asking) + continue; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if (!option_relevant (connection, (const NMMetaAbstractInfo *) bi)) + continue; + g_ptr_array_add (infos, (gpointer) bi); + } + } else { + if (!property_info->is_cli_option) + continue; + if (!option_relevant (connection, (const NMMetaAbstractInfo *) property_info)) + continue; + g_ptr_array_add (infos, (gpointer) property_info); + } + } + if (infos->len) { + s_asking = s; + break; } } - /* Make sure we won't ask again. */ - disable_options (setting_name, NULL); + if (infos->len) { + const NMMetaSettingInfoEditor *setting_info = NULL; + _meta_abstract_get (infos->pdata[0], &setting_info, NULL, NULL, NULL, NULL, NULL, NULL); + + /* Now ask for the settings. */ + if ( already_confirmed + || want_provide_opt_args (_(setting_info->pretty_name), infos->len)) { + ask_option (nmc, connection, infos->pdata[0]); + already_confirmed = TRUE; + /* asking for an option may enable other options. Create the list again. */ + g_ptr_array_set_size (infos, 0); + goto again; + } + } + + if (s_asking == NM_META_SETTING_TYPE_UNKNOWN) + return FALSE; + + /* Make sure we won't ask again. */ + disable_options (nm_meta_setting_infos[s_asking].setting_name, NULL); return TRUE; } @@ -4915,8 +4998,8 @@ do_connection_add (NmCli *nmc, int argc, char **argv) GError *error = NULL; AddConnectionInfo *info = NULL; gboolean save_bool = TRUE; - const OptionInfo *candidate; gboolean seen_dash_dash = FALSE; + NMMetaSettingType s; next_arg (nmc, &argc, &argv, NULL); @@ -5000,8 +5083,9 @@ read_properties: const GPtrArray *connections; connections = nm_client_get_connections (nmc->client); - try_name = ifname ? g_strdup_printf ("%s-%s", get_name_alias (type, slave_type, nmc_valid_connection_types), ifname) - : g_strdup (get_name_alias (type, slave_type, nmc_valid_connection_types)); + try_name = ifname + ? g_strdup_printf ("%s-%s", get_name_alias (type, slave_type, nmc_valid_connection_types), ifname) + : g_strdup (get_name_alias (type, slave_type, nmc_valid_connection_types)); default_name = nmc_unique_connection_name (connections, try_name); g_free (try_name); g_object_set (s_con, NM_SETTING_CONNECTION_ID, default_name, NULL); @@ -5023,13 +5107,39 @@ read_properties: * from doing something that's not likely to make sense (such as missing ifname * on a bond/bridge/team, etc.). Added just to preserve traditional behavior, it * perhaps is a good idea to just remove this. */ - for (candidate = option_info; candidate->setting_name; candidate++) { - if (!option_relevant (connection, candidate)) - continue; - if (candidate->flags & NM_META_PROPERTY_INF_FLAG_REQD) { - g_string_printf (nmc->return_text, _("Error: '%s' argument is required."), candidate->option); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if (!option_relevant (connection, (const NMMetaAbstractInfo *) bi)) + continue; + if (bi->inf_flags & NM_META_PROPERTY_INF_FLAG_REQD) { + g_string_printf (nmc->return_text, _("Error: '%s' argument is required."), bi->field_name); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + } + } else { + if (!property_info->is_cli_option) + continue; + if (!option_relevant (connection, (const NMMetaAbstractInfo *) property_info)) + continue; + if (property_info->inf_flags & NM_META_PROPERTY_INF_FLAG_REQD) { + g_string_printf (nmc->return_text, _("Error: '%s' argument is required."), property_info->property_alias); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto finish; + } + } } } @@ -8541,7 +8651,7 @@ do_connection_load (NmCli *nmc, int argc, char **argv) } // FIXME: change the text when non-VPN connection types are supported -#define PROMPT_IMPORT_TYPE PROMPT_VPN_TYPE +#define PROMPT_IMPORT_TYPE NM_META_TEXT_PROMPT_VPN_TYPE #define PROMPT_IMPORT_FILE N_("File to import: ") static void diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 69d95c6efc..4393923fc5 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -4581,6 +4581,77 @@ _set_fcn_wireless_security_psk (ARGS_SET_FCN) /*****************************************************************************/ +static const NMMetaPropertyInfo property_infos_BOND[]; + +#define NESTED_PROPERTY_INFO_BOND \ + .meta_type = &nm_meta_type_nested_property_info, \ + .parent_info = &property_infos_BOND[0] + +static const NMMetaNestedPropertyTypeInfo meta_nested_property_type_infos_bond[] = { + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "mode", + .prompt = NM_META_TEXT_PROMPT_BOND_MODE, + .def_hint = "[balance-rr]", + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "primary", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding primary interface [none]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + /* this is a virtual property, only needed during "ask" mode. */ + .field_name = NULL, + .prompt = N_("Bonding monitoring mode"), + .def_hint = NM_META_TEXT_PROMPT_BOND_MON_MODE_CHOICES, + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "miimon", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding miimon [100]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "downdelay", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding downdelay [0]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "updelay", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding updelay [0]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "arp-interval", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding arp-interval [0]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "arp-ip-target", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("Bonding arp-ip-target [none]"), + }, + { + NESTED_PROPERTY_INFO_BOND, + .field_name = "lacp-rate", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = N_("LACP rate ('slow' or 'fast') [slow]"), + }, +}; + +const NMMetaPropertyTypDataNested nm_meta_property_typ_data_bond = { + .nested = meta_nested_property_type_infos_bond, + .nested_len = G_N_ELEMENTS (meta_nested_property_type_infos_bond), +}; + +/*****************************************************************************/ + #define DEFINE_PROPERTY_TYPE(...) \ (&((NMMetaPropertyType) { __VA_ARGS__ } )) @@ -4975,10 +5046,17 @@ static const NMMetaPropertyInfo property_infos_802_1X[] = { static const NMMetaPropertyInfo property_infos_ADSL[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_USERNAME), + .is_cli_option = TRUE, + .property_alias = "username", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("Username"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_PASSWORD), + .is_cli_option = TRUE, + .property_alias = "password", + .prompt = N_("Password [none]"), .is_secret = TRUE, .property_type = &_pt_gobject_string, }, @@ -4988,6 +5066,11 @@ static const NMMetaPropertyInfo property_infos_ADSL[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_PROTOCOL), + .is_cli_option = TRUE, + .property_alias = "protocol", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_ADSL_PROTO, + .def_hint = NM_META_TEXT_PROMPT_ADSL_PROTO_CHOICES, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_ADSL_PROTOCOL_PPPOA, @@ -4997,6 +5080,10 @@ static const NMMetaPropertyInfo property_infos_ADSL[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_ENCAPSULATION), + .is_cli_option = TRUE, + .property_alias = "encapsulation", + .prompt = NM_META_TEXT_PROMPT_ADSL_ENCAP, + .def_hint = NM_META_TEXT_PROMPT_ADSL_ENCAP_CHOICES, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_ADSL_ENCAPSULATION_VCMUX, @@ -5018,10 +5105,18 @@ static const NMMetaPropertyInfo property_infos_ADSL[] = { static const NMMetaPropertyInfo property_infos_BLUETOOTH[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_BDADDR), + .is_cli_option = TRUE, + .property_alias = "addr", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("Bluetooth device address"), .property_type = &_pt_gobject_mac, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_TYPE), + .is_cli_option = TRUE, + .property_alias = "bt-type", + .prompt = NM_META_TEXT_PROMPT_BT_TYPE, + .def_hint = NM_META_TEXT_PROMPT_BT_TYPE_CHOICES, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_BLUETOOTH_TYPE_DUN, @@ -5042,6 +5137,9 @@ static const NMMetaPropertyInfo property_infos_BOND[] = { .remove_fcn = _remove_fcn_bond_options, .values_fcn = _values_fcn_bond_options, ), + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (nested, + .data = &nm_meta_property_typ_data_bond, + ), }, }; @@ -5050,34 +5148,58 @@ static const NMMetaPropertyInfo property_infos_BOND[] = { static const NMMetaPropertyInfo property_infos_BRIDGE[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "mac", + .prompt = N_("MAC [none]"), .property_type = &_pt_gobject_mac, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_STP), + .is_cli_option = TRUE, + .property_alias = "stp", + .prompt = N_("Enable STP [no]"), .property_type = &_pt_gobject_bool, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PRIORITY), + .is_cli_option = TRUE, + .property_alias = "priority", + .prompt = N_("STP priority [32768]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_FORWARD_DELAY), + .is_cli_option = TRUE, + .property_alias = "forward-delay", + .prompt = N_("Forward delay [15]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_HELLO_TIME), + .is_cli_option = TRUE, + .property_alias = "hello-time", + .prompt = N_("Hello time [2]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MAX_AGE), + .is_cli_option = TRUE, + .property_alias = "max-age", + .prompt = N_("Max age [20]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_AGEING_TIME), + .is_cli_option = TRUE, + .property_alias = "ageing-time", + .prompt = N_("MAC address ageing time [300]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_SNOOPING), + .is_cli_option = TRUE, + .property_alias = "multicast-snooping", + .prompt = N_("Enable IGMP snooping [no]"), .property_type = &_pt_gobject_bool, }, }; @@ -5087,14 +5209,23 @@ static const NMMetaPropertyInfo property_infos_BRIDGE[] = { static const NMMetaPropertyInfo property_infos_BRIDGE_PORT[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_PRIORITY), + .is_cli_option = TRUE, + .property_alias = "priority", + .prompt = N_("Bridge port priority [32]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_PATH_COST), + .is_cli_option = TRUE, + .property_alias = "path-cost", + .prompt = N_("Bridge port STP path cost [100]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE), + .is_cli_option = TRUE, + .property_alias = "hairpin", + .prompt = N_("Hairpin [no]"), .property_type = &_pt_gobject_bool, }, }; @@ -5108,10 +5239,16 @@ static const NMMetaPropertyInfo property_infos_CDMA[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_USERNAME), + .is_cli_option = TRUE, + .property_alias = "user", + .prompt = N_("Username [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_PASSWORD), + .is_cli_option = TRUE, + .property_alias = "password", + .prompt = N_("Password [none]"), .is_secret = TRUE, .property_type = &_pt_gobject_string, }, @@ -5133,6 +5270,9 @@ static const NMMetaPropertyInfo property_infos_CDMA[] = { static const NMMetaPropertyInfo property_infos_CONNECTION[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_ID), + .is_cli_option = TRUE, + .property_alias = "con-name", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, .property_type = &_pt_gobject_string, }, { @@ -5145,6 +5285,10 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_INTERFACE_NAME), + .is_cli_option = TRUE, + .property_alias = "ifname", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_IFNAME, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_gobject_ifname, @@ -5152,6 +5296,10 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_TYPE), + .is_cli_option = TRUE, + .property_alias = "type", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_CON_TYPE, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_connection_type, @@ -5159,6 +5307,9 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT), + .is_cli_option = TRUE, + .property_alias = "autoconnect", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, .property_type = &_pt_gobject_bool, }, { @@ -5199,6 +5350,10 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MASTER), + .is_cli_option = TRUE, + .property_alias = "master", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, + .prompt = NM_META_TEXT_PROMPT_MASTER, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_connection_master, @@ -5206,6 +5361,9 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_SLAVE_TYPE), + .is_cli_option = TRUE, + .property_alias = "slave-type", + .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_BOND_SETTING_NAME, @@ -5394,10 +5552,16 @@ static const NMMetaPropertyInfo property_infos_GSM[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_USERNAME), + .is_cli_option = TRUE, + .property_alias = "user", + .prompt = N_("Username [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_PASSWORD), + .is_cli_option = TRUE, + .property_alias = "password", + .prompt = N_("Password [none]"), .is_secret = TRUE, .property_type = &_pt_gobject_string, }, @@ -5407,6 +5571,10 @@ static const NMMetaPropertyInfo property_infos_GSM[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_APN), + .is_cli_option = TRUE, + .property_alias = "apn", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("APN"), .property_type = &_pt_gobject_string, }, { @@ -5455,6 +5623,9 @@ static const NMMetaPropertyInfo property_infos_GSM[] = { static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "mac", + .prompt = N_("MAC [none]"), .property_type = &_pt_gobject_mac, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac, .mode = NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND, @@ -5462,6 +5633,9 @@ static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_MTU), + .is_cli_option = TRUE, + .property_alias = "mtu", + .prompt = N_("MTU [auto]"), .property_type = &_pt_gobject_mtu, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu, .get_fcn = MTU_GET_FCN (NMSettingInfiniband, nm_setting_infiniband_get_mtu), @@ -5469,6 +5643,10 @@ static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_TRANSPORT_MODE), + .is_cli_option = TRUE, + .property_alias = "transport-mode", + .prompt = NM_META_TEXT_PROMPT_IB_MODE, + .def_hint = NM_META_TEXT_PROMPT_IB_MODE_CHOICES, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC ("datagram", "connected"), @@ -5476,6 +5654,9 @@ static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_P_KEY), + .is_cli_option = TRUE, + .property_alias = "p-key", + .prompt = N_("P_KEY [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_infiniband_p_key, .set_fcn = _set_fcn_infiniband_p_key, @@ -5483,6 +5664,9 @@ static const NMMetaPropertyInfo property_infos_INFINIBAND[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_PARENT), + .is_cli_option = TRUE, + .property_alias = "parent", + .prompt = N_("Parent interface [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_gobject_ifname, @@ -5539,6 +5723,10 @@ static const NMMetaPropertyInfo property_infos_IP4_CONFIG[] = { }, { PROPERTY_INFO (NM_SETTING_IP_CONFIG_ADDRESSES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES), + .is_cli_option = TRUE, + .property_alias = "ip4", + .inf_flags = NM_META_PROPERTY_INF_FLAG_MULTI, + .prompt = N_("IPv4 address (IP[/plen]) [none]"), .describe_message = N_ ("Enter a list of IPv4 addresses formatted as:\n" " ip[/prefix], ip[/prefix],...\n" @@ -5552,6 +5740,9 @@ static const NMMetaPropertyInfo property_infos_IP4_CONFIG[] = { }, { PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY), + .is_cli_option = TRUE, + .property_alias = "gw4", + .prompt = N_("IPv4 gateway [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_ip4_config_gateway, @@ -5677,6 +5868,10 @@ static const NMMetaPropertyInfo property_infos_IP6_CONFIG[] = { }, { PROPERTY_INFO (NM_SETTING_IP_CONFIG_ADDRESSES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES), + .is_cli_option = TRUE, + .property_alias = "ip6", + .inf_flags = NM_META_PROPERTY_INF_FLAG_MULTI, + .prompt = N_("IPv6 address (IP[/plen]) [none]"), .describe_message = N_ ("Enter a list of IPv6 addresses formatted as:\n" " ip[/prefix], ip[/prefix],...\n" @@ -5690,6 +5885,9 @@ static const NMMetaPropertyInfo property_infos_IP6_CONFIG[] = { }, { PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY), + .is_cli_option = TRUE, + .property_alias = "gw6", + .prompt = N_("IPv6 gateway [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_ip6_config_gateway, @@ -5768,6 +5966,10 @@ static const NMMetaPropertyInfo property_infos_IP6_CONFIG[] = { static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_MODE), + .is_cli_option = TRUE, + .property_alias = "mode", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_IP_TUNNEL_MODE, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_ip_tunnel_mode, .set_fcn = _set_fcn_ip_tunnel_mode, @@ -5781,14 +5983,24 @@ static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_PARENT), + .is_cli_option = TRUE, + .property_alias = "dev", + .prompt = N_("Parent device [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_LOCAL), + .is_cli_option = TRUE, + .property_alias = "local", + .prompt = N_("Local endpoint [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_REMOTE), + .is_cli_option = TRUE, + .property_alias = "remote", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("Remote"), .property_type = &_pt_gobject_string, }, { @@ -5830,10 +6042,19 @@ static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { static const NMMetaPropertyInfo property_infos_MACSEC[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PARENT), + .is_cli_option = TRUE, + .property_alias = "dev", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("MACsec parent device or connection UUID"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MODE), + .is_cli_option = TRUE, + .property_alias = "mode", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_MACSEC_MODE, + .def_hint = NM_META_TEXT_PROMPT_MACSEC_MODE_CHOICES, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_macsec_mode, .set_fcn = _set_fcn_macsec_mode, @@ -5845,10 +6066,16 @@ static const NMMetaPropertyInfo property_infos_MACSEC[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_ENCRYPT), + .is_cli_option = TRUE, + .property_alias = "encrypt", + .prompt = N_("Enable encryption [yes]"), .property_type = &_pt_gobject_bool, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MKA_CAK), + .is_cli_option = TRUE, + .property_alias = "cak", + .prompt = N_("MKA CAK"), .is_secret = TRUE, .property_type = &_pt_gobject_string, }, @@ -5858,10 +6085,16 @@ static const NMMetaPropertyInfo property_infos_MACSEC[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MKA_CKN), + .is_cli_option = TRUE, + .property_alias = "ckn", + .prompt = N_("MKA_CKN"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PORT), + .is_cli_option = TRUE, + .property_alias = "port", + .prompt = N_("SCI port [1]"), .property_type = &_pt_gobject_int, }, { @@ -5882,10 +6115,18 @@ static const NMMetaPropertyInfo property_infos_MACSEC[] = { static const NMMetaPropertyInfo property_infos_MACVLAN[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_PARENT), + .is_cli_option = TRUE, + .property_alias = "dev", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("MACVLAN parent device or connection UUID"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_MODE), + .is_cli_option = TRUE, + .property_alias = "mode", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_MACVLAN_MODE, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_macvlan_mode, .set_fcn = _set_fcn_macvlan_mode, @@ -5903,6 +6144,9 @@ static const NMMetaPropertyInfo property_infos_MACVLAN[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_TAP), + .is_cli_option = TRUE, + .property_alias = "tap", + .prompt = N_("Tap [no]"), .property_type = &_pt_gobject_bool, }, }; @@ -5912,6 +6156,10 @@ static const NMMetaPropertyInfo property_infos_MACVLAN[] = { static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_SSID), + .is_cli_option = TRUE, + .property_alias = "ssid", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("SSID"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_olpc_mesh_ssid, .set_fcn = _set_fcn_gobject_ssid, @@ -5919,6 +6167,9 @@ static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_CHANNEL), + .is_cli_option = TRUE, + .property_alias = "channel", + .prompt = N_("OLPC Mesh channel [1]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_olpc_mesh_channel, @@ -5926,6 +6177,9 @@ static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "dhcp-anycast", + .prompt = N_("DHCP anycast MAC address [none]"), .property_type = &_pt_gobject_mac, }, }; @@ -5935,14 +6189,24 @@ static const NMMetaPropertyInfo property_infos_OLPC_MESH[] = { static const NMMetaPropertyInfo property_infos_PPPOE[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_SERVICE), + .is_cli_option = TRUE, + .property_alias = "service", + .prompt = N_("Service [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_USERNAME), + .is_cli_option = TRUE, + .property_alias = "username", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("PPPoE username"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_PASSWORD), + .is_cli_option = TRUE, + .property_alias = "password", + .prompt = N_("Password [none]"), .is_secret = TRUE, .property_type = &_pt_gobject_string, }, @@ -6037,6 +6301,10 @@ static const NMMetaPropertyInfo property_infos_PPP[] = { static const NMMetaPropertyInfo property_infos_PROXY[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_METHOD), + .is_cli_option = TRUE, + .property_alias = "method", + .prompt = NM_META_TEXT_PROMPT_PROXY_METHOD, + .def_hint = NM_META_TEXT_PROMPT_PROXY_METHOD_CHOICES, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_proxy_method, .set_fcn = _set_fcn_proxy_method, @@ -6050,14 +6318,23 @@ static const NMMetaPropertyInfo property_infos_PROXY[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_BROWSER_ONLY), + .is_cli_option = TRUE, + .property_alias = "browser-only", + .prompt = N_("Browser only [no]"), .property_type = &_pt_gobject_bool }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_PAC_URL), + .is_cli_option = TRUE, + .property_alias = "pac-url", + .prompt = N_("PAC URL"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_PAC_SCRIPT), + .is_cli_option = TRUE, + .property_alias = "pac-script", + .prompt = N_("PAC script"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_proxy_pac_script, @@ -6070,6 +6347,9 @@ static const NMMetaPropertyInfo property_infos_PROXY[] = { static const NMMetaPropertyInfo property_infos_TEAM[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_CONFIG), + .is_cli_option = TRUE, + .property_alias = "config", + .prompt = N_("Team JSON configuration [none]"), .describe_message = N_ (TEAM_DESCRIBE_MESSAGE), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, @@ -6083,6 +6363,9 @@ static const NMMetaPropertyInfo property_infos_TEAM[] = { static const NMMetaPropertyInfo property_infos_TEAM_PORT[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_CONFIG), + .is_cli_option = TRUE, + .property_alias = "config", + .prompt = N_("Team JSON configuration [none]"), .describe_message = N_ (TEAM_DESCRIBE_MESSAGE), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, @@ -6124,6 +6407,10 @@ static const NMMetaPropertyInfo property_infos_SERIAL[] = { static const NMMetaPropertyInfo property_infos_TUN[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_MODE), + .is_cli_option = TRUE, + .property_alias = "mode", + .prompt = NM_META_TEXT_PROMPT_TUN_MODE, + .def_hint = NM_META_TEXT_PROMPT_TUN_MODE_CHOICES, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_tun_mode, .set_fcn = _set_fcn_tun_mode, @@ -6134,22 +6421,37 @@ static const NMMetaPropertyInfo property_infos_TUN[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_OWNER), + .is_cli_option = TRUE, + .property_alias = "owner", + .prompt = N_("User ID [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_GROUP), + .is_cli_option = TRUE, + .property_alias = "group", + .prompt = N_("Group ID [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_PI), + .is_cli_option = TRUE, + .property_alias = "pi", + .prompt = N_("Enable PI [no]"), .property_type = &_pt_gobject_bool, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_VNET_HDR), + .is_cli_option = TRUE, + .property_alias = "vnet-hdr", + .prompt = N_("Enable VNET header [no]"), .property_type = &_pt_gobject_bool, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_MULTI_QUEUE), + .is_cli_option = TRUE, + .property_alias = "multi-queue", + .prompt = N_("Enable multi queue [no]"), .property_type = &_pt_gobject_bool, }, }; @@ -6159,14 +6461,25 @@ static const NMMetaPropertyInfo property_infos_TUN[] = { static const NMMetaPropertyInfo property_infos_VLAN[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_PARENT), + .is_cli_option = TRUE, + .property_alias = "dev", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("VLAN parent device or connection UUID"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_ID), + .is_cli_option = TRUE, + .property_alias = "id", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("VLAN ID (<0-4094>)"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_FLAGS), + .is_cli_option = TRUE, + .property_alias = "flags", + .prompt = N_("VLAN flags (<0-7>) [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_vlan_flags, .set_fcn = _set_fcn_gobject_flags, @@ -6174,6 +6487,9 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP), + .is_cli_option = TRUE, + .property_alias = "ingress", + .prompt = N_("Ingress priority maps [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_vlan_ingress_priority_map, .set_fcn = _set_fcn_vlan_ingress_priority_map, @@ -6182,6 +6498,9 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP), + .is_cli_option = TRUE, + .property_alias = "egress", + .prompt = N_("Egress priority maps [none]"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_vlan_egress_priority_map, .set_fcn = _set_fcn_vlan_egress_priority_map, @@ -6195,6 +6514,10 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { static const NMMetaPropertyInfo property_infos_VPN[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SERVICE_TYPE), + .is_cli_option = TRUE, + .property_alias = "vpn-type", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_VPN_TYPE, .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_vpn_service_type, @@ -6202,6 +6525,9 @@ static const NMMetaPropertyInfo property_infos_VPN[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_USER_NAME), + .is_cli_option = TRUE, + .property_alias = "user", + .prompt = N_("Username [none]"), .property_type = &_pt_gobject_string, }, { @@ -6236,30 +6562,53 @@ static const NMMetaPropertyInfo property_infos_VPN[] = { static const NMMetaPropertyInfo property_infos_VXLAN[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_PARENT), + .is_cli_option = TRUE, + .property_alias = "dev", + .prompt = N_("Parent device [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_ID), + .is_cli_option = TRUE, + .property_alias = "id", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("VXLAN ID"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_LOCAL), + .is_cli_option = TRUE, + .property_alias = "local", + .prompt = N_("Local address [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_REMOTE), + .is_cli_option = TRUE, + .property_alias = "remote", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("Remote"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_SOURCE_PORT_MIN), + .is_cli_option = TRUE, + .property_alias = "source-port-min", + .prompt = N_("Minimum source port [0]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_SOURCE_PORT_MAX), + .is_cli_option = TRUE, + .property_alias = "source-port-max", + .prompt = N_("Maximum source port [0]"), .property_type = &_pt_gobject_uint, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_DESTINATION_PORT), + .is_cli_option = TRUE, + .property_alias = "destination-port", + .prompt = N_("Destination port [8472]"), .property_type = &_pt_gobject_uint, }, { @@ -6305,10 +6654,17 @@ static const NMMetaPropertyInfo property_infos_VXLAN[] = { static const NMMetaPropertyInfo property_infos_WIMAX[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIMAX_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "mac", + .prompt = N_("MAC [none]"), .property_type = &_pt_gobject_string, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIMAX_NETWORK_NAME), + .is_cli_option = TRUE, + .property_alias = "nsp", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("WiMAX NSP name"), .property_type = &_pt_gobject_mac, }, }; @@ -6341,10 +6697,16 @@ static const NMMetaPropertyInfo property_infos_WIRED[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "mac", + .prompt = N_("MAC [none]"), .property_type = &_pt_gobject_mac, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_CLONED_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "cloned-mac", + .prompt = N_("Cloned MAC [none]"), .property_type = &_pt_gobject_mac, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac, .mode = NM_META_PROPERTY_TYPE_MAC_MODE_CLONED, @@ -6364,6 +6726,9 @@ static const NMMetaPropertyInfo property_infos_WIRED[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MTU), + .is_cli_option = TRUE, + .property_alias = "mtu", + .prompt = N_("MTU [auto]"), .property_type = &_pt_gobject_mtu, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu, .get_fcn = MTU_GET_FCN (NMSettingWired, nm_setting_wired_get_mtu), @@ -6414,6 +6779,10 @@ static const NMMetaPropertyInfo property_infos_WIRED[] = { static const NMMetaPropertyInfo property_infos_WIRELESS[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SSID), + .is_cli_option = TRUE, + .property_alias = "ssid", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("SSID"), .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_wireless_ssid, .set_fcn = _set_fcn_gobject_ssid, @@ -6421,6 +6790,10 @@ static const NMMetaPropertyInfo property_infos_WIRELESS[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MODE), + .is_cli_option = TRUE, + .property_alias = "mode", + .prompt = NM_META_TEXT_PROMPT_WIFI_MODE, + .def_hint = NM_META_TEXT_PROMPT_WIFI_MODE_CHOICES, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_WIRELESS_MODE_INFRA, @@ -6459,9 +6832,15 @@ static const NMMetaPropertyInfo property_infos_WIRELESS[] = { { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS), .property_type = &_pt_gobject_mac, + .is_cli_option = TRUE, + .property_alias = "mac", + .prompt = N_("MAC [none]"), }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS), + .is_cli_option = TRUE, + .property_alias = "cloned-mac", + .prompt = N_("Cloned MAC [none]"), .property_type = &_pt_gobject_mac, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac, .mode = NM_META_PROPERTY_TYPE_MAC_MODE_CLONED, @@ -6488,6 +6867,9 @@ static const NMMetaPropertyInfo property_infos_WIRELESS[] = { }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MTU), + .is_cli_option = TRUE, + .property_alias = "mtu", + .prompt = N_("MTU [auto]"), .property_type = &_pt_gobject_mtu, .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu, .get_fcn = MTU_GET_FCN (NMSettingWireless, nm_setting_wireless_get_mtu), @@ -6640,11 +7022,46 @@ static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { }, }; +#define SETTING_PRETTY_NAME_802_1X "802-1x settings" +#define SETTING_PRETTY_NAME_ADSL "ADSL connection" +#define SETTING_PRETTY_NAME_BLUETOOTH "bluetooth connection" +#define SETTING_PRETTY_NAME_BOND "Bond device" +#define SETTING_PRETTY_NAME_BRIDGE "Bridge device" +#define SETTING_PRETTY_NAME_BRIDGE_PORT "Bridge port" +#define SETTING_PRETTY_NAME_CDMA "CDMA mobile broadband connection" +#define SETTING_PRETTY_NAME_CONNECTION "General settings" +#define SETTING_PRETTY_NAME_DCB "DCB settings" +#define SETTING_PRETTY_NAME_DUMMY "Dummy settings" +#define SETTING_PRETTY_NAME_GSM "GSM mobile broadband connection" +#define SETTING_PRETTY_NAME_INFINIBAND "InfiniBand connection" +#define SETTING_PRETTY_NAME_IP4_CONFIG "IPv4 protocol" +#define SETTING_PRETTY_NAME_IP6_CONFIG "IPv6 protocol" +#define SETTING_PRETTY_NAME_IP_TUNNEL "IP-tunnel settings" +#define SETTING_PRETTY_NAME_MACSEC "MACsec connection" +#define SETTING_PRETTY_NAME_MACVLAN "macvlan connection" +#define SETTING_PRETTY_NAME_OLPC_MESH "OLPC Mesh connection" +#define SETTING_PRETTY_NAME_PPP "PPP settings" +#define SETTING_PRETTY_NAME_PPPOE "PPPoE" +#define SETTING_PRETTY_NAME_PROXY "Proxy" +#define SETTING_PRETTY_NAME_SERIAL "Serial settings" +#define SETTING_PRETTY_NAME_TEAM "Team device" +#define SETTING_PRETTY_NAME_TEAM_PORT "Team port" +#define SETTING_PRETTY_NAME_TUN "Tun device" +#define SETTING_PRETTY_NAME_USER "User settings" +#define SETTING_PRETTY_NAME_VLAN "VLAN connection" +#define SETTING_PRETTY_NAME_VPN "VPN connection" +#define SETTING_PRETTY_NAME_VXLAN "VXLAN connection" +#define SETTING_PRETTY_NAME_WIMAX "WiMAX connection" +#define SETTING_PRETTY_NAME_WIRED "Wired Ethernet" +#define SETTING_PRETTY_NAME_WIRELESS "Wi-Fi connection" +#define SETTING_PRETTY_NAME_WIRELESS_SECURITY "Wi-Fi security settings" + const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { #define SETTING_INFO_EMPTY(type) \ [NM_META_SETTING_TYPE_##type] = { \ .meta_type = &nm_meta_type_setting_info_editor, \ .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ + .pretty_name = N_(SETTING_PRETTY_NAME_##type), \ } #define SETTING_INFO(type) \ [NM_META_SETTING_TYPE_##type] = { \ @@ -6652,6 +7069,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ .properties = property_infos_##type, \ .properties_num = G_N_ELEMENTS (property_infos_##type), \ + .pretty_name = N_(SETTING_PRETTY_NAME_##type), \ } SETTING_INFO (802_1X), SETTING_INFO (ADSL), @@ -6805,3 +7223,7 @@ const NMMetaType nm_meta_type_property_info = { .get_nested = _meta_type_property_info_get_nested, .get_fcn = _meta_type_property_info_get_fcn, }; + +const NMMetaType nm_meta_type_nested_property_info = { + .type_name = "nested_property_info", +}; diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index bd91e6fa03..2a967267cd 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -24,6 +24,60 @@ #define NM_META_TEXT_HIDDEN "" +#define NM_META_TEXT_PROMPT_ADSL_PROTO N_("Protocol") +#define NM_META_TEXT_PROMPT_ADSL_PROTO_CHOICES "(" NM_SETTING_ADSL_PROTOCOL_PPPOA "/" NM_SETTING_ADSL_PROTOCOL_PPPOE "/" NM_SETTING_ADSL_PROTOCOL_IPOATM ")" + +#define NM_META_TEXT_PROMPT_ADSL_ENCAP N_("ADSL encapsulation") +#define NM_META_TEXT_PROMPT_ADSL_ENCAP_CHOICES "(" NM_SETTING_ADSL_ENCAPSULATION_VCMUX "/" NM_SETTING_ADSL_ENCAPSULATION_LLC ") [none]" + +#define NM_META_TEXT_PROMPT_CON_TYPE N_("Connection type") +#define NM_META_TEXT_PROMPT_IFNAME N_("Interface name [*]") +#define NM_META_TEXT_PROMPT_VPN_TYPE N_("VPN type") +#define NM_META_TEXT_PROMPT_MASTER N_("Master") + +#define NM_META_TEXT_PROMPT_IB_MODE N_("Transport mode") +#define NM_META_TEXT_WORD_DATAGRAM "datagram" +#define NM_META_TEXT_WORD_CONNECTED "connected" +#define NM_META_TEXT_PROMPT_IB_MODE_CHOICES "(" NM_META_TEXT_WORD_DATAGRAM "/" NM_META_TEXT_WORD_CONNECTED ") [" NM_META_TEXT_WORD_DATAGRAM "]" + +#define NM_META_TEXT_PROMPT_BT_TYPE N_("Bluetooth type") +#define NM_META_TEXT_WORD_PANU "panu" +#define NM_META_TEXT_WORD_DUN_GSM "dun-gsm" +#define NM_META_TEXT_WORD_DUN_CDMA "dun-cdma" +#define NM_META_TEXT_PROMPT_BT_TYPE_CHOICES "(" NM_META_TEXT_WORD_PANU "/" NM_META_TEXT_WORD_DUN_GSM "/" NM_META_TEXT_WORD_DUN_CDMA ") [" NM_META_TEXT_WORD_PANU "]" + +#define NM_META_TEXT_PROMPT_BOND_MODE N_("Bonding mode") + +#define NM_META_TEXT_PROMPT_BOND_MON_MODE N_("Bonding monitoring mode") +#define NM_META_TEXT_WORD_MIIMON "miimon" +#define NM_META_TEXT_WORD_ARP "arp" +#define NM_META_TEXT_PROMPT_BOND_MON_MODE_CHOICES "(" NM_META_TEXT_WORD_MIIMON "/" NM_META_TEXT_WORD_ARP ") [" NM_META_TEXT_WORD_MIIMON "]" + +#define NM_META_TEXT_PROMPT_WIFI_MODE N_("Wi-Fi mode") +#define NM_META_TEXT_WORD_INFRA "infrastructure" +#define NM_META_TEXT_WORD_AP "ap" +#define NM_META_TEXT_WORD_ADHOC "adhoc" +#define NM_META_TEXT_PROMPT_WIFI_MODE_CHOICES "(" NM_META_TEXT_WORD_INFRA "/" NM_META_TEXT_WORD_AP "/" NM_META_TEXT_WORD_ADHOC ") [" NM_META_TEXT_WORD_INFRA "]" + +#define NM_META_TEXT_PROMPT_TUN_MODE N_("Tun mode") +#define NM_META_TEXT_WORD_TUN "tun" +#define NM_META_TEXT_WORD_TAP "tap" +#define NM_META_TEXT_PROMPT_TUN_MODE_CHOICES "(" NM_META_TEXT_WORD_TUN "/" NM_META_TEXT_WORD_TAP ") [" NM_META_TEXT_WORD_TUN "]" + +#define NM_META_TEXT_PROMPT_IP_TUNNEL_MODE N_("IP Tunnel mode") + +#define NM_META_TEXT_PROMPT_MACVLAN_MODE N_("MACVLAN mode") + +#define NM_META_TEXT_PROMPT_MACSEC_MODE N_("MACsec mode") +#define NM_META_TEXT_WORD_PSK "psk" +#define NM_META_TEXT_WORD_EAP "eap" +#define NM_META_TEXT_PROMPT_MACSEC_MODE_CHOICES "(" NM_META_TEXT_WORD_PSK "/" NM_META_TEXT_WORD_EAP ")" + +#define NM_META_TEXT_PROMPT_PROXY_METHOD N_("Proxy method") +#define NM_META_TEXT_WORD_NONE "none" +#define NM_META_TEXT_WORD_AUTO "auto" +#define NM_META_TEXT_PROMPT_PROXY_METHOD_CHOICES "(" NM_META_TEXT_WORD_NONE "/" NM_META_TEXT_WORD_AUTO ") [" NM_META_TEXT_WORD_NONE "]" + typedef enum { NM_META_TERM_COLOR_NORMAL = 0, NM_META_TERM_COLOR_BLACK = 1, @@ -145,6 +199,8 @@ struct _NMMetaPropertyType { struct _NMUtilsEnumValueInfo; +struct _NMMetaPropertyTypDataNested; + struct _NMMetaPropertyTypData { union { struct { @@ -162,6 +218,9 @@ struct _NMMetaPropertyTypData { struct { NMMetaPropertyTypeMacMode mode; } mac; + struct { + const struct _NMMetaPropertyTypDataNested *data; + } nested; } subtype; const char *const*values_static; NMMetaPropertyTypFlags typ_flags; @@ -181,8 +240,17 @@ struct _NMMetaPropertyInfo { const char *property_name; + const char *property_alias; + + NMMetaPropertyInfFlags inf_flags; bool is_secret:1; + bool is_cli_option:1; + + const char *prompt; + + const char *def_hint; + const char *describe_doc; const char *describe_message; @@ -194,6 +262,7 @@ struct _NMMetaPropertyInfo { struct _NMMetaSettingInfoEditor { const NMMetaType *meta_type; const NMMetaSettingInfo *general; + const char *pretty_name; /* the order of the properties matter. The first *must* be the * "name", and then the order is as they are listed by default. */ const NMMetaPropertyInfo *properties; @@ -249,4 +318,28 @@ struct _NMMetaEnvironment { /*****************************************************************************/ +/* NMSettingBond is special in that it has nested properties. + * We will add API to proper handle such types (Bond, VPN, User), + * but for now just expose the type info directly. */ + +extern const NMMetaType nm_meta_type_nested_property_info; + +typedef struct _NMMetaNestedPropertyTypeInfo { + const NMMetaType *meta_type; + const NMMetaPropertyInfo *parent_info; + const char *field_name; + NMMetaPropertyInfFlags inf_flags; + const char *prompt; + const char *def_hint; +} NMMetaNestedPropertyTypeInfo; + +typedef struct _NMMetaPropertyTypDataNested { + const NMMetaNestedPropertyTypeInfo *nested; + guint nested_len; +} NMMetaPropertyTypDataNested; + +const NMMetaPropertyTypDataNested nm_meta_property_typ_data_bond; + +/*****************************************************************************/ + #endif /* __NM_META_SETTING_DESC_H__ */ From cfd9f66ae90573377665bb0a21accc62db94c42e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 16:38:35 +0200 Subject: [PATCH 20/32] cli: add property completion to meta-data (not used yet). --- clients/cli/connections.c | 18 +++---- clients/common/nm-meta-setting-access.c | 65 +++++++++++++++++++++++++ clients/common/nm-meta-setting-access.h | 4 ++ clients/common/nm-meta-setting-desc.c | 28 +++++++++++ clients/common/nm-meta-setting-desc.h | 7 +++ 5 files changed, 113 insertions(+), 9 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 38975fb8c6..943182a6a2 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3846,13 +3846,6 @@ ensure_settings (NMConnection *connection, const NameItem *item) /*----------------------------------------------------------------------------*/ -static char * -gen_func_slave_type (const char *text, int state) -{ - const char *words[] = { "bond", "team", "bridge", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - static char * gen_func_vpn_types (const char *text, int state) { @@ -4306,7 +4299,6 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", NULL, gen_func_bool_values_l10n), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, nmc_rl_gen_func_ifnames), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_SLAVE_TYPE, "slave-type", NULL, gen_func_slave_type), OPTION_INFO (INFINIBAND, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NULL, gen_func_ib_type), OPTION_INFO (WIRELESS, NM_SETTING_WIRELESS_MODE, "mode", NULL, gen_func_wifi_mode), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), @@ -4462,6 +4454,15 @@ static void complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) { const OptionInfo *candidate; + const char *const*values; + gs_strfreev char **values_to_free = NULL; + + values = nm_meta_abstract_info_complete (abstract_info, prefix, &values_to_free); + if (values) { + for (; values[0]; values++) + g_print ("%s\n", values[0]); + return; + } candidate = _meta_abstract_get_option_info (abstract_info); if (candidate && candidate->generator_func) @@ -4513,7 +4514,6 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar } else if ( strcmp (setting_name, NM_SETTING_VXLAN_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_VXLAN_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - } /*----------------------------------------------------------------------------*/ diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index d3843dfef1..e18b03632e 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -253,3 +253,68 @@ nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, out_flags, out_to_free); } + +const char *const* +nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, + const char *text, + char ***out_to_free) +{ + const char *const*values; + gsize i, j, text_len; + + nm_assert (abstract_info); + nm_assert (abstract_info->meta_type); + nm_assert (out_to_free && !*out_to_free); + + *out_to_free = NULL; + + if (!abstract_info->meta_type->complete_fcn) + return NULL; + + values = abstract_info->meta_type->complete_fcn (abstract_info, + text, + out_to_free); + + nm_assert (!*out_to_free || values == (const char *const*) *out_to_free); + + if (!text || !text[0] || !values || !values[0]) + return values; + + /* for convenience, we all the complete_fcn() implementations to + * ignore "text". We filter out invalid matches here. */ + + text_len = strlen (text); + + if (*out_to_free) { + char **v = *out_to_free; + + for (i =0, j = 0; v[i]; i++) { + if (strncmp (v[i], text, text_len) != 0) + continue; + v[j++] = v[i]; + } + v[j++] = NULL; + return (const char *const*) *out_to_free; + } else { + const char *const*v = values; + char **r; + + for (i = 0, j = 0; v[i]; i++) { + if (strncmp (v[i], text, text_len) != 0) + continue; + j++; + } + if (j == i) + return values; + + r = g_new (char *, j + 1); + v = values; + for (i = 0, j = 0; v[i]; i++) { + if (strncmp (v[i], text, text_len) != 0) + continue; + r[j++] = g_strdup (v[i]); + } + r[j++] = NULL; + return (const char *const*) (*out_to_free = r); + } +} diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 8aec04aced..7a816875cd 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -59,6 +59,10 @@ gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); +const char *const*nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, + const char *text, + char ***out_to_free); + /*****************************************************************************/ #endif /* _NM_META_SETTING_ACCESS_H__ */ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 4393923fc5..aff546d0e6 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -7210,6 +7210,33 @@ _meta_type_property_info_get_nested (const NMMetaAbstractInfo *abstract_info, return NULL; } +static const char *const* +_meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, + const char *text, + char ***out_to_free) +{ + const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; + + nm_assert (out_to_free && !*out_to_free); + + if (info->property_type->complete_fcn) { + return info->property_type->complete_fcn (info, + text, + out_to_free); + } + + if (info->property_type->values_fcn) { + return info->property_type->values_fcn (info, + out_to_free); + } + + if ( info->property_typ_data + && info->property_typ_data->values_static) + return info->property_typ_data->values_static; + + return NULL; +} + const NMMetaType nm_meta_type_setting_info_editor = { .type_name = "setting_info_editor", .get_name = _meta_type_setting_info_editor_get_name, @@ -7222,6 +7249,7 @@ const NMMetaType nm_meta_type_property_info = { .get_name = _meta_type_property_info_get_name, .get_nested = _meta_type_property_info_get_nested, .get_fcn = _meta_type_property_info_get_fcn, + .complete_fcn = _meta_type_property_info_complete_fcn, }; const NMMetaType nm_meta_type_nested_property_info = { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 2a967267cd..0339a59d81 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -195,6 +195,10 @@ struct _NMMetaPropertyType { const char *const*(*values_fcn) (const NMMetaPropertyInfo *property_info, char ***out_to_free); + + const char *const*(*complete_fcn) (const NMMetaPropertyInfo *property_info, + const char *text, + char ***out_to_free); }; struct _NMUtilsEnumValueInfo; @@ -284,6 +288,9 @@ struct _NMMetaType { NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); + const char *const*(*complete_fcn) (const NMMetaAbstractInfo *info, + const char *text, + char ***out_to_free); }; struct _NMMetaAbstractInfo { From 0b7e9c3beff4496ec446b4b3f260403dcedf888a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 17:25:31 +0200 Subject: [PATCH 21/32] cli: move prompting for boolean values to meta data This changes behavior, in that yes|no prompt and answer is no longer localized. For command line arguments, I think it is always wrong for nmcli to behave differently based on the localization. That is, input properties on command line should not be translated. One could make an argument, that in interactive mode that is different and the user can be prompted in the his language. But I think for consistency, it is wrong to ask for localized nmcli input. --- clients/cli/connections.c | 55 ++++++++++----------------- clients/common/nm-client-utils.c | 4 +- clients/common/nm-meta-setting-desc.c | 26 +++++++++++++ 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 943182a6a2..87e318c3b5 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3375,8 +3375,6 @@ normalized_master_for_slave (const GPtrArray *connections, #define WORD_YES "yes" #define WORD_NO "no" -#define WORD_LOC_YES _("yes") -#define WORD_LOC_NO _("no") static const char * prompt_yes_no (gboolean default_yes, char *delim) { @@ -3386,8 +3384,8 @@ prompt_yes_no (gboolean default_yes, char *delim) delim = ""; snprintf (prompt, sizeof (prompt), "(%s/%s) [%s]%s ", - WORD_LOC_YES, WORD_LOC_NO, - default_yes ? WORD_LOC_YES : WORD_LOC_NO, delim); + WORD_YES, WORD_NO, + default_yes ? WORD_YES : WORD_NO, delim); return prompt; } @@ -3858,7 +3856,7 @@ gen_func_vpn_types (const char *text, int state) static char * gen_func_bool_values_l10n (const char *text, int state) { - const char *words[] = { WORD_LOC_YES, WORD_LOC_NO, NULL }; + const char *words[] = { WORD_YES, WORD_NO, NULL }; return nmc_rl_gen_func_basic (text, state, words); } @@ -4230,17 +4228,6 @@ set_bluetooth_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, con return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); } -static gboolean -set_yes_no (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) -{ - if (g_strcmp0 (value, _(WORD_LOC_YES))) - value = WORD_YES; - if (g_strcmp0 (value, _(WORD_LOC_NO))) - value = WORD_NO; - - return set_property (con, option->setting_info->general->setting_name, option->property, value, '\0', error); -} - static gboolean set_ip4_address (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { @@ -4296,7 +4283,6 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) .generator_func = generator_func_, \ } OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_AUTOCONNECT, "autoconnect", NULL, gen_func_bool_values_l10n), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, nmc_rl_gen_func_ifnames), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), OPTION_INFO (INFINIBAND, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NULL, gen_func_ib_type), @@ -4312,28 +4298,19 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-interval", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-ip-target", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "lacp-rate", set_bond_option, gen_func_bond_lacp_rate), - OPTION_INFO (BRIDGE, NM_SETTING_BRIDGE_STP, "stp", set_yes_no, gen_func_bool_values_l10n), - OPTION_INFO (BRIDGE, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "multicast-snooping", set_yes_no, gen_func_bool_values_l10n), - OPTION_INFO (BRIDGE_PORT, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin", set_yes_no, gen_func_bool_values_l10n), OPTION_INFO (VPN, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NULL, gen_func_vpn_types), OPTION_INFO (ADSL, NM_SETTING_ADSL_PROTOCOL, "protocol", NULL, gen_func_adsl_proto), OPTION_INFO (ADSL, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NULL, gen_func_adsl_encap), OPTION_INFO (MACSEC, NM_SETTING_MACSEC_MODE, "mode", NULL, gen_func_macsec_mode), - OPTION_INFO (MACSEC, NM_SETTING_MACSEC_ENCRYPT, "encrypt", set_yes_no, gen_func_bool_values_l10n), OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_MODE, "mode", NULL, gen_func_macvlan_mode), - OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_TAP, "tap", set_yes_no, gen_func_bool_values_l10n), OPTION_INFO (VXLAN, NM_SETTING_VXLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (TUN, NM_SETTING_TUN_MODE, "mode", NULL, gen_func_tun_mode), - OPTION_INFO (TUN, NM_SETTING_TUN_PI, "pi", set_yes_no, gen_func_bool_values_l10n), - OPTION_INFO (TUN, NM_SETTING_TUN_VNET_HDR, "vnet-hdr", set_yes_no, gen_func_bool_values_l10n), - OPTION_INFO (TUN, NM_SETTING_TUN_MULTI_QUEUE, "multi-queue", set_yes_no, gen_func_bool_values_l10n), OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_MODE, "mode", NULL, gen_func_ip_tunnel_mode), OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (IP4_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", set_ip4_address, NULL), OPTION_INFO (IP6_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", set_ip6_address, NULL), OPTION_INFO (PROXY, NM_SETTING_PROXY_METHOD, "method", NULL, gen_func_proxy_method), - OPTION_INFO (PROXY, NM_SETTING_PROXY_BROWSER_ONLY, "browser-only", set_yes_no, gen_func_bool_values_l10n), { 0 }, }; const char *property_name, *option; @@ -4450,7 +4427,7 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix) } } -static void +static gboolean complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) { const OptionInfo *candidate; @@ -4461,17 +4438,29 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) if (values) { for (; values[0]; values++) g_print ("%s\n", values[0]); - return; + return TRUE; } candidate = _meta_abstract_get_option_info (abstract_info); - if (candidate && candidate->generator_func) + if (candidate && candidate->generator_func) { run_rl_generator (candidate->generator_func, prefix); + return TRUE; + } + + return FALSE; } static void complete_property (const gchar *setting_name, const gchar *property, const gchar *prefix) { + const NMMetaPropertyInfo *property_info; + + property_info = nm_meta_property_info_find_by_name (setting_name, property); + if (property_info) { + if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix)) + return; + } + if (strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) == 0) { if (strcmp (property, NM_SETTING_CONNECTION_TYPE) == 0) run_rl_generator (gen_connection_types, prefix); @@ -4509,8 +4498,6 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar run_rl_generator (gen_func_macvlan_mode, prefix); else if (strcmp (property, NM_SETTING_MACVLAN_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - else if (strcmp (property, NM_SETTING_MACVLAN_TAP) == 0) - run_rl_generator (gen_func_bool_values_l10n, prefix); } else if ( strcmp (setting_name, NM_SETTING_VXLAN_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_VXLAN_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); @@ -4913,7 +4900,7 @@ want_provide_opt_args (const char *type, int num) "Do you want to provide them? %s", num), prompt_yes_no (TRUE, NULL)); answer = answer ? g_strstrip (answer) : NULL; - if (answer && !matches (answer, WORD_LOC_YES)) + if (answer && !matches (answer, WORD_YES)) ret = FALSE; g_free (answer); return ret; @@ -6663,7 +6650,7 @@ confirm_quit (void) "Do you really want to quit? %s"), prompt_yes_no (FALSE, NULL)); answer = answer ? g_strstrip (answer) : NULL; - if (answer && matches (answer, WORD_LOC_YES)) + if (answer && matches (answer, WORD_YES)) want_quit = TRUE; g_free (answer); @@ -7015,7 +7002,7 @@ confirm_connection_saving (NMConnection *local, NMConnection *remote) "That might result in an immediate activation of the connection.\n" "Do you still want to save? %s"), prompt_yes_no (TRUE, NULL)); answer = answer ? g_strstrip (answer) : NULL; - if (!answer || matches (answer, WORD_LOC_YES)) + if (!answer || matches (answer, WORD_YES)) confirmed = TRUE; else confirmed = FALSE; diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index 8f8b51606b..84e7061772 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -92,8 +92,8 @@ nmc_string_to_uint (const char *str, gboolean nmc_string_to_bool (const char *str, gboolean *val_bool, GError **error) { - const char *s_true[] = { "true", "yes", "on", NULL }; - const char *s_false[] = { "false", "no", "off", NULL }; + const char *s_true[] = { "true", "yes", "on", "1", NULL }; + const char *s_false[] = { "false", "no", "off", "0", NULL }; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index aff546d0e6..327fb61ad5 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -523,6 +523,9 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_REMOVE_FCN \ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error +#define ARGS_COMPLETE_FCN \ + const NMMetaPropertyInfo *property_info, const char *text, char ***out_to_free + #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free @@ -1084,6 +1087,28 @@ _values_fcn_gobject_enum (ARGS_VALUES_FCN) /*****************************************************************************/ +static const char *const* +_complete_fcn_gobject_bool (ARGS_COMPLETE_FCN) +{ + static const char *const v[] = { + "true", + "false", + "on", + "off", + "1", + "0", + "yes", + "no", + NULL, + }; + + if (!text || !text[0]) + return &v[6]; + return v; +} + +/*****************************************************************************/ + static char * wep_key_type_to_string (NMWepKeyType type) { @@ -4680,6 +4705,7 @@ static const NMMetaPropertyType _pt_gobject_string = { static const NMMetaPropertyType _pt_gobject_bool = { .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_gobject_bool, + .complete_fcn = _complete_fcn_gobject_bool, }; static const NMMetaPropertyType _pt_gobject_int = { From 218f46ebcc2040608aecb36b4f63f084d62b31c4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 18:09:13 +0200 Subject: [PATCH 22/32] cli: use meta data's completion in nmcli_con_add_tab_completion() --- clients/cli/connections.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 87e318c3b5..64290ef833 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3509,6 +3509,18 @@ _meta_property_needs_bond_hack (const NMMetaPropertyInfo *property_info) } +static char ** +_meta_abstract_complete (const NMMetaAbstractInfo *abstract_info, const char *text) +{ + const char *const*values; + char **values_to_free = NULL; + + values = nm_meta_abstract_info_complete (abstract_info, text, &values_to_free); + if (values) + return values_to_free ?: g_strdupv ((char **) values); + return NULL; +} + static void _meta_abstract_get (const NMMetaAbstractInfo *abstract_info, const NMMetaSettingInfoEditor **out_setting_info, @@ -4753,6 +4765,7 @@ is_single_word (const char* line) static char ** nmcli_con_add_tab_completion (const char *text, int start, int end) { + NMMetaSettingType s; char **match_array = NULL; rl_compentry_func_t *generator_func = NULL; gs_free char *no = g_strdup_printf ("[%s]: ", gettext ("no")); @@ -4767,6 +4780,40 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) if (!is_single_word (rl_line_buffer)) return NULL; + for (s = 0; s < _NM_META_SETTING_TYPE_NUM; s++) { + const NMMetaPropertyInfo *const*property_infos; + guint p; + + property_infos = nm_property_infos_for_setting_type (s); + for (p = 0; property_infos[p]; p++) { + const NMMetaPropertyInfo *property_info = property_infos[p]; + + if (_meta_property_needs_bond_hack (property_info)) { + guint i; + + for (i = 0; i < nm_meta_property_typ_data_bond.nested_len; i++) { + const NMMetaNestedPropertyTypeInfo *bi = &nm_meta_property_typ_data_bond.nested[i]; + + if ( bi->prompt + && g_str_has_prefix (rl_prompt, bi->prompt)) { + goto next; + } + } + } else { + if ( property_info->prompt + && g_str_has_prefix (rl_prompt, property_info->prompt)) { + char **values; + + values = _meta_abstract_complete ((const NMMetaAbstractInfo *) property_info, text); + if (values) + return values; + goto next; + } + } + } + } + +next: if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) generator_func = gen_connection_types; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IFNAME)) From 7ef23e5c0a01f8a1e8a95a0e926cb3b5777dee6c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 17:25:31 +0200 Subject: [PATCH 23/32] cli: move prompting for enum values to meta data --- clients/cli/connections.c | 64 ++------------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 64290ef833..3a26b7b6dd 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3934,50 +3934,6 @@ gen_func_tun_mode (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_func_ip_tunnel_mode (const char *text, int state) -{ - gs_free const char **words = NULL; - - words = nm_utils_enum_get_values (nm_ip_tunnel_mode_get_type (), - NM_IP_TUNNEL_MODE_UNKNOWN + 1, - G_MAXINT); - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_macsec_mode (const char *text, int state) -{ - gs_free const char **words = NULL; - - words = nm_utils_enum_get_values (nm_setting_macsec_mode_get_type (), - G_MININT, - G_MAXINT); - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_macvlan_mode (const char *text, int state) -{ - gs_free const char **words = NULL; - - words = nm_utils_enum_get_values (nm_setting_macvlan_mode_get_type(), - NM_SETTING_MACVLAN_MODE_UNKNOWN + 1, - G_MAXINT); - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_proxy_method (const char *text, int state) -{ - gs_free const char **words = NULL; - - words = nm_utils_enum_get_values (nm_setting_proxy_method_get_type (), - G_MININT, - G_MAXINT); - return nmc_rl_gen_func_basic (text, state, words); -} - static char * gen_func_master_ifnames (const char *text, int state) { @@ -4313,16 +4269,12 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (VPN, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NULL, gen_func_vpn_types), OPTION_INFO (ADSL, NM_SETTING_ADSL_PROTOCOL, "protocol", NULL, gen_func_adsl_proto), OPTION_INFO (ADSL, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NULL, gen_func_adsl_encap), - OPTION_INFO (MACSEC, NM_SETTING_MACSEC_MODE, "mode", NULL, gen_func_macsec_mode), OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), - OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_MODE, "mode", NULL, gen_func_macvlan_mode), OPTION_INFO (VXLAN, NM_SETTING_VXLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (TUN, NM_SETTING_TUN_MODE, "mode", NULL, gen_func_tun_mode), - OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_MODE, "mode", NULL, gen_func_ip_tunnel_mode), OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (IP4_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", set_ip4_address, NULL), OPTION_INFO (IP6_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", set_ip6_address, NULL), - OPTION_INFO (PROXY, NM_SETTING_PROXY_METHOD, "method", NULL, gen_func_proxy_method), { 0 }, }; const char *property_name, *option; @@ -4501,14 +4453,10 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar && strcmp (property, NM_SETTING_TUN_MODE) == 0) run_rl_generator (gen_func_tun_mode, prefix); else if (strcmp (setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_IP_TUNNEL_MODE) == 0) - run_rl_generator (gen_func_ip_tunnel_mode, prefix); - else if (strcmp (property, NM_SETTING_IP_TUNNEL_PARENT) == 0) + if (strcmp (property, NM_SETTING_IP_TUNNEL_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); } else if (strcmp (setting_name, NM_SETTING_MACVLAN_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_MACVLAN_MODE) == 0) - run_rl_generator (gen_func_macvlan_mode, prefix); - else if (strcmp (property, NM_SETTING_MACVLAN_PARENT) == 0) + if (strcmp (property, NM_SETTING_MACVLAN_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); } else if ( strcmp (setting_name, NM_SETTING_VXLAN_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_VXLAN_PARENT) == 0) @@ -4838,14 +4786,6 @@ next: generator_func = gen_func_adsl_encap; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_TUN_MODE)) generator_func = gen_func_tun_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IP_TUNNEL_MODE)) - generator_func = gen_func_ip_tunnel_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MACVLAN_MODE)) - generator_func = gen_func_macvlan_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MACSEC_MODE)) - generator_func = gen_func_macsec_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_PROXY_METHOD)) - generator_func = gen_func_proxy_method; else if ( g_str_has_suffix (rl_prompt, yes) || g_str_has_suffix (rl_prompt, no)) generator_func = gen_func_bool_values_l10n; From 0fa5fc3f51051b4e2f9fab7e6a7161b2af3fde17 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 17:25:31 +0200 Subject: [PATCH 24/32] cli: move completing VPN service types to meta data --- clients/cli/connections.c | 43 ++++----------------------- clients/common/nm-meta-setting-desc.c | 31 ++++++++++++++++++- clients/common/nm-meta-setting-desc.h | 6 ++++ 3 files changed, 41 insertions(+), 39 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 3a26b7b6dd..8affeb9bfd 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3856,15 +3856,6 @@ ensure_settings (NMConnection *connection, const NameItem *item) /*----------------------------------------------------------------------------*/ -static char * -gen_func_vpn_types (const char *text, int state) -{ - gs_strfreev char **plugin_names = NULL; - - plugin_names = nm_vpn_plugin_info_list_get_service_types (nm_vpn_get_plugin_infos (), FALSE, TRUE); - return nmc_rl_gen_func_basic (text, state, (const char **) plugin_names); -} - static char * gen_func_bool_values_l10n (const char *text, int state) { @@ -4266,7 +4257,6 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-interval", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-ip-target", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "lacp-rate", set_bond_option, gen_func_bond_lacp_rate), - OPTION_INFO (VPN, NM_SETTING_VPN_SERVICE_TYPE, "vpn-type", NULL, gen_func_vpn_types), OPTION_INFO (ADSL, NM_SETTING_ADSL_PROTOCOL, "protocol", NULL, gen_func_adsl_proto), OPTION_INFO (ADSL, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NULL, gen_func_adsl_encap), OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), @@ -4432,10 +4422,7 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar run_rl_generator (gen_func_master_ifnames, prefix); else if (strcmp (property, NM_SETTING_CONNECTION_INTERFACE_NAME) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - } else if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_VPN_SERVICE_TYPE) == 0) - run_rl_generator (gen_func_vpn_types, prefix); - else if ( strcmp (setting_name, NM_SETTING_WIRELESS_SETTING_NAME) == 0 + } else if ( strcmp (setting_name, NM_SETTING_WIRELESS_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_WIRELESS_MODE) == 0) run_rl_generator (gen_func_wifi_mode, prefix); else if ( strcmp (setting_name, NM_SETTING_INFINIBAND_SETTING_NAME) == 0 @@ -4766,8 +4753,6 @@ next: generator_func = gen_connection_types; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IFNAME)) generator_func = nmc_rl_gen_func_ifnames; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_VPN_TYPE)) - generator_func = gen_func_vpn_types; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER)) generator_func = gen_func_master_ifnames; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_WIFI_MODE)) @@ -8624,26 +8609,8 @@ do_connection_load (NmCli *nmc, int argc, char **argv) return nmc->return_value; } -// FIXME: change the text when non-VPN connection types are supported -#define PROMPT_IMPORT_TYPE NM_META_TEXT_PROMPT_VPN_TYPE #define PROMPT_IMPORT_FILE N_("File to import: ") -static void -nmc_complete_vpn_service (const char *prefix) -{ - char **services; - char **candidate; - - services = nm_vpn_plugin_info_list_get_service_types (NULL, FALSE, TRUE); - for (candidate = services; *candidate; candidate++) { - if (!*prefix && g_str_has_prefix (*candidate, NM_DBUS_INTERFACE)) - continue; - if (!*prefix || matches (prefix, *candidate)) - g_print ("%s\n", *candidate); - } - g_strfreev (services); -} - static NMCResultCode do_connection_import (NmCli *nmc, int argc, char **argv) { @@ -8668,7 +8635,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) g_assert (!nmc->complete); if (nmc->ask) { - type_ask = nmc_readline (gettext (PROMPT_IMPORT_TYPE)); + type_ask = nmc_readline (gettext (NM_META_TEXT_PROMPT_VPN_TYPE)); filename_ask = nmc_readline (gettext (PROMPT_IMPORT_FILE)); type = type_ask = type_ask ? g_strstrip (type_ask) : NULL; filename = filename_ask = filename_ask ? g_strstrip (filename_ask) : NULL; @@ -8693,7 +8660,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) } if (argc == 1 && nmc->complete) - nmc_complete_vpn_service (*argv); + complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv); if (!type) type = *argv; @@ -8968,8 +8935,8 @@ nmcli_con_tab_completion (const char *text, int start, int end) generator_func = gen_func_connection_names; } else if (g_strcmp0 (rl_prompt, PROMPT_ACTIVE_CONNECTIONS) == 0) { generator_func = gen_func_active_connection_names; - } else if (g_strcmp0 (rl_prompt, PROMPT_IMPORT_TYPE) == 0) { - generator_func = gen_func_vpn_types; + } else if (g_strcmp0 (rl_prompt, NM_META_TEXT_PROMPT_VPN_TYPE) == 0) { + return _meta_abstract_complete ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, text); } else if (g_strcmp0 (rl_prompt, PROMPT_IMPORT_FILE) == 0) { rl_attempted_completion_over = 0; rl_complete_with_tilde_expansion = 1; diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 327fb61ad5..8a35b6dbfb 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -1619,6 +1619,34 @@ _set_fcn_vpn_service_type (ARGS_SET_FCN) return TRUE; } +static const char *const* +_complete_fcn_vpn_service_type (ARGS_COMPLETE_FCN) +{ + gsize i, j; + char **values; + + values = nm_vpn_plugin_info_list_get_service_types (nm_vpn_get_plugin_infos (), FALSE, TRUE); + if (!values) + return NULL; + + if (!text || !*text) { + /* If the prompt text is empty or contains no '.', + * filter out full names. */ + for (i = 0, j = 0; values[i]; i++) { + if (strchr (values[i], '.')) { + g_free (values[i]); + continue; + } + + if (i != j) + values[j] = values[i]; + j++; + } + values[j++] = NULL; + } + return (const char *const*) (*out_to_free = values); +} + static gboolean nmc_util_is_domain (const char *domain) { @@ -6538,7 +6566,7 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VPN static const NMMetaPropertyInfo property_infos_VPN[] = { - { + [_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SERVICE_TYPE), .is_cli_option = TRUE, .property_alias = "vpn-type", @@ -6547,6 +6575,7 @@ static const NMMetaPropertyInfo property_infos_VPN[] = { .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_vpn_service_type, + .complete_fcn = _complete_fcn_vpn_service_type, ), }, { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 0339a59d81..b61adeaf70 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -237,6 +237,12 @@ typedef enum { NM_META_PROPERTY_INF_FLAG_MULTI = 0x04, /* Ask multiple times, do an append instead of set. */ } NMMetaPropertyInfFlags; +enum { + _NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE = 0, +}; + +#define nm_meta_property_info_vpn_service_type (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VPN].properties[_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE]) + struct _NMMetaPropertyInfo { const NMMetaType *meta_type; From 88f100e176fe3036fc821ee4d8cfc5a5ccd61037 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 17:25:31 +0200 Subject: [PATCH 25/32] cli: move completing static-value types to meta data --- clients/cli/connections.c | 66 +-------------------------------------- 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 8affeb9bfd..dbe3736fa9 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3863,20 +3863,6 @@ gen_func_bool_values_l10n (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_func_wifi_mode (const char *text, int state) -{ - const char *words[] = { "infrastructure", "ap", "adhoc", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_ib_type (const char *text, int state) -{ - const char *words[] = { "datagram", "connected", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - static char * gen_func_bt_type (const char *text, int state) { @@ -3904,27 +3890,6 @@ gen_func_bond_lacp_rate (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_func_adsl_proto (const char *text, int state) -{ - const char *words[] = { "pppoe", "pppoa", "ipoatm", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_adsl_encap (const char *text, int state) -{ - const char *words[] = { "vcmux", "llc", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_tun_mode (const char *text, int state) -{ - const char *words[] = { "tun", "tap", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - static char * gen_func_master_ifnames (const char *text, int state) { @@ -4244,8 +4209,6 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, nmc_rl_gen_func_ifnames), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), - OPTION_INFO (INFINIBAND, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "transport-mode", NULL, gen_func_ib_type), - OPTION_INFO (WIRELESS, NM_SETTING_WIRELESS_MODE, "mode", NULL, gen_func_wifi_mode), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), OPTION_INFO (VLAN, NM_SETTING_VLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "mode", set_bond_option, gen_func_bond_mode), @@ -4257,11 +4220,8 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-interval", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-ip-target", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "lacp-rate", set_bond_option, gen_func_bond_lacp_rate), - OPTION_INFO (ADSL, NM_SETTING_ADSL_PROTOCOL, "protocol", NULL, gen_func_adsl_proto), - OPTION_INFO (ADSL, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", NULL, gen_func_adsl_encap), OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (VXLAN, NM_SETTING_VXLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), - OPTION_INFO (TUN, NM_SETTING_TUN_MODE, "mode", NULL, gen_func_tun_mode), OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (IP4_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", set_ip4_address, NULL), OPTION_INFO (IP6_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", set_ip6_address, NULL), @@ -4422,23 +4382,9 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar run_rl_generator (gen_func_master_ifnames, prefix); else if (strcmp (property, NM_SETTING_CONNECTION_INTERFACE_NAME) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - } else if ( strcmp (setting_name, NM_SETTING_WIRELESS_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_WIRELESS_MODE) == 0) - run_rl_generator (gen_func_wifi_mode, prefix); - else if ( strcmp (setting_name, NM_SETTING_INFINIBAND_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_INFINIBAND_TRANSPORT_MODE) == 0) - run_rl_generator (gen_func_ib_type, prefix); - else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 + } else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) run_rl_generator (gen_func_bt_type, prefix); - else if (strcmp (setting_name, NM_SETTING_ADSL_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_ADSL_PROTOCOL) == 0) - run_rl_generator (gen_func_adsl_proto, prefix); - else if (strcmp (property, NM_SETTING_ADSL_ENCAPSULATION) == 0) - run_rl_generator (gen_func_adsl_encap, prefix); - } else if ( strcmp (setting_name, NM_SETTING_TUN_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_TUN_MODE) == 0) - run_rl_generator (gen_func_tun_mode, prefix); else if (strcmp (setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME) == 0) { if (strcmp (property, NM_SETTING_IP_TUNNEL_PARENT) == 0) run_rl_generator (nmc_rl_gen_func_ifnames, prefix); @@ -4755,22 +4701,12 @@ next: generator_func = nmc_rl_gen_func_ifnames; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER)) generator_func = gen_func_master_ifnames; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_WIFI_MODE)) - generator_func = gen_func_wifi_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IB_MODE)) - generator_func = gen_func_ib_type; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) generator_func = gen_func_bt_type; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE)) generator_func = gen_func_bond_mode; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MON_MODE)) generator_func = gen_func_bond_mon_mode; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_ADSL_PROTO)) - generator_func = gen_func_adsl_proto; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_ADSL_ENCAP)) - generator_func = gen_func_adsl_encap; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_TUN_MODE)) - generator_func = gen_func_tun_mode; else if ( g_str_has_suffix (rl_prompt, yes) || g_str_has_suffix (rl_prompt, no)) generator_func = gen_func_bool_values_l10n; From 6c2727af14f394000a35c5ee8ca23649683ba9ab Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 21:40:19 +0200 Subject: [PATCH 26/32] cli: add meta data for NMSettingGeneric --- clients/common/nm-meta-setting-desc.c | 2 ++ shared/nm-meta-setting.c | 5 +++++ shared/nm-meta-setting.h | 1 + 3 files changed, 8 insertions(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 8a35b6dbfb..e2f309ee95 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -7087,6 +7087,7 @@ static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { #define SETTING_PRETTY_NAME_CONNECTION "General settings" #define SETTING_PRETTY_NAME_DCB "DCB settings" #define SETTING_PRETTY_NAME_DUMMY "Dummy settings" +#define SETTING_PRETTY_NAME_GENERIC "Generic settings" #define SETTING_PRETTY_NAME_GSM "GSM mobile broadband connection" #define SETTING_PRETTY_NAME_INFINIBAND "InfiniBand connection" #define SETTING_PRETTY_NAME_IP4_CONFIG "IPv4 protocol" @@ -7136,6 +7137,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { SETTING_INFO (CONNECTION), SETTING_INFO (DCB), SETTING_INFO_EMPTY (DUMMY), + SETTING_INFO_EMPTY (GENERIC), SETTING_INFO (GSM), SETTING_INFO (INFINIBAND), SETTING_INFO (IP4_CONFIG), diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c index 58bd3f1004..1294a24d98 100644 --- a/shared/nm-meta-setting.c +++ b/shared/nm-meta-setting.c @@ -190,6 +190,11 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = N_ (NM_SETTING_DUMMY_SETTING_NAME), .get_setting_gtype = nm_setting_dummy_get_type, }, + [NM_META_SETTING_TYPE_GENERIC] = { + .meta_type = NM_META_SETTING_TYPE_GENERIC, + .setting_name = N_ (NM_SETTING_GENERIC_SETTING_NAME), + .get_setting_gtype = nm_setting_generic_get_type, + }, [NM_META_SETTING_TYPE_GSM] = { .meta_type = NM_META_SETTING_TYPE_GSM, .setting_name = N_ (NM_SETTING_GSM_SETTING_NAME), diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h index 3d78a85045..949a6920c6 100644 --- a/shared/nm-meta-setting.h +++ b/shared/nm-meta-setting.h @@ -66,6 +66,7 @@ typedef enum { NM_META_SETTING_TYPE_CONNECTION, NM_META_SETTING_TYPE_DCB, NM_META_SETTING_TYPE_DUMMY, + NM_META_SETTING_TYPE_GENERIC, NM_META_SETTING_TYPE_GSM, NM_META_SETTING_TYPE_INFINIBAND, NM_META_SETTING_TYPE_IP4_CONFIG, From 3ed0fc1b4542b3bc107ff9746275079ac299fa40 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 10 Apr 2017 23:01:22 +0200 Subject: [PATCH 27/32] cli: move setting alias to meta data --- clients/cli/connections.c | 321 ++++++++++++++------------ clients/common/nm-meta-setting-desc.c | 19 +- clients/common/nm-meta-setting-desc.h | 1 + 3 files changed, 190 insertions(+), 151 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index dbe3736fa9..6f70b7113e 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -2775,217 +2775,233 @@ finish: typedef struct NameItem { const char *name; - const char *alias; const struct NameItem *settings; gboolean mandatory; } NameItem; +#define NAME_ITEM_SIMPLE(name_, mandatory_) \ + { \ + .name = NM_SETTING_##name_##_SETTING_NAME, \ + .mandatory = mandatory_, \ + } + static const NameItem nmc_generic_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + { 0 } }; static const NameItem nmc_ethernet_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_DCB_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRED, TRUE), + NAME_ITEM_SIMPLE (802_1X, FALSE), + NAME_ITEM_SIMPLE (DCB, FALSE), + { 0 } }; static const NameItem nmc_infiniband_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (INFINIBAND, TRUE), + { 0 } }; static const NameItem nmc_wifi_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", NULL, TRUE }, - { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-sec", NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRELESS, TRUE), + NAME_ITEM_SIMPLE (WIRELESS_SECURITY, FALSE), + NAME_ITEM_SIMPLE (802_1X, FALSE), + { 0 } }; static const NameItem nmc_wimax_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIMAX, TRUE), + { 0 } }; static const NameItem nmc_gsm_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (GSM, TRUE), + NAME_ITEM_SIMPLE (SERIAL, FALSE), + NAME_ITEM_SIMPLE (PPP, FALSE), + { 0 } }; static const NameItem nmc_cdma_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (CDMA, TRUE), + NAME_ITEM_SIMPLE (SERIAL, FALSE), + NAME_ITEM_SIMPLE (PPP, FALSE), + { 0 } }; static const NameItem nmc_bluetooth_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (BLUETOOTH, TRUE), + { 0 } }; static const NameItem nmc_adsl_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (ADSL, TRUE), + { 0 } }; /* PPPoE is a base connection type from historical reasons. * See libnm-core/nm-setting.c:_nm_setting_is_base_type() */ static const NameItem nmc_pppoe_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRED, TRUE), + NAME_ITEM_SIMPLE (PPPOE, TRUE), + NAME_ITEM_SIMPLE (PPP, FALSE), + NAME_ITEM_SIMPLE (802_1X, FALSE), + { 0 } }; static const NameItem nmc_olpc_mesh_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (OLPC_MESH, TRUE), + { 0 } }; static const NameItem nmc_vpn_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_VPN_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (VPN, TRUE), + { 0 } }; static const NameItem nmc_vlan_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + NAME_ITEM_SIMPLE (VLAN, TRUE), + { 0 } }; static const NameItem nmc_bond_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BOND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (BOND, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_team_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (TEAM, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_bridge_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (BRIDGE, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_bond_slave_settings [] = { - { NULL, NULL, NULL, FALSE } + { 0 } }; static const NameItem nmc_team_slave_settings [] = { - { NM_SETTING_TEAM_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (TEAM_PORT, TRUE), + { 0 } }; static const NameItem nmc_bridge_slave_settings [] = { - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (BRIDGE_PORT, TRUE), + { 0 } }; static const NameItem nmc_no_slave_settings [] = { - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_PROXY_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (IP4_CONFIG, FALSE), + NAME_ITEM_SIMPLE (IP6_CONFIG, FALSE), + NAME_ITEM_SIMPLE (PROXY, FALSE), + { 0 } }; static const NameItem nmc_tun_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_TUN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (TUN, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_ip_tunnel_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (IP_TUNNEL, TRUE), + { 0 } }; static const NameItem nmc_macsec_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_MACSEC_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + NAME_ITEM_SIMPLE (802_1X, FALSE), + NAME_ITEM_SIMPLE (MACSEC, TRUE), + { 0 } }; static const NameItem nmc_macvlan_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_MACVLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + NAME_ITEM_SIMPLE (MACVLAN, TRUE), + { 0 } }; static const NameItem nmc_vxlan_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_VXLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (VXLAN, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_dummy_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_DUMMY_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NULL, NULL, NULL, FALSE } + NAME_ITEM_SIMPLE (CONNECTION, TRUE), + NAME_ITEM_SIMPLE (DUMMY, TRUE), + NAME_ITEM_SIMPLE (WIRED, FALSE), + { 0 } }; static const NameItem nmc_valid_connection_types[] = { - { NM_SETTING_GENERIC_SETTING_NAME, NULL, nmc_generic_settings }, /* Needs to be first. */ - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", nmc_ethernet_settings }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, nmc_pppoe_settings }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", nmc_wifi_settings }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, nmc_wimax_settings }, - { NM_SETTING_GSM_SETTING_NAME, NULL, nmc_gsm_settings }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, nmc_cdma_settings }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, nmc_infiniband_settings }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, nmc_adsl_settings }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, nmc_bluetooth_settings }, - { NM_SETTING_VPN_SETTING_NAME, NULL, nmc_vpn_settings }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", nmc_olpc_mesh_settings }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, nmc_vlan_settings }, - { NM_SETTING_BOND_SETTING_NAME, NULL, nmc_bond_settings }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, nmc_team_settings }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, nmc_bridge_settings }, - { "bond-slave", NULL, nmc_bond_slave_settings }, - { "team-slave", NULL, nmc_team_slave_settings }, - { "bridge-slave", NULL, nmc_bridge_slave_settings }, - { "no-slave", NULL, nmc_no_slave_settings }, - { NM_SETTING_TUN_SETTING_NAME, NULL, nmc_tun_settings }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, nmc_ip_tunnel_settings }, - { NM_SETTING_MACSEC_SETTING_NAME, NULL, nmc_macsec_settings }, - { NM_SETTING_MACVLAN_SETTING_NAME, NULL, nmc_macvlan_settings }, - { NM_SETTING_VXLAN_SETTING_NAME, NULL, nmc_vxlan_settings }, - { NM_SETTING_DUMMY_SETTING_NAME, NULL, nmc_dummy_settings }, - { NULL, NULL, NULL } + { NM_SETTING_GENERIC_SETTING_NAME, nmc_generic_settings }, /* Needs to be first. */ + { NM_SETTING_WIRED_SETTING_NAME, nmc_ethernet_settings }, + { NM_SETTING_PPPOE_SETTING_NAME, nmc_pppoe_settings }, + { NM_SETTING_WIRELESS_SETTING_NAME, nmc_wifi_settings }, + { NM_SETTING_WIMAX_SETTING_NAME, nmc_wimax_settings }, + { NM_SETTING_GSM_SETTING_NAME, nmc_gsm_settings }, + { NM_SETTING_CDMA_SETTING_NAME, nmc_cdma_settings }, + { NM_SETTING_INFINIBAND_SETTING_NAME, nmc_infiniband_settings }, + { NM_SETTING_ADSL_SETTING_NAME, nmc_adsl_settings }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, nmc_bluetooth_settings }, + { NM_SETTING_VPN_SETTING_NAME, nmc_vpn_settings }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, nmc_olpc_mesh_settings }, + { NM_SETTING_VLAN_SETTING_NAME, nmc_vlan_settings }, + { NM_SETTING_BOND_SETTING_NAME, nmc_bond_settings }, + { NM_SETTING_TEAM_SETTING_NAME, nmc_team_settings }, + { NM_SETTING_BRIDGE_SETTING_NAME, nmc_bridge_settings }, + { "bond-slave", nmc_bond_slave_settings }, + { "team-slave", nmc_team_slave_settings }, + { "bridge-slave", nmc_bridge_slave_settings }, + { "no-slave", nmc_no_slave_settings }, + { NM_SETTING_TUN_SETTING_NAME, nmc_tun_settings }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, nmc_ip_tunnel_settings }, + { NM_SETTING_MACSEC_SETTING_NAME, nmc_macsec_settings }, + { NM_SETTING_MACVLAN_SETTING_NAME, nmc_macvlan_settings }, + { NM_SETTING_VXLAN_SETTING_NAME, nmc_vxlan_settings }, + { NM_SETTING_DUMMY_SETTING_NAME, nmc_dummy_settings }, + { 0 } }; +static const char * +_name_item_get_alias (const NameItem *item) +{ + const NMMetaSettingInfoEditor *info; + + info = nm_meta_setting_info_editor_find_by_name (item->name); + if (!info) + return NULL; + return info->alias; +} + /* * Return the most appropriate name for the connection of a type 'name' possibly with given 'slave_type' * if exists, else return the 'name'. The returned string must not be freed. @@ -3011,12 +3027,8 @@ get_name_alias (const char *name, const char *slave_type, const NameItem array[] } else return NULL; - if (iter) { - if (iter->alias) - return iter->alias; - else - return iter->name; - } + if (iter) + return _name_item_get_alias (iter) ?: iter->name; return name; } @@ -3038,10 +3050,13 @@ get_valid_options_string (const NameItem *array, const NameItem *array_slv) for (i = 0; i < 2; i++, iter = array_slv) { while (iter && iter->name) { + const char *alias; + if (str->len) g_string_append (str, ", "); - if (iter->alias) - g_string_append_printf (str, "%s (%s)", iter->name, iter->alias); + alias = _name_item_get_alias (iter); + if (alias) + g_string_append_printf (str, "%s (%s)", iter->name, alias); else g_string_append (str, iter->name); iter++; @@ -3103,8 +3118,11 @@ get_valid_properties_string (const NameItem *array, for (i = 0; i < 2; i++, iter = array_slv) { while (!full_match && iter && iter->name) { + const char *alias = _name_item_get_alias (iter); + if ( !(g_str_has_prefix (iter->name, prefix)) - && (!(iter->alias) || !g_str_has_prefix (iter->alias, prefix))) { + && ( !alias + || !g_str_has_prefix (alias, prefix))) { iter++; continue; } @@ -3115,7 +3133,7 @@ get_valid_properties_string (const NameItem *array, * prefix and no check on ambiguity should be performed. * Moreover, erase previous matches from output string */ if ( nm_streq (prefix, iter->name) - || nm_streq0 (prefix, iter->alias)) { + || nm_streq0 (prefix, alias)) { g_string_erase (str, 0, -1); full_match = TRUE; } else if (prop_name) { @@ -3135,11 +3153,11 @@ get_valid_properties_string (const NameItem *array, arg_name = setting_info->properties[j].property_name; /* If required, expand the alias too */ - if (!postfix && iter->alias) { + if (!postfix && alias) { if (modifier) g_string_append_c (str, modifier); new = g_strdup_printf ("%s.%s\n", - iter->alias, + alias, arg_name); g_string_append (str, new); g_free (new); @@ -3187,9 +3205,11 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ iter = array; for (i = 0; i < 2; i++, iter = array_slv) { while (iter && iter->name) { + const char *alias; g_ptr_array_add (tmp_arr, (gpointer) iter->name); - if (iter->alias) - g_ptr_array_add (tmp_arr, (gpointer) iter->alias); + alias = _name_item_get_alias (iter); + if (alias) + g_ptr_array_add (tmp_arr, (gpointer) alias); iter++; } } @@ -3216,7 +3236,7 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ for (i = 0; i < 2; i++, iter = array_slv) { while (iter && iter->name) { if ( nm_streq (iter->name, str) - || nm_streq0 (iter->alias, str)) { + || nm_streq0 (_name_item_get_alias (iter), str)) { return iter->name; } iter++; @@ -5191,8 +5211,10 @@ gen_connection_types (const char *text, int state) } while (nmc_valid_connection_types[list_idx].name) { - a_type = nmc_valid_connection_types[list_idx].alias; - c_type = nmc_valid_connection_types[list_idx].name; + const NameItem *item = &nmc_valid_connection_types[list_idx]; + + a_type = _name_item_get_alias (item); + c_type = item->name; list_idx++; if (a_type && !strncmp (text, a_type, len)) return g_strdup (a_type); @@ -5224,8 +5246,10 @@ gen_setting_names (const char *text, int state) if (!valid_settings_arr) return NULL; while (valid_settings_arr[list_idx].name) { - a_name = valid_settings_arr[list_idx].alias; - s_name = valid_settings_arr[list_idx].name; + const NameItem *item = &valid_settings_arr[list_idx]; + + a_name = _name_item_get_alias (item); + s_name = item->name; list_idx++; if (len == 0 && a_name) return g_strdup_printf ("%s (%s)", s_name, a_name); @@ -5249,8 +5273,10 @@ gen_setting_names (const char *text, int state) g_free (slv_type); while (valid_settings_arr[list_idx].name) { - a_name = valid_settings_arr[list_idx].alias; - s_name = valid_settings_arr[list_idx].name; + const NameItem *item = &valid_settings_arr[list_idx]; + + a_name = _name_item_get_alias (item); + s_name = item->name; list_idx++; if (len == 0 && a_name) return g_strdup_printf ("%s (%s)", s_name, a_name); @@ -7853,10 +7879,13 @@ static void nmc_complete_connection_type (const char *prefix, const NameItem *types) { while (types->name) { + const char *alias; + if (!*prefix || matches (prefix, types->name)) g_print ("%s\n", types->name); - if (types->alias && (!*prefix || matches (prefix, types->alias))) - g_print ("%s\n", types->alias); + alias = _name_item_get_alias (types); + if (alias && (!*prefix || matches (prefix, alias))) + g_print ("%s\n", alias); types++; } } diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index e2f309ee95..36fec16945 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -7119,13 +7119,14 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ .pretty_name = N_(SETTING_PRETTY_NAME_##type), \ } -#define SETTING_INFO(type) \ +#define SETTING_INFO(type, ...) \ [NM_META_SETTING_TYPE_##type] = { \ .meta_type = &nm_meta_type_setting_info_editor, \ .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ .properties = property_infos_##type, \ .properties_num = G_N_ELEMENTS (property_infos_##type), \ .pretty_name = N_(SETTING_PRETTY_NAME_##type), \ + __VA_ARGS__ \ } SETTING_INFO (802_1X), SETTING_INFO (ADSL), @@ -7145,7 +7146,9 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { SETTING_INFO (IP_TUNNEL), SETTING_INFO (MACSEC), SETTING_INFO (MACVLAN), - SETTING_INFO (OLPC_MESH), + SETTING_INFO (OLPC_MESH, + .alias = "olpc-mesh", + ), SETTING_INFO (PPPOE), SETTING_INFO (PPP), SETTING_INFO (PROXY), @@ -7158,9 +7161,15 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { SETTING_INFO (VPN), SETTING_INFO (VXLAN), SETTING_INFO (WIMAX), - SETTING_INFO (WIRED), - SETTING_INFO (WIRELESS), - SETTING_INFO (WIRELESS_SECURITY), + SETTING_INFO (WIRED, + .alias = "ethernet", + ), + SETTING_INFO (WIRELESS, + .alias = "wifi", + ), + SETTING_INFO (WIRELESS_SECURITY, + .alias = "wifi-sec", + ), }; /*****************************************************************************/ diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index b61adeaf70..491147bc5e 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -272,6 +272,7 @@ struct _NMMetaPropertyInfo { struct _NMMetaSettingInfoEditor { const NMMetaType *meta_type; const NMMetaSettingInfo *general; + const char *alias; const char *pretty_name; /* the order of the properties matter. The first *must* be the * "name", and then the order is as they are listed by default. */ From d32817999c2bc8da33e99b48671b068ad870a4e0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 11 Apr 2017 11:31:27 +0200 Subject: [PATCH 28/32] cli: move information about valid connection settings to common --- clients/cli/connections.c | 692 +++++++++--------------- clients/common/nm-meta-setting-access.c | 35 +- clients/common/nm-meta-setting-access.h | 2 +- clients/common/nm-meta-setting-desc.c | 229 +++++++- clients/common/nm-meta-setting-desc.h | 21 + clients/common/tests/test-general.c | 25 +- 6 files changed, 524 insertions(+), 480 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 6f70b7113e..373596304e 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -2773,262 +2773,26 @@ finish: /*----------------------------------------------------------------------------*/ -typedef struct NameItem { - const char *name; - const struct NameItem *settings; - gboolean mandatory; -} NameItem; - -#define NAME_ITEM_SIMPLE(name_, mandatory_) \ - { \ - .name = NM_SETTING_##name_##_SETTING_NAME, \ - .mandatory = mandatory_, \ - } - -static const NameItem nmc_generic_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - { 0 } -}; - -static const NameItem nmc_ethernet_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRED, TRUE), - NAME_ITEM_SIMPLE (802_1X, FALSE), - NAME_ITEM_SIMPLE (DCB, FALSE), - { 0 } -}; - -static const NameItem nmc_infiniband_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (INFINIBAND, TRUE), - { 0 } -}; - -static const NameItem nmc_wifi_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRELESS, TRUE), - NAME_ITEM_SIMPLE (WIRELESS_SECURITY, FALSE), - NAME_ITEM_SIMPLE (802_1X, FALSE), - { 0 } -}; - -static const NameItem nmc_wimax_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIMAX, TRUE), - { 0 } -}; - -static const NameItem nmc_gsm_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (GSM, TRUE), - NAME_ITEM_SIMPLE (SERIAL, FALSE), - NAME_ITEM_SIMPLE (PPP, FALSE), - { 0 } -}; - -static const NameItem nmc_cdma_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (CDMA, TRUE), - NAME_ITEM_SIMPLE (SERIAL, FALSE), - NAME_ITEM_SIMPLE (PPP, FALSE), - { 0 } -}; - -static const NameItem nmc_bluetooth_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (BLUETOOTH, TRUE), - { 0 } -}; - -static const NameItem nmc_adsl_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (ADSL, TRUE), - { 0 } -}; - -/* PPPoE is a base connection type from historical reasons. - * See libnm-core/nm-setting.c:_nm_setting_is_base_type() - */ -static const NameItem nmc_pppoe_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRED, TRUE), - NAME_ITEM_SIMPLE (PPPOE, TRUE), - NAME_ITEM_SIMPLE (PPP, FALSE), - NAME_ITEM_SIMPLE (802_1X, FALSE), - { 0 } -}; - -static const NameItem nmc_olpc_mesh_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (OLPC_MESH, TRUE), - { 0 } -}; - -static const NameItem nmc_vpn_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (VPN, TRUE), - { 0 } -}; - -static const NameItem nmc_vlan_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - NAME_ITEM_SIMPLE (VLAN, TRUE), - { 0 } -}; - -static const NameItem nmc_bond_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (BOND, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_team_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (TEAM, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_bridge_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (BRIDGE, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_bond_slave_settings [] = { - { 0 } -}; - -static const NameItem nmc_team_slave_settings [] = { - NAME_ITEM_SIMPLE (TEAM_PORT, TRUE), - { 0 } -}; - -static const NameItem nmc_bridge_slave_settings [] = { - NAME_ITEM_SIMPLE (BRIDGE_PORT, TRUE), - { 0 } -}; - -static const NameItem nmc_no_slave_settings [] = { - NAME_ITEM_SIMPLE (IP4_CONFIG, FALSE), - NAME_ITEM_SIMPLE (IP6_CONFIG, FALSE), - NAME_ITEM_SIMPLE (PROXY, FALSE), - { 0 } -}; - -static const NameItem nmc_tun_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (TUN, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_ip_tunnel_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (IP_TUNNEL, TRUE), - { 0 } -}; - -static const NameItem nmc_macsec_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - NAME_ITEM_SIMPLE (802_1X, FALSE), - NAME_ITEM_SIMPLE (MACSEC, TRUE), - { 0 } -}; - -static const NameItem nmc_macvlan_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - NAME_ITEM_SIMPLE (MACVLAN, TRUE), - { 0 } -}; - -static const NameItem nmc_vxlan_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (VXLAN, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_dummy_settings [] = { - NAME_ITEM_SIMPLE (CONNECTION, TRUE), - NAME_ITEM_SIMPLE (DUMMY, TRUE), - NAME_ITEM_SIMPLE (WIRED, FALSE), - { 0 } -}; - -static const NameItem nmc_valid_connection_types[] = { - { NM_SETTING_GENERIC_SETTING_NAME, nmc_generic_settings }, /* Needs to be first. */ - { NM_SETTING_WIRED_SETTING_NAME, nmc_ethernet_settings }, - { NM_SETTING_PPPOE_SETTING_NAME, nmc_pppoe_settings }, - { NM_SETTING_WIRELESS_SETTING_NAME, nmc_wifi_settings }, - { NM_SETTING_WIMAX_SETTING_NAME, nmc_wimax_settings }, - { NM_SETTING_GSM_SETTING_NAME, nmc_gsm_settings }, - { NM_SETTING_CDMA_SETTING_NAME, nmc_cdma_settings }, - { NM_SETTING_INFINIBAND_SETTING_NAME, nmc_infiniband_settings }, - { NM_SETTING_ADSL_SETTING_NAME, nmc_adsl_settings }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, nmc_bluetooth_settings }, - { NM_SETTING_VPN_SETTING_NAME, nmc_vpn_settings }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, nmc_olpc_mesh_settings }, - { NM_SETTING_VLAN_SETTING_NAME, nmc_vlan_settings }, - { NM_SETTING_BOND_SETTING_NAME, nmc_bond_settings }, - { NM_SETTING_TEAM_SETTING_NAME, nmc_team_settings }, - { NM_SETTING_BRIDGE_SETTING_NAME, nmc_bridge_settings }, - { "bond-slave", nmc_bond_slave_settings }, - { "team-slave", nmc_team_slave_settings }, - { "bridge-slave", nmc_bridge_slave_settings }, - { "no-slave", nmc_no_slave_settings }, - { NM_SETTING_TUN_SETTING_NAME, nmc_tun_settings }, - { NM_SETTING_IP_TUNNEL_SETTING_NAME, nmc_ip_tunnel_settings }, - { NM_SETTING_MACSEC_SETTING_NAME, nmc_macsec_settings }, - { NM_SETTING_MACVLAN_SETTING_NAME, nmc_macvlan_settings }, - { NM_SETTING_VXLAN_SETTING_NAME, nmc_vxlan_settings }, - { NM_SETTING_DUMMY_SETTING_NAME, nmc_dummy_settings }, - { 0 } -}; - -static const char * -_name_item_get_alias (const NameItem *item) -{ - const NMMetaSettingInfoEditor *info; - - info = nm_meta_setting_info_editor_find_by_name (item->name); - if (!info) - return NULL; - return info->alias; -} - /* * Return the most appropriate name for the connection of a type 'name' possibly with given 'slave_type' * if exists, else return the 'name'. The returned string must not be freed. */ static const char * -get_name_alias (const char *name, const char *slave_type, const NameItem array[]) +get_name_alias_toplevel (const char *name, const char *slave_type) { - const NameItem *iter = &array[0]; + const NMMetaSettingInfoEditor *setting_info; if (slave_type) { - while (iter && iter->name) { - if ( g_str_has_prefix (iter->name, slave_type) - && g_str_has_suffix (iter->name, "-slave")) - break; - iter++; - } - } else if (name) { - while (iter && iter->name) { - if (!strcmp (name, iter->name)) - break; - iter++; - } - } else - return NULL; + const char *slave_name; - if (iter) - return _name_item_get_alias (iter) ?: iter->name; + if (nm_meta_setting_info_valid_parts_for_slave_type (slave_type, &slave_name)) + return slave_name ?: name; + return name; + } + + setting_info = nm_meta_setting_info_editor_find_by_name (name, FALSE); + if (setting_info) + return setting_info->alias ?: setting_info->general->setting_name; return name; } @@ -3040,47 +2804,62 @@ get_name_alias (const char *name, const char *slave_type, const NameItem array[] * Returns: string; the caller is responsible for freeing it. */ static char * -get_valid_options_string (const NameItem *array, const NameItem *array_slv) +Get_valid_options_string (const NMMetaSettingValidPartItem *const*array, const NMMetaSettingValidPartItem *const*array_slv) { - const NameItem *iter = array; + const NMMetaSettingValidPartItem *const*iter = array; GString *str; int i; str = g_string_sized_new (150); for (i = 0; i < 2; i++, iter = array_slv) { - while (iter && iter->name) { - const char *alias; + for (; iter && *iter; iter++) { + const NMMetaSettingInfoEditor *setting_info = (*iter)->setting_info; if (str->len) g_string_append (str, ", "); - alias = _name_item_get_alias (iter); - if (alias) - g_string_append_printf (str, "%s (%s)", iter->name, alias); + if (setting_info->alias) + g_string_append_printf (str, "%s (%s)", setting_info->general->setting_name, setting_info->alias); else - g_string_append (str, iter->name); - iter++; + g_string_append (str, setting_info->general->setting_name); } } return g_string_free (str, FALSE); } -static const NameItem * +static char * +get_valid_options_string_toplevel (void) +{ + GString *str; + int i; + + str = g_string_sized_new (150); + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[i]; + + if (str->len) + g_string_append (str, ", "); + if (setting_info->alias) + g_string_append_printf (str, "%s (%s)", setting_info->general->setting_name, setting_info->alias); + else + g_string_append (str, setting_info->general->setting_name); + } + return g_string_free (str, FALSE); +} + +static const NMMetaSettingValidPartItem *const* get_valid_settings_array (const char *con_type) { - guint i, num; + const NMMetaSettingInfoEditor *setting_info; /* No connection type yet? Return settings for a generic connection * (just the "connection" setting), which always makes sense. */ if (!con_type) - return nmc_valid_connection_types[0].settings; - - num = G_N_ELEMENTS (nmc_valid_connection_types); - for (i = 0; i < num; i++) { - if (nm_streq0 (con_type, nmc_valid_connection_types[i].name)) - return nmc_valid_connection_types[i].settings; - } + return nm_meta_setting_info_valid_parts_default; + setting_info = nm_meta_setting_info_editor_find_by_name (con_type, FALSE); + if (setting_info) + return setting_info->valid_parts ?: NM_PTRARRAY_EMPTY (const NMMetaSettingValidPartItem *); return NULL; } @@ -3099,14 +2878,13 @@ get_valid_settings_array (const char *con_type) * Returns: list of property.arg elements */ static char * -get_valid_properties_string (const NameItem *array, - const NameItem *array_slv, +get_valid_properties_string (const NMMetaSettingValidPartItem *const*array, + const NMMetaSettingValidPartItem *const*array_slv, char modifier, const char *prefix, const char *postfix) { - const NameItem *iter = array; - const NMMetaSettingInfoEditor *setting_info; + const NMMetaSettingValidPartItem *const*iter = array; const char *prop_name = NULL; GString *str; int i, j; @@ -3117,35 +2895,32 @@ get_valid_properties_string (const NameItem *array, str = g_string_sized_new (1024); for (i = 0; i < 2; i++, iter = array_slv) { - while (!full_match && iter && iter->name) { - const char *alias = _name_item_get_alias (iter); + for(; !full_match && iter && *iter; iter++) { + const NMMetaSettingInfoEditor *setting_info = (*iter)->setting_info; - if ( !(g_str_has_prefix (iter->name, prefix)) - && ( !alias - || !g_str_has_prefix (alias, prefix))) { - iter++; + if ( !(g_str_has_prefix (setting_info->general->setting_name, prefix)) + && ( !setting_info->alias + || !g_str_has_prefix (setting_info->alias, prefix))) { continue; } + /* If postix (so prefix is terminated by a dot), check * that prefix is not ambiguous */ if (postfix) { /* If we have a perfect match, no need to look for others * prefix and no check on ambiguity should be performed. * Moreover, erase previous matches from output string */ - if ( nm_streq (prefix, iter->name) - || nm_streq0 (prefix, alias)) { + if ( nm_streq (prefix, setting_info->general->setting_name) + || nm_streq0 (prefix, setting_info->alias)) { g_string_erase (str, 0, -1); full_match = TRUE; - } else if (prop_name) { + } else if (prop_name) return g_string_free (str, TRUE); - } prop_name = prefix; - } else { - prop_name = iter->name; - } + } else + prop_name = setting_info->general->setting_name; /* Search the array with the arguments of the current property */ - setting_info = nm_meta_setting_info_editor_find_by_name (iter->name); for (j = 0; j < setting_info->properties_num; j++) { gchar *new; const char *arg_name; @@ -3153,11 +2928,11 @@ get_valid_properties_string (const NameItem *array, arg_name = setting_info->properties[j].property_name; /* If required, expand the alias too */ - if (!postfix && alias) { + if (!postfix && setting_info->alias) { if (modifier) g_string_append_c (str, modifier); new = g_strdup_printf ("%s.%s\n", - alias, + setting_info->alias, arg_name); g_string_append (str, new); g_free (new); @@ -3174,7 +2949,6 @@ get_valid_properties_string (const NameItem *array, g_string_append (str, new); g_free (new); } - iter++; } } return g_string_free (str, FALSE); @@ -3190,9 +2964,9 @@ get_valid_properties_string (const NameItem *array, * The returned string must not be freed. */ static const char * -check_valid_name (const char *val, const NameItem *array, const NameItem *array_slv, GError **error) +check_valid_name (const char *val, const NMMetaSettingValidPartItem *const*array, const NMMetaSettingValidPartItem *const*array_slv, GError **error) { - const NameItem *iter; + const NMMetaSettingValidPartItem *const*iter; gs_unref_ptrarray GPtrArray *tmp_arr = NULL; const char *str; GError *tmp_err = NULL; @@ -3204,13 +2978,12 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ tmp_arr = g_ptr_array_sized_new (32); iter = array; for (i = 0; i < 2; i++, iter = array_slv) { - while (iter && iter->name) { - const char *alias; - g_ptr_array_add (tmp_arr, (gpointer) iter->name); - alias = _name_item_get_alias (iter); - if (alias) - g_ptr_array_add (tmp_arr, (gpointer) alias); - iter++; + for (; iter && *iter; iter++) { + const NMMetaSettingInfoEditor *setting_info = (*iter)->setting_info; + + g_ptr_array_add (tmp_arr, (gpointer) setting_info->general->setting_name); + if (setting_info->alias) + g_ptr_array_add (tmp_arr, (gpointer) setting_info->alias); } } g_ptr_array_add (tmp_arr, (gpointer) NULL); @@ -3222,10 +2995,10 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ g_propagate_error (error, tmp_err); else { /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string (array, array_slv); + gs_free char *err_str = NULL; + err_str = Get_valid_options_string (array, array_slv); g_set_error (error, 1, 0, _("'%s' not among [%s]"), val, err_str); - g_free (err_str); g_clear_error (&tmp_err); } return NULL; @@ -3234,12 +3007,13 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ /* Return a pointer to the found string in passed 'array' */ iter = array; for (i = 0; i < 2; i++, iter = array_slv) { - while (iter && iter->name) { - if ( nm_streq (iter->name, str) - || nm_streq0 (_name_item_get_alias (iter), str)) { - return iter->name; + for (; iter && *iter; iter++) { + const NMMetaSettingInfoEditor *setting_info = (*iter)->setting_info; + + if ( nm_streq (setting_info->general->setting_name, str) + || nm_streq0 (setting_info->alias, str)) { + return setting_info->general->setting_name; } - iter++; } } @@ -3248,38 +3022,76 @@ check_valid_name (const char *val, const NameItem *array, const NameItem *array_ return NULL; } +static const char * +check_valid_name_toplevel (const char *val, GError **error) +{ + gs_unref_ptrarray GPtrArray *tmp_arr = NULL; + const char *str; + GError *tmp_err = NULL; + int i; + const NMMetaSettingInfoEditor *setting_info; + + /* Create a temporary array that can be used in nmc_string_is_valid() */ + tmp_arr = g_ptr_array_sized_new (32); + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + setting_info = &nm_meta_setting_infos_editor[i]; + g_ptr_array_add (tmp_arr, (gpointer) setting_info->general->setting_name); + if (setting_info->alias) + g_ptr_array_add (tmp_arr, (gpointer) setting_info->alias); + } + g_ptr_array_add (tmp_arr, (gpointer) NULL); + + /* Check string validity */ + str = nmc_string_is_valid (val, (const char **) tmp_arr->pdata, &tmp_err); + if (!str) { + if (tmp_err->code == 1) + g_propagate_error (error, tmp_err); + else { + /* We want to handle aliases, so construct own error message */ + char *err_str = get_valid_options_string_toplevel (); + + g_set_error (error, 1, 0, _("'%s' not among [%s]"), val, err_str); + g_free (err_str); + g_clear_error (&tmp_err); + } + return NULL; + } + + setting_info = nm_meta_setting_info_editor_find_by_name (str, TRUE); + if (setting_info) + return setting_info->general->setting_name; + + /* We should not really come here */ + g_set_error (error, 1, 0, _("Unknown error")); + return NULL; +} + static gboolean is_setting_mandatory (NMConnection *connection, NMSetting *setting) { NMSettingConnection *s_con; const char *c_type; - const NameItem *item; + const NMMetaSettingValidPartItem *const*item; const char *name; const char *s_type; - char *slv_type; + guint i; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); c_type = nm_setting_connection_get_connection_type (s_con); + s_type = nm_setting_connection_get_slave_type (s_con); name = nm_setting_get_name (setting); - item = get_valid_settings_array (c_type); - while (item && item->name) { - if (!strcmp (name, item->name)) - return item->mandatory; - item++; - } - - /* Let's give a try to parameters related to slave type */ - s_type = nm_setting_connection_get_slave_type (s_con); - slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); - item = get_valid_settings_array (slv_type); - g_free (slv_type); - while (item && item->name) { - if (!strcmp (name, item->name)) - return item->mandatory; - item++; + for (i = 0; i < 2; i++) { + if (i == 0) + item = get_valid_settings_array (c_type); + else + item = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); + for (; item && *item; item++) { + if (!strcmp (name, (*item)->setting_info->general->setting_name)) + return (*item)->mandatory; + } } return FALSE; @@ -3411,7 +3223,7 @@ prompt_yes_no (gboolean default_yes, char *delim) } static NMSetting * -is_setting_valid (NMConnection *connection, const NameItem *valid_settings_main, const NameItem *valid_settings_slave, char *setting) +is_setting_valid (NMConnection *connection, const NMMetaSettingValidPartItem *const*valid_settings_main, const NMMetaSettingValidPartItem *const*valid_settings_slave, char *setting) { const char *setting_name; @@ -3641,7 +3453,7 @@ disable_options (const gchar *setting_name, const gchar *property) } else { const NMMetaSettingInfoEditor *setting_info; - setting_info = nm_meta_setting_info_editor_find_by_name (setting_name); + setting_info = nm_meta_setting_info_editor_find_by_name (setting_name, FALSE); if (!setting_info) g_return_if_reached (); property_infos = nm_property_infos_for_setting_type (setting_info->general->meta_type); @@ -3811,10 +3623,9 @@ set_option (NmCli *nmc, NMConnection *connection, const NMMetaAbstractInfo *abst * and slave type. */ static gboolean -con_settings (NMConnection *connection, const NameItem **type_settings, const NameItem **slv_settings, GError **error) +con_settings (NMConnection *connection, const NMMetaSettingValidPartItem *const**type_settings, const NMMetaSettingValidPartItem *const**slv_settings, GError **error) { const char *con_type; - gs_free char *slv_type = NULL; NMSettingConnection *s_con; g_return_val_if_fail (type_settings, FALSE); @@ -3824,18 +3635,11 @@ con_settings (NMConnection *connection, const NameItem **type_settings, const Na g_assert (s_con); con_type = nm_setting_connection_get_slave_type (s_con); - if (!con_type) - con_type = "no"; - slv_type = g_strdup_printf ("%s-slave", con_type); - if (slv_type) { - *slv_settings = get_valid_settings_array (slv_type); - if (!*slv_settings) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: invalid slave type; %s."), slv_type); - return FALSE; - } - } else { - *slv_settings = NULL; + *slv_settings = nm_meta_setting_info_valid_parts_for_slave_type (con_type, NULL); + if (!*slv_settings) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: invalid slave type; %s."), con_type); + return FALSE; } con_type = nm_setting_connection_get_connection_type (s_con); @@ -3856,17 +3660,16 @@ con_settings (NMConnection *connection, const NameItem **type_settings, const Na * it's possible that a type is aready set). */ static void -ensure_settings (NMConnection *connection, const NameItem *item) +ensure_settings (NMConnection *connection, const NMMetaSettingValidPartItem *const*item) { - const NameItem *setting_item; NMSetting *setting; - for (setting_item = item; setting_item->name; setting_item++) { - if (!setting_item->mandatory) + for (; item && *item; item++) { + if (!(*item)->mandatory) continue; - if (nm_connection_get_setting_by_name (connection, setting_item->name)) + if (nm_connection_get_setting_by_name (connection, (*item)->setting_info->general->setting_name)) continue; - setting = nmc_setting_new_for_name (setting_item->name); + setting = nmc_setting_new_for_name ((*item)->setting_info->general->setting_name); if (setting) { nmc_setting_custom_init (setting); nm_connection_add_setting (connection, setting); @@ -3951,11 +3754,12 @@ gen_func_master_ifnames (const char *text, int state) static gboolean set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) { - const NameItem *type_settings, *slv_settings; + const NMMetaSettingValidPartItem *const*type_settings; + const NMMetaSettingValidPartItem *const*slv_settings; GError *local = NULL; const gchar *master[] = { "master", NULL }; - value = check_valid_name (value, nmc_valid_connection_types, NULL, &local); + value = check_valid_name_toplevel (value, &local); if (!value) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("Error: bad connection type: %s."), local->message); @@ -4290,11 +4094,10 @@ complete_property_name (NmCli *nmc, NMConnection *connection, const gchar *postfix) { NMSettingConnection *s_con; - const NameItem *valid_settings_main = NULL; - const NameItem *valid_settings_slave = NULL; + const NMMetaSettingValidPartItem *const*valid_settings_main; + const NMMetaSettingValidPartItem *const*valid_settings_slave; const char *connection_type = NULL; const char *slave_type = NULL; - gs_free char *slv_type = NULL; gs_free char *word_list = NULL; NMMetaSettingType s; @@ -4302,9 +4105,8 @@ complete_property_name (NmCli *nmc, NMConnection *connection, s_con = nm_connection_get_setting_connection (connection); if (s_con) slave_type = nm_setting_connection_get_slave_type (s_con); - slv_type = g_strdup_printf ("%s-slave", slave_type ? slave_type : "no"); valid_settings_main = get_valid_settings_array (connection_type); - valid_settings_slave = get_valid_settings_array (slv_type); + valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (slave_type, NULL); word_list = get_valid_properties_string (valid_settings_main, valid_settings_slave, modifier, prefix, postfix); if (word_list) @@ -4456,7 +4258,8 @@ nmc_read_connection_properties (NmCli *nmc, do { const NMMetaAbstractInfo *chosen = NULL; gs_strfreev gchar **strv = NULL; - const NameItem *type_settings, *slv_settings; + const NMMetaSettingValidPartItem *const*type_settings; + const NMMetaSettingValidPartItem *const*slv_settings; char modifier = '\0'; if (!con_settings (connection, &type_settings, &slv_settings, error)) @@ -4999,8 +4802,8 @@ read_properties: connections = nm_client_get_connections (nmc->client); try_name = ifname - ? g_strdup_printf ("%s-%s", get_name_alias (type, slave_type, nmc_valid_connection_types), ifname) - : g_strdup (get_name_alias (type, slave_type, nmc_valid_connection_types)); + ? g_strdup_printf ("%s-%s", get_name_alias_toplevel (type, slave_type), ifname) + : g_strdup (get_name_alias_toplevel (type, slave_type)); default_name = nmc_unique_connection_name (connections, try_name); g_free (try_name); g_object_set (s_con, NM_SETTING_CONNECTION_ID, default_name, NULL); @@ -5203,23 +5006,29 @@ static char * gen_connection_types (const char *text, int state) { static int list_idx, len; - const char *c_type, *a_type; + static int had_name; if (!state) { list_idx = 0; len = strlen (text); + had_name = FALSE; } - while (nmc_valid_connection_types[list_idx].name) { - const NameItem *item = &nmc_valid_connection_types[list_idx]; + for (; list_idx < _NM_META_SETTING_TYPE_NUM; ) { + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[list_idx]; - a_type = _name_item_get_alias (item); - c_type = item->name; + if (!had_name) { + had_name = TRUE; + if (!text || strncmp (text, setting_info->general->setting_name, len) == 0) + return g_strdup (setting_info->general->setting_name); + } + + had_name = FALSE; list_idx++; - if (a_type && !strncmp (text, a_type, len)) - return g_strdup (a_type); - if (c_type && !strncmp (text, c_type, len)) - return g_strdup (c_type); + if (setting_info->alias) { + if (!text || strncmp (text, setting_info->alias, len) == 0) + return g_strdup (setting_info->alias); + } } return NULL; @@ -5230,10 +5039,9 @@ gen_setting_names (const char *text, int state) { static int list_idx, len, is_slv; const char *s_name, *a_name; - const NameItem *valid_settings_arr; + const NMMetaSettingValidPartItem *const*valid_settings_arr; NMSettingConnection *s_con; const char *s_type = NULL; - char *slv_type; if (!state) { list_idx = 0; @@ -5243,13 +5051,13 @@ gen_setting_names (const char *text, int state) if (!is_slv) { valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - if (!valid_settings_arr) + if (list_idx >= NM_PTRARRAY_LEN (valid_settings_arr)) return NULL; - while (valid_settings_arr[list_idx].name) { - const NameItem *item = &valid_settings_arr[list_idx]; + for (; valid_settings_arr[list_idx];) { + const NMMetaSettingInfoEditor *setting_info = valid_settings_arr[list_idx]->setting_info; - a_name = _name_item_get_alias (item); - s_name = item->name; + a_name = setting_info->alias; + s_name = setting_info->general->setting_name; list_idx++; if (len == 0 && a_name) return g_strdup_printf ("%s (%s)", s_name, a_name); @@ -5268,22 +5076,22 @@ gen_setting_names (const char *text, int state) s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); if (s_con) s_type = nm_setting_connection_get_slave_type (s_con); - slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); - valid_settings_arr = get_valid_settings_array (slv_type); - g_free (slv_type); + valid_settings_arr = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); - while (valid_settings_arr[list_idx].name) { - const NameItem *item = &valid_settings_arr[list_idx]; + if (list_idx < NM_PTRARRAY_LEN (valid_settings_arr)) { + while (valid_settings_arr[list_idx]) { + const NMMetaSettingInfoEditor *setting_info = valid_settings_arr[list_idx]->setting_info; - a_name = _name_item_get_alias (item); - s_name = item->name; - list_idx++; - if (len == 0 && a_name) - return g_strdup_printf ("%s (%s)", s_name, a_name); - if (a_name && !strncmp (text, a_name, len)) - return g_strdup (a_name); - if (s_name && !strncmp (text, s_name, len)) - return g_strdup (s_name); + a_name = setting_info->alias; + s_name = setting_info->general->setting_name; + list_idx++; + if (len == 0 && a_name) + return g_strdup_printf ("%s (%s)", s_name, a_name); + if (a_name && !strncmp (text, a_name, len)) + return g_strdup (a_name); + if (s_name && !strncmp (text, s_name, len)) + return g_strdup (s_name); + } } return NULL; @@ -5298,8 +5106,8 @@ gen_property_names (const char *text, int state) const char *line = rl_line_buffer; const char *setting_name; char **strv = NULL; - const NameItem *valid_settings_main; - const NameItem *valid_settings_slave; + const NMMetaSettingValidPartItem *const*valid_settings_main; + const NMMetaSettingValidPartItem *const*valid_settings_slave; const char *p1; const char *slv_type; @@ -5309,7 +5117,7 @@ gen_property_names (const char *text, int state) while (p1 > line && !g_ascii_isspace (*p1)) p1--; - strv = g_strsplit (p1+1, ".", 2); + strv = g_strsplit (p1 + 1, ".", 2); valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); @@ -5317,12 +5125,12 @@ gen_property_names (const char *text, int state) * guessing the slave type from the setting name already * typed (or autocompleted) */ if (nm_streq0 (strv[0], NM_SETTING_TEAM_PORT_SETTING_NAME)) - slv_type = "team-slave"; + slv_type = NM_SETTING_TEAM_SETTING_NAME; else if (nm_streq0 (strv[0], NM_SETTING_BRIDGE_PORT_SETTING_NAME)) - slv_type = "bridge-slave"; + slv_type = NM_SETTING_BRIDGE_SETTING_NAME; else - slv_type = "no-slave"; - valid_settings_slave = get_valid_settings_array (slv_type); + slv_type = NULL; + valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (slv_type, NULL); setting_name = check_valid_name (strv[0], valid_settings_main, @@ -5607,15 +5415,14 @@ static void get_setting_and_property (const char *prompt, const char *line, NMSetting **setting_out, char**property_out) { - const NameItem *valid_settings_main; - const NameItem *valid_settings_slave; + const NMMetaSettingValidPartItem *const*valid_settings_main; + const NMMetaSettingValidPartItem *const*valid_settings_slave; const char *setting_name; NMSetting *setting = NULL; char *property = NULL; char *sett = NULL, *prop = NULL; NMSettingConnection *s_con; const char *s_type = NULL; - char *slv_type; extract_setting_and_property (prompt, line, &sett, &prop); if (sett) { @@ -5623,11 +5430,9 @@ get_setting_and_property (const char *prompt, const char *line, s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); if (s_con) s_type = nm_setting_connection_get_slave_type (s_con); - slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); - valid_settings_slave = get_valid_settings_array (slv_type); - g_free (slv_type); + valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); setting_name = check_valid_name (sett, valid_settings_main, valid_settings_slave, NULL); @@ -6826,7 +6631,7 @@ split_editor_main_cmd_args (const char *str, char **setting, char **property, ch } static NMSetting * -create_setting_by_name (const char *name, const NameItem *valid_settings_main, const NameItem *valid_settings_slave) +create_setting_by_name (const char *name, const NMMetaSettingValidPartItem *const*valid_settings_main, const NMMetaSettingValidPartItem *const*valid_settings_slave) { const char *setting_name; NMSetting *setting = NULL; @@ -6845,8 +6650,8 @@ create_setting_by_name (const char *name, const NameItem *valid_settings_main, c static const char * ask_check_setting (const char *arg, - const NameItem *valid_settings_main, - const NameItem *valid_settings_slave, + const NMMetaSettingValidPartItem *const*valid_settings_main, + const NMMetaSettingValidPartItem *const*valid_settings_slave, const char *valid_settings_str) { char *setting_name_user; @@ -7000,11 +6805,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t gboolean cmd_loop = TRUE; char *cmd_arg = NULL; char *cmd_arg_s, *cmd_arg_p, *cmd_arg_v; - const NameItem *valid_settings_main = NULL; - const NameItem *valid_settings_slave = NULL; + const NMMetaSettingValidPartItem *const*valid_settings_main; + const NMMetaSettingValidPartItem *const*valid_settings_slave; char *valid_settings_str = NULL; const char *s_type = NULL; - char *slv_type; AddConnectionInfo *info = NULL; gboolean dirty; gboolean temp_changes; @@ -7014,13 +6818,11 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t s_con = nm_connection_get_setting_connection (connection); if (s_con) s_type = nm_setting_connection_get_slave_type (s_con); - slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); valid_settings_main = get_valid_settings_array (connection_type); - valid_settings_slave = get_valid_settings_array (slv_type); - g_free (slv_type); + valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); - valid_settings_str = get_valid_options_string (valid_settings_main, valid_settings_slave); + valid_settings_str = Get_valid_options_string (valid_settings_main, valid_settings_slave); g_print (_("You may edit the following settings: %s\n"), valid_settings_str); menu_ctx.level = 0; @@ -7172,9 +6974,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t const char *user_arg = cmd_arg_s ? cmd_arg_s : cmd_arg_p; setting_name = ask_check_setting (user_arg, - valid_settings_main, - valid_settings_slave, - valid_settings_str); + valid_settings_main, + valid_settings_slave, + valid_settings_str); if (!setting_name) break; @@ -7260,19 +7062,20 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t user_s = descr_all ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { ss = is_setting_valid (connection, - valid_settings_main, - valid_settings_slave, - user_s); + valid_settings_main, + valid_settings_slave, + user_s); if (!ss) { if (check_valid_name (user_s, valid_settings_main, valid_settings_slave, - NULL)) + NULL)) { g_print (_("Setting '%s' is not present in the connection.\n"), - user_s); - else + user_s); + } else { g_print (_("Error: invalid setting argument '%s'; valid are [%s]\n"), user_s, valid_settings_str); + } break; } } else @@ -7300,9 +7103,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; s_tmp = is_setting_valid (connection, - valid_settings_main, - valid_settings_slave, - cmd_arg_p); + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) { /* Remove setting from the connection */ connection_remove_setting (connection, s_tmp); @@ -7351,13 +7154,13 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t user_s = descr_all ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { ss = is_setting_valid (connection, - valid_settings_main, - valid_settings_slave, - user_s); + valid_settings_main, + valid_settings_slave, + user_s); if (!ss) { ss = create_setting_by_name (user_s, - valid_settings_main, - valid_settings_slave); + valid_settings_main, + valid_settings_slave); if (!ss) { g_print (_("Error: invalid setting argument '%s'; valid are [%s]\n"), user_s, valid_settings_str); @@ -7381,9 +7184,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; s_tmp = is_setting_valid (connection, - valid_settings_main, - valid_settings_slave, - cmd_arg_p); + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) print_setting_description (s_tmp); else @@ -7414,6 +7217,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t user_s = whole_setting ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { const char *s_name; + s_name = check_valid_name (user_s, valid_settings_main, valid_settings_slave, @@ -7445,9 +7249,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; s_tmp = is_setting_valid (connection, - valid_settings_main, - valid_settings_slave, - cmd_arg_p); + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) { /* Print the whole setting */ editor_show_setting (s_tmp, nmc); @@ -7876,17 +7680,18 @@ editor_init_existing_connection (NMConnection *connection) } static void -nmc_complete_connection_type (const char *prefix, const NameItem *types) +nmc_complete_connection_type (const char *prefix) { - while (types->name) { - const char *alias; + guint i; - if (!*prefix || matches (prefix, types->name)) - g_print ("%s\n", types->name); - alias = _name_item_get_alias (types); - if (alias && (!*prefix || matches (prefix, alias))) - g_print ("%s\n", alias); - types++; + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[i]; + + if (!*prefix || matches (prefix, setting_info->general->setting_name)) + g_print ("%s\n", setting_info->general->setting_name); + if ( setting_info->alias + && (!*prefix || matches (prefix, setting_info->alias))) + g_print ("%s\n", setting_info->alias); } } @@ -8003,12 +7808,12 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) /* New connection */ if (nmc->complete) { if (type && argc == 0) - nmc_complete_connection_type (type, nmc_valid_connection_types); + nmc_complete_connection_type (type); goto error; } - connection_type = check_valid_name (type, nmc_valid_connection_types, NULL, &err1); - tmp_str = get_valid_options_string (nmc_valid_connection_types, NULL); + connection_type = check_valid_name_toplevel (type, &err1); + tmp_str = get_valid_options_string_toplevel (); while (!connection_type) { if (!type) @@ -8019,7 +7824,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) type_ask = nmc_readline (EDITOR_PROMPT_CON_TYPE); type = type_ask = type_ask ? g_strstrip (type_ask) : NULL; - connection_type = check_valid_name (type_ask, nmc_valid_connection_types, NULL, &err1); + connection_type = check_valid_name_toplevel (type_ask, &err1); g_free (type_ask); } g_free (tmp_str); @@ -8032,9 +7837,10 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) uuid = nm_utils_uuid_generate (); if (con_name) default_name = g_strdup (con_name); - else + else { default_name = nmc_unique_connection_name (connections, - get_name_alias (connection_type, NULL, nmc_valid_connection_types)); + get_name_alias_toplevel (connection_type, NULL)); + } g_object_set (s_con, NM_SETTING_CONNECTION_ID, default_name, diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index e18b03632e..dc1ed024a6 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -24,26 +24,31 @@ /*****************************************************************************/ const NMMetaSettingInfoEditor * -nm_meta_setting_info_editor_find_by_name (const char *setting_name) +nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use_alias) { const NMMetaSettingInfo *meta_setting_info; const NMMetaSettingInfoEditor *setting_info; + guint i; g_return_val_if_fail (setting_name, NULL); meta_setting_info = nm_meta_setting_infos_by_name (setting_name); - - if (!meta_setting_info) - return NULL; - - g_return_val_if_fail (nm_streq0 (meta_setting_info->setting_name, setting_name), NULL); - - if (meta_setting_info->meta_type >= G_N_ELEMENTS (nm_meta_setting_infos_editor)) - return NULL; - - setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; - - g_return_val_if_fail (setting_info->general == meta_setting_info, NULL); + setting_info = NULL; + if (meta_setting_info) { + nm_assert (nm_streq0 (meta_setting_info->setting_name, setting_name)); + if (meta_setting_info->meta_type < G_N_ELEMENTS (nm_meta_setting_infos_editor)) { + setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; + nm_assert (setting_info->general == meta_setting_info); + } + } + if (!setting_info && use_alias) { + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + if (nm_streq0 (nm_meta_setting_infos_editor[i].alias, setting_name)) { + setting_info = &nm_meta_setting_infos_editor[i]; + break; + } + } + } return setting_info; } @@ -81,7 +86,7 @@ nm_meta_setting_info_editor_find_by_setting (NMSetting *setting) setting_info = nm_meta_setting_info_editor_find_by_gtype (G_OBJECT_TYPE (setting)); - nm_assert (setting_info == nm_meta_setting_info_editor_find_by_name (nm_setting_get_name (setting))); + nm_assert (setting_info == nm_meta_setting_info_editor_find_by_name (nm_setting_get_name (setting), FALSE)); nm_assert (!setting_info || G_TYPE_CHECK_INSTANCE_TYPE (setting, setting_info->general->get_setting_gtype ())); return setting_info; @@ -111,7 +116,7 @@ nm_meta_property_info_find_by_name (const char *setting_name, const char *proper const NMMetaSettingInfoEditor *setting_info; const NMMetaPropertyInfo *property_info; - setting_info = nm_meta_setting_info_editor_find_by_name (setting_name); + setting_info = nm_meta_setting_info_editor_find_by_name (setting_name, FALSE); if (!setting_info) return NULL; diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 7a816875cd..78ad93ab2e 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -25,7 +25,7 @@ /*****************************************************************************/ -const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_name (const char *setting_name); +const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use_alias); const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_gtype (GType gtype); const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_setting (NMSetting *setting); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 36fec16945..cb559eb7c1 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -7112,12 +7112,22 @@ static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { #define SETTING_PRETTY_NAME_WIRELESS "Wi-Fi connection" #define SETTING_PRETTY_NAME_WIRELESS_SECURITY "Wi-Fi security settings" +#define NM_META_SETTING_VALID_PARTS(...) \ + ((const NMMetaSettingValidPartItem *const[]) { __VA_ARGS__ NULL }) + +#define NM_META_SETTING_VALID_PART_ITEM(type, mand) \ + (&((const NMMetaSettingValidPartItem) { \ + .setting_info = &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_##type], \ + .mandatory = mand, \ + })) + const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { -#define SETTING_INFO_EMPTY(type) \ +#define SETTING_INFO_EMPTY(type, ...) \ [NM_META_SETTING_TYPE_##type] = { \ .meta_type = &nm_meta_type_setting_info_editor, \ .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \ .pretty_name = N_(SETTING_PRETTY_NAME_##type), \ + __VA_ARGS__ \ } #define SETTING_INFO(type, ...) \ [NM_META_SETTING_TYPE_##type] = { \ @@ -7129,43 +7139,174 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { __VA_ARGS__ \ } SETTING_INFO (802_1X), - SETTING_INFO (ADSL), - SETTING_INFO (BLUETOOTH), - SETTING_INFO (BOND), - SETTING_INFO (BRIDGE), + SETTING_INFO (ADSL, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (ADSL, TRUE), + ), + ), + SETTING_INFO (BLUETOOTH, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (BLUETOOTH, TRUE), + ), + ), + SETTING_INFO (BOND, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (BOND, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), + SETTING_INFO (BRIDGE, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (BRIDGE, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), SETTING_INFO (BRIDGE_PORT), - SETTING_INFO (CDMA), + SETTING_INFO (CDMA, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (CDMA, TRUE), + NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE), + NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), + ), + ), SETTING_INFO (CONNECTION), SETTING_INFO (DCB), - SETTING_INFO_EMPTY (DUMMY), - SETTING_INFO_EMPTY (GENERIC), - SETTING_INFO (GSM), - SETTING_INFO (INFINIBAND), + SETTING_INFO_EMPTY (DUMMY, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (DUMMY, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), + SETTING_INFO_EMPTY (GENERIC, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (GENERIC, TRUE), + ), + ), + SETTING_INFO (GSM, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (GSM, TRUE), + NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE), + NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), + ), + ), + SETTING_INFO (INFINIBAND, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (INFINIBAND, TRUE), + ), + ), SETTING_INFO (IP4_CONFIG), SETTING_INFO (IP6_CONFIG), - SETTING_INFO (IP_TUNNEL), - SETTING_INFO (MACSEC), - SETTING_INFO (MACVLAN), + SETTING_INFO (IP_TUNNEL, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (IP_TUNNEL, TRUE), + ), + ), + SETTING_INFO (MACSEC, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (MACSEC, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + ), + ), + SETTING_INFO (MACVLAN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (MACVLAN, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), SETTING_INFO (OLPC_MESH, .alias = "olpc-mesh", + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (OLPC_MESH, TRUE), + ), + ), + SETTING_INFO (PPPOE, + /* PPPoE is a base connection type from historical reasons. + * See libnm-core/nm-setting.c:_nm_setting_is_base_type() + */ + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (PPPOE, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE), + NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), + NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + ), ), - SETTING_INFO (PPPOE), SETTING_INFO (PPP), SETTING_INFO (PROXY), SETTING_INFO (SERIAL), - SETTING_INFO (TEAM), + SETTING_INFO (TEAM, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (TEAM, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), SETTING_INFO (TEAM_PORT), - SETTING_INFO (TUN), + SETTING_INFO (TUN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (TUN, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), SETTING_INFO_EMPTY (USER), - SETTING_INFO (VLAN), - SETTING_INFO (VPN), - SETTING_INFO (VXLAN), - SETTING_INFO (WIMAX), + SETTING_INFO (VLAN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (VLAN, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), + SETTING_INFO (VPN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (VPN, TRUE), + ), + ), + SETTING_INFO (VXLAN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (VXLAN, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + ), + ), + SETTING_INFO (WIMAX, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIMAX, TRUE), + ), + ), SETTING_INFO (WIRED, .alias = "ethernet", + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE), + NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + NM_META_SETTING_VALID_PART_ITEM (DCB, FALSE), + ), ), SETTING_INFO (WIRELESS, .alias = "wifi", + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRELESS, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRELESS_SECURITY, FALSE), + NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), + ), ), SETTING_INFO (WIRELESS_SECURITY, .alias = "wifi-sec", @@ -7174,6 +7315,54 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { /*****************************************************************************/ +const NMMetaSettingValidPartItem *const nm_meta_setting_info_valid_parts_default[] = { + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NULL +}; + +/*****************************************************************************/ + +static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = { + NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE), + NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE), + NM_META_SETTING_VALID_PART_ITEM (PROXY, FALSE), + NULL, +}; + +static const NMMetaSettingValidPartItem *const valid_settings_slave_bridge[] = { + NM_META_SETTING_VALID_PART_ITEM (BRIDGE_PORT, TRUE), + NULL, +}; + +static const NMMetaSettingValidPartItem *const valid_settings_slave_team[] = { + NM_META_SETTING_VALID_PART_ITEM (TEAM_PORT, TRUE), + NULL, +}; + +const NMMetaSettingValidPartItem *const* +nm_meta_setting_info_valid_parts_for_slave_type (const char *slave_type, const char **out_slave_name) +{ + if (!slave_type) { + NM_SET_OUT (out_slave_name, NULL); + return valid_settings_noslave; + } + if (nm_streq (slave_type, NM_SETTING_BOND_SETTING_NAME)) { + NM_SET_OUT (out_slave_name, "bond-slave"); + return NM_PTRARRAY_EMPTY (const NMMetaSettingValidPartItem *); + } + if (nm_streq (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { + NM_SET_OUT (out_slave_name, "bridge-slave"); + return valid_settings_slave_bridge; + } + if (nm_streq (slave_type, NM_SETTING_TEAM_SETTING_NAME)) { + NM_SET_OUT (out_slave_name, "team-slave"); + return valid_settings_slave_team; + } + return NULL; +} + +/*****************************************************************************/ + static const char * _meta_type_setting_info_editor_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 491147bc5e..3653e10968 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -269,6 +269,11 @@ struct _NMMetaPropertyInfo { const NMMetaPropertyTypData *property_typ_data; }; +typedef struct _NMMetaSettingValidPartItem { + const NMMetaSettingInfoEditor *setting_info; + bool mandatory; +} NMMetaSettingValidPartItem; + struct _NMMetaSettingInfoEditor { const NMMetaType *meta_type; const NMMetaSettingInfo *general; @@ -278,6 +283,18 @@ struct _NMMetaSettingInfoEditor { * "name", and then the order is as they are listed by default. */ const NMMetaPropertyInfo *properties; guint properties_num; + + /* a NMConnection has a main type (connection.type), which is a + * main NMSetting instance. Depending on the type, a connection + * may have a list of other allowed settings. + * + * For example, a connection of type "vlan" may have settings + * of type "connection", "vlan", and "wired". + * + * Some setting types a not a main type (NMSettingProxy). They + * don't have valid_settings but are usually referenced by other + * settings to be valid for them. */ + const NMMetaSettingValidPartItem *const*valid_parts; }; struct _NMMetaType { @@ -309,6 +326,10 @@ extern const NMMetaType nm_meta_type_property_info; extern const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[_NM_META_SETTING_TYPE_NUM]; +extern const NMMetaSettingValidPartItem *const nm_meta_setting_info_valid_parts_default[]; + +const NMMetaSettingValidPartItem *const*nm_meta_setting_info_valid_parts_for_slave_type (const char *slave_type, const char **out_slave_name); + /*****************************************************************************/ typedef enum { diff --git a/clients/common/tests/test-general.c b/clients/common/tests/test-general.c index b5f9af75de..058ee26994 100644 --- a/clients/common/tests/test-general.c +++ b/clients/common/tests/test-general.c @@ -95,6 +95,29 @@ test_client_meta_check (void) } } else g_assert (!info->properties); + + if (info->valid_parts) { + gsize i, l; + gs_unref_hashtable GHashTable *dup = g_hash_table_new (NULL, NULL); + + l = NM_PTRARRAY_LEN (info->valid_parts); + g_assert (l >= 2); + + for (i = 0; info->valid_parts[i]; i++) { + g_assert (info->valid_parts[i]->setting_info); + g_assert (nm_g_hash_table_add (dup, (gpointer) info->valid_parts[i]->setting_info)); + + if (i == 0) { + g_assert (info->valid_parts[i]->setting_info == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_CONNECTION]); + g_assert (info->valid_parts[i]->mandatory); + } + if (i == 1) { + g_assert (info->valid_parts[i]->setting_info == &nm_meta_setting_infos_editor[m]); + g_assert (info->valid_parts[i]->mandatory); + } + } + g_assert (i == l); + } } for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) { @@ -112,7 +135,7 @@ test_client_meta_check (void) for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) { const NMMetaSettingInfoEditor *info = &nm_meta_setting_infos_editor[m]; - g_assert (nm_meta_setting_info_editor_find_by_name (info->general->setting_name) == info); + g_assert (nm_meta_setting_info_editor_find_by_name (info->general->setting_name, FALSE) == info); g_assert (nm_meta_setting_info_editor_find_by_gtype (info->general->get_setting_gtype ()) == info); for (p = 0; p < info->properties_num; p++) { From 1e4bc51a4a2e1d1c5d3f988bc1d3d6a9c0a3ae56 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 11 Apr 2017 15:48:04 +0200 Subject: [PATCH 29/32] cli: move completion for devices names to meta data --- clients/cli/connections.c | 31 +++++--------- clients/cli/settings.c | 25 +++++++++++ clients/common/nm-meta-setting-access.c | 4 ++ clients/common/nm-meta-setting-access.h | 2 + clients/common/nm-meta-setting-desc.c | 55 ++++++++++++++++++++++--- clients/common/nm-meta-setting-desc.h | 10 +++++ 6 files changed, 102 insertions(+), 25 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 373596304e..e56b2a2311 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3347,7 +3347,11 @@ _meta_abstract_complete (const NMMetaAbstractInfo *abstract_info, const char *te const char *const*values; char **values_to_free = NULL; - values = nm_meta_abstract_info_complete (abstract_info, text, &values_to_free); + values = nm_meta_abstract_info_complete (abstract_info, + nmc_meta_environment, + nmc_meta_environment_arg, + text, + &values_to_free); if (values) return values_to_free ?: g_strdupv ((char **) values); return NULL; @@ -4031,10 +4035,9 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) .generator_func = generator_func_, \ } OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, nmc_rl_gen_func_ifnames), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, NULL), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), - OPTION_INFO (VLAN, NM_SETTING_VLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "mode", set_bond_option, gen_func_bond_mode), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "primary", set_bond_option, nmc_rl_gen_func_ifnames), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, NULL, set_bond_monitoring_mode, gen_func_bond_mon_mode), @@ -4044,9 +4047,6 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-interval", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "arp-ip-target", set_bond_option, NULL), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "lacp-rate", set_bond_option, gen_func_bond_lacp_rate), - OPTION_INFO (MACVLAN, NM_SETTING_MACVLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), - OPTION_INFO (VXLAN, NM_SETTING_VXLAN_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), - OPTION_INFO (IP_TUNNEL, NM_SETTING_IP_TUNNEL_PARENT, "dev", NULL, nmc_rl_gen_func_ifnames), OPTION_INFO (IP4_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip4", set_ip4_address, NULL), OPTION_INFO (IP6_CONFIG, NM_SETTING_IP_CONFIG_ADDRESSES, "ip6", set_ip6_address, NULL), { 0 }, @@ -4170,7 +4170,11 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) const char *const*values; gs_strfreev char **values_to_free = NULL; - values = nm_meta_abstract_info_complete (abstract_info, prefix, &values_to_free); + values = nm_meta_abstract_info_complete (abstract_info, + nmc_meta_environment, + nmc_meta_environment_arg, + prefix, + &values_to_free); if (values) { for (; values[0]; values++) g_print ("%s\n", values[0]); @@ -4202,20 +4206,9 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar run_rl_generator (gen_connection_types, prefix); else if (strcmp (property, NM_SETTING_CONNECTION_MASTER) == 0) run_rl_generator (gen_func_master_ifnames, prefix); - else if (strcmp (property, NM_SETTING_CONNECTION_INTERFACE_NAME) == 0) - run_rl_generator (nmc_rl_gen_func_ifnames, prefix); } else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) run_rl_generator (gen_func_bt_type, prefix); - else if (strcmp (setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_IP_TUNNEL_PARENT) == 0) - run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - } else if (strcmp (setting_name, NM_SETTING_MACVLAN_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_MACVLAN_PARENT) == 0) - run_rl_generator (nmc_rl_gen_func_ifnames, prefix); - } else if ( strcmp (setting_name, NM_SETTING_VXLAN_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_VXLAN_PARENT) == 0) - run_rl_generator (nmc_rl_gen_func_ifnames, prefix); } /*----------------------------------------------------------------------------*/ @@ -4520,8 +4513,6 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) next: if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) generator_func = gen_connection_types; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_IFNAME)) - generator_func = nmc_rl_gen_func_ifnames; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER)) generator_func = gen_func_master_ifnames; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index c508a139f1..a9ad116249 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -456,10 +456,35 @@ _env_warn_fcn_handle (const NMMetaEnvironment *environment, g_print (_("Error: %s\n"), m); } +static NMDevice *const* +_env_get_nm_devices (const NMMetaEnvironment *environment, + gpointer environment_user_data, + guint *out_len) +{ + NmCli *nmc = environment_user_data; + const GPtrArray *devices; + + nm_assert (nmc); + + /* the returned list is *not* NULL terminated. Need to + * provide and honor the out_len argument. */ + nm_assert (out_len); + + devices = nm_client_get_devices (nmc->client); + if (!devices) { + *out_len = 0; + return NULL; + } + + *out_len = devices->len; + return (NMDevice *const*) devices->pdata; +} + /*****************************************************************************/ const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment) { .warn_fcn = _env_warn_fcn_handle, + .get_nm_devices = _env_get_nm_devices, }); NmCli *const nmc_meta_environment_arg = &nm_cli; diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index dc1ed024a6..63d070602e 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -261,6 +261,8 @@ nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, const char *const* nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, const char *text, char ***out_to_free) { @@ -277,6 +279,8 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, return NULL; values = abstract_info->meta_type->complete_fcn (abstract_info, + environment, + environment_user_data, text, out_to_free); diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 78ad93ab2e..19c4ad7d60 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -60,6 +60,8 @@ gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info gpointer *out_to_free); const char *const*nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, const char *text, char ***out_to_free); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index cb559eb7c1..922561af2d 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -524,7 +524,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error #define ARGS_COMPLETE_FCN \ - const NMMetaPropertyInfo *property_info, const char *text, char ***out_to_free + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const char *text, char ***out_to_free #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free @@ -1107,6 +1107,40 @@ _complete_fcn_gobject_bool (ARGS_COMPLETE_FCN) return v; } +static const char *const* +_complete_fcn_gobject_devices (ARGS_COMPLETE_FCN) +{ + NMDevice *const*devices = NULL; + guint i, j; + guint len = 0; + char **ifnames; + + if ( environment + && environment->get_nm_devices) { + devices = environment->get_nm_devices (environment, + environment_user_data, + &len); + } + + if (len == 0) + return NULL; + + ifnames = g_new (char *, len + 1); + for (i = 0, j = 0; i < len; i++) { + const char *ifname; + + nm_assert (NM_IS_DEVICE (devices[i])); + + ifname = nm_device_get_iface (devices[i]); + if (ifname) + ifnames[j++] = g_strdup (ifname); + } + ifnames[j++] = NULL; + + *out_to_free = ifnames; + return (const char *const*) ifnames; +} + /*****************************************************************************/ static char * @@ -4772,6 +4806,12 @@ static const NMMetaPropertyType _pt_gobject_enum = { .values_fcn = _values_fcn_gobject_enum, }; +static const NMMetaPropertyType _pt_gobject_devices = { + .get_fcn = _get_fcn_gobject, + .set_fcn = _set_fcn_gobject_string, + .complete_fcn = _complete_fcn_gobject_devices, +}; + /*****************************************************************************/ #include "settings-docs.c" @@ -5346,6 +5386,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_gobject_ifname, + .complete_fcn = _complete_fcn_gobject_devices, ), }, { @@ -6040,7 +6081,7 @@ static const NMMetaPropertyInfo property_infos_IP_TUNNEL[] = { .is_cli_option = TRUE, .property_alias = "dev", .prompt = N_("Parent device [none]"), - .property_type = &_pt_gobject_string, + .property_type = &_pt_gobject_devices, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_LOCAL), @@ -6173,7 +6214,7 @@ static const NMMetaPropertyInfo property_infos_MACVLAN[] = { .property_alias = "dev", .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, .prompt = N_("MACVLAN parent device or connection UUID"), - .property_type = &_pt_gobject_string, + .property_type = &_pt_gobject_devices, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_MODE), @@ -6519,7 +6560,7 @@ static const NMMetaPropertyInfo property_infos_VLAN[] = { .property_alias = "dev", .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, .prompt = N_("VLAN parent device or connection UUID"), - .property_type = &_pt_gobject_string, + .property_type = &_pt_gobject_devices, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_ID), @@ -6620,7 +6661,7 @@ static const NMMetaPropertyInfo property_infos_VXLAN[] = { .is_cli_option = TRUE, .property_alias = "dev", .prompt = N_("Parent device [none]"), - .property_type = &_pt_gobject_string, + .property_type = &_pt_gobject_devices, }, { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_ID), @@ -7467,6 +7508,8 @@ _meta_type_property_info_get_nested (const NMMetaAbstractInfo *abstract_info, static const char *const* _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, const char *text, char ***out_to_free) { @@ -7476,6 +7519,8 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, if (info->property_type->complete_fcn) { return info->property_type->complete_fcn (info, + environment, + environment_user_data, text, out_to_free); } diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 3653e10968..a3df61f91a 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -22,6 +22,8 @@ #include "nm-meta-setting.h" +struct _NMDevice; + #define NM_META_TEXT_HIDDEN "" #define NM_META_TEXT_PROMPT_ADSL_PROTO N_("Protocol") @@ -197,6 +199,8 @@ struct _NMMetaPropertyType { char ***out_to_free); const char *const*(*complete_fcn) (const NMMetaPropertyInfo *property_info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, const char *text, char ***out_to_free); }; @@ -313,6 +317,8 @@ struct _NMMetaType { NMMetaAccessorGetOutFlags *out_flags, gpointer *out_to_free); const char *const*(*complete_fcn) (const NMMetaAbstractInfo *info, + const NMMetaEnvironment *environment, + gpointer environment_user_data, const char *text, char ***out_to_free); }; @@ -349,6 +355,10 @@ struct _NMMetaEnvironment { const char *fmt_l10n, /* the untranslated format string, but it is marked for translation using N_(). */ va_list ap); + struct _NMDevice *const*(*get_nm_devices) (const NMMetaEnvironment *environment, + gpointer environment_user_data, + guint *out_len); + }; /*****************************************************************************/ From 2a760897f201a2864cfc01c48222c960889141f9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 11 Apr 2017 15:48:04 +0200 Subject: [PATCH 30/32] cli: move completion for master connections to meta data This change (improves) behavior. Before, we would only complete if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0) which doesn't really make sense as it depends on the slave-type, not nmc_tab_completion.con_type. --- clients/cli/connections.c | 62 ++++++----------------- clients/cli/settings.c | 25 +++++++++ clients/common/nm-meta-setting-access.c | 2 + clients/common/nm-meta-setting-access.h | 1 + clients/common/nm-meta-setting-desc.c | 67 ++++++++++++++++++++++++- clients/common/nm-meta-setting-desc.h | 14 ++++++ 6 files changed, 123 insertions(+), 48 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index e56b2a2311..cf1a750805 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3346,10 +3346,14 @@ _meta_abstract_complete (const NMMetaAbstractInfo *abstract_info, const char *te { const char *const*values; char **values_to_free = NULL; + const NMMetaOperationContext ctx = { + .connection = nmc_tab_completion.connection, + }; values = nm_meta_abstract_info_complete (abstract_info, nmc_meta_environment, nmc_meta_environment_arg, + &ctx, text, &values_to_free); if (values) @@ -3717,42 +3721,6 @@ gen_func_bond_lacp_rate (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_func_master_ifnames (const char *text, int state) -{ - int i; - GPtrArray *ifnames; - char *ret; - NMConnection *con; - NMSettingConnection *s_con; - const char *con_type, *ifname; - const GPtrArray *connections; - - connections = nm_client_get_connections (nm_cli.client); - - /* Disable appending space after completion */ - rl_completion_append_character = '\0'; - - ifnames = g_ptr_array_sized_new (20); - for (i = 0; i < connections->len; i++) { - con = NM_CONNECTION (connections->pdata[i]); - s_con = nm_connection_get_setting_connection (con); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0) - continue; - ifname = nm_connection_get_interface_name (con); - g_ptr_array_add (ifnames, (gpointer) ifname); - } - g_ptr_array_add (ifnames, (gpointer) NULL); - - ret = nmc_rl_gen_func_basic (text, state, (const char **) ifnames->pdata); - - g_ptr_array_free (ifnames, TRUE); - return ret; -} - - /*----------------------------------------------------------------------------*/ static gboolean @@ -4036,7 +4004,7 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) } OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, NULL), - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, NULL), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "mode", set_bond_option, gen_func_bond_mode), OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "primary", set_bond_option, nmc_rl_gen_func_ifnames), @@ -4164,15 +4132,19 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix) } static gboolean -complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) +complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix, NMConnection *context_connection) { const OptionInfo *candidate; const char *const*values; gs_strfreev char **values_to_free = NULL; + const NMMetaOperationContext ctx = { + .connection = context_connection, + }; values = nm_meta_abstract_info_complete (abstract_info, nmc_meta_environment, nmc_meta_environment_arg, + &ctx, prefix, &values_to_free); if (values) { @@ -4191,21 +4163,19 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix) } static void -complete_property (const gchar *setting_name, const gchar *property, const gchar *prefix) +complete_property (const gchar *setting_name, const gchar *property, const gchar *prefix, NMConnection *connection) { const NMMetaPropertyInfo *property_info; property_info = nm_meta_property_info_find_by_name (setting_name, property); if (property_info) { - if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix)) + if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix, connection)) return; } if (strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) == 0) { if (strcmp (property, NM_SETTING_CONNECTION_TYPE) == 0) run_rl_generator (gen_connection_types, prefix); - else if (strcmp (property, NM_SETTING_CONNECTION_MASTER) == 0) - run_rl_generator (gen_func_master_ifnames, prefix); } else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) run_rl_generator (gen_func_bt_type, prefix); @@ -4299,7 +4269,7 @@ nmc_read_connection_properties (NmCli *nmc, return FALSE; if (!*argc && nmc->complete) - complete_property (setting, strv[1], value ? value : ""); + complete_property (setting, strv[1], value ? value : "", connection); if (!set_property (connection, setting_name, strv[1], value, modifier, error)) return FALSE; @@ -4378,7 +4348,7 @@ nmc_read_connection_properties (NmCli *nmc, return FALSE; if (!*argc && nmc->complete) - complete_option (chosen, value ? value : ""); + complete_option (chosen, value ? value : "", connection); if (!set_option (nmc, connection, chosen, value, error)) return FALSE; @@ -4513,8 +4483,6 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) next: if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) generator_func = gen_connection_types; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER)) - generator_func = gen_func_master_ifnames; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) generator_func = gen_func_bt_type; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE)) @@ -8422,7 +8390,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) } if (argc == 1 && nmc->complete) - complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv); + complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv, NULL); if (!type) type = *argv; diff --git a/clients/cli/settings.c b/clients/cli/settings.c index a9ad116249..f3372da943 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -480,11 +480,36 @@ _env_get_nm_devices (const NMMetaEnvironment *environment, return (NMDevice *const*) devices->pdata; } +static NMRemoteConnection *const* +_env_get_nm_connections (const NMMetaEnvironment *environment, + gpointer environment_user_data, + guint *out_len) +{ + NmCli *nmc = environment_user_data; + const GPtrArray *values; + + nm_assert (nmc); + + /* the returned list is *not* NULL terminated. Need to + * provide and honor the out_len argument. */ + nm_assert (out_len); + + values = nm_client_get_connections (nmc->client); + if (!values) { + *out_len = 0; + return NULL; + } + + *out_len = values->len; + return (NMRemoteConnection *const*) values->pdata; +} + /*****************************************************************************/ const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment) { .warn_fcn = _env_warn_fcn_handle, .get_nm_devices = _env_get_nm_devices, + .get_nm_connections = _env_get_nm_connections, }); NmCli *const nmc_meta_environment_arg = &nm_cli; diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 63d070602e..e53513e9c4 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -263,6 +263,7 @@ const char *const* nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, const NMMetaEnvironment *environment, gpointer environment_user_data, + const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free) { @@ -281,6 +282,7 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, values = abstract_info->meta_type->complete_fcn (abstract_info, environment, environment_user_data, + operation_context, text, out_to_free); diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 19c4ad7d60..0479d03c2b 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -62,6 +62,7 @@ gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info const char *const*nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, const NMMetaEnvironment *environment, gpointer environment_user_data, + const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 922561af2d..402566bfcf 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -524,7 +524,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error #define ARGS_COMPLETE_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const char *text, char ***out_to_free + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free @@ -2359,6 +2359,68 @@ _set_fcn_connection_master (ARGS_SET_FCN) return TRUE; } +static const char *const* +_complete_fcn_connection_master (ARGS_COMPLETE_FCN) +{ + NMRemoteConnection *const*connections = NULL; + guint len = 0; + guint i, j; + char **result; + NMSettingConnection *s_con; + const char *expected_type = NULL; + gsize text_len; + + if ( environment + && environment->get_nm_connections) { + connections = environment->get_nm_connections (environment, + environment_user_data, + &len); + } + if (!len) + return NULL; + + if ( (!text || !*text) + && operation_context + && operation_context->connection) { + /* if we have no text yet, initially only complete for matching + * slave-type. */ + s_con = nm_connection_get_setting_connection (operation_context->connection); + if (s_con) + expected_type = nm_setting_connection_get_slave_type (s_con); + } + + text_len = strlen (text); + + result = g_new (char *, (2 * len) + 1); + for (i = 0, j = 0; i < len; i++) { + const char *v; + + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connections[i])); + if (!s_con) + continue; + + if ( expected_type + && !nm_streq0 (nm_setting_connection_get_connection_type (s_con), + expected_type)) + continue; + + if (text && text[0]) { + /* if we have text, also complete for the UUID. */ + v = nm_setting_connection_get_uuid (s_con); + if (v && (!text || strncmp (text, v, text_len) == 0)) + result[j++] = g_strdup (v); + } + + v = nm_setting_connection_get_interface_name (s_con); + if (v && (!text || strncmp (text, v, text_len) == 0)) + result[j++] = g_strdup (v); + } + result[j++] = NULL; + + *out_to_free = NULL; + return (const char *const*) result; +} + static gboolean _set_fcn_connection_secondaries (ARGS_SET_FCN) { @@ -5452,6 +5514,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_connection_master, + .complete_fcn = _complete_fcn_connection_master, ), }, { @@ -7510,6 +7573,7 @@ static const char *const* _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, const NMMetaEnvironment *environment, gpointer environment_user_data, + const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free) { @@ -7521,6 +7585,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, return info->property_type->complete_fcn (info, environment, environment_user_data, + operation_context, text, out_to_free); } diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index a3df61f91a..6a750d5c8a 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -168,6 +168,14 @@ typedef struct _NMMetaSettingInfoEditor NMMetaSettingInfoEditor; typedef struct _NMMetaPropertyInfo NMMetaPropertyInfo; typedef struct _NMMetaPropertyType NMMetaPropertyType; typedef struct _NMMetaPropertyTypData NMMetaPropertyTypData; +typedef struct _NMMetaOperationContext NMMetaOperationContext; + +/* this gives some context information for virtual functions. + * This command actually violates layering, and should be considered + * a hack. In the future, try to replace it's use. */ +struct _NMMetaOperationContext { + NMConnection *connection; +}; struct _NMMetaPropertyType { @@ -201,6 +209,7 @@ struct _NMMetaPropertyType { const char *const*(*complete_fcn) (const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, + const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free); }; @@ -319,6 +328,7 @@ struct _NMMetaType { const char *const*(*complete_fcn) (const NMMetaAbstractInfo *info, const NMMetaEnvironment *environment, gpointer environment_user_data, + const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free); }; @@ -359,6 +369,10 @@ struct _NMMetaEnvironment { gpointer environment_user_data, guint *out_len); + struct _NMRemoteConnection *const*(*get_nm_connections) (const NMMetaEnvironment *environment, + gpointer environment_user_data, + guint *out_len); + }; /*****************************************************************************/ From b629b986879b88987ec699217cb351c6759b3d3f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 11 Apr 2017 15:48:04 +0200 Subject: [PATCH 31/32] cli: move completion for connection type to meta data --- clients/cli/common.c | 32 +++++++++++++ clients/cli/common.h | 1 + clients/cli/connections.c | 69 ++++++++------------------- clients/cli/nmcli.h | 2 + clients/common/nm-meta-setting-desc.c | 34 ++++++++++++- clients/common/nm-meta-setting-desc.h | 2 + 6 files changed, 90 insertions(+), 50 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index 8738cef7b6..e37d9d8c8b 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -1126,6 +1126,38 @@ nmc_rl_gen_func_basic (const char *text, int state, const char *const*words) return NULL; } +static struct { + bool initialized; + guint idx; + char **values; +} _rl_compentry_func_wrap = { 0 }; + +static char * +_rl_compentry_func_wrap_fcn (const char *text, int state) +{ + g_return_val_if_fail (_rl_compentry_func_wrap.initialized, NULL); + + if ( !_rl_compentry_func_wrap.values + || !_rl_compentry_func_wrap.values[_rl_compentry_func_wrap.idx]) { + g_strfreev (_rl_compentry_func_wrap.values); + _rl_compentry_func_wrap.values = NULL; + _rl_compentry_func_wrap.initialized = FALSE; + return NULL; + } + + return g_strdup (_rl_compentry_func_wrap.values[_rl_compentry_func_wrap.idx++]); +} + +NmcCompEntryFunc +nmc_rl_compentry_func_wrap (const char *const*values) +{ + g_strfreev (_rl_compentry_func_wrap.values); + _rl_compentry_func_wrap.values = g_strdupv ((char **) values); + _rl_compentry_func_wrap.idx = 0; + _rl_compentry_func_wrap.initialized = TRUE; + return _rl_compentry_func_wrap_fcn; +} + char * nmc_rl_gen_func_ifnames (const char *text, int state) { diff --git a/clients/cli/common.h b/clients/cli/common.h index 4f0f1b1ddb..b7057e462f 100644 --- a/clients/cli/common.h +++ b/clients/cli/common.h @@ -53,6 +53,7 @@ char *nmc_unique_connection_name (const GPtrArray *connections, void nmc_cleanup_readline (void); char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2); char *nmc_readline_echo (gboolean echo_on, const char *prompt_fmt, ...) G_GNUC_PRINTF (2, 3); +NmcCompEntryFunc nmc_rl_compentry_func_wrap (const char *const*values); char *nmc_rl_gen_func_basic (const char *text, int state, const char *const*words); char *nmc_rl_gen_func_ifnames (const char *text, int state); gboolean nmc_get_in_readline (void); diff --git a/clients/cli/connections.c b/clients/cli/connections.c index cf1a750805..dd7cfc5261 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -184,8 +184,6 @@ typedef struct { } TabCompletionInfo; static TabCompletionInfo nmc_tab_completion = {NULL, NULL, NULL, NULL}; -static char *gen_connection_types (const char *text, int state); - static void usage (void) { @@ -2771,7 +2769,7 @@ finish: return nmc->return_value; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ /* * Return the most appropriate name for the connection of a type 'name' possibly with given 'slave_type' @@ -3097,7 +3095,7 @@ is_setting_mandatory (NMConnection *connection, NMSetting *setting) return FALSE; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static const char * _strip_master_prefix (const char *master, const char *(**func)(NMConnection *)) @@ -3685,7 +3683,7 @@ ensure_settings (NMConnection *connection, const NMMetaSettingValidPartItem *con } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static char * gen_func_bool_values_l10n (const char *text, int state) @@ -3721,7 +3719,7 @@ gen_func_bond_lacp_rate (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static gboolean set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) @@ -4002,7 +4000,7 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) .check_and_set = check_and_set_, \ .generator_func = generator_func_, \ } - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, NULL), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, NULL), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, NULL), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), @@ -4053,7 +4051,7 @@ option_relevant (NMConnection *connection, const NMMetaAbstractInfo *abstract_in return TRUE; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void complete_property_name (NmCli *nmc, NMConnection *connection, @@ -4173,15 +4171,12 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar return; } - if (strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_CONNECTION_TYPE) == 0) - run_rl_generator (gen_connection_types, prefix); - } else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 + if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) run_rl_generator (gen_func_bt_type, prefix); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static gboolean get_value (const char **value, int *argc, char ***argv, const char *option, GError **error) @@ -4481,9 +4476,7 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) } next: - if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) - generator_func = gen_connection_types; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) + if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) generator_func = gen_func_bt_type; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE)) generator_func = gen_func_bond_mode; @@ -4841,7 +4834,7 @@ finish: return nmc->return_value; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ /* Functions for readline TAB completion in editor */ static void @@ -4961,36 +4954,14 @@ gen_cmd_save (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_connection_types (const char *text, int state) +static rl_compentry_func_t * +gen_connection_types (const char *text) { - static int list_idx, len; - static int had_name; + gs_strfreev char **values = NULL; - if (!state) { - list_idx = 0; - len = strlen (text); - had_name = FALSE; - } - - for (; list_idx < _NM_META_SETTING_TYPE_NUM; ) { - const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[list_idx]; - - if (!had_name) { - had_name = TRUE; - if (!text || strncmp (text, setting_info->general->setting_name, len) == 0) - return g_strdup (setting_info->general->setting_name); - } - - had_name = FALSE; - list_idx++; - if (setting_info->alias) { - if (!text || strncmp (text, setting_info->alias, len) == 0) - return g_strdup (setting_info->alias); - } - } - - return NULL; + values = _meta_abstract_complete ((const NMMetaAbstractInfo *) nm_meta_property_info_connection_type, + text); + return nmc_rl_compentry_func_wrap ((const char *const*) values); } static char * @@ -5586,7 +5557,7 @@ nmcli_editor_tab_completion (const char *text, int start, int end) /* Choose the right generator function */ if (strcmp (prompt_tmp, EDITOR_PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; + generator_func = gen_connection_types (text); else if (strcmp (prompt_tmp, EDITOR_PROMPT_SETTING) == 0) generator_func = gen_setting_names; else if (strcmp (prompt_tmp, EDITOR_PROMPT_PROPERTY) == 0) @@ -5772,7 +5743,7 @@ save_history_cmds (const char *uuid) } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void editor_show_connection (NMConnection *connection, NmCli *nmc) @@ -6125,7 +6096,7 @@ editor_sub_usage (const char *command) } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ typedef struct { NMDevice *device; @@ -6250,7 +6221,7 @@ activate_connection_editor_cb (GObject *client, g_clear_error (&error); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void print_property_description (NMSetting *setting, const char *prop_name) diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 7203b21c8e..839a49bbc0 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -32,6 +32,8 @@ typedef gpointer NMPolkitListener; #endif +typedef char *(*NmcCompEntryFunc) (const char *, int); + /* nmcli exit codes */ typedef enum { /* Indicates successful execution */ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 402566bfcf..ddcce8c04e 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2272,6 +2272,37 @@ _set_fcn_connection_type (ARGS_SET_FCN) return TRUE; } +static const char *const* +_complete_fcn_connection_type (ARGS_COMPLETE_FCN) +{ + guint i, j; + char **result; + gsize text_len; + + result = g_new (char *, _NM_META_SETTING_TYPE_NUM * 2 + 1); + + text_len = text ? strlen (text) : 0; + + for (i = 0, j = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[i]; + const char *v; + + v = setting_info->alias; + if (v) { + if (!text || strncmp (text, v, text_len) == 0) + result[j++] = g_strdup (v); + } + if (!text || !*text || !v) { + v = setting_info->general->setting_name; + if (!text || strncmp (text, v, text_len) == 0) + result[j++] = g_strdup (v); + } + } + result[j++] = NULL; + + return (const char *const*) (*out_to_free = result); +} + /* define from libnm-core/nm-setting-connection.c */ #define PERM_USER_PREFIX "user:" @@ -5451,7 +5482,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .complete_fcn = _complete_fcn_gobject_devices, ), }, - { + [_NM_META_PROPERTY_TYPE_CONNECTION_TYPE] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_TYPE), .is_cli_option = TRUE, .property_alias = "type", @@ -5460,6 +5491,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_connection_type, + .complete_fcn = _complete_fcn_connection_type, ), }, { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 6a750d5c8a..859f453d2f 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -252,8 +252,10 @@ typedef enum { enum { _NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE = 0, + _NM_META_PROPERTY_TYPE_CONNECTION_TYPE = 4, }; +#define nm_meta_property_info_connection_type (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_CONNECTION].properties[_NM_META_PROPERTY_TYPE_CONNECTION_TYPE]) #define nm_meta_property_info_vpn_service_type (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VPN].properties[_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE]) struct _NMMetaPropertyInfo { From 6d12d2f3a08609539dae93e0767d288816b35c4e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 12 Apr 2017 10:13:41 +0200 Subject: [PATCH 32/32] cli: move setting creation to meta data --- clients/cli/connections.c | 85 +++++-------- clients/cli/settings.c | 68 ----------- clients/cli/settings.h | 1 - clients/common/nm-meta-setting-access.c | 20 +++ clients/common/nm-meta-setting-access.h | 3 + clients/common/nm-meta-setting-desc.c | 155 +++++++++++++++++++++++- clients/common/nm-meta-setting-desc.h | 9 ++ 7 files changed, 216 insertions(+), 125 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index dd7cfc5261..cdc20578aa 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -495,22 +495,6 @@ usage_connection_export (void) "The data are directed to standard output or to a file if a name is given.\n\n")); } -static NMSetting * -nmc_setting_new_for_name (const char *name) -{ - GType stype; - NMSetting *setting = NULL; - - if (name) { - stype = nm_setting_lookup_type (name); - if (stype != G_TYPE_INVALID) { - setting = g_object_new (stype, NULL); - g_warn_if_fail (NM_IS_SETTING (setting)); - } - } - return setting; -} - static void quit (void) { @@ -3531,16 +3515,8 @@ set_property (NMConnection *connection, setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { - setting = nmc_setting_new_for_name (setting_name); - if (!setting) { - g_assert (FALSE); - /* This should really not happen */ - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN, - _("Error: don't know how to create '%s' setting."), - setting_name); - return FALSE; - } - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (connection, setting); } @@ -3675,11 +3651,9 @@ ensure_settings (NMConnection *connection, const NMMetaSettingValidPartItem *con continue; if (nm_connection_get_setting_by_name (connection, (*item)->setting_info->general->setting_name)) continue; - setting = nmc_setting_new_for_name ((*item)->setting_info->general->setting_name); - if (setting) { - nmc_setting_custom_init (setting); - nm_connection_add_setting (connection, setting); - } + setting = nm_meta_setting_info_editor_new_setting ((*item)->setting_info, + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); + nm_connection_add_setting (connection, setting); } } @@ -3926,8 +3900,8 @@ set_bluetooth_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, con if ( !strcmp (value, NM_SETTING_BLUETOOTH_TYPE_DUN) || !strcmp (value, NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm")) { value = NM_SETTING_BLUETOOTH_TYPE_DUN; - setting = nm_setting_gsm_new (); - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_GSM], + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (con, setting); } else if (!strcmp (value, NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma")) { value = NM_SETTING_BLUETOOTH_TYPE_DUN; @@ -5066,7 +5040,8 @@ gen_property_names (const char *text, int state) valid_settings_main, valid_settings_slave, NULL); - setting = nmc_setting_new_for_name (setting_name); + setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), + NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT); } else { /* Else take the current setting, if any */ setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; @@ -5366,7 +5341,8 @@ get_setting_and_property (const char *prompt, const char *line, setting_name = check_valid_name (sett, valid_settings_main, valid_settings_slave, NULL); - setting = nmc_setting_new_for_name (setting_name); + setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), + NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT); } else setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; @@ -6570,10 +6546,8 @@ create_setting_by_name (const char *name, const NMMetaSettingValidPartItem *cons setting_name = check_valid_name (name, valid_settings_main, valid_settings_slave, NULL); if (setting_name) { - setting = nmc_setting_new_for_name (setting_name); - if (!setting) - return NULL; /* This should really not happen */ - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); } return setting; } @@ -6912,12 +6886,16 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { - setting = nmc_setting_new_for_name (setting_name); - if (!setting) { + const NMMetaSettingInfoEditor *setting_info; + + setting_info = nm_meta_setting_info_editor_find_by_name (setting_name, FALSE); + if (!setting_info) { g_print (_("Error: unknown setting '%s'\n"), setting_name); break; } - nmc_setting_custom_init (setting); + + setting = nm_meta_setting_info_editor_new_setting (setting_info, + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); if (NM_IS_SETTING_WIRELESS (setting)) nmc_setting_wireless_connect_handlers (NM_SETTING_WIRELESS (setting)); @@ -7548,11 +7526,14 @@ editor_init_new_connection (NmCli *nmc, NMConnection *connection) NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL); } else { + const NMMetaSettingInfoEditor *setting_info; + /* Add a "base" setting to the connection by default */ - base_setting = nmc_setting_new_for_name (con_type); - if (!base_setting) + setting_info = nm_meta_setting_info_editor_find_by_name (con_type, FALSE); + if (!setting_info) return; - nmc_setting_custom_init (base_setting); + base_setting = nm_meta_setting_info_editor_new_setting (setting_info, + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (connection, base_setting); set_default_interface_name (nmc, s_con); @@ -7567,18 +7548,16 @@ editor_init_new_connection (NmCli *nmc, NMConnection *connection) } - /* Always add IPv4 and IPv6 settings for non-slave connections */ - setting = nm_setting_ip4_config_new (); - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_IP4_CONFIG], + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (connection, setting); - setting = nm_setting_ip6_config_new (); - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_IP6_CONFIG], + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (connection, setting); - /* Also Proxy Setting */ - setting = nm_setting_proxy_new (); - nmc_setting_custom_init (setting); + setting = nm_meta_setting_info_editor_new_setting (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_PROXY], + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI); nm_connection_add_setting (connection, setting); } } diff --git a/clients/cli/settings.c b/clients/cli/settings.c index f3372da943..0f18ec7f67 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -304,74 +304,6 @@ nmc_setting_connection_connect_handlers (NMSettingConnection *setting, NMConnect G_CALLBACK (connection_master_changed_cb), connection); } -/* - * Customize some properties of the setting so that the setting has sensible - * values. - */ -void -nmc_setting_custom_init (NMSetting *setting) -{ - g_return_if_fail (NM_IS_SETTING (setting)); - - if (NM_IS_SETTING_VLAN (setting)) { - /* Set sensible initial VLAN values */ - g_object_set (NM_SETTING_VLAN (setting), - NM_SETTING_VLAN_ID, 1, - NULL); - } else if (NM_IS_SETTING_INFINIBAND (setting)) { - /* Initialize 'transport-mode' so that 'infiniband' is valid */ - g_object_set (NM_SETTING_INFINIBAND (setting), - NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", - NULL); - } else if (NM_IS_SETTING_CDMA (setting)) { - /* Initialize 'number' so that 'cdma' is valid */ - g_object_set (NM_SETTING_CDMA (setting), - NM_SETTING_CDMA_NUMBER, "#777", - NULL); - } else if (NM_IS_SETTING_GSM (setting)) { - /* Initialize 'number' so that 'gsm' is valid */ - g_object_set (NM_SETTING_GSM (setting), - NM_SETTING_GSM_NUMBER, "*99#", - NULL); - } else if (NM_IS_SETTING_OLPC_MESH (setting)) { - g_object_set (NM_SETTING_OLPC_MESH (setting), - NM_SETTING_OLPC_MESH_CHANNEL, 1, - NULL); - } else if (NM_IS_SETTING_WIRELESS (setting)) { - /* For Wi-Fi set mode to "infrastructure". Even though mode == NULL - * is regarded as "infrastructure", explicit value makes no doubts. - */ - g_object_set (NM_SETTING_WIRELESS (setting), - NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, - NULL); - } else if (NM_IS_SETTING_ADSL (setting)) { - /* Initialize a protocol */ - g_object_set (NM_SETTING_ADSL (setting), - NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOE, - NULL); - } else if (NM_IS_SETTING_IP4_CONFIG (setting)) { - g_object_set (NM_SETTING_IP_CONFIG (setting), - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - } else if (NM_IS_SETTING_IP6_CONFIG (setting)) { - g_object_set (NM_SETTING_IP_CONFIG (setting), - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); - } else if (NM_IS_SETTING_PROXY (setting)) { - g_object_set (NM_SETTING_PROXY (setting), - NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, - NULL); - } else if (NM_IS_SETTING_TUN (setting)) { - g_object_set (NM_SETTING_TUN (setting), - NM_SETTING_TUN_MODE, NM_SETTING_TUN_MODE_TUN, - NULL); - } else if (NM_IS_SETTING_BLUETOOTH (setting)) { - g_object_set (NM_SETTING_BLUETOOTH (setting), - NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, - NULL); - } -} - /*****************************************************************************/ static gboolean diff --git a/clients/cli/settings.h b/clients/cli/settings.h index 0125a78269..7dad622bf8 100644 --- a/clients/cli/settings.h +++ b/clients/cli/settings.h @@ -27,7 +27,6 @@ /*****************************************************************************/ -void nmc_setting_custom_init (NMSetting *setting); void nmc_setting_ip4_connect_handlers (NMSettingIPConfig *setting); void nmc_setting_ip6_connect_handlers (NMSettingIPConfig *setting); void nmc_setting_proxy_connect_handlers (NMSettingProxy *setting); diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index e53513e9c4..4b5f82d3e4 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -148,6 +148,26 @@ nm_meta_property_info_find_by_setting (NMSetting *setting, const char *property_ return property_info; } +NMSetting * +nm_meta_setting_info_editor_new_setting (const NMMetaSettingInfoEditor *setting_info, + NMMetaAccessorSettingInitType init_type) +{ + NMSetting *setting; + + g_return_val_if_fail (setting_info, NULL); + + setting = g_object_new (setting_info->general->get_setting_gtype (), NULL); + + if ( setting_info->setting_init_fcn + && init_type != NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT) { + setting_info->setting_init_fcn (setting_info, + setting, + init_type); + } + + return setting; +} + /*****************************************************************************/ /* this basically returns NMMetaSettingType.properties, but with type diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 0479d03c2b..9863a96f14 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -25,6 +25,9 @@ /*****************************************************************************/ +NMSetting *nm_meta_setting_info_editor_new_setting (const NMMetaSettingInfoEditor *setting_info, + NMMetaAccessorSettingInitType init_type); + const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use_alias); const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_gtype (GType gtype); const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_setting (NMSetting *setting); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index ddcce8c04e..981ecddf30 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -529,6 +529,9 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free +#define ARGS_SETTING_INIT_FCN \ + const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, NMMetaAccessorSettingInitType init_type + #define RETURN_UNSUPPORTED_GET_TYPE() \ G_STMT_START { \ if (!NM_IN_SET (get_type, \ @@ -7213,6 +7216,137 @@ static const NMMetaPropertyInfo property_infos_WIRELESS_SECURITY[] = { }, }; +/*****************************************************************************/ + +static void +_setting_init_fcn_adsl (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + /* Initialize a protocol */ + g_object_set (NM_SETTING_ADSL (setting), + NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOE, + NULL); + } +} + +static void +_setting_init_fcn_bluetooth (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_BLUETOOTH (setting), + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + } +} + +static void +_setting_init_fcn_cdma (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + /* Initialize 'number' so that 'cdma' is valid */ + g_object_set (NM_SETTING_CDMA (setting), + NM_SETTING_CDMA_NUMBER, "#777", + NULL); + } +} + +static void +_setting_init_fcn_gsm (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + /* Initialize 'number' so that 'gsm' is valid */ + g_object_set (NM_SETTING_GSM (setting), + NM_SETTING_GSM_NUMBER, "*99#", + NULL); + } +} + +static void +_setting_init_fcn_infiniband (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + /* Initialize 'transport-mode' so that 'infiniband' is valid */ + g_object_set (NM_SETTING_INFINIBAND (setting), + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NULL); + } +} + +static void +_setting_init_fcn_ip4_config (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_IP_CONFIG (setting), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + } +} + +static void +_setting_init_fcn_ip6_config (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_IP_CONFIG (setting), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + } +} + +static void +_setting_init_fcn_olpc_mesh (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_OLPC_MESH (setting), + NM_SETTING_OLPC_MESH_CHANNEL, 1, + NULL); + } +} + +static void +_setting_init_fcn_proxy (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_PROXY (setting), + NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, + NULL); + } +} + +static void +_setting_init_fcn_tun (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (NM_SETTING_TUN (setting), + NM_SETTING_TUN_MODE, NM_SETTING_TUN_MODE_TUN, + NULL); + } +} + +static void +_setting_init_fcn_vlan (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + g_object_set (setting, + NM_SETTING_VLAN_ID, 1, + NULL); + } +} + +static void +_setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) +{ + if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) { + /* For Wi-Fi set mode to "infrastructure". Even though mode == NULL + * is regarded as "infrastructure", explicit value makes no doubts. + */ + g_object_set (NM_SETTING_WIRELESS (setting), + NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, + NULL); + } +} + +/*****************************************************************************/ + #define SETTING_PRETTY_NAME_802_1X "802-1x settings" #define SETTING_PRETTY_NAME_ADSL "ADSL connection" #define SETTING_PRETTY_NAME_BLUETOOTH "bluetooth connection" @@ -7280,12 +7414,14 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (ADSL, TRUE), ), + .setting_init_fcn = _setting_init_fcn_adsl, ), SETTING_INFO (BLUETOOTH, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (BLUETOOTH, TRUE), ), + .setting_init_fcn = _setting_init_fcn_bluetooth, ), SETTING_INFO (BOND, .valid_parts = NM_META_SETTING_VALID_PARTS ( @@ -7309,6 +7445,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE), NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), ), + .setting_init_fcn = _setting_init_fcn_cdma, ), SETTING_INFO (CONNECTION), SETTING_INFO (DCB), @@ -7332,15 +7469,21 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE), NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE), ), + .setting_init_fcn = _setting_init_fcn_gsm, ), SETTING_INFO (INFINIBAND, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (INFINIBAND, TRUE), ), + .setting_init_fcn = _setting_init_fcn_infiniband, + ), + SETTING_INFO (IP4_CONFIG, + .setting_init_fcn = _setting_init_fcn_ip4_config, + ), + SETTING_INFO (IP6_CONFIG, + .setting_init_fcn = _setting_init_fcn_ip6_config, ), - SETTING_INFO (IP4_CONFIG), - SETTING_INFO (IP6_CONFIG), SETTING_INFO (IP_TUNNEL, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), @@ -7368,6 +7511,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (OLPC_MESH, TRUE), ), + .setting_init_fcn = _setting_init_fcn_olpc_mesh, ), SETTING_INFO (PPPOE, /* PPPoE is a base connection type from historical reasons. @@ -7382,7 +7526,9 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { ), ), SETTING_INFO (PPP), - SETTING_INFO (PROXY), + SETTING_INFO (PROXY, + .setting_init_fcn = _setting_init_fcn_proxy, + ), SETTING_INFO (SERIAL), SETTING_INFO (TEAM, .valid_parts = NM_META_SETTING_VALID_PARTS ( @@ -7398,6 +7544,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (TUN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), ), + .setting_init_fcn = _setting_init_fcn_tun, ), SETTING_INFO_EMPTY (USER), SETTING_INFO (VLAN, @@ -7406,6 +7553,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (VLAN, TRUE), NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), ), + .setting_init_fcn = _setting_init_fcn_vlan, ), SETTING_INFO (VPN, .valid_parts = NM_META_SETTING_VALID_PARTS ( @@ -7443,6 +7591,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (WIRELESS_SECURITY, FALSE), NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE), ), + .setting_init_fcn = _setting_init_fcn_wireless, ), SETTING_INFO (WIRELESS_SECURITY, .alias = "wifi-sec", diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 859f453d2f..cfacd347bf 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -108,6 +108,11 @@ typedef enum { NM_META_ACCESSOR_GET_TYPE_TERMFORMAT, } NMMetaAccessorGetType; +typedef enum { + NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT, + NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI, +} NMMetaAccessorSettingInitType; + static inline void nm_meta_termformat_unpack (gconstpointer value, NMMetaTermColor *out_color, NMMetaTermFormat *out_format) { @@ -310,6 +315,10 @@ struct _NMMetaSettingInfoEditor { * don't have valid_settings but are usually referenced by other * settings to be valid for them. */ const NMMetaSettingValidPartItem *const*valid_parts; + + void (*setting_init_fcn) (const NMMetaSettingInfoEditor *setting_info, + NMSetting *setting, + NMMetaAccessorSettingInitType init_type); }; struct _NMMetaType {