summaryrefslogtreecommitdiffstats
path: root/src/cli/cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/cli.c')
-rw-r--r--src/cli/cli.c368
1 files changed, 0 insertions, 368 deletions
diff --git a/src/cli/cli.c b/src/cli/cli.c
deleted file mode 100644
index db971b83..00000000
--- a/src/cli/cli.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- Copyright (C) 2009, 2010 Red Hat, 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.
-*/
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-#include <getopt.h>
-#include "abrtlib.h"
-#include "report.h"
-
-
-/* Vector of problems: */
-/* problem_data_vector[i] = { "name" = { "content", CD_FLAG_foo_bits } } */
-
-typedef GPtrArray vector_of_problem_data_t;
-
-static inline problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i)
-{
- return (problem_data_t *)g_ptr_array_index(vector, i);
-}
-
-static void free_vector_of_problem_data(vector_of_problem_data_t *vector)
-{
- if (vector)
- g_ptr_array_free(vector, TRUE);
-}
-
-static vector_of_problem_data_t *new_vector_of_problem_data(void)
-{
- return g_ptr_array_new_with_free_func((void (*)(void*)) &free_problem_data);
-}
-
-
-static problem_data_t *FillCrashInfo(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);
- add_to_problem_data_ext(problem_data, CD_DUMPDIR, dump_dir_name, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
-
- return problem_data;
-}
-
-static void GetCrashInfos(vector_of_problem_data_t *retval, const char *dir_name)
-{
- VERB1 log("Loading dumps from '%s'", dir_name);
-
- DIR *dir = opendir(dir_name);
- if (dir != NULL)
- {
- struct dirent *dent;
- while ((dent = readdir(dir)) != NULL)
- {
- if (dot_or_dotdot(dent->d_name))
- continue; /* skip "." and ".." */
-
- char *dump_dir_name = concat_path_file(dir_name, dent->d_name);
-
- struct stat statbuf;
- if (stat(dump_dir_name, &statbuf) == 0
- && S_ISDIR(statbuf.st_mode)
- ) {
- problem_data_t *problem_data = FillCrashInfo(dump_dir_name);
- if (problem_data)
- g_ptr_array_add(retval, problem_data);
- }
- free(dump_dir_name);
- }
- closedir(dir);
- }
-}
-
-/** Prints basic information about a crash to stdout. */
-static void print_crash(problem_data_t *problem_data)
-{
- char* desc = make_description(
- problem_data,
- /*names_to_skip:*/ NULL,
- /*max_text_size:*/ CD_TEXT_ATT_SIZE,
- MAKEDESC_SHOW_ONLY_LIST
- );
- fputs(desc, stdout);
- free(desc);
-}
-
-/**
- * Prints a list containing "crashes" to stdout.
- * @param include_reported
- * Do not skip entries marked as already reported.
- */
-static void print_crash_list(vector_of_problem_data_t *crash_list, bool include_reported)
-{
- unsigned i;
- for (i = 0; i < crash_list->len; ++i)
- {
- problem_data_t *crash = get_problem_data(crash_list, i);
- if (!include_reported)
- {
- const char *msg = get_problem_item_content_or_NULL(crash, FILENAME_REPORTED_TO);
- if (msg)
- continue;
- }
-
- printf("%u.\n", i);
- print_crash(crash);
- }
-}
-
-/**
- * Prints full information about a crash
- */
-static void print_crash_info(problem_data_t *problem_data, bool show_multiline)
-{
- char* desc = make_description(
- problem_data,
- /*names_to_skip:*/ NULL,
- /*max_text_size:*/ CD_TEXT_ATT_SIZE,
- MAKEDESC_SHOW_FILES | (show_multiline ? MAKEDESC_SHOW_MULTILINE : 0)
- );
- fputs(desc, stdout);
- free(desc);
-}
-
-static char *do_log(char *log_line, void *param)
-{
- log("%s", log_line);
- return log_line;
-}
-
-int main(int argc, char** argv)
-{
- abrt_init(argv);
-
- setlocale(LC_ALL, "");
-#if ENABLE_NLS
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-#endif
-
- GList *D_list = NULL;
- const char *event_name = NULL;
- const char *pfx = "";
-
- /* Can't keep these strings/structs static: _() doesn't support that */
- const char *program_usage_string = _(
- "\b [-vsp] -l[f] [-D BASE_DIR]...\n"
- "or: \b [-vsp] -i[f] DUMP_DIR\n"
- "or: \b [-vsp] -L[PREFIX] [DUMP_DIR]\n"
- "or: \b [-vsp] -e EVENT DUMP_DIR\n"
- "or: \b [-vsp] -a[y] DUMP_DIR\n"
- "or: \b [-vsp] -r[y] DUMP_DIR\n"
- "or: \b [-vsp] -d DUMP_DIR"
- );
- enum {
- OPT_list = 1 << 0,
- OPT_D = 1 << 1,
- OPT_info = 1 << 2,
- OPT_list_events = 1 << 3,
- OPT_run_event = 1 << 4,
- OPT_analyze = 1 << 5,
- OPT_report = 1 << 6,
- OPT_delete = 1 << 7,
- OPT_version = 1 << 8,
- OPTMASK_op = OPT_list|OPT_info|OPT_list_events|OPT_run_event|OPT_analyze|OPT_report|OPT_delete|OPT_version,
- OPTMASK_need_arg = OPT_info|OPT_run_event|OPT_analyze|OPT_report|OPT_delete,
- OPT_f = 1 << 9,
- OPT_y = 1 << 10,
- OPT_v = 1 << 11,
- OPT_s = 1 << 12,
- OPT_p = 1 << 13,
- };
- /* Keep enum above and order of options below in sync! */
- struct options program_options[] = {
- /* short_name long_name value parameter_name help */
- OPT_BOOL( 'l', "list" , NULL, _("List not yet reported problems, or all with -f")),
- OPT_LIST( 'D', NULL , &D_list, "BASE_DIR", _("Directory to list problems from (default: -D $HOME/.abrt/spool -D "DEBUG_DUMPS_DIR")")),
- OPT_BOOL( 'i', "info" , NULL, _("Print information about DUMP_DIR (detailed with -f)")),
- OPT_OPTSTRING('L', NULL , &pfx, "PREFIX", _("List possible events [which start with PREFIX]")),
- OPT_STRING( 'e', NULL , &event_name, "EVENT", _("Run EVENT on DUMP_DIR")),
- OPT_BOOL( 'a', "analyze", NULL, _("Run analyze event(s) on DUMP_DIR")),
- OPT_BOOL( 'r', "report" , NULL, _("Send a report about DUMP_DIR")),
- OPT_BOOL( 'd', "delete" , NULL, _("Remove DUMP_DIR")),
- OPT_BOOL( 'V', "version", NULL, _("Display version and exit")),
- OPT_BOOL( 'f', "full" , NULL, _("Full listing")),
- OPT_BOOL( 'y', "always" , NULL, _("Noninteractive: don't ask questions, assume 'yes'")),
- OPT__VERBOSE(&g_verbose),
- OPT_BOOL( 's', NULL , NULL, _("Log to syslog")),
- OPT_BOOL( 'p', NULL , NULL, _("Add program names to log")),
- OPT_END()
- };
- unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
- unsigned op = (opts & OPTMASK_op);
- if (!op || ((op-1) & op))
- /* "You must specify exactly one operation" */
- show_usage_and_die(program_usage_string, program_options);
- argv += optind;
- argc -= optind;
- if (argc > 1
- /* dont_need_arg == have_arg? bad in both cases:
- * TRUE == TRUE (dont need arg but have) or
- * FALSE == FALSE (need arg but havent).
- * OPT_list_events is an exception, it can be used in both cases.
- */
- || ((op != OPT_list_events) && (!(opts & OPTMASK_need_arg) == argc))
- ) {
- show_usage_and_die(program_usage_string, program_options);
- }
-
- if (op == OPT_version)
- {
- printf("%s "VERSION"\n", g_progname);
- return 0;
- }
-
- export_abrt_envvars(opts & OPT_p);
- if (opts & OPT_s)
- {
- openlog(msg_prefix, 0, LOG_DAEMON);
- logmode = LOGMODE_SYSLOG;
- }
-
- char *dump_dir_name = argv[0];
- bool full = (opts & OPT_f);
- bool always = (opts & OPT_y);
-
- if (!D_list)
- {
- char *home = getenv("HOME");
- if (home)
- D_list = g_list_append(D_list, concat_path_file(home, ".abrt/spool"));
- D_list = g_list_append(D_list, (void*)DEBUG_DUMPS_DIR);
- }
-
- /* Get settings */
- load_event_config_data();
-
- /* Do the selected operation. */
- int exitcode = 0;
- switch (op)
- {
- case OPT_list:
- {
- vector_of_problem_data_t *ci = new_vector_of_problem_data();
- while (D_list)
- {
- char *dir = (char *)D_list->data;
- GetCrashInfos(ci, dir);
- D_list = g_list_remove(D_list, dir);
- }
- print_crash_list(ci, full);
- free_vector_of_problem_data(ci);
- break;
- }
- case OPT_list_events: /* -L[PREFIX] */
- {
- /* Note that dump_dir_name may be NULL here, it means "show all
- * possible events regardless of dir"
- */
- char *events = list_possible_events(NULL, dump_dir_name, pfx);
- if (!events)
- return 1; /* error msg is already logged */
- fputs(events, stdout);
- free(events);
- break;
- }
- case OPT_run_event: /* -e EVENT: run event */
- {
- struct run_event_state *run_state = new_run_event_state();
- run_state->logging_callback = do_log;
- int r = run_event_on_dir_name(run_state, dump_dir_name, event_name);
- if (r == 0 && run_state->children_count == 0)
- error_msg_and_die("No actions are found for event '%s'", event_name);
- free_run_event_state(run_state);
- break;
- }
- case OPT_analyze:
- {
- /* Load problem_data from dump dir */
- struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
- if (!dd)
- return 1;
- char *analyze_events_as_lines = list_possible_events(dd, NULL, "analyze");
- dd_close(dd);
-
- if (analyze_events_as_lines && *analyze_events_as_lines)
- {
- GList *list_analyze_events = str_to_glist(analyze_events_as_lines, '\n');
- char *event = select_event_option(list_analyze_events);
- list_free_with_free(list_analyze_events);
- exitcode = run_analyze_event(dump_dir_name, event);
- free(event);
- }
- free(analyze_events_as_lines);
- break;
- }
- case OPT_report:
- {
- struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
- if (!dd)
- break;
- int readonly = !dd->locked;
- dd_close(dd);
- if (readonly)
- {
- log("'%s' is not writable", dump_dir_name);
- /* D_list can't be NULL here */
- struct dump_dir *dd_copy = steal_directory((char *)D_list->data, dump_dir_name);
- if (dd_copy)
- {
- delete_dump_dir_possibly_using_abrtd(dump_dir_name);
- dump_dir_name = xstrdup(dd_copy->dd_dirname);
- dd_close(dd_copy);
- }
- }
-
- exitcode = report(dump_dir_name, (always ? CLI_REPORT_BATCH : 0));
- if (exitcode == -1)
- error_msg_and_die("Crash '%s' not found", dump_dir_name);
- break;
- }
- case OPT_delete:
- {
- exitcode = delete_dump_dir_possibly_using_abrtd(dump_dir_name);
- break;
- }
- case OPT_info:
- {
- /* Load problem_data from dump dir */
- struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
- if (!dd)
- return -1;
-
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
-
- add_to_problem_data_ext(problem_data, CD_DUMPDIR, dump_dir_name,
- CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE);
-
- print_crash_info(problem_data, full);
- free_problem_data(problem_data);
-
- break;
- }
- }
-
- return exitcode;
-}