|
Packit Service |
87a54e |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit |
5756e2 |
/*
|
|
Packit |
5756e2 |
* Copyright (C) 2010 - 2017 Red Hat, Inc.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-default.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-meta-setting-access.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static const NMMetaSettingInfoEditor *
|
|
Packit Service |
a1bd4f |
_get_meta_setting_info_editor_from_msi(const NMMetaSettingInfo *meta_setting_info)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *setting_info;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!meta_setting_info)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(meta_setting_info->get_setting_gtype);
|
|
Packit Service |
a1bd4f |
nm_assert(meta_setting_info->meta_type < G_N_ELEMENTS(nm_meta_setting_infos_editor));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type];
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(setting_info->general == meta_setting_info);
|
|
Packit Service |
a1bd4f |
return setting_info;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaSettingInfoEditor *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_find_by_name(const char *setting_name, gboolean use_alias)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *setting_info;
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(setting_name, NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
setting_info =
|
|
Packit Service |
a1bd4f |
_get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_name(setting_name));
|
|
Packit Service |
a1bd4f |
if (!setting_info && use_alias) {
|
|
Packit Service |
a1bd4f |
for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) {
|
|
Packit Service |
a1bd4f |
if (nm_streq0(nm_meta_setting_infos_editor[i].alias, setting_name)) {
|
|
Packit Service |
a1bd4f |
setting_info = &nm_meta_setting_infos_editor[i];
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return setting_info;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaSettingInfoEditor *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_find_by_gtype(GType gtype)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
return _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_gtype(gtype));
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaSettingInfoEditor *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_find_by_setting(NMSetting *setting)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *setting_info;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(NM_IS_SETTING(setting), NULL);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
setting_info = nm_meta_setting_info_editor_find_by_gtype(G_OBJECT_TYPE(setting));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(setting_info);
|
|
Packit Service |
a1bd4f |
nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(setting, setting_info->general->get_setting_gtype()));
|
|
Packit Service |
a1bd4f |
return setting_info;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaPropertyInfo *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info,
|
|
Packit Service |
a1bd4f |
const char * property_name)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(setting_info, NULL);
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(property_name, NULL);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
for (i = 0; i < setting_info->properties_num; i++) {
|
|
Packit Service |
a1bd4f |
nm_assert(setting_info->properties[i]->property_name);
|
|
Packit Service |
a1bd4f |
nm_assert(setting_info->properties[i]->setting_info == setting_info);
|
|
Packit Service |
a1bd4f |
if (nm_streq(setting_info->properties[i]->property_name, property_name))
|
|
Packit Service |
a1bd4f |
return setting_info->properties[i];
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!setting_info)
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
for (i = 0; i < setting_info->properties_num; i++) {
|
|
Packit Service |
a1bd4f |
if (setting_info->properties[i]->is_secret)
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaPropertyInfo *
|
|
Packit Service |
a1bd4f |
nm_meta_property_info_find_by_name(const char *setting_name, const char *property_name)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *setting_info;
|
|
Packit Service |
a1bd4f |
const NMMetaPropertyInfo * property_info;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
setting_info = nm_meta_setting_info_editor_find_by_name(setting_name, FALSE);
|
|
Packit Service |
a1bd4f |
if (!setting_info)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name);
|
|
Packit Service |
a1bd4f |
if (!property_info)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(property_info->setting_info == setting_info);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return property_info;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const NMMetaPropertyInfo *
|
|
Packit Service |
a1bd4f |
nm_meta_property_info_find_by_setting(NMSetting *setting, const char *property_name)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *setting_info;
|
|
Packit Service |
a1bd4f |
const NMMetaPropertyInfo * property_info;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
setting_info = nm_meta_setting_info_editor_find_by_setting(setting);
|
|
Packit Service |
a1bd4f |
if (!setting_info)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name);
|
|
Packit Service |
a1bd4f |
if (!property_info)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(property_info->setting_info == setting_info);
|
|
Packit Service |
a1bd4f |
nm_assert(property_info
|
|
Packit Service |
a1bd4f |
== nm_meta_property_info_find_by_name(nm_setting_get_name(setting), property_name));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return property_info;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMSetting *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info,
|
|
Packit Service |
a1bd4f |
NMMetaAccessorSettingInitType init_type)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMSetting *setting;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(setting_info, NULL);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
setting = g_object_new(setting_info->general->get_setting_gtype(), NULL);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (setting_info->setting_init_fcn && init_type != NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT) {
|
|
Packit Service |
a1bd4f |
setting_info->setting_init_fcn(setting_info, setting, init_type);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return setting;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
const NMMetaSettingInfoEditor *const *
|
|
Packit Service |
a1bd4f |
nm_meta_setting_infos_editor_p(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
static const NMMetaSettingInfoEditor *cache[_NM_META_SETTING_TYPE_NUM + 1] = {NULL};
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (G_UNLIKELY(!cache[0])) {
|
|
Packit Service |
a1bd4f |
for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++)
|
|
Packit Service |
a1bd4f |
cache[i] = &nm_meta_setting_infos_editor[i];
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return cache;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const char *
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get_name(const NMMetaAbstractInfo *abstract_info, gboolean for_header)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const char *n;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info);
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info->meta_type);
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info->meta_type->get_name);
|
|
Packit Service |
a1bd4f |
n = abstract_info->meta_type->get_name(abstract_info, for_header);
|
|
Packit Service |
a1bd4f |
nm_assert(n && n[0]);
|
|
Packit Service |
a1bd4f |
return n;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info,
|
|
Packit Service |
a1bd4f |
guint * out_len,
|
|
Packit Service |
a1bd4f |
gpointer * nested_to_free)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *nested;
|
|
Packit Service |
a1bd4f |
guint l = 0;
|
|
Packit Service |
a1bd4f |
gs_free gpointer f = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info);
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info->meta_type);
|
|
Packit Service |
a1bd4f |
nm_assert(nested_to_free && !*nested_to_free);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (abstract_info->meta_type->get_nested) {
|
|
Packit Service |
a1bd4f |
nested = abstract_info->meta_type->get_nested(abstract_info, &l, &f);
|
|
Packit Service |
a1bd4f |
nm_assert(NM_PTRARRAY_LEN(nested) == l);
|
|
Packit Service |
a1bd4f |
nm_assert(!f || nested == f);
|
|
Packit Service |
a1bd4f |
if (nested && nested[0]) {
|
|
Packit Service |
a1bd4f |
NM_SET_OUT(out_len, l);
|
|
Packit Service |
a1bd4f |
*nested_to_free = g_steal_pointer(&f);
|
|
Packit Service |
a1bd4f |
return nested;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
NM_SET_OUT(out_len, 0);
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gconstpointer
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info,
|
|
Packit Service |
a1bd4f |
const NMMetaEnvironment * environment,
|
|
Packit Service |
a1bd4f |
gpointer environment_user_data,
|
|
Packit Service |
a1bd4f |
gpointer target,
|
|
Packit Service |
a1bd4f |
gpointer target_data,
|
|
Packit Service |
a1bd4f |
NMMetaAccessorGetType get_type,
|
|
Packit Service |
a1bd4f |
NMMetaAccessorGetFlags get_flags,
|
|
Packit Service |
a1bd4f |
NMMetaAccessorGetOutFlags *out_flags,
|
|
Packit Service |
a1bd4f |
gboolean * out_is_default,
|
|
Packit Service |
a1bd4f |
gpointer * out_to_free)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info);
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info->meta_type);
|
|
Packit Service |
a1bd4f |
nm_assert(!out_to_free || !*out_to_free);
|
|
Packit Service |
a1bd4f |
nm_assert(out_flags);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
*out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE;
|
|
Packit Service |
a1bd4f |
NM_SET_OUT(out_is_default, FALSE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!abstract_info->meta_type->get_fcn)
|
|
Packit Service |
a1bd4f |
g_return_val_if_reached(NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return abstract_info->meta_type->get_fcn(abstract_info,
|
|
Packit Service |
a1bd4f |
environment,
|
|
Packit Service |
a1bd4f |
environment_user_data,
|
|
Packit Service |
a1bd4f |
target,
|
|
Packit Service |
a1bd4f |
target_data,
|
|
Packit Service |
a1bd4f |
get_type,
|
|
Packit Service |
a1bd4f |
get_flags,
|
|
Packit Service |
a1bd4f |
out_flags,
|
|
Packit Service |
a1bd4f |
out_is_default,
|
|
Packit Service |
a1bd4f |
out_to_free);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
const char *const *
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_complete(const NMMetaAbstractInfo * abstract_info,
|
|
Packit Service |
a1bd4f |
const NMMetaEnvironment * environment,
|
|
Packit Service |
a1bd4f |
gpointer environment_user_data,
|
|
Packit Service |
a1bd4f |
const NMMetaOperationContext *operation_context,
|
|
Packit Service |
a1bd4f |
const char * text,
|
|
Packit Service |
a1bd4f |
gboolean * out_complete_filename,
|
|
Packit Service |
a1bd4f |
char *** out_to_free)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const char *const *values;
|
|
Packit Service |
a1bd4f |
gsize i, j, text_len;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info);
|
|
Packit Service |
a1bd4f |
nm_assert(abstract_info->meta_type);
|
|
Packit Service |
a1bd4f |
nm_assert(out_to_free && !*out_to_free);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
*out_to_free = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!abstract_info->meta_type->complete_fcn)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
values = abstract_info->meta_type->complete_fcn(abstract_info,
|
|
Packit Service |
a1bd4f |
environment,
|
|
Packit Service |
a1bd4f |
environment_user_data,
|
|
Packit Service |
a1bd4f |
operation_context,
|
|
Packit Service |
a1bd4f |
text,
|
|
Packit Service |
a1bd4f |
out_complete_filename,
|
|
Packit Service |
a1bd4f |
out_to_free);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(!*out_to_free || values == (const char *const *) *out_to_free);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!values)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!values[0]) {
|
|
Packit Service |
a1bd4f |
nm_clear_g_free(out_to_free);
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!text || !text[0])
|
|
Packit Service |
a1bd4f |
return values;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* for convenience, we allow the complete_fcn() implementations to
|
|
Packit Service |
a1bd4f |
* ignore "text". We filter out invalid matches here. */
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
text_len = strlen(text);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (*out_to_free) {
|
|
Packit Service |
a1bd4f |
char **v = *out_to_free;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (i = 0, j = 0; v[i]; i++) {
|
|
Packit Service |
a1bd4f |
if (strncmp(v[i], text, text_len) != 0) {
|
|
Packit Service |
a1bd4f |
g_free(v[i]);
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
v[j++] = v[i];
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
if (j)
|
|
Packit Service |
a1bd4f |
v[j++] = NULL;
|
|
Packit Service |
a1bd4f |
else {
|
|
Packit Service |
a1bd4f |
g_free(v);
|
|
Packit Service |
a1bd4f |
*out_to_free = v = NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return (const char *const *) v;
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
const char *const *v = values;
|
|
Packit Service |
a1bd4f |
char ** r;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (i = 0, j = 0; v[i]; i++) {
|
|
Packit Service |
a1bd4f |
if (strncmp(v[i], text, text_len) != 0)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
j++;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
if (j == i)
|
|
Packit Service |
a1bd4f |
return values;
|
|
Packit Service |
a1bd4f |
else if (!j)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
r = g_new(char *, j + 1);
|
|
Packit Service |
a1bd4f |
v = values;
|
|
Packit Service |
a1bd4f |
for (i = 0, j = 0; v[i]; i++) {
|
|
Packit Service |
a1bd4f |
if (strncmp(v[i], text, text_len) != 0)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
r[j++] = g_strdup(v[i]);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
r[j++] = NULL;
|
|
Packit Service |
a1bd4f |
return (const char *const *) (*out_to_free = r);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
char *
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info,
|
|
Packit Service |
a1bd4f |
const char * name_prefix)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_free gpointer nested_to_free = NULL;
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *nested;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nested = nm_meta_abstract_info_get_nested(abstract_info, NULL, &nested_to_free);
|
|
Packit Service |
a1bd4f |
if (!nested)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!name_prefix)
|
|
Packit Service |
a1bd4f |
name_prefix = nm_meta_abstract_info_get_name(abstract_info, FALSE);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return nm_meta_abstract_infos_get_names_str(nested, name_prefix);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
char *
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array,
|
|
Packit Service |
a1bd4f |
const char * name_prefix)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GString *str;
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!fields_array || !fields_array[0])
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
str = g_string_sized_new(128);
|
|
Packit Service |
a1bd4f |
for (i = 0; fields_array[i]; i++) {
|
|
Packit Service |
a1bd4f |
if (str->len > 0)
|
|
Packit Service |
a1bd4f |
g_string_append_c(str, ',');
|
|
Packit Service |
a1bd4f |
if (name_prefix) {
|
|
Packit Service |
a1bd4f |
g_string_append(str, name_prefix);
|
|
Packit Service |
a1bd4f |
g_string_append_c(str, '.');
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
g_string_append(str, nm_meta_abstract_info_get_name(fields_array[i], FALSE));
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return g_string_free(str, FALSE);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
guint idx;
|
|
Packit Service |
a1bd4f |
gsize self_offset_plus_1;
|
|
Packit Service |
a1bd4f |
gsize sub_offset_plus_1;
|
|
Packit |
5756e2 |
} OutputSelectionItem;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static NMMetaSelectionResultList *
|
|
Packit Service |
a1bd4f |
_output_selection_pack(const NMMetaAbstractInfo *const *fields_array, GArray *array, GString *str)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMMetaSelectionResultList *result;
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit Service |
a1bd4f |
guint len;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
len = array ? array->len : 0;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* re-organize the collected output data in one buffer that can be freed using
|
|
Packit Service |
a1bd4f |
* g_free(). This makes allocation more complicated, but saves us from special
|
|
Packit Service |
a1bd4f |
* handling for free. */
|
|
Packit Service |
a1bd4f |
result = g_malloc0(sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))
|
|
Packit Service |
a1bd4f |
+ (str ? str->len : 0));
|
|
Packit Service |
a1bd4f |
*((guint *) &result->num) = len;
|
|
Packit Service |
a1bd4f |
if (len > 0) {
|
|
Packit Service |
a1bd4f |
char *pdata =
|
|
Packit Service |
a1bd4f |
&((char *)
|
|
Packit Service |
a1bd4f |
result)[sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))];
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (str)
|
|
Packit Service |
a1bd4f |
memcpy(pdata, str->str, str->len);
|
|
Packit Service |
a1bd4f |
for (i = 0; i < len; i++) {
|
|
Packit Service |
a1bd4f |
const OutputSelectionItem *a = &g_array_index(array, OutputSelectionItem, i);
|
|
Packit Service |
a1bd4f |
NMMetaSelectionItem * p = (NMMetaSelectionItem *) &result->items[i];
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
p->info = fields_array[a->idx];
|
|
Packit Service |
a1bd4f |
p->idx = a->idx;
|
|
Packit Service |
a1bd4f |
if (a->self_offset_plus_1 > 0)
|
|
Packit Service |
a1bd4f |
p->self_selection = &pdata[a->self_offset_plus_1 - 1];
|
|
Packit Service |
a1bd4f |
if (a->sub_offset_plus_1 > 0)
|
|
Packit Service |
a1bd4f |
p->sub_selection = &pdata[a->sub_offset_plus_1 - 1];
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return result;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
_output_selection_select_one(const NMMetaAbstractInfo *const *fields_array,
|
|
Packit Service |
a1bd4f |
const char * fields_prefix,
|
|
Packit Service |
a1bd4f |
const char * fields_str,
|
|
Packit Service |
a1bd4f |
gboolean validate_nested,
|
|
Packit Service |
a1bd4f |
GArray ** p_array,
|
|
Packit Service |
a1bd4f |
GString ** p_str,
|
|
Packit Service |
a1bd4f |
GError ** error)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
guint i, j;
|
|
Packit Service |
a1bd4f |
const char * i_name;
|
|
Packit Service |
a1bd4f |
const char * right;
|
|
Packit Service |
a1bd4f |
gboolean found = FALSE;
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *fields_array_failure = NULL;
|
|
Packit Service |
a1bd4f |
gs_free char * fields_str_clone = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(fields_str);
|
|
Packit Service |
a1bd4f |
nm_assert(p_array);
|
|
Packit Service |
a1bd4f |
nm_assert(p_str);
|
|
Packit Service |
a1bd4f |
nm_assert(!error || !*error);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
right = strchr(fields_str, '.');
|
|
Packit Service |
a1bd4f |
if (right) {
|
|
Packit Service |
a1bd4f |
fields_str_clone = g_strdup(fields_str);
|
|
Packit Service |
a1bd4f |
fields_str_clone[right - fields_str] = '\0';
|
|
Packit Service |
a1bd4f |
i_name = fields_str_clone;
|
|
Packit Service |
a1bd4f |
right = &fields_str_clone[right - fields_str + 1];
|
|
Packit Service |
a1bd4f |
} else
|
|
Packit Service |
a1bd4f |
i_name = fields_str;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!fields_array)
|
|
Packit Service |
a1bd4f |
goto not_found;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (i = 0; fields_array[i]; i++) {
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo * fi = fields_array[i];
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *nested;
|
|
Packit Service |
a1bd4f |
gs_free gpointer nested_to_free = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (g_ascii_strcasecmp(i_name, nm_meta_abstract_info_get_name(fi, FALSE)) != 0)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!right || !validate_nested) {
|
|
Packit Service |
a1bd4f |
found = TRUE;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nested = nm_meta_abstract_info_get_nested(fi, NULL, &nested_to_free);
|
|
Packit Service |
a1bd4f |
if (nested) {
|
|
Packit Service |
a1bd4f |
for (j = 0; nested[j]; nested++) {
|
|
Packit Service |
a1bd4f |
if (g_ascii_strcasecmp(right, nm_meta_abstract_info_get_name(nested[j], FALSE))
|
|
Packit Service |
a1bd4f |
== 0) {
|
|
Packit Service |
a1bd4f |
found = TRUE;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
fields_array_failure = fields_array[i];
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!found) {
|
|
Packit |
5756e2 |
not_found:
|
|
Packit Service |
a1bd4f |
if (!right && !fields_prefix
|
|
Packit Service |
a1bd4f |
&& (!g_ascii_strcasecmp(i_name, "all") || !g_ascii_strcasecmp(i_name, "common")))
|
|
Packit Service |
a1bd4f |
g_set_error(error,
|
|
Packit Service |
a1bd4f |
NM_UTILS_ERROR,
|
|
Packit Service |
a1bd4f |
NM_UTILS_ERROR_UNKNOWN,
|
|
Packit Service |
a1bd4f |
_("field '%s' has to be alone"),
|
|
Packit Service |
a1bd4f |
i_name);
|
|
Packit Service |
a1bd4f |
else {
|
|
Packit Service |
a1bd4f |
gs_free char *allowed_fields = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (fields_array_failure) {
|
|
Packit Service |
a1bd4f |
gs_free char *p = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (fields_prefix) {
|
|
Packit Service |
a1bd4f |
p = g_strdup_printf(
|
|
Packit Service |
a1bd4f |
"%s.%s",
|
|
Packit Service |
a1bd4f |
fields_prefix,
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get_name(fields_array_failure, FALSE));
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
allowed_fields =
|
|
Packit Service |
a1bd4f |
nm_meta_abstract_info_get_nested_names_str(fields_array_failure, p);
|
|
Packit Service |
a1bd4f |
} else
|
|
Packit Service |
a1bd4f |
allowed_fields = nm_meta_abstract_infos_get_names_str(fields_array, NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_set_error(error,
|
|
Packit Service |
a1bd4f |
NM_UTILS_ERROR,
|
|
Packit Service |
a1bd4f |
NM_UTILS_ERROR_UNKNOWN,
|
|
Packit Service |
a1bd4f |
_("invalid field '%s%s%s%s%s'; %s%s%s"),
|
|
Packit Service |
a1bd4f |
fields_prefix ?: "",
|
|
Packit Service |
a1bd4f |
fields_prefix ? "." : "",
|
|
Packit Service |
a1bd4f |
i_name,
|
|
Packit Service |
a1bd4f |
right ? "." : "",
|
|
Packit Service |
a1bd4f |
right ?: "",
|
|
Packit Service |
a1bd4f |
NM_PRINT_FMT_QUOTED(allowed_fields,
|
|
Packit Service |
a1bd4f |
"allowed fields: ",
|
|
Packit Service |
a1bd4f |
allowed_fields,
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
"no fields"));
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
GString * str;
|
|
Packit Service |
a1bd4f |
OutputSelectionItem s = {
|
|
Packit Service |
a1bd4f |
.idx = i,
|
|
Packit Service |
a1bd4f |
};
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!*p_str)
|
|
Packit Service |
a1bd4f |
*p_str = g_string_sized_new(64);
|
|
Packit Service |
a1bd4f |
str = *p_str;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
s.self_offset_plus_1 = str->len + 1;
|
|
Packit Service |
a1bd4f |
if (fields_prefix) {
|
|
Packit Service |
a1bd4f |
g_string_append(str, fields_prefix);
|
|
Packit Service |
a1bd4f |
g_string_append_c(str, '.');
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
g_string_append_len(str, i_name, strlen(i_name) + 1);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (right) {
|
|
Packit Service |
a1bd4f |
s.sub_offset_plus_1 = str->len + 1;
|
|
Packit Service |
a1bd4f |
g_string_append_len(str, right, strlen(right) + 1);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!*p_array)
|
|
Packit Service |
a1bd4f |
*p_array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem));
|
|
Packit Service |
a1bd4f |
g_array_append_val(*p_array, s);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMMetaSelectionResultList *
|
|
Packit Service |
a1bd4f |
nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_array GArray *array = NULL;
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (fields_array) {
|
|
Packit Service |
a1bd4f |
array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem));
|
|
Packit Service |
a1bd4f |
for (i = 0; fields_array[i]; i++) {
|
|
Packit Service |
a1bd4f |
OutputSelectionItem s = {
|
|
Packit Service |
a1bd4f |
.idx = i,
|
|
Packit Service |
a1bd4f |
};
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_array_append_val(array, s);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return _output_selection_pack(fields_array, array, NULL);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMMetaSelectionResultList *
|
|
Packit Service |
a1bd4f |
nm_meta_selection_create_parse_one(
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *fields_array,
|
|
Packit Service |
a1bd4f |
const char * fields_prefix,
|
|
Packit Service |
a1bd4f |
const char *
|
|
Packit Service |
a1bd4f |
fields_str, /* one field selector (contains no commas) and is already stripped of spaces. */
|
|
Packit Service |
a1bd4f |
gboolean validate_nested,
|
|
Packit Service |
a1bd4f |
GError **error)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_array GArray *array = NULL;
|
|
Packit Service |
a1bd4f |
nm_auto_free_gstring GString *str = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(!error || !*error, NULL);
|
|
Packit Service |
a1bd4f |
nm_assert(fields_str && !strchr(fields_str, ','));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!_output_selection_select_one(fields_array,
|
|
Packit Service |
a1bd4f |
fields_prefix,
|
|
Packit Service |
a1bd4f |
fields_str,
|
|
Packit Service |
a1bd4f |
validate_nested,
|
|
Packit Service |
a1bd4f |
&array,
|
|
Packit Service |
a1bd4f |
&str,
|
|
Packit Service |
a1bd4f |
error))
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
return _output_selection_pack(fields_array, array, str);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMMetaSelectionResultList *
|
|
Packit Service |
a1bd4f |
nm_meta_selection_create_parse_list(
|
|
Packit Service |
a1bd4f |
const NMMetaAbstractInfo *const *fields_array,
|
|
Packit Service |
a1bd4f |
const char * fields_str, /* a comma separated list of selectors */
|
|
Packit Service |
a1bd4f |
gboolean validate_nested,
|
|
Packit Service |
a1bd4f |
GError ** error)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_array GArray *array = NULL;
|
|
Packit Service |
a1bd4f |
nm_auto_free_gstring GString *str = NULL;
|
|
Packit Service |
a1bd4f |
gs_free char * fields_str_clone = NULL;
|
|
Packit Service |
a1bd4f |
char * fields_str_cur;
|
|
Packit Service |
a1bd4f |
char * fields_str_next;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(!error || !*error, NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!fields_str)
|
|
Packit Service |
a1bd4f |
return nm_meta_selection_create_all(fields_array);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
fields_str_clone = g_strdup(fields_str);
|
|
Packit Service |
a1bd4f |
for (fields_str_cur = fields_str_clone; fields_str_cur; fields_str_cur = fields_str_next) {
|
|
Packit Service |
a1bd4f |
fields_str_cur = nm_str_skip_leading_spaces(fields_str_cur);
|
|
Packit Service |
a1bd4f |
fields_str_next = strchr(fields_str_cur, ',');
|
|
Packit Service |
a1bd4f |
if (fields_str_next)
|
|
Packit Service |
a1bd4f |
*fields_str_next++ = '\0';
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_strchomp(fields_str_cur);
|
|
Packit Service |
a1bd4f |
if (!fields_str_cur[0])
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
if (!_output_selection_select_one(fields_array,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
fields_str_cur,
|
|
Packit Service |
a1bd4f |
validate_nested,
|
|
Packit Service |
a1bd4f |
&array,
|
|
Packit Service |
a1bd4f |
&str,
|
|
Packit Service |
a1bd4f |
error))
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return _output_selection_pack(fields_array, array, str);
|
|
Packit |
5756e2 |
}
|