[ABRT PATCH] abrt-cli list: use sha1 hash as short ids instead of @N thing. rhbz#906733
Jiri Moskovcak
jmoskovc at redhat.com
Thu Sep 5 10:08:07 UTC 2013
- pushed, thanks
On 09/04/2013 03:32 PM, Denys Vlasenko wrote:
> Once upon a time it was meant to allow addressing problems with @N
> instead of full name. However, it is problematic - what the numbering
> should be if e.g. --since DATE was used? Should we scan all directories
> regardless because we want to show the same @N's as in full list?
> Same problem with "--full List even reported problems" versus
> !--full.
>
> Instead, use git's trick of "shortcut IDs" based on SHA hashes.
> In our case, use sha1 hash of directory name.
>
> abrt-cli info STR will attempt to use STR as sha1 hash
> of directory name if STR isn't an existing directory name,
> is >= 5 chars long, and is a hex string.
>
> Example:
> $ abrt-cli list
> ...
> @d9ca58e5b3e509759c582a5c162bfe24b23150dd
> Directory: /var/tmp/abrt/oops-2013-08-27-14:08:13-9866-0
> time: Tue 27 Aug 2013 02:08:13 PM CEST
> $ abrt-cli info d9ca5
> Directory: /var/tmp/abrt/oops-2013-08-27-14:08:13-9866-0
> time: Tue 27 Aug 2013 02:08:13 PM CEST
>
> Signed-off-by: Denys Vlasenko <dvlasenk at redhat.com>
> ---
> src/cli/abrt-cli-core.c | 18 -----------
> src/cli/abrt-cli-core.h | 1 -
> src/cli/list.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 82 insertions(+), 22 deletions(-)
>
> diff --git a/src/cli/abrt-cli-core.c b/src/cli/abrt-cli-core.c
> index 4f2a094..26d08cc 100644
> --- a/src/cli/abrt-cli-core.c
> +++ b/src/cli/abrt-cli-core.c
> @@ -39,24 +39,6 @@ vector_of_problem_data_t *new_vector_of_problem_data(void)
> return g_ptr_array_new_with_free_func((void (*)(void*)) &problem_data_free);
> }
>
> -problem_data_t *fill_crash_info(const char *dump_dir_name)
> -{
> - int sv_logmode = logmode;
> - logmode = 0; /* suppress EPERM/EACCES errors in opendir */
> - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ DD_OPEN_READONLY);
> - logmode = sv_logmode;
> -
> - if (!dd)
> - return NULL;
> -
> - problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
> - dd_close(dd);
> - problem_data_add(problem_data, CD_DUMPDIR, dump_dir_name,
> - CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
> -
> - return problem_data;
> -}
> -
> static int
> append_problem_data(struct dump_dir *dd, void *arg)
> {
> diff --git a/src/cli/abrt-cli-core.h b/src/cli/abrt-cli-core.h
> index b0f6186..8eedc13 100644
> --- a/src/cli/abrt-cli-core.h
> +++ b/src/cli/abrt-cli-core.h
> @@ -28,7 +28,6 @@ problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i);
>
> void free_vector_of_problem_data(vector_of_problem_data_t *vector);
> vector_of_problem_data_t *new_vector_of_problem_data(void);
> -problem_data_t *fill_crash_info(const char *dump_dir_name);
> vector_of_problem_data_t *fetch_crash_infos(GList *dir_list);
>
> #endif /* ABRT_CLI_CORE_H_ */
> diff --git a/src/cli/list.c b/src/cli/list.c
> index 06b271d..a257623 100644
> --- a/src/cli/list.c
> +++ b/src/cli/list.c
> @@ -30,6 +30,83 @@
> * ~/.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 */
> + int sv_logmode = logmode;
> + logmode = 0; /* suppress EPERM/EACCES errors in opendir */
> + 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)
> + {
> + /* 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, ¶m);
> + if (!param.found_name)
> + return NULL;
> + dd = dd_opendir(param.found_name, /*flags:*/ DD_OPEN_READONLY);
> + free(param.found_name);
> + }
> +
> + if (!dd)
> + return NULL;
> +
> + problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
> + problem_data_add(problem_data, CD_DUMPDIR, dd->dd_dirname,
> + CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
> + dd_close(dd);
> +
> + return problem_data;
> +}
> +
> /** Prints basic information about a crash to stdout. */
> static void print_crash(problem_data_t *problem_data, int detailed, int text_size)
> {
> @@ -82,7 +159,9 @@ static void print_crash_list(vector_of_problem_data_t *crash_list, int detailed,
> continue;
> }
>
> - printf("@%i\n", i);
> + struct problem_item *item = g_hash_table_lookup(crash, CD_DUMPDIR);
> + if (item)
> + printf("@%s\n", str2hash(item->content));
> print_crash(crash, detailed, text_size);
> if (i != crash_list->len - 1)
> printf("\n");
> @@ -158,10 +237,10 @@ int cmd_info(int argc, const char **argv)
> while (*argv)
> {
> const char *dump_dir = *argv++;
> - problem_data_t *problem = fill_crash_info(dump_dir);
> + problem_data_t *problem = load_problem_data(dump_dir);
> if (!problem)
> {
> - error_msg("no such problem directory '%s'", dump_dir);
> + error_msg(_("No such problem directory '%s'"), dump_dir);
> errs++;
> continue;
> }
>
More information about the Crash-catcher
mailing list