Blame src/cli/list.c

Packit 8ea169
/*
Packit 8ea169
    Copyright (C) 2011  ABRT Team
Packit 8ea169
    Copyright (C) 2011  RedHat inc.
Packit 8ea169
Packit 8ea169
    This program is free software; you can redistribute it and/or modify
Packit 8ea169
    it under the terms of the GNU General Public License as published by
Packit 8ea169
    the Free Software Foundation; either version 2 of the License, or
Packit 8ea169
    (at your option) any later version.
Packit 8ea169
Packit 8ea169
    This program is distributed in the hope that it will be useful,
Packit 8ea169
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8ea169
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8ea169
    GNU General Public License for more details.
Packit 8ea169
Packit 8ea169
    You should have received a copy of the GNU General Public License along
Packit 8ea169
    with this program; if not, write to the Free Software Foundation, Inc.,
Packit 8ea169
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 8ea169
*/
Packit 8ea169
Packit 8ea169
#include "libabrt.h"
Packit 8ea169
Packit 8ea169
#include "abrt-cli-core.h"
Packit 8ea169
#include "builtin-cmd.h"
Packit 8ea169
Packit 8ea169
/* TODO: npajkovs
Packit 8ea169
 *     add --pretty=oneline|raw|normal|format="%a %b %c"
Packit 8ea169
 *     add  wildcard e.g. *-2011-04-01-10-* (list all problems in specific day)
Packit 8ea169
 *
Packit 8ea169
 * TODO?: remove base dir from list of crashes? is there a way that same crash can be in
Packit 8ea169
 *       ~/.abrt/spool and /var/tmp/abrt? needs more _meditation_.
Packit 8ea169
 */
Packit 8ea169
Packit 8ea169
static problem_data_t *load_problem_data(const char *problem_id)
Packit 8ea169
{
Packit 8ea169
    char *name2 = NULL;
Packit 8ea169
Packit 8ea169
    /* First, check if there is a problem with the passed id */
Packit 8ea169
    GList *problems = get_problems_over_dbus(g_cli_authenticate);
Packit 8ea169
    if (problems == ERR_PTR)
Packit 8ea169
        return NULL;
Packit 8ea169
Packit 8ea169
    GList *item = g_list_find_custom(problems, problem_id, (GCompareFunc)strcmp);
Packit 8ea169
Packit 8ea169
    /* (git requires at least 5 char hash prefix, we do the same) */
Packit 8ea169
    if (item == NULL)
Packit 8ea169
    {
Packit 8ea169
        /* Try loading by dirname hash */
Packit 8ea169
        name2 = find_problem_by_hash(problem_id, problems);
Packit 8ea169
        if (name2 == NULL)
Packit 8ea169
            return NULL;
Packit 8ea169
Packit 8ea169
        problem_id = name2;
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    problem_data_t *problem_data = get_full_problem_data_over_dbus(problem_id);
Packit 8ea169
Packit 8ea169
    return (problem_data == ERR_PTR ? NULL : problem_data);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
/** Prints basic information about a crash to stdout. */
Packit 8ea169
static void print_crash(problem_data_t *problem_data, int detailed, int text_size)
Packit 8ea169
{
Packit 8ea169
    if (!problem_data)
Packit 8ea169
        return;
Packit 8ea169
Packit 8ea169
    char *desc;
Packit 8ea169
    if (detailed)
Packit 8ea169
    {
Packit 8ea169
        desc = make_description(problem_data,
Packit 8ea169
                                /*names_to_skip:*/ NULL,
Packit 8ea169
                                /*max_text_size:*/ text_size,
Packit 8ea169
                                MAKEDESC_SHOW_FILES | MAKEDESC_SHOW_MULTILINE);
Packit 8ea169
    }
Packit 8ea169
    else
Packit 8ea169
    {
Packit 8ea169
        desc = make_description(problem_data,
Packit 8ea169
                            /*names_to_skip:*/ NULL,
Packit 8ea169
                            /*max_text_size:*/ text_size,
Packit 8ea169
                            MAKEDESC_SHOW_ONLY_LIST | MAKEDESC_SHOW_URLS);
Packit 8ea169
    }
Packit 8ea169
    fputs(desc, stdout);
Packit 8ea169
    free(desc);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
/**
Packit 8ea169
 * Prints a list containing "crashes" to stdout.
Packit 8ea169
 * @param only_unreported
Packit 8ea169
 *   Do not skip entries marked as already reported.
Packit 8ea169
 */
Packit 8ea169
static bool print_crash_list(vector_of_problem_data_t *crash_list, int detailed, int only_not_reported, long since, long until, int text_size)
Packit 8ea169
{
Packit 8ea169
    bool output = false;
Packit 8ea169
    unsigned i;
Packit 8ea169
    for (i = 0; i < crash_list->len; ++i)
Packit 8ea169
    {
Packit 8ea169
        problem_data_t *crash = get_problem_data(crash_list, i);
Packit 8ea169
        if (only_not_reported)
Packit 8ea169
        {
Packit 8ea169
            if (problem_data_get_content_or_NULL(crash, FILENAME_REPORTED_TO))
Packit 8ea169
                continue;
Packit 8ea169
        }
Packit 8ea169
        if (since || until)
Packit 8ea169
        {
Packit 8ea169
            char *s = problem_data_get_content_or_NULL(crash, FILENAME_LAST_OCCURRENCE);
Packit 8ea169
            long val = s ? atol(s) : 0;
Packit 8ea169
            if (since && val < since)
Packit 8ea169
                continue;
Packit 8ea169
            if (until && val > until)
Packit 8ea169
                continue;
Packit 8ea169
        }
Packit 8ea169
Packit 8ea169
        char hash_str[SHA1_RESULT_LEN*2 + 1];
Packit 8ea169
        struct problem_item *item = g_hash_table_lookup(crash, CD_DUMPDIR);
Packit 8ea169
        if (item)
Packit 8ea169
            printf("id %s\n", str_to_sha1str(hash_str, item->content));
Packit 8ea169
        print_crash(crash, detailed, text_size);
Packit 8ea169
        if (i != crash_list->len - 1)
Packit 8ea169
            printf("\n");
Packit 8ea169
        output = true;
Packit 8ea169
    }
Packit 8ea169
    return output;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int cmd_list(int argc, const char **argv)
Packit 8ea169
{
Packit 8ea169
    const char *program_usage_string = _(
Packit 8ea169
        "& list [options]"
Packit 8ea169
        );
Packit 8ea169
Packit 8ea169
    int opt_not_reported = 0;
Packit 8ea169
    int opt_detailed = 0;
Packit 8ea169
    int opt_since = 0;
Packit 8ea169
    int opt_until = 0;
Packit 8ea169
    struct options program_options[] = {
Packit 8ea169
        OPT__VERBOSE(&g_verbose),
Packit 8ea169
        OPT_BOOL('n', "not-reported"     , &opt_not_reported,      _("List only not-reported problems")),
Packit 8ea169
        /* deprecate -d option with --pretty=full*/
Packit 8ea169
        OPT_BOOL('d', "detailed" , &opt_detailed,  _("Show detailed report")),
Packit 8ea169
        OPT_INTEGER('s', "since" , &opt_since,  _("List only the problems more recent than specified timestamp")),
Packit 8ea169
        OPT_INTEGER('u', "until" , &opt_until,  _("List only the problems older than specified timestamp")),
Packit 8ea169
        OPT_END()
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    parse_opts(argc, (char **)argv, program_options, program_usage_string);
Packit 8ea169
Packit 8ea169
    vector_of_problem_data_t *ci = fetch_crash_infos();
Packit 8ea169
    if (ci == NULL)
Packit 8ea169
        return 1;
Packit 8ea169
Packit 8ea169
    g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
Packit 8ea169
Packit 8ea169
#if SUGGEST_AUTOREPORTING != 0
Packit 8ea169
    const bool output =
Packit 8ea169
#endif
Packit 8ea169
    print_crash_list(ci, opt_detailed, opt_not_reported, opt_since, opt_until, CD_TEXT_ATT_SIZE_BZ);
Packit 8ea169
Packit 8ea169
    free_vector_of_problem_data(ci);
Packit 8ea169
Packit 8ea169
#if SUGGEST_AUTOREPORTING != 0
Packit 8ea169
    load_abrt_conf();
Packit 8ea169
    if (!g_settings_autoreporting)
Packit 8ea169
    {
Packit 8ea169
        if (output)
Packit 8ea169
            putc('\n', stderr);
Packit 8ea169
Packit 8ea169
        fprintf(stderr, _("The Autoreporting feature is disabled. Please consider enabling it by issuing\n"
Packit 8ea169
                          "'abrt-auto-reporting enabled' as a user with root privileges\n"));
Packit 8ea169
    }
Packit 8ea169
#endif
Packit 8ea169
Packit 8ea169
    return 0;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int _cmd_info(problem_data_t *problem_data, int detailed, int text_size)
Packit 8ea169
{
Packit 8ea169
    print_crash(problem_data, detailed, text_size);
Packit 8ea169
    return 0;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int cmd_info(int argc, const char **argv)
Packit 8ea169
{
Packit 8ea169
    const char *program_usage_string = _(
Packit 8ea169
        "& info [options] DIR..."
Packit 8ea169
        );
Packit 8ea169
Packit 8ea169
    int opt_detailed = 0;
Packit 8ea169
    int text_size = CD_TEXT_ATT_SIZE_BZ;
Packit 8ea169
    struct options program_options[] = {
Packit 8ea169
        OPT__VERBOSE(&g_verbose),
Packit 8ea169
        /* deprecate -d option with --pretty=full*/
Packit 8ea169
        OPT_BOOL(   'd', "detailed" , &opt_detailed, _("Show detailed report")),
Packit 8ea169
        OPT_INTEGER('s', "size",      &text_size,    _("Text larger than this will be shown abridged")),
Packit 8ea169
        OPT_END()
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    parse_opts(argc, (char **)argv, program_options, program_usage_string);
Packit 8ea169
    argv += optind;
Packit 8ea169
Packit 8ea169
    if (!argv[0])
Packit 8ea169
        show_usage_and_die(program_usage_string, program_options);
Packit 8ea169
Packit 8ea169
    if (text_size <= 0)
Packit 8ea169
        text_size = INT_MAX;
Packit 8ea169
Packit 8ea169
    int errs = 0;
Packit 8ea169
    while (*argv)
Packit 8ea169
    {
Packit 8ea169
        const char *dump_dir = *argv++;
Packit 8ea169
        problem_data_t *problem = load_problem_data(dump_dir);
Packit 8ea169
        if (!problem)
Packit 8ea169
        {
Packit 8ea169
            error_msg(_("No such problem directory '%s'"), dump_dir);
Packit 8ea169
            errs++;
Packit 8ea169
            continue;
Packit 8ea169
        }
Packit 8ea169
Packit 8ea169
        _cmd_info(problem, opt_detailed, text_size);
Packit 8ea169
        problem_data_free(problem);
Packit 8ea169
        if (*argv)
Packit 8ea169
            printf("\n");
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return errs;
Packit 8ea169
}