/* Copyright (C) 2014 ABRT Team Copyright (C) 2014 RedHat inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "libabrt.h" #include "client.h" #include "abrt-cli-core.h" #include "builtin-cmd.h" enum { ACT_ERR = 0, ACT_REMOVE, ACT_REPORT, ACT_INFO, ACT_SKIP }; static int process_one_crash(problem_data_t *problem_data, int report_flags) { if (problem_data == NULL) return ACT_ERR; static const char *name_to_skip[] = { FILENAME_PACKAGE , FILENAME_UID , FILENAME_COUNT }; char *desc = make_description(problem_data, /*names_to_skip:*/ (char **)name_to_skip, /*max_text_size:*/ CD_TEXT_ATT_SIZE_BZ, MAKEDESC_SHOW_ONLY_LIST | MAKEDESC_SHOW_URLS); fputs(desc, stdout); free(desc); const char *dir_name = problem_data_get_content_or_NULL(problem_data, CD_DUMPDIR); char *action = NULL; int ret_val = 0; while (ret_val == 0) { const char *not_reportable = problem_data_get_content_or_NULL(problem_data, FILENAME_NOT_REPORTABLE); /* if the problem is not-reportable then ask does not contain option report(e) */ if ((report_flags & CMD_REPORT_UNSAFE) || not_reportable == NULL) action = ask(_("Actions: remove(rm), report(e), info(i), skip(s):")); else action = ask(_("Actions: remove(rm), info(i), skip(s):")); if(strcmp(action, "rm") == 0 || strcmp(action, "remove") == 0 ) { log_warning(_("Deleting '%s'"), dir_name); const char *dirs_strv[] = {dir_name, NULL}; _cmd_remove(dirs_strv); ret_val = ACT_REMOVE; } else if (((report_flags & CMD_REPORT_UNSAFE) || not_reportable == NULL) && (strcmp(action, "e") == 0 || strcmp(action, "report") == 0)) { log_warning(_("Reporting '%s'"), dir_name); const char *dirs_strv[] = {dir_name, NULL}; _cmd_report(dirs_strv, report_flags); ret_val = ACT_REPORT; } else if (strcmp(action, "i") == 0 || strcmp(action, "info") == 0) { _cmd_info(problem_data, /*detailed*/1, CD_TEXT_ATT_SIZE_BZ); ret_val = ACT_INFO; } else if (strcmp(action, "s") == 0 || strcmp(action, "skip") == 0) { ret_val = ACT_SKIP; } free(action); } return ret_val; } static void process_crashes(vector_of_problem_data_t *crash_list, long since, int report_flags) { for (unsigned i = 0; i < crash_list->len; ++i) { problem_data_t *crash = get_problem_data(crash_list, i); if (since != 0) { char *s = problem_data_get_content_or_NULL(crash, FILENAME_LAST_OCCURRENCE); long val = s ? atol(s) : 0; if (val < since) continue; } /* do not print '\n' before first problem */ if(i != 0) printf("\n"); int action = process_one_crash(crash, report_flags); if (i != crash_list->len - 1) { if (action == ACT_REMOVE || action == ACT_REPORT || action == ACT_INFO) { /* dummy must be free because the function ask allocate memory */ char *dummy = ask(_("For next problem press ENTER:")); free(dummy); } } } return; } int cmd_process(int argc, const char **argv) { const char *program_usage_string = _( "& process [options]\n" "\n" "Without --since argument, iterates over all detected problems." ); enum { OPT_v = 1 << 0, OPT_s = 1 << 1, OPT_u = 1 << 2, }; int opt_since = 0; struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_INTEGER('s', "since" , &opt_since, _("Selects only problems detected after timestamp")), OPT_BOOL( 'u', "unsafe", NULL, _("Ignore security checks to be able to " "report all problems")), OPT_END() }; unsigned opts = parse_opts(argc, (char **)argv, program_options, program_usage_string); vector_of_problem_data_t *ci = fetch_crash_infos(); g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE); int report_flags = 0; if (opts & OPT_u) report_flags |= CMD_REPORT_UNSAFE; process_crashes(ci, opt_since, report_flags); free_vector_of_problem_data(ci); return 0; }