Blame src/lib/problem_api_dbus.c

Packit 8ea169
/*
Packit 8ea169
    Copyright (C) 2011  ABRT Team
Packit 8ea169
    Copyright (C) 2011  RedHat inc.
Packit 8ea169
Packit 8ea169
    This program is free software; you can redistribute it and/or modify
Packit 8ea169
    it under the terms of the GNU General Public License as published by
Packit 8ea169
    the Free Software Foundation; either version 2 of the License, or
Packit 8ea169
    (at your option) any later version.
Packit 8ea169
Packit 8ea169
    This program is distributed in the hope that it will be useful,
Packit 8ea169
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8ea169
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8ea169
    GNU General Public License for more details.
Packit 8ea169
Packit 8ea169
    You should have received a copy of the GNU General Public License along
Packit 8ea169
    with this program; if not, write to the Free Software Foundation, Inc.,
Packit 8ea169
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 8ea169
*/
Packit 8ea169
Packit 8ea169
#include "abrt_glib.h"
Packit 8ea169
#include "internal_libabrt.h"
Packit 8ea169
Packit 8ea169
static GDBusProxy *get_dbus_proxy(void)
Packit 8ea169
{
Packit 8ea169
    static GDBusProxy *proxy;
Packit 8ea169
Packit 8ea169
    /* we cache it, so we can't free it! */
Packit 8ea169
    if (proxy != NULL)
Packit 8ea169
        return proxy;
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
Packit 8ea169
                                         G_DBUS_PROXY_FLAGS_NONE,
Packit 8ea169
                                         NULL,
Packit 8ea169
                                         ABRT_DBUS_NAME,
Packit 8ea169
                                         ABRT_DBUS_OBJECT,
Packit 8ea169
                                         ABRT_DBUS_IFACE,
Packit 8ea169
                                         NULL,
Packit 8ea169
                                         &error);
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't connect to system DBus: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        /* proxy is NULL in this case */
Packit 8ea169
    }
Packit 8ea169
    return proxy;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int chown_dir_over_dbus(const char *problem_dir_path)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return 1;
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                        "ChownProblemDir",
Packit 8ea169
                        g_variant_new("(s)", problem_dir_path),
Packit 8ea169
                        G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                        -1,
Packit 8ea169
                        NULL,
Packit 8ea169
                        &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't chown '%s': %s"), problem_dir_path, error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return 1;
Packit 8ea169
    }
Packit 8ea169
    return 0;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int delete_problem_dirs_over_dbus(const GList *problem_dir_paths)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return 1;
Packit 8ea169
Packit 8ea169
    GVariant *parameters = variant_from_string_list(problem_dir_paths);
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                    "DeleteProblem",
Packit 8ea169
                    parameters,
Packit 8ea169
                    G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                    -1,
Packit 8ea169
                    NULL,
Packit 8ea169
                    &error);
Packit 8ea169
//g_variant_unref(parameters); -- need this??? no?? why?
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Deleting problem directory failed: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return 1;
Packit 8ea169
    }
Packit 8ea169
    return 0;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int fill_problem_data_over_dbus(const char *problem_id, const char **elements, problem_data_t *problem_data)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return -1;
Packit 8ea169
Packit 8ea169
    GVariantBuilder *args_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
Packit 8ea169
Packit 8ea169
    for (const char **iter = elements; *iter; ++iter)
Packit 8ea169
        g_variant_builder_add(args_builder, "s", *iter);
Packit 8ea169
Packit 8ea169
    GVariant *params = g_variant_new("(sas)", problem_id, args_builder);
Packit 8ea169
    g_variant_builder_unref(args_builder);
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    GVariant *result = g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                                            "GetInfo",
Packit 8ea169
                                            params,
Packit 8ea169
                                            G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                                            -1,
Packit 8ea169
                                            NULL,
Packit 8ea169
                                            &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("D-Bus GetInfo method call failed: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return -2;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
Packit 8ea169
    char *key, *val;
Packit 8ea169
    GVariantIter *iter;
Packit 8ea169
    g_variant_get(result, "(a{ss})", &iter);
Packit 8ea169
    while (g_variant_iter_loop(iter, "{ss}", &key, &val))
Packit 8ea169
        problem_data_add_text_noteditable(problem_data, key, val);
Packit 8ea169
Packit 8ea169
    g_variant_unref(result);
Packit 8ea169
Packit 8ea169
    return 0;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    static const char *elements[] = {
Packit 8ea169
        FILENAME_TIME,
Packit 8ea169
        FILENAME_REASON,
Packit 8ea169
        FILENAME_NOT_REPORTABLE,
Packit 8ea169
        FILENAME_COMPONENT,
Packit 8ea169
        FILENAME_EXECUTABLE,
Packit 8ea169
        FILENAME_REPORTED_TO,
Packit 8ea169
        NULL,
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    problem_data_t *pd = problem_data_new();
Packit 8ea169
Packit 8ea169
    if (fill_problem_data_over_dbus(problem_dir_path, elements, pd) != 0)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't get problem data from abrt-dbus"));
Packit 8ea169
        problem_data_free(pd);
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return pd;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
GList *get_problems_over_dbus(bool authorize)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    GVariant *result = g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                                    authorize ? "GetAllProblems" : "GetProblems",
Packit 8ea169
                                    g_variant_new("()"),
Packit 8ea169
                                    G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                                    -1,
Packit 8ea169
                                    NULL,
Packit 8ea169
                                    &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't get problem list from abrt-dbus: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    GList *list = NULL;
Packit 8ea169
    if (result)
Packit 8ea169
    {
Packit 8ea169
        /* Fetch "as" from "(as)" */
Packit 8ea169
        GVariant *array = g_variant_get_child_value(result, 0);
Packit 8ea169
        list = string_list_from_variant(array);
Packit 8ea169
        g_variant_unref(array);
Packit 8ea169
        g_variant_unref(result);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return list;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
problem_data_t *get_full_problem_data_over_dbus(const char *problem_dir_path)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    GVariant *result = g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                                    "GetProblemData",
Packit 8ea169
                                    g_variant_new("(s)", problem_dir_path),
Packit 8ea169
                                    G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                                    -1,
Packit 8ea169
                                    NULL,
Packit 8ea169
                                    &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't get problem data from abrt-dbus: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    GVariantIter *iter = NULL;
Packit 8ea169
    g_variant_get(result, "(a{s(its)})", &iter);
Packit 8ea169
Packit 8ea169
    gchar *name = NULL;
Packit 8ea169
    gint flags;
Packit 8ea169
    gulong size;
Packit 8ea169
    gchar *value = NULL;
Packit 8ea169
Packit 8ea169
    problem_data_t *pd = problem_data_new();
Packit 8ea169
    while (g_variant_iter_loop(iter, "{&s(it&s)}", &name, &flags, &size, &value))
Packit 8ea169
        problem_data_add_ext(pd, name, value, flags, size);
Packit 8ea169
Packit 8ea169
    problem_data_add(pd, CD_DUMPDIR, problem_dir_path,
Packit 8ea169
            CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
Packit 8ea169
Packit 8ea169
    g_variant_unref(result);
Packit 8ea169
Packit 8ea169
    return pd;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int test_exist_over_dbus(const char *problem_id, const char *element_name)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return -1;
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    GVariant *result = g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                                            "TestElementExists",
Packit 8ea169
                                            g_variant_new("(ss)", problem_id, element_name),
Packit 8ea169
                                            G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                                            -1,
Packit 8ea169
                                            NULL,
Packit 8ea169
                                            &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't test whether the element exists over abrt-dbus: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return -1;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    gboolean retval;
Packit 8ea169
    g_variant_get(result, "(b)", &retval);
Packit 8ea169
    g_variant_unref(result);
Packit 8ea169
Packit 8ea169
    return retval;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int dbus_problem_is_complete(const char *problem_id)
Packit 8ea169
{
Packit 8ea169
    return test_exist_over_dbus(problem_id, FILENAME_COUNT);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
char *load_text_over_dbus(const char *problem_id, const char *element_name)
Packit 8ea169
{
Packit 8ea169
    INITIALIZE_LIBABRT();
Packit 8ea169
Packit 8ea169
    GDBusProxy *proxy = get_dbus_proxy();
Packit 8ea169
    if (!proxy)
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
Packit 8ea169
    GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
Packit 8ea169
    g_variant_builder_add(builder, "s", element_name);
Packit 8ea169
    GVariant *params = g_variant_new("(sas)", problem_id, builder);
Packit 8ea169
    g_variant_builder_unref(builder);
Packit 8ea169
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    GVariant *result = g_dbus_proxy_call_sync(proxy,
Packit 8ea169
                                            "GetInfo",
Packit 8ea169
                                            params,
Packit 8ea169
                                            G_DBUS_CALL_FLAGS_NONE,
Packit 8ea169
                                            -1,
Packit 8ea169
                                            NULL,
Packit 8ea169
                                            &error);
Packit 8ea169
Packit 8ea169
    if (error)
Packit 8ea169
    {
Packit 8ea169
        error_msg(_("Can't get problem data from abrt-dbus: %s"), error->message);
Packit 8ea169
        g_error_free(error);
Packit 8ea169
        return ERR_PTR;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    GVariant *values = g_variant_get_child_value(result, 0);
Packit 8ea169
    g_variant_unref(result);
Packit 8ea169
Packit 8ea169
    char *retval = NULL;
Packit 8ea169
    if (g_variant_n_children(values) == 1)
Packit 8ea169
    {
Packit 8ea169
        GVariant *contents = g_variant_get_child_value(values, 0);
Packit 8ea169
        gchar *key;
Packit 8ea169
        g_variant_get(contents, "{&ss}", &key, &retval);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    g_variant_unref(values);
Packit 8ea169
    return retval;
Packit 8ea169
}