/*
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;
}