mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-17 23:20:29 +01:00
nmcli: merge branch 'th/nmcli-list-options'
https://github.com/NetworkManager/NetworkManager/pull/317
This commit is contained in:
commit
f224d6a853
28 changed files with 2300 additions and 2737 deletions
|
|
@ -669,6 +669,7 @@ libnm_core_lib_h_pub_mkenums = \
|
|||
libnm-core/nm-core-enum-types.h
|
||||
libnm_core_lib_h_priv = \
|
||||
shared/nm-ethtool-utils.h \
|
||||
shared/nm-libnm-core-utils.h \
|
||||
shared/nm-meta-setting.h \
|
||||
libnm-core/nm-crypto.h \
|
||||
libnm-core/nm-crypto-impl.h \
|
||||
|
|
@ -731,6 +732,7 @@ libnm_core_lib_c_settings_real = \
|
|||
libnm_core_lib_c_real = \
|
||||
$(libnm_core_lib_c_settings_real) \
|
||||
shared/nm-ethtool-utils.c \
|
||||
shared/nm-libnm-core-utils.c \
|
||||
shared/nm-meta-setting.c \
|
||||
libnm-core/nm-crypto.c \
|
||||
libnm-core/nm-connection.c \
|
||||
|
|
@ -3914,6 +3916,8 @@ clients_common_libnmc_la_SOURCES = \
|
|||
\
|
||||
shared/nm-ethtool-utils.c \
|
||||
shared/nm-ethtool-utils.h \
|
||||
shared/nm-libnm-core-utils.c \
|
||||
shared/nm-libnm-core-utils.h \
|
||||
\
|
||||
clients/common/nm-meta-setting-desc.c \
|
||||
clients/common/nm-meta-setting-desc.h \
|
||||
|
|
|
|||
|
|
@ -3959,11 +3959,12 @@ set_property (NMClient *client,
|
|||
char modifier,
|
||||
GError **error)
|
||||
{
|
||||
gs_free char *property_name = NULL, *value_free = NULL;
|
||||
gs_free char *property_name = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
NMSetting *setting;
|
||||
GError *local = NULL;
|
||||
|
||||
g_assert (setting_name && setting_name[0]);
|
||||
nm_assert (setting_name && setting_name[0]);
|
||||
nm_assert (NM_IN_SET (modifier, '\0', '+', '-'));
|
||||
|
||||
setting = nm_connection_get_setting_by_name (connection, setting_name);
|
||||
if (!setting) {
|
||||
|
|
@ -3977,48 +3978,26 @@ set_property (NMClient *client,
|
|||
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
|
||||
_("Error: invalid property '%s': %s."),
|
||||
property, local->message);
|
||||
g_clear_error (&local);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (modifier != '-') {
|
||||
/* Set/add value */
|
||||
if (modifier != '+') {
|
||||
/* We allow the existing property value to be passed as parameter,
|
||||
* so make a copy if we are going to free it.
|
||||
*/
|
||||
value = value_free = g_strdup (value);
|
||||
nmc_setting_reset_property (setting, property_name, NULL);
|
||||
}
|
||||
if (!nmc_setting_set_property (client, setting, property_name, value, &local)) {
|
||||
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
|
||||
_("Error: failed to modify %s.%s: %s."),
|
||||
setting_name, property, local->message);
|
||||
g_clear_error (&local);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Remove value
|
||||
* - either empty: remove whole value
|
||||
* - or specified by index <0-n>: remove item at the index
|
||||
* - or option name: remove item with the option name
|
||||
*/
|
||||
if (value) {
|
||||
unsigned long idx;
|
||||
|
||||
if (nmc_string_to_uint (value, TRUE, 0, G_MAXUINT32, &idx))
|
||||
nmc_setting_remove_property_option (setting, property_name, NULL, idx, &local);
|
||||
else
|
||||
nmc_setting_remove_property_option (setting, property_name, value, 0, &local);
|
||||
if (local) {
|
||||
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
|
||||
_("Error: failed to remove a value from %s.%s: %s."),
|
||||
setting_name, property, local->message);
|
||||
g_clear_error (&local);
|
||||
return FALSE;
|
||||
}
|
||||
} else
|
||||
nmc_setting_reset_property (setting, property_name, NULL);
|
||||
if (!nmc_setting_set_property (client,
|
||||
setting,
|
||||
property_name,
|
||||
( (modifier == '-' && !value)
|
||||
? '\0'
|
||||
: modifier),
|
||||
value,
|
||||
&local)) {
|
||||
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
|
||||
_("Error: failed to %s %s.%s: %s."),
|
||||
( modifier != '-'
|
||||
? "modify"
|
||||
: "remove a value from"),
|
||||
setting_name,
|
||||
property,
|
||||
local->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Don't ask for this property in interactive mode. */
|
||||
|
|
@ -6904,7 +6883,6 @@ property_edit_submenu (NmCli *nmc,
|
|||
gs_free char *cmd_property_user = NULL;
|
||||
gs_free char *cmd_property_arg = NULL;
|
||||
gs_free char *prop_val_user = NULL;
|
||||
nm_auto_unset_gvalue GValue prop_g_value = G_VALUE_INIT;
|
||||
gboolean removed;
|
||||
gboolean dirty;
|
||||
|
||||
|
|
@ -6954,24 +6932,17 @@ property_edit_submenu (NmCli *nmc,
|
|||
} else
|
||||
prop_val_user = g_strdup (cmd_property_arg);
|
||||
|
||||
/* nmc_setting_set_property() only adds new value, thus we have to
|
||||
* remove the original value and save it for error cases.
|
||||
*/
|
||||
if (cmdsub == NMC_EDITOR_SUB_CMD_SET) {
|
||||
nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||
nmc_property_set_default_value (curr_setting, prop_name);
|
||||
}
|
||||
|
||||
set_result = nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err);
|
||||
set_result = nmc_setting_set_property (nmc->client,
|
||||
curr_setting,
|
||||
prop_name,
|
||||
(cmdsub == NMC_EDITOR_SUB_CMD_SET)
|
||||
? '\0'
|
||||
: '+',
|
||||
prop_val_user,
|
||||
&tmp_err);
|
||||
if (!set_result) {
|
||||
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
if (cmdsub == NMC_EDITOR_SUB_CMD_SET) {
|
||||
/* Block change signals and restore original value */
|
||||
g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
|
||||
nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||
g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -6982,41 +6953,23 @@ property_edit_submenu (NmCli *nmc,
|
|||
_("Edit '%s' value: "),
|
||||
prop_name);
|
||||
|
||||
nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||
nmc_property_set_default_value (curr_setting, prop_name);
|
||||
|
||||
if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err)) {
|
||||
if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, '\0', prop_val_user, &tmp_err)) {
|
||||
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
|
||||
nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||
g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case NMC_EDITOR_SUB_CMD_REMOVE:
|
||||
if (cmd_property_arg) {
|
||||
unsigned long val_int = G_MAXUINT32;
|
||||
gs_free char *option = NULL;
|
||||
|
||||
if (!nmc_string_to_uint (cmd_property_arg, TRUE, 0, G_MAXUINT32, &val_int)) {
|
||||
option = g_strdup (cmd_property_arg);
|
||||
g_strstrip (option);
|
||||
}
|
||||
|
||||
if (!nmc_setting_remove_property_option (curr_setting, prop_name,
|
||||
option,
|
||||
(guint32) val_int,
|
||||
&tmp_err)) {
|
||||
g_print (_("Error: %s\n"), tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
}
|
||||
} else {
|
||||
if (!nmc_setting_reset_property (curr_setting, prop_name, &tmp_err)) {
|
||||
g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
|
||||
tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
}
|
||||
if (!nmc_setting_set_property (nmc->client,
|
||||
curr_setting,
|
||||
prop_name,
|
||||
( cmd_property_arg
|
||||
? '-'
|
||||
: '\0'),
|
||||
cmd_property_arg,
|
||||
&tmp_err)) {
|
||||
g_print (_("Error: %s\n"), tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -7367,8 +7320,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
_("Enter '%s' value: "),
|
||||
prop_name);
|
||||
|
||||
/* Set property value */
|
||||
if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, prop_val_user, &tmp_err)) {
|
||||
if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '+', prop_val_user, &tmp_err)) {
|
||||
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
}
|
||||
|
|
@ -7428,8 +7380,13 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
prop_name);
|
||||
}
|
||||
|
||||
/* Set property value */
|
||||
if (!nmc_setting_set_property (nmc->client, ss, prop_name, cmd_arg_v, &tmp_err)) {
|
||||
/* setting a value in edit mode "appends". That seems unexpected behavior. */
|
||||
if (!nmc_setting_set_property (nmc->client,
|
||||
ss,
|
||||
prop_name,
|
||||
cmd_arg_v ? '+' : '\0',
|
||||
cmd_arg_v,
|
||||
&tmp_err)) {
|
||||
g_print (_("Error: failed to set '%s' property: %s\n"),
|
||||
prop_name, tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
|
|
@ -7526,8 +7483,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
if (!prop_name)
|
||||
break;
|
||||
|
||||
/* Delete property value */
|
||||
if (!nmc_setting_reset_property (menu_ctx.curr_setting, prop_name, &tmp_err)) {
|
||||
if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '\0', NULL, &tmp_err)) {
|
||||
g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
|
||||
tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
|
|
@ -7577,8 +7533,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
|
||||
prop_name = is_property_valid (ss, cmd_arg_p, &tmp_err);
|
||||
if (prop_name) {
|
||||
/* Delete property value */
|
||||
if (!nmc_setting_reset_property (ss, prop_name, &tmp_err)) {
|
||||
if (!nmc_setting_set_property (nmc->client, ss, prop_name, '\0', NULL, &tmp_err)) {
|
||||
g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
|
||||
tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
|
|
@ -8148,6 +8103,9 @@ editor_init_existing_connection (NMConnection *connection)
|
|||
NMSettingWireless *s_wireless;
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
/* FIXME: this approach of connecting handlers to do something is fundamentally
|
||||
* flawed. See the comment in nmc_setting_ip6_connect_handlers(). */
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||
s_proxy = nm_connection_get_setting_proxy (connection);
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ ipv4_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
|
|||
static void
|
||||
ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
static GValue value = G_VALUE_INIT;
|
||||
static GPtrArray *old_value = NULL;
|
||||
static gboolean answered = FALSE;
|
||||
static gboolean answer = FALSE;
|
||||
|
||||
|
|
@ -103,17 +103,17 @@ ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|||
answer = get_answer ("ipv4.addresses", NULL);
|
||||
}
|
||||
if (answer) {
|
||||
if (G_IS_VALUE (&value))
|
||||
g_value_unset (&value);
|
||||
nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
|
||||
nm_clear_pointer (&old_value, g_ptr_array_unref);
|
||||
g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL);
|
||||
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
answered = FALSE;
|
||||
if (G_IS_VALUE (&value)) {
|
||||
nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
|
||||
g_value_unset (&value);
|
||||
if (old_value) {
|
||||
gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value);
|
||||
|
||||
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +142,25 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
|
|||
}
|
||||
} else {
|
||||
answered = FALSE;
|
||||
/* FIXME: editor_init_existing_connection() and registering handlers is not the
|
||||
* right approach.
|
||||
*
|
||||
* This only happens to work because in nmcli's edit mode
|
||||
* tends to append addresses -- instead of setting them.
|
||||
* If we would change that (to behavior I'd expect), we'd get:
|
||||
*
|
||||
* nmcli> set ipv6.addresses fc01::1:5/68
|
||||
* Do you also want to set 'ipv6.method' to 'manual'? [yes]: y
|
||||
* nmcli> set ipv6.addresses fc01::1:6/68
|
||||
* Do you also want to set 'ipv6.method' to 'manual'? [yes]:
|
||||
*
|
||||
* That's because nmc_setting_set_property() calls set_fcn(). With modifier '\0'
|
||||
* (set), it would first clear all addresses before adding the address. Thereby
|
||||
* emitting multiple property changed signals.
|
||||
*
|
||||
* That can be avoided by freezing/thawing the signals, but this solution
|
||||
* here is ugly in general.
|
||||
*/
|
||||
if (!g_strcmp0 (nm_setting_ip_config_get_method (NM_SETTING_IP_CONFIG (object)), NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
|
||||
g_object_set (object, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
|
||||
}
|
||||
|
|
@ -152,7 +171,7 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
|
|||
static void
|
||||
ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
static GValue value = G_VALUE_INIT;
|
||||
static GPtrArray *old_value = NULL;
|
||||
static gboolean answered = FALSE;
|
||||
static gboolean answer = FALSE;
|
||||
|
||||
|
|
@ -166,17 +185,17 @@ ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|||
answer = get_answer ("ipv6.addresses", NULL);
|
||||
}
|
||||
if (answer) {
|
||||
if (G_IS_VALUE (&value))
|
||||
g_value_unset (&value);
|
||||
nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
|
||||
nm_clear_pointer (&old_value, g_ptr_array_unref);
|
||||
g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL);
|
||||
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
answered = FALSE;
|
||||
if (G_IS_VALUE (&value)) {
|
||||
nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
|
||||
g_value_unset (&value);
|
||||
if (old_value) {
|
||||
gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value);
|
||||
|
||||
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -509,151 +528,67 @@ nmc_setting_get_property_parsable (NMSetting *setting, const char *prop, GError
|
|||
return get_property_val (setting, prop, NM_META_ACCESSOR_GET_TYPE_PARSABLE, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_fcn_call (const NMMetaPropertyInfo *property_info,
|
||||
NMSetting *setting,
|
||||
const char *value,
|
||||
GError **error)
|
||||
{
|
||||
return property_info->property_type->set_fcn (property_info,
|
||||
nmc_meta_environment,
|
||||
nmc_meta_environment_arg,
|
||||
setting,
|
||||
value,
|
||||
error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic function for setting property value.
|
||||
*
|
||||
* Sets property=value in setting by calling specialized functions.
|
||||
* If value is NULL then default property value is set.
|
||||
*
|
||||
* Returns: TRUE on success; FALSE on failure and sets error
|
||||
*/
|
||||
gboolean
|
||||
nmc_setting_set_property (NMClient *client, NMSetting *setting, const char *prop, const char *value, GError **error)
|
||||
nmc_setting_set_property (NMClient *client,
|
||||
NMSetting *setting,
|
||||
const char *prop,
|
||||
char modifier,
|
||||
const char *value,
|
||||
GError **error)
|
||||
{
|
||||
const NMMetaPropertyInfo *property_info;
|
||||
gs_free char *value_to_free = NULL;
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IN_SET (modifier, '\0', '-', '+'), FALSE);
|
||||
g_return_val_if_fail (value || modifier == '\0', FALSE);
|
||||
|
||||
if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
|
||||
if (!(property_info = nm_meta_property_info_find_by_setting (setting, prop)))
|
||||
goto out_fail_read_only;
|
||||
if (!property_info->property_type->set_fcn)
|
||||
goto out_fail_read_only;
|
||||
|
||||
if (!value) {
|
||||
/* No value argument sets default value */
|
||||
nmc_property_set_default_value (setting, prop);
|
||||
return TRUE;
|
||||
}
|
||||
if ( modifier == '-'
|
||||
&& !property_info->property_type->set_supports_remove) {
|
||||
/* The property is a plain property. It does not support '-'.
|
||||
*
|
||||
* Maybe we should fail, but just return silently. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (property_info->property_type->set_fcn) {
|
||||
switch (property_info->setting_info->general->meta_type) {
|
||||
case NM_META_SETTING_TYPE_CONNECTION:
|
||||
if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) {
|
||||
gs_free char *value_coerced = NULL;
|
||||
|
||||
if (!_set_fcn_precheck_connection_secondaries (client, value, &value_coerced, error))
|
||||
return FALSE;
|
||||
|
||||
return _set_fcn_call (property_info,
|
||||
setting,
|
||||
value_coerced ?: value,
|
||||
error);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (value) {
|
||||
switch (property_info->setting_info->general->meta_type) {
|
||||
case NM_META_SETTING_TYPE_CONNECTION:
|
||||
if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) {
|
||||
if (!_set_fcn_precheck_connection_secondaries (client, value, &value_to_free, error))
|
||||
return FALSE;
|
||||
if (value_to_free)
|
||||
value = value_to_free;
|
||||
}
|
||||
return _set_fcn_call (property_info,
|
||||
setting,
|
||||
value,
|
||||
error);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_set_error_literal (error, 1, 0, _("the property can't be changed"));
|
||||
g_object_freeze_notify (G_OBJECT (setting));
|
||||
success = property_info->property_type->set_fcn (property_info,
|
||||
nmc_meta_environment,
|
||||
nmc_meta_environment_arg,
|
||||
setting,
|
||||
modifier,
|
||||
value,
|
||||
error);
|
||||
g_object_thaw_notify (G_OBJECT (setting));
|
||||
return success;
|
||||
|
||||
out_fail_read_only:
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("the property can't be changed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nmc_property_set_default_value (NMSetting *setting, const char *prop)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GParamSpec *param_spec;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
|
||||
if (param_spec) {
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (param_spec));
|
||||
g_param_value_set_default (param_spec, &value);
|
||||
g_object_set_property (G_OBJECT (setting), prop, &value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic function for resetting (single value) properties.
|
||||
*
|
||||
* The function resets the property value to the default one. It respects
|
||||
* nmcli restrictions for changing properties. So if 'set_func' is NULL,
|
||||
* resetting the value is denied.
|
||||
*
|
||||
* Returns: TRUE on success; FALSE on failure and sets error
|
||||
*/
|
||||
gboolean
|
||||
nmc_setting_reset_property (NMSetting *setting, const char *prop, GError **error)
|
||||
{
|
||||
const NMMetaPropertyInfo *property_info;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
|
||||
if (property_info->property_type->set_fcn) {
|
||||
nmc_property_set_default_value (setting, prop);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_set_error_literal (error, 1, 0, _("the property can't be changed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic function for removing items for collection-type properties.
|
||||
*
|
||||
* If 'option' is not NULL, it tries to remove it, otherwise 'idx' is used.
|
||||
* For single-value properties (not having specialized remove function) this
|
||||
* function does nothing and just returns TRUE.
|
||||
*
|
||||
* Returns: TRUE on success; FALSE on failure and sets error
|
||||
*/
|
||||
gboolean
|
||||
nmc_setting_remove_property_option (NMSetting *setting,
|
||||
const char *prop,
|
||||
const char *option,
|
||||
guint32 idx,
|
||||
GError **error)
|
||||
{
|
||||
const NMMetaPropertyInfo *property_info;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
|
||||
if (property_info->property_type->remove_fcn) {
|
||||
return property_info->property_type->remove_fcn (property_info,
|
||||
nmc_meta_environment,
|
||||
nmc_meta_environment_arg,
|
||||
setting,
|
||||
option,
|
||||
idx,
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get valid property names for a setting.
|
||||
*
|
||||
|
|
@ -749,41 +684,6 @@ nmc_setting_get_property_desc (NMSetting *setting, const char *prop)
|
|||
nmcli_desc ?: "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets setting:prop property value and returns it in 'value'.
|
||||
* Caller is responsible for freeing the GValue resources using g_value_unset()
|
||||
*/
|
||||
gboolean
|
||||
nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value)
|
||||
{
|
||||
GParamSpec *param_spec;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
|
||||
if (param_spec) {
|
||||
memset (value, 0, sizeof (GValue));
|
||||
g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (param_spec));
|
||||
g_object_get_property (G_OBJECT (setting), prop, value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets setting:prop property value from 'value'.
|
||||
*/
|
||||
gboolean
|
||||
nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value)
|
||||
{
|
||||
GParamSpec *param_spec;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
|
||||
if (param_spec && G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (param_spec)) {
|
||||
g_object_set_property (G_OBJECT (setting), prop, value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
|
|
|
|||
|
|
@ -45,20 +45,9 @@ char *nmc_setting_get_property_parsable (NMSetting *setting,
|
|||
gboolean nmc_setting_set_property (NMClient *client,
|
||||
NMSetting *setting,
|
||||
const char *prop,
|
||||
char modifier,
|
||||
const char *val,
|
||||
GError **error);
|
||||
gboolean nmc_setting_reset_property (NMSetting *setting,
|
||||
const char *prop,
|
||||
GError **error);
|
||||
gboolean nmc_setting_remove_property_option (NMSetting *setting,
|
||||
const char *prop,
|
||||
const char *option,
|
||||
guint32 idx,
|
||||
GError **error);
|
||||
void nmc_property_set_default_value (NMSetting *setting, const char *prop);
|
||||
|
||||
gboolean nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value);
|
||||
gboolean nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value);
|
||||
|
||||
gboolean setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ libnmc = static_library(
|
|||
sources: files(
|
||||
'nm-meta-setting-access.c',
|
||||
'nm-meta-setting-desc.c',
|
||||
) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + [settings_docs_source],
|
||||
) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + shared_nm_libnm_core_utils_c + [settings_docs_source],
|
||||
dependencies: deps,
|
||||
c_args: cflags,
|
||||
link_with: libnmc_base,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ nmc_string_to_uint_base (const char *str,
|
|||
char *end;
|
||||
unsigned long int tmp;
|
||||
|
||||
if (!str || !str[0])
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: don't use this function, replace by _nm_utils_ascii_str_to_int64() */
|
||||
errno = 0;
|
||||
tmp = strtoul (str, &end, base);
|
||||
if (errno || *end != '\0' || (range_check && (tmp < min || tmp > max))) {
|
||||
|
|
|
|||
|
|
@ -23,13 +23,7 @@
|
|||
#include "nm-meta-setting.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "nm-device.h"
|
||||
|
||||
|
||||
#define nm_auto_unref_ip_address nm_auto (_nm_ip_address_unref)
|
||||
NM_AUTO_DEFINE_FCN0 (NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref)
|
||||
|
||||
#define nm_auto_unref_wgpeer nm_auto (_nm_auto_unref_wgpeer)
|
||||
NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
|
||||
#include "nm-libnm-core-utils.h"
|
||||
|
||||
const NMObject **nmc_objects_sort_by_path (const NMObject *const*objs, gssize len);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -209,15 +209,9 @@ struct _NMMetaPropertyType {
|
|||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
NMSetting *setting,
|
||||
char modifier,
|
||||
const char *value,
|
||||
GError **error);
|
||||
gboolean (*remove_fcn) (const NMMetaPropertyInfo *property_info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
NMSetting *setting,
|
||||
const char *option,
|
||||
guint32 idx,
|
||||
GError **error);
|
||||
|
||||
const char *const*(*values_fcn) (const NMMetaPropertyInfo *property_info,
|
||||
char ***out_to_free);
|
||||
|
|
@ -228,6 +222,10 @@ struct _NMMetaPropertyType {
|
|||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free);
|
||||
|
||||
/* Whether set_fcn() supports the '-' modifier. That is, whether the property
|
||||
* is a list type. */
|
||||
bool set_supports_remove:1;
|
||||
};
|
||||
|
||||
struct _NMUtilsEnumValueInfo;
|
||||
|
|
@ -244,9 +242,6 @@ typedef struct {
|
|||
|
||||
struct _NMMetaPropertyTypData {
|
||||
union {
|
||||
struct {
|
||||
gboolean (*fcn) (NMSetting *setting);
|
||||
} get_with_default;
|
||||
struct {
|
||||
GType (*get_gtype) (void);
|
||||
int min;
|
||||
|
|
@ -271,16 +266,78 @@ struct _NMMetaPropertyTypData {
|
|||
struct {
|
||||
bool legacy_format:1;
|
||||
} gobject_bytes;
|
||||
struct {
|
||||
guint32 (*get_num_fcn_u32) (NMSetting *setting);
|
||||
guint (*get_num_fcn_u) (NMSetting *setting);
|
||||
void (*clear_all_fcn) (NMSetting *setting);
|
||||
gboolean (*add_fcn) (NMSetting *setting,
|
||||
const char *item);
|
||||
void (*add2_fcn) (NMSetting *setting,
|
||||
const char *item);
|
||||
const char *(*validate_fcn) (const char *item, GError **error);
|
||||
const char *(*validate2_fcn) (NMSetting *setting, const char *item, GError **error);
|
||||
void (*remove_by_idx_fcn_u32) (NMSetting *setting, guint32 idx);
|
||||
void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx);
|
||||
void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx);
|
||||
gboolean (*remove_by_value_fcn) (NMSetting *setting, const char *item);
|
||||
|
||||
/* if true, separate the list by space and allow backslash escaping. */
|
||||
bool with_escaped_spaces:1;
|
||||
} multilist;
|
||||
struct {
|
||||
guint (*get_num_fcn) (NMSetting *setting);
|
||||
void (*obj_to_str_fcn) (NMMetaAccessorGetType get_type,
|
||||
NMSetting *setting,
|
||||
guint idx,
|
||||
GString *str);
|
||||
gboolean (*set_fcn) (NMSetting *setting,
|
||||
gboolean do_add /* or else remove. */,
|
||||
const char *value,
|
||||
GError **error);
|
||||
void (*clear_all_fcn) (NMSetting *setting);
|
||||
void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx);
|
||||
void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx);
|
||||
bool delimit_pretty_with_semicolon:1;
|
||||
} objlist;
|
||||
struct {
|
||||
gboolean (*set_fcn) (NMSetting *setting,
|
||||
const char *option,
|
||||
const char *value,
|
||||
GError **error);
|
||||
bool no_empty_value:1;
|
||||
} optionlist;
|
||||
struct {
|
||||
guint32 (*get_fcn) (NMSetting *setting);
|
||||
} mtu;
|
||||
struct {
|
||||
NMSetting8021xSchemeType scheme_type;
|
||||
} cert_8021x;
|
||||
struct {
|
||||
NMMetaPropertyTypeMacMode mode;
|
||||
} mac;
|
||||
struct {
|
||||
guint (*get_fcn) (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void (*set_fcn) (NMSettingDcb *setting,
|
||||
guint id,
|
||||
guint value);
|
||||
guint max;
|
||||
guint other;
|
||||
bool is_percent:1;
|
||||
} dcb;
|
||||
struct {
|
||||
gboolean (*get_fcn) (NMSettingDcb *s_dcb,
|
||||
guint priority);
|
||||
void (*set_fcn) (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
gboolean enabled);
|
||||
bool with_flow_control_flags:1;
|
||||
} dcb_bool;
|
||||
struct {
|
||||
NMEthtoolID ethtool_id;
|
||||
} ethtool;
|
||||
} subtype;
|
||||
gboolean (*is_default_fcn) (NMSetting *setting);
|
||||
const char *const*values_static;
|
||||
const NMMetaPropertyTypDataNested *nested;
|
||||
NMMetaPropertyTypFlags typ_flags;
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ libnm_core_sources_all = libnm_core_sources
|
|||
libnm_core_sources_all += libnm_core_enum
|
||||
libnm_core_sources_all += shared_nm_meta_setting_c
|
||||
libnm_core_sources_all += shared_nm_ethtool_utils_c
|
||||
libnm_core_sources_all += shared_nm_libnm_core_utils_c
|
||||
libnm_core_sources_all += [version_header]
|
||||
|
||||
libnm_core = static_library(
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@
|
|||
#include "nm-utils.h"
|
||||
#include "nm-vpn-dbus-interface.h"
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
#include "nm-libnm-core-utils.h"
|
||||
|
||||
/* IEEE 802.1D-1998 timer values */
|
||||
#define NM_BR_MIN_HELLO_TIME 1
|
||||
|
|
@ -264,14 +265,6 @@ GHashTable *_nm_ip_route_get_attributes_direct (NMIPRoute *route);
|
|||
NMSriovVF *_nm_utils_sriov_vf_from_strparts (const char *index, const char *detail, gboolean ignore_unknown, GError **error);
|
||||
gboolean _nm_sriov_vf_attribute_validate_all (const NMSriovVF *vf, GError **error);
|
||||
|
||||
static inline void
|
||||
_nm_auto_ip_route_unref (NMIPRoute **v)
|
||||
{
|
||||
if (*v)
|
||||
nm_ip_route_unref (*v);
|
||||
}
|
||||
#define nm_auto_ip_route_unref nm_auto (_nm_auto_ip_route_unref)
|
||||
|
||||
GPtrArray *_nm_utils_copy_array (const GPtrArray *array,
|
||||
NMUtilsCopyFunc copy_func,
|
||||
GDestroyNotify free_func);
|
||||
|
|
@ -554,18 +547,6 @@ gboolean _nm_utils_team_config_set (char **conf,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
|
||||
{
|
||||
if (NM_IS_SETTING_IP4_CONFIG (s_ip))
|
||||
return AF_INET;
|
||||
if (NM_IS_SETTING_IP6_CONFIG (s_ip))
|
||||
return AF_INET6;
|
||||
g_return_val_if_reached (AF_UNSPEC);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint32 _nm_utils_parse_tc_handle (const char *str,
|
||||
GError **error);
|
||||
void _nm_utils_string_append_tc_parent (GString *string,
|
||||
|
|
@ -763,9 +744,6 @@ gboolean _nm_connection_find_secret (NMConnection *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer)
|
||||
NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
|
||||
|
||||
gboolean nm_utils_base64secret_normalize (const char *base64_key,
|
||||
gsize required_key_len,
|
||||
char **out_base64_key_norm);
|
||||
|
|
|
|||
|
|
@ -397,8 +397,7 @@ nm_setting_connection_add_permission (NMSettingConnection *setting,
|
|||
GSList *iter;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
|
||||
g_return_val_if_fail (ptype, FALSE);
|
||||
g_return_val_if_fail (strlen (ptype) > 0, FALSE);
|
||||
g_return_val_if_fail (ptype && ptype[0], FALSE);
|
||||
g_return_val_if_fail (detail == NULL, FALSE);
|
||||
|
||||
/* Only "user" for now... */
|
||||
|
|
@ -470,9 +469,9 @@ nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting,
|
|||
GSList *iter;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
|
||||
g_return_val_if_fail (ptype, FALSE);
|
||||
g_return_val_if_fail (strlen (ptype) > 0, FALSE);
|
||||
g_return_val_if_fail (ptype && ptype[0], FALSE);
|
||||
g_return_val_if_fail (detail == NULL, FALSE);
|
||||
g_return_val_if_fail (pitem != NULL, FALSE);
|
||||
|
||||
/* Only "user" for now... */
|
||||
g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE);
|
||||
|
|
|
|||
|
|
@ -1003,6 +1003,7 @@ nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, guint idx)
|
|||
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
|
||||
g_return_val_if_fail (priv->runner_tx_hash, NULL);
|
||||
g_return_val_if_fail (idx < priv->runner_tx_hash->len, NULL);
|
||||
|
||||
return priv->runner_tx_hash->pdata[idx];
|
||||
|
|
@ -1023,6 +1024,7 @@ nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, guint idx)
|
|||
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_TEAM (setting));
|
||||
g_return_if_fail (priv->runner_tx_hash);
|
||||
g_return_if_fail (idx < priv->runner_tx_hash->len);
|
||||
|
||||
g_ptr_array_remove_index (priv->runner_tx_hash, idx);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-libnm-core-utils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-types-internal.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -106,48 +107,33 @@ nm_setting_vlan_get_flags (NMSettingVlan *setting)
|
|||
return NM_SETTING_VLAN_GET_PRIVATE (setting)->flags;
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_max_prio (NMVlanPriorityMap map, gboolean from)
|
||||
static NMVlanQosMapping *
|
||||
priority_map_new (guint32 from, guint32 to)
|
||||
{
|
||||
if (map == NM_VLAN_INGRESS_MAP)
|
||||
return from ? MAX_8021P_PRIO : MAX_SKB_PRIO;
|
||||
else if (map == NM_VLAN_EGRESS_MAP)
|
||||
return from ? MAX_SKB_PRIO : MAX_8021P_PRIO;
|
||||
g_assert_not_reached ();
|
||||
NMVlanQosMapping *mapping;
|
||||
|
||||
mapping = g_new (NMVlanQosMapping, 1);
|
||||
*mapping = (NMVlanQosMapping) {
|
||||
.from = from,
|
||||
.to = to,
|
||||
};
|
||||
return mapping;
|
||||
}
|
||||
|
||||
static NMVlanQosMapping *
|
||||
priority_map_new_from_str (NMVlanPriorityMap map, const char *str)
|
||||
{
|
||||
NMVlanQosMapping *p = NULL;
|
||||
char **t = NULL;
|
||||
guint32 len;
|
||||
guint64 from, to;
|
||||
guint32 from, to;
|
||||
|
||||
g_return_val_if_fail (str && str[0], NULL);
|
||||
|
||||
t = g_strsplit (str, ":", 0);
|
||||
len = g_strv_length (t);
|
||||
if (len == 2) {
|
||||
from = g_ascii_strtoull (t[0], NULL, 10);
|
||||
to = g_ascii_strtoull (t[1], NULL, 10);
|
||||
|
||||
if ((from <= get_max_prio (map, TRUE)) && (to <= get_max_prio (map, FALSE))) {
|
||||
G_STATIC_ASSERT (sizeof (*p) == sizeof (p->from) + sizeof (p->to));
|
||||
p = g_malloc (sizeof (NMVlanQosMapping));
|
||||
p->from = from;
|
||||
p->to = to;
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (t);
|
||||
return p;
|
||||
if (!nm_utils_vlan_priority_map_parse_str (map, str, FALSE, &from, &to, NULL))
|
||||
return NULL;
|
||||
return priority_map_new (from, to);
|
||||
}
|
||||
|
||||
static void
|
||||
priority_map_free (NMVlanQosMapping *map)
|
||||
{
|
||||
g_return_if_fail (map != NULL);
|
||||
nm_assert (map);
|
||||
g_free (map);
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +144,7 @@ get_map (NMSettingVlan *self, NMVlanPriorityMap map)
|
|||
return NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map;
|
||||
else if (map == NM_VLAN_EGRESS_MAP)
|
||||
return NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map;
|
||||
g_assert_not_reached ();
|
||||
nm_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +193,7 @@ set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list)
|
|||
NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map = list;
|
||||
_notify (self, PROP_EGRESS_PRIORITY_MAP);
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -489,6 +475,36 @@ nm_setting_vlan_remove_priority (NMSettingVlan *setting,
|
|||
set_map (setting, map, g_slist_delete_link (list, item));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
priority_map_remove_by_value (NMSettingVlan *setting,
|
||||
NMVlanPriorityMap map,
|
||||
guint32 from,
|
||||
guint32 to,
|
||||
gboolean wildcard_to)
|
||||
{
|
||||
GSList *list = NULL, *iter = NULL;
|
||||
NMVlanQosMapping *item;
|
||||
|
||||
nm_assert (NM_IS_SETTING_VLAN (setting));
|
||||
nm_assert (NM_IN_SET (map, NM_VLAN_INGRESS_MAP, NM_VLAN_EGRESS_MAP));
|
||||
|
||||
list = get_map (setting, map);
|
||||
for (iter = list; iter; iter = g_slist_next (iter)) {
|
||||
item = iter->data;
|
||||
|
||||
if (item->from != from)
|
||||
continue;
|
||||
if ( !wildcard_to
|
||||
&& item->to != to)
|
||||
continue;
|
||||
|
||||
priority_map_free ((NMVlanQosMapping *) (iter->data));
|
||||
set_map (setting, map, g_slist_delete_link (list, iter));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_vlan_remove_priority_by_value:
|
||||
* @setting: the #NMSettingVlan
|
||||
|
|
@ -508,22 +524,10 @@ nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting,
|
|||
guint32 from,
|
||||
guint32 to)
|
||||
{
|
||||
GSList *list = NULL, *iter = NULL;
|
||||
NMVlanQosMapping *item;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE);
|
||||
g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE);
|
||||
|
||||
list = get_map (setting, map);
|
||||
for (iter = list; iter; iter = g_slist_next (iter)) {
|
||||
item = iter->data;
|
||||
if (item->from == from && item->to == to) {
|
||||
priority_map_free ((NMVlanQosMapping *) (iter->data));
|
||||
set_map (setting, map, g_slist_delete_link (list, iter));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return priority_map_remove_by_value (setting, map, from, to, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -543,19 +547,15 @@ nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting,
|
|||
NMVlanPriorityMap map,
|
||||
const char *str)
|
||||
{
|
||||
NMVlanQosMapping *item;
|
||||
gboolean found;
|
||||
gboolean is_wildcard_to;
|
||||
guint32 from, to;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE);
|
||||
g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE);
|
||||
|
||||
item = priority_map_new_from_str (map, str);
|
||||
if (!item)
|
||||
if (!nm_utils_vlan_priority_map_parse_str (map, str, TRUE, &from, &to, &is_wildcard_to))
|
||||
return FALSE;
|
||||
|
||||
found = nm_setting_vlan_remove_priority_by_value (setting, map, item->from, item->to);
|
||||
g_free (item);
|
||||
return found;
|
||||
return priority_map_remove_by_value (setting, map, from, to, is_wildcard_to);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -703,18 +703,16 @@ static GSList *
|
|||
priority_strv_to_maplist (NMVlanPriorityMap map, char **strv)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
int i;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; strv && strv[i]; i++) {
|
||||
NMVlanQosMapping *item;
|
||||
guint32 from, to;
|
||||
|
||||
item = priority_map_new_from_str (map, strv[i]);
|
||||
if (item) {
|
||||
if (!check_replace_duplicate_priority (list, item->from, item->to))
|
||||
list = g_slist_prepend (list, item);
|
||||
else
|
||||
g_free (item);
|
||||
}
|
||||
if (!nm_utils_vlan_priority_map_parse_str (map, strv[i], FALSE, &from, &to, NULL))
|
||||
continue;
|
||||
if (check_replace_duplicate_priority (list, from, to))
|
||||
continue;
|
||||
list = g_slist_prepend (list, priority_map_new (from, to));
|
||||
}
|
||||
return g_slist_sort (list, prio_map_compare);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,10 +173,8 @@ nm_setting_vpn_add_data_item (NMSettingVpn *setting,
|
|||
const char *item)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_VPN (setting));
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (strlen (key) > 0);
|
||||
g_return_if_fail (item != NULL);
|
||||
g_return_if_fail (strlen (item) > 0);
|
||||
g_return_if_fail (key && key[0]);
|
||||
g_return_if_fail (item && item[0]);
|
||||
|
||||
g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
|
||||
g_strdup (key), g_strdup (item));
|
||||
|
|
@ -242,6 +240,7 @@ nm_setting_vpn_remove_data_item (NMSettingVpn *setting, const char *key)
|
|||
gboolean found;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
|
||||
g_return_val_if_fail (key, FALSE);
|
||||
|
||||
found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
|
||||
if (found)
|
||||
|
|
@ -350,10 +349,8 @@ nm_setting_vpn_add_secret (NMSettingVpn *setting,
|
|||
const char *secret)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_VPN (setting));
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (strlen (key) > 0);
|
||||
g_return_if_fail (secret != NULL);
|
||||
g_return_if_fail (strlen (secret) > 0);
|
||||
g_return_if_fail (key && key[0]);
|
||||
g_return_if_fail (secret && secret[0]);
|
||||
|
||||
g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets,
|
||||
g_strdup (key), g_strdup (secret));
|
||||
|
|
@ -419,6 +416,7 @@ nm_setting_vpn_remove_secret (NMSettingVpn *setting, const char *key)
|
|||
gboolean found;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
|
||||
g_return_val_if_fail (key, FALSE);
|
||||
|
||||
found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key);
|
||||
if (found)
|
||||
|
|
|
|||
|
|
@ -483,8 +483,7 @@ nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting,
|
|||
const char *key)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
g_return_val_if_fail (strlen (key), NULL);
|
||||
g_return_val_if_fail (key && key[0], NULL);
|
||||
|
||||
return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
|
||||
}
|
||||
|
|
@ -508,17 +507,11 @@ nm_setting_wired_add_s390_option (NMSettingWired *setting,
|
|||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
size_t value_len;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (strlen (key), FALSE);
|
||||
g_return_val_if_fail (key && key[0], FALSE);
|
||||
g_return_val_if_fail (g_strv_contains (valid_s390_opts, key), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
value_len = strlen (value);
|
||||
g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE);
|
||||
|
||||
g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options,
|
||||
g_strdup (key),
|
||||
g_strdup (value));
|
||||
|
|
@ -544,8 +537,7 @@ nm_setting_wired_remove_s390_option (NMSettingWired *setting,
|
|||
gboolean found;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (strlen (key), FALSE);
|
||||
g_return_val_if_fail (key && key[0], FALSE);
|
||||
|
||||
found = g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
|
||||
if (found)
|
||||
|
|
@ -683,7 +675,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
g_hash_table_iter_init (&iter, priv->s390_options);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
|
||||
if ( !g_strv_contains (valid_s390_opts, key)
|
||||
|| !strlen (value)
|
||||
|| value[0] == '\0'
|
||||
|| (strlen (value) > 200)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
|
|||
|
|
@ -2962,8 +2962,7 @@ nm_utils_sriov_vf_from_str (const char *str, GError **error)
|
|||
|
||||
detail = strchr (str, ' ');
|
||||
if (detail) {
|
||||
index_free = g_strndup (str, detail - str);
|
||||
str = index_free;
|
||||
str = nm_strndup_a (200, str, detail - str, &index_free);
|
||||
detail++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,29 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int));
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_nm_ascii_spaces (void)
|
||||
{
|
||||
int i;
|
||||
const char *const S = NM_ASCII_SPACES;
|
||||
|
||||
for (i = 0; S[i]; i++)
|
||||
g_assert (!strchr (&S[i + 1], S[i]));
|
||||
|
||||
for (i = 0; S[i] != '\0'; i++)
|
||||
g_assert (g_ascii_isspace (S[i]));
|
||||
|
||||
g_assert (!g_ascii_isspace ((char) 0));
|
||||
for (i = 1; i < 0x100; i++) {
|
||||
if (g_ascii_isspace ((char) i))
|
||||
g_assert (strchr (S, (char) i));
|
||||
else
|
||||
g_assert (!strchr (S, (char) i));
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _nm_packed {
|
||||
int v0;
|
||||
char v1;
|
||||
|
|
@ -809,54 +832,54 @@ test_setting_vpn_items (void)
|
|||
nm_setting_vpn_remove_data_item (s_vpn, "foobar4-flags");
|
||||
|
||||
/* Try to add some blank values and make sure they are rejected */
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, NULL, NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, "", "");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (item) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, "foobar1", "");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, NULL);
|
||||
|
||||
/* Try to add some blank secrets and make sure they are rejected */
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, NULL, NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, "", "");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (secret) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, "foobar1", "");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
|
||||
nm_setting_vpn_add_secret (s_vpn, "", "blahblah1");
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
|
|
@ -2347,7 +2370,7 @@ test_setting_connection_permissions_helpers (void)
|
|||
g_assert (!success);
|
||||
|
||||
/* Ensure a bad [type] is rejected */
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype));
|
||||
NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype && ptype[0]));
|
||||
success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
g_assert (!success);
|
||||
|
|
@ -7733,24 +7756,73 @@ test_nm_utils_escape_spaces (void)
|
|||
g_free (to_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_do_test_unescape_spaces (const char *in, const char *out)
|
||||
{
|
||||
nm_auto_free_gstring GString *str_out = g_string_new (NULL);
|
||||
nm_auto_free_gstring GString *str_in = g_string_new (NULL);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
||||
g_string_set_size (str_in, 0);
|
||||
|
||||
g_string_append (str_in, in);
|
||||
|
||||
if (i == 0)
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, out);
|
||||
else if (i == 1)
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out);
|
||||
else {
|
||||
bool do_strip = nmtst_get_rand_bool ();
|
||||
guint n = nmtst_get_rand_int () % 20;
|
||||
guint j;
|
||||
|
||||
g_string_set_size (str_out, 0);
|
||||
if (!do_strip)
|
||||
g_string_append (str_out, out);
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
gboolean append = nmtst_get_rand_bool ();
|
||||
char ch = nmtst_rand_select (' ', '\t');
|
||||
|
||||
if (append && out[strlen (out) - 1] == '\\')
|
||||
append = FALSE;
|
||||
|
||||
g_string_insert_c (str_in, append ? -1 : 0, ch);
|
||||
if (!do_strip)
|
||||
g_string_insert_c (str_out, append ? -1 : 0, ch);
|
||||
}
|
||||
|
||||
if (do_strip)
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out);
|
||||
else
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, str_out->str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_utils_unescape_spaces (void)
|
||||
{
|
||||
#define CHECK_STR(in, out) \
|
||||
G_STMT_START { \
|
||||
gs_free char *str = g_strdup (in); \
|
||||
\
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str), ==, out); \
|
||||
} G_STMT_END
|
||||
|
||||
CHECK_STR ("\\a", "\\a");
|
||||
CHECK_STR ("foobar", "foobar");
|
||||
CHECK_STR ("foo bar", "foo bar");
|
||||
CHECK_STR ("foo\\ bar", "foo bar");
|
||||
CHECK_STR ("foo\\", "foo\\");
|
||||
CHECK_STR ("\\\\\t", "\\\t");
|
||||
|
||||
#undef CHECK_STR
|
||||
_do_test_unescape_spaces ("", "");
|
||||
_do_test_unescape_spaces ("\\", "\\");
|
||||
_do_test_unescape_spaces ("\\ ", " ");
|
||||
_do_test_unescape_spaces ("\\\t", "\t");
|
||||
_do_test_unescape_spaces ("a", "a");
|
||||
_do_test_unescape_spaces ("\\a", "\\a");
|
||||
_do_test_unescape_spaces ("foobar", "foobar");
|
||||
_do_test_unescape_spaces ("foo bar", "foo bar");
|
||||
_do_test_unescape_spaces ("foo\\ bar", "foo bar");
|
||||
_do_test_unescape_spaces ("foo\\", "foo\\");
|
||||
_do_test_unescape_spaces ("\\\\", "\\\\");
|
||||
_do_test_unescape_spaces ("foo bar", "foo bar");
|
||||
_do_test_unescape_spaces ("\\ foo bar", " foo bar");
|
||||
_do_test_unescape_spaces ("\\ foo bar\\ ", " foo bar ");
|
||||
_do_test_unescape_spaces ("\\\tfoo bar\\\t", "\tfoo bar\t");
|
||||
_do_test_unescape_spaces ("\\\tfoo bar \\\t", "\tfoo bar \t");
|
||||
_do_test_unescape_spaces ("\\\t", "\t");
|
||||
_do_test_unescape_spaces ("\\\t \\ ", "\t ");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -7761,6 +7833,7 @@ int main (int argc, char **argv)
|
|||
{
|
||||
nmtst_init (&argc, &argv, TRUE);
|
||||
|
||||
g_test_add_func ("/core/general/test_nm_ascii_spaces", test_nm_ascii_spaces);
|
||||
g_test_add_func ("/core/general/test_nm_hash", test_nm_hash);
|
||||
g_test_add_func ("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn);
|
||||
g_test_add_func ("/core/general/test_c_list_sort", test_c_list_sort);
|
||||
|
|
|
|||
|
|
@ -892,8 +892,7 @@ nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
|
|||
g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
g_return_if_fail (nm_connection_get_path (connection));
|
||||
g_return_if_fail (setting_name != NULL);
|
||||
g_return_if_fail (strlen (setting_name) > 0);
|
||||
g_return_if_fail (setting_name && setting_name[0]);
|
||||
g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM));
|
||||
g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ version_header = configure_file(
|
|||
|
||||
shared_nm_ethtool_utils_c = files('nm-ethtool-utils.c')
|
||||
|
||||
shared_nm_libnm_core_utils_c = files('nm-libnm-core-utils.c')
|
||||
|
||||
shared_nm_meta_setting_c = files('nm-meta-setting.c')
|
||||
|
||||
shared_nm_test_utils_impl_c = files('nm-test-utils-impl.c')
|
||||
|
|
|
|||
76
shared/nm-libnm-core-utils.c
Normal file
76
shared/nm-libnm-core-utils.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-libnm-core-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type,
|
||||
const char *str,
|
||||
gboolean allow_wildcard_to,
|
||||
guint32 *out_from,
|
||||
guint32 *out_to,
|
||||
gboolean *out_has_wildcard_to)
|
||||
{
|
||||
const char *s2;
|
||||
gint64 v1, v2;
|
||||
|
||||
nm_assert (str);
|
||||
|
||||
s2 = strchr (str, ':');
|
||||
|
||||
if (!s2) {
|
||||
if (!allow_wildcard_to)
|
||||
return FALSE;
|
||||
v1 = _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXUINT32, -1);
|
||||
v2 = -1;
|
||||
} else {
|
||||
gs_free char *s1_free = NULL;
|
||||
gsize s1_len = (s2 - str);
|
||||
|
||||
s2 = nm_str_skip_leading_spaces (&s2[1]);
|
||||
if ( s2[0] == '\0'
|
||||
|| ( s2[0] == '*'
|
||||
&& NM_STRCHAR_ALL (&s2[1], ch, g_ascii_isspace (ch)))) {
|
||||
if (!allow_wildcard_to)
|
||||
return FALSE;
|
||||
v2 = -1;
|
||||
} else {
|
||||
v2 = _nm_utils_ascii_str_to_int64 (s2, 10, 0, G_MAXUINT32, -1);
|
||||
if ( v2 < 0
|
||||
|| (guint32) v2 > nm_utils_vlan_priority_map_get_max_prio (map_type, FALSE))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
v1 = _nm_utils_ascii_str_to_int64 (nm_strndup_a (100, str, s1_len, &s1_free),
|
||||
10, 0, G_MAXUINT32, -1);
|
||||
}
|
||||
|
||||
if ( v1 < 0
|
||||
|| (guint32) v1 > nm_utils_vlan_priority_map_get_max_prio (map_type, TRUE))
|
||||
return FALSE;
|
||||
|
||||
NM_SET_OUT (out_from, v1);
|
||||
NM_SET_OUT (out_to, v2 < 0
|
||||
? 0u
|
||||
: (guint) v2);
|
||||
NM_SET_OUT (out_has_wildcard_to, v2 < 0);
|
||||
return TRUE;
|
||||
}
|
||||
90
shared/nm-libnm-core-utils.h
Normal file
90
shared/nm-libnm-core-utils.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __NM_LIBNM_SHARED_UTILS_H__
|
||||
#define __NM_LIBNM_SHARED_UTILS_H__
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-ip-config.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-sriov.h"
|
||||
#include "nm-setting-team.h"
|
||||
#include "nm-setting-vlan.h"
|
||||
#include "nm-setting-wireguard.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define nm_auto_unref_ip_address nm_auto (_nm_ip_address_unref)
|
||||
NM_AUTO_DEFINE_FCN0 (NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref)
|
||||
|
||||
#define nm_auto_unref_ip_route nm_auto (_nm_auto_unref_ip_route)
|
||||
NM_AUTO_DEFINE_FCN0 (NMIPRoute *, _nm_auto_unref_ip_route, nm_ip_route_unref)
|
||||
|
||||
#define nm_auto_unref_sriov_vf nm_auto (_nm_auto_unref_sriov_vf)
|
||||
NM_AUTO_DEFINE_FCN0 (NMSriovVF *, _nm_auto_unref_sriov_vf, nm_sriov_vf_unref)
|
||||
|
||||
#define nm_auto_unref_tc_qdisc nm_auto (_nm_auto_unref_tc_qdisc)
|
||||
NM_AUTO_DEFINE_FCN0 (NMTCQdisc *, _nm_auto_unref_tc_qdisc, nm_tc_qdisc_unref)
|
||||
|
||||
#define nm_auto_unref_tc_tfilter nm_auto (_nm_auto_unref_tc_tfilter)
|
||||
NM_AUTO_DEFINE_FCN0 (NMTCTfilter *, _nm_auto_unref_tc_tfilter, nm_tc_tfilter_unref)
|
||||
|
||||
#define nm_auto_unref_team_link_watcher nm_auto (_nm_auto_unref_team_link_watcher)
|
||||
NM_AUTO_DEFINE_FCN0 (NMTeamLinkWatcher *, _nm_auto_unref_team_link_watcher, nm_team_link_watcher_unref)
|
||||
|
||||
#define nm_auto_unref_wgpeer nm_auto (_nm_auto_unref_wgpeer)
|
||||
NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static inline guint32
|
||||
nm_utils_vlan_priority_map_get_max_prio (NMVlanPriorityMap map, gboolean from)
|
||||
{
|
||||
if (map == NM_VLAN_INGRESS_MAP) {
|
||||
return from
|
||||
? 7u /* MAX_8021P_PRIO */
|
||||
: (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */;
|
||||
}
|
||||
nm_assert (map == NM_VLAN_EGRESS_MAP);
|
||||
return from
|
||||
? (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */
|
||||
: 7u /* MAX_8021P_PRIO */;
|
||||
}
|
||||
|
||||
gboolean nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type,
|
||||
const char *str,
|
||||
gboolean allow_wildcard_to,
|
||||
guint32 *out_from,
|
||||
guint32 *out_to,
|
||||
gboolean *out_has_wildcard_to);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
|
||||
{
|
||||
if (NM_IS_SETTING_IP4_CONFIG (s_ip))
|
||||
return AF_INET;
|
||||
if (NM_IS_SETTING_IP6_CONFIG (s_ip))
|
||||
return AF_INET6;
|
||||
g_return_val_if_reached (AF_UNSPEC);
|
||||
}
|
||||
|
||||
#endif /* __NM_LIBNM_SHARED_UTILS_H__ */
|
||||
|
|
@ -82,6 +82,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_ca_cert_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_ca_cert_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_ca_cert_password_flags,
|
||||
.set_cert_func = nm_setting_802_1x_set_ca_cert,
|
||||
.file_suffix = "ca-cert",
|
||||
},
|
||||
|
||||
|
|
@ -94,6 +95,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_phase2_ca_cert_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_phase2_ca_cert_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_phase2_ca_cert_password_flags,
|
||||
.set_cert_func = nm_setting_802_1x_set_phase2_ca_cert,
|
||||
.file_suffix = "inner-ca-cert",
|
||||
},
|
||||
|
||||
|
|
@ -106,6 +108,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_client_cert_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_client_cert_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_client_cert_password_flags,
|
||||
.set_cert_func = nm_setting_802_1x_set_client_cert,
|
||||
.file_suffix = "client-cert",
|
||||
},
|
||||
|
||||
|
|
@ -118,6 +121,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_phase2_client_cert_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_phase2_client_cert_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_phase2_client_cert_password_flags,
|
||||
.set_cert_func = nm_setting_802_1x_set_phase2_client_cert,
|
||||
.file_suffix = "inner-client-cert",
|
||||
},
|
||||
|
||||
|
|
@ -130,7 +134,9 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_private_key_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_private_key_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_private_key_password_flags,
|
||||
.set_private_key_func = nm_setting_802_1x_set_private_key,
|
||||
.file_suffix = "private-key",
|
||||
.is_secret = TRUE,
|
||||
},
|
||||
|
||||
[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] = {
|
||||
|
|
@ -142,7 +148,9 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
|
|||
.uri_func = nm_setting_802_1x_get_phase2_private_key_uri,
|
||||
.passwd_func = nm_setting_802_1x_get_phase2_private_key_password,
|
||||
.pwflag_func = nm_setting_802_1x_get_phase2_private_key_password_flags,
|
||||
.set_private_key_func = nm_setting_802_1x_set_phase2_private_key,
|
||||
.file_suffix = "inner-private-key",
|
||||
.is_secret = TRUE,
|
||||
},
|
||||
|
||||
[NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN] = { NULL },
|
||||
|
|
|
|||
|
|
@ -89,7 +89,19 @@ typedef struct {
|
|||
const char * (*uri_func) (NMSetting8021x *setting);
|
||||
const char * (*passwd_func) (NMSetting8021x *setting);
|
||||
NMSettingSecretFlags (*pwflag_func) (NMSetting8021x *setting);
|
||||
gboolean (*set_cert_func) (NMSetting8021x *setting,
|
||||
const char *value,
|
||||
NMSetting8021xCKScheme scheme,
|
||||
NMSetting8021xCKFormat *out_format,
|
||||
GError **error);
|
||||
gboolean (*set_private_key_func) (NMSetting8021x *setting,
|
||||
const char *value,
|
||||
const char *password,
|
||||
NMSetting8021xCKScheme scheme,
|
||||
NMSetting8021xCKFormat *out_format,
|
||||
GError **error);
|
||||
const char *file_suffix;
|
||||
bool is_secret:1;
|
||||
} NMSetting8021xSchemeVtable;
|
||||
|
||||
extern const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1];
|
||||
|
|
|
|||
|
|
@ -1334,6 +1334,9 @@ _NM_BACKPORT_SYMBOL_IMPL(version, return_type, func, _##func##_##version, args_t
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* mirrors g_ascii_isspace() and what we consider spaces in general. */
|
||||
#define NM_ASCII_SPACES "\t\n\f\r "
|
||||
|
||||
#define nm_str_skip_leading_spaces(str) \
|
||||
({ \
|
||||
typeof (*(str)) *_str = (str); \
|
||||
|
|
|
|||
|
|
@ -635,8 +635,16 @@ nm_utils_parse_inaddr (int addr_family,
|
|||
NMIPAddr addrbin;
|
||||
char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
|
||||
|
||||
if (!nm_utils_parse_inaddr_bin (addr_family, text, &addr_family, &addrbin))
|
||||
g_return_val_if_fail (text, FALSE);
|
||||
|
||||
if (addr_family == AF_UNSPEC)
|
||||
addr_family = strchr (text, ':') ? AF_INET6 : AF_INET;
|
||||
else
|
||||
g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE);
|
||||
|
||||
if (inet_pton (addr_family, text, &addrbin) != 1)
|
||||
return FALSE;
|
||||
|
||||
NM_SET_OUT (out_addr, g_strdup (inet_ntop (addr_family, &addrbin, addrstr_buf, sizeof (addrstr_buf))));
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -954,6 +962,15 @@ comp_l:
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_char_lookup_table_init (guint8 lookup[static 256],
|
||||
const char *candidates)
|
||||
{
|
||||
memset (lookup, 0, 256);
|
||||
while (candidates[0] != '\0')
|
||||
lookup[(guint8) ((candidates++)[0])] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_strsplit_set:
|
||||
* @str: the string to split.
|
||||
|
|
@ -979,6 +996,8 @@ comp_l:
|
|||
* The strings to which the result strv array points to are allocated
|
||||
* after the returned result itself. Don't free the strings themself,
|
||||
* but free everything with g_free().
|
||||
* It is however safe and allowed to modify the indiviual strings,
|
||||
* like "g_strstrip((char *) iter[0])".
|
||||
*/
|
||||
const char **
|
||||
nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping)
|
||||
|
|
@ -997,9 +1016,8 @@ nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_e
|
|||
/* initialize lookup table for delimiter */
|
||||
if (!delimiters)
|
||||
delimiters = " \t\n";
|
||||
memset (delimiters_table, 0, sizeof (delimiters_table));
|
||||
for (i = 0; delimiters[i]; i++)
|
||||
delimiters_table[(guint8) delimiters[i]] = 1;
|
||||
|
||||
_char_lookup_table_init (delimiters_table, delimiters);
|
||||
|
||||
#define _is_delimiter(ch, delimiters_table, allow_esc, esc) \
|
||||
((delimiters_table)[(guint8) (ch)] != 0 && (!allow_esc || !esc))
|
||||
|
|
@ -2412,23 +2430,26 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define IS_SPACE(c) NM_IN_SET ((c), ' ', '\t')
|
||||
#define _CH_LOOKUP(ch_lookup, ch) (!!((ch_lookup)[(guint8) (ch)]))
|
||||
|
||||
const char *
|
||||
_nm_utils_escape_spaces (const char *str, char **to_free)
|
||||
_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free)
|
||||
{
|
||||
const char *ptr = str;
|
||||
char *ret, *r;
|
||||
guint8 ch_lookup[256];
|
||||
|
||||
*to_free = NULL;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
_char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES);
|
||||
|
||||
while (TRUE) {
|
||||
if (!*ptr)
|
||||
return str;
|
||||
if (IS_SPACE (*ptr))
|
||||
if (_CH_LOOKUP (ch_lookup, *ptr))
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
|
@ -2438,7 +2459,7 @@ _nm_utils_escape_spaces (const char *str, char **to_free)
|
|||
r = ret;
|
||||
*to_free = ret;
|
||||
while (*ptr) {
|
||||
if (IS_SPACE (*ptr))
|
||||
if (_CH_LOOKUP (ch_lookup, *ptr))
|
||||
*r++ = '\\';
|
||||
*r++ = *ptr++;
|
||||
}
|
||||
|
|
@ -2448,25 +2469,42 @@ _nm_utils_escape_spaces (const char *str, char **to_free)
|
|||
}
|
||||
|
||||
char *
|
||||
_nm_utils_unescape_spaces (char *str)
|
||||
_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip)
|
||||
{
|
||||
guint i, j = 0;
|
||||
gsize i = 0;
|
||||
gsize j = 0;
|
||||
gsize preserve_space_at = 0;
|
||||
guint8 ch_lookup[256];
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; str[i]; i++) {
|
||||
if (str[i] == '\\' && IS_SPACE (str[i+1]))
|
||||
_char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES);
|
||||
|
||||
if (do_strip) {
|
||||
while (str[i] && _CH_LOOKUP (ch_lookup, str[i]))
|
||||
i++;
|
||||
}
|
||||
|
||||
for (; str[i]; i++) {
|
||||
if ( str[i] == '\\'
|
||||
&& _CH_LOOKUP (ch_lookup, str[i+1])) {
|
||||
preserve_space_at = j;
|
||||
i++;
|
||||
}
|
||||
str[j++] = str[i];
|
||||
}
|
||||
str[j] = '\0';
|
||||
|
||||
if (do_strip && j > 0) {
|
||||
while ( --j > preserve_space_at
|
||||
&& _CH_LOOKUP (ch_lookup, str[j]))
|
||||
str[j] = '\0';
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#undef IS_SPACE
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -1084,8 +1084,20 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *_nm_utils_escape_spaces (const char *str, char **to_free);
|
||||
char *_nm_utils_unescape_spaces (char *str);
|
||||
const char *_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free);
|
||||
char *_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip);
|
||||
|
||||
static inline const char *
|
||||
_nm_utils_escape_spaces (const char *str, char **to_free)
|
||||
{
|
||||
return _nm_utils_escape_plain (str, NM_ASCII_SPACES, to_free);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
_nm_utils_unescape_spaces (char *str, gboolean do_strip)
|
||||
{
|
||||
return _nm_utils_unescape_plain (str, NM_ASCII_SPACES, do_strip);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ parse_route_line (const char *line,
|
|||
NMIPRoute **out_route,
|
||||
GError **error)
|
||||
{
|
||||
nm_auto_ip_route_unref NMIPRoute *route = NULL;
|
||||
nm_auto_unref_ip_route NMIPRoute *route = NULL;
|
||||
gs_free const char **words_free = NULL;
|
||||
const char *const*words;
|
||||
const char *s;
|
||||
|
|
@ -1284,7 +1284,7 @@ read_route_file (int addr_family,
|
|||
for (line = strtok_r (contents, "\n", &contents_rest);
|
||||
line;
|
||||
line = strtok_r (NULL, "\n", &contents_rest)) {
|
||||
nm_auto_ip_route_unref NMIPRoute *route = NULL;
|
||||
nm_auto_unref_ip_route NMIPRoute *route = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
int e;
|
||||
|
||||
|
|
@ -1449,7 +1449,7 @@ make_match_setting (shvarFile *ifcfg)
|
|||
if (!s_match)
|
||||
s_match = (NMSettingMatch *) nm_setting_match_new ();
|
||||
nm_setting_match_add_interface_name (s_match,
|
||||
_nm_utils_unescape_spaces ((char *) strv[i]));
|
||||
_nm_utils_unescape_spaces ((char *) strv[i], TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue