Matej Habrnal 34dad7
From a2977b0fe023a896c3006f27ee2b148690dff24a Mon Sep 17 00:00:00 2001
Matej Habrnal 34dad7
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal 34dad7
Date: Wed, 8 Apr 2015 08:23:03 +0200
Matej Habrnal 34dad7
Subject: [PATCH] applet: switch to D-Bus methods
Matej Habrnal 34dad7
Matej Habrnal 34dad7
This patch is a part of our efforts to make abrt-applet independent on
Matej Habrnal 34dad7
the backend.
Matej Habrnal 34dad7
Matej Habrnal 34dad7
This patch converts all data manipulation functions to D-Bus calls, so
Matej Habrnal 34dad7
the notifications are made of data obtained through D-Bus.
Matej Habrnal 34dad7
Matej Habrnal 34dad7
The reporting still relies on file system access, though.
Matej Habrnal 34dad7
Matej Habrnal 34dad7
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal 34dad7
---
Matej Habrnal 34dad7
 src/applet/applet.c        | 181 ++++++++++++++++++++++++++++-----------------
Matej Habrnal 34dad7
 src/include/libabrt.h      |  16 ++++
Matej Habrnal 34dad7
 src/lib/problem_api_dbus.c |  61 +++++++++++----
Matej Habrnal 34dad7
 3 files changed, 174 insertions(+), 84 deletions(-)
Matej Habrnal 34dad7
Matej Habrnal 34dad7
diff --git a/src/applet/applet.c b/src/applet/applet.c
Matej Habrnal 34dad7
index 7b58f6e..4df69fc 100644
Matej Habrnal 34dad7
--- a/src/applet/applet.c
Matej Habrnal 34dad7
+++ b/src/applet/applet.c
Matej Habrnal 34dad7
@@ -120,6 +120,7 @@ typedef struct problem_info {
Matej Habrnal 34dad7
     bool reported;
Matej Habrnal 34dad7
     bool was_announced;
Matej Habrnal 34dad7
     bool is_writable;
Matej Habrnal 34dad7
+    int time;
Matej Habrnal 34dad7
 } problem_info_t;
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
 static void push_to_deferred_queue(problem_info_t *pi)
Matej Habrnal 34dad7
@@ -137,6 +138,59 @@ static const char *problem_info_get_command_line(problem_info_t *pi)
Matej Habrnal 34dad7
     return problem_data_get_content_or_NULL(pi->problem_data, FILENAME_CMDLINE);
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
+static int problem_info_get_time(problem_info_t *pi)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    if (pi->time == -1)
Matej Habrnal 34dad7
+    {
Matej Habrnal 34dad7
+        const char *time_str = problem_data_get_content_or_NULL(pi->problem_data, FILENAME_TIME);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+        if (time_str == NULL)
Matej Habrnal 34dad7
+            error_msg_and_die("BUG: Problem info has data without the element time");
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+        pi->time = atoi(time_str);
Matej Habrnal 34dad7
+    }
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    return pi->time;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+static const char **problem_info_get_env(problem_info_t *pi)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    if (pi->envp == NULL)
Matej Habrnal 34dad7
+    {
Matej Habrnal 34dad7
+        const char *env_str = problem_data_get_content_or_NULL(pi->problem_data, FILENAME_ENVIRON);
Matej Habrnal 34dad7
+        pi->envp = (env_str != NULL) ? g_strsplit (env_str, "\n", -1) : NULL;
Matej Habrnal 34dad7
+    }
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    return (const char **)pi->envp;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+static int problem_info_get_pid(problem_info_t *pi)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    if (pi->pid == -1)
Matej Habrnal 34dad7
+    {
Matej Habrnal 34dad7
+        const char *pid_str = problem_data_get_content_or_NULL(pi->problem_data, FILENAME_PID);
Matej Habrnal 34dad7
+        pi->pid = (pid_str != NULL) ? atoi (pid_str) : -1;
Matej Habrnal 34dad7
+    }
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    return pi->pid;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+static int problem_info_get_count(problem_info_t *pi)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    if (pi->count == -1)
Matej Habrnal 34dad7
+    {
Matej Habrnal 34dad7
+        const char *count_str = problem_data_get_content_or_NULL(pi->problem_data, FILENAME_COUNT);
Matej Habrnal 34dad7
+        pi->count = count_str ? atoi(count_str) : 1;
Matej Habrnal 34dad7
+    }
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    return pi->count;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+static bool problem_info_is_reported(problem_info_t *pi)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    return problem_data_get_content_or_NULL(pi->problem_data, FILENAME_REPORTED_TO) != NULL;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
 static void problem_info_set_dir(problem_info_t *pi, const char *dir)
Matej Habrnal 34dad7
 {
Matej Habrnal 34dad7
     problem_data_add_text_noteditable(pi->problem_data, CD_DUMPDIR, dir);
Matej Habrnal 34dad7
@@ -176,6 +230,9 @@ static problem_info_t *problem_info_new(const char *dir)
Matej Habrnal 34dad7
 {
Matej Habrnal 34dad7
     problem_info_t *pi = g_new0(problem_info_t, 1);
Matej Habrnal 34dad7
     pi->refcount = 1;
Matej Habrnal 34dad7
+    pi->time = -1;
Matej Habrnal 34dad7
+    pi->pid = -1;
Matej Habrnal 34dad7
+    pi->count = -1;
Matej Habrnal 34dad7
     pi->problem_data = problem_data_new();
Matej Habrnal 34dad7
     problem_info_set_dir(pi, dir);
Matej Habrnal 34dad7
     return pi;
Matej Habrnal 34dad7
@@ -194,8 +251,6 @@ static void problem_info_unref(gpointer data)
Matej Habrnal 34dad7
         return;
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     problem_data_free(pi->problem_data);
Matej Habrnal 34dad7
-    if (pi->envp)
Matej Habrnal 34dad7
-        g_strfreev(pi->envp);
Matej Habrnal 34dad7
     g_free(pi);
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
@@ -556,7 +611,7 @@ static void notify_problem_list(GList *problems)
Matej Habrnal 34dad7
             continue;
Matej Habrnal 34dad7
         }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-        app = problem_create_app_from_env ((const char **)pi->envp, pi->pid);
Matej Habrnal 34dad7
+        app = problem_create_app_from_env (problem_info_get_env(pi), problem_info_get_pid(pi));
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
         if (!app)
Matej Habrnal 34dad7
             app = problem_create_app_from_cmdline (problem_info_get_command_line(pi));
Matej Habrnal 34dad7
@@ -572,7 +627,7 @@ static void notify_problem_list(GList *problems)
Matej Habrnal 34dad7
         gboolean is_packaged = pi->is_packaged;
Matej Habrnal 34dad7
         gboolean is_running_again = is_app_running(app);
Matej Habrnal 34dad7
         gboolean is_current_user = !pi->foreign;
Matej Habrnal 34dad7
-        gboolean already_reported = (pi->count > 1);
Matej Habrnal 34dad7
+        gboolean already_reported = problem_info_get_count(pi) > 1;
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
         gboolean report_button = FALSE;
Matej Habrnal 34dad7
         gboolean restart_button = FALSE;
Matej Habrnal 34dad7
@@ -914,14 +969,22 @@ static void Crash(GVariant *parameters)
Matej Habrnal 34dad7
     if (foreign_problem && !g_user_is_admin)
Matej Habrnal 34dad7
         return;
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-    struct dump_dir *dd = dd_opendir(dir, DD_OPEN_READONLY);
Matej Habrnal 34dad7
-    char *command_line = dd_load_text_ext(dd, FILENAME_CMDLINE, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
Matej Habrnal 34dad7
-    char *count_str = dd_load_text_ext(dd, FILENAME_COUNT, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
Matej Habrnal 34dad7
-    guint count = count_str ? atoi(count_str) : 1;
Matej Habrnal 34dad7
-    g_free(count_str);
Matej Habrnal 34dad7
-    char *env = dd_load_text_ext(dd, FILENAME_ENVIRON, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
Matej Habrnal 34dad7
-    char *pid = dd_load_text_ext(dd, FILENAME_PID, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
Matej Habrnal 34dad7
-    dd_close(dd);
Matej Habrnal 34dad7
+    static const char *elements[] = {
Matej Habrnal 34dad7
+        FILENAME_CMDLINE,
Matej Habrnal 34dad7
+        FILENAME_COUNT,
Matej Habrnal 34dad7
+        FILENAME_UUID,
Matej Habrnal 34dad7
+        FILENAME_DUPHASH,
Matej Habrnal 34dad7
+        FILENAME_COMPONENT,
Matej Habrnal 34dad7
+        FILENAME_ENVIRON,
Matej Habrnal 34dad7
+        FILENAME_PID,
Matej Habrnal 34dad7
+        NULL,
Matej Habrnal 34dad7
+    };
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    problem_info_t *pi = problem_info_new(dir);
Matej Habrnal 34dad7
+    fill_problem_data_over_dbus(dir, elements, pi->problem_data);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    pi->foreign = foreign_problem;
Matej Habrnal 34dad7
+    pi->is_packaged = (package_name != NULL);
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     /*
Matej Habrnal 34dad7
      * Can't append dir to the seen list because of directory stealing
Matej Habrnal 34dad7
@@ -929,24 +992,6 @@ static void Crash(GVariant *parameters)
Matej Habrnal 34dad7
      * append_dirlist(dir);
Matej Habrnal 34dad7
      *
Matej Habrnal 34dad7
      */
Matej Habrnal 34dad7
-
Matej Habrnal 34dad7
-    problem_info_t *pi = problem_info_new(dir);
Matej Habrnal 34dad7
-    if (uuid != NULL && uuid[0] != '\0')
Matej Habrnal 34dad7
-        problem_data_add_text_noteditable(pi->problem_data, FILENAME_UUID, uuid);
Matej Habrnal 34dad7
-    if (duphash != NULL && duphash[0] != '\0')
Matej Habrnal 34dad7
-        problem_data_add_text_noteditable(pi->problem_data, FILENAME_DUPHASH, duphash);
Matej Habrnal 34dad7
-    if (package_name != NULL && package_name[0] != '\0')
Matej Habrnal 34dad7
-        problem_data_add_text_noteditable(pi->problem_data, FILENAME_COMPONENT, package_name);
Matej Habrnal 34dad7
-    if (command_line != NULL)
Matej Habrnal 34dad7
-        problem_data_add_text_noteditable(pi->problem_data, FILENAME_CMDLINE, command_line);
Matej Habrnal 34dad7
-    pi->foreign = foreign_problem;
Matej Habrnal 34dad7
-    pi->count = count;
Matej Habrnal 34dad7
-    pi->is_packaged = (package_name != NULL);
Matej Habrnal 34dad7
-    pi->envp = (env != NULL) ? g_strsplit (env, "\n", -1) : NULL;
Matej Habrnal 34dad7
-    pi->pid = (pid != NULL) ? atoi (pid) : -1;
Matej Habrnal 34dad7
-    free(command_line);
Matej Habrnal 34dad7
-    free(env);
Matej Habrnal 34dad7
-    free(pid);
Matej Habrnal 34dad7
     show_problem_notification(pi);
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
@@ -970,6 +1015,19 @@ name_acquired_handler (GDBusConnection *connection,
Matej Habrnal 34dad7
                        const gchar *name,
Matej Habrnal 34dad7
                        gpointer user_data)
Matej Habrnal 34dad7
 {
Matej Habrnal 34dad7
+    static const char *elements[] = {
Matej Habrnal 34dad7
+        FILENAME_CMDLINE,
Matej Habrnal 34dad7
+        FILENAME_COUNT,
Matej Habrnal 34dad7
+        FILENAME_UUID,
Matej Habrnal 34dad7
+        FILENAME_DUPHASH,
Matej Habrnal 34dad7
+        FILENAME_COMPONENT,
Matej Habrnal 34dad7
+        FILENAME_UID,
Matej Habrnal 34dad7
+        FILENAME_TIME,
Matej Habrnal 34dad7
+        FILENAME_REPORTED_TO,
Matej Habrnal 34dad7
+        FILENAME_NOT_REPORTABLE,
Matej Habrnal 34dad7
+        NULL
Matej Habrnal 34dad7
+    };
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
     /* If some new dirs appeared since our last run, let user know it */
Matej Habrnal 34dad7
     GList *new_dirs = NULL;
Matej Habrnal 34dad7
     GList *notify_list = NULL;
Matej Habrnal 34dad7
@@ -980,58 +1038,45 @@ name_acquired_handler (GDBusConnection *connection,
Matej Habrnal 34dad7
     /* Age limit = now - 3 days */
Matej Habrnal 34dad7
     const unsigned long min_born_time = (unsigned long)(time_before_ndays(3));
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-    while (new_dirs)
Matej Habrnal 34dad7
+    for ( ; new_dirs != NULL; new_dirs = g_list_next(new_dirs))
Matej Habrnal 34dad7
     {
Matej Habrnal 34dad7
-        struct dump_dir *dd = dd_opendir((char *)new_dirs->data, DD_OPEN_READONLY);
Matej Habrnal 34dad7
-        if (dd == NULL)
Matej Habrnal 34dad7
+        const char *problem_id = (const char *)new_dirs->data;
Matej Habrnal 34dad7
+        problem_info_t *pi = problem_info_new(problem_id);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+        if (fill_problem_data_over_dbus(problem_id, elements, pi->problem_data) != 0)
Matej Habrnal 34dad7
         {
Matej Habrnal 34dad7
-            log_notice("'%s' is not a dump dir - ignoring\n", (char *)new_dirs->data);
Matej Habrnal 34dad7
-            new_dirs = g_list_next(new_dirs);
Matej Habrnal 34dad7
+            log_notice("'%s' is not a dump dir - ignoring\n", problem_id);
Matej Habrnal 34dad7
+            problem_info_unref(pi);
Matej Habrnal 34dad7
             continue;
Matej Habrnal 34dad7
         }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-        if (dd->dd_time < min_born_time)
Matej Habrnal 34dad7
+        /* TODO: add a filter for only complete problems to GetProblems D-Bus method */
Matej Habrnal 34dad7
+        if (!dbus_problem_is_complete(problem_id))
Matej Habrnal 34dad7
         {
Matej Habrnal 34dad7
-            log_notice("Ignoring outdated problem '%s'", (char *)new_dirs->data);
Matej Habrnal 34dad7
-            goto next;
Matej Habrnal 34dad7
+            log_notice("Ignoring incomplete problem '%s'", problem_id);
Matej Habrnal 34dad7
+            problem_info_unref(pi);
Matej Habrnal 34dad7
+            continue;
Matej Habrnal 34dad7
         }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-        if (!problem_dump_dir_is_complete(dd))
Matej Habrnal 34dad7
+        /* TODO: add a filter for max-old reported problems to GetProblems D-Bus method */
Matej Habrnal 34dad7
+        if (problem_info_get_time(pi) < min_born_time)
Matej Habrnal 34dad7
         {
Matej Habrnal 34dad7
-            log_notice("Ignoring incomplete problem '%s'", (char *)new_dirs->data);
Matej Habrnal 34dad7
-            goto next;
Matej Habrnal 34dad7
+            log_notice("Ignoring outdated problem '%s'", problem_id);
Matej Habrnal 34dad7
+            problem_info_unref(pi);
Matej Habrnal 34dad7
+            continue;
Matej Habrnal 34dad7
         }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-        if (!dd_exist(dd, FILENAME_REPORTED_TO))
Matej Habrnal 34dad7
+        /* TODO: add a filter for not-yet reported problems to GetProblems D-Bus method */
Matej Habrnal 34dad7
+        if (problem_info_is_reported(pi))
Matej Habrnal 34dad7
         {
Matej Habrnal 34dad7
-            problem_info_t *pi = problem_info_new(new_dirs->data);
Matej Habrnal 34dad7
-            const char *elements[] = {FILENAME_UUID, FILENAME_DUPHASH, FILENAME_COMPONENT, FILENAME_NOT_REPORTABLE, FILENAME_CMDLINE};
Matej Habrnal 34dad7
-
Matej Habrnal 34dad7
-            for (size_t i = 0; i < sizeof(elements)/sizeof(*elements); ++i)
Matej Habrnal 34dad7
-            {
Matej Habrnal 34dad7
-                char * const value = dd_load_text_ext(dd, elements[i],
Matej Habrnal 34dad7
-                        DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
Matej Habrnal 34dad7
-                if (value)
Matej Habrnal 34dad7
-                    problem_data_add_text_noteditable(pi->problem_data, elements[i], value);
Matej Habrnal 34dad7
-                free(value);
Matej Habrnal 34dad7
-            }
Matej Habrnal 34dad7
-
Matej Habrnal 34dad7
-            /* Can't be foreign because if the problem is foreign then the
Matej Habrnal 34dad7
-             * dd_opendir() call failed few lines above and the problem is ignored.
Matej Habrnal 34dad7
-             * */
Matej Habrnal 34dad7
-            pi->foreign = false;
Matej Habrnal 34dad7
-
Matej Habrnal 34dad7
-            notify_list = g_list_prepend(notify_list, pi);
Matej Habrnal 34dad7
-        }
Matej Habrnal 34dad7
-        else
Matej Habrnal 34dad7
-        {
Matej Habrnal 34dad7
-            log_notice("Ignoring already reported problem '%s'", (char *)new_dirs->data);
Matej Habrnal 34dad7
+            log_notice("Ignoring already reported problem '%s'", problem_id);
Matej Habrnal 34dad7
+            problem_info_unref(pi);
Matej Habrnal 34dad7
+            continue;
Matej Habrnal 34dad7
         }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-next:
Matej Habrnal 34dad7
-        dd_close(dd);
Matej Habrnal 34dad7
-
Matej Habrnal 34dad7
-        new_dirs = g_list_next(new_dirs);
Matej Habrnal 34dad7
+        /* Can't be foreig because new_dir_exists() returns only own problems */
Matej Habrnal 34dad7
+        pi->foreign = false;
Matej Habrnal 34dad7
+        notify_list = g_list_prepend(notify_list, pi);
Matej Habrnal 34dad7
     }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     if (notify_list)
Matej Habrnal 34dad7
diff --git a/src/include/libabrt.h b/src/include/libabrt.h
Matej Habrnal 34dad7
index 19ad4a8..07dc172 100644
Matej Habrnal 34dad7
--- a/src/include/libabrt.h
Matej Habrnal 34dad7
+++ b/src/include/libabrt.h
Matej Habrnal 34dad7
@@ -164,6 +164,15 @@ int chown_dir_over_dbus(const char *problem_dir_path);
Matej Habrnal 34dad7
 int test_exist_over_dbus(const char *problem_id, const char *element_name);
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
 /**
Matej Habrnal 34dad7
+  @brief Checks whether the problem corresponding to the given ID is complete
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+  Might require authorization
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+  @return Positive number if such the proble is complete, 0 if doesn't and negative number if an error occurs.
Matej Habrnal 34dad7
+ */
Matej Habrnal 34dad7
+int dbus_problem_is_complete(const char *problem_id);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+/**
Matej Habrnal 34dad7
   @ Returns value of the given element name
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
   Might require authorization
Matej Habrnal 34dad7
@@ -182,6 +191,13 @@ char *load_text_over_dbus(const char *problem_id, const char *element_name);
Matej Habrnal 34dad7
 int delete_problem_dirs_over_dbus(const GList *problem_dir_paths);
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
 /**
Matej Habrnal 34dad7
+  @brief Fetches given problem elements for specified problem id
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+  @return on failures returns non zero value and emits error message
Matej Habrnal 34dad7
+*/
Matej Habrnal 34dad7
+int fill_problem_data_over_dbus(const char *problem_dir_path, const char **elements, problem_data_t *problem_data);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+/**
Matej Habrnal 34dad7
   @brief Fetches problem information for specified problem id
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
   @return problem_data_t or NULL on failure
Matej Habrnal 34dad7
diff --git a/src/lib/problem_api_dbus.c b/src/lib/problem_api_dbus.c
Matej Habrnal 34dad7
index 5148932..ce5c47b 100644
Matej Habrnal 34dad7
--- a/src/lib/problem_api_dbus.c
Matej Habrnal 34dad7
+++ b/src/lib/problem_api_dbus.c
Matej Habrnal 34dad7
@@ -101,23 +101,21 @@ int delete_problem_dirs_over_dbus(const GList *problem_dir_paths)
Matej Habrnal 34dad7
     return 0;
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
Matej Habrnal 34dad7
+int fill_problem_data_over_dbus(const char *problem_id, const char **elements, problem_data_t *problem_data)
Matej Habrnal 34dad7
 {
Matej Habrnal 34dad7
     INITIALIZE_LIBABRT();
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     GDBusProxy *proxy = get_dbus_proxy();
Matej Habrnal 34dad7
     if (!proxy)
Matej Habrnal 34dad7
-        return NULL;
Matej Habrnal 34dad7
+        return -1;
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-    GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_TIME          );
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_REASON        );
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_NOT_REPORTABLE);
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_COMPONENT     );
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_EXECUTABLE    );
Matej Habrnal 34dad7
-    g_variant_builder_add(builder, "s", FILENAME_REPORTED_TO   );
Matej Habrnal 34dad7
-    GVariant *params = g_variant_new("(sas)", problem_dir_path, builder);
Matej Habrnal 34dad7
-    g_variant_builder_unref(builder);
Matej Habrnal 34dad7
+    GVariantBuilder *args_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    for (const char **iter = elements; *iter; ++iter)
Matej Habrnal 34dad7
+        g_variant_builder_add(args_builder, "s", *iter);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    GVariant *params = g_variant_new("(sas)", problem_id, args_builder);
Matej Habrnal 34dad7
+    g_variant_builder_unref(args_builder);
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     GError *error = NULL;
Matej Habrnal 34dad7
     GVariant *result = g_dbus_proxy_call_sync(proxy,
Matej Habrnal 34dad7
@@ -130,20 +128,46 @@ problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
     if (error)
Matej Habrnal 34dad7
     {
Matej Habrnal 34dad7
-        error_msg(_("Can't get problem data from abrt-dbus: %s"), error->message);
Matej Habrnal 34dad7
+        error_msg(_("D-Bus GetInfo method call failed: %s"), error->message);
Matej Habrnal 34dad7
         g_error_free(error);
Matej Habrnal 34dad7
-        return NULL;
Matej Habrnal 34dad7
+        return -2;
Matej Habrnal 34dad7
     }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
-    problem_data_t *pd = problem_data_new();
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
     char *key, *val;
Matej Habrnal 34dad7
     GVariantIter *iter;
Matej Habrnal 34dad7
     g_variant_get(result, "(a{ss})", &iter);
Matej Habrnal 34dad7
     while (g_variant_iter_loop(iter, "{ss}", &key, &val))
Matej Habrnal 34dad7
+        problem_data_add_text_noteditable(problem_data, key, val);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    g_variant_unref(result);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    return 0;
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    INITIALIZE_LIBABRT();
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    static const char *elements[] = {
Matej Habrnal 34dad7
+        FILENAME_TIME,
Matej Habrnal 34dad7
+        FILENAME_REASON,
Matej Habrnal 34dad7
+        FILENAME_NOT_REPORTABLE,
Matej Habrnal 34dad7
+        FILENAME_COMPONENT,
Matej Habrnal 34dad7
+        FILENAME_EXECUTABLE,
Matej Habrnal 34dad7
+        FILENAME_REPORTED_TO,
Matej Habrnal 34dad7
+        NULL,
Matej Habrnal 34dad7
+    };
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    problem_data_t *pd = problem_data_new();
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
+    if (fill_problem_data_over_dbus(problem_dir_path, elements, pd) != 0)
Matej Habrnal 34dad7
     {
Matej Habrnal 34dad7
-        problem_data_add_text_noteditable(pd, key, val);
Matej Habrnal 34dad7
+        error_msg(_("Can't get problem data from abrt-dbus"));
Matej Habrnal 34dad7
+        problem_data_free(pd);
Matej Habrnal 34dad7
+        return NULL;
Matej Habrnal 34dad7
     }
Matej Habrnal 34dad7
-    g_variant_unref(result);
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
     return pd;
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
@@ -259,6 +283,11 @@ int test_exist_over_dbus(const char *problem_id, const char *element_name)
Matej Habrnal 34dad7
     return retval;
Matej Habrnal 34dad7
 }
Matej Habrnal 34dad7
 
Matej Habrnal 34dad7
+int dbus_problem_is_complete(const char *problem_id)
Matej Habrnal 34dad7
+{
Matej Habrnal 34dad7
+    return test_exist_over_dbus(problem_id, FILENAME_COUNT);
Matej Habrnal 34dad7
+}
Matej Habrnal 34dad7
+
Matej Habrnal 34dad7
 char *load_text_over_dbus(const char *problem_id, const char *element_name)
Matej Habrnal 34dad7
 {
Matej Habrnal 34dad7
     INITIALIZE_LIBABRT();
Matej Habrnal 34dad7
-- 
Matej Habrnal 34dad7
2.4.1
Matej Habrnal 34dad7