mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 15:20:11 +01:00
Naming is important, because the name of a thing should give you a good idea what it does. Also, to find a thing, it needs a good name in the first place. But naming is also hard. Historically, some strv helper API was named as nm_utils_strv_*(), and some API had a leading underscore (as it is internal API). This was all inconsistent. Do some renaming and try to unify things. We get rid of the leading underscore if this is just a regular (internal) helper. But not for example from _nm_strv_find_first(), because that is the implementation of nm_strv_find_first(). - _nm_utils_strv_cleanup() -> nm_strv_cleanup() - _nm_utils_strv_cleanup_const() -> nm_strv_cleanup_const() - _nm_utils_strv_cmp_n() -> _nm_strv_cmp_n() - _nm_utils_strv_dup() -> _nm_strv_dup() - _nm_utils_strv_dup_packed() -> _nm_strv_dup_packed() - _nm_utils_strv_find_first() -> _nm_strv_find_first() - _nm_utils_strv_sort() -> _nm_strv_sort() - _nm_utils_strv_to_ptrarray() -> nm_strv_to_ptrarray() - _nm_utils_strv_to_slist() -> nm_strv_to_gslist() - nm_utils_strv_cmp_n() -> nm_strv_cmp_n() - nm_utils_strv_dup() -> nm_strv_dup() - nm_utils_strv_dup_packed() -> nm_strv_dup_packed() - nm_utils_strv_dup_shallow_maybe_a() -> nm_strv_dup_shallow_maybe_a() - nm_utils_strv_equal() -> nm_strv_equal() - nm_utils_strv_find_binary_search() -> nm_strv_find_binary_search() - nm_utils_strv_find_first() -> nm_strv_find_first() - nm_utils_strv_make_deep_copied() -> nm_strv_make_deep_copied() - nm_utils_strv_make_deep_copied_n() -> nm_strv_make_deep_copied_n() - nm_utils_strv_make_deep_copied_nonnull() -> nm_strv_make_deep_copied_nonnull() - nm_utils_strv_sort() -> nm_strv_sort() Note that no names are swapped and none of the new names existed previously. That means, all the new names are really new, which simplifies to find errors due to this larger refactoring. E.g. if you backport a patch from after this change to an old branch, you'll get a compiler error and notice that something is missing.
290 lines
7.9 KiB
C
290 lines
7.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2018 Red Hat, Inc.
|
|
*/
|
|
|
|
#include "src/core/nm-default-daemon.h"
|
|
|
|
#include "nm-dbus-utils.h"
|
|
|
|
#include "nm-dbus-object.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
GDBusPropertyInfo *
|
|
nm_dbus_utils_interface_info_lookup_property(const GDBusInterfaceInfo *interface_info,
|
|
const char * property_name,
|
|
guint * property_idx)
|
|
{
|
|
guint i;
|
|
|
|
nm_assert(interface_info);
|
|
nm_assert(property_name);
|
|
|
|
/* there is also g_dbus_interface_info_lookup_property(), however that makes use
|
|
* of a global cache. */
|
|
if (interface_info->properties) {
|
|
for (i = 0; interface_info->properties[i]; i++) {
|
|
GDBusPropertyInfo *info = interface_info->properties[i];
|
|
|
|
if (nm_streq(info->name, property_name)) {
|
|
NM_SET_OUT(property_idx, i);
|
|
return info;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
GDBusMethodInfo *
|
|
nm_dbus_utils_interface_info_lookup_method(const GDBusInterfaceInfo *interface_info,
|
|
const char * method_name)
|
|
{
|
|
guint i;
|
|
|
|
nm_assert(interface_info);
|
|
nm_assert(method_name);
|
|
|
|
/* there is also g_dbus_interface_info_lookup_property(), however that makes use
|
|
* of a global cache. */
|
|
if (interface_info->methods) {
|
|
for (i = 0; interface_info->methods[i]; i++) {
|
|
GDBusMethodInfo *info = interface_info->methods[i];
|
|
|
|
if (nm_streq(info->name, method_name))
|
|
return info;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
GVariant *
|
|
nm_dbus_utils_get_property(GObject *obj, const char *signature, const char *property_name)
|
|
{
|
|
nm_auto_unset_gvalue GValue value = G_VALUE_INIT;
|
|
GParamSpec * pspec;
|
|
GVariant * variant;
|
|
|
|
nm_assert(G_IS_OBJECT(obj));
|
|
nm_assert(g_variant_type_string_is_valid(signature));
|
|
nm_assert(property_name && property_name[0]);
|
|
|
|
pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), property_name);
|
|
|
|
nm_assert(pspec);
|
|
|
|
nm_assert(pspec->value_type != G_TYPE_VARIANT
|
|
|| nm_streq((char *) (((GParamSpecVariant *) pspec)->type), signature));
|
|
|
|
g_value_init(&value, pspec->value_type);
|
|
|
|
g_object_get_property(obj, property_name, &value);
|
|
|
|
variant = g_dbus_gvalue_to_gvariant(&value, G_VARIANT_TYPE(signature));
|
|
|
|
nm_assert(!variant || g_variant_is_of_type(variant, G_VARIANT_TYPE(signature)));
|
|
|
|
/* returns never-floating variant */
|
|
nm_assert(!variant || !g_variant_is_floating(variant));
|
|
|
|
return variant;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
nm_dbus_utils_g_value_set_object_path(GValue *value, gpointer object)
|
|
{
|
|
const char *path;
|
|
|
|
g_return_if_fail(!object || NM_IS_DBUS_OBJECT(object));
|
|
|
|
if (object && (path = nm_dbus_object_get_path(object)))
|
|
g_value_set_string(value, path);
|
|
else
|
|
g_value_set_string(value, NULL);
|
|
}
|
|
|
|
void
|
|
nm_dbus_utils_g_value_set_object_path_still_exported(GValue *value, gpointer object)
|
|
{
|
|
const char *path;
|
|
|
|
g_return_if_fail(!object || NM_IS_DBUS_OBJECT(object));
|
|
|
|
if (object && (path = nm_dbus_object_get_path_still_exported(object)))
|
|
g_value_set_string(value, path);
|
|
else
|
|
g_value_set_string(value, "/");
|
|
}
|
|
|
|
void
|
|
nm_dbus_utils_g_value_set_object_path_from_hash(
|
|
GValue * value,
|
|
GHashTable *hash /* has keys of NMDBusObject type. */,
|
|
gboolean expect_all_exported)
|
|
{
|
|
NMDBusObject * obj;
|
|
char ** strv;
|
|
guint i, n;
|
|
GHashTableIter iter;
|
|
|
|
nm_assert(value);
|
|
nm_assert(hash);
|
|
|
|
n = g_hash_table_size(hash);
|
|
strv = g_new(char *, n + 1);
|
|
i = 0;
|
|
g_hash_table_iter_init(&iter, hash);
|
|
while (g_hash_table_iter_next(&iter, (gpointer *) &obj, NULL)) {
|
|
const char *path;
|
|
|
|
path = nm_dbus_object_get_path_still_exported(obj);
|
|
if (!path) {
|
|
nm_assert(!expect_all_exported);
|
|
continue;
|
|
}
|
|
strv[i++] = g_strdup(path);
|
|
}
|
|
nm_assert(i <= n);
|
|
strv[i] = NULL;
|
|
|
|
/* sort the names, to give a well-defined, stable order. */
|
|
nm_strv_sort(strv, i);
|
|
|
|
g_value_take_boxed(value, strv);
|
|
}
|
|
|
|
const char **
|
|
nm_dbus_utils_get_paths_for_clist(const CList *lst_head,
|
|
gssize lst_len,
|
|
guint member_offset,
|
|
gboolean expect_all_exported)
|
|
{
|
|
const CList *iter;
|
|
const char **strv;
|
|
const char * path;
|
|
gsize i, n;
|
|
|
|
nm_assert(lst_head);
|
|
|
|
if (lst_len < 0)
|
|
n = c_list_length(lst_head);
|
|
else {
|
|
n = lst_len;
|
|
nm_assert(n == c_list_length(lst_head));
|
|
}
|
|
|
|
i = 0;
|
|
strv = g_new(const char *, n + 1);
|
|
c_list_for_each (iter, lst_head) {
|
|
NMDBusObject *obj = (NMDBusObject *) (((const char *) iter) - member_offset);
|
|
|
|
path = nm_dbus_object_get_path(obj);
|
|
if (!path) {
|
|
nm_assert(expect_all_exported);
|
|
continue;
|
|
}
|
|
|
|
nm_assert(i < n);
|
|
strv[i++] = path;
|
|
}
|
|
nm_assert(i <= n);
|
|
strv[i] = NULL;
|
|
|
|
return strv;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
nm_dbus_track_obj_path_init(NMDBusTrackObjPath *track, GObject *target, const GParamSpec *pspec)
|
|
{
|
|
nm_assert(track);
|
|
nm_assert(G_IS_OBJECT(target));
|
|
nm_assert(G_IS_PARAM_SPEC(pspec));
|
|
|
|
track->_obj = NULL;
|
|
track->_notify_target = target;
|
|
track->_notify_pspec = pspec;
|
|
track->_notify_signal_id = 0;
|
|
track->_visible = FALSE;
|
|
}
|
|
|
|
void
|
|
nm_dbus_track_obj_path_deinit(NMDBusTrackObjPath *track)
|
|
{
|
|
/* we allow deinit() to be called multiple times (e.g. from
|
|
* dispose(), which must be re-entrant). */
|
|
nm_assert(track);
|
|
nm_assert(!track->_notify_target || G_IS_OBJECT(track->_notify_target));
|
|
|
|
nm_clear_g_signal_handler(track->obj, &track->_notify_signal_id);
|
|
track->_notify_target = NULL;
|
|
track->_notify_pspec = NULL;
|
|
track->_visible = FALSE;
|
|
nm_clear_g_object(&track->_obj);
|
|
}
|
|
|
|
void
|
|
nm_dbus_track_obj_path_notify(const NMDBusTrackObjPath *track)
|
|
{
|
|
nm_assert(track);
|
|
nm_assert(G_IS_OBJECT(track->_notify_target));
|
|
nm_assert(G_IS_PARAM_SPEC(track->_notify_pspec));
|
|
|
|
g_object_notify_by_pspec(track->_notify_target, (GParamSpec *) track->_notify_pspec);
|
|
}
|
|
|
|
const char *
|
|
nm_dbus_track_obj_path_get(const NMDBusTrackObjPath *track)
|
|
{
|
|
nm_assert(track);
|
|
nm_assert(G_IS_OBJECT(track->_notify_target));
|
|
|
|
return track->obj && track->visible ? nm_dbus_object_get_path_still_exported(track->obj) : NULL;
|
|
}
|
|
|
|
static void
|
|
_track_obj_exported_changed(NMDBusObject *obj, NMDBusTrackObjPath *track)
|
|
{
|
|
nm_dbus_track_obj_path_notify(track);
|
|
}
|
|
|
|
void
|
|
nm_dbus_track_obj_path_set(NMDBusTrackObjPath *track, gpointer obj, gboolean visible)
|
|
{
|
|
gs_unref_object NMDBusObject *old_obj = NULL;
|
|
const char * old_path;
|
|
|
|
nm_assert(track);
|
|
nm_assert(G_IS_OBJECT(track->_notify_target));
|
|
|
|
g_return_if_fail(!obj || NM_IS_DBUS_OBJECT(obj));
|
|
|
|
if (track->obj == obj && track->visible == !!visible)
|
|
return;
|
|
|
|
old_path = nm_dbus_track_obj_path_get(track);
|
|
|
|
track->_visible = visible;
|
|
|
|
if (track->obj != obj) {
|
|
nm_clear_g_signal_handler(track->obj, &track->_notify_signal_id);
|
|
|
|
old_obj = track->obj;
|
|
track->_obj = nm_g_object_ref(obj);
|
|
|
|
if (obj) {
|
|
track->_notify_signal_id = g_signal_connect(obj,
|
|
NM_DBUS_OBJECT_EXPORTED_CHANGED,
|
|
G_CALLBACK(_track_obj_exported_changed),
|
|
track);
|
|
}
|
|
}
|
|
|
|
if (!nm_streq0(old_path, nm_dbus_track_obj_path_get(track)))
|
|
nm_dbus_track_obj_path_notify(track);
|
|
}
|