diff --git a/0001-doc-D-Bus-api-make-desc-of-DeleteProblem-clearer.patch b/0001-doc-D-Bus-api-make-desc-of-DeleteProblem-clearer.patch new file mode 100644 index 0000000..ee63ff1 --- /dev/null +++ b/0001-doc-D-Bus-api-make-desc-of-DeleteProblem-clearer.patch @@ -0,0 +1,26 @@ +From e45d05fa7072e52362981cef02fa8429365e14af Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Thu, 19 Mar 2015 17:15:31 +0100 +Subject: [PATCH] doc: D-Bus api: make desc of DeleteProblem clearer + +Signed-off-by: Matej Habrnal +--- + doc/problems-service/org.freedesktop.Problems.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/doc/problems-service/org.freedesktop.Problems.xml.in b/doc/problems-service/org.freedesktop.Problems.xml.in +index 6fcd990..38ee5b6 100644 +--- a/doc/problems-service/org.freedesktop.Problems.xml.in ++++ b/doc/problems-service/org.freedesktop.Problems.xml.in +@@ -274,7 +274,7 @@ for prblmid in problems.GetProblems(): + + + +- Deletes a specified problem. ++ Deletes specified problems. The problems are specified as array of problem_dir. + + + An identifier of problem to be deleted. +-- +2.3.2 + diff --git a/0002-applet-get-the-list-of-problems-through-D-Bus-servic.patch b/0002-applet-get-the-list-of-problems-through-D-Bus-servic.patch new file mode 100644 index 0000000..11ced0f --- /dev/null +++ b/0002-applet-get-the-list-of-problems-through-D-Bus-servic.patch @@ -0,0 +1,293 @@ +From 57895ccd0c6289faada8e5f3327e276ffded46b5 Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Thu, 19 Mar 2015 08:35:38 +0100 +Subject: [PATCH] applet: get the list of problems through D-Bus service + +The default dump location directory is not iterable for regular users. + +v2: +problem_create_app_from_env() will return NULL if envp is NULL, so there +is no need to check pi->envp to NULL. + +V3: +unref g_problems_proxy + +Signed-off-by: Jakub Filak +--- + src/applet/applet.c | 143 +++++++++++++++++++++++++++++++++------------------- + 1 file changed, 92 insertions(+), 51 deletions(-) + +diff --git a/src/applet/applet.c b/src/applet/applet.c +index d6d581a..b471dbc 100644 +--- a/src/applet/applet.c ++++ b/src/applet/applet.c +@@ -36,6 +36,14 @@ + #include "libabrt.h" + #include "problem_api.h" + ++/* 5s timeout*/ ++#define ORG_FREEDESKTOP_PROBLEMS_CALL_DEFAULT_TIMEOUT 5000 ++ ++#define ORG_FREEDESKTOP_PROBLEMS_BUS "org.freedesktop.problems" ++#define ORG_FREEDESKTOP_PROBLEMS_OBJECT "/org/freedesktop/problems" ++#define ORG_FREEDESKTOP_PROBLEMS_INTERFACE "org.freedesktop.problems" ++#define ORG_FREEDESKTOP_PROBLEMS_NAMESPACE(member) "org.freedesktop.problems."member ++ + /* libnotify action keys */ + #define A_REPORT_REPORT "REPORT" + #define A_RESTART_APPLICATION "RESTART" +@@ -44,8 +52,8 @@ + + #define NOTIFICATION_ICON_NAME "face-sad-symbolic" + ++static GDBusProxy *g_problems_proxy; + static GNetworkMonitor *netmon; +-static char **s_dirs; + static GList *g_deferred_crash_queue; + static guint g_deferred_timeout; + static bool g_gnome_abrt_available; +@@ -110,7 +118,6 @@ typedef struct problem_info { + bool foreign; + guint count; + bool is_packaged; +- char *command_line; + char **envp; + pid_t pid; + bool known; +@@ -129,6 +136,11 @@ static const char *problem_info_get_dir(problem_info_t *pi) + return problem_data_get_content_or_NULL(pi->problem_data, CD_DUMPDIR); + } + ++static const char *problem_info_get_command_line(problem_info_t *pi) ++{ ++ return problem_data_get_content_or_NULL(pi->problem_data, FILENAME_CMDLINE); ++} ++ + static void problem_info_set_dir(problem_info_t *pi, const char *dir) + { + problem_data_add_text_noteditable(pi->problem_data, CD_DUMPDIR, dir); +@@ -186,7 +198,6 @@ static void problem_info_unref(gpointer data) + return; + + problem_data_free(pi->problem_data); +- g_free(pi->command_line); + if (pi->envp) + g_strfreev(pi->envp); + g_free(pi); +@@ -200,6 +211,57 @@ static problem_info_t* problem_info_ref(problem_info_t *pi) + return pi; + } + ++static GVariant *dbus_call_sync(GDBusProxy *proxy, const gchar *method, GVariant *args) ++{ ++ GError *error = NULL; ++ GVariant *const resp = g_dbus_proxy_call_sync(proxy, ++ method, ++ args, ++ G_DBUS_PROXY_FLAGS_NONE, ++ ORG_FREEDESKTOP_PROBLEMS_CALL_DEFAULT_TIMEOUT, ++ /* GCancellable */ NULL, ++ &error); ++ if (error) ++ { ++ error_msg(_("Can't call method '%s' over DBus on path '%s' interface '%s': %s"), ++ method, ++ g_dbus_proxy_get_object_path(proxy), ++ g_dbus_proxy_get_interface_name(proxy), ++ error->message); ++ g_error_free(error); ++ /* resp is NULL in this case */ ++ } ++ ++ ++ return resp; ++} ++ ++static int ofd_problems_get_problems(GList **problems) ++{ ++ /* GetProblems ( IN , OUT as) */ ++ GVariant *dbus_res = dbus_call_sync(g_problems_proxy, "GetProblems", NULL); ++ ++ if (dbus_res == NULL) ++ return -1; ++ ++ GVariant *resp = g_variant_get_child_value(dbus_res, 0); ++ g_variant_unref(dbus_res); ++ ++ const gsize n_results = g_variant_n_children(resp); ++ for (gsize child = 0; child < n_results; ++child) ++ { ++ GVariant *const problem_id = g_variant_get_child_value(resp, child); ++ ++ *problems = g_list_prepend(*problems, g_variant_dup_string(problem_id, NULL)); ++ ++ g_variant_unref(problem_id); ++ } ++ ++ g_variant_unref(resp); ++ ++ return 0; ++} ++ + static void run_event_async(problem_info_t *pi, const char *event_name); + + struct event_processing_state +@@ -230,29 +292,6 @@ static void free_event_processing_state(struct event_processing_state *p) + g_free(p); + } + +-static GList *add_dirs_to_dirlist(GList *dirlist, const char *dirname) +-{ +- DIR *dir = opendir(dirname); +- if (!dir) +- return dirlist; +- +- struct dirent *dent; +- while ((dent = readdir(dir)) != NULL) +- { +- if (dot_or_dotdot(dent->d_name)) +- continue; +- char *full_name = concat_path_file(dirname, dent->d_name); +- struct stat statbuf; +- if (lstat(full_name, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) +- dirlist = g_list_prepend(dirlist, full_name); +- else +- free(full_name); +- } +- closedir(dir); +- +- return g_list_reverse(dirlist); +-} +- + /* Compares the problem directories to list saved in + * $XDG_CACHE_HOME/abrt/applet_dirlist and updates the applet_dirlist + * with updated list. +@@ -263,12 +302,10 @@ static GList *add_dirs_to_dirlist(GList *dirlist, const char *dirname) + static void new_dir_exists(GList **new_dirs) + { + GList *dirlist = NULL; +- char **pp = s_dirs; +- while (*pp) ++ if (ofd_problems_get_problems(&dirlist) != 0) + { +- log_notice("Looking for crashes in %s", *pp); +- dirlist = add_dirs_to_dirlist(dirlist, *pp); +- pp++; ++ error_msg(_("Failed to get the problem list from Problems D-Bus service.")); ++ return; + } + + const char *cachedir = g_get_user_cache_dir(); +@@ -484,7 +521,7 @@ static void action_restart(NotifyNotification *notification, gchar *action, gpoi + } + + problem_info_t *pi = (problem_info_t *)user_data; +- app = problem_create_app_from_cmdline (pi->command_line); ++ app = problem_create_app_from_cmdline (problem_info_get_command_line(pi)); + g_assert (app); + + if (!g_app_info_launch(G_APP_INFO(app), NULL, NULL, &err)) +@@ -575,8 +612,9 @@ static void notify_problem_list(GList *problems) + } + + app = problem_create_app_from_env ((const char **)pi->envp, pi->pid); ++ + if (!app) +- app = problem_create_app_from_cmdline (pi->command_line); ++ app = problem_create_app_from_cmdline (problem_info_get_command_line(pi)); + + /* For each problem we'll need to know: + * - Whether or not the crash happened in an “app” +@@ -653,7 +691,7 @@ static void notify_problem_list(GList *problems) + } + else + { +- char *binary = problem_get_argv0 (pi->command_line); ++ char *binary = problem_get_argv0 (problem_info_get_command_line(pi)); + notify_body = g_strdup_printf (_("We're sorry, it looks like %s crashed. Please contact the developer if you want to report the issue."), + binary); + g_free (binary); +@@ -950,10 +988,11 @@ static void Crash(GVariant *parameters) + problem_data_add_text_noteditable(pi->problem_data, FILENAME_DUPHASH, duphash); + if (package_name != NULL && package_name[0] != '\0') + problem_data_add_text_noteditable(pi->problem_data, FILENAME_COMPONENT, package_name); ++ if (command_line != NULL) ++ problem_data_add_text_noteditable(pi->problem_data, FILENAME_CMDLINE, command_line); + pi->foreign = foreign_problem; + pi->count = count; + pi->is_packaged = (package_name != NULL); +- pi->command_line = g_strdup(command_line); + pi->envp = (env != NULL) ? g_strsplit (env, "\n", -1) : NULL; + pi->pid = (pid != NULL) ? atoi (pid) : -1; + free(command_line); +@@ -1017,7 +1056,7 @@ name_acquired_handler (GDBusConnection *connection, + if (!dd_exist(dd, FILENAME_REPORTED_TO)) + { + problem_info_t *pi = problem_info_new(new_dirs->data); +- const char *elements[] = {FILENAME_UUID, FILENAME_DUPHASH, FILENAME_COMPONENT, FILENAME_NOT_REPORTABLE}; ++ const char *elements[] = {FILENAME_UUID, FILENAME_DUPHASH, FILENAME_COMPONENT, FILENAME_NOT_REPORTABLE, FILENAME_CMDLINE}; + + for (size_t i = 0; i < sizeof(elements)/sizeof(*elements); ++i) + { +@@ -1125,19 +1164,6 @@ int main(int argc, char** argv) + load_event_config_data(); + load_user_settings("abrt-applet"); + +- const char *default_dirs[] = { +- g_settings_dump_location, +- NULL, +- NULL, +- }; +- argv += optind; +- if (!argv[0]) +- { +- default_dirs[1] = concat_path_file(g_get_user_cache_dir(), "abrt/spool"); +- argv = (char**)default_dirs; +- } +- s_dirs = argv; +- + /* Initialize our (dbus_abrt) machinery by filtering + * for signals: + * signal sender=:1.73 -> path=/org/freedesktop/problems; interface=org.freedesktop.problems; member=Crash +@@ -1151,14 +1177,27 @@ int main(int argc, char** argv) + perror_msg_and_die("Can't connect to system dbus: %s", error->message); + guint filter_id = g_dbus_connection_signal_subscribe(system_conn, + NULL, +- "org.freedesktop.problems", ++ ORG_FREEDESKTOP_PROBLEMS_BUS, + "Crash", +- "/org/freedesktop/problems", ++ ORG_FREEDESKTOP_PROBLEMS_OBJECT, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + handle_message, + NULL, NULL); + ++ g_problems_proxy = g_dbus_proxy_new_sync(system_conn, ++ G_DBUS_PROXY_FLAGS_NONE, ++ /* GDBusInterfaceInfo */ NULL, ++ ORG_FREEDESKTOP_PROBLEMS_BUS, ++ ORG_FREEDESKTOP_PROBLEMS_OBJECT, ++ ORG_FREEDESKTOP_PROBLEMS_INTERFACE, ++ /* GCancellable */ NULL, ++ &error); ++ if (g_problems_proxy == NULL) ++ perror_msg_and_die(_("Can't connect ot DBus bus '"ORG_FREEDESKTOP_PROBLEMS_BUS \ ++ "' path '"ORG_FREEDESKTOP_PROBLEMS_OBJECT \ ++ "' interface '"ORG_FREEDESKTOP_PROBLEMS_INTERFACE"': %s"), error->message); ++ + guint name_own_id = g_bus_own_name (G_BUS_TYPE_SESSION, + ABRT_DBUS_NAME".applet", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE, +@@ -1198,6 +1237,8 @@ int main(int argc, char** argv) + */ + new_dir_exists(/* new dirs list */ NULL); + ++ g_object_unref(g_problems_proxy); ++ + if (notify_is_initted()) + notify_uninit(); + +-- +2.3.2 + diff --git a/0003-applet-fix-freeing-of-the-notify-problem-list.patch b/0003-applet-fix-freeing-of-the-notify-problem-list.patch new file mode 100644 index 0000000..a170f93 --- /dev/null +++ b/0003-applet-fix-freeing-of-the-notify-problem-list.patch @@ -0,0 +1,81 @@ +From 25a3f7f6f61e387d903e4e1547ad91184131dd8e Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Thu, 19 Mar 2015 13:58:16 +0100 +Subject: [PATCH] applet: fix freeing of the notify problem list + +The functions that process the list also frees the list. + +Signed-off-by: Jakub Filak +--- + src/applet/applet.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/src/applet/applet.c b/src/applet/applet.c +index b471dbc..0cf9b49 100644 +--- a/src/applet/applet.c ++++ b/src/applet/applet.c +@@ -87,11 +87,17 @@ static bool is_networking_enabled(void) + static void show_problem_list_notification(GList *problems); + static void problem_info_unref(gpointer data); + +-static gboolean process_deferred_queue_timeout_fn(GList *queue) ++static gboolean process_deferred_queue_timeout_fn(void) + { + g_deferred_timeout = 0; +- show_problem_list_notification(queue); +- g_list_free_full (queue, problem_info_unref); ++ ++ GList *tmp = g_deferred_crash_queue; ++ g_deferred_crash_queue = NULL; ++ ++ /* this function calls push_to_deferred_queue() which appends data to ++ * g_deferred_crash_queue but the function also modifies the argument ++ * so we must reset g_deferred_crash_queue before the call */ ++ show_problem_list_notification(tmp); + + /* Remove this timeout fn from the main loop*/ + return G_SOURCE_REMOVE; +@@ -107,8 +113,7 @@ static void connectivity_changed_cb(GObject *gobject, + if (g_deferred_timeout) + g_source_remove(g_deferred_timeout); + +- g_deferred_timeout = g_idle_add ((GSourceFunc)process_deferred_queue_timeout_fn, +- g_deferred_crash_queue); ++ g_deferred_timeout = g_idle_add ((GSourceFunc)process_deferred_queue_timeout_fn, NULL); + } + } + +@@ -583,6 +588,9 @@ add_restart_app_button (NotifyNotification *notification, + problem_info_ref (pi), problem_info_unref); + } + ++/* ++ * Destroys the problems argument ++ */ + static void notify_problem_list(GList *problems) + { + if (problems == NULL) +@@ -890,6 +898,9 @@ static void run_event_async(problem_info_t *pi, const char *event_name) + handle_event_output_cb, state); + } + ++/* ++ * Destroys the problems argument ++ */ + static void show_problem_list_notification(GList *problems) + { + if (is_autoreporting_enabled()) +@@ -1086,10 +1097,7 @@ next: + } + + if (notify_list) +- { + show_problem_list_notification(notify_list); +- g_list_free_full (notify_list, problem_info_unref); +- } + + list_free_with_free(new_dirs); + +-- +2.3.2 + diff --git a/abrt.spec b/abrt.spec index 692f923..52cc3d1 100644 --- a/abrt.spec +++ b/abrt.spec @@ -46,7 +46,7 @@ Summary: Automatic bug detection and reporting tool Name: abrt Version: 2.5.0 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ Group: Applications/System URL: https://github.com/abrt/abrt/wiki/ABRT-Project @@ -55,7 +55,10 @@ Source: https://fedorahosted.org/released/%{name}/%{name}-%{version}.tar.gz Patch0: disable-OpenGPGCheck-in-Fedora-Rawhide.patch # git format-patch %%{Version} --topo-order -N -M; -# for p in `ls 0*.patch`; do printf "Patch%04d: %s\n" $i $p; ((i++)); done +# i=1; for p in `ls 0*.patch`; do printf "Patch%04d: %s\n" $i $p; ((i++)); done +Patch0001: 0001-doc-D-Bus-api-make-desc-of-DeleteProblem-clearer.patch +Patch0002: 0002-applet-get-the-list-of-problems-through-D-Bus-servic.patch +Patch0003: 0003-applet-fix-freeing-of-the-notify-problem-list.patch # '%%autosetup -S git' -> git BuildRequires: git @@ -1024,6 +1027,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %config(noreplace) %{_sysconfdir}/profile.d/abrt-console-notification.sh %changelog +* Fri Mar 20 2015 Jakub Filak 2.5.0-2 +- applet: re-enable notifications of problems not-yet seen problems at start-up + * Wed Mar 18 2015 Jakub Filak 2.5.0-1 - dbus: add a new method GetProblemData - abrt_event: run save package data event even if component exists