Blame src/cli/process.c

Packit 8ea169
/*
Packit 8ea169
    Copyright (C) 2014  ABRT Team
Packit 8ea169
    Copyright (C) 2014  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
#include "client.h"
Packit 8ea169
Packit 8ea169
#include "abrt-cli-core.h"
Packit 8ea169
#include "builtin-cmd.h"
Packit 8ea169
Packit 8ea169
Packit 8ea169
enum {
Packit 8ea169
    ACT_ERR = 0,
Packit 8ea169
    ACT_REMOVE,
Packit 8ea169
    ACT_REPORT,
Packit 8ea169
    ACT_INFO,
Packit 8ea169
    ACT_SKIP
Packit 8ea169
};
Packit 8ea169
Packit 8ea169
static int process_one_crash(problem_data_t *problem_data, int report_flags)
Packit 8ea169
{
Packit 8ea169
    if (problem_data == NULL)
Packit 8ea169
        return ACT_ERR;
Packit 8ea169
Packit 8ea169
    static const char *name_to_skip[] = {
Packit 8ea169
            FILENAME_PACKAGE   ,
Packit 8ea169
            FILENAME_UID       ,
Packit 8ea169
            FILENAME_COUNT
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    char *desc = make_description(problem_data,
Packit 8ea169
                        /*names_to_skip:*/ (char **)name_to_skip,
Packit 8ea169
                        /*max_text_size:*/ CD_TEXT_ATT_SIZE_BZ,
Packit 8ea169
                        MAKEDESC_SHOW_ONLY_LIST | MAKEDESC_SHOW_URLS);
Packit 8ea169
Packit 8ea169
    fputs(desc, stdout);
Packit 8ea169
    free(desc);
Packit 8ea169
Packit 8ea169
    const char *dir_name = problem_data_get_content_or_NULL(problem_data,
Packit 8ea169
                                                            CD_DUMPDIR);
Packit 8ea169
    char *action = NULL;
Packit 8ea169
    int ret_val = 0;
Packit 8ea169
    while (ret_val == 0)
Packit 8ea169
    {
Packit 8ea169
        const char *not_reportable = problem_data_get_content_or_NULL(problem_data, FILENAME_NOT_REPORTABLE);
Packit 8ea169
Packit 8ea169
        /* if the problem is not-reportable then ask does not contain option report(e) */
Packit 8ea169
        if ((report_flags & CMD_REPORT_UNSAFE) || not_reportable == NULL)
Packit 8ea169
            action = ask(_("Actions: remove(rm), report(e), info(i), skip(s):"));
Packit 8ea169
        else
Packit 8ea169
            action = ask(_("Actions: remove(rm), info(i), skip(s):"));
Packit 8ea169
Packit 8ea169
        if(strcmp(action, "rm") == 0 || strcmp(action, "remove") == 0 )
Packit 8ea169
        {
Packit 8ea169
            log_warning(_("Deleting '%s'"), dir_name);
Packit 8ea169
            const char *dirs_strv[] = {dir_name, NULL};
Packit 8ea169
            _cmd_remove(dirs_strv);
Packit 8ea169
Packit 8ea169
            ret_val = ACT_REMOVE;
Packit 8ea169
        }
Packit 8ea169
        else if (((report_flags & CMD_REPORT_UNSAFE) || not_reportable == NULL)
Packit 8ea169
             && (strcmp(action, "e") == 0 || strcmp(action, "report") == 0))
Packit 8ea169
        {
Packit 8ea169
            log_warning(_("Reporting '%s'"), dir_name);
Packit 8ea169
            const char *dirs_strv[] = {dir_name, NULL};
Packit 8ea169
            _cmd_report(dirs_strv, report_flags);
Packit 8ea169
Packit 8ea169
            ret_val = ACT_REPORT;
Packit 8ea169
        }
Packit 8ea169
        else if (strcmp(action, "i") == 0 || strcmp(action, "info") == 0)
Packit 8ea169
        {
Packit 8ea169
            _cmd_info(problem_data, /*detailed*/1, CD_TEXT_ATT_SIZE_BZ);
Packit 8ea169
Packit 8ea169
            ret_val = ACT_INFO;
Packit 8ea169
        }
Packit 8ea169
        else if (strcmp(action, "s") == 0 || strcmp(action, "skip") == 0)
Packit 8ea169
        {
Packit 8ea169
            ret_val = ACT_SKIP;
Packit 8ea169
        }
Packit 8ea169
Packit 8ea169
        free(action);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return ret_val;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
static void process_crashes(vector_of_problem_data_t *crash_list, long since, int report_flags)
Packit 8ea169
{
Packit 8ea169
Packit 8ea169
    for (unsigned i = 0; i < crash_list->len; ++i)
Packit 8ea169
    {
Packit 8ea169
        problem_data_t *crash = get_problem_data(crash_list, i);
Packit 8ea169
Packit 8ea169
        if (since != 0)
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 (val < since)
Packit 8ea169
                continue;
Packit 8ea169
        }
Packit 8ea169
Packit 8ea169
        /* do not print '\n' before first problem */
Packit 8ea169
        if(i != 0)
Packit 8ea169
            printf("\n");
Packit 8ea169
Packit 8ea169
        int action = process_one_crash(crash, report_flags);
Packit 8ea169
Packit 8ea169
        if (i != crash_list->len - 1)
Packit 8ea169
        {
Packit 8ea169
            if (action == ACT_REMOVE || action == ACT_REPORT || action == ACT_INFO)
Packit 8ea169
            {
Packit 8ea169
                /* dummy must be free because the function ask allocate memory */
Packit 8ea169
                char *dummy = ask(_("For next problem press ENTER:"));
Packit 8ea169
                free(dummy);
Packit 8ea169
            }
Packit 8ea169
        }
Packit 8ea169
    }
Packit 8ea169
    return;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
int cmd_process(int argc, const char **argv)
Packit 8ea169
{
Packit 8ea169
    const char *program_usage_string = _(
Packit 8ea169
        "& process [options]\n"
Packit 8ea169
        "\n"
Packit 8ea169
        "Without --since argument, iterates over all detected problems."
Packit 8ea169
    );
Packit 8ea169
Packit 8ea169
    enum {
Packit 8ea169
        OPT_v = 1 << 0,
Packit 8ea169
        OPT_s = 1 << 1,
Packit 8ea169
        OPT_u = 1 << 2,
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    int opt_since = 0;
Packit 8ea169
    struct options program_options[] = {
Packit 8ea169
        OPT__VERBOSE(&g_verbose),
Packit 8ea169
        OPT_INTEGER('s', "since" , &opt_since,  _("Selects only problems detected after timestamp")),
Packit 8ea169
        OPT_BOOL(   'u', "unsafe", NULL,        _("Ignore security checks to be able to "
Packit 8ea169
                                                  "report all problems")),
Packit 8ea169
        OPT_END()
Packit 8ea169
    };
Packit 8ea169
Packit 8ea169
    unsigned opts = 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
Packit 8ea169
    g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
Packit 8ea169
Packit 8ea169
    int report_flags = 0;
Packit 8ea169
    if (opts & OPT_u)
Packit 8ea169
        report_flags |= CMD_REPORT_UNSAFE;
Packit 8ea169
    process_crashes(ci, opt_since, report_flags);
Packit 8ea169
Packit 8ea169
    free_vector_of_problem_data(ci);
Packit 8ea169
Packit 8ea169
    return 0;
Packit 8ea169
}