summaryrefslogtreecommitdiff
path: root/libnm-core/nm-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-utils.c')
-rw-r--r--libnm-core/nm-utils.c385
1 files changed, 218 insertions, 167 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 425c302713..b633a5099c 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -16,10 +16,8 @@
#include <sys/stat.h>
#include <linux/pkt_sched.h>
-#if WITH_JSON_VALIDATION
-#include "nm-json.h"
-#endif
-
+#include "nm-glib-aux/nm-json-aux.h"
+#include "nm-glib-aux/nm-str-buf.h"
#include "nm-glib-aux/nm-enum-utils.h"
#include "nm-glib-aux/nm-time-utils.h"
#include "nm-glib-aux/nm-secret-utils.h"
@@ -2067,8 +2065,8 @@ nm_utils_ip_addresses_from_variant (GVariant *value,
g_variant_iter_init (&attrs_iter, addr_var);
while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) {
- if ( strcmp (attr_name, "address") != 0
- && strcmp (attr_name, "prefix") != 0)
+ if (!NM_IN_STRSET (attr_name, "address",
+ "prefix"))
nm_ip_address_set_attribute (addr, attr_name, attr_val);
g_variant_unref (attr_val);
}
@@ -2193,10 +2191,10 @@ nm_utils_ip_routes_from_variant (GVariant *value,
g_variant_iter_init (&attrs_iter, route_var);
while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) {
- if ( strcmp (attr_name, "dest") != 0
- && strcmp (attr_name, "prefix") != 0
- && strcmp (attr_name, "next-hop") != 0
- && strcmp (attr_name, "metric") != 0)
+ if (!NM_IN_STRSET (attr_name, "dest",
+ "prefix",
+ "next-hop",
+ "metric"))
nm_ip_route_set_attribute (route, attr_name, attr_val);
g_variant_unref (attr_val);
}
@@ -2227,7 +2225,7 @@ _string_append_tc_handle (GString *string, guint32 handle)
*
* This is used to either write out the parent handle to the tc qdisc string
* or to pretty-format (use symbolic name for root) the key in keyfile.
- * The presence of prefix determnines which one is the case.
+ * The presence of prefix determines which one is the case.
*
* Private API due to general ugliness and overall uselessness for anything
* sensible.
@@ -2376,7 +2374,8 @@ _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc)
const char *kind = nm_tc_qdisc_get_kind (qdisc);
gs_free char *str = NULL;
- if (handle != TC_H_UNSPEC && strcmp (kind, "ingress") != 0) {
+ if ( handle != TC_H_UNSPEC
+ && !nm_streq (kind, "ingress")) {
g_string_append (string, "handle ");
_string_append_tc_handle (string, handle);
g_string_append_c (string, ' ');
@@ -2468,7 +2467,7 @@ _tc_read_common_opts (const char *str,
variant = g_hash_table_lookup (ht, "kind");
if (variant) {
*kind = g_variant_dup_string (variant, NULL);
- if (strcmp (*kind, "ingress") == 0) {
+ if (nm_streq (*kind, "ingress")) {
if (*parent == TC_H_UNSPEC)
*parent = TC_H_INGRESS;
if (*handle == TC_H_UNSPEC)
@@ -2524,7 +2523,7 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error)
return NULL;
for (i = 0; rest && tc_qdisc_attribute_spec[i]; i++) {
- if (strcmp (tc_qdisc_attribute_spec[i]->kind, kind) == 0) {
+ if (nm_streq (tc_qdisc_attribute_spec[i]->kind, kind)) {
options = nm_utils_parse_variant_attributes (rest,
' ', ' ', FALSE,
tc_qdisc_attribute_spec[i]->attrs,
@@ -2589,11 +2588,21 @@ _string_append_tc_action (GString *string, NMTCAction *action, GError **error)
{
const char *kind = nm_tc_action_get_kind (action);
gs_free char *str = NULL;
+ const NMVariantAttributeSpec *const *attrs;
+
+ if (nm_streq (kind, "simple"))
+ attrs = tc_action_simple_attribute_spec;
+ else if (nm_streq (kind, "mirred"))
+ attrs = tc_action_mirred_attribute_spec;
+ else
+ attrs = NULL;
+
g_string_append (string, kind);
- str = nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action),
- ' ', ' ');
+ str = _nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action),
+ attrs,
+ ' ', ' ');
if (str) {
g_string_append_c (string, ' ');
g_string_append (string, str);
@@ -2670,9 +2679,9 @@ nm_utils_tc_action_from_str (const char *str, GError **error)
}
kind = g_variant_get_string (variant, NULL);
- if (strcmp (kind, "simple") == 0)
+ if (nm_streq (kind, "simple"))
attrs = tc_action_simple_attribute_spec;
- else if (strcmp (kind, "mirred") == 0)
+ else if (nm_streq (kind, "mirred"))
attrs = tc_action_mirred_attribute_spec;
else
attrs = NULL;
@@ -2893,7 +2902,7 @@ nm_utils_sriov_vf_to_str (const NMSriovVF *vf, gboolean omit_index, GError **err
if (num_attrs > 0) {
if (!omit_index)
g_string_append_c (str, ' ');
- _nm_utils_format_variant_attributes_full (str, values, num_attrs, ' ', '=');
+ _nm_utils_format_variant_attributes_full (str, values, num_attrs, NULL, ' ', '=');
}
vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans);
@@ -3300,30 +3309,29 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g
char *
_nm_utils_uuid_generate_from_strings (const char *string1, ...)
{
- GString *str;
- va_list args;
- const char *s;
- char *uuid;
-
if (!string1)
return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS);
- str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/
+ {
+ nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE);
+ va_list args;
+ const char *s;
- g_string_append_len (str, string1, strlen (string1) + 1);
+ nm_str_buf_append_len (&str, string1, strlen (string1) + 1u);
- va_start (args, string1);
- s = va_arg (args, const char *);
- while (s) {
- g_string_append_len (str, s, strlen (s) + 1);
+ va_start (args, string1);
s = va_arg (args, const char *);
- }
- va_end (args);
-
- uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS);
+ while (s) {
+ nm_str_buf_append_len (&str, s, strlen (s) + 1u);
+ s = va_arg (args, const char *);
+ }
+ va_end (args);
- g_string_free (str, TRUE);
- return uuid;
+ return nm_utils_uuid_generate_from_string (nm_str_buf_get_str_unsafe (&str),
+ str.len,
+ NM_UTILS_UUID_TYPE_VERSION3,
+ NM_UTILS_UUID_NS);
+ }
}
/*****************************************************************************/
@@ -3571,9 +3579,6 @@ nm_utils_file_search_in_paths (const char *progname,
gpointer user_data,
GError **error)
{
- GString *tmp;
- const char *ret;
-
g_return_val_if_fail (!error || !*error, NULL);
g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL);
g_return_val_if_fail (file_test_flags || predicate, NULL);
@@ -3582,32 +3587,35 @@ nm_utils_file_search_in_paths (const char *progname,
* it simpler to pass in a path from configure checks. */
if ( try_first
&& try_first[0] == '/'
- && (file_test_flags == 0 || g_file_test (try_first, file_test_flags))
- && (!predicate || predicate (try_first, user_data)))
+ && ( file_test_flags == 0
+ || g_file_test (try_first, file_test_flags))
+ && ( !predicate
+ || predicate (try_first, user_data)))
return g_intern_string (try_first);
- if (!paths || !*paths)
- goto NOT_FOUND;
+ if ( paths
+ && paths[0]) {
+ nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE);
- tmp = g_string_sized_new (50);
- for (; *paths; paths++) {
- if (!*paths)
- continue;
- g_string_append (tmp, *paths);
- if (tmp->str[tmp->len - 1] != '/')
- g_string_append_c (tmp, '/');
- g_string_append (tmp, progname);
- if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags))
- && (!predicate || predicate (tmp->str, user_data))) {
- ret = g_intern_string (tmp->str);
- g_string_free (tmp, TRUE);
- return ret;
+ for (; *paths; paths++) {
+ const char *path = *paths;
+ const char *s;
+
+ if (!path[0])
+ continue;
+
+ nm_str_buf_reset (&strbuf, path);
+ nm_str_buf_ensure_trailing_c (&strbuf, '/');
+ s = nm_str_buf_append0 (&strbuf, progname);
+
+ if ( ( file_test_flags == 0
+ || g_file_test (s, file_test_flags))
+ && ( !predicate
+ || predicate (s, user_data)))
+ return g_intern_string (s);
}
- g_string_set_size (tmp, 0);
}
- g_string_free (tmp, TRUE);
-NOT_FOUND:
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname);
return NULL;
}
@@ -3620,7 +3628,7 @@ struct cf_pair {
guint32 freq;
};
-static struct cf_pair a_table[] = {
+static const struct cf_pair a_table[] = {
/* A band */
{ 7, 5035 },
{ 8, 5040 },
@@ -3667,10 +3675,60 @@ static struct cf_pair a_table[] = {
{ 188, 4945 },
{ 192, 4960 },
{ 196, 4980 },
- { 0, -1 }
+ { 0, 0 }
+};
+
+static const guint a_table_freqs[G_N_ELEMENTS (a_table)] = {
+ /* A band */
+ 5035,
+ 5040,
+ 5045,
+ 5055,
+ 5060,
+ 5080,
+ 5170,
+ 5180,
+ 5190,
+ 5200,
+ 5210,
+ 5220,
+ 5230,
+ 5240,
+ 5250,
+ 5260,
+ 5280,
+ 5290,
+ 5300,
+ 5320,
+ 5500,
+ 5520,
+ 5540,
+ 5560,
+ 5580,
+ 5600,
+ 5620,
+ 5640,
+ 5660,
+ 5680,
+ 5700,
+ 5745,
+ 5760,
+ 5765,
+ 5785,
+ 5800,
+ 5805,
+ 5825,
+ 4915,
+ 4920,
+ 4925,
+ 4935,
+ 4945,
+ 4960,
+ 4980,
+ 0,
};
-static struct cf_pair bg_table[] = {
+static const struct cf_pair bg_table[] = {
/* B/G band */
{ 1, 2412 },
{ 2, 2417 },
@@ -3686,7 +3744,26 @@ static struct cf_pair bg_table[] = {
{ 12, 2467 },
{ 13, 2472 },
{ 14, 2484 },
- { 0, -1 }
+ { 0, 0 }
+};
+
+static const guint bg_table_freqs[G_N_ELEMENTS (bg_table)] = {
+ /* B/G band */
+ 2412,
+ 2417,
+ 2422,
+ 2427,
+ 2432,
+ 2437,
+ 2442,
+ 2447,
+ 2452,
+ 2457,
+ 2462,
+ 2467,
+ 2472,
+ 2484,
+ 0,
};
/**
@@ -3703,16 +3780,16 @@ nm_utils_wifi_freq_to_channel (guint32 freq)
int i = 0;
if (freq > 4900) {
- while (a_table[i].chan && (a_table[i].freq != freq))
+ while ( a_table[i].freq
+ && (a_table[i].freq != freq))
i++;
return a_table[i].chan;
- } else {
- while (bg_table[i].chan && (bg_table[i].freq != freq))
- i++;
- return bg_table[i].chan;
}
- return 0;
+ while ( bg_table[i].freq
+ && (bg_table[i].freq != freq))
+ i++;
+ return bg_table[i].chan;
}
/**
@@ -3748,16 +3825,24 @@ nm_utils_wifi_freq_to_band (guint32 freq)
guint32
nm_utils_wifi_channel_to_freq (guint32 channel, const char *band)
{
- int i = 0;
+ int i;
- if (!strcmp (band, "a")) {
- while (a_table[i].chan && (a_table[i].chan != channel))
- i++;
- return a_table[i].freq;
- } else if (!strcmp (band, "bg")) {
- while (bg_table[i].chan && (bg_table[i].chan != channel))
- i++;
- return bg_table[i].freq;
+ g_return_val_if_fail (band, 0);
+
+ if (nm_streq (band, "a")) {
+ for (i = 0; a_table[i].chan; i++) {
+ if (a_table[i].chan == channel)
+ return a_table[i].freq;
+ }
+ return ((guint32) -1);
+ }
+
+ if (nm_streq (band, "bg")) {
+ for (i = 0; bg_table[i].chan; i++) {
+ if (bg_table[i].chan == channel)
+ return bg_table[i].freq;
+ }
+ return ((guint32) -1);
}
return 0;
@@ -3776,26 +3861,24 @@ nm_utils_wifi_channel_to_freq (guint32 channel, const char *band)
guint32
nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band)
{
- size_t a_size = sizeof (a_table) / sizeof (struct cf_pair);
- size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair);
- struct cf_pair *pair = NULL;
+ size_t a_size = G_N_ELEMENTS (a_table);
+ size_t bg_size = G_N_ELEMENTS (bg_table);
+ const struct cf_pair *pair;
- if (!strcmp (band, "a")) {
+ if (nm_streq (band, "a")) {
if (channel < a_table[0].chan)
return a_table[0].chan;
if (channel > a_table[a_size - 2].chan)
return a_table[a_size - 2].chan;
pair = &a_table[0];
- } else if (!strcmp (band, "bg")) {
+ } else if (nm_streq (band, "bg")) {
if (channel < bg_table[0].chan)
return bg_table[0].chan;
if (channel > bg_table[bg_size - 2].chan)
return bg_table[bg_size - 2].chan;
pair = &bg_table[0];
- } else {
- g_assert_not_reached ();
- return 0;
- }
+ } else
+ g_return_val_if_reached (0);
while (pair->chan) {
if (channel == pair->chan)
@@ -3823,49 +3906,32 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band)
gboolean
nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
{
- struct cf_pair *table = NULL;
- int i = 0;
-
- if (!strcmp (band, "a"))
- table = a_table;
- else if (!strcmp (band, "bg"))
- table = bg_table;
- else
- return FALSE;
-
- while (table[i].chan && (table[i].chan != channel))
- i++;
-
- if (table[i].chan != 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static const guint *
-_wifi_freqs (gboolean bg_band)
-{
- static guint *freqs_2ghz = NULL;
- static guint *freqs_5ghz = NULL;
- guint *freqs;
-
- freqs = bg_band ? freqs_2ghz : freqs_5ghz;
- if (G_UNLIKELY (freqs == NULL)) {
- struct cf_pair *table;
- int i;
+ guint32 freq;
- table = bg_band ? bg_table : a_table;
- freqs = g_new0 (guint, bg_band ? G_N_ELEMENTS (bg_table) : G_N_ELEMENTS (a_table));
- for (i = 0; table[i].chan; i++)
- freqs[i] = table[i].freq;
- freqs[i] = 0;
- if (bg_band)
- freqs_2ghz = freqs;
- else
- freqs_5ghz = freqs;
- }
- return freqs;
-}
+ freq = nm_utils_wifi_channel_to_freq (channel, band);
+
+ return !NM_IN_SET (freq, 0u, (guint32) -1);
+}
+
+#define _nm_assert_wifi_freqs(table, table_freqs) \
+ G_STMT_START { \
+ if (NM_MORE_ASSERT_ONCE (5)) { \
+ int i, j; \
+ \
+ G_STATIC_ASSERT (G_N_ELEMENTS (table) > 0); \
+ G_STATIC_ASSERT (G_N_ELEMENTS (table) == G_N_ELEMENTS (table_freqs)); \
+ \
+ for (i = 0; i < G_N_ELEMENTS (table); i++) { \
+ nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].chan == 0)); \
+ nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].freq == 0)); \
+ nm_assert (table[i].freq == table_freqs[i]); \
+ for (j = 0; j < i; j++) { \
+ nm_assert (table[j].chan != table[i].chan); \
+ nm_assert (table[j].freq != table[i].freq); \
+ } \
+ } \
+ } \
+ } G_STMT_END
/**
* nm_utils_wifi_2ghz_freqs:
@@ -3879,7 +3945,8 @@ _wifi_freqs (gboolean bg_band)
const guint *
nm_utils_wifi_2ghz_freqs (void)
{
- return _wifi_freqs (TRUE);
+ _nm_assert_wifi_freqs (bg_table, bg_table_freqs);
+ return bg_table_freqs;
}
/**
@@ -3894,7 +3961,8 @@ nm_utils_wifi_2ghz_freqs (void)
const guint *
nm_utils_wifi_5ghz_freqs (void)
{
- return _wifi_freqs (FALSE);
+ _nm_assert_wifi_freqs (a_table, a_table_freqs);
+ return a_table_freqs;
}
/**
@@ -4019,7 +4087,7 @@ fail:
* @out_length: the output length in case of success.
*
* Parses @asc and converts it to binary form in @buffer.
- * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed.
+ * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed.
*
* It is like nm_utils_hwaddr_aton(), but contrary to that it
* can parse addresses of any length. That is, you don't need
@@ -4046,7 +4114,7 @@ _nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gs
* the size of the buffer in bytes.
*
* Parses @asc and converts it to binary form in @buffer.
- * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed.
+ * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed.
*
* Return value: @buffer, or %NULL if @asc couldn't be parsed
* or would be shorter or longer than @length.
@@ -5028,7 +5096,7 @@ typedef struct {
const char *num;
} BondMode;
-static BondMode bond_mode_table[] = {
+static const BondMode bond_mode_table[] = {
[0] = { "balance-rr", "0" },
[1] = { "active-backup", "1" },
[2] = { "balance-xor", "2" },
@@ -5080,8 +5148,8 @@ nm_utils_bond_mode_string_to_int (const char *mode)
return -1;
for (i = 0; i < G_N_ELEMENTS (bond_mode_table); i++) {
- if ( strcmp (mode, bond_mode_table[i].str) == 0
- || strcmp (mode, bond_mode_table[i].num) == 0)
+ if (NM_IN_STRSET (mode, bond_mode_table[i].str,
+ bond_mode_table[i].num))
return i;
}
return -1;
@@ -5139,13 +5207,13 @@ _nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b)
return FALSE;
if (k1->type & STRSTRDICTKEY_ALL_SET) {
- if (strcmp (k1->data, k2->data) != 0)
+ if (!nm_streq (k1->data, k2->data))
return FALSE;
if (k1->type == STRSTRDICTKEY_ALL_SET) {
gsize l = strlen (k1->data) + 1;
- return strcmp (&k1->data[l], &k2->data[l]) == 0;
+ return nm_streq (&k1->data[l], &k2->data[l]);
}
}
@@ -5196,7 +5264,7 @@ validate_dns_option (const char *name,
return !!*name;
for (desc = option_descs; desc->name; desc++) {
- if (!strcmp (name, desc->name) &&
+ if (nm_streq (name, desc->name) &&
numeric == desc->numeric &&
(!desc->ipv6_only || ipv6))
return TRUE;
@@ -5286,26 +5354,21 @@ _nm_utils_dns_option_validate (const char *option,
*/
gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option)
{
- gboolean ret;
- char *option_name, *tmp_name;
+ gs_free char *option_name = NULL;
guint i;
if (!_nm_utils_dns_option_validate (option, &option_name, NULL, FALSE, NULL))
return -1;
for (i = 0; i < array->len; i++) {
+ gs_free char *tmp_name = NULL;
+
if (_nm_utils_dns_option_validate (array->pdata[i], &tmp_name, NULL, FALSE, NULL)) {
- ret = strcmp (tmp_name, option_name);
- g_free (tmp_name);
- if (!ret) {
- g_free (option_name);
+ if (nm_streq (tmp_name, option_name))
return i;
- }
}
-
}
- g_free (option_name);
return -1;
}
@@ -5427,9 +5490,9 @@ _nm_utils_is_json_object_no_validation (const char *str, GError **error)
gboolean
nm_utils_is_json_object (const char *str, GError **error)
{
-#if WITH_JSON_VALIDATION
- nm_auto_decref_json json_t *json = NULL;
- json_error_t jerror;
+ nm_auto_decref_json nm_json_t *json = NULL;
+ const NMJsonVt *vt;
+ nm_json_error_t jerror;
g_return_val_if_fail (!error || !*error, FALSE);
@@ -5441,10 +5504,10 @@ nm_utils_is_json_object (const char *str, GError **error)
return FALSE;
}
- if (!nm_jansson_load ())
+ if (!(vt = nm_json_vt ()))
return _nm_utils_is_json_object_no_validation (str, error);
- json = json_loads (str, JSON_REJECT_DUPLICATES, &jerror);
+ json = vt->nm_json_loads (str, NM_JSON_REJECT_DUPLICATES, &jerror);
if (!json) {
g_set_error (error,
NM_CONNECTION_ERROR,
@@ -5457,7 +5520,7 @@ nm_utils_is_json_object (const char *str, GError **error)
/* valid JSON (depending on the definition) can also be a literal.
* Here we only allow objects. */
- if (!json_is_object (json)) {
+ if (!nm_json_is_object (json)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@@ -5466,19 +5529,6 @@ nm_utils_is_json_object (const char *str, GError **error)
}
return TRUE;
-#else /* !WITH_JSON_VALIDATION */
- g_return_val_if_fail (!error || !*error, FALSE);
-
- if (!str || !str[0]) {
- g_set_error_literal (error,
- NM_CONNECTION_ERROR,
- NM_CONNECTION_ERROR_INVALID_PROPERTY,
- str ? _("value is NULL") : _("value is empty"));
- return FALSE;
- }
-
- return _nm_utils_is_json_object_no_validation (str, error);
-#endif
}
static char *
@@ -5752,6 +5802,7 @@ nm_utils_format_variant_attributes (GHashTable *attributes,
char key_value_separator)
{
return _nm_utils_format_variant_attributes (attributes,
+ NULL,
attr_separator,
key_value_separator);
}