Blame shared/nm-glib-aux/nm-dbus-aux.c

Packit Service 87a54e
/* SPDX-License-Identifier: LGPL-2.1-or-later */
Packit 5756e2
/*
Packit 5756e2
 * Copyright (C) 2019 Red Hat, Inc.
Packit 5756e2
 */
Packit 5756e2
Packit 5756e2
#include "nm-default.h"
Packit 5756e2
Packit 5756e2
#include "nm-dbus-aux.h"
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_nm_dbus_connection_call_get_name_owner_cb(GObject *source, GAsyncResult *res, gpointer user_data)
Packit 5756e2
{
Packit Service a1bd4f
    gs_unref_variant GVariant *ret           = NULL;
Packit Service a1bd4f
    gs_free_error GError *             error = NULL;
Packit Service a1bd4f
    const char *                       owner = NULL;
Packit Service a1bd4f
    gpointer                           orig_user_data;
Packit Service a1bd4f
    NMDBusConnectionCallGetNameOwnerCb callback;
Packit 5756e2
Packit Service a1bd4f
    nm_utils_user_data_unpack(user_data, &orig_user_data, &callback);
Packit 5756e2
Packit Service a1bd4f
    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
Packit Service a1bd4f
    if (ret)
Packit Service a1bd4f
        g_variant_get(ret, "(&s)", &owner);
Packit 5756e2
Packit Service a1bd4f
    callback(owner, error, orig_user_data);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_get_name_owner(GDBusConnection *                  dbus_connection,
Packit Service a1bd4f
                                       const char *                       service_name,
Packit Service a1bd4f
                                       int                                timeout_msec,
Packit Service a1bd4f
                                       GCancellable *                     cancellable,
Packit Service a1bd4f
                                       NMDBusConnectionCallGetNameOwnerCb callback,
Packit Service a1bd4f
                                       gpointer                           user_data)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(callback);
Packit Service a1bd4f
Packit Service a1bd4f
    g_dbus_connection_call(dbus_connection,
Packit Service a1bd4f
                           DBUS_SERVICE_DBUS,
Packit Service a1bd4f
                           DBUS_PATH_DBUS,
Packit Service a1bd4f
                           DBUS_INTERFACE_DBUS,
Packit Service a1bd4f
                           "GetNameOwner",
Packit Service a1bd4f
                           g_variant_new("(s)", service_name),
Packit Service a1bd4f
                           G_VARIANT_TYPE("(s)"),
Packit Service a1bd4f
                           G_DBUS_CALL_FLAGS_NONE,
Packit Service a1bd4f
                           timeout_msec,
Packit Service a1bd4f
                           cancellable,
Packit Service a1bd4f
                           _nm_dbus_connection_call_get_name_owner_cb,
Packit Service a1bd4f
                           nm_utils_user_data_pack(user_data, callback));
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_nm_dbus_connection_call_default_cb(GObject *source, GAsyncResult *res, gpointer user_data)
Packit 5756e2
{
Packit Service a1bd4f
    gs_unref_variant GVariant *ret      = NULL;
Packit Service a1bd4f
    gs_free_error GError *        error = NULL;
Packit Service a1bd4f
    gpointer                      orig_user_data;
Packit Service a1bd4f
    NMDBusConnectionCallDefaultCb callback;
Packit 5756e2
Packit Service a1bd4f
    nm_utils_user_data_unpack(user_data, &orig_user_data, &callback);
Packit 5756e2
Packit Service a1bd4f
    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
Packit 5756e2
Packit Service a1bd4f
    nm_assert((!!ret) != (!!error));
Packit 5756e2
Packit Service a1bd4f
    callback(ret, error, orig_user_data);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_get_all(GDBusConnection *             dbus_connection,
Packit Service a1bd4f
                                const char *                  bus_name,
Packit Service a1bd4f
                                const char *                  object_path,
Packit Service a1bd4f
                                const char *                  interface_name,
Packit Service a1bd4f
                                int                           timeout_msec,
Packit Service a1bd4f
                                GCancellable *                cancellable,
Packit Service a1bd4f
                                NMDBusConnectionCallDefaultCb callback,
Packit Service a1bd4f
                                gpointer                      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(callback);
Packit Service a1bd4f
Packit Service a1bd4f
    g_dbus_connection_call(dbus_connection,
Packit Service a1bd4f
                           bus_name,
Packit Service a1bd4f
                           object_path,
Packit Service a1bd4f
                           DBUS_INTERFACE_PROPERTIES,
Packit Service a1bd4f
                           "GetAll",
Packit Service a1bd4f
                           g_variant_new("(s)", interface_name),
Packit Service a1bd4f
                           G_VARIANT_TYPE("(a{sv})"),
Packit Service a1bd4f
                           G_DBUS_CALL_FLAGS_NONE,
Packit Service a1bd4f
                           timeout_msec,
Packit Service a1bd4f
                           cancellable,
Packit Service a1bd4f
                           _nm_dbus_connection_call_default_cb,
Packit Service a1bd4f
                           nm_utils_user_data_pack(user_data, callback));
Packit 5756e2
}
Packit 5756e2
Packit Service a1bd4f
void
Packit Service a1bd4f
nm_dbus_connection_call_set(GDBusConnection *             dbus_connection,
Packit Service a1bd4f
                            const char *                  bus_name,
Packit Service a1bd4f
                            const char *                  object_path,
Packit Service a1bd4f
                            const char *                  interface_name,
Packit Service a1bd4f
                            const char *                  property_name,
Packit Service a1bd4f
                            GVariant *                    value,
Packit Service a1bd4f
                            int                           timeout_msec,
Packit Service a1bd4f
                            GCancellable *                cancellable,
Packit Service a1bd4f
                            NMDBusConnectionCallDefaultCb callback,
Packit Service a1bd4f
                            gpointer                      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    g_dbus_connection_call(dbus_connection,
Packit Service a1bd4f
                           bus_name,
Packit Service a1bd4f
                           object_path,
Packit Service a1bd4f
                           DBUS_INTERFACE_PROPERTIES,
Packit Service a1bd4f
                           "Set",
Packit Service a1bd4f
                           g_variant_new("(ssv)", interface_name, property_name, value),
Packit Service a1bd4f
                           G_VARIANT_TYPE("()"),
Packit Service a1bd4f
                           G_DBUS_CALL_FLAGS_NONE,
Packit Service a1bd4f
                           timeout_msec,
Packit Service a1bd4f
                           cancellable,
Packit Service a1bd4f
                           callback ? _nm_dbus_connection_call_default_cb : NULL,
Packit Service a1bd4f
                           callback ? nm_utils_user_data_pack(user_data, callback) : NULL);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_nm_dbus_connection_call_get_managed_objects_cb(GObject *     source,
Packit Service a1bd4f
                                                GAsyncResult *res,
Packit Service a1bd4f
                                                gpointer      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    gs_unref_variant GVariant *ret      = NULL;
Packit Service a1bd4f
    gs_unref_variant GVariant *arg      = NULL;
Packit Service a1bd4f
    gs_free_error GError *        error = NULL;
Packit Service a1bd4f
    gpointer                      orig_user_data;
Packit Service a1bd4f
    NMDBusConnectionCallDefaultCb callback;
Packit 5756e2
Packit Service a1bd4f
    nm_utils_user_data_unpack(user_data, &orig_user_data, &callback);
Packit 5756e2
Packit Service a1bd4f
    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
Packit 5756e2
Packit Service a1bd4f
    nm_assert((!!ret) != (!!error));
Packit 5756e2
Packit Service a1bd4f
    if (ret) {
Packit Service a1bd4f
        nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("(a{oa{sa{sv}}})")));
Packit Service a1bd4f
        arg = g_variant_get_child_value(ret, 0);
Packit Service a1bd4f
    }
Packit 5756e2
Packit Service a1bd4f
    callback(arg, error, orig_user_data);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_get_managed_objects(GDBusConnection *             dbus_connection,
Packit Service a1bd4f
                                            const char *                  bus_name,
Packit Service a1bd4f
                                            const char *                  object_path,
Packit Service a1bd4f
                                            GDBusCallFlags                flags,
Packit Service a1bd4f
                                            int                           timeout_msec,
Packit Service a1bd4f
                                            GCancellable *                cancellable,
Packit Service a1bd4f
                                            NMDBusConnectionCallDefaultCb callback,
Packit Service a1bd4f
                                            gpointer                      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(callback);
Packit Service a1bd4f
Packit Service a1bd4f
    g_dbus_connection_call(dbus_connection,
Packit Service a1bd4f
                           bus_name,
Packit Service a1bd4f
                           object_path,
Packit Service a1bd4f
                           DBUS_INTERFACE_OBJECT_MANAGER,
Packit Service a1bd4f
                           "GetManagedObjects",
Packit Service a1bd4f
                           NULL,
Packit Service a1bd4f
                           G_VARIANT_TYPE("(a{oa{sa{sv}}})"),
Packit Service a1bd4f
                           flags,
Packit Service a1bd4f
                           timeout_msec,
Packit Service a1bd4f
                           cancellable,
Packit Service a1bd4f
                           _nm_dbus_connection_call_get_managed_objects_cb,
Packit Service a1bd4f
                           nm_utils_user_data_pack(user_data, callback));
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_call_finish_cb(GObject *     source,
Packit Service a1bd4f
                GAsyncResult *result,
Packit Service a1bd4f
                gpointer      user_data,
Packit Service a1bd4f
                gboolean      return_void,
Packit Service a1bd4f
                gboolean      strip_dbus_error)
Packit 5756e2
{
Packit Service a1bd4f
    gs_unref_object GTask *task      = user_data;
Packit Service a1bd4f
    gs_unref_variant GVariant *ret   = NULL;
Packit Service a1bd4f
    GError *                   error = NULL;
Packit Service a1bd4f
Packit Service a1bd4f
    nm_assert(G_IS_DBUS_CONNECTION(source));
Packit Service a1bd4f
    nm_assert(G_IS_TASK(user_data));
Packit Service a1bd4f
Packit Service a1bd4f
    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
Packit Service a1bd4f
    if (!ret) {
Packit Service a1bd4f
        if (strip_dbus_error)
Packit Service a1bd4f
            g_dbus_error_strip_remote_error(error);
Packit Service a1bd4f
        g_task_return_error(task, error);
Packit Service a1bd4f
        return;
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    if (!return_void)
Packit Service a1bd4f
        g_task_return_pointer(task, g_steal_pointer(&ret), (GDestroyNotify) g_variant_unref);
Packit Service a1bd4f
    else {
Packit Service a1bd4f
        nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("()")));
Packit Service a1bd4f
        g_task_return_boolean(task, TRUE);
Packit Service a1bd4f
    }
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/**
Packit 5756e2
 * nm_dbus_connection_call_finish_void_cb:
Packit 5756e2
 *
Packit 5756e2
 * A default callback to pass as callback to g_dbus_connection_call().
Packit 5756e2
 *
Packit 5756e2
 * - user_data must be a GTask, whose reference will be consumed by the
Packit 5756e2
 *   callback.
Packit 5756e2
 * - the return GVariant must be a empty tuple "()".
Packit 5756e2
 * - the GTask is returned either with error or TRUE boolean.
Packit 5756e2
 */
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_finish_void_cb(GObject *source, GAsyncResult *result, gpointer user_data)
Packit 5756e2
{
Packit Service a1bd4f
    _call_finish_cb(source, result, user_data, TRUE, FALSE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/**
Packit 5756e2
 * nm_dbus_connection_call_finish_void_strip_dbus_error_cb:
Packit 5756e2
 *
Packit 5756e2
 * Like nm_dbus_connection_call_finish_void_cb(). The difference
Packit 5756e2
 * is that on error this will first call g_dbus_error_strip_remote_error() on the error.
Packit 5756e2
 */
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_finish_void_strip_dbus_error_cb(GObject *     source,
Packit Service a1bd4f
                                                        GAsyncResult *result,
Packit Service a1bd4f
                                                        gpointer      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    _call_finish_cb(source, result, user_data, TRUE, TRUE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/**
Packit 5756e2
 * nm_dbus_connection_call_finish_variant_cb:
Packit 5756e2
 *
Packit 5756e2
 * A default callback to pass as callback to g_dbus_connection_call().
Packit 5756e2
 *
Packit 5756e2
 * - user_data must be a GTask, whose reference will be consumed by the
Packit 5756e2
 *   callback.
Packit 5756e2
 * - the GTask is returned either with error or with a pointer containing the GVariant.
Packit 5756e2
 */
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_finish_variant_cb(GObject *source, GAsyncResult *result, gpointer user_data)
Packit 5756e2
{
Packit Service a1bd4f
    _call_finish_cb(source, result, user_data, FALSE, FALSE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/**
Packit 5756e2
 * nm_dbus_connection_call_finish_variant_strip_dbus_error_cb:
Packit 5756e2
 *
Packit 5756e2
 * Like nm_dbus_connection_call_finish_variant_strip_dbus_error_cb(). The difference
Packit 5756e2
 * is that on error this will first call g_dbus_error_strip_remote_error() on the error.
Packit 5756e2
 */
Packit 5756e2
void
Packit Service a1bd4f
nm_dbus_connection_call_finish_variant_strip_dbus_error_cb(GObject *     source,
Packit Service a1bd4f
                                                           GAsyncResult *result,
Packit Service a1bd4f
                                                           gpointer      user_data)
Packit 5756e2
{
Packit Service a1bd4f
    _call_finish_cb(source, result, user_data, FALSE, TRUE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
gboolean
Packit Service a1bd4f
_nm_dbus_error_is(GError *error, ...)
Packit 5756e2
{
Packit Service a1bd4f
    gs_free char *dbus_error = NULL;
Packit Service a1bd4f
    const char *  name;
Packit Service a1bd4f
    va_list       ap;
Packit Service a1bd4f
Packit Service a1bd4f
    dbus_error = g_dbus_error_get_remote_error(error);
Packit Service a1bd4f
    if (!dbus_error)
Packit Service a1bd4f
        return FALSE;
Packit Service a1bd4f
Packit Service a1bd4f
    va_start(ap, error);
Packit Service a1bd4f
    while ((name = va_arg(ap, const char *))) {
Packit Service a1bd4f
        if (nm_streq(dbus_error, name)) {
Packit Service a1bd4f
            va_end(ap);
Packit Service a1bd4f
            return TRUE;
Packit Service a1bd4f
        }
Packit Service a1bd4f
    }
Packit Service a1bd4f
    va_end(ap);
Packit Service a1bd4f
Packit Service a1bd4f
    return FALSE;
Packit 5756e2
}