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