diff options
Diffstat (limited to 'libnm-core/nm-utils.c')
| -rw-r--r-- | libnm-core/nm-utils.c | 220 |
1 files changed, 72 insertions, 148 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index ebbbfd3a..eb65f8db 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -35,13 +35,11 @@ #include <net/if.h> #include <linux/pkt_sched.h> -#if WITH_JANSSON +#if WITH_JSON_VALIDATION #include "nm-json.h" -#include <jansson.h> #endif #include "nm-utils/nm-enum-utils.h" -#include "nm-utils/nm-hash-utils.h" #include "nm-common-macros.h" #include "nm-utils-private.h" #include "nm-setting-private.h" @@ -138,7 +136,6 @@ static const struct IsoLangToEncodings isoLangEntries2[] = LANG_ENCODINGS (NULL, NULL) }; - static GHashTable * langToEncodings5 = NULL; static GHashTable * langToEncodings2 = NULL; @@ -150,7 +147,7 @@ init_lang_to_encodings_hash (void) if (G_UNLIKELY (langToEncodings5 == NULL)) { /* Five-letter codes */ enc = (struct IsoLangToEncodings *) &isoLangEntries5[0]; - langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal); + langToEncodings5 = g_hash_table_new (nm_str_hash, g_str_equal); while (enc->lang) { g_hash_table_insert (langToEncodings5, (gpointer) enc->lang, (gpointer) enc->encodings); @@ -161,7 +158,7 @@ init_lang_to_encodings_hash (void) if (G_UNLIKELY (langToEncodings2 == NULL)) { /* Two-letter codes */ enc = (struct IsoLangToEncodings *) &isoLangEntries2[0]; - langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal); + langToEncodings2 = g_hash_table_new (nm_str_hash, g_str_equal); while (enc->lang) { g_hash_table_insert (langToEncodings2, (gpointer) enc->lang, (gpointer) enc->encodings); @@ -252,11 +249,9 @@ _nm_utils_init (void) g_error ("libnm-util symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); g_module_close (self); - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - nm_g_type_init (); - _nm_dbus_errors_init (); } @@ -468,7 +463,7 @@ _nm_utils_string_slist_validate (GSList *list, const char **valid_values) * @hash: a #GHashTable * * Utility function to iterate over a hash table and return - * it's values as a #GSList. + * its values as a #GSList. * * Returns: (element-type gpointer) (transfer container): a newly allocated #GSList * containing the values of the hash table. The caller must free the @@ -546,7 +541,7 @@ _nm_utils_strdict_from_dbus (GVariant *dbus_value, const char *key, *value; GHashTable *hash; - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); g_variant_iter_init (&iter, dbus_value); while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) g_hash_table_insert (hash, g_strdup (key), g_strdup (value)); @@ -561,7 +556,7 @@ _nm_utils_copy_strdict (GHashTable *strdict) GHashTableIter iter; gpointer key, value; - copy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + copy = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); if (strdict) { g_hash_table_iter_init (&iter, strdict); while (g_hash_table_iter_next (&iter, &key, &value)) @@ -1883,7 +1878,7 @@ GVariant * nm_utils_ip_addresses_to_variant (GPtrArray *addresses) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); @@ -1891,8 +1886,8 @@ nm_utils_ip_addresses_to_variant (GPtrArray *addresses) for (i = 0; i < addresses->len; i++) { NMIPAddress *addr = addresses->pdata[i]; GVariantBuilder addr_builder; - char **names; - int n; + gs_free const char **names = NULL; + guint j, len; g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&addr_builder, "{sv}", @@ -1902,13 +1897,12 @@ nm_utils_ip_addresses_to_variant (GPtrArray *addresses) "prefix", g_variant_new_uint32 (nm_ip_address_get_prefix (addr))); - names = nm_ip_address_get_attribute_names (addr); - for (n = 0; names[n]; n++) { + names = _nm_ip_address_get_attribute_names (addr, TRUE, &len); + for (j = 0; j < len; j++) { g_variant_builder_add (&addr_builder, "{sv}", - names[n], - nm_ip_address_get_attribute (addr, names[n])); + names[j], + nm_ip_address_get_attribute (addr, names[j])); } - g_strfreev (names); g_variant_builder_add (&builder, "a{sv}", &addr_builder); } @@ -2226,7 +2220,7 @@ _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc) * * Returns: formatted string or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ char * nm_utils_tc_qdisc_to_str (NMTCQdisc *qdisc, GError **error) @@ -2242,7 +2236,6 @@ nm_utils_tc_qdisc_to_str (NMTCQdisc *qdisc, GError **error) return g_string_free (string, FALSE); } - static gboolean _tc_read_common_opts (const char *str, guint32 *handle, @@ -2327,7 +2320,7 @@ _tc_read_common_opts (const char *str, * * Returns: the %NMTCQdisc or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ NMTCQdisc * nm_utils_tc_qdisc_from_str (const char *str, GError **error) @@ -2416,7 +2409,7 @@ _string_append_tc_action (GString *string, NMTCAction *action, GError **error) * * Returns: formatted string or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ char * nm_utils_tc_action_to_str (NMTCAction *action, GError **error) @@ -2442,7 +2435,7 @@ nm_utils_tc_action_to_str (NMTCAction *action, GError **error) * * Returns: the %NMTCAction or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ NMTCAction * nm_utils_tc_action_from_str (const char *str, GError **error) @@ -2458,10 +2451,10 @@ nm_utils_tc_action_from_str (const char *str, GError **error) nm_assert (str); nm_assert (!error || !*error); - ht = nm_utils_parse_variant_attributes (str, - ' ', ' ', FALSE, - tc_action_attribute_spec, - error); + ht = nm_utils_parse_variant_attributes (str, + ' ', ' ', FALSE, + tc_action_attribute_spec, + error); if (!ht) return FALSE; @@ -2497,10 +2490,10 @@ nm_utils_tc_action_from_str (const char *str, GError **error) return NULL; } - options = nm_utils_parse_variant_attributes (rest, - ' ', ' ', FALSE, - attrs, - error); + options = nm_utils_parse_variant_attributes (rest, + ' ', ' ', FALSE, + attrs, + error); if (!options) { nm_tc_action_unref (action); return NULL; @@ -2560,7 +2553,7 @@ _nm_utils_string_append_tc_tfilter_rest (GString *string, NMTCTfilter *tfilter, * * Returns: formatted string or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ char * nm_utils_tc_tfilter_to_str (NMTCTfilter *tfilter, GError **error) @@ -2595,7 +2588,7 @@ static const NMVariantAttributeSpec * const tc_tfilter_attribute_spec[] = { * * Returns: the %NMTCTfilter or %NULL * - * Since: 1.10.2 + * Since: 1.12 */ NMTCTfilter * nm_utils_tc_tfilter_from_str (const char *str, GError **error) @@ -3043,7 +3036,6 @@ _nm_utils_check_file (const char *filename, return TRUE; } - gboolean _nm_utils_check_module_file (const char *name, int check_owner, @@ -3444,59 +3436,28 @@ nm_utils_wifi_5ghz_freqs (void) * @strength: the access point strength, from 0 to 100 * * 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. + * strength suitable for printing to stdout. + * + * Previous versions used to take a guess at the terminal type and possibly + * return a wide UTF-8 encoded string. Now it always returns a 7-bit + * clean strings of one to 0 to 4 asterisks. Users that actually need + * the functionality are encouraged to make their implementations instead. * * Returns: the graphical representation of the access point strength */ const char * nm_utils_wifi_strength_bars (guint8 strength) { - static const char *strength_full, *strength_high, *strength_med, *strength_low, *strength_none; - - if (G_UNLIKELY (strength_full == NULL)) { - gboolean can_show_graphics = TRUE; - char *locale_str; - - 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_graphics = FALSE; - } - - /* The linux console font doesn't have these characters */ - if (g_strcmp0 (g_getenv ("TERM"), "linux") == 0) - can_show_graphics = FALSE; - - if (can_show_graphics) { - strength_full = /* ▂▄▆█ */ "\342\226\202\342\226\204\342\226\206\342\226\210"; - strength_high = /* ▂▄▆_ */ "\342\226\202\342\226\204\342\226\206_"; - strength_med = /* ▂▄__ */ "\342\226\202\342\226\204__"; - strength_low = /* ▂___ */ "\342\226\202___"; - strength_none = /* ____ */ "____"; - } else { - strength_full = "****"; - strength_high = "*** "; - strength_med = "** "; - strength_low = "* "; - strength_none = " "; - } - } - if (strength > 80) - return strength_full; + return "****"; else if (strength > 55) - return strength_high; + return "*** "; else if (strength > 30) - return strength_med; + return "** "; else if (strength > 5) - return strength_low; + return "* "; else - return strength_none; + return " "; } /** @@ -3698,7 +3659,7 @@ _nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gs /** * nm_utils_hwaddr_aton: * @asc: the ASCII representation of a hardware address - * @buffer: buffer to store the result into + * @buffer: (type guint8) (array length=length): buffer to store the result into * @length: the expected length in bytes of the result and * the size of the buffer in bytes. * @@ -3724,8 +3685,8 @@ nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length) return buffer; } -static void -_bin2str (gconstpointer addr, gsize length, const char delimiter, gboolean upper_case, char *out) +void +_nm_utils_bin2str_full (gconstpointer addr, gsize length, const char delimiter, gboolean upper_case, char *out) { const guint8 *in = addr; const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; @@ -3775,7 +3736,7 @@ nm_utils_bin2hexstr (gconstpointer src, gsize len, int final_len) g_return_val_if_fail (final_len < 0 || (gsize) final_len < buflen, NULL); result = g_malloc (buflen); - _bin2str (src, len, '\0', FALSE, result); + _nm_utils_bin2str_full (src, len, '\0', FALSE, result); /* Cut converted key off at the correct length for this cipher type */ if (final_len >= 0 && (gsize) final_len < buflen) @@ -3802,7 +3763,7 @@ nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length) g_return_val_if_fail (length > 0, g_strdup ("")); result = g_malloc (length * 3); - _bin2str (addr, length, ':', TRUE, result); + _nm_utils_bin2str_full (addr, length, ':', TRUE, result); return result; } @@ -3815,7 +3776,7 @@ nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_cas if (buf_len < addr_len * 3) g_return_val_if_reached (NULL); - _bin2str (addr, addr_len, ':', upper_case, buf); + _nm_utils_bin2str_full (addr, addr_len, ':', upper_case, buf); return buf; } @@ -3838,7 +3799,7 @@ _nm_utils_bin2str (gconstpointer addr, gsize length, gboolean upper_case) g_return_val_if_fail (length > 0, g_strdup ("")); result = g_malloc (length * 3); - _bin2str (addr, length, ':', upper_case, result); + _nm_utils_bin2str_full (addr, length, ':', upper_case, result); return result; } @@ -3866,9 +3827,11 @@ nm_utils_hwaddr_valid (const char *asc, gssize length) if (!hwaddr_aton (asc, buf, length, &l)) return FALSE; return length == l; - } else if (length == -1) { + } else if (length == -1) return !!hwaddr_aton (asc, buf, sizeof (buf), &l); - } else + else if (length == 0) + return FALSE; + else g_return_val_if_reached (FALSE); } @@ -3930,9 +3893,9 @@ _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length) /** * nm_utils_hwaddr_matches: - * @hwaddr1: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr1: (nullable): pointer to a binary or ASCII hardware address, or %NULL * @hwaddr1_len: size of @hwaddr1, or -1 if @hwaddr1 is ASCII - * @hwaddr2: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr2: (nullable): pointer to a binary or ASCII hardware address, or %NULL * @hwaddr2_len: size of @hwaddr2, or -1 if @hwaddr2 is ASCII * * Generalized hardware address comparison function. Tests if @hwaddr1 and @@ -4357,7 +4320,7 @@ nm_utils_inet_ntop (int addr_family, gconstpointer addr, char *dst) s = inet_ntop (addr_family, addr, - dst ? dst : _nm_utils_inet_ntop_buffer, + dst ?: _nm_utils_inet_ntop_buffer, addr_family == AF_INET6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN); nm_assert (s); return s; @@ -4371,7 +4334,7 @@ nm_utils_inet_ntop (int addr_family, gconstpointer addr, char *dst) * characters. If set to %NULL, it will return a pointer to an internal, static * buffer (shared with nm_utils_inet6_ntop()). Beware, that the internal * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or - * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Also, * using the internal buffer is not thread safe. When in doubt, pass your own * @dst buffer to avoid these issues. * @@ -4383,7 +4346,7 @@ nm_utils_inet_ntop (int addr_family, gconstpointer addr, char *dst) const char * nm_utils_inet4_ntop (in_addr_t inaddr, char *dst) { - return inet_ntop (AF_INET, &inaddr, dst ? dst : _nm_utils_inet_ntop_buffer, + return inet_ntop (AF_INET, &inaddr, dst ?: _nm_utils_inet_ntop_buffer, INET_ADDRSTRLEN); } @@ -4395,7 +4358,7 @@ nm_utils_inet4_ntop (in_addr_t inaddr, char *dst) * characters. If set to %NULL, it will return a pointer to an internal, static * buffer (shared with nm_utils_inet4_ntop()). Beware, that the internal * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or - * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Also, * using the internal buffer is not thread safe. When in doubt, pass your own * @dst buffer to avoid these issues. * @@ -4409,7 +4372,7 @@ const char * nm_utils_inet6_ntop (const struct in6_addr *in6addr, char *dst) { g_return_val_if_fail (in6addr, NULL); - return inet_ntop (AF_INET6, in6addr, dst ? dst : _nm_utils_inet_ntop_buffer, + return inet_ntop (AF_INET6, in6addr, dst ?: _nm_utils_inet_ntop_buffer, INET6_ADDRSTRLEN); } @@ -4622,9 +4585,6 @@ _nm_utils_strstrdictkey_hash (gconstpointer a) nm_hash_update_val (&h, k->type); if (k->type & STRSTRDICTKEY_ALL_SET) { - gsize n; - - n = 0; p = strchr (k->data, '\0'); if (k->type == STRSTRDICTKEY_ALL_SET) { /* the key contains two strings. Continue... */ @@ -4844,7 +4804,7 @@ gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) char * nm_utils_enum_to_str (GType type, int value) { - return _nm_utils_enum_to_str_full (type, value, ", "); + return _nm_utils_enum_to_str_full (type, value, ", ", NULL); } /** @@ -4927,33 +4887,7 @@ _nm_utils_is_json_object_no_validation (const char *str, GError **error) return FALSE; } -#if WITH_JANSSON - -/* Added in Jansson v2.3 (released Jan 27 2012) */ -#ifndef json_object_foreach -#define json_object_foreach(object, key, value) \ - for(key = json_object_iter_key(json_object_iter(object)); \ - key && (value = json_object_iter_value(json_object_iter_at (object, key) )); \ - key = json_object_iter_key(json_object_iter_next(object, json_object_iter_at (object, key)))) -#endif - -/* Added in Jansson v2.4 (released Sep 23 2012), but travis.ci has v2.2. */ -#ifndef json_boolean -#define json_boolean(val) ((val) ? json_true() : json_false()) -#endif - -/* Added in Jansson v2.5 (released Sep 19 2013), but travis.ci has v2.2. */ -#ifndef json_array_foreach -#define json_array_foreach(array, index, value) \ - for (index = 0; \ - index < json_array_size(array) && (value = json_array_get(array, index)); \ - index++) -#endif - -/* Added in Jansson v2.7 */ -#ifndef json_boolean_value -#define json_boolean_value json_is_true -#endif +#if WITH_JSON_VALIDATION static void _json_add_object (json_t *json, @@ -5083,7 +5017,6 @@ _json_team_add_defaults (json_t *json, json_object_set_new (json_element, "name", json_string (runner)); } - if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) { _json_add_object (json, "notify_peers", "count", NULL, json_integer (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT)); @@ -5370,7 +5303,6 @@ fail: return NULL; } - /** * nm_utils_is_json_object: * @str: the JSON string to test @@ -5427,15 +5359,6 @@ nm_utils_is_json_object (const char *str, GError **error) return TRUE; } -/* json_object_foreach_safe() is only available since Jansson 2.8, - * reimplement it */ -#define _json_object_foreach_safe(object, n, key, value) \ - for (key = json_object_iter_key (json_object_iter (object)), \ - n = json_object_iter_next (object, json_object_iter_at (object, key)); \ - key && (value = json_object_iter_value (json_object_iter_at (object, key))); \ - key = json_object_iter_key (n), \ - n = json_object_iter_next (object, json_object_iter_at (object, key))) - gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, @@ -5475,7 +5398,7 @@ _nm_utils_team_config_equal (const char *conf1, /* Only consider a given subset of nodes, others can change depending on * current state */ for (i = 0, json = json1; i < 2; i++, json = json2) { - _json_object_foreach_safe (json, tmp, key, value) { + json_object_foreach_safe (json, tmp, key, value) { if (!NM_IN_STRSET (key, "runner", "link_watch")) json_object_del (json, key); } @@ -5495,7 +5418,6 @@ out: return ret; } - GValue * _nm_utils_team_config_get (const char *conf, const char *key, @@ -5734,7 +5656,7 @@ done: return updated; } -#else /* WITH_JANSSON */ +#else /* !WITH_JSON_VALIDATION */ gboolean nm_utils_is_json_object (const char *str, GError **error) @@ -6026,7 +5948,8 @@ attribute_unescape (const char *start, const char *end) * * Parse attributes from a string. * - * Returns: (transfer full): a #GHashTable mapping attribute names to #GVariant values. + * Returns: (transfer full) (element-type utf8 GVariant): a #GHashTable mapping + * attribute names to #GVariant values. * * Since: 1.8 */ @@ -6048,7 +5971,7 @@ nm_utils_parse_variant_attributes (const char *string, g_return_val_if_fail (key_value_separator, NULL); g_return_val_if_fail (!error || !*error, NULL); - ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + ht = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); while (TRUE) { gs_free char *name = NULL, *value = NULL; @@ -6185,7 +6108,7 @@ next: /* * nm_utils_format_variant_attributes: - * @attributes: a #GHashTable mapping attribute names to #GVariant values + * @attributes: (element-type utf8 GVariant): a #GHashTable mapping attribute names to #GVariant values * @attr_separator: the attribute separator character * @key_value_separator: character separating key and values * @@ -6207,8 +6130,8 @@ nm_utils_format_variant_attributes (GHashTable *attributes, const char *name, *value; char *escaped; char buf[64]; - gs_free_list GList *keys = NULL; - GList *iter; + gs_free NMUtilsNamedValue *values = NULL; + guint i, len; g_return_val_if_fail (attr_separator, NULL); g_return_val_if_fail (key_value_separator, NULL); @@ -6216,12 +6139,13 @@ nm_utils_format_variant_attributes (GHashTable *attributes, if (!attributes || !g_hash_table_size (attributes)) return NULL; - keys = g_list_sort (g_hash_table_get_keys (attributes), (GCompareFunc) g_strcmp0); + values = nm_utils_named_values_from_str_dict (attributes, &len); + str = g_string_new (""); - for (iter = keys; iter; iter = g_list_next (iter)) { - name = iter->data; - variant = g_hash_table_lookup (attributes, name); + for (i = 0; i < len; i++) { + name = values[i].name; + variant = (GVariant *) values[i].value_ptr; value = NULL; if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) |