mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-06-20 07:08:29 +02:00
all: merge branch 'th/uuid-normalize'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/880
This commit is contained in:
commit
0d928c670d
18 changed files with 470 additions and 119 deletions
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "nm-settings-storage.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-settings-plugin.h"
|
||||
|
||||
|
|
@ -72,7 +73,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
|
|||
case PROP_UUID:
|
||||
/* construct-only */
|
||||
self->_uuid = g_value_dup_string(value);
|
||||
nm_assert(!self->_uuid || nm_utils_is_uuid(self->_uuid));
|
||||
nm_assert(!self->_uuid || nm_uuid_is_normalized(self->_uuid));
|
||||
break;
|
||||
case PROP_FILENAME:
|
||||
/* construct-only */
|
||||
|
|
@ -97,7 +98,7 @@ NMSettingsStorage *
|
|||
nm_settings_storage_new(NMSettingsPlugin *plugin, const char *uuid, const char *filename)
|
||||
{
|
||||
nm_assert(NM_IS_SETTINGS_PLUGIN(plugin));
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
|
||||
return g_object_new(NM_TYPE_SETTINGS_STORAGE,
|
||||
NM_SETTINGS_STORAGE_PLUGIN,
|
||||
|
|
|
|||
|
|
@ -60,14 +60,14 @@ nm_settings_storage_get_plugin(const NMSettingsStorage *self)
|
|||
return self->_plugin;
|
||||
}
|
||||
|
||||
gboolean nm_uuid_is_valid_full(const char *str);
|
||||
gboolean nm_uuid_is_normalized_full(const char *str);
|
||||
|
||||
static inline const char *
|
||||
nm_settings_storage_get_uuid(const NMSettingsStorage *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL);
|
||||
|
||||
nm_assert(nm_uuid_is_valid_full(self->_uuid));
|
||||
nm_assert(nm_uuid_is_normalized_full(self->_uuid));
|
||||
return self->_uuid;
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ nm_settings_storage_get_uuid_opt(const NMSettingsStorage *self)
|
|||
{
|
||||
g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL);
|
||||
|
||||
nm_assert(!self->_uuid || nm_uuid_is_valid_full(self->_uuid));
|
||||
nm_assert(!self->_uuid || nm_uuid_is_normalized_full(self->_uuid));
|
||||
return self->_uuid;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#endif
|
||||
|
||||
#include "libnm-core-aux-intern/nm-common-macros.h"
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-keyfile-aux.h"
|
||||
#include "libnm-core-intern/nm-keyfile-internal.h"
|
||||
#include "nm-dbus-interface.h"
|
||||
|
|
@ -139,7 +140,7 @@ nm_assert_storage_data_lst(CList *head)
|
|||
u = nm_settings_storage_get_uuid(sd->storage);
|
||||
if (!uuid) {
|
||||
uuid = u;
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
} else
|
||||
nm_assert(nm_streq0(uuid, u));
|
||||
}
|
||||
|
|
@ -182,7 +183,7 @@ _sett_conn_entry_new(const char *uuid)
|
|||
SettConnEntry *sett_conn_entry;
|
||||
gsize l_p_1;
|
||||
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
|
||||
l_p_1 = strlen(uuid) + 1;
|
||||
|
||||
|
|
@ -1461,7 +1462,7 @@ _add_connection_to_first_plugin(NMSettings * self,
|
|||
|
||||
uuid = nm_connection_get_uuid(new_connection);
|
||||
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
|
||||
for (iter = priv->plugins; iter; iter = iter->next) {
|
||||
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN(iter->data);
|
||||
|
|
@ -2295,7 +2296,7 @@ nm_settings_delete_connection(NMSettings * self,
|
|||
nm_assert(NM_IS_SETTINGS_STORAGE(cur_storage));
|
||||
|
||||
uuid = nm_settings_storage_get_uuid(cur_storage);
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
|
||||
sett_conn_entry = _sett_conn_entries_get(self, uuid);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "nms-ifcfg-rh-storage.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "nm-utils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-connection.h"
|
||||
|
|
@ -88,7 +89,7 @@ static NMSIfcfgRHStorage *
|
|||
_storage_new(NMSIfcfgRHPlugin *plugin, const char *uuid, const char *filename)
|
||||
{
|
||||
nm_assert(NMS_IS_IFCFG_RH_PLUGIN(plugin));
|
||||
nm_assert(!uuid || nm_utils_is_uuid(uuid));
|
||||
nm_assert(!uuid || nm_uuid_is_normalized(uuid));
|
||||
nm_assert(filename && filename[0] == '/');
|
||||
|
||||
return g_object_new(NMS_TYPE_IFCFG_RH_STORAGE,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "libnm-std-aux/c-list-util.h"
|
||||
#include "libnm-glib-aux/nm-c-list.h"
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-io-utils.h"
|
||||
|
||||
#include "nm-connection.h"
|
||||
|
|
@ -233,7 +234,7 @@ _read_from_file(const char * full_filename,
|
|||
|
||||
nm_assert(!connection
|
||||
|| (_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS));
|
||||
nm_assert(!connection || nm_utils_is_uuid(nm_connection_get_uuid(connection)));
|
||||
nm_assert(!connection || nm_uuid_is_normalized(nm_connection_get_uuid(connection)));
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
|
@ -260,7 +261,7 @@ _nm_assert_storage(gpointer plugin /* NMSKeyfilePlugin */,
|
|||
|
||||
uuid = nms_keyfile_storage_get_uuid(storage);
|
||||
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
|
||||
nm_assert(((NMSKeyfileStorage *) storage)->is_meta_data
|
||||
|| !(((NMSKeyfileStorage *) storage)->u.conn_data.connection)
|
||||
|
|
@ -1106,7 +1107,7 @@ nms_keyfile_plugin_set_nmmeta_tombstone(NMSKeyfilePlugin * self,
|
|||
const char * dirname;
|
||||
|
||||
nm_assert(NMS_IS_KEYFILE_PLUGIN(self));
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
nm_assert(!out_storage || !*out_storage);
|
||||
nm_assert(!shadowed_storage || (set && in_memory));
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "nms-keyfile-storage.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "nm-utils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nms-keyfile-plugin.h"
|
||||
|
|
@ -108,7 +109,7 @@ _storage_new(NMSKeyfilePlugin * plugin,
|
|||
NMSKeyfileStorage *self;
|
||||
|
||||
nm_assert(NMS_IS_KEYFILE_PLUGIN(plugin));
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
nm_assert(filename && filename[0] == '/');
|
||||
|
||||
self = g_object_new(NMS_TYPE_KEYFILE_STORAGE,
|
||||
|
|
@ -135,7 +136,7 @@ nms_keyfile_storage_new_tombstone(NMSKeyfilePlugin * plugin,
|
|||
{
|
||||
NMSKeyfileStorage *self;
|
||||
|
||||
nm_assert(nm_utils_is_uuid(uuid));
|
||||
nm_assert(nm_uuid_is_normalized(uuid));
|
||||
nm_assert(filename && filename[0] == '/');
|
||||
nm_assert(nms_keyfile_nmmeta_check_filename(filename, NULL));
|
||||
nm_assert(NM_IN_SET(storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, NMS_KEYFILE_STORAGE_TYPE_RUN));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-io-utils.h"
|
||||
#include "libnm-core-intern/nm-keyfile-internal.h"
|
||||
#include "nm-utils.h"
|
||||
|
|
@ -30,9 +31,9 @@
|
|||
const char *
|
||||
nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len)
|
||||
{
|
||||
const char *uuid;
|
||||
const char *s;
|
||||
gsize len;
|
||||
char uuid[37];
|
||||
|
||||
s = strrchr(filename, '/');
|
||||
if (s)
|
||||
|
|
@ -50,17 +51,18 @@ nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len)
|
|||
|
||||
len -= NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA);
|
||||
|
||||
if (!NM_IN_SET(len, 36, 40)) {
|
||||
if (len != 36) {
|
||||
/* the remaining part of the filename has not the right length to
|
||||
* contain a UUID (according to nm_utils_is_uuid()). */
|
||||
* contain a UUID (according to nm_uuid_is_normalized()). */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uuid = nm_strndup_a(100, filename, len, NULL);
|
||||
if (!nm_utils_is_uuid(uuid))
|
||||
memcpy(uuid, filename, 36);
|
||||
uuid[36] = '\0';
|
||||
if (!nm_uuid_is_normalized(uuid))
|
||||
return NULL;
|
||||
|
||||
NM_SET_OUT(out_uuid_len, len);
|
||||
NM_SET_OUT(out_uuid_len, 36);
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temp
|
|||
char *s;
|
||||
|
||||
nm_assert(dirname && dirname[0] == '/');
|
||||
nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/'));
|
||||
nm_assert(nm_uuid_is_normalized(uuid) && !strchr(uuid, '/'));
|
||||
|
||||
if (g_snprintf(filename,
|
||||
sizeof(filename),
|
||||
|
|
@ -80,7 +82,7 @@ nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temp
|
|||
NM_KEYFILE_PATH_SUFFIX_NMMETA,
|
||||
temporary ? "~" : "")
|
||||
>= sizeof(filename)) {
|
||||
/* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always
|
||||
/* valid uuids are limited in length (nm_uuid_is_normalized). The buffer should always
|
||||
* be large enough. */
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
|
@ -137,7 +139,11 @@ nms_keyfile_nmmeta_read(const char * dirname,
|
|||
NMMETA_KF_GROUP_NAME_NMMETA,
|
||||
NMMETA_KF_KEY_NAME_NMMETA_UUID,
|
||||
NULL);
|
||||
if (!nm_streq0(v_uuid, uuid))
|
||||
if (!v_uuid)
|
||||
return FALSE;
|
||||
if (strncmp(v_uuid, uuid, uuid_len) != 0)
|
||||
return FALSE;
|
||||
if (v_uuid[uuid_len] != '\0')
|
||||
return FALSE;
|
||||
|
||||
loaded_path = g_key_file_get_string(kf,
|
||||
|
|
@ -211,7 +217,7 @@ nms_keyfile_nmmeta_write(const char *dirname,
|
|||
int errsv;
|
||||
|
||||
nm_assert(dirname && dirname[0] == '/');
|
||||
nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/'));
|
||||
nm_assert(nm_uuid_is_normalized(uuid) && !strchr(uuid, '/'));
|
||||
nm_assert(!loaded_path || loaded_path[0] == '/');
|
||||
nm_assert(!shadowed_storage || loaded_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ gboolean _nm_connection_detect_slave_type_full(NMSettingConnection *s_con,
|
|||
|
||||
const char *_nm_connection_detect_bluetooth_type(NMConnection *self);
|
||||
|
||||
gboolean _nm_setting_connection_verify_secondaries(GArray *secondaries, GError **error);
|
||||
|
||||
gboolean _nm_connection_verify_required_interface_name(NMConnection *connection, GError **error);
|
||||
|
||||
int _nm_setting_ovs_interface_verify_interface_type(NMSettingOvsInterface *self,
|
||||
|
|
|
|||
|
|
@ -725,6 +725,113 @@ _normalize_connection_uuid(NMConnection *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_connection_verify_secondaries(GArray *secondaries, GError **error)
|
||||
{
|
||||
const char *const *strv;
|
||||
const guint len = nm_g_array_len(secondaries);
|
||||
guint has_normalizable = FALSE;
|
||||
gboolean has_invalid = FALSE;
|
||||
gboolean has_duplicate = FALSE;
|
||||
guint i;
|
||||
|
||||
if (len == 0)
|
||||
return TRUE;
|
||||
|
||||
/* For historic reasons, the secondaries were not normalized/validated.
|
||||
*
|
||||
* Now, when we find any invalid/non-normalized values, we reject/normalize
|
||||
* them. We also filter out duplicates. */
|
||||
|
||||
strv = nm_strvarray_get_strv_non_empty(secondaries, NULL);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
const char *uuid = strv[i];
|
||||
gboolean normalized;
|
||||
|
||||
if (!nm_uuid_is_valid_nm(uuid, &normalized, NULL)) {
|
||||
has_invalid = TRUE;
|
||||
goto out;
|
||||
}
|
||||
if (normalized)
|
||||
has_normalizable = TRUE;
|
||||
}
|
||||
if (has_normalizable)
|
||||
goto out;
|
||||
|
||||
if (len > 1) {
|
||||
gs_free const char **strv_to_free = NULL;
|
||||
const char ** strv2;
|
||||
|
||||
strv2 = nm_utils_strv_dup_shallow_maybe_a(20, strv, len, &strv_to_free);
|
||||
nm_utils_strv_sort(strv2, len);
|
||||
has_duplicate = nm_strv_has_duplicate(strv2, len, TRUE);
|
||||
}
|
||||
|
||||
out:
|
||||
if (has_invalid) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("has an invalid UUID"));
|
||||
} else if (has_normalizable) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("has a UUID that requires normalization"));
|
||||
} else if (has_duplicate) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("has duplicate UUIDs"));
|
||||
} else
|
||||
return TRUE;
|
||||
|
||||
g_prefix_error(error,
|
||||
"%s.%s: ",
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_SECONDARIES);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_connection_secondaries(NMConnection *self)
|
||||
{
|
||||
NMSettingConnection *s_con = nm_connection_get_setting_connection(self);
|
||||
GArray * secondaries;
|
||||
gs_strfreev char ** strv = NULL;
|
||||
guint i;
|
||||
guint j;
|
||||
|
||||
nm_assert(s_con);
|
||||
|
||||
secondaries = _nm_setting_connection_get_secondaries(s_con);
|
||||
if (nm_g_array_len(secondaries) == 0)
|
||||
return FALSE;
|
||||
|
||||
if (_nm_setting_connection_verify_secondaries(secondaries, NULL))
|
||||
return FALSE;
|
||||
|
||||
strv = nm_strvarray_get_strv_non_empty_dup(secondaries, NULL);
|
||||
for (i = 0, j = 0; strv[i]; i++) {
|
||||
gs_free char *s = g_steal_pointer(&strv[i]);
|
||||
char uuid_normalized[37];
|
||||
gboolean uuid_is_normalized;
|
||||
|
||||
if (!nm_uuid_is_valid_nm(s, &uuid_is_normalized, uuid_normalized))
|
||||
continue;
|
||||
|
||||
if (nm_utils_strv_find_first(strv, j, uuid_is_normalized ? uuid_normalized : s) >= 0)
|
||||
continue;
|
||||
|
||||
strv[j++] = uuid_is_normalized ? g_strdup(uuid_normalized) : g_steal_pointer(&s);
|
||||
}
|
||||
strv[j] = NULL;
|
||||
|
||||
g_object_set(s_con, NM_SETTING_CONNECTION_SECONDARIES, strv, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_connection_type(NMConnection *self)
|
||||
{
|
||||
|
|
@ -1617,6 +1724,7 @@ _connection_normalize(NMConnection *connection,
|
|||
was_modified |= _normalize_connection_uuid(connection);
|
||||
was_modified |= _normalize_connection_type(connection);
|
||||
was_modified |= _normalize_connection_slave_type(connection);
|
||||
was_modified |= _normalize_connection_secondaries(connection);
|
||||
was_modified |= _normalize_required_settings(connection);
|
||||
was_modified |= _normalize_invalid_slave_port_settings(connection);
|
||||
was_modified |= _normalize_ip_config(connection, parameters);
|
||||
|
|
@ -1740,7 +1848,7 @@ _nm_connection_ensure_normalized(NMConnection * connection,
|
|||
|
||||
nm_assert(NM_IS_CONNECTION(connection));
|
||||
nm_assert(!out_connection_clone || !*out_connection_clone);
|
||||
nm_assert(!expected_uuid || nm_utils_is_uuid(expected_uuid));
|
||||
nm_assert(!expected_uuid || nm_uuid_is_normalized(expected_uuid));
|
||||
|
||||
if (expected_uuid) {
|
||||
if (nm_streq0(expected_uuid, nm_connection_get_uuid(connection)))
|
||||
|
|
|
|||
|
|
@ -70,26 +70,26 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection,
|
|||
PROP_MUD_URL, );
|
||||
|
||||
typedef struct {
|
||||
GArray *permissions;
|
||||
GSList *secondaries; /* secondary connections to activate with the base connection */
|
||||
char * id;
|
||||
char * uuid;
|
||||
char * stable_id;
|
||||
char * interface_name;
|
||||
char * type;
|
||||
char * master;
|
||||
char * slave_type;
|
||||
char * zone;
|
||||
char * mud_url;
|
||||
guint64 timestamp;
|
||||
int autoconnect_priority;
|
||||
int autoconnect_retries;
|
||||
int multi_connect;
|
||||
int auth_retries;
|
||||
int mdns;
|
||||
int llmnr;
|
||||
int wait_device_timeout;
|
||||
guint gateway_ping_timeout;
|
||||
GArray * permissions;
|
||||
GArray * secondaries;
|
||||
char * id;
|
||||
char * uuid;
|
||||
char * stable_id;
|
||||
char * interface_name;
|
||||
char * type;
|
||||
char * master;
|
||||
char * slave_type;
|
||||
char * zone;
|
||||
char * mud_url;
|
||||
guint64 timestamp;
|
||||
int autoconnect_priority;
|
||||
int autoconnect_retries;
|
||||
int multi_connect;
|
||||
int auth_retries;
|
||||
int mdns;
|
||||
int llmnr;
|
||||
int wait_device_timeout;
|
||||
guint gateway_ping_timeout;
|
||||
NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
|
||||
NMMetered metered;
|
||||
NMSettingConnectionLldp lldp;
|
||||
|
|
@ -741,6 +741,12 @@ nm_setting_connection_get_autoconnect_slaves(NMSettingConnection *setting)
|
|||
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->autoconnect_slaves;
|
||||
}
|
||||
|
||||
GArray *
|
||||
_nm_setting_connection_get_secondaries(NMSettingConnection *setting)
|
||||
{
|
||||
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->secondaries;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_connection_get_num_secondaries:
|
||||
* @setting: the #NMSettingConnection
|
||||
|
|
@ -752,27 +758,37 @@ nm_setting_connection_get_num_secondaries(NMSettingConnection *setting)
|
|||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0);
|
||||
|
||||
return g_slist_length(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->secondaries);
|
||||
return nm_g_array_len(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->secondaries);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_connection_get_secondary:
|
||||
* @setting: the #NMSettingConnection
|
||||
* @idx: the zero-based index of the secondary connection UUID entry
|
||||
* @idx: the zero-based index of the secondary connection UUID entry.
|
||||
* Access one past the length of secondaries is ok and will return
|
||||
* %NULL. Otherwise, it is a user error.
|
||||
*
|
||||
* Returns: the secondary connection UUID at index @idx
|
||||
* Returns: the secondary connection UUID at index @idx or
|
||||
* %NULL if @idx is the number of secondaries.
|
||||
**/
|
||||
const char *
|
||||
nm_setting_connection_get_secondary(NMSettingConnection *setting, guint32 idx)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
guint secondaries_len;
|
||||
|
||||
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL);
|
||||
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
g_return_val_if_fail(idx <= g_slist_length(priv->secondaries), NULL);
|
||||
|
||||
return (const char *) g_slist_nth_data(priv->secondaries, idx);
|
||||
secondaries_len = nm_g_array_len(priv->secondaries);
|
||||
if (idx >= secondaries_len) {
|
||||
/* access one past the length is OK. */
|
||||
g_return_val_if_fail(idx == secondaries_len, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nm_strvarray_get_idx(priv->secondaries, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -806,19 +822,16 @@ gboolean
|
|||
nm_setting_connection_add_secondary(NMSettingConnection *setting, const char *sec_uuid)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
GSList * iter;
|
||||
|
||||
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE);
|
||||
g_return_val_if_fail(sec_uuid != NULL, FALSE);
|
||||
g_return_val_if_fail(sec_uuid[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(sec_uuid, FALSE);
|
||||
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
for (iter = priv->secondaries; iter; iter = g_slist_next(iter)) {
|
||||
if (!strcmp(sec_uuid, (char *) iter->data))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv->secondaries = g_slist_append(priv->secondaries, g_strdup(sec_uuid));
|
||||
if (nm_strvarray_find_first(priv->secondaries, sec_uuid) >= 0)
|
||||
return FALSE;
|
||||
|
||||
nm_strvarray_add(nm_strvarray_ensure(&priv->secondaries), sec_uuid);
|
||||
_notify(setting, PROP_SECONDARIES);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -834,16 +847,14 @@ void
|
|||
nm_setting_connection_remove_secondary(NMSettingConnection *setting, guint32 idx)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
GSList * elt;
|
||||
|
||||
g_return_if_fail(NM_IS_SETTING_CONNECTION(setting));
|
||||
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
elt = g_slist_nth(priv->secondaries, idx);
|
||||
g_return_if_fail(elt != NULL);
|
||||
|
||||
g_free(elt->data);
|
||||
priv->secondaries = g_slist_delete_link(priv->secondaries, elt);
|
||||
g_return_if_fail(idx < nm_g_array_len(priv->secondaries));
|
||||
|
||||
g_array_remove_index(priv->secondaries, idx);
|
||||
_notify(setting, PROP_SECONDARIES);
|
||||
}
|
||||
|
||||
|
|
@ -860,19 +871,15 @@ gboolean
|
|||
nm_setting_connection_remove_secondary_by_value(NMSettingConnection *setting, const char *sec_uuid)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
GSList * iter;
|
||||
|
||||
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE);
|
||||
g_return_val_if_fail(sec_uuid != NULL, FALSE);
|
||||
g_return_val_if_fail(sec_uuid[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(sec_uuid, FALSE);
|
||||
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
for (iter = priv->secondaries; iter; iter = g_slist_next(iter)) {
|
||||
if (!strcmp(sec_uuid, (char *) iter->data)) {
|
||||
priv->secondaries = g_slist_delete_link(priv->secondaries, iter);
|
||||
_notify(setting, PROP_SECONDARIES);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nm_strvarray_remove_first(priv->secondaries, sec_uuid)) {
|
||||
_notify(setting, PROP_SECONDARIES);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1474,6 +1481,9 @@ after_interface_name:
|
|||
return NM_SETTING_VERIFY_NORMALIZABLE;
|
||||
}
|
||||
|
||||
if (!_nm_setting_connection_verify_secondaries(priv->secondaries, error))
|
||||
return NM_SETTING_VERIFY_NORMALIZABLE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1622,7 +1632,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|||
g_value_set_enum(value, nm_setting_connection_get_autoconnect_slaves(setting));
|
||||
break;
|
||||
case PROP_SECONDARIES:
|
||||
g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->secondaries, TRUE));
|
||||
g_value_take_boxed(value, nm_strvarray_get_strv_non_empty_dup(priv->secondaries, NULL));
|
||||
break;
|
||||
case PROP_GATEWAY_PING_TIMEOUT:
|
||||
g_value_set_uint(value, priv->gateway_ping_timeout);
|
||||
|
|
@ -1734,8 +1744,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
|
|||
priv->autoconnect_slaves = g_value_get_enum(value);
|
||||
break;
|
||||
case PROP_SECONDARIES:
|
||||
g_slist_free_full(priv->secondaries, g_free);
|
||||
priv->secondaries = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE);
|
||||
nm_strvarray_set_strv(&priv->secondaries, g_value_get_boxed(value));
|
||||
break;
|
||||
case PROP_GATEWAY_PING_TIMEOUT:
|
||||
priv->gateway_ping_timeout = g_value_get_uint(value);
|
||||
|
|
@ -1814,7 +1823,7 @@ finalize(GObject *object)
|
|||
g_free(priv->slave_type);
|
||||
g_free(priv->mud_url);
|
||||
nm_clear_pointer(&priv->permissions, g_array_unref);
|
||||
g_slist_free_full(priv->secondaries, g_free);
|
||||
nm_clear_pointer(&priv->secondaries, g_array_unref);
|
||||
|
||||
G_OBJECT_CLASS(nm_setting_connection_parent_class)->finalize(object);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ nm_setting_match_get_interface_name(NMSettingMatch *setting, int idx)
|
|||
g_return_val_if_fail(setting->interface_name && idx >= 0 && idx < setting->interface_name->len,
|
||||
NULL);
|
||||
|
||||
return g_array_index(setting->interface_name, const char *, idx);
|
||||
return nm_strvarray_get_idx(setting->interface_name, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,8 +96,7 @@ void
|
|||
nm_setting_match_add_interface_name(NMSettingMatch *setting, const char *interface_name)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_MATCH(setting));
|
||||
g_return_if_fail(interface_name != NULL);
|
||||
g_return_if_fail(interface_name[0] != '\0');
|
||||
g_return_if_fail(interface_name);
|
||||
|
||||
nm_strvarray_add(nm_strvarray_ensure(&setting->interface_name), interface_name);
|
||||
_notify(setting, PROP_INTERFACE_NAME);
|
||||
|
|
@ -138,8 +137,7 @@ gboolean
|
|||
nm_setting_match_remove_interface_name_by_value(NMSettingMatch *setting, const char *interface_name)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE);
|
||||
g_return_val_if_fail(interface_name != NULL, FALSE);
|
||||
g_return_val_if_fail(interface_name[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(interface_name, FALSE);
|
||||
|
||||
if (nm_strvarray_remove_first(setting->interface_name, interface_name)) {
|
||||
_notify(setting, PROP_INTERFACE_NAME);
|
||||
|
|
@ -225,7 +223,7 @@ nm_setting_match_get_kernel_command_line(NMSettingMatch *setting, guint idx)
|
|||
g_return_val_if_fail(setting->kernel_command_line && idx < setting->kernel_command_line->len,
|
||||
NULL);
|
||||
|
||||
return g_array_index(setting->kernel_command_line, const char *, idx);
|
||||
return nm_strvarray_get_idx(setting->kernel_command_line, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -241,8 +239,7 @@ void
|
|||
nm_setting_match_add_kernel_command_line(NMSettingMatch *setting, const char *kernel_command_line)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_MATCH(setting));
|
||||
g_return_if_fail(kernel_command_line != NULL);
|
||||
g_return_if_fail(kernel_command_line[0] != '\0');
|
||||
g_return_if_fail(kernel_command_line);
|
||||
|
||||
nm_strvarray_add(nm_strvarray_ensure(&setting->kernel_command_line), kernel_command_line);
|
||||
_notify(setting, PROP_KERNEL_COMMAND_LINE);
|
||||
|
|
@ -284,8 +281,7 @@ nm_setting_match_remove_kernel_command_line_by_value(NMSettingMatch *setting,
|
|||
const char * kernel_command_line)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE);
|
||||
g_return_val_if_fail(kernel_command_line != NULL, FALSE);
|
||||
g_return_val_if_fail(kernel_command_line[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(kernel_command_line, FALSE);
|
||||
|
||||
if (nm_strvarray_remove_first(setting->kernel_command_line, kernel_command_line)) {
|
||||
_notify(setting, PROP_KERNEL_COMMAND_LINE);
|
||||
|
|
@ -367,7 +363,7 @@ nm_setting_match_get_driver(NMSettingMatch *setting, guint idx)
|
|||
|
||||
g_return_val_if_fail(setting->driver && idx < setting->driver->len, NULL);
|
||||
|
||||
return g_array_index(setting->driver, const char *, idx);
|
||||
return nm_strvarray_get_idx(setting->driver, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -383,8 +379,7 @@ void
|
|||
nm_setting_match_add_driver(NMSettingMatch *setting, const char *driver)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_MATCH(setting));
|
||||
g_return_if_fail(driver != NULL);
|
||||
g_return_if_fail(driver[0] != '\0');
|
||||
g_return_if_fail(driver);
|
||||
|
||||
nm_strvarray_add(nm_strvarray_ensure(&setting->driver), driver);
|
||||
_notify(setting, PROP_DRIVER);
|
||||
|
|
@ -425,8 +420,7 @@ gboolean
|
|||
nm_setting_match_remove_driver_by_value(NMSettingMatch *setting, const char *driver)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE);
|
||||
g_return_val_if_fail(driver != NULL, FALSE);
|
||||
g_return_val_if_fail(driver[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(driver, FALSE);
|
||||
|
||||
if (nm_strvarray_remove_first(setting->driver, driver)) {
|
||||
_notify(setting, PROP_DRIVER);
|
||||
|
|
@ -508,7 +502,7 @@ nm_setting_match_get_path(NMSettingMatch *setting, guint idx)
|
|||
|
||||
g_return_val_if_fail(setting->path && idx < setting->path->len, NULL);
|
||||
|
||||
return g_array_index(setting->path, const char *, idx);
|
||||
return nm_strvarray_get_idx(setting->path, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -524,8 +518,7 @@ void
|
|||
nm_setting_match_add_path(NMSettingMatch *setting, const char *path)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_MATCH(setting));
|
||||
g_return_if_fail(path != NULL);
|
||||
g_return_if_fail(path[0] != '\0');
|
||||
g_return_if_fail(path);
|
||||
|
||||
nm_strvarray_add(nm_strvarray_ensure(&setting->path), path);
|
||||
_notify(setting, PROP_PATH);
|
||||
|
|
@ -566,8 +559,7 @@ gboolean
|
|||
nm_setting_match_remove_path_by_value(NMSettingMatch *setting, const char *path)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE);
|
||||
g_return_val_if_fail(path != NULL, FALSE);
|
||||
g_return_val_if_fail(path[0] != '\0', FALSE);
|
||||
g_return_val_if_fail(path, FALSE);
|
||||
|
||||
if (nm_strvarray_remove_first(setting->path, path)) {
|
||||
_notify(setting, PROP_PATH);
|
||||
|
|
@ -624,16 +616,17 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_INTERFACE_NAME:
|
||||
g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->interface_name, NULL));
|
||||
g_value_take_boxed(value, nm_strvarray_get_strv_non_empty_dup(self->interface_name, NULL));
|
||||
break;
|
||||
case PROP_KERNEL_COMMAND_LINE:
|
||||
g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->kernel_command_line, NULL));
|
||||
g_value_take_boxed(value,
|
||||
nm_strvarray_get_strv_non_empty_dup(self->kernel_command_line, NULL));
|
||||
break;
|
||||
case PROP_DRIVER:
|
||||
g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->driver, NULL));
|
||||
g_value_take_boxed(value, nm_strvarray_get_strv_non_empty_dup(self->driver, NULL));
|
||||
break;
|
||||
case PROP_PATH:
|
||||
g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->path, NULL));
|
||||
g_value_take_boxed(value, nm_strvarray_get_strv_non_empty_dup(self->path, NULL));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
|
|
@ -707,7 +700,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
if (self->interface_name) {
|
||||
for (i = 0; i < self->interface_name->len; i++) {
|
||||
if (nm_str_is_empty(g_array_index(self->interface_name, const char *, i))) {
|
||||
if (nm_str_is_empty(nm_strvarray_get_idx(self->interface_name, i))) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -723,7 +716,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
if (self->kernel_command_line) {
|
||||
for (i = 0; i < self->kernel_command_line->len; i++) {
|
||||
if (nm_str_is_empty(g_array_index(self->kernel_command_line, const char *, i))) {
|
||||
if (nm_str_is_empty(nm_strvarray_get_idx(self->kernel_command_line, i))) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -739,7 +732,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
if (self->driver) {
|
||||
for (i = 0; i < self->driver->len; i++) {
|
||||
if (nm_str_is_empty(g_array_index(self->driver, const char *, i))) {
|
||||
if (nm_str_is_empty(nm_strvarray_get_idx(self->driver, i))) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -755,7 +748,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
if (self->path) {
|
||||
for (i = 0; i < self->path->len; i++) {
|
||||
if (nm_str_is_empty(g_array_index(self->path, const char *, i))) {
|
||||
if (nm_str_is_empty(nm_strvarray_get_idx(self->path, i))) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
|
|||
|
|
@ -5060,7 +5060,7 @@ test_setting_connection_changed_signal(void)
|
|||
ASSERT_CHANGED(nm_setting_connection_add_secondary(s_con, uuid));
|
||||
ASSERT_CHANGED(nm_setting_connection_remove_secondary(s_con, 0));
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < nm_g_array_len(priv->secondaries)));
|
||||
ASSERT_UNCHANGED(nm_setting_connection_remove_secondary(s_con, 1));
|
||||
g_test_assert_expected_messages();
|
||||
|
||||
|
|
@ -7788,7 +7788,7 @@ static void
|
|||
__test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_test)
|
||||
{
|
||||
g_assert(uuid_test);
|
||||
g_assert(nm_utils_is_uuid(uuid_test));
|
||||
g_assert(nm_uuid_is_normalized(uuid_test));
|
||||
|
||||
if (strcmp(uuid_test, expected_uuid)) {
|
||||
g_error("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s",
|
||||
|
|
|
|||
|
|
@ -4465,6 +4465,123 @@ test_setting_metadata(void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_setting_connection_secondaries_verify(void)
|
||||
{
|
||||
gs_unref_object NMConnection *con = NULL;
|
||||
NMSettingConnection * s_con;
|
||||
guint i_run;
|
||||
guint i_word;
|
||||
|
||||
con = nmtst_create_minimal_connection("test-sec", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con);
|
||||
nmtst_connection_normalize(con);
|
||||
|
||||
for (i_run = 0; i_run < 100; i_run++) {
|
||||
guint word_len = nmtst_get_rand_word_length(NULL);
|
||||
gs_unref_ptrarray GPtrArray *arr = NULL;
|
||||
gs_unref_ptrarray GPtrArray *arr_norm = NULL;
|
||||
gboolean was_normalized;
|
||||
gboolean was_normalized2;
|
||||
|
||||
/* create a random list of invalid, normalizable and normalized UUIDs. */
|
||||
arr = g_ptr_array_new();
|
||||
for (i_word = 0; i_word < word_len; i_word++) {
|
||||
g_ptr_array_add(arr,
|
||||
(char *) nmtst_rand_select((const char *) "",
|
||||
"52c3feb9-3aa2-46f6-a07b-1765918699eb",
|
||||
"52C3feb9-3aa2-46f6-a07b-1765918699eb",
|
||||
"52C3feb9-3aa2-46f6-a07b-1765918699eb",
|
||||
"f86dfb13df764894ab3836b7cdb9d82dde8b27c4",
|
||||
"52C3feb93-aa2-46f6-a07b-1765918699eb",
|
||||
"bogus"));
|
||||
}
|
||||
g_ptr_array_add(arr, NULL);
|
||||
|
||||
/* set the new list of secondaries, and assert that the result is as expected. */
|
||||
|
||||
nmtst_assert_connection_verifies_without_normalization(con);
|
||||
|
||||
g_object_set(s_con, NM_SETTING_CONNECTION_SECONDARIES, arr->pdata, NULL);
|
||||
|
||||
#define _assert_secondaries(s_con, expected) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
NMSettingConnection *const _s_con = (s_con); \
|
||||
const char *const * _expected = (expected); \
|
||||
GArray * _secondaries; \
|
||||
const guint _expected_len = NM_PTRARRAY_LEN(_expected); \
|
||||
gs_strfreev char ** _sec_strv = NULL; \
|
||||
guint _i; \
|
||||
\
|
||||
g_assert(_expected); \
|
||||
\
|
||||
if (nmtst_get_rand_bool()) { \
|
||||
_secondaries = _nm_setting_connection_get_secondaries(_s_con); \
|
||||
g_assert_cmpint(_expected_len, ==, nm_g_array_len(_secondaries)); \
|
||||
g_assert((_expected_len == 0) == (!_secondaries)); \
|
||||
g_assert(nm_utils_strv_equal(_expected, nm_strvarray_get_strv(&_secondaries, NULL))); \
|
||||
} \
|
||||
\
|
||||
if (nmtst_get_rand_bool()) { \
|
||||
g_object_get(_s_con, NM_SETTING_CONNECTION_SECONDARIES, &_sec_strv, NULL); \
|
||||
g_assert_cmpint(_expected_len, ==, NM_PTRARRAY_LEN(_sec_strv)); \
|
||||
g_assert((_expected_len == 0) == (!_sec_strv)); \
|
||||
g_assert(nm_utils_strv_equal(_expected, _sec_strv ?: NM_STRV_EMPTY())); \
|
||||
} \
|
||||
\
|
||||
g_assert_cmpint(nm_setting_connection_get_num_secondaries(_s_con), ==, _expected_len); \
|
||||
if (nmtst_get_rand_bool()) { \
|
||||
for (_i = 0; _i < _expected_len; _i++) { \
|
||||
g_assert_cmpstr(nm_setting_connection_get_secondary(_s_con, _i), \
|
||||
==, \
|
||||
_expected[_i]); \
|
||||
} \
|
||||
g_assert_null(nm_setting_connection_get_secondary(_s_con, _expected_len)); \
|
||||
} \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
_assert_secondaries(s_con, (const char *const *) arr->pdata);
|
||||
|
||||
/* reimplement the normalization that we expect to happen and
|
||||
* create an array @arr_norm with the expected result after normalization. */
|
||||
arr_norm = g_ptr_array_new_with_free_func(g_free);
|
||||
for (i_word = 0; i_word < word_len; i_word++) {
|
||||
const char *s = arr->pdata[i_word];
|
||||
gboolean is_normalized;
|
||||
char uuid_normalized[37];
|
||||
|
||||
if (!nm_uuid_is_valid_nm(s, &is_normalized, uuid_normalized))
|
||||
continue;
|
||||
|
||||
if (is_normalized)
|
||||
s = uuid_normalized;
|
||||
|
||||
if (nm_utils_strv_find_first((char **) arr_norm->pdata, arr_norm->len, s) >= 0)
|
||||
continue;
|
||||
|
||||
g_ptr_array_add(arr_norm, g_strdup(s));
|
||||
}
|
||||
g_ptr_array_add(arr_norm, NULL);
|
||||
|
||||
was_normalized = !nm_utils_strv_equal((char **) arr->pdata, (char **) arr_norm->pdata);
|
||||
|
||||
if (was_normalized)
|
||||
nmtst_assert_connection_verifies_and_normalizable(con);
|
||||
else
|
||||
nmtst_assert_connection_verifies_without_normalization(con);
|
||||
|
||||
if (was_normalized || nmtst_get_rand_bool()) {
|
||||
was_normalized2 = nmtst_connection_normalize(con);
|
||||
g_assert(was_normalized == was_normalized2);
|
||||
}
|
||||
|
||||
_assert_secondaries(s_con, (const char *const *) arr_norm->pdata);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
||||
int
|
||||
|
|
@ -4483,6 +4600,9 @@ main(int argc, char **argv)
|
|||
test_8021x);
|
||||
g_test_add_data_func("/libnm/setting-8021x/pkcs12", "test-cert.p12, test", test_8021x);
|
||||
|
||||
g_test_add_func("/libnm/settings/test_setting_connection_secondaries_verify",
|
||||
test_setting_connection_secondaries_verify);
|
||||
|
||||
g_test_add_func("/libnm/settings/bond/verify", test_bond_verify);
|
||||
g_test_add_func("/libnm/settings/bond/compare", test_bond_compare);
|
||||
g_test_add_func("/libnm/settings/bond/normalize", test_bond_normalize);
|
||||
|
|
|
|||
|
|
@ -515,6 +515,10 @@ GPtrArray *_nm_setting_bridge_port_get_vlans(NMSettingBridgePort *setting);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
GArray *_nm_setting_connection_get_secondaries(NMSettingConnection *setting);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMSettingBluetooth *_nm_connection_get_setting_bluetooth_for_nap(NMConnection *connection);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -2290,6 +2290,36 @@ nm_utils_strv_find_first(char **list, gssize len, const char *needle)
|
|||
return -1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_strv_has_duplicate(const char *const *strv, gssize len, gboolean is_sorted)
|
||||
{
|
||||
gsize l;
|
||||
gsize i;
|
||||
gsize j;
|
||||
|
||||
l = len < 0 ? NM_PTRARRAY_LEN(strv) : (gsize) len;
|
||||
|
||||
if (is_sorted) {
|
||||
#if NM_MORE_ASSERTS > 10
|
||||
for (i = 1; i < l; i++)
|
||||
nm_assert(nm_strcmp0(strv[i - 1], strv[i]) <= 0);
|
||||
#endif
|
||||
for (i = 1; i < l; i++) {
|
||||
if (nm_streq0(strv[i - 1], strv[i]))
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < l; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (nm_streq0(strv[j], strv[i]))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char **
|
||||
_nm_utils_strv_cleanup(char ** strv,
|
||||
gboolean strip_whitespace,
|
||||
|
|
|
|||
|
|
@ -710,6 +710,8 @@ nm_utils_strsplit_set(const char *str, const char *delimiters)
|
|||
|
||||
gssize nm_utils_strv_find_first(char **list, gssize len, const char *needle);
|
||||
|
||||
gboolean nm_strv_has_duplicate(const char *const *list, gssize len, gboolean is_sorted);
|
||||
|
||||
char **_nm_utils_strv_cleanup(char ** strv,
|
||||
gboolean strip_whitespace,
|
||||
gboolean skip_empty,
|
||||
|
|
@ -1907,6 +1909,34 @@ const char **_nm_utils_strv_dup_packed(const char *const *strv, gssize len);
|
|||
|
||||
#define nm_utils_strv_dup_packed(strv, len) _nm_utils_strv_dup_packed(NM_CAST_STRV_CC(strv), (len))
|
||||
|
||||
#define nm_utils_strv_dup_shallow_maybe_a(alloca_maxlen, strv, len, to_free) \
|
||||
({ \
|
||||
const char *const *const _strv = NM_CAST_STRV_CC(strv); \
|
||||
const gssize _len = (len); \
|
||||
const char ** _result = NULL; \
|
||||
const char ***const _to_free = (to_free); \
|
||||
\
|
||||
G_STATIC_ASSERT_EXPR((alloca_maxlen) <= 500u / sizeof(const char *)); \
|
||||
G_STATIC_ASSERT_EXPR((alloca_maxlen) > 0u); \
|
||||
nm_assert(_to_free && !*_to_free); \
|
||||
\
|
||||
if (_len >= 0 || _strv) { \
|
||||
const gsize _l = (_len < 0) ? NM_PTRARRAY_LEN(_strv) : ((gsize) _len); \
|
||||
\
|
||||
if (G_LIKELY(_l < (alloca_maxlen))) { \
|
||||
_result = g_newa(const char *, _l + 1); \
|
||||
} else { \
|
||||
_result = g_new(const char *, _l + 1); \
|
||||
*_to_free = _result; \
|
||||
} \
|
||||
if (_l > 0) \
|
||||
memcpy(_result, _strv, _l * sizeof(const char *)); \
|
||||
_result[_l] = NULL; \
|
||||
} \
|
||||
\
|
||||
_result; \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GSList *nm_utils_g_slist_find_str(const GSList *list, const char *needle);
|
||||
|
|
@ -2717,6 +2747,15 @@ nm_strvarray_add(GArray *array, const char *str)
|
|||
g_array_append_val(array, s);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
nm_strvarray_get_idx(GArray *array, guint idx)
|
||||
{
|
||||
nm_assert(array);
|
||||
nm_assert(idx < array->len);
|
||||
|
||||
return g_array_index(array, const char *, idx);
|
||||
}
|
||||
|
||||
static inline const char *const *
|
||||
nm_strvarray_get_strv_non_empty(GArray *arr, guint *length)
|
||||
{
|
||||
|
|
@ -2729,6 +2768,21 @@ nm_strvarray_get_strv_non_empty(GArray *arr, guint *length)
|
|||
return &g_array_index(arr, const char *, 0);
|
||||
}
|
||||
|
||||
static inline char **
|
||||
nm_strvarray_get_strv_non_empty_dup(GArray *arr, guint *length)
|
||||
{
|
||||
const char *const *strv;
|
||||
|
||||
if (!arr || arr->len == 0) {
|
||||
NM_SET_OUT(length, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NM_SET_OUT(length, arr->len);
|
||||
strv = &g_array_index(arr, const char *, 0);
|
||||
return nm_utils_strv_dup(strv, arr->len, TRUE);
|
||||
}
|
||||
|
||||
static inline const char *const *
|
||||
nm_strvarray_get_strv(GArray **arr, guint *length)
|
||||
{
|
||||
|
|
@ -2756,8 +2810,8 @@ nm_strvarray_set_strv(GArray **array, const char *const *strv)
|
|||
nm_strvarray_add(*array, strv[0]);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_strvarray_remove_first(GArray *strv, const char *needle)
|
||||
static inline gssize
|
||||
nm_strvarray_find_first(GArray *strv, const char *needle)
|
||||
{
|
||||
guint i;
|
||||
|
||||
|
|
@ -2765,13 +2819,25 @@ nm_strvarray_remove_first(GArray *strv, const char *needle)
|
|||
|
||||
if (strv) {
|
||||
for (i = 0; i < strv->len; i++) {
|
||||
if (nm_streq(needle, g_array_index(strv, const char *, i))) {
|
||||
g_array_remove_index(strv, i);
|
||||
return TRUE;
|
||||
}
|
||||
if (nm_streq(needle, g_array_index(strv, const char *, i)))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_strvarray_remove_first(GArray *strv, const char *needle)
|
||||
{
|
||||
gssize idx;
|
||||
|
||||
nm_assert(needle);
|
||||
|
||||
idx = nm_strvarray_find_first(strv, needle);
|
||||
if (idx < 0)
|
||||
return FALSE;
|
||||
g_array_remove_index(strv, idx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -130,13 +130,13 @@ nm_uuid_generate_random(NMUuid *out_uuid)
|
|||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_uuid_is_valid_full(const char *str)
|
||||
nm_uuid_is_normalized_full(const char *str)
|
||||
{
|
||||
/* The only reason why this exists is that nm_uuid_is_valid() is an inline function.
|
||||
/* The only reason why this exists is that nm_uuid_is_normalized() is an inline function.
|
||||
* If you need to forward declare the function, that won't work.
|
||||
*
|
||||
* Usually, you wouldn't use this variant! */
|
||||
return nm_uuid_is_valid(str);
|
||||
return nm_uuid_is_normalized(str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -33,14 +33,22 @@ gboolean nm_uuid_is_null(const NMUuid *uuid);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_uuid_is_valid_full(const char *str);
|
||||
|
||||
static inline gboolean
|
||||
nm_uuid_is_valid(const char *str)
|
||||
{
|
||||
return str && nm_uuid_parse_full(str, NULL, NULL);
|
||||
}
|
||||
|
||||
gboolean nm_uuid_is_normalized_full(const char *str);
|
||||
|
||||
static inline gboolean
|
||||
nm_uuid_is_normalized(const char *str)
|
||||
{
|
||||
gboolean is_normalized;
|
||||
|
||||
return str && nm_uuid_parse_full(str, NULL, &is_normalized) && is_normalized;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_uuid_is_valid_nmlegacy(const char *str);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue