ishcherb / rpms / abrt

Forked from rpms/abrt 6 years ago
Clone
fa19501
From 739b52102b162209d3add0988e829f4409971a3c Mon Sep 17 00:00:00 2001
fa19501
From: Jakub Filak <jfilak@redhat.com>
fa19501
Date: Tue, 24 Mar 2015 20:57:34 +0100
fa19501
Subject: [PATCH] cli: use the DBus methods for getting problem information
fa19501
fa19501
The dump directory is no longer accessible by non-root users and we also
fa19501
want to get rid of direct access to allow administrators (wheel members)
fa19501
see problem data without the need to ChownProblem directory before.
fa19501
fa19501
Signed-off-by: Jakub Filak <jfilak@redhat.com>
fa19501
---
fa19501
 src/cli/abrt-cli-core.c | 74 ++++++++++++++++++++++++-------------------------
fa19501
 src/cli/abrt-cli-core.h |  4 ++-
fa19501
 src/cli/list.c          | 45 +++++++++++-------------------
fa19501
 src/cli/process.c       |  6 +---
fa19501
 src/cli/status.c        | 66 +++++++++++++------------------------------
fa19501
 5 files changed, 77 insertions(+), 118 deletions(-)
fa19501
fa19501
diff --git a/src/cli/abrt-cli-core.c b/src/cli/abrt-cli-core.c
fa19501
index 23a74a8..77a37f7 100644
fa19501
--- a/src/cli/abrt-cli-core.c
fa19501
+++ b/src/cli/abrt-cli-core.c
fa19501
@@ -39,24 +39,22 @@ vector_of_problem_data_t *new_vector_of_problem_data(void)
fa19501
     return g_ptr_array_new_with_free_func((void (*)(void*)) &problem_data_free);
fa19501
 }
fa19501
 
fa19501
-static int
fa19501
-append_problem_data(struct dump_dir *dd, void *arg)
fa19501
+vector_of_problem_data_t *fetch_crash_infos(void)
fa19501
 {
fa19501
-    vector_of_problem_data_t *vpd = arg;
fa19501
-
fa19501
-    problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
fa19501
-    problem_data_add(problem_data, CD_DUMPDIR, dd->dd_dirname,
fa19501
-                            CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
fa19501
-    g_ptr_array_add(vpd, problem_data);
fa19501
-    return 0;
fa19501
-}
fa19501
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
fa19501
+    if (problems == ERR_PTR)
fa19501
+        return NULL;
fa19501
 
fa19501
-vector_of_problem_data_t *fetch_crash_infos(GList *dir_list)
fa19501
-{
fa19501
     vector_of_problem_data_t *vpd = new_vector_of_problem_data();
fa19501
 
fa19501
-    for (GList *li = dir_list; li; li = li->next)
fa19501
-        for_each_problem_in_dir(li->data, getuid(), append_problem_data, vpd);
fa19501
+    for (GList *iter = problems; iter; iter = g_list_next(iter))
fa19501
+    {
fa19501
+        problem_data_t *problem_data = get_full_problem_data_over_dbus((const char *)(iter->data));
fa19501
+        if (problem_data == ERR_PTR)
fa19501
+            continue;
fa19501
+
fa19501
+        g_ptr_array_add(vpd, problem_data);
fa19501
+    }
fa19501
 
fa19501
     return vpd;
fa19501
 }
fa19501
@@ -74,36 +72,38 @@ static bool isxdigit_str(const char *str)
fa19501
     return true;
fa19501
 }
fa19501
 
fa19501
-struct name_resolution_param {
fa19501
-    const char *shortcut;
fa19501
-    unsigned strlen_shortcut;
fa19501
-    char *found_name;
fa19501
-};
fa19501
-
fa19501
-static int find_dir_by_hash(struct dump_dir *dd, void *arg)
fa19501
+char *find_problem_by_hash(const char *hash, GList *problems)
fa19501
 {
fa19501
-    struct name_resolution_param *param = arg;
fa19501
-    char hash_str[SHA1_RESULT_LEN*2 + 1];
fa19501
-    str_to_sha1str(hash_str, dd->dd_dirname);
fa19501
-    if (strncasecmp(param->shortcut, hash_str, param->strlen_shortcut) == 0)
fa19501
+    unsigned hash_len = strlen(hash);
fa19501
+    if (!isxdigit_str(hash) || hash_len < 5)
fa19501
+        return NULL;
fa19501
+
fa19501
+    char *found_name = NULL;
fa19501
+    for (GList *iter = problems; iter; iter = g_list_next(iter))
fa19501
     {
fa19501
-        if (param->found_name)
fa19501
-            error_msg_and_die(_("'%s' identifies more than one problem directory"), param->shortcut);
fa19501
-        param->found_name = xstrdup(dd->dd_dirname);
fa19501
+        char hash_str[SHA1_RESULT_LEN*2 + 1];
fa19501
+        str_to_sha1str(hash_str, (const char *)(iter->data));
fa19501
+        if (strncasecmp(hash, hash_str, hash_len) == 0)
fa19501
+        {
fa19501
+            if (found_name)
fa19501
+                error_msg_and_die(_("'%s' identifies more than one problem directory"), hash);
fa19501
+            found_name = xstrdup((const char *)(iter->data));
fa19501
+        }
fa19501
     }
fa19501
-    return 0;
fa19501
+
fa19501
+    return found_name;
fa19501
 }
fa19501
 
fa19501
 char *hash2dirname(const char *hash)
fa19501
 {
fa19501
-    unsigned hash_len = strlen(hash);
fa19501
-    if (!isxdigit_str(hash) || hash_len < 5)
fa19501
+    /* Try loading by dirname hash */
fa19501
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
fa19501
+    if (problems == ERR_PTR)
fa19501
         return NULL;
fa19501
 
fa19501
-    /* Try loading by dirname hash */
fa19501
-    struct name_resolution_param param = { hash, hash_len, NULL };
fa19501
-    GList *dir_list = get_problem_storages();
fa19501
-    for (GList *li = dir_list; li; li = li->next)
fa19501
-        for_each_problem_in_dir(li->data, getuid(), find_dir_by_hash, ¶m;;
fa19501
-    return param.found_name;
fa19501
+    char *found_name = find_problem_by_hash(hash, problems);
fa19501
+
fa19501
+    g_list_free_full(problems, free);
fa19501
+
fa19501
+    return found_name;
fa19501
 }
fa19501
diff --git a/src/cli/abrt-cli-core.h b/src/cli/abrt-cli-core.h
fa19501
index 83d0b5d..33b2ea6 100644
fa19501
--- a/src/cli/abrt-cli-core.h
fa19501
+++ b/src/cli/abrt-cli-core.h
fa19501
@@ -28,9 +28,11 @@ problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i);
fa19501
 
fa19501
 void free_vector_of_problem_data(vector_of_problem_data_t *vector);
fa19501
 vector_of_problem_data_t *new_vector_of_problem_data(void);
fa19501
-vector_of_problem_data_t *fetch_crash_infos(GList *dir_list);
fa19501
+vector_of_problem_data_t *fetch_crash_infos(void);
fa19501
 
fa19501
 /* Returns malloced string, or NULL if not found: */
fa19501
+char *find_problem_by_hash(const char *hash, GList *problems);
fa19501
+/* Returns malloced string, or NULL if not found: */
fa19501
 char *hash2dirname(const char *hash);
fa19501
 
fa19501
 
fa19501
diff --git a/src/cli/list.c b/src/cli/list.c
fa19501
index 2eefcfe..c0c819d 100644
fa19501
--- a/src/cli/list.c
fa19501
+++ b/src/cli/list.c
fa19501
@@ -30,33 +30,28 @@
fa19501
  *       ~/.abrt/spool and /var/tmp/abrt? needs more _meditation_.
fa19501
  */
fa19501
 
fa19501
-static problem_data_t *load_problem_data(const char *dump_dir_name)
fa19501
+static problem_data_t *load_problem_data(const char *problem_id)
fa19501
 {
fa19501
-    /* First, try loading by dirname */
fa19501
-    int sv_logmode = logmode;
fa19501
-    logmode = 0; /* suppress EPERM/EACCES errors in opendir */
fa19501
-    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ DD_OPEN_READONLY);
fa19501
-    logmode = sv_logmode;
fa19501
+    char *name2 = NULL;
fa19501
+
fa19501
+    /* First, check if there is a problem with the passed id */
fa19501
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
fa19501
+    GList *item = g_list_find_custom(problems, problem_id, (GCompareFunc)strcmp);
fa19501
 
fa19501
     /* (git requires at least 5 char hash prefix, we do the same) */
fa19501
-    if (!dd && errno == ENOENT)
fa19501
+    if (item == NULL)
fa19501
     {
fa19501
         /* Try loading by dirname hash */
fa19501
-        char *name2 = hash2dirname(dump_dir_name);
fa19501
-        if (name2)
fa19501
-            dd = dd_opendir(name2, /*flags:*/ DD_OPEN_READONLY);
fa19501
-        free(name2);
fa19501
-    }
fa19501
+        name2 = find_problem_by_hash(problem_id, problems);
fa19501
+        if (name2 == NULL)
fa19501
+            return NULL;
fa19501
 
fa19501
-    if (!dd)
fa19501
-        return NULL;
fa19501
+        problem_id = name2;
fa19501
+    }
fa19501
 
fa19501
-    problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
fa19501
-    problem_data_add(problem_data, CD_DUMPDIR, dd->dd_dirname,
fa19501
-                            CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
fa19501
-    dd_close(dd);
fa19501
+    problem_data_t *problem_data = get_full_problem_data_over_dbus(problem_id);
fa19501
 
fa19501
-    return problem_data;
fa19501
+    return (problem_data == ERR_PTR ? NULL : problem_data);
fa19501
 }
fa19501
 
fa19501
 /** Prints basic information about a crash to stdout. */
fa19501
@@ -127,7 +122,7 @@ static bool print_crash_list(vector_of_problem_data_t *crash_list, int detailed,
fa19501
 int cmd_list(int argc, const char **argv)
fa19501
 {
fa19501
     const char *program_usage_string = _(
fa19501
-        "& list [options] [DIR]..."
fa19501
+        "& list [options]"
fa19501
         );
fa19501
 
fa19501
     int opt_not_reported = 0;
fa19501
@@ -145,15 +140,8 @@ int cmd_list(int argc, const char **argv)
fa19501
     };
fa19501
 
fa19501
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
fa19501
-    argv += optind;
fa19501
-
fa19501
-    GList *D_list = NULL;
fa19501
-    while (*argv)
fa19501
-        D_list = g_list_append(D_list, xstrdup(*argv++));
fa19501
-    if (!D_list)
fa19501
-        D_list = get_problem_storages();
fa19501
 
fa19501
-    vector_of_problem_data_t *ci = fetch_crash_infos(D_list);
fa19501
+    vector_of_problem_data_t *ci = fetch_crash_infos();
fa19501
 
fa19501
     g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
fa19501
 
fa19501
@@ -163,7 +151,6 @@ int cmd_list(int argc, const char **argv)
fa19501
     print_crash_list(ci, opt_detailed, opt_not_reported, opt_since, opt_until, CD_TEXT_ATT_SIZE_BZ);
fa19501
 
fa19501
     free_vector_of_problem_data(ci);
fa19501
-    list_free_with_free(D_list);
fa19501
 
fa19501
 #if SUGGEST_AUTOREPORTING != 0
fa19501
     load_abrt_conf();
fa19501
diff --git a/src/cli/process.c b/src/cli/process.c
fa19501
index 7f4fff5..39462f9 100644
fa19501
--- a/src/cli/process.c
fa19501
+++ b/src/cli/process.c
fa19501
@@ -152,18 +152,14 @@ int cmd_process(int argc, const char **argv)
fa19501
     };
fa19501
 
fa19501
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
fa19501
-    argv += optind;
fa19501
 
fa19501
-    GList *D_list = get_problem_storages();
fa19501
-
fa19501
-    vector_of_problem_data_t *ci = fetch_crash_infos(D_list);
fa19501
+    vector_of_problem_data_t *ci = fetch_crash_infos();
fa19501
 
fa19501
     g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
fa19501
 
fa19501
     process_crashes(ci, opt_since);
fa19501
 
fa19501
     free_vector_of_problem_data(ci);
fa19501
-    list_free_with_free(D_list);
fa19501
 
fa19501
     return 0;
fa19501
 }
fa19501
diff --git a/src/cli/status.c b/src/cli/status.c
fa19501
index 1de2d41..68bdd0e 100644
fa19501
--- a/src/cli/status.c
fa19501
+++ b/src/cli/status.c
fa19501
@@ -21,53 +21,36 @@
fa19501
 #include <sys/types.h>
fa19501
 #include "problem_api.h"
fa19501
 
fa19501
-struct time_range {
fa19501
-    unsigned count;
fa19501
-    unsigned long since;
fa19501
-};
fa19501
-
fa19501
-static int count_dir_if_newer_than(struct dump_dir *dd, void *arg)
fa19501
-{
fa19501
-    struct time_range *me = arg;
fa19501
-
fa19501
-    if (dd_exist(dd, FILENAME_REPORTED_TO))
fa19501
-        return 0;
fa19501
-
fa19501
-    char *time_str = dd_load_text(dd, FILENAME_LAST_OCCURRENCE);
fa19501
-    long val = atol(time_str);
fa19501
-    free(time_str);
fa19501
-    if (val < me->since)
fa19501
-        return 0;
fa19501
-
fa19501
-    me->count++;
fa19501
-    return 0;
fa19501
-}
fa19501
-
fa19501
-static void count_problems_in_dir(gpointer data, gpointer arg)
fa19501
+static unsigned int count_problem_dirs(unsigned long since)
fa19501
 {
fa19501
-    char *path = data;
fa19501
-    struct time_range *me = arg;
fa19501
+    unsigned count = 0;
fa19501
 
fa19501
-    log_info("scanning '%s' for problems since %lu", path, me->since);
fa19501
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
fa19501
+    for (GList *iter = problems; iter != NULL; iter = g_list_next(iter))
fa19501
+    {
fa19501
+        const char *problem_id = (const char *)iter->data;
fa19501
+        if (test_exist_over_dbus(problem_id, FILENAME_REPORTED_TO))
fa19501
+            continue;
fa19501
 
fa19501
-    for_each_problem_in_dir(path, getuid(), count_dir_if_newer_than, me);
fa19501
-}
fa19501
+        char *time_str = load_text_over_dbus(problem_id, FILENAME_LAST_OCCURRENCE);
fa19501
+        if (time_str == NULL)
fa19501
+            continue;
fa19501
 
fa19501
-static unsigned int count_problem_dirs(GList *paths, unsigned long since)
fa19501
-{
fa19501
-    struct time_range me;
fa19501
-    me.count = 0;
fa19501
-    me.since = since;
fa19501
+        long val = atol(time_str);
fa19501
+        free(time_str);
fa19501
+        if (val < since)
fa19501
+            return 0;
fa19501
 
fa19501
-    g_list_foreach(paths, count_problems_in_dir, &me);
fa19501
+        count++;
fa19501
+    }
fa19501
 
fa19501
-    return me.count;
fa19501
+    return count;
fa19501
 }
fa19501
 
fa19501
 int cmd_status(int argc, const char **argv)
fa19501
 {
fa19501
     const char *program_usage_string = _(
fa19501
-        "& status [DIR]..."
fa19501
+        "& status"
fa19501
         );
fa19501
 
fa19501
     int opt_bare = 0; /* must be _int_, OPT_BOOL expects that! */
fa19501
@@ -81,17 +64,8 @@ int cmd_status(int argc, const char **argv)
fa19501
     };
fa19501
 
fa19501
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
fa19501
-    argv += optind;
fa19501
-
fa19501
-    GList *problem_dir_list = NULL;
fa19501
-    while (*argv)
fa19501
-        problem_dir_list = g_list_append(problem_dir_list, xstrdup(*argv++));
fa19501
-    if (!problem_dir_list)
fa19501
-        problem_dir_list = get_problem_storages();
fa19501
-
fa19501
-    unsigned int problem_count = count_problem_dirs(problem_dir_list, opt_since);
fa19501
 
fa19501
-    list_free_with_free(problem_dir_list);
fa19501
+    unsigned int problem_count = count_problem_dirs(opt_since);
fa19501
 
fa19501
     /* show only if there is at least 1 problem or user set the -v */
fa19501
     if (problem_count > 0 || g_verbose > 0)
fa19501
-- 
fa19501
2.1.0
fa19501