Blame src/libnm-client-impl/nm-dbus-helpers.c

Packit Service dff8e4
/* SPDX-License-Identifier: LGPL-2.1-or-later */
Packit Service dff8e4
/*
Packit Service dff8e4
 * Copyright (C) 2013 Red Hat, Inc.
Packit Service dff8e4
 */
Packit Service dff8e4
Packit Service dff8e4
#include "libnm-client-impl/nm-default-libnm.h"
Packit Service dff8e4
Packit Service dff8e4
#include "nm-dbus-helpers.h"
Packit Service dff8e4
Packit Service dff8e4
#include "nm-dbus-interface.h"
Packit Service dff8e4
Packit Service dff8e4
GBusType
Packit Service dff8e4
_nm_dbus_bus_type(void)
Packit Service dff8e4
{
Packit Service dff8e4
    static volatile int bus_type = G_BUS_TYPE_NONE;
Packit Service dff8e4
    int                 v;
Packit Service dff8e4
Packit Service dff8e4
    v = g_atomic_int_get(&bus_type);
Packit Service dff8e4
    if (G_UNLIKELY(v == G_BUS_TYPE_NONE)) {
Packit Service dff8e4
        v = G_BUS_TYPE_SYSTEM;
Packit Service dff8e4
        if (g_getenv("LIBNM_USE_SESSION_BUS"))
Packit Service dff8e4
            v = G_BUS_TYPE_SESSION;
Packit Service dff8e4
        if (!g_atomic_int_compare_and_exchange(&bus_type, G_BUS_TYPE_NONE, v))
Packit Service dff8e4
            v = g_atomic_int_get(&bus_type);
Packit Service dff8e4
        nm_assert(v != G_BUS_TYPE_NONE);
Packit Service dff8e4
    }
Packit Service dff8e4
    return v;
Packit Service dff8e4
}
Packit Service dff8e4
Packit Service dff8e4
/* Binds the properties on a generated server-side GDBus object to the
Packit Service dff8e4
 * corresponding properties on the public object.
Packit Service dff8e4
 */
Packit Service dff8e4
void
Packit Service dff8e4
_nm_dbus_bind_properties(gpointer object, gpointer skeleton)
Packit Service dff8e4
{
Packit Service dff8e4
    GParamSpec **properties;
Packit Service dff8e4
    guint        n_properties;
Packit Service dff8e4
    int          i;
Packit Service dff8e4
Packit Service dff8e4
    properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(skeleton), &n_properties);
Packit Service dff8e4
    for (i = 0; i < n_properties; i++) {
Packit Service dff8e4
        if (g_str_has_prefix(properties[i]->name, "g-"))
Packit Service dff8e4
            continue;
Packit Service dff8e4
Packit Service dff8e4
        g_object_bind_property(object,
Packit Service dff8e4
                               properties[i]->name,
Packit Service dff8e4
                               skeleton,
Packit Service dff8e4
                               properties[i]->name,
Packit Service dff8e4
                               G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
Packit Service dff8e4
    }
Packit Service dff8e4
    g_free(properties);
Packit Service dff8e4
}
Packit Service dff8e4
Packit Service dff8e4
static char *
Packit Service dff8e4
signal_name_from_method_name(const char *method_name)
Packit Service dff8e4
{
Packit Service dff8e4
    GString *   signal_name;
Packit Service dff8e4
    const char *p;
Packit Service dff8e4
Packit Service dff8e4
    signal_name = g_string_new("handle");
Packit Service dff8e4
    for (p = method_name; *p; p++) {
Packit Service dff8e4
        if (g_ascii_isupper(*p))
Packit Service dff8e4
            g_string_append_c(signal_name, '-');
Packit Service dff8e4
        g_string_append_c(signal_name, g_ascii_tolower(*p));
Packit Service dff8e4
    }
Packit Service dff8e4
Packit Service dff8e4
    return g_string_free(signal_name, FALSE);
Packit Service dff8e4
}
Packit Service dff8e4
Packit Service dff8e4
static void
Packit Service dff8e4
_nm_dbus_method_meta_marshal(GClosure *    closure,
Packit Service dff8e4
                             GValue *      return_value,
Packit Service dff8e4
                             guint         n_param_values,
Packit Service dff8e4
                             const GValue *param_values,
Packit Service dff8e4
                             gpointer      invocation_hint,
Packit Service dff8e4
                             gpointer      marshal_data)
Packit Service dff8e4
{
Packit Service dff8e4
    closure->marshal(closure,
Packit Service dff8e4
                     return_value,
Packit Service dff8e4
                     n_param_values,
Packit Service dff8e4
                     param_values,
Packit Service dff8e4
                     invocation_hint,
Packit Service dff8e4
                     ((GCClosure *) closure)->callback);
Packit Service dff8e4
Packit Service dff8e4
    g_value_set_boolean(return_value, TRUE);
Packit Service dff8e4
}
Packit Service dff8e4
Packit Service dff8e4
/* Takes (method_name, handler_func) pairs and connects the handlers to the
Packit Service dff8e4
 * signals on skeleton, with object as the user_data, but swapped so it comes
Packit Service dff8e4
 * first in the argument list, and handling the return value automatically.
Packit Service dff8e4
 */
Packit Service dff8e4
void
Packit Service dff8e4
_nm_dbus_bind_methods(gpointer object, gpointer skeleton, ...)
Packit Service dff8e4
{
Packit Service dff8e4
    va_list     ap;
Packit Service dff8e4
    const char *method_name;
Packit Service dff8e4
    char *      signal_name;
Packit Service dff8e4
    GCallback   handler;
Packit Service dff8e4
    GClosure *  closure;
Packit Service dff8e4
Packit Service dff8e4
    va_start(ap, skeleton);
Packit Service dff8e4
    while ((method_name = va_arg(ap, const char *)) && (handler = va_arg(ap, GCallback))) {
Packit Service dff8e4
        signal_name = signal_name_from_method_name(method_name);
Packit Service dff8e4
        closure     = g_cclosure_new_swap(handler, object, NULL);
Packit Service dff8e4
        g_closure_set_meta_marshal(closure, NULL, _nm_dbus_method_meta_marshal);
Packit Service dff8e4
        g_signal_connect_closure(skeleton, signal_name, closure, FALSE);
Packit Service dff8e4
        g_free(signal_name);
Packit Service dff8e4
    }
Packit Service dff8e4
    va_end(ap);
Packit Service dff8e4
}