summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-06-26 09:36:18 +0200
committerThomas Haller <thaller@redhat.com>2020-06-26 09:36:18 +0200
commit62747bb07653ab362c33abeae04213de7bde177d (patch)
treecf774d691c95512b64fdfc40d677da013a36c6c0
parentd0a2eb8f050d753fa2ca65bbab00ef192bec66d2 (diff)
parent3b4a4bef7b276cbd2ff587d6586ebbce456859eb (diff)
downloadNetworkManager-62747bb07653ab362c33abeae04213de7bde177d.tar.gz
all: merge branch 'th/strbuf-uses'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/547
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile-utils.c44
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile.c257
-rw-r--r--libnm-core/nm-setting-bridge.c35
-rw-r--r--libnm-core/nm-setting-ip-config.c133
-rw-r--r--libnm-core/nm-utils.c332
-rw-r--r--libnm-core/tests/test-general.c50
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c10
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h52
-rw-r--r--shared/nm-glib-aux/nm-str-buf.h99
-rw-r--r--shared/nm-glib-aux/tests/test-shared-general.c2
-rw-r--r--src/supplicant/nm-supplicant-config.c78
12 files changed, 672 insertions, 424 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 1d67b09408..a5ccaeaa5c 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -894,10 +894,6 @@ gboolean nm_utils_base64secret_normalize (const char *base64_key,
/*****************************************************************************/
-void _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan,
- GString *string,
- gboolean leading_space);
-
gboolean nm_utils_connection_is_adhoc_wpa (NMConnection *connection);
const char *nm_utils_wifi_freq_to_band (guint32 freq);
diff --git a/libnm-core/nm-keyfile/nm-keyfile-utils.c b/libnm-core/nm-keyfile/nm-keyfile-utils.c
index 0ffce40b96..e8119b1bd3 100644
--- a/libnm-core/nm-keyfile/nm-keyfile-utils.c
+++ b/libnm-core/nm-keyfile/nm-keyfile-utils.c
@@ -504,8 +504,9 @@ static const char *
_keyfile_key_encode (const char *name,
char **out_to_free)
{
- gsize len, i;
- GString *str;
+ NMStrBuf str;
+ gsize len;
+ gsize i;
nm_assert (name);
nm_assert (out_to_free && !*out_to_free);
@@ -555,14 +556,15 @@ _keyfile_key_encode (const char *name,
len = i + strlen (&name[i]);
nm_assert (len == strlen (name));
- str = g_string_sized_new (len + 15);
+
+ nm_str_buf_init (&str, len + 15u, FALSE);
if (name[0] == ' ') {
nm_assert (i == 0);
- g_string_append (str, "\\20");
+ nm_str_buf_append (&str, "\\20");
i = 1;
} else
- g_string_append_len (str, name, i);
+ nm_str_buf_append_len (&str, name, i);
for (;; i++) {
const guchar ch = (guchar) name[i];
@@ -577,21 +579,24 @@ _keyfile_key_encode (const char *name,
&& g_ascii_isxdigit (name[i + 1])
&& g_ascii_isxdigit (name[i + 2]))
|| ( ch == ' '
- && name[i + 1] == '\0'))
- g_string_append_printf (str, "\\%02X", ch);
- else
- g_string_append_c (str, (char) ch);
+ && name[i + 1] == '\0')) {
+ nm_str_buf_append_c (&str, '\\');
+ nm_str_buf_append_c_hex (&str, ch, TRUE);
+ } else
+ nm_str_buf_append_c (&str, (char) ch);
}
- return (*out_to_free = g_string_free (str, FALSE));
+ return (*out_to_free = nm_str_buf_finalize (&str, NULL));
}
static const char *
_keyfile_key_decode (const char *key,
char **out_to_free)
{
- gsize i, len;
- GString *str;
+ char *out;
+ gsize len;
+ gsize i;
+ gsize j;
nm_assert (key);
nm_assert (out_to_free && !*out_to_free);
@@ -617,9 +622,12 @@ _keyfile_key_decode (const char *key,
return "";
nm_assert (len == strlen (key));
- str = g_string_sized_new (len + 3);
- g_string_append_len (str, key, i);
+ out = g_new (char, len + 1u);
+
+ memcpy (out, key, sizeof (char) * i);
+
+ j = i;
for (;;) {
const char ch = key[i];
char ch1, ch2;
@@ -633,16 +641,18 @@ _keyfile_key_decode (const char *key,
&& g_ascii_isxdigit ((ch2 = key[i + 2]))) {
v = (g_ascii_xdigit_value (ch1) << 4) + g_ascii_xdigit_value (ch2);
if (v != 0) {
- g_string_append_c (str, (char) v);
+ out[j++] = (char) v;
i += 3;
continue;
}
}
- g_string_append_c (str, ch);
+ out[j++] = ch;
i++;
}
- return (*out_to_free = g_string_free (str, FALSE));
+ nm_assert (j <= len);
+ out[j] = '\0';
+ return (*out_to_free = out);
}
/*****************************************************************************/
diff --git a/libnm-core/nm-keyfile/nm-keyfile.c b/libnm-core/nm-keyfile/nm-keyfile.c
index 77af2b6492..aeaf527450 100644
--- a/libnm-core/nm-keyfile/nm-keyfile.c
+++ b/libnm-core/nm-keyfile/nm-keyfile.c
@@ -16,6 +16,7 @@
#include <arpa/inet.h>
#include <linux/pkt_sched.h>
+#include "nm-glib-aux/nm-str-buf.h"
#include "nm-glib-aux/nm-secret-utils.h"
#include "systemd/nm-sd-utils-shared.h"
#include "nm-libnm-core-intern/nm-common-macros.h"
@@ -2107,79 +2108,81 @@ write_ip_values (GKeyFile *file,
const char *gateway,
gboolean is_route)
{
- nm_auto_free_gstring GString *output = NULL;
- int addr_family;
- guint i;
- const char *addr;
- const char *gw;
- guint32 plen;
- char key_name[64];
- char *key_name_idx;
-
- if (!array->len)
- return;
-
- addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME)
- ? AF_INET
- : AF_INET6;
-
- strcpy (key_name, is_route ? "route" : "address");
- key_name_idx = key_name + strlen (key_name);
-
- output = g_string_sized_new (2*INET_ADDRSTRLEN + 10);
- for (i = 0; i < array->len; i++) {
- gint64 metric = -1;
-
- if (is_route) {
- NMIPRoute *route = array->pdata[i];
+ if (array->len > 0) {
+ nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT (2*INET_ADDRSTRLEN + 10, FALSE);
+ int addr_family;
+ guint i;
+ const char *addr;
+ const char *gw;
+ guint32 plen;
+ char key_name[64];
+ char *key_name_idx;
+
+ addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME)
+ ? AF_INET
+ : AF_INET6;
+
+ strcpy (key_name, is_route ? "route" : "address");
+ key_name_idx = key_name + strlen (key_name);
+
+ for (i = 0; i < array->len; i++) {
+ gint64 metric = -1;
+
+ if (is_route) {
+ NMIPRoute *route = array->pdata[i];
+
+ addr = nm_ip_route_get_dest (route);
+ plen = nm_ip_route_get_prefix (route);
+ gw = nm_ip_route_get_next_hop (route);
+ metric = nm_ip_route_get_metric (route);
+ } else {
+ NMIPAddress *address = array->pdata[i];
- addr = nm_ip_route_get_dest (route);
- plen = nm_ip_route_get_prefix (route);
- gw = nm_ip_route_get_next_hop (route);
- metric = nm_ip_route_get_metric (route);
- } else {
- NMIPAddress *address = array->pdata[i];
+ addr = nm_ip_address_get_address (address);
+ plen = nm_ip_address_get_prefix (address);
+ gw = (i == 0)
+ ? gateway
+ : NULL;
+ }
- addr = nm_ip_address_get_address (address);
- plen = nm_ip_address_get_prefix (address);
- gw = (i == 0)
- ? gateway
- : NULL;
- }
+ nm_str_buf_set_size (&output, 0, FALSE, FALSE);
+ nm_str_buf_append_printf (&output, "%s/%u", addr, plen);
+ if ( metric != -1
+ || gw) {
+ /* Older versions of the plugin do not support the form
+ * "a.b.c.d/plen,,metric", so, we always have to write the
+ * gateway, even if there isn't one.
+ * The current version supports reading of the above form.
+ */
+ if (!gw) {
+ if (addr_family == AF_INET)
+ gw = "0.0.0.0";
+ else
+ gw = "::";
+ }
- g_string_set_size (output, 0);
- g_string_append_printf (output, "%s/%u", addr, plen);
- if ( metric != -1
- || gw) {
- /* Older versions of the plugin do not support the form
- * "a.b.c.d/plen,,metric", so, we always have to write the
- * gateway, even if there isn't one.
- * The current version supports reading of the above form.
- */
- if (!gw) {
- if (addr_family == AF_INET)
- gw = "0.0.0.0";
- else
- gw = "::";
+ nm_str_buf_append_c (&output, ',');
+ nm_str_buf_append (&output, gw);
+ if ( is_route
+ && metric != -1)
+ nm_str_buf_append_printf (&output, ",%lu", (unsigned long) metric);
}
- g_string_append_printf (output, ",%s", gw);
- if ( is_route
- && metric != -1)
- g_string_append_printf (output, ",%lu", (unsigned long) metric);
- }
-
- sprintf (key_name_idx, "%u", i + 1);
- nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str);
+ sprintf (key_name_idx, "%u", i + 1);
+ nm_keyfile_plugin_kf_set_string (file,
+ setting_name,
+ key_name,
+ nm_str_buf_get_str (&output));
- if (is_route) {
- gs_free char *attributes = NULL;
+ if (is_route) {
+ gs_free char *attributes = NULL;
- attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]),
- ',', '=');
- if (attributes) {
- g_strlcat (key_name, "_options", sizeof (key_name));
- nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes);
+ attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]),
+ ',', '=');
+ if (attributes) {
+ g_strlcat (key_name, "_options", sizeof (key_name));
+ nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes);
+ }
}
}
}
@@ -2220,34 +2223,29 @@ bridge_vlan_writer (KeyfileWriterInfo *info,
const char *key,
const GValue *value)
{
- NMBridgeVlan *vlan;
GPtrArray *vlans;
- GString *string;
- guint i;
-
- vlans = (GPtrArray *) g_value_get_boxed (value);
- if (!vlans || !vlans->len)
- return;
- string = g_string_new ("");
- for (i = 0; i < vlans->len; i++) {
- gs_free char *vlan_str = NULL;
+ vlans = g_value_get_boxed (value);
+ if ( vlans
+ && vlans->len > 0) {
+ const guint string_initial_size = vlans->len * 10u;
+ nm_auto_str_buf NMStrBuf string = NM_STR_BUF_INIT (string_initial_size, FALSE);
+ guint i;
- vlan = vlans->pdata[i];
- vlan_str = nm_bridge_vlan_to_str (vlan, NULL);
- if (!vlan_str)
- continue;
- if (string->len > 0)
- g_string_append (string, ",");
- nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string);
- }
+ for (i = 0; i < vlans->len; i++) {
+ gs_free char *vlan_str = NULL;
- nm_keyfile_plugin_kf_set_string (info->keyfile,
- nm_setting_get_name (setting),
- "vlans",
- string->str);
+ vlan_str = nm_bridge_vlan_to_str (vlans->pdata[i], NULL);
+ if (i > 0)
+ nm_str_buf_append_c (&string, ',');
+ nm_utils_escaped_tokens_escape_strbuf_assert (vlan_str, ",", &string);
+ }
- g_string_free (string, TRUE);
+ nm_keyfile_plugin_kf_set_string (info->keyfile,
+ nm_setting_get_name (setting),
+ "vlans",
+ nm_str_buf_get_str (&string));
+ }
}
@@ -2348,17 +2346,21 @@ qdisc_writer (KeyfileWriterInfo *info,
const char *key,
const GValue *value)
{
- gsize i;
+ nm_auto_free_gstring GString *key_name = NULL;
+ nm_auto_free_gstring GString *value_str = NULL;
GPtrArray *array;
+ guint i;
- array = (GPtrArray *) g_value_get_boxed (value);
- if (!array || !array->len)
+ array = g_value_get_boxed (value);
+ if ( !array
+ || !array->len)
return;
for (i = 0; i < array->len; i++) {
NMTCQdisc *qdisc = array->pdata[i];
- GString *key_name = g_string_sized_new (16);
- GString *value_str = g_string_sized_new (60);
+
+ nm_gstring_prepare (&key_name);
+ nm_gstring_prepare (&value_str);
g_string_append (key_name, "qdisc.");
_nm_utils_string_append_tc_parent (key_name, NULL,
@@ -2369,9 +2371,6 @@ qdisc_writer (KeyfileWriterInfo *info,
NM_SETTING_TC_CONFIG_SETTING_NAME,
key_name->str,
value_str->str);
-
- g_string_free (key_name, TRUE);
- g_string_free (value_str, TRUE);
}
}
@@ -2381,17 +2380,21 @@ tfilter_writer (KeyfileWriterInfo *info,
const char *key,
const GValue *value)
{
- gsize i;
+ nm_auto_free_gstring GString *key_name = NULL;
+ nm_auto_free_gstring GString *value_str = NULL;
GPtrArray *array;
+ guint i;
- array = (GPtrArray *) g_value_get_boxed (value);
- if (!array || !array->len)
+ array = g_value_get_boxed (value);
+ if ( !array
+ || !array->len)
return;
for (i = 0; i < array->len; i++) {
NMTCTfilter *tfilter = array->pdata[i];
- GString *key_name = g_string_sized_new (16);
- GString *value_str = g_string_sized_new (60);
+
+ nm_gstring_prepare (&key_name);
+ nm_gstring_prepare (&value_str);
g_string_append (key_name, "tfilter.");
_nm_utils_string_append_tc_parent (key_name, NULL,
@@ -2402,9 +2405,6 @@ tfilter_writer (KeyfileWriterInfo *info,
NM_SETTING_TC_CONFIG_SETTING_NAME,
key_name->str,
value_str->str);
-
- g_string_free (key_name, TRUE);
- g_string_free (value_str, TRUE);
}
}
@@ -4309,46 +4309,53 @@ char *
nm_keyfile_utils_create_filename (const char *name,
gboolean with_extension)
{
- GString *str;
- const char *f = name;
/* keyfile used to escape with '*', do not change that behavior.
*
* But for newly added escapings, use '_' instead.
* Also, @with_extension is new-style. */
const char ESCAPE_CHAR = with_extension ? '_' : '*';
const char ESCAPE_CHAR2 = '_';
+ NMStrBuf str;
+ char *p;
+ gsize len;
+ gsize i;
g_return_val_if_fail (name && name[0], NULL);
- str = g_string_sized_new (60);
+ nm_str_buf_init (&str, 0, FALSE);
+
+ len = strlen (name);
+
+ p = nm_str_buf_append_len0 (&str, name, len);
/* Convert '/' to ESCAPE_CHAR */
- for (f = name; f[0]; f++) {
- if (f[0] == '/')
- g_string_append_c (str, ESCAPE_CHAR);
- else
- g_string_append_c (str, f[0]);
+ for (i = 0; i < len; i++) {
+ if (p[i] == '/')
+ p[i] = ESCAPE_CHAR;
}
/* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject.
* We can escape here more aggressivly then what we would read back. */
- if (str->str[0] == '.')
- str->str[0] = ESCAPE_CHAR2;
- if (str->str[str->len - 1] == '~')
- str->str[str->len - 1] = ESCAPE_CHAR2;
- if ( check_mkstemp_suffix (str->str)
- || check_suffix (str->str, PEM_TAG)
- || check_suffix (str->str, DER_TAG))
- g_string_append_c (str, ESCAPE_CHAR2);
+ if (p[0] == '.')
+ p[0] = ESCAPE_CHAR2;
+ if (p[str.len - 1] == '~')
+ p[str.len - 1] = ESCAPE_CHAR2;
+
+ if ( check_mkstemp_suffix (p)
+ || check_suffix (p, PEM_TAG)
+ || check_suffix (p, DER_TAG))
+ nm_str_buf_append_c (&str, ESCAPE_CHAR2);
if (with_extension)
- g_string_append (str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
+ nm_str_buf_append (&str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
+
+ p = nm_str_buf_finalize (&str, NULL);
/* nm_keyfile_utils_create_filename() must mirror ignore_filename() */
- nm_assert (!strchr (str->str, '/'));
- nm_assert (!nm_keyfile_utils_ignore_filename (str->str, with_extension));
+ nm_assert (!strchr (p, '/'));
+ nm_assert (!nm_keyfile_utils_ignore_filename (p, with_extension));
- return g_string_free (str, FALSE);;
+ return p;
}
/*****************************************************************************/
diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c
index 2ead27393e..0595af8730 100644
--- a/libnm-core/nm-setting-bridge.c
+++ b/libnm-core/nm-setting-bridge.c
@@ -10,6 +10,7 @@
#include <ctype.h>
#include <stdlib.h>
+#include "nm-glib-aux/nm-str-buf.h"
#include "nm-connection-private.h"
#include "nm-utils.h"
#include "nm-utils-private.h"
@@ -407,25 +408,6 @@ nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan)
return copy;
}
-void
-_nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan,
- GString *string,
- gboolean leading_space)
-{
- if (nm_bridge_vlan_is_pvid (vlan)) {
- if (leading_space)
- g_string_append_c (string, ' ');
- g_string_append (string, "pvid");
- leading_space = TRUE;
- }
- if (nm_bridge_vlan_is_untagged (vlan)) {
- if (leading_space)
- g_string_append_c (string, ' ');
- g_string_append (string, "untagged");
- leading_space = TRUE;
- }
-}
-
/**
* nm_bridge_vlan_to_str:
* @vlan: the %NMBridgeVlan
@@ -440,7 +422,7 @@ _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan,
char *
nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error)
{
- GString *string;
+ NMStrBuf string;
g_return_val_if_fail (vlan, NULL);
g_return_val_if_fail (!error || !*error, NULL);
@@ -449,16 +431,19 @@ nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error)
* future if more parameters are added to the object that could
* make it invalid. */
- string = g_string_sized_new (28);
+ nm_str_buf_init (&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE);
if (vlan->vid_start == vlan->vid_end)
- g_string_append_printf (string, "%u", vlan->vid_start);
+ nm_str_buf_append_printf (&string, "%u", vlan->vid_start);
else
- g_string_append_printf (string, "%u-%u", vlan->vid_start, vlan->vid_end);
+ nm_str_buf_append_printf (&string, "%u-%u", vlan->vid_start, vlan->vid_end);
- _nm_bridge_vlan_str_append_rest (vlan, string, TRUE);
+ if (nm_bridge_vlan_is_pvid (vlan))
+ nm_str_buf_append (&string, " pvid");
+ if (nm_bridge_vlan_is_untagged (vlan))
+ nm_str_buf_append (&string, " untagged");
- return g_string_free (string, FALSE);
+ return nm_str_buf_finalize (&string, NULL);
}
/**
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index f7a022b6cb..c377452170 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -11,6 +11,7 @@
#include <arpa/inet.h>
#include <linux/fib_rules.h>
+#include "nm-glib-aux/nm-str-buf.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
#include "nm-utils.h"
@@ -3404,7 +3405,7 @@ next_words_consumed:
}
static void
-_rr_string_append_inet_addr (GString *str,
+_rr_string_append_inet_addr (NMStrBuf *str,
gboolean is_from /* or else is-to */,
gboolean required,
int addr_family,
@@ -3415,26 +3416,26 @@ _rr_string_append_inet_addr (GString *str,
if (addr_len == 0) {
if (required) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "%s %s/0",
- is_from ? "from" : "to",
- (addr_family == AF_INET)
- ? "0.0.0.0"
- : "::");
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '),
+ "%s %s/0",
+ is_from ? "from" : "to",
+ (addr_family == AF_INET)
+ ? "0.0.0.0"
+ : "::");
}
return;
}
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "%s %s",
- is_from ? "from" : "to",
- nm_utils_inet_ntop (addr_family,
- addr_bin,
- addr_str));
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '),
+ "%s %s",
+ is_from ? "from" : "to",
+ nm_utils_inet_ntop (addr_family,
+ addr_bin,
+ addr_str));
if (addr_len != nm_utils_addr_family_to_size (addr_family) * 8) {
- g_string_append_printf (str,
- "/%u",
- addr_len);
+ nm_str_buf_append_printf (str,
+ "/%u",
+ addr_len);
}
}
@@ -3457,8 +3458,8 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self,
GHashTable *extra_args,
GError **error)
{
- nm_auto_free_gstring GString *str = NULL;
int addr_family;
+ NMStrBuf str;
g_return_val_if_fail (NM_IS_IP_ROUTING_RULE (self, TRUE), NULL);
@@ -3494,18 +3495,18 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self,
}
}
- str = g_string_sized_new (30);
+ nm_str_buf_init (&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE);
if (self->priority_has) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "priority %u",
- (guint) self->priority);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "priority %u",
+ (guint) self->priority);
}
if (self->invert)
- g_string_append (nm_gstring_add_space_delimiter (str), "not");
+ nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), "not");
- _rr_string_append_inet_addr (str,
+ _rr_string_append_inet_addr (&str,
TRUE,
( !self->to_has
|| !self->to_valid),
@@ -3515,7 +3516,7 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self,
? self->from_len
: 0);
- _rr_string_append_inet_addr (str,
+ _rr_string_append_inet_addr (&str,
FALSE,
FALSE,
addr_family,
@@ -3525,88 +3526,88 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self,
: 0);
if (self->tos != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "tos 0x%02x",
- (guint) self->tos);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "tos 0x%02x",
+ (guint) self->tos);
}
if (self->ipproto != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "ipproto %u",
- (guint) self->ipproto);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "ipproto %u",
+ (guint) self->ipproto);
}
if ( self->fwmark != 0
|| self->fwmask != 0) {
if (self->fwmark != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "fwmark 0x%x",
- self->fwmark);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "fwmark 0x%x",
+ self->fwmark);
} else {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "fwmark 0");
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "fwmark 0");
}
if (self->fwmask != 0xFFFFFFFFu) {
if (self->fwmask != 0)
- g_string_append_printf (str, "/0x%x", self->fwmask);
+ nm_str_buf_append_printf (&str, "/0x%x", self->fwmask);
else
- g_string_append_printf (str, "/0");
+ nm_str_buf_append_printf (&str, "/0");
}
}
if ( self->sport_start != 0
|| self->sport_end != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "sport %u",
- self->sport_start);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "sport %u",
+ self->sport_start);
if (self->sport_start != self->sport_end) {
- g_string_append_printf (str,
- "-%u",
- self->sport_end);
+ nm_str_buf_append_printf (&str,
+ "-%u",
+ self->sport_end);
}
}
if ( self->dport_start != 0
|| self->dport_end != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "dport %u",
- self->dport_start);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "dport %u",
+ self->dport_start);
if (self->dport_start != self->dport_end) {
- g_string_append_printf (str,
- "-%u",
- self->dport_end);
+ nm_str_buf_append_printf (&str,
+ "-%u",
+ self->dport_end);
}
}
if (self->iifname) {
- g_string_append (nm_gstring_add_space_delimiter (str),
- "iif ");
- nm_utils_escaped_tokens_escape_gstr (self->iifname,
- NM_ASCII_SPACES,
- str);
+ nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '),
+ "iif ");
+ nm_utils_escaped_tokens_escape_strbuf (self->iifname,
+ NM_ASCII_SPACES,
+ &str);
}
if (self->oifname) {
- g_string_append (nm_gstring_add_space_delimiter (str),
- "oif ");
- nm_utils_escaped_tokens_escape_gstr (self->oifname,
- NM_ASCII_SPACES,
- str);
+ nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '),
+ "oif ");
+ nm_utils_escaped_tokens_escape_strbuf (self->oifname,
+ NM_ASCII_SPACES,
+ &str);
}
if (self->table != 0) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "table %u",
- (guint) self->table);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "table %u",
+ (guint) self->table);
}
if (self->suppress_prefixlength != -1) {
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "suppress_prefixlength %d",
- (int) self->suppress_prefixlength);
+ nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '),
+ "suppress_prefixlength %d",
+ (int) self->suppress_prefixlength);
}
- return g_string_free (g_steal_pointer (&str), FALSE);
+ return nm_str_buf_finalize (&str, NULL);
}
/*****************************************************************************/
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index c88afb3238..ca6b70ce20 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -20,6 +20,7 @@
#include "nm-json.h"
#endif
+#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 +2068,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 +2194,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);
}
@@ -2376,7 +2377,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 +2470,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 +2526,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,
@@ -2670,9 +2672,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;
@@ -3300,30 +3302,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 +3572,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 +3580,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 +3621,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 +3668,60 @@ static struct cf_pair a_table[] = {
{ 188, 4945 },
{ 192, 4960 },
{ 196, 4980 },
- { 0, -1 }
+ { 0, 0 }
};
-static struct cf_pair bg_table[] = {
+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 const struct cf_pair bg_table[] = {
/* B/G band */
{ 1, 2412 },
{ 2, 2417 },
@@ -3686,7 +3737,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 +3773,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 +3818,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 +3854,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 +3899,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 +3938,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 +3954,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;
}
/**
@@ -5028,7 +5089,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 +5141,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 +5200,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 +5257,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 +5347,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;
}
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index f70a7d5a65..a1c716f473 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -9100,6 +9100,55 @@ test_strsplit_quoted (void)
/*****************************************************************************/
+static void
+_do_wifi_ghz_freqs (const guint *freqs, const char *band)
+{
+ int len;
+ int j;
+ int i;
+
+ g_assert (NM_IN_STRSET (band, "a", "bg"));
+ g_assert (freqs);
+ g_assert (freqs[0] != 0);
+
+ for (i = 0; freqs[i]; i++) {
+ for (j = 0; j < i; j++)
+ g_assert (freqs[i] != freqs[j]);
+ }
+ len = i;
+
+ g_assert (nm_utils_wifi_freq_to_channel (0) == 0);
+ g_assert (nm_utils_wifi_channel_to_freq (0, "bg") == -1);
+ g_assert (nm_utils_wifi_channel_to_freq (0, "foo") == 0);
+ g_assert (!nm_utils_wifi_is_channel_valid (0, "bg"));
+ g_assert (!nm_utils_wifi_is_channel_valid (0, "foo"));
+
+ for (i = 0; i < len; i++) {
+ guint freq = freqs[i];
+ guint32 chan;
+ guint32 freq2;
+
+ chan = nm_utils_wifi_freq_to_channel (freq);
+ g_assert (chan != 0);
+
+ freq2 = nm_utils_wifi_channel_to_freq (chan, band);
+ g_assert (freq2 == freq);
+
+ g_assert (nm_utils_wifi_is_channel_valid (chan, band));
+ }
+
+ g_assert (freqs[len] == 0);
+}
+
+static void
+test_nm_utils_wifi_ghz_freqs (void)
+{
+ _do_wifi_ghz_freqs (nm_utils_wifi_2ghz_freqs (), "bg");
+ _do_wifi_ghz_freqs (nm_utils_wifi_5ghz_freqs (), "a");
+}
+
+/*****************************************************************************/
+
NMTST_DEFINE ();
int main (int argc, char **argv)
@@ -9273,6 +9322,7 @@ int main (int argc, char **argv)
g_test_add_data_func ("/core/general/test_integrate_maincontext/2", GUINT_TO_POINTER (2), test_integrate_maincontext);
g_test_add_func ("/core/general/test_nm_ip_addr_zero", test_nm_ip_addr_zero);
+ g_test_add_func ("/core/general/test_nm_utils_wifi_ghz_freqs", test_nm_utils_wifi_ghz_freqs);
g_test_add_func ("/core/general/test_strsplit_quoted", test_strsplit_quoted);
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c
index a2e90273c5..8290016448 100644
--- a/shared/nm-glib-aux/nm-shared-utils.c
+++ b/shared/nm-glib-aux/nm-shared-utils.c
@@ -23,6 +23,9 @@ G_STATIC_ASSERT (G_STRUCT_OFFSET (NMUtilsNamedValue, value_ptr) == sizeof (const
/*****************************************************************************/
+const char _nm_hexchar_table_lower[16] = "0123456789abcdef";
+const char _nm_hexchar_table_upper[16] = "0123456789ABCDEF";
+
const void *const _NM_PTRARRAY_EMPTY[1] = { NULL };
/*****************************************************************************/
@@ -4966,7 +4969,12 @@ nm_str_buf_append_printf (NMStrBuf *strbuf,
nm_assert (l < G_MAXINT);
if ((gsize) l >= available) {
- gsize l2 = ((gsize) l) + 1u;
+ gsize l2;
+
+ if (l == 0)
+ return;
+
+ l2 = ((gsize) l) + 1u;
nm_str_buf_maybe_expand (strbuf, l2, FALSE);
diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h
index 893ec11c0d..c16a89b3af 100644
--- a/shared/nm-glib-aux/nm-shared-utils.h
+++ b/shared/nm-glib-aux/nm-shared-utils.h
@@ -631,23 +631,24 @@ nm_utils_escaped_tokens_escape (const char *str,
out_to_free);
}
-static inline GString *
-nm_utils_escaped_tokens_escape_gstr_assert (const char *str,
- const char *delimiters,
- GString *gstring)
+/**
+ * nm_utils_escaped_tokens_escape_unnecessary:
+ * @str: the string to check for "escape"
+ * @delimiters: the delimiters
+ *
+ * This asserts that calling nm_utils_escaped_tokens_escape()
+ * on @str has no effect and returns @str directly. This is only
+ * for asserting that @str is safe to not require any escaping.
+ *
+ * Returns: @str
+ */
+static inline const char *
+nm_utils_escaped_tokens_escape_unnecessary (const char *str,
+ const char *delimiters)
{
#if NM_MORE_ASSERTS > 0
- /* Just appends @str to @gstring, but also assert that
- * no escaping is necessary.
- *
- * Use nm_utils_escaped_tokens_escape_gstr_assert() instead
- * of nm_utils_escaped_tokens_escape_gstr(), if you *know* that
- * @str contains no delimiters, no backslashes, and no trailing
- * whitespace that requires escaping. */
-
nm_assert (str);
- nm_assert (gstring);
nm_assert (delimiters);
{
@@ -660,8 +661,16 @@ nm_utils_escaped_tokens_escape_gstr_assert (const char *str,
}
#endif
- g_string_append (gstring, str);
- return gstring;
+ return str;
+}
+
+static inline void
+nm_utils_escaped_tokens_escape_gstr_assert (const char *str,
+ const char *delimiters,
+ GString *gstring)
+{
+ g_string_append (gstring,
+ nm_utils_escaped_tokens_escape_unnecessary (str, delimiters));
}
static inline GString *
@@ -1809,6 +1818,17 @@ int nm_utils_getpagesize (void);
/*****************************************************************************/
+extern const char _nm_hexchar_table_lower[16];
+extern const char _nm_hexchar_table_upper[16];
+
+static inline char
+nm_hexchar (int x, gboolean upper_case)
+{
+ return upper_case
+ ? _nm_hexchar_table_upper[x & 15]
+ : _nm_hexchar_table_lower[x & 15];
+}
+
char *nm_utils_bin2hexstr_full (gconstpointer addr,
gsize length,
char delimiter,
@@ -1985,6 +2005,8 @@ void nm_indirect_g_free (gpointer arg);
* via nm_utils_get_next_realloc_size() gives you 232, and so on. By using
* these sizes, it results in one less allocation, if you anyway don't know the
* exact size in advance. */
+#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((gsize) 32)
+#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((gsize) 40)
#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((gsize) 104)
#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((gsize) 1000)
diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h
index 13af81c01d..61246969de 100644
--- a/shared/nm-glib-aux/nm-str-buf.h
+++ b/shared/nm-glib-aux/nm-str-buf.h
@@ -212,6 +212,16 @@ nm_str_buf_append_c4 (NMStrBuf *strbuf,
}
static inline void
+nm_str_buf_append_c_hex (NMStrBuf *strbuf,
+ char ch,
+ gboolean upper_case)
+{
+ nm_str_buf_maybe_expand (strbuf, 3, FALSE);
+ strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar (((guchar) ch) >> 4, upper_case);
+ strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar ((guchar) ch, upper_case);
+}
+
+static inline void
nm_str_buf_append_len (NMStrBuf *strbuf,
const char *str,
gsize len)
@@ -225,6 +235,25 @@ nm_str_buf_append_len (NMStrBuf *strbuf,
}
}
+static inline char *
+nm_str_buf_append_len0 (NMStrBuf *strbuf,
+ const char *str,
+ gsize len)
+{
+ _nm_str_buf_assert (strbuf);
+
+ /* this is basically like nm_str_buf_append_len() and
+ * nm_str_buf_get_str() in one. */
+
+ nm_str_buf_maybe_expand (strbuf, len + 1u, FALSE);
+ if (len > 0) {
+ memcpy (&strbuf->_priv_str[strbuf->_priv_len], str, len);
+ strbuf->_priv_len += len;
+ }
+ strbuf->_priv_str[strbuf->_priv_len] = '\0';
+ return strbuf->_priv_str;
+}
+
static inline void
nm_str_buf_append (NMStrBuf *strbuf,
const char *str)
@@ -234,6 +263,15 @@ nm_str_buf_append (NMStrBuf *strbuf,
nm_str_buf_append_len (strbuf, str, strlen (str));
}
+static inline char *
+nm_str_buf_append0 (NMStrBuf *strbuf,
+ const char *str)
+{
+ nm_assert (str);
+
+ return nm_str_buf_append_len0 (strbuf, str, strlen (str));
+}
+
void nm_str_buf_append_printf (NMStrBuf *strbuf,
const char *format,
...) _nm_printf (2, 3);
@@ -248,6 +286,65 @@ nm_str_buf_ensure_trailing_c (NMStrBuf *strbuf, char ch)
nm_str_buf_append_c (strbuf, ch);
}
+static inline NMStrBuf *
+nm_str_buf_append_required_delimiter (NMStrBuf *strbuf,
+ char delimiter)
+{
+ _nm_str_buf_assert (strbuf);
+
+ /* appends the @delimiter if it is required (that is, if the
+ * string is not empty). */
+ if (strbuf->len > 0)
+ nm_str_buf_append_c (strbuf, delimiter);
+ return strbuf;
+}
+
+static inline void
+nm_str_buf_reset (NMStrBuf *strbuf,
+ const char *str)
+{
+ _nm_str_buf_assert (strbuf);
+
+ if (strbuf->_priv_len > 0) {
+ if (strbuf->_priv_do_bzero_mem) {
+ /* we only clear the memory that we wrote to. */
+ nm_explicit_bzero (strbuf->_priv_str, strbuf->_priv_len);
+ }
+ strbuf->_priv_len = 0;
+ }
+
+ if (str)
+ nm_str_buf_append (strbuf, str);
+}
+
+/*****************************************************************************/
+
+/* Calls nm_utils_escaped_tokens_escape() on @str and appends the
+ * result to @strbuf. */
+static inline void
+nm_utils_escaped_tokens_escape_strbuf (const char *str,
+ const char *delimiters,
+ NMStrBuf *strbuf)
+{
+ gs_free char *str_to_free = NULL;
+
+ nm_assert (str);
+
+ nm_str_buf_append (strbuf,
+ nm_utils_escaped_tokens_escape (str, delimiters, &str_to_free));
+}
+
+/* Calls nm_utils_escaped_tokens_escape_unnecessary() on @str and appends the
+ * string to @strbuf. */
+static inline void
+nm_utils_escaped_tokens_escape_strbuf_assert (const char *str,
+ const char *delimiters,
+ NMStrBuf *strbuf)
+{
+ nm_str_buf_append (strbuf,
+ nm_utils_escaped_tokens_escape_unnecessary (str, delimiters));
+}
+
/*****************************************************************************/
static inline gboolean
@@ -281,7 +378,7 @@ nm_str_buf_is_initalized (NMStrBuf *strbuf)
* NUL character is always present after "strbuf->len" characters.
* If currently no buffer is allocated, this will return %NULL.
*/
-static inline const char *
+static inline char *
nm_str_buf_get_str (NMStrBuf *strbuf)
{
_nm_str_buf_assert (strbuf);
diff --git a/shared/nm-glib-aux/tests/test-shared-general.c b/shared/nm-glib-aux/tests/test-shared-general.c
index 5c8bdf18e8..a435e28195 100644
--- a/shared/nm-glib-aux/tests/test-shared-general.c
+++ b/shared/nm-glib-aux/tests/test-shared-general.c
@@ -636,6 +636,8 @@ test_nm_utils_get_next_realloc_size (void)
{ G_MAXSIZE - 24u, G_MAXSIZE, G_MAXSIZE },
{ G_MAXSIZE - 1u, G_MAXSIZE, G_MAXSIZE },
{ G_MAXSIZE, G_MAXSIZE, G_MAXSIZE },
+ { NM_UTILS_GET_NEXT_REALLOC_SIZE_32, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, NM_UTILS_GET_NEXT_REALLOC_SIZE_32 },
+ { NM_UTILS_GET_NEXT_REALLOC_SIZE_40, NM_UTILS_GET_NEXT_REALLOC_SIZE_40, NM_UTILS_GET_NEXT_REALLOC_SIZE_40 },
{ NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104 },
{ NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 },
};
diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c
index 058792d026..1e09697721 100644
--- a/src/supplicant/nm-supplicant-config.c
+++ b/src/supplicant/nm-supplicant-config.c
@@ -10,8 +10,8 @@
#include <stdlib.h>
+#include "nm-glib-aux/nm-str-buf.h"
#include "nm-core-internal.h"
-
#include "nm-supplicant-settings-verify.h"
#include "nm-setting.h"
#include "nm-libnm-core-intern/nm-auth-subject.h"
@@ -342,26 +342,39 @@ wifi_freqs_to_string (gboolean bg_band)
{
static const char *str_2ghz = NULL;
static const char *str_5ghz = NULL;
- const char *str;
+ const char **f_p;
+ const char *f;
+
+ f_p = bg_band
+ ? &str_2ghz
+ : &str_5ghz;
- str = bg_band ? str_2ghz : str_5ghz;
+again:
+ f = g_atomic_pointer_get (f_p);
- if (G_UNLIKELY (str == NULL)) {
- GString *tmp;
+ if (G_UNLIKELY (!f)) {
+ nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT (400, FALSE);
const guint *freqs;
int i;
- freqs = bg_band ? nm_utils_wifi_2ghz_freqs () : nm_utils_wifi_5ghz_freqs ();
- tmp = g_string_sized_new (bg_band ? 70 : 225);
- for (i = 0; freqs[i]; i++)
- g_string_append_printf (tmp, i == 0 ? "%d" : " %d", freqs[i]);
- str = g_string_free (tmp, FALSE);
- if (bg_band)
- str_2ghz = str;
- else
- str_5ghz = str;
+ freqs = bg_band
+ ? nm_utils_wifi_2ghz_freqs ()
+ : nm_utils_wifi_5ghz_freqs ();
+ for (i = 0; freqs[i]; i++) {
+ if (i > 0)
+ nm_str_buf_append_c (&strbuf, ' ');
+ nm_str_buf_append_printf (&strbuf, "%u", freqs[i]);
+ }
+
+ f = g_strdup (nm_str_buf_get_str (&strbuf));
+
+ if (!g_atomic_pointer_compare_and_exchange (f_p, NULL, f)) {
+ g_free ((char *) f);
+ goto again;
+ }
}
- return str;
+
+ return f;
}
gboolean
@@ -464,9 +477,9 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
mode = nm_setting_wireless_get_mode (setting);
- is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE;
- is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE;
- is_mesh = (mode && !strcmp (mode, "mesh")) ? TRUE : FALSE;
+ is_adhoc = nm_streq0 (mode, "adhoc");
+ is_ap = nm_streq0 (mode, "ap");
+ is_mesh = nm_streq0 (mode, "mesh");
if (is_adhoc || is_ap)
priv->ap_scan = 2;
else
@@ -540,9 +553,9 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
} else {
const char *freqs = NULL;
- if (!strcmp (band, "a"))
+ if (nm_streq (band, "a"))
freqs = wifi_freqs_to_string (FALSE);
- else if (!strcmp (band, "bg"))
+ else if (nm_streq (band, "bg"))
freqs = wifi_freqs_to_string (TRUE);
if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), NULL, error))
@@ -888,10 +901,10 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
}
/* Only WPA-specific things when using WPA */
- if ( !strcmp (key_mgmt, "wpa-psk")
- || !strcmp (key_mgmt, "wpa-eap")
- || !strcmp (key_mgmt, "sae")
- || !strcmp (key_mgmt, "owe")) {
+ if (NM_IN_STRSET (key_mgmt, "wpa-psk",
+ "wpa-eap",
+ "sae",
+ "owe")) {
if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, NULL, error))
return FALSE;
if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, NULL, error))
@@ -914,7 +927,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
}
/* WEP keys if required */
- if (!strcmp (key_mgmt, "none")) {
+ if (nm_streq (key_mgmt, "none")) {
NMWepKeyType wep_type = nm_setting_wireless_security_get_wep_key_type (setting);
const char *wep0 = nm_setting_wireless_security_get_wep_key (setting, 0);
const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1);
@@ -939,9 +952,9 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
}
}
- if (auth_alg && !strcmp (auth_alg, "leap")) {
+ if (nm_streq0 (auth_alg, "leap")) {
/* LEAP */
- if (!strcmp (key_mgmt, "ieee8021x")) {
+ if (nm_streq (key_mgmt, "ieee8021x")) {
const char *tmp;
tmp = nm_setting_wireless_security_get_leap_username (setting);
@@ -961,7 +974,8 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
}
} else {
/* 802.1x for Dynamic WEP and WPA-Enterprise */
- if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) {
+ if (NM_IN_STRSET (key_mgmt, "ieee8021x",
+ "wpa-eap")) {
if (!setting_8021x) {
g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Cannot set key-mgmt %s with missing 8021x setting", key_mgmt);
@@ -971,7 +985,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
return FALSE;
}
- if (!strcmp (key_mgmt, "wpa-eap")) {
+ if (nm_streq (key_mgmt, "wpa-eap")) {
/* When using WPA-Enterprise, we want to use Proactive Key Caching (also
* called Opportunistic Key Caching) to avoid full EAP exchanges when
* roaming between access points in the same mobility group.
@@ -1135,9 +1149,9 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
phase1 = g_string_new (NULL);
peapver = nm_setting_802_1x_get_phase1_peapver (setting);
if (peapver) {
- if (!strcmp (peapver, "0"))
+ if (nm_streq (peapver, "0"))
g_string_append (phase1, "peapver=0");
- else if (!strcmp (peapver, "1"))
+ else if (nm_streq (peapver, "1"))
g_string_append (phase1, "peapver=1");
}
@@ -1153,7 +1167,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
g_string_append_c (phase1, ' ');
g_string_append_printf (phase1, "fast_provisioning=%s", value);
- if (strcmp (value, "0") != 0)
+ if (!nm_streq (value, "0"))
fast_provisoning_allowed = TRUE;
}