Blame src/utils/dbus.c

Packit Service 158247
/*
Packit Service 158247
 * Copyright (C) 2018  Red Hat, Inc.
Packit Service 158247
 *
Packit Service 158247
 * This library is free software; you can redistribute it and/or
Packit Service 158247
 * modify it under the terms of the GNU Lesser General Public
Packit Service 158247
 * License as published by the Free Software Foundation; either
Packit Service 158247
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 158247
 *
Packit Service 158247
 * This library is distributed in the hope that it will be useful,
Packit Service 158247
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 158247
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 158247
 * Lesser General Public License for more details.
Packit Service 158247
 *
Packit Service 158247
 * You should have received a copy of the GNU Lesser General Public
Packit Service 158247
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service 158247
 *
Packit Service 158247
 * Author: Vojtech Trefny <vtrefny@redhat.com>
Packit Service 158247
 */
Packit Service 158247
Packit Service 158247
#include <glib.h>
Packit Service 158247
#include <gio/gio.h>
Packit Service 158247
Packit Service 158247
#include "dbus.h"
Packit Service 158247
Packit Service 158247
#define DBUS_TOP_IFACE "org.freedesktop.DBus"
Packit Service 158247
#define DBUS_TOP_OBJ "/org/freedesktop/DBus"
Packit Service 158247
#define DBUS_PROPS_IFACE "org.freedesktop.DBus.Properties"
Packit Service 158247
#define DBUS_INTRO_IFACE "org.freedesktop.DBus.Introspectable"
Packit Service 158247
Packit Service 158247
Packit Service 158247
/**
Packit Service 158247
 * bd_utils_dbus_error_quark: (skip)
Packit Service 158247
 */
Packit Service 158247
GQuark bd_utils_dbus_error_quark (void)
Packit Service 158247
{
Packit Service 158247
    return g_quark_from_static_string ("g-bd-utils-dbus-error-quark");
Packit Service 158247
}
Packit Service 158247
Packit Service 158247
/**
Packit Service 158247
 * bd_utils_dbus_service_available:
Packit Service 158247
 * @connection: (allow-none): existing GDBusConnection or %NULL
Packit Service 158247
 * @bus_type: bus type (system or session), ignored if @connection is specified
Packit Service 158247
 * @bus_name: name of the service to check (e.g. "com.redhat.lvmdbus1")
Packit Service 158247
 * @obj_prefix: object path prefix for the service (e.g. "/com/redhat/lvmdbus1")
Packit Service 158247
 * @error: (out): place to store error (if any)
Packit Service 158247
 *
Packit Service 158247
 * Returns: whether the service was found in the system
Packit Service 158247
 */
Packit Service 158247
gboolean bd_utils_dbus_service_available (GDBusConnection *connection, GBusType bus_type, const gchar *bus_name, const gchar *obj_prefix, GError **error) {
Packit Service 158247
    GVariant *ret = NULL;
Packit Service 158247
    GVariant *real_ret = NULL;
Packit Service 158247
    GVariantIter iter;
Packit Service 158247
    GVariant *service = NULL;
Packit Service 158247
    gboolean found = FALSE;
Packit Service 158247
    GDBusConnection *bus = NULL;
Packit Service 158247
Packit Service 158247
    if (connection)
Packit Service 158247
        bus = g_object_ref (connection);
Packit Service 158247
    else {
Packit Service 158247
        bus = g_bus_get_sync (bus_type, NULL, error);
Packit Service 158247
        if (!bus) {
Packit Service 158247
            g_critical ("Failed to get system bus: %s\n", (*error)->message);
Packit Service 158247
            return FALSE;
Packit Service 158247
        }
Packit Service 158247
Packit Service 158247
        ret = g_dbus_connection_call_sync (bus, DBUS_TOP_IFACE, DBUS_TOP_OBJ, DBUS_TOP_IFACE,
Packit Service 158247
                                           "ListNames", NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
Packit Service 158247
                                           -1, NULL, error);
Packit Service 158247
        if (!ret) {
Packit Service 158247
            g_object_unref (bus);
Packit Service 158247
            return FALSE;
Packit Service 158247
        }
Packit Service 158247
    }
Packit Service 158247
Packit Service 158247
    real_ret = g_variant_get_child_value (ret, 0);
Packit Service 158247
    g_variant_unref (ret);
Packit Service 158247
Packit Service 158247
    g_variant_iter_init (&iter, real_ret);
Packit Service 158247
    while (!found && (service = g_variant_iter_next_value (&iter))) {
Packit Service 158247
        found = (g_strcmp0 (g_variant_get_string (service, NULL), bus_name) == 0);
Packit Service 158247
        g_variant_unref (service);
Packit Service 158247
    }
Packit Service 158247
    g_variant_unref (real_ret);
Packit Service 158247
Packit Service 158247
    ret = g_dbus_connection_call_sync (bus, DBUS_TOP_IFACE, DBUS_TOP_OBJ, DBUS_TOP_IFACE,
Packit Service 158247
                                       "ListActivatableNames", NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
Packit Service 158247
                                       -1, NULL, error);
Packit Service 158247
    if (!ret) {
Packit Service 158247
        g_object_unref (bus);
Packit Service 158247
        return FALSE;
Packit Service 158247
    }
Packit Service 158247
Packit Service 158247
    real_ret = g_variant_get_child_value (ret, 0);
Packit Service 158247
    g_variant_unref (ret);
Packit Service 158247
Packit Service 158247
    g_variant_iter_init (&iter, real_ret);
Packit Service 158247
    while (!found && (service = g_variant_iter_next_value (&iter))) {
Packit Service 158247
        found = (g_strcmp0 (g_variant_get_string (service, NULL), bus_name) == 0);
Packit Service 158247
        g_variant_unref (service);
Packit Service 158247
    }
Packit Service 158247
    g_variant_unref (real_ret);
Packit Service 158247
Packit Service 158247
    if (!found) {
Packit Service 158247
        g_object_unref (bus);
Packit Service 158247
        return FALSE;
Packit Service 158247
    }
Packit Service 158247
Packit Service 158247
    /* try to introspect the root node - i.e. check we can access it and possibly
Packit Service 158247
       autostart the service */
Packit Service 158247
    ret = g_dbus_connection_call_sync (bus, bus_name, obj_prefix, DBUS_INTRO_IFACE,
Packit Service 158247
                                       "Introspect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
Packit Service 158247
                                       -1, NULL, error);
Packit Service 158247
    if (!ret) {
Packit Service 158247
        if (*error) {
Packit Service 158247
            g_object_unref (bus);
Packit Service 158247
            return FALSE;
Packit Service 158247
        } else {
Packit Service 158247
            g_object_unref (bus);
Packit Service 158247
            return TRUE;
Packit Service 158247
        }
Packit Service 158247
    } else
Packit Service 158247
        g_variant_unref (ret);
Packit Service 158247
Packit Service 158247
    g_object_unref (bus);
Packit Service 158247
    return TRUE;
Packit Service 158247
}