[[ABRT PATCH v2] abrt-cli report: accept sha1 hashes of directory names. #693

Denys Vlasenko dvlasenk at redhat.com
Tue Sep 10 11:14:22 UTC 2013


v2: made str2hash() return const char*.

Signed-off-by: Denys Vlasenko <dvlasenk at redhat.com>
---
 po/POTFILES.in          |  1 +
 src/cli/abrt-cli-core.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/cli/abrt-cli-core.h |  5 +++++
 src/cli/list.c          | 57 ++++-------------------------------------------
 src/cli/report.c        | 22 ++++++------------
 5 files changed, 76 insertions(+), 68 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index cd0a887..817b3fd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -42,6 +42,7 @@ src/plugins/bodhi.c
 
 src/hooks/abrt-merge-pstoreoops.c
 
+src/cli/abrt-cli-core.c
 src/cli/abrt-cli.c
 src/cli/list.c
 src/cli/status.c
diff --git a/src/cli/abrt-cli-core.c b/src/cli/abrt-cli-core.c
index 26d08cc..89bd04a 100644
--- a/src/cli/abrt-cli-core.c
+++ b/src/cli/abrt-cli-core.c
@@ -60,3 +60,62 @@ vector_of_problem_data_t *fetch_crash_infos(GList *dir_list)
 
     return vpd;
 }
+
+
+static bool isxdigit_str(const char *str)
+{
+    do
+    {
+        if (*str < '0' || *str > '9')
+            if ((*str|0x20) < 'a' || (*str|0x20) > 'f')
+                return false;
+        str++;
+    } while (*str);
+    return true;
+}
+
+const char *str2hash(const char *str)
+{
+    static char result[SHA1_RESULT_LEN*2 + 1];
+
+    char hash_bytes[SHA1_RESULT_LEN];
+    sha1_ctx_t sha1ctx;
+    sha1_begin(&sha1ctx);
+    sha1_hash(&sha1ctx, str, strlen(str));
+    sha1_end(&sha1ctx, hash_bytes);
+    bin2hex(result, hash_bytes, SHA1_RESULT_LEN)[0] = '\0';
+    return result;
+}
+
+struct name_resolution_param {
+    const char *shortcut;
+    unsigned strlen_shortcut;
+    char *found_name;
+};
+
+static int find_dir_by_hash(struct dump_dir *dd, void *arg)
+{
+    struct name_resolution_param *param = arg;
+    const char *h = str2hash(dd->dd_dirname);
+    if (strncasecmp(param->shortcut, h, param->strlen_shortcut) == 0)
+    {
+        if (param->found_name)
+            error_msg_and_die(_("'%s' identifies more than one problem directory"), param->shortcut);
+        param->found_name = xstrdup(dd->dd_dirname);
+    }
+    return 0;
+}
+
+char *hash2dirname(const char *hash)
+{
+    unsigned hash_len = strlen(hash);
+    if (!isxdigit_str(hash) || hash_len < 5)
+        return NULL;
+
+    /* Try loading by dirname hash */
+    struct name_resolution_param param = { hash, hash_len, NULL };
+    GList *dir_list = get_problem_storages();
+    for (GList *li = dir_list; li; li = li->next)
+        for_each_problem_in_dir(li->data, getuid(), find_dir_by_hash, &param);
+    return param.found_name;
+}
diff --git a/src/cli/abrt-cli-core.h b/src/cli/abrt-cli-core.h
index 8eedc13..2e5dfe5 100644
--- a/src/cli/abrt-cli-core.h
+++ b/src/cli/abrt-cli-core.h
@@ -30,4 +30,9 @@ void free_vector_of_problem_data(vector_of_problem_data_t *vector);
 vector_of_problem_data_t *new_vector_of_problem_data(void);
 vector_of_problem_data_t *fetch_crash_infos(GList *dir_list);
 
+const char *str2hash(const char *str);
+/* Returns malloced string, or NULL if not found: */
+char *hash2dirname(const char *hash);
+
+
 #endif /* ABRT_CLI_CORE_H_ */
diff --git a/src/cli/list.c b/src/cli/list.c
index a257623..c6bc895 100644
--- a/src/cli/list.c
+++ b/src/cli/list.c
@@ -30,49 +30,6 @@
  *       ~/.abrt/spool and /var/tmp/abrt? needs more _meditation_.
  */
 
-static bool isxdigit_str(const char *str)
-{
-    do
-    {
-        if (*str < '0' || *str > '9')
-            if ((*str|0x20) < 'a' || (*str|0x20) > 'f')
-                return false;
-        str++;
-    } while (*str);
-    return true;
-}
-
-static char *str2hash(const char *str)
-{
-    static char result[SHA1_RESULT_LEN*2 + 1];
-
-    char hash_bytes[SHA1_RESULT_LEN];
-    sha1_ctx_t sha1ctx;
-    sha1_begin(&sha1ctx);
-    sha1_hash(&sha1ctx, str, strlen(str));
-    sha1_end(&sha1ctx, hash_bytes);
-    bin2hex(result, hash_bytes, SHA1_RESULT_LEN)[0] = '\0';
-    return result;
-}
-
-struct name_resolution_param {
-    const char *shortcut;
-    unsigned strlen_shortcut;
-    char *found_name;
-};
-static int find_dir_by_hash(struct dump_dir *dd, void *arg)
-{
-    struct name_resolution_param *param = arg;
-    char *h = str2hash(dd->dd_dirname);
-    if (strncasecmp(param->shortcut, h, param->strlen_shortcut) == 0)
-    {
-        if (param->found_name)
-            error_msg_and_die(_("'%s' identifies more than one problem directory"), param->shortcut);
-        param->found_name = xstrdup(dd->dd_dirname);
-    }
-    return 0;
-}
-
 static problem_data_t *load_problem_data(const char *dump_dir_name)
 {
     /* First, try loading by dirname */
@@ -81,19 +38,13 @@ static problem_data_t *load_problem_data(const char *dump_dir_name)
     struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ DD_OPEN_READONLY);
     logmode = sv_logmode;
 
-    unsigned name_len = strlen(dump_dir_name);
     /* (git requires at least 5 char hash prefix, we do the same) */
-    if (!dd && errno == ENOENT && isxdigit_str(dump_dir_name) && name_len >= 5)
+    if (!dd && errno == ENOENT)
     {
         /* Try loading by dirname hash */
-        struct name_resolution_param param = { dump_dir_name, name_len, NULL };
-        GList *dir_list = get_problem_storages();
-        for (GList *li = dir_list; li; li = li->next)
-            for_each_problem_in_dir(li->data, getuid(), find_dir_by_hash, &param);
-        if (!param.found_name)
-            return NULL;
-        dd = dd_opendir(param.found_name, /*flags:*/ DD_OPEN_READONLY);
-        free(param.found_name);
+        char *name2 = hash2dirname(dump_dir_name);
+        dd = dd_opendir(name2, /*flags:*/ DD_OPEN_READONLY);
+        free(name2);
     }
 
     if (!dd)
diff --git a/src/cli/report.c b/src/cli/report.c
index 781c691..c5787e0 100644
--- a/src/cli/report.c
+++ b/src/cli/report.c
@@ -51,26 +51,18 @@ int cmd_report(int argc, const char **argv)
     {
         const char *dir_name = *argv++;
 
-        vector_of_problem_data_t *ci = NULL;
-        if (*dir_name == '@')
+        char *free_me = NULL;
+        if (access(dir_name, F_OK) != 0 && errno == ENOENT)
         {
-            dir_name++;
-            unsigned at = xatoi_positive(dir_name);
-
-            ci = fetch_crash_infos(D_list);
-            if (at >= ci->len)
-                error_msg_and_die("error: number is out of range '%s'", dir_name);
-
-            g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
-            problem_data_t *pd = get_problem_data(ci, at);
-
-            dir_name = problem_data_get_content_or_NULL(pd, CD_DUMPDIR);
+            free_me = hash2dirname(dir_name);
+            if (free_me)
+                dir_name = free_me;
         }
-
         int status = report_problem_in_dir(dir_name,
                                              LIBREPORT_WAIT
                                            | LIBREPORT_RUN_CLI);
-        free_vector_of_problem_data(ci);
+        free(free_me);
+
         if (status)
             exit(status);
     }
-- 
1.8.1.4



More information about the Crash-catcher mailing list