From aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 5 Oct 2020 22:27:18 +0200 Subject: New upstream version 1.27.90 --- clients/common/nm-client-utils.c | 1382 +-- clients/common/nm-client-utils.h | 55 +- clients/common/nm-meta-setting-access.c | 1017 +- clients/common/nm-meta-setting-access.h | 117 +- clients/common/nm-meta-setting-desc.c | 14703 ++++++++++++++------------- clients/common/nm-meta-setting-desc.h | 729 +- clients/common/nm-polkit-listener.c | 1516 ++- clients/common/nm-polkit-listener.h | 34 +- clients/common/nm-secret-agent-simple.c | 2224 ++-- clients/common/nm-secret-agent-simple.h | 58 +- clients/common/nm-vpn-helpers.c | 1500 ++- clients/common/nm-vpn-helpers.h | 31 +- clients/common/qrcodegen.c | 1634 +-- clients/common/qrcodegen.h | 149 +- clients/common/settings-docs.h | 42 +- clients/common/settings-docs.h.in | 42 +- clients/common/tests/test-clients-common.c | 564 +- clients/common/tests/test-libnm-core-aux.c | 424 +- 18 files changed, 13274 insertions(+), 12947 deletions(-) (limited to 'clients/common') diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index d3a02161..e3d3c46a 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2017 Red Hat, Inc. */ @@ -17,41 +17,36 @@ /*****************************************************************************/ static int -_nmc_objects_sort_by_path_cmp (gconstpointer pa, gconstpointer pb, gpointer user_data) +_nmc_objects_sort_by_path_cmp(gconstpointer pa, gconstpointer pb, gpointer user_data) { - NMObject *a = *((NMObject **) pa); - NMObject *b = *((NMObject **) pb); + NMObject *a = *((NMObject **) pa); + NMObject *b = *((NMObject **) pb); - NM_CMP_SELF (a, b); - NM_CMP_RETURN (nm_utils_dbus_path_cmp (nm_object_get_path (a), - nm_object_get_path (b))); - return 0; + NM_CMP_SELF(a, b); + NM_CMP_RETURN(nm_utils_dbus_path_cmp(nm_object_get_path(a), nm_object_get_path(b))); + return 0; } const NMObject ** -nmc_objects_sort_by_path (const NMObject *const* objs, gssize len) +nmc_objects_sort_by_path(const NMObject *const *objs, gssize len) { - const NMObject **arr; - gsize i, l; - - if (len < 0) - l = NM_PTRARRAY_LEN (objs); - else - l = len; - - arr = g_new (const NMObject *, l + 1); - for (i = 0; i < l; i++) - arr[i] = objs[i]; - arr[l] = NULL; - - if (l > 1) { - g_qsort_with_data (arr, - l, - sizeof (gpointer), - _nmc_objects_sort_by_path_cmp, - NULL); - } - return arr; + const NMObject **arr; + gsize i, l; + + if (len < 0) + l = NM_PTRARRAY_LEN(objs); + else + l = len; + + arr = g_new(const NMObject *, l + 1); + for (i = 0; i < l; i++) + arr[i] = objs[i]; + arr[l] = NULL; + + if (l > 1) { + g_qsort_with_data(arr, l, sizeof(gpointer), _nmc_objects_sort_by_path_cmp, NULL); + } + return arr; } /*****************************************************************************/ @@ -60,100 +55,117 @@ nmc_objects_sort_by_path (const NMObject *const* objs, gssize len) * If required, the resulting number is checked to be in the range. */ static gboolean -nmc_string_to_uint_base (const char *str, - int base, - gboolean range_check, - unsigned long int min, - unsigned long int max, - unsigned long int *value) +nmc_string_to_uint_base(const char * str, + int base, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value) { - char *end; - unsigned long int tmp; - - if (!str || !str[0]) - return FALSE; - - /* FIXME: don't use this function, replace by _nm_utils_ascii_str_to_int64() */ - errno = 0; - tmp = strtoul (str, &end, base); - if (errno || *end != '\0' || (range_check && (tmp < min || tmp > max))) { - return FALSE; - } - *value = tmp; - return TRUE; + char * end; + unsigned long int tmp; + + if (!str || !str[0]) + return FALSE; + + /* FIXME: don't use this function, replace by _nm_utils_ascii_str_to_int64() */ + errno = 0; + tmp = strtoul(str, &end, base); + if (errno || *end != '\0' || (range_check && (tmp < min || tmp > max))) { + return FALSE; + } + *value = tmp; + return TRUE; } gboolean -nmc_string_to_uint (const char *str, - gboolean range_check, - unsigned long int min, - unsigned long int max, - unsigned long int *value) +nmc_string_to_uint(const char * str, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value) { - return nmc_string_to_uint_base (str, 10, range_check, min, max, value); + return nmc_string_to_uint_base(str, 10, range_check, min, max, value); } gboolean -nmc_string_to_bool (const char *str, gboolean *val_bool, GError **error) +nmc_string_to_bool(const char *str, gboolean *val_bool, GError **error) { - 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); - - if (g_strcmp0 (str, "o") == 0) { - g_set_error (error, 1, 0, - /* TRANSLATORS: the first %s is the partial value entered by - * the user, the second %s a list of compatible values. - */ - _("'%s' is ambiguous (%s)"), str, "on x off"); - return FALSE; - } - - if (nmc_string_is_valid (str, s_true, NULL)) - *val_bool = TRUE; - else if (nmc_string_is_valid (str, s_false, NULL)) - *val_bool = FALSE; - else { - g_set_error (error, 1, 0, - _("'%s' is not valid; use [%s] or [%s]"), - str, "true, yes, on", "false, no, off"); - return FALSE; - } - return TRUE; + 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); + + if (g_strcmp0(str, "o") == 0) { + g_set_error(error, + 1, + 0, + /* TRANSLATORS: the first %s is the partial value entered by + * the user, the second %s a list of compatible values. + */ + _("'%s' is ambiguous (%s)"), + str, + "on x off"); + return FALSE; + } + + if (nmc_string_is_valid(str, s_true, NULL)) + *val_bool = TRUE; + else if (nmc_string_is_valid(str, s_false, NULL)) + *val_bool = FALSE; + else { + g_set_error(error, + 1, + 0, + _("'%s' is not valid; use [%s] or [%s]"), + str, + "true, yes, on", + "false, no, off"); + return FALSE; + } + return TRUE; } gboolean -nmc_string_to_ternary (const char *str, NMTernary *val, GError **error) +nmc_string_to_ternary(const char *str, NMTernary *val, GError **error) { - const char *s_true[] = { "true", "yes", "on", NULL }; - const char *s_false[] = { "false", "no", "off", NULL }; - const char *s_unknown[] = { "unknown", NULL }; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (g_strcmp0 (str, "o") == 0) { - g_set_error (error, 1, 0, - /* TRANSLATORS: the first %s is the partial value entered by - * the user, the second %s a list of compatible values. - */ - _("'%s' is ambiguous (%s)"), str, "on x off"); - return FALSE; - } - - if (nmc_string_is_valid (str, s_true, NULL)) - *val = NM_TERNARY_TRUE; - else if (nmc_string_is_valid (str, s_false, NULL)) - *val = NM_TERNARY_FALSE; - else if (nmc_string_is_valid (str, s_unknown, NULL)) - *val = NM_TERNARY_DEFAULT; - else { - g_set_error (error, 1, 0, - _("'%s' is not valid; use [%s], [%s] or [%s]"), - str, "true, yes, on", "false, no, off", "unknown"); - return FALSE; - } - return TRUE; + const char *s_true[] = {"true", "yes", "on", NULL}; + const char *s_false[] = {"false", "no", "off", NULL}; + const char *s_unknown[] = {"unknown", NULL}; + + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + if (g_strcmp0(str, "o") == 0) { + g_set_error(error, + 1, + 0, + /* TRANSLATORS: the first %s is the partial value entered by + * the user, the second %s a list of compatible values. + */ + _("'%s' is ambiguous (%s)"), + str, + "on x off"); + return FALSE; + } + + if (nmc_string_is_valid(str, s_true, NULL)) + *val = NM_TERNARY_TRUE; + else if (nmc_string_is_valid(str, s_false, NULL)) + *val = NM_TERNARY_FALSE; + else if (nmc_string_is_valid(str, s_unknown, NULL)) + *val = NM_TERNARY_DEFAULT; + else { + g_set_error(error, + 1, + 0, + _("'%s' is not valid; use [%s], [%s] or [%s]"), + str, + "true, yes, on", + "false, no, off", + "unknown"); + return FALSE; + } + return TRUE; } /* @@ -163,349 +175,411 @@ nmc_string_to_ternary (const char *str, NMTernary *val, GError **error) * On failure: error->code : 0 - string not found; 1 - string is ambiguous */ const char * -nmc_string_is_valid (const char *input, const char **allowed, GError **error) +nmc_string_is_valid(const char *input, const char **allowed, GError **error) { - const char **p; - size_t input_ln, p_len; - const char *partial_match = NULL; - gboolean ambiguous = FALSE; - - g_return_val_if_fail (!error || !*error, NULL); - - if (!input || !*input) - goto finish; - - input_ln = strlen (input); - for (p = allowed; p && *p; p++) { - p_len = strlen (*p); - if (g_ascii_strncasecmp (input, *p, input_ln) == 0) { - if (input_ln == p_len) - return *p; - if (!partial_match) - partial_match = *p; - else - ambiguous = TRUE; - } - } - - if (ambiguous) { - GString *candidates = g_string_new (""); - - for (p = allowed; *p; p++) { - if (g_ascii_strncasecmp (input, *p, input_ln) == 0) { - if (candidates->len > 0) - g_string_append (candidates, ", "); - g_string_append (candidates, *p); - } - } - g_set_error (error, 1, 1, _("'%s' is ambiguous: %s"), - input, candidates->str); - g_string_free (candidates, TRUE); - return NULL; - } + const char **p; + size_t input_ln, p_len; + const char * partial_match = NULL; + gboolean ambiguous = FALSE; + + g_return_val_if_fail(!error || !*error, NULL); + + if (!input || !*input) + goto finish; + + input_ln = strlen(input); + for (p = allowed; p && *p; p++) { + p_len = strlen(*p); + if (g_ascii_strncasecmp(input, *p, input_ln) == 0) { + if (input_ln == p_len) + return *p; + if (!partial_match) + partial_match = *p; + else + ambiguous = TRUE; + } + } + + if (ambiguous) { + GString *candidates = g_string_new(""); + + for (p = allowed; *p; p++) { + if (g_ascii_strncasecmp(input, *p, input_ln) == 0) { + if (candidates->len > 0) + g_string_append(candidates, ", "); + g_string_append(candidates, *p); + } + } + g_set_error(error, 1, 1, _("'%s' is ambiguous: %s"), input, candidates->str); + g_string_free(candidates, TRUE); + return NULL; + } finish: - if (!partial_match) { - char *valid_vals = g_strjoinv (", ", (char **) allowed); + if (!partial_match) { + char *valid_vals = g_strjoinv(", ", (char **) allowed); - if (!input || !*input) - g_set_error (error, 1, 0, _("missing name, try one of [%s]"), valid_vals); - else - g_set_error (error, 1, 0, _("'%s' not among [%s]"), input, valid_vals); + if (!input || !*input) + g_set_error(error, 1, 0, _("missing name, try one of [%s]"), valid_vals); + else + g_set_error(error, 1, 0, _("'%s' not among [%s]"), input, valid_vals); - g_free (valid_vals); - } + g_free(valid_vals); + } - return partial_match; + return partial_match; } gboolean -matches (const char *cmd, const char *pattern) +matches(const char *cmd, const char *pattern) { - size_t len = strlen (cmd); - if (!len || len > strlen (pattern)) - return FALSE; - return memcmp (pattern, cmd, len) == 0; + size_t len = strlen(cmd); + if (!len || len > strlen(pattern)) + return FALSE; + return memcmp(pattern, cmd, len) == 0; } const char * -nmc_bond_validate_mode (const char *mode, GError **error) +nmc_bond_validate_mode(const char *mode, GError **error) { - unsigned long mode_int; - static const char *valid_modes[] = { "balance-rr", - "active-backup", - "balance-xor", - "broadcast", - "802.3ad", - "balance-tlb", - "balance-alb", - NULL }; - if (nmc_string_to_uint (mode, TRUE, 0, 6, &mode_int)) { - /* Translate bonding mode numbers to mode names: - * https://www.kernel.org/doc/Documentation/networking/bonding.txt - */ - return valid_modes[mode_int]; - } else - return nmc_string_is_valid (mode, valid_modes, error); + unsigned long mode_int; + static const char *valid_modes[] = {"balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + NULL}; + if (nmc_string_to_uint(mode, TRUE, 0, 6, &mode_int)) { + /* Translate bonding mode numbers to mode names: + * https://www.kernel.org/doc/Documentation/networking/bonding.txt + */ + return valid_modes[mode_int]; + } else + return nmc_string_is_valid(mode, valid_modes, error); } -NM_UTILS_LOOKUP_STR_DEFINE (nmc_device_state_to_string, NMDeviceState, - NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_UNMANAGED, N_("unmanaged")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_UNAVAILABLE, N_("unavailable")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_DISCONNECTED, N_("disconnected")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_PREPARE, N_("connecting (prepare)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_CONFIG, N_("connecting (configuring)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_NEED_AUTH, N_("connecting (need authentication)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_IP_CONFIG, N_("connecting (getting IP configuration)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_IP_CHECK, N_("connecting (checking IP connectivity)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_SECONDARIES, N_("connecting (starting secondary connections)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_ACTIVATED, N_("connected")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_DEACTIVATING, N_("deactivating")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_FAILED, N_("connection failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_UNKNOWN, N_("unknown")), -) - -static -NM_UTILS_LOOKUP_STR_DEFINE (_device_state_to_string, NMDeviceState, - NM_UTILS_LOOKUP_DEFAULT (NULL), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_PREPARE, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_CONFIG, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_NEED_AUTH, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_IP_CONFIG, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_IP_CHECK, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_SECONDARIES, N_("connecting (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_ACTIVATED, N_("connected (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_DEACTIVATING, N_("deactivating (externally)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_FAILED, N_("deactivating (externally)")), - NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (), -) +NM_UTILS_LOOKUP_STR_DEFINE( + nmc_device_state_to_string, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(N_("unknown")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNMANAGED, N_("unmanaged")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNAVAILABLE, N_("unavailable")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DISCONNECTED, N_("disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_PREPARE, N_("connecting (prepare)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_CONFIG, N_("connecting (configuring)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_NEED_AUTH, N_("connecting (need authentication)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CONFIG, N_("connecting (getting IP configuration)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CHECK, N_("connecting (checking IP connectivity)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_SECONDARIES, + N_("connecting (starting secondary connections)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_ACTIVATED, N_("connected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DEACTIVATING, N_("deactivating")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_FAILED, N_("connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNKNOWN, N_("unknown")), ); + +static NM_UTILS_LOOKUP_STR_DEFINE( + _device_state_to_string, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_PREPARE, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_CONFIG, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_NEED_AUTH, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CONFIG, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CHECK, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_SECONDARIES, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_ACTIVATED, N_("connected (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DEACTIVATING, N_("deactivating (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_FAILED, N_("deactivating (externally)")), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER(), ); const char * -nmc_device_state_to_string_with_external (NMDevice *device) +nmc_device_state_to_string_with_external(NMDevice *device) { - NMActiveConnection *ac; - NMDeviceState state; - const char *s; + NMActiveConnection *ac; + NMDeviceState state; + const char * s; - state = nm_device_get_state (device); + state = nm_device_get_state(device); - if ( (ac = nm_device_get_active_connection (device)) - && NM_FLAGS_HAS (nm_active_connection_get_state_flags (ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL) - && (s = _device_state_to_string (state))) - return s; + if ((ac = nm_device_get_active_connection(device)) + && NM_FLAGS_HAS(nm_active_connection_get_state_flags(ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL) + && (s = _device_state_to_string(state))) + return s; - return nmc_device_state_to_string (state); + return nmc_device_state_to_string(state); } -NM_UTILS_LOOKUP_STR_DEFINE (nmc_device_metered_to_string, NMMetered, - NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), - NM_UTILS_LOOKUP_ITEM (NM_METERED_YES, N_("yes")), - NM_UTILS_LOOKUP_ITEM (NM_METERED_NO, N_("no")), - NM_UTILS_LOOKUP_ITEM (NM_METERED_GUESS_YES, N_("yes (guessed)")), - NM_UTILS_LOOKUP_ITEM (NM_METERED_GUESS_NO, N_("no (guessed)")), - NM_UTILS_LOOKUP_ITEM (NM_METERED_UNKNOWN, N_("unknown")), -) - -NM_UTILS_LOOKUP_STR_DEFINE (nmc_device_reason_to_string, NMDeviceStateReason, - /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ - NM_UTILS_LOOKUP_DEFAULT (N_("Unknown")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_NONE, N_("No reason given")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_UNKNOWN, N_("Unknown error")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_NOW_MANAGED, N_("Device is now managed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_NOW_UNMANAGED, N_("Device is now unmanaged")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_CONFIG_FAILED, N_("The device could not be readied for configuration")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, N_("IP configuration could not be reserved (no available address, timeout, etc.)")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, N_("The IP configuration is no longer valid")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_NO_SECRETS, N_("Secrets were required, but not provided")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, N_("802.1X supplicant disconnected")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, N_("802.1X supplicant configuration failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, N_("802.1X supplicant failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, N_("802.1X supplicant took too long to authenticate")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PPP_START_FAILED, N_("PPP service failed to start")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PPP_DISCONNECT, N_("PPP service disconnected")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PPP_FAILED, N_("PPP failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_DHCP_START_FAILED, N_("DHCP client failed to start")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_DHCP_ERROR, N_("DHCP client error")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_DHCP_FAILED, N_("DHCP client failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SHARED_START_FAILED, N_("Shared connection service failed to start")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SHARED_FAILED, N_("Shared connection service failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, N_("AutoIP service failed to start")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_ERROR, N_("AutoIP service error")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_FAILED, N_("AutoIP service failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_BUSY, N_("The line is busy")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, N_("No dial tone")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, N_("No carrier could be established")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, N_("The dialing request timed out")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, N_("The dialing attempt failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, N_("Modem initialization failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_APN_FAILED, N_("Failed to select the specified APN")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, N_("Not searching for networks")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, N_("Network registration denied")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, N_("Network registration timed out")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, N_("Failed to register with the requested network")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, N_("PIN check failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, N_("Necessary firmware for the device may be missing")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_REMOVED, N_("The device was removed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SLEEPING, N_("NetworkManager went to sleep")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, N_("The device's active connection disappeared")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_USER_REQUESTED, N_("Device disconnected by user or client")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_CARRIER, N_("Carrier/link changed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, N_("The device's existing connection was assumed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, N_("The supplicant is now available")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, N_("The modem could not be found")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_BT_FAILED, N_("The Bluetooth connection failed or timed out")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, N_("GSM Modem's SIM card not inserted")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, N_("GSM Modem's SIM PIN required")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, N_("GSM Modem's SIM PUK required")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, N_("GSM Modem's SIM wrong")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_INFINIBAND_MODE, N_("InfiniBand device does not support connected mode")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, N_("A dependency of the connection failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_BR2684_FAILED, N_("A problem with the RFC 2684 Ethernet over ADSL bridge")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, N_("ModemManager is unavailable")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, N_("The Wi-Fi network could not be found")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, N_("A secondary connection of the base connection failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, N_("DCB or FCoE setup failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, N_("teamd control failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_FAILED, N_("Modem failed or no longer available")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, N_("Modem now ready and available")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, N_("SIM PIN was incorrect")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_NEW_ACTIVATION, N_("New connection activation was enqueued")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PARENT_CHANGED, N_("The device's parent changed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, N_("The device parent's management changed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_OVSDB_FAILED, N_("Open vSwitch database connection failed")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, N_("A duplicate IP address was detected")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, N_("The selected IP method is not supported")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, N_("Failed to configure SR-IOV parameters")), - NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, N_("The Wi-Fi P2P peer could not be found")), -) - -NM_UTILS_LOOKUP_STR_DEFINE (nm_active_connection_state_reason_to_string, NMActiveConnectionStateReason, - /* TRANSLATORS: Unknown reason for a connection state change (NMActiveConnectionStateReason) */ - NM_UTILS_LOOKUP_DEFAULT (N_("Unknown")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, N_("Unknown reason")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_NONE, N_("The connection was disconnected")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED, N_("Disconnected by user")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, N_("The base network connection was interrupted")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED, N_("The VPN service stopped unexpectedly")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, N_("The VPN service returned invalid configuration")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, N_("The connection attempt timed out")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, N_("The VPN service did not start in time")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, N_("The VPN service failed to start")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, N_("No valid secrets")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED, N_("Invalid secrets")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED, N_("The connection was removed")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED, N_("Master connection failed")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED, N_("Could not create a software link")), - NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED, N_("The device disappeared")), -) +NM_UTILS_LOOKUP_STR_DEFINE(nmc_device_metered_to_string, + NMMetered, + NM_UTILS_LOOKUP_DEFAULT(N_("unknown")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_YES, N_("yes")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_NO, N_("no")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_GUESS_YES, N_("yes (guessed)")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_GUESS_NO, N_("no (guessed)")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_UNKNOWN, N_("unknown")), ); + +NM_UTILS_LOOKUP_STR_DEFINE( + nmc_device_reason_to_string, + NMDeviceStateReason, + /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ + NM_UTILS_LOOKUP_DEFAULT(N_("Unknown")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NONE, N_("No reason given")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, N_("Unknown error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, N_("Device is now managed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, N_("Device is now unmanaged")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, + N_("The device could not be readied for configuration")), + NM_UTILS_LOOKUP_ITEM( + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, + N_("IP configuration could not be reserved (no available address, timeout, etc.)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, + N_("The IP configuration is no longer valid")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, + N_("Secrets were required, but not provided")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, + N_("802.1X supplicant disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, + N_("802.1X supplicant configuration failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, N_("802.1X supplicant failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, + N_("802.1X supplicant took too long to authenticate")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, + N_("PPP service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, N_("PPP service disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, N_("PPP failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, + N_("DHCP client failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, N_("DHCP client error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, N_("DHCP client failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, + N_("Shared connection service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, + N_("Shared connection service failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, + N_("AutoIP service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, N_("AutoIP service error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, N_("AutoIP service failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, N_("The line is busy")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, N_("No dial tone")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, + N_("No carrier could be established")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, + N_("The dialing request timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, + N_("The dialing attempt failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, + N_("Modem initialization failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, + N_("Failed to select the specified APN")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, + N_("Not searching for networks")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, + N_("Network registration denied")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, + N_("Network registration timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, + N_("Failed to register with the requested network")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, N_("PIN check failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, + N_("Necessary firmware for the device may be missing")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_REMOVED, N_("The device was removed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, N_("NetworkManager went to sleep")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, + N_("The device's active connection disappeared")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, + N_("Device disconnected by user or client")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CARRIER, N_("Carrier/link changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, + N_("The device's existing connection was assumed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + N_("The supplicant is now available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, + N_("The modem could not be found")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, + N_("The Bluetooth connection failed or timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, + N_("GSM Modem's SIM card not inserted")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, + N_("GSM Modem's SIM PIN required")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, + N_("GSM Modem's SIM PUK required")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, N_("GSM Modem's SIM wrong")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, + N_("InfiniBand device does not support connected mode")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, + N_("A dependency of the connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, + N_("A problem with the RFC 2684 Ethernet over ADSL bridge")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, + N_("ModemManager is unavailable")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, + N_("The Wi-Fi network could not be found")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, + N_("A secondary connection of the base connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, N_("DCB or FCoE setup failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, N_("teamd control failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, + N_("Modem failed or no longer available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, + N_("Modem now ready and available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, N_("SIM PIN was incorrect")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, + N_("New connection activation was enqueued")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, N_("The device's parent changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, + N_("The device parent's management changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, + N_("Open vSwitch database connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, + N_("A duplicate IP address was detected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, + N_("The selected IP method is not supported")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, + N_("Failed to configure SR-IOV parameters")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, + N_("The Wi-Fi P2P peer could not be found")), ); + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_active_connection_state_reason_to_string, + NMActiveConnectionStateReason, + /* TRANSLATORS: Unknown reason for a connection state change (NMActiveConnectionStateReason) */ + NM_UTILS_LOOKUP_DEFAULT(N_("Unknown")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, N_("Unknown reason")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_NONE, + N_("The connection was disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED, + N_("Disconnected by user")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, + N_("The base network connection was interrupted")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED, + N_("The VPN service stopped unexpectedly")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, + N_("The VPN service returned invalid configuration")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, + N_("The connection attempt timed out")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, + N_("The VPN service did not start in time")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, + N_("The VPN service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, N_("No valid secrets")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED, N_("Invalid secrets")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED, + N_("The connection was removed")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED, + N_("Master connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED, + N_("Could not create a software link")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED, + N_("The device disappeared")), ); NMActiveConnectionState -nmc_activation_get_effective_state (NMActiveConnection *active, - NMDevice *device, - const char **reason) +nmc_activation_get_effective_state(NMActiveConnection *active, + NMDevice * device, + const char ** reason) { - NMActiveConnectionState ac_state; - NMActiveConnectionStateReason ac_reason; - NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN; - NMDeviceStateReason dev_reason = NM_DEVICE_STATE_REASON_UNKNOWN; - - g_return_val_if_fail (active, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); - g_return_val_if_fail (reason, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); - - *reason = NULL; - ac_reason = nm_active_connection_get_state_reason (active); - - if (device) { - dev_state = nm_device_get_state (device); - dev_reason = nm_device_get_state_reason (device); - } - - ac_state = nm_active_connection_get_state (active); - switch (ac_state) { - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: - if ( !device - || ac_reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED - || nm_device_get_active_connection (device) != active) { - /* (1) - * - we have no device, - * - or, @ac_reason is specific - * - or, @device no longer references the current @active - * >> we complete with @ac_reason. */ - *reason = gettext (nm_active_connection_state_reason_to_string (ac_reason)); - } else if ( dev_state <= NM_DEVICE_STATE_DISCONNECTED - || dev_state >= NM_DEVICE_STATE_FAILED) { - /* (2) - * - not (1) - * - and, the device is no longer in an activated state, - * >> we complete with @dev_reason. */ - *reason = gettext (nmc_device_reason_to_string (dev_reason)); - } else { - /* (3) - * we wait for the device go disconnect. We will get a better - * failure reason from the device (2). */ - return NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - } - break; - case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: - /* activating master connection does not automatically activate any slaves, so their - * active connection state will not progress beyond ACTIVATING state. - * Monitor the device instead. */ - if ( device - && ( NM_IS_DEVICE_BOND (device) - || NM_IS_DEVICE_TEAM (device) - || NM_IS_DEVICE_BRIDGE (device)) - && dev_state >= NM_DEVICE_STATE_IP_CONFIG - && dev_state <= NM_DEVICE_STATE_ACTIVATED) { - *reason = "master waiting for slaves"; - return NM_ACTIVE_CONNECTION_STATE_ACTIVATED; - } - break; - default: - break; - } - - return ac_state; + NMActiveConnectionState ac_state; + NMActiveConnectionStateReason ac_reason; + NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN; + NMDeviceStateReason dev_reason = NM_DEVICE_STATE_REASON_UNKNOWN; + + g_return_val_if_fail(active, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + g_return_val_if_fail(reason, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + + *reason = NULL; + ac_reason = nm_active_connection_get_state_reason(active); + + if (device) { + dev_state = nm_device_get_state(device); + dev_reason = nm_device_get_state_reason(device); + } + + ac_state = nm_active_connection_get_state(active); + switch (ac_state) { + case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: + if (!device || ac_reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED + || nm_device_get_active_connection(device) != active) { + /* (1) + * - we have no device, + * - or, @ac_reason is specific + * - or, @device no longer references the current @active + * >> we complete with @ac_reason. */ + *reason = gettext(nm_active_connection_state_reason_to_string(ac_reason)); + } else if (dev_state <= NM_DEVICE_STATE_DISCONNECTED + || dev_state >= NM_DEVICE_STATE_FAILED) { + /* (2) + * - not (1) + * - and, the device is no longer in an activated state, + * >> we complete with @dev_reason. */ + *reason = gettext(nmc_device_reason_to_string(dev_reason)); + } else { + /* (3) + * we wait for the device go disconnect. We will get a better + * failure reason from the device (2). */ + return NM_ACTIVE_CONNECTION_STATE_UNKNOWN; + } + break; + case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: + /* activating master connection does not automatically activate any slaves, so their + * active connection state will not progress beyond ACTIVATING state. + * Monitor the device instead. */ + if (device + && (NM_IS_DEVICE_BOND(device) || NM_IS_DEVICE_TEAM(device) + || NM_IS_DEVICE_BRIDGE(device)) + && dev_state >= NM_DEVICE_STATE_IP_CONFIG && dev_state <= NM_DEVICE_STATE_ACTIVATED) { + *reason = "master waiting for slaves"; + return NM_ACTIVE_CONNECTION_STATE_ACTIVATED; + } + break; + default: + break; + } + + return ac_state; } static gboolean -can_show_utf8 (void) +can_show_utf8(void) { - static gboolean can_show_utf8_set = FALSE; - static gboolean can_show_utf8 = TRUE; - char *locale_str; - - if (G_LIKELY (can_show_utf8_set)) - return can_show_utf8; - - if (!g_get_charset (NULL)) { - /* Non-UTF-8 locale */ - locale_str = g_locale_from_utf8 ("\342\226\202\342\226\204\342\226\206\342\226\210", -1, NULL, NULL, NULL); - if (locale_str) - g_free (locale_str); - else - can_show_utf8 = FALSE; - } - - return can_show_utf8; + static gboolean can_show_utf8_set = FALSE; + static gboolean can_show_utf8 = TRUE; + char * locale_str; + + if (G_LIKELY(can_show_utf8_set)) + return can_show_utf8; + + if (!g_get_charset(NULL)) { + /* Non-UTF-8 locale */ + locale_str = g_locale_from_utf8("\342\226\202\342\226\204\342\226\206\342\226\210", + -1, + NULL, + NULL, + NULL); + if (locale_str) + g_free(locale_str); + else + can_show_utf8 = FALSE; + } + + return can_show_utf8; } - static gboolean -can_show_graphics (void) +can_show_graphics(void) { - static gboolean can_show_graphics_set = FALSE; - static gboolean can_show_graphics = TRUE; + static gboolean can_show_graphics_set = FALSE; + static gboolean can_show_graphics = TRUE; - if (G_LIKELY (can_show_graphics_set)) - return can_show_graphics; + if (G_LIKELY(can_show_graphics_set)) + return can_show_graphics; - can_show_graphics = can_show_utf8 (); + can_show_graphics = can_show_utf8(); - /* The linux console font typically doesn't have characters we need */ - if (g_strcmp0 (g_getenv ("TERM"), "linux") == 0) - can_show_graphics = FALSE; + /* The linux console font typically doesn't have characters we need */ + if (g_strcmp0(g_getenv("TERM"), "linux") == 0) + can_show_graphics = FALSE; - return can_show_graphics; + return can_show_graphics; } /** @@ -515,26 +589,26 @@ can_show_graphics (void) * Converts @strength into a 4-character-wide graphical representation of * strength suitable for printing to stdout. If the current locale and terminal * support it, this will use unicode graphics characters to represent - * "bars". Otherwise it will use 0 to 4 asterisks. + * "bars". Otherwise, it will use 0 to 4 asterisks. * * Returns: the graphical representation of the access point strength */ const char * -nmc_wifi_strength_bars (guint8 strength) +nmc_wifi_strength_bars(guint8 strength) { - if (!can_show_graphics ()) - return nm_utils_wifi_strength_bars (strength); - - if (strength > 80) - return /* ▂▄▆█ */ "\342\226\202\342\226\204\342\226\206\342\226\210"; - else if (strength > 55) - return /* ▂▄▆_ */ "\342\226\202\342\226\204\342\226\206_"; - else if (strength > 30) - return /* ▂▄__ */ "\342\226\202\342\226\204__"; - else if (strength > 5) - return /* ▂___ */ "\342\226\202___"; - else - return /* ____ */ "____"; + if (!can_show_graphics()) + return nm_utils_wifi_strength_bars(strength); + + if (strength > 80) + return /* ▂▄▆█ */ "\342\226\202\342\226\204\342\226\206\342\226\210"; + else if (strength > 55) + return /* ▂▄▆_ */ "\342\226\202\342\226\204\342\226\206_"; + else if (strength > 30) + return /* ▂▄__ */ "\342\226\202\342\226\204__"; + else if (strength > 5) + return /* ▂___ */ "\342\226\202___"; + else + return /* ____ */ "____"; } /** @@ -543,12 +617,12 @@ nmc_wifi_strength_bars (guint8 strength) * Returns: the string substituted when hiding actual password glyphs */ const char * -nmc_password_subst_char (void) +nmc_password_subst_char(void) { - if (can_show_graphics ()) - return "\u2022"; /* Bullet */ - else - return "*"; + if (can_show_graphics()) + return "\u2022"; /* Bullet */ + else + return "*"; } /* @@ -566,60 +640,59 @@ NM_PRAGMA_WARNING_REENABLE #pragma GCC visibility pop void -nmc_print_qrcode (const char *str) +nmc_print_qrcode(const char *str) { - uint8_t tempBuffer[qrcodegen_BUFFER_LEN_FOR_VERSION (qrcodegen_VERSION_MAX)]; - uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION (qrcodegen_VERSION_MAX)]; - gboolean term_linux; - int size; - int x; - int y; - - term_linux = g_strcmp0 (g_getenv ("TERM"), "linux") == 0; - if (!term_linux && !can_show_graphics ()) - return; - - if (!qrcodegen_encodeText (str, - tempBuffer, - qrcode, - qrcodegen_Ecc_LOW, - qrcodegen_VERSION_MIN, - qrcodegen_VERSION_MAX, - qrcodegen_Mask_AUTO, - FALSE)) { - return; - } - - size = qrcodegen_getSize (qrcode); - - g_print ("\n"); - - if (term_linux) { - /* G1 alternate character set on Linux console. */ - for (y = -1; y < size + 1; y += 1) { - g_print (" \033[37;40;1m\016"); - for (x = -1; x < size + 1; x++) { - g_print ( qrcodegen_getModule (qrcode, x, y) - ? " " : "\060\060"); - } - g_print ("\017\033[0m\n"); - } - } else { - /* UTF-8 */ - for (y = -2; y < size + 2; y += 2) { - g_print (" \033[37;40m"); - for (x = -2; x < size + 2; x++) { - bool top = qrcodegen_getModule (qrcode, x, y); - bool bottom = qrcodegen_getModule (qrcode, x, y + 1); - if (top) { - g_print (bottom ? " " : "\u2584"); - } else { - g_print (bottom ? "\u2580" : "\u2588"); - } - } - g_print ("\033[0m\n"); - } - } + uint8_t tempBuffer[qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)]; + uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)]; + gboolean term_linux; + int size; + int x; + int y; + + term_linux = g_strcmp0(g_getenv("TERM"), "linux") == 0; + if (!term_linux && !can_show_graphics()) + return; + + if (!qrcodegen_encodeText(str, + tempBuffer, + qrcode, + qrcodegen_Ecc_LOW, + qrcodegen_VERSION_MIN, + qrcodegen_VERSION_MAX, + qrcodegen_Mask_AUTO, + FALSE)) { + return; + } + + size = qrcodegen_getSize(qrcode); + + g_print("\n"); + + if (term_linux) { + /* G1 alternate character set on Linux console. */ + for (y = -1; y < size + 1; y += 1) { + g_print(" \033[37;40;1m\016"); + for (x = -1; x < size + 1; x++) { + g_print(qrcodegen_getModule(qrcode, x, y) ? " " : "\060\060"); + } + g_print("\017\033[0m\n"); + } + } else { + /* UTF-8 */ + for (y = -2; y < size + 2; y += 2) { + g_print(" \033[37;40m"); + for (x = -2; x < size + 2; x++) { + bool top = qrcodegen_getModule(qrcode, x, y); + bool bottom = qrcodegen_getModule(qrcode, x, y + 1); + if (top) { + g_print(bottom ? " " : "\u2584"); + } else { + g_print(bottom ? "\u2580" : "\u2588"); + } + } + g_print("\033[0m\n"); + } + } } /** @@ -638,173 +711,176 @@ nmc_print_qrcode (const char *str) * Returns: (transfer full): hash table with parsed passwords, or %NULL on an error */ GHashTable * -nmc_utils_read_passwd_file (const char *passwd_file, - gssize *out_error_line, - GError **error) +nmc_utils_read_passwd_file(const char *passwd_file, gssize *out_error_line, GError **error) { - nm_auto_clear_secret_ptr NMSecretPtr contents = { 0 }; - - NM_SET_OUT (out_error_line, -1); - - if (!passwd_file) - return g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); - - if (!nm_utils_file_get_contents (-1, - passwd_file, - 1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, - &contents.str, - &contents.len, - NULL, - error)) - return NULL; - - return nmc_utils_parse_passwd_file (contents.str, out_error_line, error); + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + NM_SET_OUT(out_error_line, -1); + + if (!passwd_file) + return g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) nm_free_secret); + + if (!nm_utils_file_get_contents(-1, + passwd_file, + 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &contents.str, + &contents.len, + NULL, + error)) + return NULL; + + return nmc_utils_parse_passwd_file(contents.str, out_error_line, error); } GHashTable * -nmc_utils_parse_passwd_file (char *contents /* will be modified */, - gssize *out_error_line, - GError **error) +nmc_utils_parse_passwd_file(char * contents /* will be modified */, + gssize * out_error_line, + GError **error) { - gs_unref_hashtable GHashTable *pwds_hash = NULL; - const char *contents_str; - gsize contents_line; - - pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); - - NM_SET_OUT (out_error_line, -1); - - contents_str = contents; - contents_line = 0; - while (contents_str[0]) { - nm_auto_free_secret char *l_hash_key = NULL; - nm_auto_free_secret char *l_hash_val = NULL; - const char *l_content_line; - const char *l_setting; - const char *l_prop; - const char *l_val; - const char *s; - gsize l_hash_val_len; - - /* consume first line. As line delimiters we accept "\r\n", "\n", and "\r". */ - l_content_line = contents_str; - s = l_content_line; - while (!NM_IN_SET (s[0], '\0', '\r', '\n')) - s++; - if (s[0] != '\0') { - if ( s[0] == '\r' - && s[1] == '\n') { - ((char *) s)[0] = '\0'; - s += 2; - } else { - ((char *) s)[0] = '\0'; - s += 1; - } - } - contents_str = s; - contents_line++; - - l_content_line = nm_str_skip_leading_spaces (l_content_line); - if (NM_IN_SET (l_content_line[0], '\0', '#')) { - /* a comment or empty line. Ignore. */ - continue; - } - - l_setting = l_content_line; - - s = l_setting; - while (!NM_IN_SET (s[0], '\0', ':', '=')) - s++; - if (s[0] == '\0') { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing colon for \".:\" format")); - return NULL; - } - ((char *) s)[0] = '\0'; - s++; - - l_val = s; - - g_strchomp ((char *) l_setting); - - nm_assert (nm_str_is_stripped (l_setting)); - - s = strchr (l_setting, '.'); - if (!s) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing dot for \".:\" format")); - return NULL; - } else if (s == l_setting) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing setting for \".:\" format")); - return NULL; - } - ((char *) s)[0] = '\0'; - s++; - - l_prop = s; - if (l_prop[0] == '\0') { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing property for \".:\" format")); - return NULL; - } - - /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ - if (NM_IN_STRSET (l_setting, "wifi-sec", "wifi")) - l_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - - if (nm_setting_lookup_type (l_setting) == G_TYPE_INVALID) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("invalid setting name")); - return NULL; - } - - if ( nm_streq (l_setting, "vpn") - && NM_STR_HAS_PREFIX (l_prop, "secret.")) { - /* in 1.12.0, we wrongly required the VPN secrets to be named - * "vpn.secret". It should be "vpn.secrets". Work around it - * (rh#1628833). */ - l_hash_key = g_strdup_printf ("vpn.secrets.%s", &l_prop[NM_STRLEN ("secret.")]); - } else - l_hash_key = g_strdup_printf ("%s.%s", l_setting, l_prop); - - if (!g_utf8_validate (l_hash_key, -1, NULL)) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("property name is not UTF-8")); - return NULL; - } - - /* Support backslash escaping in the secret value. We strip non-escaped leading/trailing whitespaces. */ - s = nm_utils_buf_utf8safe_unescape (l_val, NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES, &l_hash_val_len, (gpointer *) &l_hash_val); - if (!l_hash_val) - l_hash_val = g_strdup (s); - - if (!g_utf8_validate (l_hash_val, -1, NULL)) { - /* In some cases it might make sense to support binary secrets (like the WPA-PSK which has no - * defined encoding. However, all API that follows can only handle UTF-8, and no mechanism - * to escape the secrets. Reject non-UTF-8 early. */ - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("secret is not UTF-8")); - return NULL; - } - - if (strlen (l_hash_val) != l_hash_val_len) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("secret is not UTF-8")); - return NULL; - } - - g_hash_table_insert (pwds_hash, g_steal_pointer (&l_hash_key), g_steal_pointer (&l_hash_val)); - } - - return g_steal_pointer (&pwds_hash); + gs_unref_hashtable GHashTable *pwds_hash = NULL; + const char * contents_str; + gsize contents_line; + + pwds_hash = + g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); + + NM_SET_OUT(out_error_line, -1); + + contents_str = contents; + contents_line = 0; + while (contents_str[0]) { + nm_auto_free_secret char *l_hash_key = NULL; + nm_auto_free_secret char *l_hash_val = NULL; + const char * l_content_line; + const char * l_setting; + const char * l_prop; + const char * l_val; + const char * s; + gsize l_hash_val_len; + + /* consume first line. As line delimiters we accept "\r\n", "\n", and "\r". */ + l_content_line = contents_str; + s = l_content_line; + while (!NM_IN_SET(s[0], '\0', '\r', '\n')) + s++; + if (s[0] != '\0') { + if (s[0] == '\r' && s[1] == '\n') { + ((char *) s)[0] = '\0'; + s += 2; + } else { + ((char *) s)[0] = '\0'; + s += 1; + } + } + contents_str = s; + contents_line++; + + l_content_line = nm_str_skip_leading_spaces(l_content_line); + if (NM_IN_SET(l_content_line[0], '\0', '#')) { + /* a comment or empty line. Ignore. */ + continue; + } + + l_setting = l_content_line; + + s = l_setting; + while (!NM_IN_SET(s[0], '\0', ':', '=')) + s++; + if (s[0] == '\0') { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing colon for \".:\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_val = s; + + g_strchomp((char *) l_setting); + + nm_assert(nm_str_is_stripped(l_setting)); + + s = strchr(l_setting, '.'); + if (!s) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing dot for \".:\" format")); + return NULL; + } else if (s == l_setting) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing setting for \".:\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_prop = s; + if (l_prop[0] == '\0') { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing property for \".:\" format")); + return NULL; + } + + /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ + if (NM_IN_STRSET(l_setting, "wifi-sec", "wifi")) + l_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + + if (nm_setting_lookup_type(l_setting) == G_TYPE_INVALID) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("invalid setting name")); + return NULL; + } + + if (nm_streq(l_setting, "vpn") && NM_STR_HAS_PREFIX(l_prop, "secret.")) { + /* in 1.12.0, we wrongly required the VPN secrets to be named + * "vpn.secret". It should be "vpn.secrets". Work around it + * (rh#1628833). */ + l_hash_key = g_strdup_printf("vpn.secrets.%s", &l_prop[NM_STRLEN("secret.")]); + } else + l_hash_key = g_strdup_printf("%s.%s", l_setting, l_prop); + + if (!g_utf8_validate(l_hash_key, -1, NULL)) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("property name is not UTF-8")); + return NULL; + } + + /* Support backslash escaping in the secret value. We strip non-escaped leading/trailing whitespaces. */ + s = nm_utils_buf_utf8safe_unescape(l_val, + NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES, + &l_hash_val_len, + (gpointer *) &l_hash_val); + if (!l_hash_val) + l_hash_val = g_strdup(s); + + if (!g_utf8_validate(l_hash_val, -1, NULL)) { + /* In some cases it might make sense to support binary secrets (like the WPA-PSK which has no + * defined encoding. However, all API that follows can only handle UTF-8, and no mechanism + * to escape the secrets. Reject non-UTF-8 early. */ + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("secret is not UTF-8")); + return NULL; + } + + if (strlen(l_hash_val) != l_hash_val_len) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("secret is not UTF-8")); + return NULL; + } + + g_hash_table_insert(pwds_hash, g_steal_pointer(&l_hash_key), g_steal_pointer(&l_hash_val)); + } + + return g_steal_pointer(&pwds_hash); } diff --git a/clients/common/nm-client-utils.h b/clients/common/nm-client-utils.h index 28eac457..540177a7 100644 --- a/clients/common/nm-client-utils.h +++ b/clients/common/nm-client-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2017 Red Hat, Inc. */ @@ -11,46 +11,43 @@ #include "nm-device.h" #include "nm-libnm-core-intern/nm-libnm-core-utils.h" -const NMObject **nmc_objects_sort_by_path (const NMObject *const*objs, gssize len); +const NMObject **nmc_objects_sort_by_path(const NMObject *const *objs, gssize len); -const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error); +const char *nmc_string_is_valid(const char *input, const char **allowed, GError **error); -gboolean nmc_string_to_uint (const char *str, - gboolean range_check, - unsigned long int min, - unsigned long int max, - unsigned long int *value); -gboolean nmc_string_to_bool (const char *str, gboolean *val_bool, GError **error); -gboolean nmc_string_to_ternary (const char *str, NMTernary *val, GError **error); +gboolean nmc_string_to_uint(const char * str, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value); +gboolean nmc_string_to_bool(const char *str, gboolean *val_bool, GError **error); +gboolean nmc_string_to_ternary(const char *str, NMTernary *val, GError **error); -gboolean matches (const char *cmd, const char *pattern); +gboolean matches(const char *cmd, const char *pattern); /* FIXME: don't expose this function on its own, at least not from this file. */ -const char *nmc_bond_validate_mode (const char *mode, GError **error); +const char *nmc_bond_validate_mode(const char *mode, GError **error); -const char *nmc_device_state_to_string_with_external (NMDevice *device); +const char *nmc_device_state_to_string_with_external(NMDevice *device); -const char *nm_active_connection_state_reason_to_string (NMActiveConnectionStateReason reason); -const char *nmc_device_state_to_string (NMDeviceState state); -const char *nmc_device_reason_to_string (NMDeviceStateReason reason); -const char *nmc_device_metered_to_string (NMMetered value); +const char *nm_active_connection_state_reason_to_string(NMActiveConnectionStateReason reason); +const char *nmc_device_state_to_string(NMDeviceState state); +const char *nmc_device_reason_to_string(NMDeviceStateReason reason); +const char *nmc_device_metered_to_string(NMMetered value); -NMActiveConnectionState nmc_activation_get_effective_state (NMActiveConnection *active, - NMDevice *device, - const char **reason); +NMActiveConnectionState nmc_activation_get_effective_state(NMActiveConnection *active, + NMDevice * device, + const char ** reason); -const char *nmc_wifi_strength_bars (guint8 strength); +const char *nmc_wifi_strength_bars(guint8 strength); -const char *nmc_password_subst_char (void); +const char *nmc_password_subst_char(void); -void nmc_print_qrcode (const char *str); +void nmc_print_qrcode(const char *str); -GHashTable *nmc_utils_parse_passwd_file (char *contents, - gssize *out_error_line, - GError **error); +GHashTable *nmc_utils_parse_passwd_file(char *contents, gssize *out_error_line, GError **error); -GHashTable *nmc_utils_read_passwd_file (const char *passwd_file, - gssize *out_error_line, - GError **error); +GHashTable * +nmc_utils_read_passwd_file(const char *passwd_file, gssize *out_error_line, GError **error); #endif /* __NM_CLIENT_UTILS_H__ */ diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 1167b555..2278078e 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2017 Red Hat, Inc. */ @@ -10,623 +10,644 @@ /*****************************************************************************/ static const NMMetaSettingInfoEditor * -_get_meta_setting_info_editor_from_msi (const NMMetaSettingInfo *meta_setting_info) +_get_meta_setting_info_editor_from_msi(const NMMetaSettingInfo *meta_setting_info) { - const NMMetaSettingInfoEditor *setting_info; + const NMMetaSettingInfoEditor *setting_info; - if (!meta_setting_info) - return NULL; + if (!meta_setting_info) + return NULL; - nm_assert (meta_setting_info->get_setting_gtype); - nm_assert (meta_setting_info->meta_type < G_N_ELEMENTS (nm_meta_setting_infos_editor)); + nm_assert(meta_setting_info->get_setting_gtype); + nm_assert(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]; + setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; - nm_assert (setting_info->general == meta_setting_info); - return setting_info; + nm_assert(setting_info->general == meta_setting_info); + return setting_info; } const NMMetaSettingInfoEditor * -nm_meta_setting_info_editor_find_by_name (const char *setting_name, gboolean use_alias) +nm_meta_setting_info_editor_find_by_name(const char *setting_name, gboolean use_alias) { - const NMMetaSettingInfoEditor *setting_info; - guint i; - - g_return_val_if_fail (setting_name, NULL); - - setting_info = _get_meta_setting_info_editor_from_msi (nm_meta_setting_infos_by_name (setting_name)); - 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; + const NMMetaSettingInfoEditor *setting_info; + guint i; + + g_return_val_if_fail(setting_name, NULL); + + setting_info = + _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_name(setting_name)); + 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; } const NMMetaSettingInfoEditor * -nm_meta_setting_info_editor_find_by_gtype (GType gtype) +nm_meta_setting_info_editor_find_by_gtype(GType gtype) { - return _get_meta_setting_info_editor_from_msi (nm_meta_setting_infos_by_gtype (gtype)); + return _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_gtype(gtype)); } const NMMetaSettingInfoEditor * -nm_meta_setting_info_editor_find_by_setting (NMSetting *setting) +nm_meta_setting_info_editor_find_by_setting(NMSetting *setting) { - const NMMetaSettingInfoEditor *setting_info; + const NMMetaSettingInfoEditor *setting_info; - g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); - setting_info = nm_meta_setting_info_editor_find_by_gtype (G_OBJECT_TYPE (setting)); + setting_info = nm_meta_setting_info_editor_find_by_gtype(G_OBJECT_TYPE(setting)); - nm_assert (setting_info); - nm_assert (G_TYPE_CHECK_INSTANCE_TYPE (setting, setting_info->general->get_setting_gtype ())); - return setting_info; + nm_assert(setting_info); + nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(setting, setting_info->general->get_setting_gtype())); + return setting_info; } /*****************************************************************************/ const NMMetaPropertyInfo * -nm_meta_setting_info_editor_get_property_info (const NMMetaSettingInfoEditor *setting_info, const char *property_name) +nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info, + const char * property_name) { - guint i; + guint i; - g_return_val_if_fail (setting_info, NULL); - g_return_val_if_fail (property_name, NULL); + g_return_val_if_fail(setting_info, NULL); + g_return_val_if_fail(property_name, NULL); - for (i = 0; i < setting_info->properties_num; i++) { - nm_assert (setting_info->properties[i]->property_name); - nm_assert (setting_info->properties[i]->setting_info == setting_info); - if (nm_streq (setting_info->properties[i]->property_name, property_name)) - return setting_info->properties[i]; - } + for (i = 0; i < setting_info->properties_num; i++) { + nm_assert(setting_info->properties[i]->property_name); + nm_assert(setting_info->properties[i]->setting_info == setting_info); + if (nm_streq(setting_info->properties[i]->property_name, property_name)) + return setting_info->properties[i]; + } - return NULL; + return NULL; } gboolean -nm_meta_setting_info_editor_has_secrets (const NMMetaSettingInfoEditor *setting_info) +nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info) { - guint i; + guint i; - if (!setting_info) - return FALSE; + if (!setting_info) + return FALSE; - for (i = 0; i < setting_info->properties_num; i++) { - if (setting_info->properties[i]->is_secret) - return TRUE; - } + for (i = 0; i < setting_info->properties_num; i++) { + if (setting_info->properties[i]->is_secret) + return TRUE; + } - return FALSE; + return FALSE; } const NMMetaPropertyInfo * -nm_meta_property_info_find_by_name (const char *setting_name, const char *property_name) +nm_meta_property_info_find_by_name(const char *setting_name, const char *property_name) { - const NMMetaSettingInfoEditor *setting_info; - const NMMetaPropertyInfo *property_info; + const NMMetaSettingInfoEditor *setting_info; + const NMMetaPropertyInfo * property_info; - setting_info = nm_meta_setting_info_editor_find_by_name (setting_name, FALSE); - if (!setting_info) - return NULL; + setting_info = nm_meta_setting_info_editor_find_by_name(setting_name, FALSE); + if (!setting_info) + return NULL; - property_info = nm_meta_setting_info_editor_get_property_info (setting_info, property_name); - if (!property_info) - return NULL; + property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name); + if (!property_info) + return NULL; - nm_assert (property_info->setting_info == setting_info); + nm_assert(property_info->setting_info == setting_info); - return property_info; + return property_info; } const NMMetaPropertyInfo * -nm_meta_property_info_find_by_setting (NMSetting *setting, const char *property_name) +nm_meta_property_info_find_by_setting(NMSetting *setting, const char *property_name) { - const NMMetaSettingInfoEditor *setting_info; - const NMMetaPropertyInfo *property_info; + const NMMetaSettingInfoEditor *setting_info; + const NMMetaPropertyInfo * property_info; - setting_info = nm_meta_setting_info_editor_find_by_setting (setting); - if (!setting_info) - return NULL; - property_info = nm_meta_setting_info_editor_get_property_info (setting_info, property_name); - if (!property_info) - return NULL; + setting_info = nm_meta_setting_info_editor_find_by_setting(setting); + if (!setting_info) + return NULL; + property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name); + if (!property_info) + return NULL; - nm_assert (property_info->setting_info == setting_info); - nm_assert (property_info == nm_meta_property_info_find_by_name (nm_setting_get_name (setting), property_name)); + nm_assert(property_info->setting_info == setting_info); + nm_assert(property_info + == nm_meta_property_info_find_by_name(nm_setting_get_name(setting), property_name)); - return property_info; + return property_info; } NMSetting * -nm_meta_setting_info_editor_new_setting (const NMMetaSettingInfoEditor *setting_info, - NMMetaAccessorSettingInitType init_type) +nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info, + NMMetaAccessorSettingInitType init_type) { - NMSetting *setting; + NMSetting *setting; - g_return_val_if_fail (setting_info, NULL); + g_return_val_if_fail(setting_info, NULL); - setting = g_object_new (setting_info->general->get_setting_gtype (), 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); - } + 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; + return setting; } /*****************************************************************************/ -const NMMetaSettingInfoEditor *const* -nm_meta_setting_infos_editor_p (void) +const NMMetaSettingInfoEditor *const * +nm_meta_setting_infos_editor_p(void) { - static const NMMetaSettingInfoEditor *cache[_NM_META_SETTING_TYPE_NUM + 1] = { NULL }; - guint i; - - if (G_UNLIKELY (!cache[0])) { - for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) - cache[i] = &nm_meta_setting_infos_editor[i]; - } - return cache; + static const NMMetaSettingInfoEditor *cache[_NM_META_SETTING_TYPE_NUM + 1] = {NULL}; + guint i; + + if (G_UNLIKELY(!cache[0])) { + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + cache[i] = &nm_meta_setting_infos_editor[i]; + } + return cache; } /*****************************************************************************/ const char * -nm_meta_abstract_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header) +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, for_header); - nm_assert (n && n[0]); - return n; + 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, for_header); + nm_assert(n && n[0]); + return n; } -const NMMetaAbstractInfo *const* -nm_meta_abstract_info_get_nested (const NMMetaAbstractInfo *abstract_info, - guint *out_len, - gpointer *nested_to_free) +const NMMetaAbstractInfo *const * +nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info, + guint * out_len, + gpointer * nested_to_free) { - const NMMetaAbstractInfo *const*nested; - guint l = 0; - gs_free gpointer f = NULL; - - nm_assert (abstract_info); - nm_assert (abstract_info->meta_type); - nm_assert (nested_to_free && !*nested_to_free); - - if (abstract_info->meta_type->get_nested) { - nested = abstract_info->meta_type->get_nested (abstract_info, &l, &f); - nm_assert (NM_PTRARRAY_LEN (nested) == l); - nm_assert (!f || nested == f); - if (nested && nested[0]) { - NM_SET_OUT (out_len, l); - *nested_to_free = g_steal_pointer (&f); - return nested; - } - } - NM_SET_OUT (out_len, 0); - return NULL; + const NMMetaAbstractInfo *const *nested; + guint l = 0; + gs_free gpointer f = NULL; + + nm_assert(abstract_info); + nm_assert(abstract_info->meta_type); + nm_assert(nested_to_free && !*nested_to_free); + + if (abstract_info->meta_type->get_nested) { + nested = abstract_info->meta_type->get_nested(abstract_info, &l, &f); + nm_assert(NM_PTRARRAY_LEN(nested) == l); + nm_assert(!f || nested == f); + if (nested && nested[0]) { + NM_SET_OUT(out_len, l); + *nested_to_free = g_steal_pointer(&f); + return nested; + } + } + 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, - gpointer target_data, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + gpointer target, + gpointer target_data, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gboolean * out_is_default, + 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; - NM_SET_OUT (out_is_default, FALSE); - - if (!abstract_info->meta_type->get_fcn) - g_return_val_if_reached (NULL); - - return abstract_info->meta_type->get_fcn (abstract_info, - environment, - environment_user_data, - target, - target_data, - get_type, - get_flags, - out_flags, - out_is_default, - 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; + NM_SET_OUT(out_is_default, FALSE); + + if (!abstract_info->meta_type->get_fcn) + g_return_val_if_reached(NULL); + + return abstract_info->meta_type->get_fcn(abstract_info, + environment, + environment_user_data, + target, + target_data, + get_type, + get_flags, + out_flags, + out_is_default, + out_to_free); } -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, - gboolean *out_complete_filename, - char ***out_to_free) +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, + gboolean * out_complete_filename, + 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, - environment, - environment_user_data, - operation_context, - text, - out_complete_filename, - out_to_free); - - nm_assert (!*out_to_free || values == (const char *const*) *out_to_free); - - if (!values) - return NULL; - - if (!values[0]) { - nm_clear_g_free (out_to_free); - return NULL; - } - - if (!text || !text[0]) - return values; - - /* for convenience, we allow 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) { - g_free (v[i]); - continue; - } - v[j++] = v[i]; - } - if (j) - v[j++] = NULL; - else { - g_free (v); - *out_to_free = v = NULL; - } - return (const char *const*) v; - } 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; - else if (!j) - return NULL; - - 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); - } + 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, + environment, + environment_user_data, + operation_context, + text, + out_complete_filename, + out_to_free); + + nm_assert(!*out_to_free || values == (const char *const *) *out_to_free); + + if (!values) + return NULL; + + if (!values[0]) { + nm_clear_g_free(out_to_free); + return NULL; + } + + if (!text || !text[0]) + return values; + + /* for convenience, we allow 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) { + g_free(v[i]); + continue; + } + v[j++] = v[i]; + } + if (j) + v[j++] = NULL; + else { + g_free(v); + *out_to_free = v = NULL; + } + return (const char *const *) v; + } 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; + else if (!j) + return NULL; + + 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); + } } /*****************************************************************************/ char * -nm_meta_abstract_info_get_nested_names_str (const NMMetaAbstractInfo *abstract_info, const char *name_prefix) +nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info, + const char * name_prefix) { - gs_free gpointer nested_to_free = NULL; - const NMMetaAbstractInfo *const*nested; + gs_free gpointer nested_to_free = NULL; + const NMMetaAbstractInfo *const *nested; - nested = nm_meta_abstract_info_get_nested (abstract_info, NULL, &nested_to_free); - if (!nested) - return NULL; + nested = nm_meta_abstract_info_get_nested(abstract_info, NULL, &nested_to_free); + if (!nested) + return NULL; - if (!name_prefix) - name_prefix = nm_meta_abstract_info_get_name (abstract_info, FALSE); + if (!name_prefix) + name_prefix = nm_meta_abstract_info_get_name(abstract_info, FALSE); - return nm_meta_abstract_infos_get_names_str (nested, name_prefix); + return nm_meta_abstract_infos_get_names_str(nested, name_prefix); } char * -nm_meta_abstract_infos_get_names_str (const NMMetaAbstractInfo *const*fields_array, const char *name_prefix) +nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array, + const char * name_prefix) { - GString *str; - guint i; - - if (!fields_array || !fields_array[0]) - return NULL; - - str = g_string_sized_new (128); - for (i = 0; fields_array[i]; i++) { - if (str->len > 0) - g_string_append_c (str, ','); - if (name_prefix) { - g_string_append (str, name_prefix); - g_string_append_c (str, '.'); - } - g_string_append (str, nm_meta_abstract_info_get_name (fields_array[i], FALSE)); - } - return g_string_free (str, FALSE); + GString *str; + guint i; + + if (!fields_array || !fields_array[0]) + return NULL; + + str = g_string_sized_new(128); + for (i = 0; fields_array[i]; i++) { + if (str->len > 0) + g_string_append_c(str, ','); + if (name_prefix) { + g_string_append(str, name_prefix); + g_string_append_c(str, '.'); + } + g_string_append(str, nm_meta_abstract_info_get_name(fields_array[i], FALSE)); + } + return g_string_free(str, FALSE); } /*****************************************************************************/ typedef struct { - guint idx; - gsize self_offset_plus_1; - gsize sub_offset_plus_1; + guint idx; + gsize self_offset_plus_1; + gsize sub_offset_plus_1; } OutputSelectionItem; static NMMetaSelectionResultList * -_output_selection_pack (const NMMetaAbstractInfo *const* fields_array, - GArray *array, - GString *str) +_output_selection_pack(const NMMetaAbstractInfo *const *fields_array, GArray *array, GString *str) { - NMMetaSelectionResultList *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 (NMMetaSelectionResultList) + (len * sizeof (NMMetaSelectionItem)) + (str ? str->len : 0)); - *((guint *) &result->num) = len; - if (len > 0) { - char *pdata = &((char *) result)[sizeof (NMMetaSelectionResultList) + (len * sizeof (NMMetaSelectionItem))]; - - if (str) - memcpy (pdata, str->str, str->len); - for (i = 0; i < len; i++) { - const OutputSelectionItem *a = &g_array_index (array, OutputSelectionItem, i); - NMMetaSelectionItem *p = (NMMetaSelectionItem *) &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; + NMMetaSelectionResultList *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(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem)) + + (str ? str->len : 0)); + *((guint *) &result->num) = len; + if (len > 0) { + char *pdata = + &((char *) + result)[sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))]; + + if (str) + memcpy(pdata, str->str, str->len); + for (i = 0; i < len; i++) { + const OutputSelectionItem *a = &g_array_index(array, OutputSelectionItem, i); + NMMetaSelectionItem * p = (NMMetaSelectionItem *) &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) +_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]; - const NMMetaAbstractInfo *const*nested; - gs_free gpointer nested_to_free = NULL; - - if (g_ascii_strcasecmp (i_name, nm_meta_abstract_info_get_name (fi, FALSE)) != 0) - continue; - - if (!right || !validate_nested) { - found = TRUE; - break; - } - - nested = nm_meta_abstract_info_get_nested (fi, NULL, &nested_to_free); - if (nested) { - for (j = 0; nested[j]; nested++) { - if (g_ascii_strcasecmp (right, nm_meta_abstract_info_get_name (nested[j], FALSE)) == 0) { - found = TRUE; - break; - } - } - } - fields_array_failure = fields_array[i]; - break; - } - - if (!found) { + 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]; + const NMMetaAbstractInfo *const *nested; + gs_free gpointer nested_to_free = NULL; + + if (g_ascii_strcasecmp(i_name, nm_meta_abstract_info_get_name(fi, FALSE)) != 0) + continue; + + if (!right || !validate_nested) { + found = TRUE; + break; + } + + nested = nm_meta_abstract_info_get_nested(fi, NULL, &nested_to_free); + if (nested) { + for (j = 0; nested[j]; nested++) { + if (g_ascii_strcasecmp(right, nm_meta_abstract_info_get_name(nested[j], FALSE)) + == 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, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, _("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, FALSE)); - } - allowed_fields = nm_meta_abstract_info_get_nested_names_str (fields_array_failure, p); - } else - allowed_fields = nm_meta_abstract_infos_get_names_str (fields_array, NULL); - - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, _("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; + if (!right && !fields_prefix + && (!g_ascii_strcasecmp(i_name, "all") || !g_ascii_strcasecmp(i_name, "common"))) + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("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, FALSE)); + } + allowed_fields = + nm_meta_abstract_info_get_nested_names_str(fields_array_failure, p); + } else + allowed_fields = nm_meta_abstract_infos_get_names_str(fields_array, NULL); + + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("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; } NMMetaSelectionResultList * -nm_meta_selection_create_all (const NMMetaAbstractInfo *const* fields_array) +nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array) { - gs_unref_array GArray *array = NULL; - guint i; + gs_unref_array GArray *array = NULL; + guint i; - if (fields_array) { - array = g_array_new (FALSE, FALSE, sizeof (OutputSelectionItem)); - for (i = 0; fields_array[i]; i++) { - OutputSelectionItem s = { - .idx = i, - }; + if (fields_array) { + array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem)); + for (i = 0; fields_array[i]; i++) { + OutputSelectionItem s = { + .idx = i, + }; - g_array_append_val (array, s); - } - } + g_array_append_val(array, s); + } + } - return _output_selection_pack (fields_array, array, NULL); + return _output_selection_pack(fields_array, array, NULL); } NMMetaSelectionResultList * -nm_meta_selection_create_parse_one (const NMMetaAbstractInfo *const* fields_array, - const char *fields_prefix, - const char *fields_str, /* one field selector (contains no commas) and is already stripped of spaces. */ - gboolean validate_nested, - GError **error) +nm_meta_selection_create_parse_one( + const NMMetaAbstractInfo *const *fields_array, + const char * fields_prefix, + const char * + fields_str, /* one field selector (contains no commas) and is already 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); - + 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); } NMMetaSelectionResultList * -nm_meta_selection_create_parse_list (const NMMetaAbstractInfo *const* fields_array, - const char *fields_str, /* a comma separated list of selectors */ - gboolean validate_nested, - GError **error) +nm_meta_selection_create_parse_list( + const NMMetaAbstractInfo *const *fields_array, + 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 nm_meta_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, - NULL, - fields_str_cur, - validate_nested, - &array, - &str, - error)) - return NULL; - } - - return _output_selection_pack (fields_array, array, str); + 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 nm_meta_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, + NULL, + fields_str_cur, + validate_nested, + &array, + &str, + error)) + return NULL; + } + + return _output_selection_pack(fields_array, array, str); } diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index 543b51fc..f5218bc4 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2017 Red Hat, Inc. */ @@ -11,81 +11,90 @@ /*****************************************************************************/ -NMSetting *nm_meta_setting_info_editor_new_setting (const NMMetaSettingInfoEditor *setting_info, - NMMetaAccessorSettingInitType init_type); +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); +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); -const NMMetaPropertyInfo *nm_meta_setting_info_editor_get_property_info (const NMMetaSettingInfoEditor *setting_info, - const char *property_name); -const NMMetaPropertyInfo *nm_meta_property_info_find_by_name (const char *setting_name, - const char *property_name); -const NMMetaPropertyInfo *nm_meta_property_info_find_by_setting (NMSetting *setting, - const char *property_name); +const NMMetaPropertyInfo * +nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info, + const char * property_name); +const NMMetaPropertyInfo *nm_meta_property_info_find_by_name(const char *setting_name, + const char *property_name); +const NMMetaPropertyInfo *nm_meta_property_info_find_by_setting(NMSetting * setting, + const char *property_name); -gboolean nm_meta_setting_info_editor_has_secrets (const NMMetaSettingInfoEditor *setting_info); +gboolean nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info); /*****************************************************************************/ -const NMMetaSettingInfoEditor *const*nm_meta_setting_infos_editor_p (void); +const NMMetaSettingInfoEditor *const *nm_meta_setting_infos_editor_p(void); /*****************************************************************************/ -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, - gpointer *nested_to_free); - -gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info, - const NMMetaEnvironment *environment, - gpointer environment_user_data, - gpointer target, - gpointer target_data, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - 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 *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, + gpointer * nested_to_free); + +gconstpointer nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + gpointer target, + gpointer target_data, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gboolean * out_is_default, + gpointer * out_to_free); + +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, + const char * text, gboolean *out_complete_filename, - char ***out_to_free); + char *** out_to_free); /*****************************************************************************/ -char *nm_meta_abstract_info_get_nested_names_str (const NMMetaAbstractInfo *abstract_info, const char *name_prefix); -char *nm_meta_abstract_infos_get_names_str (const NMMetaAbstractInfo *const*fields_array, const char *name_prefix); +char *nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info, + const char * name_prefix); +char *nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array, + const char * name_prefix); /*****************************************************************************/ typedef struct { - const NMMetaAbstractInfo *info; - const char *self_selection; - const char *sub_selection; - guint idx; + const NMMetaAbstractInfo *info; + const char * self_selection; + const char * sub_selection; + guint idx; } NMMetaSelectionItem; typedef struct { - const guint num; - const NMMetaSelectionItem items[]; + const guint num; + const NMMetaSelectionItem items[]; } NMMetaSelectionResultList; -NMMetaSelectionResultList *nm_meta_selection_create_all (const NMMetaAbstractInfo *const* fields_array); -NMMetaSelectionResultList *nm_meta_selection_create_parse_one (const NMMetaAbstractInfo *const* fields_array, - const char *fields_prefix, - const char *fields_str, - gboolean validate_nested, - GError **error); -NMMetaSelectionResultList *nm_meta_selection_create_parse_list (const NMMetaAbstractInfo *const* fields_array, - const char *fields_str, - gboolean validate_nested, - GError **error); +NMMetaSelectionResultList * +nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array); +NMMetaSelectionResultList * +nm_meta_selection_create_parse_one(const NMMetaAbstractInfo *const *fields_array, + const char * fields_prefix, + const char * fields_str, + gboolean validate_nested, + GError ** error); +NMMetaSelectionResultList * +nm_meta_selection_create_parse_list(const NMMetaAbstractInfo *const *fields_array, + const char * fields_str, + gboolean validate_nested, + GError ** error); #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 2ac91b41..cdb3084a 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2018 Red Hat, Inc. */ @@ -22,406 +22,403 @@ /*****************************************************************************/ -static char *secret_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type); +static char *secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type); -#define ALL_SECRET_FLAGS \ - (NM_SETTING_SECRET_FLAG_NONE | \ - NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ - NM_SETTING_SECRET_FLAG_NOT_SAVED | \ - NM_SETTING_SECRET_FLAG_NOT_REQUIRED) +#define ALL_SECRET_FLAGS \ + (NM_SETTING_SECRET_FLAG_NONE | NM_SETTING_SECRET_FLAG_AGENT_OWNED \ + | NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED) /*****************************************************************************/ static GType -_gobject_property_get_gtype (GObject *gobject, const char *property_name) +_gobject_property_get_gtype(GObject *gobject, const char *property_name) { - GParamSpec *param_spec; + GParamSpec *param_spec; - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject), property_name); - if (param_spec) - return param_spec->value_type; - g_return_val_if_reached (G_TYPE_INVALID); + param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(gobject), property_name); + if (param_spec) + return param_spec->value_type; + g_return_val_if_reached(G_TYPE_INVALID); } static GType -_gtype_property_get_gtype (GType gtype, const char *property_name) +_gtype_property_get_gtype(GType gtype, const char *property_name) { - /* given @gtype, a type for a GObject, lookup the property @property_name - * and return its value_type. */ - if (G_TYPE_IS_CLASSED (gtype)) { - GParamSpec *param_spec; - nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref (gtype); + /* given @gtype, a type for a GObject, lookup the property @property_name + * and return its value_type. */ + if (G_TYPE_IS_CLASSED(gtype)) { + GParamSpec * param_spec; + nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref(gtype); - if (G_IS_OBJECT_CLASS (gtypeclass)) { - param_spec = g_object_class_find_property (G_OBJECT_CLASS (gtypeclass), property_name); - if (param_spec) - return param_spec->value_type; - } - } - g_return_val_if_reached (G_TYPE_INVALID); + if (G_IS_OBJECT_CLASS(gtypeclass)) { + param_spec = g_object_class_find_property(G_OBJECT_CLASS(gtypeclass), property_name); + if (param_spec) + return param_spec->value_type; + } + } + g_return_val_if_reached(G_TYPE_INVALID); } /*****************************************************************************/ static char * -bytes_to_string (GBytes *bytes) +bytes_to_string(GBytes *bytes) { - const guint8 *data; - gsize len; + const guint8 *data; + gsize len; - if (!bytes) - return NULL; + if (!bytes) + return NULL; - data = g_bytes_get_data (bytes, &len); - return nm_utils_bin2hexstr_full (data, - len, - '\0', - TRUE, - NULL); + data = g_bytes_get_data(bytes, &len); + return nm_utils_bin2hexstr_full(data, len, '\0', TRUE, NULL); } /*****************************************************************************/ static int -_int64_cmp_desc (gconstpointer a, - gconstpointer b, - gpointer user_data) +_int64_cmp_desc(gconstpointer a, gconstpointer b, gpointer user_data) { - NM_CMP_DIRECT (*((const gint64 *) b), *((const gint64 *) a)); - return 0; + NM_CMP_DIRECT(*((const gint64 *) b), *((const gint64 *) a)); + return 0; } static gint64 * -_value_str_as_index_list (const char *value, gsize *out_len) -{ - gs_free char *str_clone_free = NULL; - gboolean str_cloned = FALSE; - char *str; - gsize i, j; - gsize n_alloc; - gsize len; - gs_free gint64 *arr = NULL; - - *out_len = 0; - - if (!value) - return NULL; - - str = (char *) value; - n_alloc = 0; - len = 0; - while (TRUE) { - gint64 i64; - const char *s; - gsize good; - - good = strcspn (str, ","NM_ASCII_SPACES); - if (good == 0) { - if (str[0] == '\0') - break; - str++; - continue; - } - if (str[good] == '\0') { - s = str; - str += good; - } else { - if (!str_cloned) { - str_cloned = TRUE; - str = nm_strndup_a (200, str, strlen (str), &str_clone_free); - } - s = str; - str[good] = '\0'; - str += good + 1; - } - - i64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT64, -1); - if (i64 == -1) - return NULL; - - if (len >= n_alloc) { - if (n_alloc > 0) { - n_alloc = n_alloc * 2; - arr = g_realloc (arr, n_alloc * sizeof (gint64)); - } else { - n_alloc = 4; - arr = g_new (gint64, n_alloc); - } - } - arr[len++] = i64; - } - - if (len > 1) { - /* sort the list of indexes descendingly, and drop duplicates. */ - g_qsort_with_data (arr, - len, - sizeof (gint64), - _int64_cmp_desc, - NULL); - j = 1; - for (i = 1; i < len; i++) { - nm_assert (arr[i - 1] >= arr[i]); - if (arr[i - 1] > arr[i]) - arr[j++] = arr[i]; - } - len = j; - } - - *out_len = len; - return g_steal_pointer (&arr); +_value_str_as_index_list(const char *value, gsize *out_len) +{ + gs_free char *str_clone_free = NULL; + gboolean str_cloned = FALSE; + char * str; + gsize i, j; + gsize n_alloc; + gsize len; + gs_free gint64 *arr = NULL; + + *out_len = 0; + + if (!value) + return NULL; + + str = (char *) value; + n_alloc = 0; + len = 0; + while (TRUE) { + gint64 i64; + const char *s; + gsize good; + + good = strcspn(str, "," NM_ASCII_SPACES); + if (good == 0) { + if (str[0] == '\0') + break; + str++; + continue; + } + if (str[good] == '\0') { + s = str; + str += good; + } else { + if (!str_cloned) { + str_cloned = TRUE; + str = nm_strndup_a(200, str, strlen(str), &str_clone_free); + } + s = str; + str[good] = '\0'; + str += good + 1; + } + + i64 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXINT64, -1); + if (i64 == -1) + return NULL; + + if (len >= n_alloc) { + if (n_alloc > 0) { + n_alloc = n_alloc * 2; + arr = g_realloc(arr, n_alloc * sizeof(gint64)); + } else { + n_alloc = 4; + arr = g_new(gint64, n_alloc); + } + } + arr[len++] = i64; + } + + if (len > 1) { + /* sort the list of indexes descendingly, and drop duplicates. */ + g_qsort_with_data(arr, len, sizeof(gint64), _int64_cmp_desc, NULL); + j = 1; + for (i = 1; i < len; i++) { + nm_assert(arr[i - 1] >= arr[i]); + if (arr[i - 1] > arr[i]) + arr[j++] = arr[i]; + } + len = j; + } + + *out_len = len; + return g_steal_pointer(&arr); } #define ESCAPED_TOKENS_WITH_SPACES_DELIMTER ' ' -#define ESCAPED_TOKENS_WITH_SPACES_DELIMTERS NM_ASCII_SPACES"," +#define ESCAPED_TOKENS_WITH_SPACES_DELIMTERS NM_ASCII_SPACES "," -#define ESCAPED_TOKENS_DELIMITER ',' -#define ESCAPED_TOKENS_DELIMITERS "," +#define ESCAPED_TOKENS_DELIMITER ',' +#define ESCAPED_TOKENS_DELIMITERS "," typedef enum { - VALUE_STRSPLIT_MODE_OBJLIST, - VALUE_STRSPLIT_MODE_MULTILIST, - VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, - VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, + VALUE_STRSPLIT_MODE_OBJLIST, + VALUE_STRSPLIT_MODE_MULTILIST, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, } ValueStrsplitMode; static const char ** -_value_strsplit (const char *value, - ValueStrsplitMode split_mode, - gsize *out_len) -{ - gs_free const char **strv = NULL; - - /* FIXME: some modes should support backslash escaping. - * In particular, to distinguish from _value_str_as_index_list(), which - * does not accept '\\'. */ - - /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ - switch (split_mode) { - case VALUE_STRSPLIT_MODE_OBJLIST: - strv = nm_utils_strsplit_set_full (value, - ESCAPED_TOKENS_DELIMITERS, - NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); - break; - case VALUE_STRSPLIT_MODE_MULTILIST: - strv = nm_utils_strsplit_set_full (value, - ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, - NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); - break; - case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: - strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_DELIMITERS); - break; - case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES: - strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); - break; - } - - NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); - return g_steal_pointer (&strv); +_value_strsplit(const char *value, ValueStrsplitMode split_mode, gsize *out_len) +{ + gs_free const char **strv = NULL; + + /* FIXME: some modes should support backslash escaping. + * In particular, to distinguish from _value_str_as_index_list(), which + * does not accept '\\'. */ + + /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ + switch (split_mode) { + case VALUE_STRSPLIT_MODE_OBJLIST: + strv = nm_utils_strsplit_set_full(value, + ESCAPED_TOKENS_DELIMITERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + break; + case VALUE_STRSPLIT_MODE_MULTILIST: + strv = nm_utils_strsplit_set_full(value, + ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + break; + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: + strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_DELIMITERS); + break; + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES: + strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); + break; + } + + NM_SET_OUT(out_len, NM_PTRARRAY_LEN(strv)); + return g_steal_pointer(&strv); } static gboolean -_value_strsplit_assert_unsplitable (const char *str) +_value_strsplit_assert_unsplitable(const char *str) { #if NM_MORE_ASSERTS > 5 - gs_free const char **strv_test = NULL; - gsize j, l; - - /* Assert that we cannot split the token and that it - * has no unescaped delimiters. */ - - strv_test = _value_strsplit (str, - VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, - NULL); - nm_assert (NM_PTRARRAY_LEN (strv_test) == 1); - - for (j = 0; str[j] != '\0'; ) { - if (str[j] == '\\') { - j++; - nm_assert (str[j] != '\0'); - } else - nm_assert (!NM_IN_SET (str[j], '\0', ',')); - j++; - } - l = j; - nm_assert ( !g_ascii_isspace (str[l - 1]) - || ( l >= 2 - && str[l - 2] == '\\')); + gs_free const char **strv_test = NULL; + gsize j, l; + + /* Assert that we cannot split the token and that it + * has no unescaped delimiters. */ + + strv_test = _value_strsplit(str, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, NULL); + nm_assert(NM_PTRARRAY_LEN(strv_test) == 1); + + for (j = 0; str[j] != '\0';) { + if (str[j] == '\\') { + j++; + nm_assert(str[j] != '\0'); + } else + nm_assert(!NM_IN_SET(str[j], '\0', ',')); + j++; + } + l = j; + nm_assert(!g_ascii_isspace(str[l - 1]) || (l >= 2 && str[l - 2] == '\\')); #endif - return TRUE; + return TRUE; } static NMIPAddress * -_parse_ip_address (int family, const char *address, GError **error) -{ - gs_free char *ip_str = NULL; - const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; - NMIPAddress *addr; - char *plen; - int prefix; - GError *local = NULL; - - g_return_val_if_fail (address, NULL); - g_return_val_if_fail (!error || !*error, NULL); - - ip_str = g_strstrip (g_strdup (address)); - - prefix = MAX_PREFIX; - - plen = strchr (ip_str, '/'); - if (plen) { - *plen++ = '\0'; - if ((prefix = _nm_utils_ascii_str_to_int64 (plen, 10, 1, MAX_PREFIX, -1)) == -1) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("invalid prefix '%s'; <1-%d> allowed"), plen, MAX_PREFIX); - return NULL; - } - } - - addr = nm_ip_address_new (family, ip_str, prefix, &local); - if (!addr) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("invalid IP address: %s"), local->message); - g_clear_error (&local); - } - return addr; +_parse_ip_address(int family, const char *address, GError **error) +{ + gs_free char *ip_str = NULL; + const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; + NMIPAddress * addr; + char * plen; + int prefix; + GError * local = NULL; + + g_return_val_if_fail(address, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + ip_str = g_strstrip(g_strdup(address)); + + prefix = MAX_PREFIX; + + plen = strchr(ip_str, '/'); + if (plen) { + *plen++ = '\0'; + if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 1, MAX_PREFIX, -1)) == -1) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid prefix '%s'; <1-%d> allowed"), + plen, + MAX_PREFIX); + return NULL; + } + } + + addr = nm_ip_address_new(family, ip_str, prefix, &local); + if (!addr) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid IP address: %s"), + local->message); + g_clear_error(&local); + } + return addr; } static NMIPRoute * -_parse_ip_route (int family, - const char *str, - GError **error) -{ - const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; - const char *next_hop = NULL; - int prefix; - NMIPRoute *route = NULL; - GError *local = NULL; - gint64 metric = -1; - guint i; - gs_free const char **routev = NULL; - gs_free char *str_clean_free = NULL; - const char *str_clean; - gs_free char *dest_clone = NULL; - const char *dest; - const char *plen; - gs_unref_hashtable GHashTable *attrs = NULL; -#define ROUTE_SYNTAX _("The valid syntax is: 'ip[/prefix] [next-hop] [metric] [attribute=val]... [,ip[/prefix] ...]'") - - nm_assert (NM_IN_SET (family, AF_INET, AF_INET6)); - nm_assert (str); - nm_assert (!error || !*error); - - str_clean = nm_strstrip_avoid_copy_a (300, str, &str_clean_free); - routev = nm_utils_strsplit_set (str_clean, " \t"); - if (!routev) { - g_set_error (error, 1, 0, - "'%s' is not valid. %s", - str, ROUTE_SYNTAX); - return NULL; - } - - dest = routev[0]; - plen = strchr (dest, '/'); /* prefix delimiter */ - if (plen) { - dest_clone = g_strdup (dest); - plen = &dest_clone[plen - dest]; - dest = dest_clone; - *((char *) plen) = '\0'; - plen++; - } - prefix = MAX_PREFIX; - if (plen) { - if ((prefix = _nm_utils_ascii_str_to_int64 (plen, 10, 0, MAX_PREFIX, -1)) == -1) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("invalid prefix '%s'; <1-%d> allowed"), - plen, MAX_PREFIX); - return NULL; - } - } - - for (i = 1; routev[i]; i++) { - gint64 tmp64; - - if (nm_utils_ipaddr_is_valid (family, routev[i])) { - if (metric != -1 || attrs) { - g_set_error (error, 1, 0, _("the next hop ('%s') must be first"), routev[i]); - return NULL; - } - next_hop = routev[i]; - } else if ((tmp64 = _nm_utils_ascii_str_to_int64 (routev[i], 10, 0, G_MAXUINT32, -1)) != -1) { - if (attrs) { - g_set_error (error, 1, 0, _("the metric ('%s') must be before attributes"), routev[i]); - return NULL; - } - metric = tmp64; - } else if (strchr (routev[i], '=')) { - GHashTableIter iter; - char *iter_key; - GVariant *iter_value; - gs_unref_hashtable GHashTable *tmp_attrs = NULL; - - tmp_attrs = nm_utils_parse_variant_attributes (routev[i], ' ', '=', FALSE, - nm_ip_route_get_variant_attribute_spec(), - error); - if (!tmp_attrs) { - g_prefix_error (error, "invalid option '%s': ", routev[i]); - return NULL; - } - - if (!attrs) { - attrs = g_hash_table_new_full (nm_str_hash, - g_str_equal, - g_free, - (GDestroyNotify) g_variant_unref); - } - - g_hash_table_iter_init (&iter, tmp_attrs); - while (g_hash_table_iter_next (&iter, (gpointer *) &iter_key, (gpointer *) &iter_value)) { - - /* need to sink the reference, because nm_utils_parse_variant_attributes() returns - * floating refs. */ - g_variant_ref_sink (iter_value); - - if (!nm_ip_route_attribute_validate (iter_key, iter_value, family, NULL, error)) { - g_prefix_error (error, "%s: ", iter_key); - return NULL; - } - g_hash_table_insert (attrs, iter_key, iter_value); - g_hash_table_iter_steal (&iter); - } - } else { - g_set_error (error, 1, 0, "%s", ROUTE_SYNTAX); - return NULL; - } - } - - route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &local); - if (!route) { - g_set_error (error, 1, 0, - _("invalid route: %s. %s"), local->message, ROUTE_SYNTAX); - g_clear_error (&local); - return NULL; - } - - if (attrs) { - GHashTableIter iter; - char *name; - GVariant *variant; - - g_hash_table_iter_init (&iter, attrs); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) - nm_ip_route_set_attribute (route, name, variant); - } - - return route; +_parse_ip_route(int family, const char *str, GError **error) +{ + const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; + const char * next_hop = NULL; + int prefix; + NMIPRoute * route = NULL; + GError * local = NULL; + gint64 metric = -1; + guint i; + gs_free const char **routev = NULL; + gs_free char * str_clean_free = NULL; + const char * str_clean; + gs_free char * dest_clone = NULL; + const char * dest; + const char * plen; + gs_unref_hashtable GHashTable *attrs = NULL; +#define ROUTE_SYNTAX \ + _("The valid syntax is: 'ip[/prefix] [next-hop] [metric] [attribute=val]... [,ip[/prefix] " \ + "...]'") + + nm_assert(NM_IN_SET(family, AF_INET, AF_INET6)); + nm_assert(str); + nm_assert(!error || !*error); + + str_clean = nm_strstrip_avoid_copy_a(300, str, &str_clean_free); + routev = nm_utils_strsplit_set(str_clean, " \t"); + if (!routev) { + g_set_error(error, 1, 0, "'%s' is not valid. %s", str, ROUTE_SYNTAX); + return NULL; + } + + dest = routev[0]; + plen = strchr(dest, '/'); /* prefix delimiter */ + if (plen) { + dest_clone = g_strdup(dest); + plen = &dest_clone[plen - dest]; + dest = dest_clone; + *((char *) plen) = '\0'; + plen++; + } + prefix = MAX_PREFIX; + if (plen) { + if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 0, MAX_PREFIX, -1)) == -1) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid prefix '%s'; <1-%d> allowed"), + plen, + MAX_PREFIX); + return NULL; + } + } + + for (i = 1; routev[i]; i++) { + gint64 tmp64; + + if (nm_utils_ipaddr_is_valid(family, routev[i])) { + if (metric != -1 || attrs) { + g_set_error(error, 1, 0, _("the next hop ('%s') must be first"), routev[i]); + return NULL; + } + next_hop = routev[i]; + } else if ((tmp64 = _nm_utils_ascii_str_to_int64(routev[i], 10, 0, G_MAXUINT32, -1)) + != -1) { + if (attrs) { + g_set_error(error, + 1, + 0, + _("the metric ('%s') must be before attributes"), + routev[i]); + return NULL; + } + metric = tmp64; + } else if (strchr(routev[i], '=')) { + GHashTableIter iter; + char * iter_key; + GVariant * iter_value; + gs_unref_hashtable GHashTable *tmp_attrs = NULL; + + tmp_attrs = nm_utils_parse_variant_attributes(routev[i], + ' ', + '=', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + error); + if (!tmp_attrs) { + g_prefix_error(error, "invalid option '%s': ", routev[i]); + return NULL; + } + + if (!attrs) { + attrs = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + g_hash_table_iter_init(&iter, tmp_attrs); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &iter_key, (gpointer *) &iter_value)) { + /* need to sink the reference, because nm_utils_parse_variant_attributes() returns + * floating refs. */ + g_variant_ref_sink(iter_value); + + if (!nm_ip_route_attribute_validate(iter_key, iter_value, family, NULL, error)) { + g_prefix_error(error, "%s: ", iter_key); + return NULL; + } + g_hash_table_insert(attrs, iter_key, iter_value); + g_hash_table_iter_steal(&iter); + } + } else { + g_set_error(error, 1, 0, "%s", ROUTE_SYNTAX); + return NULL; + } + } + + route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &local); + if (!route) { + g_set_error(error, 1, 0, _("invalid route: %s. %s"), local->message, ROUTE_SYNTAX); + g_clear_error(&local); + return NULL; + } + + if (attrs) { + GHashTableIter iter; + char * name; + GVariant * variant; + + g_hash_table_iter_init(&iter, attrs); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) + nm_ip_route_set_attribute(route, name, variant); + } + + return route; } /*****************************************************************************/ /* Max priority values from libnm-core/nm-setting-vlan.c */ #define MAX_SKB_PRIO G_MAXUINT32 -#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ +#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ /* * nmc_proxy_check_script: @@ -435,68 +432,74 @@ _parse_ip_route (int family, * Returns: %TRUE if the script is valid, %FALSE if it is invalid */ static gboolean -nmc_proxy_check_script (const char *script, char **out_script, GError **error) -{ - enum { - _PAC_SCRIPT_TYPE_GUESS, - _PAC_SCRIPT_TYPE_FILE, - _PAC_SCRIPT_TYPE_JSON, - } desired_type = _PAC_SCRIPT_TYPE_GUESS; - const char *filename = NULL; - size_t c_len = 0; - gs_free char *script_clone = NULL; - - *out_script = NULL; - - if (!script || !script[0]) - return TRUE; - - if (g_str_has_prefix (script, "file://")) { - script += NM_STRLEN ("file://"); - desired_type = _PAC_SCRIPT_TYPE_FILE; - } else if (g_str_has_prefix (script, "js://")) { - script += NM_STRLEN ("js://"); - desired_type = _PAC_SCRIPT_TYPE_JSON; - } - - if (NM_IN_SET (desired_type, _PAC_SCRIPT_TYPE_FILE, _PAC_SCRIPT_TYPE_GUESS)) { - gs_free char *contents = NULL; - - if (!g_file_get_contents (script, &contents, &c_len, NULL)) { - if (desired_type == _PAC_SCRIPT_TYPE_FILE) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("cannot read pac-script from file '%s'"), - script); - return FALSE; - } - } else { - if (c_len != strlen (contents)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("file '%s' contains non-valid utf-8"), - script); - return FALSE; - } - filename = script; - script = script_clone = g_steal_pointer (&contents); - } - } - - if ( !strstr (script, "FindProxyForURL") - || !g_utf8_validate (script, -1, NULL)) { - if (filename) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' does not contain a valid PAC Script"), filename); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("Not a valid PAC Script")); - } - return FALSE; - } - - *out_script = (script == script_clone) - ? g_steal_pointer (&script_clone) - : g_strdup (script); - return TRUE; +nmc_proxy_check_script(const char *script, char **out_script, GError **error) +{ + enum { + _PAC_SCRIPT_TYPE_GUESS, + _PAC_SCRIPT_TYPE_FILE, + _PAC_SCRIPT_TYPE_JSON, + } desired_type = _PAC_SCRIPT_TYPE_GUESS; + const char * filename = NULL; + size_t c_len = 0; + gs_free char *script_clone = NULL; + + *out_script = NULL; + + if (!script || !script[0]) + return TRUE; + + if (g_str_has_prefix(script, "file://")) { + script += NM_STRLEN("file://"); + desired_type = _PAC_SCRIPT_TYPE_FILE; + } else if (g_str_has_prefix(script, "js://")) { + script += NM_STRLEN("js://"); + desired_type = _PAC_SCRIPT_TYPE_JSON; + } + + if (NM_IN_SET(desired_type, _PAC_SCRIPT_TYPE_FILE, _PAC_SCRIPT_TYPE_GUESS)) { + gs_free char *contents = NULL; + + if (!g_file_get_contents(script, &contents, &c_len, NULL)) { + if (desired_type == _PAC_SCRIPT_TYPE_FILE) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("cannot read pac-script from file '%s'"), + script); + return FALSE; + } + } else { + if (c_len != strlen(contents)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("file '%s' contains non-valid utf-8"), + script); + return FALSE; + } + filename = script; + script = script_clone = g_steal_pointer(&contents); + } + } + + if (!strstr(script, "FindProxyForURL") || !g_utf8_validate(script, -1, NULL)) { + if (filename) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' does not contain a valid PAC Script"), + filename); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("Not a valid PAC Script")); + } + return FALSE; + } + + *out_script = (script == script_clone) ? g_steal_pointer(&script_clone) : g_strdup(script); + return TRUE; } /* @@ -512,3926 +515,3979 @@ nmc_proxy_check_script (const char *script, char **out_script, GError **error) * Returns: %TRUE if the config is valid, %FALSE if it is invalid */ static gboolean -nmc_team_check_config (const char *config, char **out_config, GError **error) -{ - enum { - _TEAM_CONFIG_TYPE_GUESS, - _TEAM_CONFIG_TYPE_FILE, - _TEAM_CONFIG_TYPE_JSON, - } desired_type = _TEAM_CONFIG_TYPE_GUESS; - size_t c_len = 0; - gs_free char *config_clone = NULL; - - *out_config = NULL; - - if (!config || !config[0]) - return TRUE; - - if (g_str_has_prefix (config, "file://")) { - config += NM_STRLEN ("file://"); - desired_type = _TEAM_CONFIG_TYPE_FILE; - } else if (g_str_has_prefix (config, "json://")) { - config += NM_STRLEN ("json://"); - desired_type = _TEAM_CONFIG_TYPE_JSON; - } - - if (NM_IN_SET (desired_type, _TEAM_CONFIG_TYPE_FILE, _TEAM_CONFIG_TYPE_GUESS)) { - gs_free char *contents = NULL; - - if (!g_file_get_contents (config, &contents, &c_len, NULL)) { - if (desired_type == _TEAM_CONFIG_TYPE_FILE) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("cannot read team config from file '%s'"), - config); - return FALSE; - } - } else { - if (c_len != strlen (contents)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("team config file '%s' contains non-valid utf-8"), - config); - return FALSE; - } - config = config_clone = g_steal_pointer (&contents); - } - } - - *out_config = (config == config_clone) - ? g_steal_pointer (&config_clone) - : g_strdup (config); - return TRUE; +nmc_team_check_config(const char *config, char **out_config, GError **error) +{ + enum { + _TEAM_CONFIG_TYPE_GUESS, + _TEAM_CONFIG_TYPE_FILE, + _TEAM_CONFIG_TYPE_JSON, + } desired_type = _TEAM_CONFIG_TYPE_GUESS; + size_t c_len = 0; + gs_free char *config_clone = NULL; + + *out_config = NULL; + + if (!config || !config[0]) + return TRUE; + + if (g_str_has_prefix(config, "file://")) { + config += NM_STRLEN("file://"); + desired_type = _TEAM_CONFIG_TYPE_FILE; + } else if (g_str_has_prefix(config, "json://")) { + config += NM_STRLEN("json://"); + desired_type = _TEAM_CONFIG_TYPE_JSON; + } + + if (NM_IN_SET(desired_type, _TEAM_CONFIG_TYPE_FILE, _TEAM_CONFIG_TYPE_GUESS)) { + gs_free char *contents = NULL; + + if (!g_file_get_contents(config, &contents, &c_len, NULL)) { + if (desired_type == _TEAM_CONFIG_TYPE_FILE) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("cannot read team config from file '%s'"), + config); + return FALSE; + } + } else { + if (c_len != strlen(contents)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("team config file '%s' contains non-valid utf-8"), + config); + return FALSE; + } + config = config_clone = g_steal_pointer(&contents); + } + } + + *out_config = (config == config_clone) ? g_steal_pointer(&config_clone) : g_strdup(config); + return TRUE; } static const char * -_get_text_hidden (NMMetaAccessorGetType get_type) +_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; + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(NM_META_TEXT_HIDDEN); + return NM_META_TEXT_HIDDEN; } /*****************************************************************************/ -G_GNUC_PRINTF (4, 5) +G_GNUC_PRINTF(4, 5) static void -_env_warn_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - NMMetaEnvWarnLevel warn_level, - const char *fmt_l10n, - ...) +_env_warn_fcn(const NMMetaEnvironment *environment, + gpointer environment_user_data, + NMMetaEnvWarnLevel warn_level, + const char * fmt_l10n, + ...) { - va_list ap; + va_list ap; - if (!environment || !environment->warn_fcn) - return; + if (!environment || !environment->warn_fcn) + return; - va_start (ap, fmt_l10n); - environment->warn_fcn (environment, - environment_user_data, - warn_level, - fmt_l10n, - ap); - va_end (ap); + va_start(ap, fmt_l10n); + environment->warn_fcn(environment, environment_user_data, warn_level, fmt_l10n, ap); + va_end(ap); } /*****************************************************************************/ -#define ARGS_DESCRIBE_FCN \ - const NMMetaPropertyInfo *property_info, char **out_to_free +#define ARGS_DESCRIBE_FCN 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, NMMetaAccessorGetOutFlags *out_flags, gboolean *out_is_default, gpointer *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, NMMetaAccessorGetOutFlags *out_flags, \ + gboolean *out_is_default, gpointer *out_to_free -#define ARGS_SET_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorModifier modifier, const char *value, GError **error +#define ARGS_SET_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, NMSetting *setting, NMMetaAccessorModifier modifier, \ + const char *value, GError **error -#define ARGS_REMOVE_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error +#define ARGS_REMOVE_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, NMSetting *setting, const char *value, GError **error -#define ARGS_COMPLETE_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, gboolean *out_complete_filename, char ***out_to_free +#define ARGS_COMPLETE_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, const NMMetaOperationContext *operation_context, \ + const char *text, gboolean *out_complete_filename, char ***out_to_free -#define ARGS_VALUES_FCN \ - const NMMetaPropertyInfo *property_info, char ***out_to_free +#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 ARGS_SETTING_INIT_FCN \ + const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, \ + NMMetaAccessorSettingInitType init_type -static gboolean _set_fcn_optionlist (ARGS_SET_FCN); +static gboolean _set_fcn_optionlist(ARGS_SET_FCN); static gboolean -_SET_FCN_DO_RESET_DEFAULT (const NMMetaPropertyInfo *property_info, NMMetaAccessorModifier modifier, const char *value) +_SET_FCN_DO_RESET_DEFAULT(const NMMetaPropertyInfo *property_info, + NMMetaAccessorModifier modifier, + const char * value) { - nm_assert (property_info); - nm_assert (!property_info->property_type->set_supports_remove); - nm_assert (NM_IN_SET (modifier, NM_META_ACCESSOR_MODIFIER_SET, - NM_META_ACCESSOR_MODIFIER_ADD)); - nm_assert ( value - || modifier == NM_META_ACCESSOR_MODIFIER_SET); + nm_assert(property_info); + nm_assert(!property_info->property_type->set_supports_remove); + nm_assert(NM_IN_SET(modifier, NM_META_ACCESSOR_MODIFIER_SET, NM_META_ACCESSOR_MODIFIER_ADD)); + nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET); - return value == NULL; + return value == NULL; } static gboolean -_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (const NMMetaPropertyInfo *property_info, NMMetaAccessorModifier modifier, const char *value) +_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(const NMMetaPropertyInfo *property_info, + NMMetaAccessorModifier modifier, + const char * value) { - nm_assert (property_info); - nm_assert (property_info->property_type->set_supports_remove); - nm_assert (NM_IN_SET (modifier, NM_META_ACCESSOR_MODIFIER_SET, - NM_META_ACCESSOR_MODIFIER_ADD, - NM_META_ACCESSOR_MODIFIER_DEL)); - nm_assert ( value - || modifier == NM_META_ACCESSOR_MODIFIER_SET); + nm_assert(property_info); + nm_assert(property_info->property_type->set_supports_remove); + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET); - return value == NULL; + return value == NULL; } static gboolean -_SET_FCN_DO_SET_ALL (NMMetaAccessorModifier modifier, const char *value) +_SET_FCN_DO_SET_ALL(NMMetaAccessorModifier modifier, const char *value) { - nm_assert (NM_IN_SET (modifier, NM_META_ACCESSOR_MODIFIER_SET, - NM_META_ACCESSOR_MODIFIER_ADD, - NM_META_ACCESSOR_MODIFIER_DEL)); - nm_assert (value); + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value); - return modifier == NM_META_ACCESSOR_MODIFIER_SET; + return modifier == NM_META_ACCESSOR_MODIFIER_SET; } static gboolean -_SET_FCN_DO_REMOVE (NMMetaAccessorModifier modifier, const char *value) -{ - nm_assert (NM_IN_SET (modifier, NM_META_ACCESSOR_MODIFIER_SET, - NM_META_ACCESSOR_MODIFIER_ADD, - NM_META_ACCESSOR_MODIFIER_DEL)); - nm_assert (value); - - return modifier == NM_META_ACCESSOR_MODIFIER_DEL; -} - -#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 - -#define RETURN_STR_TEMPORARY(val) \ - G_STMT_START { \ - const char *_val = (val); \ - \ - if (_val == NULL) \ - return NULL; \ - if (_val[0] == '\0') \ - return ""; \ - return ((*(out_to_free)) = g_strdup (_val)); \ - } G_STMT_END +_SET_FCN_DO_REMOVE(NMMetaAccessorModifier modifier, const char *value) +{ + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value); + + return modifier == NM_META_ACCESSOR_MODIFIER_DEL; +} + +#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 + +#define RETURN_STR_TEMPORARY(val) \ + G_STMT_START \ + { \ + const char *_val = (val); \ + \ + if (_val == NULL) \ + return NULL; \ + if (_val[0] == '\0') \ + return ""; \ + return ((*(out_to_free)) = g_strdup(_val)); \ + } \ + G_STMT_END static gboolean -_gobject_property_is_default (NMSetting *setting, const char *prop_name) +_gobject_property_is_default(NMSetting *setting, const char *prop_name) { - nm_auto_unset_gvalue GValue v = G_VALUE_INIT; - GParamSpec *pspec; - GHashTable *ht; - char **strv; + nm_auto_unset_gvalue GValue v = G_VALUE_INIT; + GParamSpec * pspec; + GHashTable * ht; + char ** strv; - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), - prop_name); - if (!G_IS_PARAM_SPEC (pspec)) - g_return_val_if_reached (FALSE); + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); - g_value_init (&v, pspec->value_type); - g_object_get_property (G_OBJECT (setting), prop_name, &v); + g_value_init(&v, pspec->value_type); + g_object_get_property(G_OBJECT(setting), prop_name, &v); - if (pspec->value_type == G_TYPE_STRV) { - strv = g_value_get_boxed (&v); - return !strv || !strv[0]; - } else if (pspec->value_type == G_TYPE_HASH_TABLE) { - ht = g_value_get_boxed (&v); - return !ht || !g_hash_table_size (ht); - } + if (pspec->value_type == G_TYPE_STRV) { + strv = g_value_get_boxed(&v); + return !strv || !strv[0]; + } else if (pspec->value_type == G_TYPE_HASH_TABLE) { + ht = g_value_get_boxed(&v); + return !ht || !g_hash_table_size(ht); + } - return g_param_value_defaults (pspec, &v); + return g_param_value_defaults(pspec, &v); } static gboolean -_gobject_property_reset (NMSetting *setting, - const char *prop_name, - gboolean reset_default) +_gobject_property_reset(NMSetting *setting, const char *prop_name, gboolean reset_default) { - nm_auto_unset_gvalue GValue v = G_VALUE_INIT; - GParamSpec *pspec; + nm_auto_unset_gvalue GValue v = G_VALUE_INIT; + GParamSpec * pspec; - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), - prop_name); - if (!G_IS_PARAM_SPEC (pspec)) - g_return_val_if_reached (FALSE); + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); - g_value_init (&v, pspec->value_type); - if (reset_default) - g_param_value_set_default (pspec, &v); - g_object_set_property (G_OBJECT (setting), prop_name, &v); - return TRUE; + g_value_init(&v, pspec->value_type); + if (reset_default) + g_param_value_set_default(pspec, &v); + g_object_set_property(G_OBJECT(setting), prop_name, &v); + return TRUE; } static gboolean -_gobject_property_reset_default (NMSetting *setting, const char *prop_name) +_gobject_property_reset_default(NMSetting *setting, const char *prop_name) { - return _gobject_property_reset (setting, prop_name, TRUE); + return _gobject_property_reset(setting, prop_name, TRUE); } static const char * -_coerce_str_emptyunset (NMMetaAccessorGetType get_type, - gboolean is_default, - const char *cstr, - char **out_str) -{ - nm_assert (out_str && !*out_str); - nm_assert ( (!is_default && cstr && cstr[0] != '\0') - || NM_IN_STRSET (cstr, NULL, "")); - - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { - if ( !cstr - || cstr[0] == '\0') { - if (is_default) - return ""; - else - return "\"\""; - } - nm_assert (!is_default); - return (*out_str = g_strdup_printf ("\"%s\"", cstr)); - } - - /* we coerce NULL/"" to either "" or " ". */ - if ( !cstr - || cstr[0] == '\0') { - if (is_default) - return ""; - else - return " "; - } - nm_assert (!is_default); - return cstr; -} - -#define RETURN_STR_EMPTYUNSET(get_type, is_default, cstr) \ - G_STMT_START { \ - char *_str = NULL; \ - const char *_cstr; \ - \ - _cstr = _coerce_str_emptyunset ((get_type), (is_default), (cstr), &_str); \ - if (_str) \ - RETURN_STR_TO_FREE (_str); \ - RETURN_STR_TEMPORARY (_cstr); \ - } G_STMT_END +_coerce_str_emptyunset(NMMetaAccessorGetType get_type, + gboolean is_default, + const char * cstr, + char ** out_str) +{ + nm_assert(out_str && !*out_str); + nm_assert((!is_default && cstr && cstr[0] != '\0') || NM_IN_STRSET(cstr, NULL, "")); + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { + if (!cstr || cstr[0] == '\0') { + if (is_default) + return ""; + else + return "\"\""; + } + nm_assert(!is_default); + return (*out_str = g_strdup_printf("\"%s\"", cstr)); + } + + /* we coerce NULL/"" to either "" or " ". */ + if (!cstr || cstr[0] == '\0') { + if (is_default) + return ""; + else + return " "; + } + nm_assert(!is_default); + return cstr; +} + +#define RETURN_STR_EMPTYUNSET(get_type, is_default, cstr) \ + G_STMT_START \ + { \ + char * _str = NULL; \ + const char *_cstr; \ + \ + _cstr = _coerce_str_emptyunset((get_type), (is_default), (cstr), &_str); \ + if (_str) \ + RETURN_STR_TO_FREE(_str); \ + RETURN_STR_TEMPORARY(_cstr); \ + } \ + G_STMT_END static gboolean -_is_default (const NMMetaPropertyInfo *property_info, - NMSetting *setting) -{ - if ( property_info->property_typ_data - && property_info->property_typ_data->is_default_fcn) - return !!(property_info->property_typ_data->is_default_fcn (setting)); - - return _gobject_property_is_default (setting, property_info->property_name); - -} - -static gconstpointer -_get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info, - NMSetting *setting, - NMMetaAccessorGetType get_type, - gboolean handle_emptyunset, - gboolean *out_is_default, - gpointer *out_to_free) -{ - const char *cstr; - GType gtype_prop; - nm_auto_unset_gvalue GValue val = G_VALUE_INIT; - gboolean is_default; - gboolean glib_handles_str_transform; - - RETURN_UNSUPPORTED_GET_TYPE (); - - is_default = _is_default (property_info, setting); - - NM_SET_OUT (out_is_default, is_default); - - gtype_prop = _gobject_property_get_gtype (G_OBJECT (setting), property_info->property_name); - - glib_handles_str_transform = !NM_IN_SET (gtype_prop, G_TYPE_BOOLEAN, - G_TYPE_STRV, - G_TYPE_BYTES, - G_TYPE_HASH_TABLE); - - if (glib_handles_str_transform) { - /* We rely on the type convertion of the gobject property to string. */ - g_value_init (&val, G_TYPE_STRING); - } else - g_value_init (&val, gtype_prop); - - g_object_get_property (G_OBJECT (setting), property_info->property_name, &val); - - /* Currently only one particular property asks us to "handle_emptyunset". - * So, don't implement it (yet) for the other types, where it's unneeded. */ - nm_assert ( !handle_emptyunset - || ( gtype_prop == G_TYPE_STRV - && !glib_handles_str_transform)); - - if (gtype_prop == G_TYPE_STRING) { - nm_assert (glib_handles_str_transform); - nm_assert (!handle_emptyunset); - if ( property_info->property_typ_data - && property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { - /* This string property can both be empty and NULL. We need to - * signal them differently. */ - cstr = g_value_get_string (&val); - nm_assert ((!!is_default) == (cstr == NULL)); - RETURN_STR_EMPTYUNSET (get_type, is_default, NULL); - } - } - - if (glib_handles_str_transform) - RETURN_STR_TEMPORARY (g_value_get_string (&val)); - - if (gtype_prop == G_TYPE_BOOLEAN) { - gboolean b; - - b = g_value_get_boolean (&val); - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - cstr = b ? _("yes") : _("no"); - else - cstr = b ? "yes" : "no"; - return cstr; - } - - if (gtype_prop == G_TYPE_STRV) { - const char *const*strv; - - strv = g_value_get_boxed (&val); - if (strv && strv[0]) - RETURN_STR_TO_FREE (g_strjoinv (",", (char **) strv)); - - if (handle_emptyunset) { - /* we need to express empty lists from unset lists differently. */ - RETURN_STR_EMPTYUNSET (get_type, is_default, NULL); - } - - return ""; - } - - if (gtype_prop == G_TYPE_BYTES) { - char *str; - - str = bytes_to_string (g_value_get_boxed (&val)); - NM_SET_OUT (out_is_default, !str || !str[0]); - RETURN_STR_TO_FREE (str); - } - - if (gtype_prop == G_TYPE_HASH_TABLE) { - GHashTable *strdict; - gs_free const char **keys = NULL; - GString *str; - gsize i; - - nm_assert ( property_info->setting_info == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_WIRED] - && NM_IN_STRSET (property_info->property_name, NM_SETTING_WIRED_S390_OPTIONS)); - nm_assert (property_info->property_type->set_fcn == _set_fcn_optionlist); - - strdict = g_value_get_boxed (&val); - keys = nm_utils_strdict_get_keys (strdict, TRUE, NULL); - if (!keys) - return NULL; - - str = g_string_new (NULL); - for (i = 0; keys[i]; i++) { - const char *key = keys[i]; - const char *v = g_hash_table_lookup (strdict, key); - gs_free char *escaped_key = NULL; - gs_free char *escaped_val = NULL; - - if (str->len > 0) - g_string_append_c (str, ','); - g_string_append (str, nm_utils_escaped_tokens_options_escape_key (key, &escaped_key)); - g_string_append_c (str, '='); - g_string_append (str, nm_utils_escaped_tokens_options_escape_val (v, &escaped_val)); - } - RETURN_STR_TO_FREE (g_string_free (str, FALSE)); - } - - nm_assert_not_reached (); - return NULL; -} - -static gconstpointer -_get_fcn_gobject (ARGS_GET_FCN) -{ - return _get_fcn_gobject_impl (property_info, setting, get_type, FALSE, out_is_default, out_to_free); -} - -static gconstpointer -_get_fcn_gobject_int (ARGS_GET_FCN) -{ - GParamSpec *pspec; - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; - gboolean is_uint64 = FALSE; - NMMetaSignUnsignInt64 v; - guint base = 10; - const NMMetaUtilsIntValueInfo *value_infos; - char *return_str; - - RETURN_UNSUPPORTED_GET_TYPE (); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), property_info->property_name); - if (!G_IS_PARAM_SPEC (pspec)) - g_return_val_if_reached (FALSE); - - g_value_init (&gval, pspec->value_type); - g_object_get_property (G_OBJECT (setting), property_info->property_name, &gval); - NM_SET_OUT (out_is_default, g_param_value_defaults (pspec, &gval)); - switch (pspec->value_type) { - case G_TYPE_INT: - v.i64 = g_value_get_int (&gval); - break; - case G_TYPE_UINT: - v.u64 = g_value_get_uint (&gval); - is_uint64 = TRUE; - break; - case G_TYPE_INT64: - v.i64 = g_value_get_int64 (&gval); - break; - case G_TYPE_UINT64: - v.u64 = g_value_get_uint64 (&gval); - is_uint64 = TRUE; - break; - default: - g_return_val_if_reached (NULL); - break; - } - - if ( property_info->property_typ_data - && property_info->property_typ_data->subtype.gobject_int.base > 0) { - base = property_info->property_typ_data->subtype.gobject_int.base; - } - - switch (base) { - case 10: - if (is_uint64) - return_str = g_strdup_printf ("%"G_GUINT64_FORMAT, v.u64); - else - return_str = g_strdup_printf ("%"G_GINT64_FORMAT, v.i64); - break; - case 16: - if (is_uint64) - return_str = g_strdup_printf ("0x%"G_GINT64_MODIFIER"x", v.u64); - else - return_str = g_strdup_printf ("0x%"G_GINT64_MODIFIER"x", (guint64) v.i64); - break; - default: - return_str = NULL; - g_assert_not_reached (); - } - - if ( get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY - && property_info->property_typ_data - && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { - for (; value_infos->nick; value_infos++) { - if ( ( is_uint64 && value_infos->value.u64 == v.u64) - || (!is_uint64 && value_infos->value.i64 == v.i64)) { - gs_free char *old_str = return_str; - - return_str = g_strdup_printf ("%s (%s)", old_str, value_infos->nick); - break; - } - } - } - - RETURN_STR_TO_FREE (return_str); -} - -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, FALSE, out_is_default, out_to_free); - - mtu = property_info->property_typ_data->subtype.mtu.get_fcn (setting); - if (mtu == 0) { - NM_SET_OUT (out_is_default, TRUE); - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - return _("auto"); - return "auto"; - } - RETURN_STR_TO_FREE (g_strdup_printf ("%u", (unsigned) mtu)); -} - -static gconstpointer -_get_fcn_gobject_secret_flags (ARGS_GET_FCN) +_is_default(const NMMetaPropertyInfo *property_info, NMSetting *setting) { - guint v; - GValue val = G_VALUE_INIT; - - RETURN_UNSUPPORTED_GET_TYPE (); + if (property_info->property_typ_data && property_info->property_typ_data->is_default_fcn) + return !!(property_info->property_typ_data->is_default_fcn(setting)); - 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_STR_TO_FREE (secret_flags_to_string (v, get_type)); + return _gobject_property_is_default(setting, property_info->property_name); } static gconstpointer -_get_fcn_gobject_enum (ARGS_GET_FCN) -{ - GType gtype = 0; - nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; - nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; - const struct _NMUtilsEnumValueInfo *value_infos = NULL; - gboolean has_gtype = FALSE; - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; - gint64 v; - gboolean format_numeric = FALSE; - gboolean format_numeric_hex = FALSE; - gboolean format_numeric_hex_unknown = FALSE; - gboolean format_text = FALSE; - gboolean format_text_l10n = FALSE; - gs_free char *s = NULL; - char s_numeric[64]; - GParamSpec *pspec; - - 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 (); - has_gtype = TRUE; - } - } - - if ( property_info->property_typ_data - && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY - && NM_FLAGS_ANY (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC - | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX - | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT - | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N)) { - format_numeric_hex = NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX); - format_numeric = format_numeric_hex || NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC); - format_text_l10n = NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N); - format_text = format_text_l10n || NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT); - } else if ( property_info->property_typ_data - && get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY - && NM_FLAGS_ANY (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC - | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX - | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT)) { - format_numeric_hex = NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX); - format_numeric = format_numeric && NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC); - format_text = NM_FLAGS_HAS (property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT); - } else if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { - /* by default, output in format "%u (%s)" (with hex for flags and l10n). */ - format_numeric = TRUE; - format_numeric_hex_unknown = TRUE; - format_text = TRUE; - format_text_l10n = TRUE; - } else { - /* by default, output only numeric (with hex for flags). */ - format_numeric = TRUE; - format_numeric_hex_unknown = TRUE; - } - - nm_assert (format_text || format_numeric); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_info->property_name); - g_return_val_if_fail (pspec, NULL); - - g_value_init (&gval, pspec->value_type); - g_object_get_property (G_OBJECT (setting), property_info->property_name, &gval); - NM_SET_OUT (out_is_default, g_param_value_defaults (pspec, &gval)); - - if ( pspec->value_type == G_TYPE_INT - || ( G_TYPE_IS_CLASSED (pspec->value_type) - && G_IS_ENUM_CLASS ((gtype_prop_class ?: (gtype_prop_class = g_type_class_ref (pspec->value_type)))))) { - if (pspec->value_type == G_TYPE_INT) { - if (!has_gtype) - g_return_val_if_reached (NULL); - v = g_value_get_int (&gval); - } else - v = g_value_get_enum (&gval); - } else if ( pspec->value_type == G_TYPE_UINT - || ( G_TYPE_IS_CLASSED (pspec->value_type) - && G_IS_FLAGS_CLASS ((gtype_prop_class ?: (gtype_prop_class = g_type_class_ref (pspec->value_type)))))) { - if (pspec->value_type == G_TYPE_UINT) { - if (!has_gtype) - g_return_val_if_reached (NULL); - v = g_value_get_uint (&gval); - } else - v = g_value_get_flags (&gval); - } else - g_return_val_if_reached (NULL); - - if (!has_gtype) { - gtype = pspec->value_type; - gtype_class = g_steal_pointer (>ype_prop_class); - } - - nm_assert (({ - nm_auto_unref_gtypeclass GTypeClass *t = NULL; - - ( G_TYPE_IS_CLASSED (gtype) - && (t = g_type_class_ref (gtype)) - && (G_IS_ENUM_CLASS (t) || G_IS_FLAGS_CLASS (t))); - })); - - if (format_numeric && !format_text) { - 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_MODIFIER"x", v) - : g_strdup_printf ("%"G_GINT64_FORMAT, v); - RETURN_STR_TO_FREE (g_steal_pointer (&s)); - } - - /* the gobject_enum.value_infos are currently ignored for the getter. They - * only declare additional aliases for the setter. */ - - if (property_info->property_typ_data) - value_infos = property_info->property_typ_data->subtype.gobject_enum.value_infos_get; - s = _nm_utils_enum_to_str_full (gtype, (int) v, ", ", value_infos); - - if (!format_numeric) - RETURN_STR_TO_FREE (g_steal_pointer (&s)); - - if ( format_numeric_hex - || ( format_numeric_hex_unknown - && !G_IS_ENUM_CLASS (gtype_class ?: (gtype_class = g_type_class_ref (gtype))))) - nm_sprintf_buf (s_numeric, "0x%"G_GINT64_MODIFIER"x", v); - else - nm_sprintf_buf (s_numeric, "%"G_GINT64_FORMAT, v); - - if (nm_streq0 (s, s_numeric)) - RETURN_STR_TO_FREE (g_steal_pointer (&s)); - - if (format_text_l10n) - RETURN_STR_TO_FREE (g_strdup_printf (_("%s (%s)"), s_numeric, s)); - else - RETURN_STR_TO_FREE (g_strdup_printf ("%s (%s)", s_numeric, s)); +_get_fcn_gobject_impl(const NMMetaPropertyInfo *property_info, + NMSetting * setting, + NMMetaAccessorGetType get_type, + gboolean handle_emptyunset, + gboolean * out_is_default, + gpointer * out_to_free) +{ + const char * cstr; + GType gtype_prop; + nm_auto_unset_gvalue GValue val = G_VALUE_INIT; + gboolean is_default; + gboolean glib_handles_str_transform; + + RETURN_UNSUPPORTED_GET_TYPE(); + + is_default = _is_default(property_info, setting); + + NM_SET_OUT(out_is_default, is_default); + + gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); + + glib_handles_str_transform = + !NM_IN_SET(gtype_prop, G_TYPE_BOOLEAN, G_TYPE_STRV, G_TYPE_BYTES, G_TYPE_HASH_TABLE); + + if (glib_handles_str_transform) { + /* We rely on the type conversion of the gobject property to string. */ + g_value_init(&val, G_TYPE_STRING); + } else + g_value_init(&val, gtype_prop); + + g_object_get_property(G_OBJECT(setting), property_info->property_name, &val); + + /* Currently, only one particular property asks us to "handle_emptyunset". + * So, don't implement it (yet) for the other types, where it's unneeded. */ + nm_assert(!handle_emptyunset || (gtype_prop == G_TYPE_STRV && !glib_handles_str_transform)); + + if (gtype_prop == G_TYPE_STRING) { + nm_assert(glib_handles_str_transform); + nm_assert(!handle_emptyunset); + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { + /* This string property can both be empty and NULL. We need to + * signal them differently. */ + cstr = g_value_get_string(&val); + nm_assert((!!is_default) == (cstr == NULL)); + RETURN_STR_EMPTYUNSET(get_type, is_default, NULL); + } + } + + if (glib_handles_str_transform) + RETURN_STR_TEMPORARY(g_value_get_string(&val)); + + if (gtype_prop == G_TYPE_BOOLEAN) { + gboolean b; + + b = g_value_get_boolean(&val); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + cstr = b ? _("yes") : _("no"); + else + cstr = b ? "yes" : "no"; + return cstr; + } + + if (gtype_prop == G_TYPE_STRV) { + const char *const *strv; + + strv = g_value_get_boxed(&val); + if (strv && strv[0]) + RETURN_STR_TO_FREE(g_strjoinv(",", (char **) strv)); + + if (handle_emptyunset) { + /* we need to express empty lists from unset lists differently. */ + RETURN_STR_EMPTYUNSET(get_type, is_default, NULL); + } + + return ""; + } + + if (gtype_prop == G_TYPE_BYTES) { + char *str; + + str = bytes_to_string(g_value_get_boxed(&val)); + NM_SET_OUT(out_is_default, !str || !str[0]); + RETURN_STR_TO_FREE(str); + } + + if (gtype_prop == G_TYPE_HASH_TABLE) { + GHashTable * strdict; + gs_free const char **keys = NULL; + GString * str; + gsize i; + + nm_assert(property_info->setting_info + == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_WIRED] + && NM_IN_STRSET(property_info->property_name, NM_SETTING_WIRED_S390_OPTIONS)); + nm_assert(property_info->property_type->set_fcn == _set_fcn_optionlist); + + strdict = g_value_get_boxed(&val); + keys = nm_utils_strdict_get_keys(strdict, TRUE, NULL); + if (!keys) + return NULL; + + str = g_string_new(NULL); + for (i = 0; keys[i]; i++) { + const char * key = keys[i]; + const char * v = g_hash_table_lookup(strdict, key); + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; + + if (str->len > 0) + g_string_append_c(str, ','); + g_string_append(str, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key)); + g_string_append_c(str, '='); + g_string_append(str, nm_utils_escaped_tokens_options_escape_val(v, &escaped_val)); + } + RETURN_STR_TO_FREE(g_string_free(str, FALSE)); + } + + nm_assert_not_reached(); + return NULL; +} + +static gconstpointer _get_fcn_gobject(ARGS_GET_FCN) +{ + return _get_fcn_gobject_impl(property_info, + setting, + get_type, + FALSE, + out_is_default, + out_to_free); +} + +static gconstpointer _get_fcn_gobject_int(ARGS_GET_FCN) +{ + GParamSpec * pspec; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gboolean is_uint64 = FALSE; + NMMetaSignUnsignInt64 v; + guint base = 10; + const NMMetaUtilsIntValueInfo *value_infos; + char * return_str; + + RETURN_UNSUPPORTED_GET_TYPE(); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + g_value_init(&gval, pspec->value_type); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval); + NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval)); + switch (pspec->value_type) { + case G_TYPE_INT: + v.i64 = g_value_get_int(&gval); + break; + case G_TYPE_UINT: + v.u64 = g_value_get_uint(&gval); + is_uint64 = TRUE; + break; + case G_TYPE_INT64: + v.i64 = g_value_get_int64(&gval); + break; + case G_TYPE_UINT64: + v.u64 = g_value_get_uint64(&gval); + is_uint64 = TRUE; + break; + default: + g_return_val_if_reached(NULL); + break; + } + + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_int.base > 0) { + base = property_info->property_typ_data->subtype.gobject_int.base; + } + + switch (base) { + case 10: + if (is_uint64) + return_str = g_strdup_printf("%" G_GUINT64_FORMAT, v.u64); + else + return_str = g_strdup_printf("%" G_GINT64_FORMAT, v.i64); + break; + case 16: + if (is_uint64) + return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", v.u64); + else + return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", (guint64) v.i64); + break; + default: + return_str = NULL; + g_assert_not_reached(); + } + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY && property_info->property_typ_data + && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { + for (; value_infos->nick; value_infos++) { + if ((is_uint64 && value_infos->value.u64 == v.u64) + || (!is_uint64 && value_infos->value.i64 == v.i64)) { + gs_free char *old_str = return_str; + + return_str = g_strdup_printf("%s (%s)", old_str, value_infos->nick); + break; + } + } + } + + RETURN_STR_TO_FREE(return_str); +} + +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, + FALSE, + out_is_default, + out_to_free); + + mtu = property_info->property_typ_data->subtype.mtu.get_fcn(setting); + if (mtu == 0) { + NM_SET_OUT(out_is_default, TRUE); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _("auto"); + return "auto"; + } + RETURN_STR_TO_FREE(g_strdup_printf("%u", (unsigned) mtu)); +} + +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_STR_TO_FREE(secret_flags_to_string(v, get_type)); +} + +static gconstpointer _get_fcn_gobject_enum(ARGS_GET_FCN) +{ + GType gtype = 0; + nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; + nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; + const struct _NMUtilsEnumValueInfo * value_infos = NULL; + gboolean has_gtype = FALSE; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gint64 v; + gboolean format_numeric = FALSE; + gboolean format_numeric_hex = FALSE; + gboolean format_numeric_hex_unknown = FALSE; + gboolean format_text = FALSE; + gboolean format_text_l10n = FALSE; + gs_free char * s = NULL; + char s_numeric[64]; + GParamSpec * pspec; + + 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(); + has_gtype = TRUE; + } + } + + if (property_info->property_typ_data && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY + && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N)) { + format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX); + format_numeric = format_numeric_hex + || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC); + format_text_l10n = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N); + format_text = format_text_l10n + || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT); + } else if (property_info->property_typ_data && get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY + && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT)) { + format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX); + format_numeric = format_numeric + && NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC); + format_text = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT); + } else if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { + /* by default, output in format "%u (%s)" (with hex for flags and l10n). */ + format_numeric = TRUE; + format_numeric_hex_unknown = TRUE; + format_text = TRUE; + format_text_l10n = TRUE; + } else { + /* by default, output only numeric (with hex for flags). */ + format_numeric = TRUE; + format_numeric_hex_unknown = TRUE; + } + + nm_assert(format_text || format_numeric); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property_info->property_name); + g_return_val_if_fail(pspec, NULL); + + g_value_init(&gval, pspec->value_type); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval); + NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval)); + + if (pspec->value_type == G_TYPE_INT + || (G_TYPE_IS_CLASSED(pspec->value_type) + && G_IS_ENUM_CLASS( + (gtype_prop_class ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) { + if (pspec->value_type == G_TYPE_INT) { + if (!has_gtype) + g_return_val_if_reached(NULL); + v = g_value_get_int(&gval); + } else + v = g_value_get_enum(&gval); + } else if (pspec->value_type == G_TYPE_UINT + || (G_TYPE_IS_CLASSED(pspec->value_type) + && G_IS_FLAGS_CLASS( + (gtype_prop_class + ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) { + if (pspec->value_type == G_TYPE_UINT) { + if (!has_gtype) + g_return_val_if_reached(NULL); + v = g_value_get_uint(&gval); + } else + v = g_value_get_flags(&gval); + } else + g_return_val_if_reached(NULL); + + if (!has_gtype) { + gtype = pspec->value_type; + gtype_class = g_steal_pointer(>ype_prop_class); + } + + nm_assert(({ + nm_auto_unref_gtypeclass GTypeClass *t = NULL; + + (G_TYPE_IS_CLASSED(gtype) && (t = g_type_class_ref(gtype)) + && (G_IS_ENUM_CLASS(t) || G_IS_FLAGS_CLASS(t))); + })); + + if (format_numeric && !format_text) { + 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_MODIFIER "x", v) + : g_strdup_printf("%" G_GINT64_FORMAT, v); + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + } + + /* the gobject_enum.value_infos are currently ignored for the getter. They + * only declare additional aliases for the setter. */ + + if (property_info->property_typ_data) + value_infos = property_info->property_typ_data->subtype.gobject_enum.value_infos_get; + s = _nm_utils_enum_to_str_full(gtype, (int) v, ", ", value_infos); + + if (!format_numeric) + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + + if (format_numeric_hex + || (format_numeric_hex_unknown + && !G_IS_ENUM_CLASS(gtype_class ?: (gtype_class = g_type_class_ref(gtype))))) + nm_sprintf_buf(s_numeric, "0x%" G_GINT64_MODIFIER "x", v); + else + nm_sprintf_buf(s_numeric, "%" G_GINT64_FORMAT, v); + + if (nm_streq0(s, s_numeric)) + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + + if (format_text_l10n) + RETURN_STR_TO_FREE(g_strdup_printf(_("%s (%s)"), s_numeric, s)); + else + RETURN_STR_TO_FREE(g_strdup_printf("%s (%s)", s_numeric, s)); } /*****************************************************************************/ -static gboolean -_set_fcn_gobject_string (ARGS_SET_FCN) -{ - gs_free char *to_free = NULL; - - if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - if (property_info->property_typ_data) { - if (property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { - if ( value - && value[0] - && NM_STRCHAR_ALL (value, ch, ch == ' ')) { - /* this string property can both be %NULL and empty. To express that, we coerce - * a value of all whitespaces to dropping the first whitespace. That means, - * " " gives "", " " gives " ", and so on. - * - * This way the user can set the string value to "" (meaning NULL) and to - * " " (meaning ""), and any other string. - * - * This is and non-obvious escaping mechanism. But out of all the possible - * solutions, it seems the most sensible one. */ - value++; - } - } - if (property_info->property_typ_data->subtype.gobject_string.validate_fcn) { - value = property_info->property_typ_data->subtype.gobject_string.validate_fcn (value, &to_free, error); - if (!value) - return FALSE; - } else if (property_info->property_typ_data->values_static) { - value = nmc_string_is_valid (value, - (const char **) property_info->property_typ_data->values_static, - error); - if (!value) - return FALSE; - } - } - g_object_set (setting, property_info->property_name, value, NULL); - return TRUE; -} - -static gboolean -_set_fcn_gobject_bool (ARGS_SET_FCN) -{ - gboolean val_bool; - - if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - if (!nmc_string_to_bool (value, &val_bool, error)) - return FALSE; - - g_object_set (setting, property_info->property_name, val_bool, NULL); - return TRUE; -} - -static gboolean -_set_fcn_gobject_int (ARGS_SET_FCN) -{ - int errsv; - const GParamSpec *pspec; - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; - gboolean is_uint64; - NMMetaSignUnsignInt64 v; - gboolean has_minmax = FALSE; - NMMetaSignUnsignInt64 min = { 0 }; - NMMetaSignUnsignInt64 max = { 0 }; - guint base = 10; - const NMMetaUtilsIntValueInfo *value_infos; - - if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), property_info->property_name); - if (!G_IS_PARAM_SPEC (pspec)) - g_return_val_if_reached (FALSE); - - is_uint64 = NM_IN_SET (pspec->value_type, G_TYPE_UINT, G_TYPE_UINT64); - - if (property_info->property_typ_data) { - if ( value - && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { - gs_free char *vv_free = NULL; - const char *vv; - - vv = nm_strstrip_avoid_copy_a (300, value, &vv_free); - for (; value_infos->nick; value_infos++) { - if (nm_streq (value_infos->nick, vv)) { - v = value_infos->value; - goto have_value_from_nick; - } - } - } - - if (property_info->property_typ_data->subtype.gobject_int.base > 0) - base = property_info->property_typ_data->subtype.gobject_int.base; - - if ( ( is_uint64 - && ( property_info->property_typ_data->subtype.gobject_int.min.u64 - || property_info->property_typ_data->subtype.gobject_int.max.u64)) - || ( !is_uint64 - && ( property_info->property_typ_data->subtype.gobject_int.min.i64 - || property_info->property_typ_data->subtype.gobject_int.max.i64))) { - min = property_info->property_typ_data->subtype.gobject_int.min; - max = property_info->property_typ_data->subtype.gobject_int.max; - has_minmax = TRUE; - } - } - - if (!has_minmax) { - switch (pspec->value_type) { - case G_TYPE_INT: - { - const GParamSpecInt *p = (GParamSpecInt *) pspec; - - min.i64 = p->minimum; - max.i64 = p->maximum; - } - break; - case G_TYPE_UINT: - { - const GParamSpecUInt *p = (GParamSpecUInt *) pspec; - - min.u64 = p->minimum; - max.u64 = p->maximum; - } - break; - case G_TYPE_INT64: - { - const GParamSpecInt64 *p = (GParamSpecInt64 *) pspec; - - min.i64 = p->minimum; - max.i64 = p->maximum; - } - break; - case G_TYPE_UINT64: - { - const GParamSpecUInt64 *p = (GParamSpecUInt64 *) pspec; - - min.u64 = p->minimum; - max.u64 = p->maximum; - } - break; - default: - g_return_val_if_reached (FALSE); - } - } - - if (is_uint64) - v.u64 = _nm_utils_ascii_str_to_uint64 (value, base, min.u64, max.u64, 0); - else - v.i64 = _nm_utils_ascii_str_to_int64 (value, base, min.i64, max.i64, 0); - - if ((errsv = errno) != 0) { - if (errsv == ERANGE) { - if (is_uint64) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is out of range [%"G_GUINT64_FORMAT", %"G_GUINT64_FORMAT"]"), - value, min.u64, max.u64); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is out of range [%"G_GINT64_FORMAT", %"G_GINT64_FORMAT"]"), - value, min.i64, max.i64); - } - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is not a valid number"), value); - } - return FALSE; - } +static gboolean _set_fcn_gobject_string(ARGS_SET_FCN) +{ + gs_free char *to_free = NULL; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { + if (value && value[0] && NM_STRCHAR_ALL(value, ch, ch == ' ')) { + /* this string property can both be %NULL and empty. To express that, we coerce + * a value of all whitespaces to dropping the first whitespace. That means, + * " " gives "", " " gives " ", and so on. + * + * This way the user can set the string value to "" (meaning NULL) and to + * " " (meaning ""), and any other string. + * + * This is and non-obvious escaping mechanism. But out of all the possible + * solutions, it seems the most sensible one. */ + value++; + } + } + if (property_info->property_typ_data->subtype.gobject_string.validate_fcn) { + value = property_info->property_typ_data->subtype.gobject_string.validate_fcn(value, + &to_free, + error); + if (!value) + return FALSE; + } else if (property_info->property_typ_data->values_static) { + value = + nmc_string_is_valid(value, + (const char **) property_info->property_typ_data->values_static, + error); + if (!value) + return FALSE; + } + } + g_object_set(setting, property_info->property_name, value, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_bool(ARGS_SET_FCN) +{ + gboolean val_bool; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (!nmc_string_to_bool(value, &val_bool, error)) + return FALSE; + + g_object_set(setting, property_info->property_name, val_bool, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_int(ARGS_SET_FCN) +{ + int errsv; + const GParamSpec * pspec; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gboolean is_uint64; + NMMetaSignUnsignInt64 v; + gboolean has_minmax = FALSE; + NMMetaSignUnsignInt64 min = {0}; + NMMetaSignUnsignInt64 max = {0}; + guint base = 10; + const NMMetaUtilsIntValueInfo *value_infos; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + is_uint64 = NM_IN_SET(pspec->value_type, G_TYPE_UINT, G_TYPE_UINT64); + + if (property_info->property_typ_data) { + if (value + && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { + gs_free char *vv_free = NULL; + const char * vv; + + vv = nm_strstrip_avoid_copy_a(300, value, &vv_free); + for (; value_infos->nick; value_infos++) { + if (nm_streq(value_infos->nick, vv)) { + v = value_infos->value; + goto have_value_from_nick; + } + } + } + + if (property_info->property_typ_data->subtype.gobject_int.base > 0) + base = property_info->property_typ_data->subtype.gobject_int.base; + + if ((is_uint64 + && (property_info->property_typ_data->subtype.gobject_int.min.u64 + || property_info->property_typ_data->subtype.gobject_int.max.u64)) + || (!is_uint64 + && (property_info->property_typ_data->subtype.gobject_int.min.i64 + || property_info->property_typ_data->subtype.gobject_int.max.i64))) { + min = property_info->property_typ_data->subtype.gobject_int.min; + max = property_info->property_typ_data->subtype.gobject_int.max; + has_minmax = TRUE; + } + } + + if (!has_minmax) { + switch (pspec->value_type) { + case G_TYPE_INT: + { + const GParamSpecInt *p = (GParamSpecInt *) pspec; + + min.i64 = p->minimum; + max.i64 = p->maximum; + } break; + case G_TYPE_UINT: + { + const GParamSpecUInt *p = (GParamSpecUInt *) pspec; + + min.u64 = p->minimum; + max.u64 = p->maximum; + } break; + case G_TYPE_INT64: + { + const GParamSpecInt64 *p = (GParamSpecInt64 *) pspec; + + min.i64 = p->minimum; + max.i64 = p->maximum; + } break; + case G_TYPE_UINT64: + { + const GParamSpecUInt64 *p = (GParamSpecUInt64 *) pspec; + + min.u64 = p->minimum; + max.u64 = p->maximum; + } break; + default: + g_return_val_if_reached(FALSE); + } + } + + if (is_uint64) + v.u64 = _nm_utils_ascii_str_to_uint64(value, base, min.u64, max.u64, 0); + else + v.i64 = _nm_utils_ascii_str_to_int64(value, base, min.i64, max.i64, 0); + + if ((errsv = errno) != 0) { + if (errsv == ERANGE) { + if (is_uint64) { + g_set_error( + error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [%" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT "]"), + value, + min.u64, + max.u64); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [%" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "]"), + value, + min.i64, + max.i64); + } + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not a valid number"), + value); + } + return FALSE; + } have_value_from_nick: - g_value_init (&gval, pspec->value_type); - switch (pspec->value_type) { - case G_TYPE_INT: - g_value_set_int (&gval, v.i64); - break; - case G_TYPE_UINT: - g_value_set_uint (&gval, v.u64); - break; - case G_TYPE_INT64: - g_value_set_int64 (&gval, v.i64); - break; - case G_TYPE_UINT64: - g_value_set_uint64 (&gval, v.u64); - break; - default: - g_return_val_if_reached (FALSE); - break; - } - - /* Validate the number according to the property spec */ - if (!nm_g_object_set_property (G_OBJECT (setting), - property_info->property_name, - &gval, - error)) - g_return_val_if_reached (FALSE); - - return TRUE; -} - -static gboolean -_set_fcn_gobject_mtu (ARGS_SET_FCN) -{ - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; - const GParamSpec *pspec; - gint64 v; - - if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - if (nm_streq (value, "auto")) - value = "0"; - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), - property_info->property_name); - if (!pspec || pspec->value_type != G_TYPE_UINT) - g_return_val_if_reached (FALSE); - - v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); - if (v < 0) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is out of range [0, %u]"), value, (unsigned) G_MAXUINT32); - return FALSE; - } - - g_value_init (&gval, pspec->value_type); - g_value_set_uint (&gval, v); - - if (!nm_g_object_set_property (G_OBJECT (setting), - property_info->property_name, - &gval, - error)) - g_return_val_if_reached (FALSE); - - return TRUE; + g_value_init(&gval, pspec->value_type); + switch (pspec->value_type) { + case G_TYPE_INT: + g_value_set_int(&gval, v.i64); + break; + case G_TYPE_UINT: + g_value_set_uint(&gval, v.u64); + break; + case G_TYPE_INT64: + g_value_set_int64(&gval, v.i64); + break; + case G_TYPE_UINT64: + g_value_set_uint64(&gval, v.u64); + break; + default: + g_return_val_if_reached(FALSE); + break; + } + + /* Validate the number according to the property spec */ + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error)) + g_return_val_if_reached(FALSE); + + return TRUE; +} + +static gboolean _set_fcn_gobject_mtu(ARGS_SET_FCN) +{ + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + const GParamSpec * pspec; + gint64 v; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (nm_streq(value, "auto")) + value = "0"; + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!pspec || pspec->value_type != G_TYPE_UINT) + g_return_val_if_reached(FALSE); + + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1); + if (v < 0) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [0, %u]"), + value, + (unsigned) G_MAXUINT32); + return FALSE; + } + + g_value_init(&gval, pspec->value_type); + g_value_set_uint(&gval, v); + + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error)) + g_return_val_if_reached(FALSE); + + return TRUE; } /* Ideally we'll be able to get this from a public header. */ #ifndef IEEE802154_ADDR_LEN -#define IEEE802154_ADDR_LEN 8 + #define IEEE802154_ADDR_LEN 8 #endif -static gboolean -_set_fcn_gobject_mac (ARGS_SET_FCN) -{ - NMMetaPropertyTypeMacMode mode; - gboolean valid; - - if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - if (property_info->property_typ_data) - mode = property_info->property_typ_data->subtype.mac.mode; - else - mode = NM_META_PROPERTY_TYPE_MAC_MODE_DEFAULT; - - if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND) { - valid = nm_utils_hwaddr_valid (value, INFINIBAND_ALEN); - } else if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_WPAN) { - valid = nm_utils_hwaddr_valid (value, IEEE802154_ADDR_LEN); - } else { - valid = nm_utils_hwaddr_valid (value, ETH_ALEN) - || ( mode == NM_META_PROPERTY_TYPE_MAC_MODE_CLONED - && NM_CLONED_MAC_IS_SPECIAL (value)); - } - - if (!valid) { - g_set_error (error, 1, 0, _("'%s' is not a valid Ethernet MAC"), value); - return FALSE; - } - - g_object_set (setting, property_info->property_name, value, NULL); - return TRUE; -} - -static gboolean -_set_fcn_gobject_enum (ARGS_SET_FCN) -{ - GType gtype = 0; - GType gtype_prop; - gboolean has_gtype = FALSE; - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; - nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; - nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; - gboolean is_flags; - int v; - - if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - 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 (); - has_gtype = TRUE; - } - } - - gtype_prop = _gobject_property_get_gtype (G_OBJECT (setting), property_info->property_name); - - if ( has_gtype - && NM_IN_SET (gtype_prop, - G_TYPE_INT, - G_TYPE_UINT) - && G_TYPE_IS_CLASSED (gtype) - && (gtype_prop_class = g_type_class_ref (gtype)) - && ( (is_flags = G_IS_FLAGS_CLASS (gtype_prop_class)) - || G_IS_ENUM_CLASS (gtype_prop_class))) { - /* valid */ - } else if ( !has_gtype - && G_TYPE_IS_CLASSED (gtype_prop) - && (gtype_prop_class = g_type_class_ref (gtype_prop)) - && ( (is_flags = G_IS_FLAGS_CLASS (gtype_prop_class)) - || G_IS_ENUM_CLASS (gtype_prop_class))) { - gtype = gtype_prop; - } else - g_return_val_if_reached (FALSE); - - if (!_nm_utils_enum_from_str_full (gtype, value, &v, NULL, - property_info->property_typ_data - ? property_info->property_typ_data->subtype.gobject_enum.value_infos - : NULL)) - goto fail; - - if ( property_info->property_typ_data - && property_info->property_typ_data->subtype.gobject_enum.pre_set_notify) { - property_info->property_typ_data->subtype.gobject_enum.pre_set_notify (property_info, - environment, - environment_user_data, - setting, - v); - } - - gtype_class = g_type_class_ref (gtype); - - if ( G_IS_FLAGS_CLASS (gtype_class) - && !_SET_FCN_DO_SET_ALL (modifier, value)) { - nm_auto_unset_gvalue GValue int_value = { }; - guint v_flag; - - g_value_init (&int_value, G_TYPE_UINT); - g_object_get_property (G_OBJECT (setting), property_info->property_name, &int_value); - v_flag = g_value_get_uint (&int_value); - - if (_SET_FCN_DO_REMOVE (modifier, value)) - v = (int) (v_flag & ~((guint) v)); - else - v = (int) (v_flag | ((guint) v)); - } - - g_value_init (&gval, gtype_prop); - if (gtype_prop == G_TYPE_INT) - g_value_set_int (&gval, v); - else if (gtype_prop == G_TYPE_UINT) - g_value_set_uint (&gval, v); - else if (is_flags) { - nm_assert (G_IS_FLAGS_CLASS (gtype_prop_class)); - g_value_set_flags (&gval, v); - } else { - nm_assert (G_IS_ENUM_CLASS (gtype_prop_class)); - g_value_set_enum (&gval, v); - } - - if (!nm_g_object_set_property (G_OBJECT (setting), property_info->property_name, &gval, NULL)) - goto fail; - - return TRUE; +static gboolean _set_fcn_gobject_mac(ARGS_SET_FCN) +{ + NMMetaPropertyTypeMacMode mode; + gboolean valid; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (property_info->property_typ_data) + mode = property_info->property_typ_data->subtype.mac.mode; + else + mode = NM_META_PROPERTY_TYPE_MAC_MODE_DEFAULT; + + if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND) { + valid = nm_utils_hwaddr_valid(value, INFINIBAND_ALEN); + } else if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_WPAN) { + valid = nm_utils_hwaddr_valid(value, IEEE802154_ADDR_LEN); + } else { + valid = + nm_utils_hwaddr_valid(value, ETH_ALEN) + || (mode == NM_META_PROPERTY_TYPE_MAC_MODE_CLONED && NM_CLONED_MAC_IS_SPECIAL(value)); + } + + if (!valid) { + g_set_error(error, 1, 0, _("'%s' is not a valid Ethernet MAC"), value); + return FALSE; + } + + g_object_set(setting, property_info->property_name, value, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_enum(ARGS_SET_FCN) +{ + GType gtype = 0; + GType gtype_prop; + gboolean has_gtype = FALSE; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; + nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; + gboolean is_flags; + int v; + + if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + 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(); + has_gtype = TRUE; + } + } + + gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); + + if (has_gtype && NM_IN_SET(gtype_prop, G_TYPE_INT, G_TYPE_UINT) && G_TYPE_IS_CLASSED(gtype) + && (gtype_prop_class = g_type_class_ref(gtype)) + && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class)) || G_IS_ENUM_CLASS(gtype_prop_class))) { + /* valid */ + } else if (!has_gtype && G_TYPE_IS_CLASSED(gtype_prop) + && (gtype_prop_class = g_type_class_ref(gtype_prop)) + && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class)) + || G_IS_ENUM_CLASS(gtype_prop_class))) { + gtype = gtype_prop; + } else + g_return_val_if_reached(FALSE); + + if (!_nm_utils_enum_from_str_full( + gtype, + value, + &v, + NULL, + property_info->property_typ_data + ? property_info->property_typ_data->subtype.gobject_enum.value_infos + : NULL)) + goto fail; + + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_enum.pre_set_notify) { + property_info->property_typ_data->subtype.gobject_enum.pre_set_notify(property_info, + environment, + environment_user_data, + setting, + v); + } + + gtype_class = g_type_class_ref(gtype); + + if (G_IS_FLAGS_CLASS(gtype_class) && !_SET_FCN_DO_SET_ALL(modifier, value)) { + nm_auto_unset_gvalue GValue int_value = {}; + guint v_flag; + + g_value_init(&int_value, G_TYPE_UINT); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &int_value); + v_flag = g_value_get_uint(&int_value); + + if (_SET_FCN_DO_REMOVE(modifier, value)) + v = (int) (v_flag & ~((guint) v)); + else + v = (int) (v_flag | ((guint) v)); + } + + g_value_init(&gval, gtype_prop); + if (gtype_prop == G_TYPE_INT) + g_value_set_int(&gval, v); + else if (gtype_prop == G_TYPE_UINT) + g_value_set_uint(&gval, v); + else if (is_flags) { + nm_assert(G_IS_FLAGS_CLASS(gtype_prop_class)); + g_value_set_flags(&gval, v); + } else { + nm_assert(G_IS_ENUM_CLASS(gtype_prop_class)); + g_value_set_enum(&gval, v); + } + + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, NULL)) + goto fail; + + return TRUE; fail: - if (error) { - gs_free const char **valid_all = NULL; - gs_free const char *valid_str = NULL; - gboolean has_minmax = FALSE; - int min = G_MININT; - int max = G_MAXINT; - - if (property_info->property_typ_data) { - if ( property_info->property_typ_data->subtype.gobject_enum.min - || property_info->property_typ_data->subtype.gobject_enum.max) { - min = property_info->property_typ_data->subtype.gobject_enum.min; - max = property_info->property_typ_data->subtype.gobject_enum.max; - has_minmax = TRUE; - } - } - - if (!has_minmax && is_flags) { - min = 0; - max = (int) G_MAXUINT; - } - - valid_all = nm_utils_enum_get_values (gtype, min, max); - valid_str = g_strjoinv (",", (char **) valid_all); - if (is_flags) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("invalid option '%s', use a combination of [%s]"), - value, - valid_str); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("invalid option '%s', use one of [%s]"), - value, - valid_str); - } - } - return FALSE; + if (error) { + gs_free const char **valid_all = NULL; + gs_free const char * valid_str = NULL; + gboolean has_minmax = FALSE; + int min = G_MININT; + int max = G_MAXINT; + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.min + || property_info->property_typ_data->subtype.gobject_enum.max) { + min = property_info->property_typ_data->subtype.gobject_enum.min; + max = property_info->property_typ_data->subtype.gobject_enum.max; + has_minmax = TRUE; + } + } + + if (!has_minmax && is_flags) { + min = 0; + max = (int) G_MAXUINT; + } + + valid_all = nm_utils_enum_get_values(gtype, min, max); + valid_str = g_strjoinv(",", (char **) valid_all); + if (is_flags) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid option '%s', use a combination of [%s]"), + value, + valid_str); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid option '%s', use one of [%s]"), + value, + valid_str); + } + } + return FALSE; } /*****************************************************************************/ -static const char *const* -_values_fcn_gobject_enum (ARGS_VALUES_FCN) -{ - GType gtype = 0; - gboolean has_gtype = FALSE; - gboolean has_minmax = FALSE; - int min = G_MININT; - int max = G_MAXINT; - char **v; - - if (property_info->property_typ_data) { - if ( property_info->property_typ_data->subtype.gobject_enum.min - || property_info->property_typ_data->subtype.gobject_enum.max) { - min = property_info->property_typ_data->subtype.gobject_enum.min; - max = property_info->property_typ_data->subtype.gobject_enum.max; - has_minmax = TRUE; - } - if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { - gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype (); - has_gtype = TRUE; - } - } - - if (!has_gtype) { - gtype = _gtype_property_get_gtype (property_info->setting_info->general->get_setting_gtype (), - property_info->property_name); - } - - if ( !has_minmax - && G_TYPE_IS_CLASSED (gtype)) { - nm_auto_unref_gtypeclass GTypeClass *class = NULL; - - class = g_type_class_ref (gtype); - if (G_IS_FLAGS_CLASS (class)) { - min = 0; - max = (int) G_MAXUINT; - } - } - - /* the gobject_enum.value_infos are currently ignored for the list of - * values. They only declare additional (hidden) aliases for the setter. */ - - v = nm_utils_strv_make_deep_copied (nm_utils_enum_get_values (gtype, min, max)); - return (const char *const*) (*out_to_free = v); +static const char *const *_values_fcn_gobject_enum(ARGS_VALUES_FCN) +{ + GType gtype = 0; + gboolean has_gtype = FALSE; + gboolean has_minmax = FALSE; + int min = G_MININT; + int max = G_MAXINT; + char ** v; + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.min + || property_info->property_typ_data->subtype.gobject_enum.max) { + min = property_info->property_typ_data->subtype.gobject_enum.min; + max = property_info->property_typ_data->subtype.gobject_enum.max; + has_minmax = TRUE; + } + if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { + gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); + has_gtype = TRUE; + } + } + + if (!has_gtype) { + gtype = _gtype_property_get_gtype(property_info->setting_info->general->get_setting_gtype(), + property_info->property_name); + } + + if (!has_minmax && G_TYPE_IS_CLASSED(gtype)) { + nm_auto_unref_gtypeclass GTypeClass *class = NULL; + + class = g_type_class_ref(gtype); + if (G_IS_FLAGS_CLASS(class)) { + min = 0; + max = (int) G_MAXUINT; + } + } + + /* the gobject_enum.value_infos are currently ignored for the list of + * values. They only declare additional (hidden) aliases for the setter. */ + + v = nm_utils_strv_make_deep_copied(nm_utils_enum_get_values(gtype, min, max)); + return (const char *const *) (*out_to_free = v); } /*****************************************************************************/ -static const char *const* -_complete_fcn_gobject_bool (ARGS_COMPLETE_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, - }; + static const char *const v[] = { + "true", + "false", + "on", + "off", + "1", + "0", + "yes", + "no", + NULL, + }; - if (!text || !text[0]) - return &v[6]; - return v; + if (!text || !text[0]) + return &v[6]; + return v; } -static const char *const* -_complete_fcn_gobject_devices (ARGS_COMPLETE_FCN) +static const char *const *_complete_fcn_gobject_devices(ARGS_COMPLETE_FCN) { - NMDevice *const*devices = NULL; - guint i, j; - guint len = 0; - char **ifnames; + 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 (environment && environment->get_nm_devices) { + devices = environment->get_nm_devices(environment, environment_user_data, &len); + } - if (len == 0) - return NULL; + if (len == 0) + return NULL; - ifnames = g_new (char *, len + 1); - for (i = 0, j = 0; i < len; i++) { - const char *ifname; + ifnames = g_new(char *, len + 1); + for (i = 0, j = 0; i < len; i++) { + const char *ifname; - nm_assert (NM_IS_DEVICE (devices[i])); + nm_assert(NM_IS_DEVICE(devices[i])); - ifname = nm_device_get_iface (devices[i]); - if (ifname) - ifnames[j++] = g_strdup (ifname); - } - ifnames[j++] = NULL; + 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; + *out_to_free = ifnames; + return (const char *const *) ifnames; } /*****************************************************************************/ static char * -wep_key_type_to_string (NMWepKeyType type) +wep_key_type_to_string(NMWepKeyType type) { - switch (type) { - case NM_WEP_KEY_TYPE_KEY: - return g_strdup_printf (_("%d (key)"), type); - case NM_WEP_KEY_TYPE_PASSPHRASE: - return g_strdup_printf (_("%d (passphrase)"), type); - case NM_WEP_KEY_TYPE_UNKNOWN: - default: - return g_strdup_printf (_("%d (unknown)"), type); - } + switch (type) { + case NM_WEP_KEY_TYPE_KEY: + return g_strdup_printf(_("%d (key)"), type); + case NM_WEP_KEY_TYPE_PASSPHRASE: + return g_strdup_printf(_("%d (passphrase)"), type); + case NM_WEP_KEY_TYPE_UNKNOWN: + default: + return g_strdup_printf(_("%d (unknown)"), type); + } } static char * -vlan_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) +vlan_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type) { - GString *flag_str; + GString *flag_str; - if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup_printf ("%u", flags); + if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) + return g_strdup_printf("%u", flags); - if (flags == 0) - return g_strdup (_("0 (NONE)")); + if (flags == 0) + return g_strdup(_("0 (NONE)")); - flag_str = g_string_new (NULL); - g_string_printf (flag_str, "%d (", flags); + flag_str = g_string_new(NULL); + g_string_printf(flag_str, "%d (", flags); - if (flags & NM_VLAN_FLAG_REORDER_HEADERS) - g_string_append (flag_str, _("REORDER_HEADERS, ")); - if (flags & NM_VLAN_FLAG_GVRP) - g_string_append (flag_str, _("GVRP, ")); - if (flags & NM_VLAN_FLAG_LOOSE_BINDING) - g_string_append (flag_str, _("LOOSE_BINDING, ")); - if (flags & NM_VLAN_FLAG_MVRP) - g_string_append (flag_str, _("MVRP, ")); + if (flags & NM_VLAN_FLAG_REORDER_HEADERS) + g_string_append(flag_str, _("REORDER_HEADERS, ")); + if (flags & NM_VLAN_FLAG_GVRP) + g_string_append(flag_str, _("GVRP, ")); + if (flags & NM_VLAN_FLAG_LOOSE_BINDING) + g_string_append(flag_str, _("LOOSE_BINDING, ")); + if (flags & NM_VLAN_FLAG_MVRP) + g_string_append(flag_str, _("MVRP, ")); - if (flag_str->str[flag_str->len-1] == '(') - g_string_append (flag_str, _("unknown")); - else - g_string_truncate (flag_str, flag_str->len-2); /* chop off trailing ', ' */ + if (flag_str->str[flag_str->len - 1] == '(') + g_string_append(flag_str, _("unknown")); + else + g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */ - g_string_append_c (flag_str, ')'); + g_string_append_c(flag_str, ')'); - return g_string_free (flag_str, FALSE); + return g_string_free(flag_str, FALSE); } static char * -secret_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) +secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type) { - GString *flag_str; + GString *flag_str; - if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) - return g_strdup_printf ("%u", flags); + if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) + return g_strdup_printf("%u", flags); - if (flags == 0) - return g_strdup (_("0 (none)")); + if (flags == 0) + return g_strdup(_("0 (none)")); - flag_str = g_string_new (NULL); - g_string_printf (flag_str, "%u (", flags); + flag_str = g_string_new(NULL); + g_string_printf(flag_str, "%u (", flags); - if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) - g_string_append (flag_str, _("agent-owned, ")); - if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) - g_string_append (flag_str, _("not saved, ")); - if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) - g_string_append (flag_str, _("not required, ")); + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_string_append(flag_str, _("agent-owned, ")); + if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) + g_string_append(flag_str, _("not saved, ")); + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + g_string_append(flag_str, _("not required, ")); - if (flag_str->str[flag_str->len-1] == '(') - g_string_append (flag_str, _("unknown")); - else - g_string_truncate (flag_str, flag_str->len-2); /* chop off trailing ', ' */ + if (flag_str->str[flag_str->len - 1] == '(') + g_string_append(flag_str, _("unknown")); + else + g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */ - g_string_append_c (flag_str, ')'); + g_string_append_c(flag_str, ')'); - return g_string_free (flag_str, FALSE); + return g_string_free(flag_str, FALSE); } static const char * -_multilist_do_validate (const NMMetaPropertyInfo *property_info, - NMSetting *setting, - const char *item, - GError **error) -{ - if (property_info->property_typ_data->values_static) { - nm_assert (!property_info->property_typ_data->subtype.multilist.validate_fcn); - return nmc_string_is_valid (item, - (const char **) property_info->property_typ_data->values_static, - error); - } - if (property_info->property_typ_data->subtype.multilist.validate_fcn) { - return property_info->property_typ_data->subtype.multilist.validate_fcn (item, - error); - } - if (property_info->property_typ_data->subtype.multilist.validate2_fcn) { - return property_info->property_typ_data->subtype.multilist.validate2_fcn (setting, - item, - error); - } - - return item; -} - -static gconstpointer -_get_fcn_multilist (ARGS_GET_FCN) -{ - return _get_fcn_gobject_impl (property_info, - setting, - get_type, - property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn != NULL, - out_is_default, - out_to_free); -} - -static gboolean -_multilist_clear_property (const NMMetaPropertyInfo *property_info, - NMSetting *setting, - gboolean is_set /* or else set default */) -{ - if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn) { - property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn (setting, is_set); - return TRUE; - } - if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) { - property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting); - return TRUE; - } - return _gobject_property_reset (setting, property_info->property_name, FALSE); -} - -static gboolean -_set_fcn_multilist (ARGS_SET_FCN) -{ - gs_free const char **strv = NULL; - gsize i, j, nstrv; - - if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) - return _multilist_clear_property (property_info, setting, FALSE); - - if ( _SET_FCN_DO_REMOVE (modifier, value) - && ( property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32 - || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s - || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u)) { - gs_free gint64 *indexes = NULL; - - indexes = _value_str_as_index_list (value, &nstrv); - if (indexes) { - gint64 num; - - if (property_info->property_typ_data->subtype.multilist.get_num_fcn_u32) - num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u32 (setting); - else - num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u (setting); - for (i = 0; i < nstrv; i++) { - gint64 idx = indexes[i]; - - if (idx >= num) - continue; - - if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32) - property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32 (setting, idx); - else if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s) - property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s (setting, idx); - else - property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u (setting, idx); - } - return TRUE; - } - } - - if ( _SET_FCN_DO_SET_ALL (modifier, value) - && property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn - && value[0] == '\0') - return _multilist_clear_property (property_info, setting, FALSE); - - strv = _value_strsplit (value, - property_info->property_typ_data->subtype.multilist.strsplit_plain - ? VALUE_STRSPLIT_MODE_MULTILIST - : ( property_info->property_typ_data->subtype.multilist.strsplit_with_spaces - ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES - : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), - &nstrv); - - j = 0; - for (i = 0; i < nstrv; i++) { - const char *item = strv[i]; - - item = _multilist_do_validate (property_info, - setting, - item, - error); - if (!item) - return FALSE; - strv[j++] = item; - } - nstrv = j; - - if (_SET_FCN_DO_SET_ALL (modifier, value)) - _multilist_clear_property (property_info, setting, TRUE); - else if ( property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn - && _is_default (property_info, setting)) { - /* the property is already the default. But we hav here a '+' / '-' modifier, so - * that always makes it non-default (empty) first. */ - _multilist_clear_property (property_info, setting, TRUE); - } - - for (i = 0; i < nstrv; i++) { - if (_SET_FCN_DO_REMOVE (modifier, value)) { - property_info->property_typ_data->subtype.multilist.remove_by_value_fcn (setting, - strv[i]); - } else { - if (property_info->property_typ_data->subtype.multilist.add2_fcn) - property_info->property_typ_data->subtype.multilist.add2_fcn (setting, strv[i]); - else - property_info->property_typ_data->subtype.multilist.add_fcn (setting, strv[i]); - } - } - return TRUE; +_multilist_do_validate(const NMMetaPropertyInfo *property_info, + NMSetting * setting, + const char * item, + GError ** error) +{ + if (property_info->property_typ_data->values_static) { + nm_assert(!property_info->property_typ_data->subtype.multilist.validate_fcn); + return nmc_string_is_valid(item, + (const char **) property_info->property_typ_data->values_static, + error); + } + if (property_info->property_typ_data->subtype.multilist.validate_fcn) { + return property_info->property_typ_data->subtype.multilist.validate_fcn(item, error); + } + if (property_info->property_typ_data->subtype.multilist.validate2_fcn) { + return property_info->property_typ_data->subtype.multilist.validate2_fcn(setting, + item, + error); + } + + return item; +} + +static gconstpointer _get_fcn_multilist(ARGS_GET_FCN) +{ + return _get_fcn_gobject_impl( + property_info, + setting, + get_type, + property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn != NULL, + out_is_default, + out_to_free); } static gboolean -_set_fcn_optionlist (ARGS_SET_FCN) -{ - gs_free const char **strv = NULL; - gs_free const char **strv_val = NULL; - gsize strv_len; - gsize i, nstrv; - - nm_assert (!error || !*error); - - if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) - return _gobject_property_reset_default (setting, property_info->property_name); - - nstrv = 0; - strv = nm_utils_escaped_tokens_options_split_list (value); - if (strv) { - strv_len = NM_PTRARRAY_LEN (strv); - - strv_val = g_new (const char *, strv_len); - for (i = 0; strv[i]; i++) { - const char *opt_name; - const char *opt_value; - - nm_utils_escaped_tokens_options_split ((char *) strv[i], &opt_name, &opt_value); - - if ( property_info->property_type->values_fcn - || property_info->property_typ_data->values_static) { - gs_strfreev char **valid_options_to_free = NULL; - const char *const*valid_options; - - if (property_info->property_type->values_fcn) - valid_options = property_info->property_type->values_fcn (property_info, &valid_options_to_free); - else - valid_options = property_info->property_typ_data->values_static; - - opt_name = nmc_string_is_valid (opt_name, (const char **) valid_options, error); - if (!opt_name) - return FALSE; - } - - if (opt_value) { - if (_SET_FCN_DO_REMOVE (modifier, value)) - opt_value = NULL; - } else { - if (!_SET_FCN_DO_REMOVE (modifier, value)) { - nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is not valid; use