summaryrefslogtreecommitdiffstats
path: root/src/cli/CLI.cpp
diff options
context:
space:
mode:
authorNikola Pajkovsky <npajkovs@redhat.com>2011-03-11 13:18:03 +0100
committerNikola Pajkovsky <npajkovs@redhat.com>2011-03-11 13:18:03 +0100
commitd9cd2ab6ef3ebe4bb7883690efeb1b8dcb4c3c65 (patch)
tree6bbc245bd8fdea789094d1b40e54af0c8c436689 /src/cli/CLI.cpp
parent2c1ca7753ca7d11640c14491c3d76124d2cba7d8 (diff)
downloadabrt-d9cd2ab6ef3ebe4bb7883690efeb1b8dcb4c3c65.tar.gz
abrt-d9cd2ab6ef3ebe4bb7883690efeb1b8dcb4c3c65.tar.xz
abrt-d9cd2ab6ef3ebe4bb7883690efeb1b8dcb4c3c65.zip
CLI.cpp -> cli.c
Signed-off-by: Nikola Pajkovsky <npajkovs@redhat.com>
Diffstat (limited to 'src/cli/CLI.cpp')
-rw-r--r--src/cli/CLI.cpp432
1 files changed, 0 insertions, 432 deletions
diff --git a/src/cli/CLI.cpp b/src/cli/CLI.cpp
deleted file mode 100644
index 49c08279..00000000
--- a/src/cli/CLI.cpp
+++ /dev/null
@@ -1,432 +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 "abrt_dbus.h"
-#include "report.h"
-
-/** Creates a localized string from crash time. */
-static char *localize_crash_time(const char *timestr)
-{
- long time = xatou(timestr);
- char timeloc[256];
- int success = strftime(timeloc, sizeof(timeloc), "%c", localtime(&time));
- if (!success)
- error_msg_and_die("Error while converting time '%s' to string", timestr);
- return xstrdup(timeloc);
-}
-
-static crash_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;
-
- crash_data_t *crash_data = create_crash_data_from_dump_dir(dd);
- dd_close(dd);
- add_to_crash_data_ext(crash_data, CD_DUMPDIR, dump_dir_name, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE);
-
- return crash_data;
-}
-
-static void GetCrashInfos(vector_of_crash_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)
- ) {
- crash_data_t *crash_data = FillCrashInfo(dump_dir_name);
- if (crash_data)
- g_ptr_array_add(retval, crash_data);
- }
- free(dump_dir_name);
- }
- closedir(dir);
- }
-}
-
-/** Prints basic information about a crash to stdout. */
-static void print_crash(crash_data_t *crash_data)
-{
- /* Create a localized string from crash time. */
- const char *timestr = get_crash_item_content_or_die(crash_data, FILENAME_TIME);
- char *timeloc = localize_crash_time(timestr);
-
- printf(_("\tCrash dump : %s\n"
- "\tUID : %s\n"
- "\tPackage : %s\n"
- "\tExecutable : %s\n"
- "\tCrash Time : %s\n"
- "\tCrash Count: %s\n"),
- get_crash_item_content_or_NULL(crash_data, CD_DUMPDIR),
- get_crash_item_content_or_NULL(crash_data, FILENAME_UID),
- get_crash_item_content_or_NULL(crash_data, FILENAME_PACKAGE),
- get_crash_item_content_or_NULL(crash_data, FILENAME_EXECUTABLE),
- timeloc,
- get_crash_item_content_or_NULL(crash_data, FILENAME_COUNT)
- );
-
- free(timeloc);
-
- /* Print the hostname if it's available. */
- const char *hostname = get_crash_item_content_or_NULL(crash_data, FILENAME_HOSTNAME);
- if (hostname)
- printf(_("\tHostname : %s\n"), hostname);
-}
-
-/**
- * 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_crash_data_t *crash_list, bool include_reported)
-{
- for (unsigned i = 0; i < crash_list->len; ++i)
- {
- crash_data_t *crash = get_crash_data(crash_list, i);
- if (!include_reported)
- {
- const char *msg = get_crash_item_content_or_NULL(crash, FILENAME_MESSAGE);
- if (!msg || !msg[0])
- continue;
- }
-
- printf("%u.\n", i);
- print_crash(crash);
- }
-}
-
-/**
- * Prints full information about a crash
- */
-static void print_crash_info(crash_data_t *crash_data, bool show_backtrace)
-{
- const char *timestr = get_crash_item_content_or_die(crash_data, FILENAME_TIME);
- char *timeloc = localize_crash_time(timestr);
-
- printf(_("Dump directory: %s\n"
- "Last crash: %s\n"
- "Analyzer: %s\n"
- "Component: %s\n"
- "Package: %s\n"
- "Command: %s\n"
- "Executable: %s\n"
- "System: %s, kernel %s\n"
- "Reason: %s\n"),
- get_crash_item_content_or_die(crash_data, CD_DUMPDIR),
- timeloc,
- get_crash_item_content_or_die(crash_data, FILENAME_ANALYZER),
- get_crash_item_content_or_die(crash_data, FILENAME_COMPONENT),
- get_crash_item_content_or_die(crash_data, FILENAME_PACKAGE),
- get_crash_item_content_or_die(crash_data, FILENAME_CMDLINE),
- get_crash_item_content_or_die(crash_data, FILENAME_EXECUTABLE),
- get_crash_item_content_or_die(crash_data, FILENAME_OS_RELEASE),
- get_crash_item_content_or_die(crash_data, FILENAME_KERNEL),
- get_crash_item_content_or_die(crash_data, FILENAME_REASON)
- );
-
- free(timeloc);
-
- /* Print optional fields only if they are available */
-
- /* Coredump is not present in kerneloopses and Python exceptions. */
- const char *coredump = get_crash_item_content_or_NULL(crash_data, FILENAME_COREDUMP);
- if (coredump)
- printf(_("Coredump file: %s\n"), coredump);
-
- const char *rating = get_crash_item_content_or_NULL(crash_data, FILENAME_RATING);
- if (rating)
- printf(_("Rating: %s\n"), rating);
-
- /* Crash function is not present in kerneloopses, and before the full report is created.*/
- const char *crash_function = get_crash_item_content_or_NULL(crash_data, FILENAME_CRASH_FUNCTION);
- if (crash_function)
- printf(_("Crash function: %s\n"), crash_function);
-
- const char *hostname = get_crash_item_content_or_NULL(crash_data, FILENAME_HOSTNAME);
- if (hostname)
- printf(_("Hostname: %s\n"), hostname);
-
- const char *comment = get_crash_item_content_or_NULL(crash_data, FILENAME_COMMENT);
- if (comment)
- printf(_("\nComment:\n%s\n"), comment);
-
- if (show_backtrace)
- {
- const char *backtrace = get_crash_item_content_or_NULL(crash_data, FILENAME_BACKTRACE);
- if (backtrace)
- printf(_("\nBacktrace:\n%s\n"), backtrace);
- }
-}
-
-/* Program options */
-enum
-{
- OPT_GET_LIST,
- OPT_REPORT,
- OPT_DELETE,
- OPT_INFO
-};
-
-/**
- * Long options.
- * Do not use the has_arg field. Arguments are handled after parsing all options.
- * The reason is that we want to use all the following combinations:
- * --report ID
- * --report ID --always
- * --report --always ID
- */
-static const struct option longopts[] =
-{
- /* name, has_arg, flag, val */
- { "help" , no_argument, NULL, '?' },
- { "verbose" , no_argument, NULL, 'v' },
- { "version" , no_argument, NULL, 'V' },
- { "list" , no_argument, NULL, 'l' },
- { "full" , no_argument, NULL, 'f' },
- { "always" , no_argument, NULL, 'y' },
- { "report" , no_argument, NULL, 'r' },
- { "delete" , no_argument, NULL, 'd' },
- { "info" , no_argument, NULL, 'i' },
- { "backtrace", no_argument, NULL, 'b' },
- { 0, 0, 0, 0 } /* prevents crashes for unknown options*/
-};
-
-/* Gets the program name from the first command line argument. */
-static const char *progname(const char *argv0)
-{
- const char* name = strrchr(argv0, '/');
- if (name)
- return ++name;
- return argv0;
-}
-
-/**
- * Prints abrt-cli version and some help text.
- * Then exits the program with return value 1.
- */
-static void print_usage_and_die(char *argv0)
-{
- const char *name = progname(argv0);
- printf("%s "VERSION"\n\n", name);
-
- /* Message has embedded tabs. */
- printf(_(
- "Usage: %s -l[f] [-D BASE_DIR]...]\n"
- " or: %s -r[y] CRASH_DIR\n"
- " or: %s -i[b] CRASH_DIR\n"
- " or: %s -d CRASH_DIR\n"
- "\n"
- " -l, --list List not yet reported crashes\n"
- " -f, --full List all crashes\n"
- " -D BASE_DIR Directory to list crashes from\n"
- " (default: -D $HOME/.abrt/spool -D %s)\n"
- "\n"
- " -r, --report Send a report about CRASH_DIR\n"
- " -y, --always ...without editing and asking\n"
- " -i, --info Print detailed information about CRASH_DIR\n"
- " -b, --backtrace ...including backtrace\n"
- " -d, --delete Remove CRASH_DIR\n"
- "\n"
- " -V, --version Display version and exit\n"
- " -v, --verbose Be verbose\n"
- ),
- name, name, name, name,
- DEBUG_DUMPS_DIR
- );
- exit(1);
-}
-
-int main(int argc, char** argv)
-{
- GList *D_list = NULL;
- char *dump_dir_name = NULL;
- int op = -1;
- bool full = false;
- bool always = false;
- bool backtrace = false;
-
- setlocale(LC_ALL, "");
-#if ENABLE_NLS
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-#endif
-
- while (1)
- {
- /* Do not use colons, arguments are handled after parsing all options. */
- int c = getopt_long(argc, argv, "?Vvrdlfyib", longopts, NULL);
-
-#define SET_OP(newop) \
- do { \
- if (op != -1 && op != newop) \
- error_msg_and_die(_("You must specify exactly one operation")); \
- op = newop; \
- } while (0)
-
- switch (c)
- {
- case -1: goto end_of_arg_parsing;
- case 'r': SET_OP(OPT_REPORT); break;
- case 'd': SET_OP(OPT_DELETE); break;
- case 'l': SET_OP(OPT_GET_LIST); break;
- case 'i': SET_OP(OPT_INFO); break;
- case 'f': full = true; break;
- case 'y': always = true; break;
- case 'b': backtrace = true; break;
- case 'v': g_verbose++; break;
- case 'D':
- D_list = g_list_append(D_list, optarg);
- break;
- case 'V':
- printf("%s "VERSION"\n", progname(argv[0]));
- return 0;
- case '?':
- default: /* some error */
- print_usage_and_die(argv[0]); /* exits app */
- }
-#undef SET_OP
- }
- end_of_arg_parsing: ;
-
- 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);
- }
-
- /* Handle option arguments. */
- argc -= optind;
- switch (argc)
- {
- case 0:
- if (op == OPT_REPORT || op == OPT_DELETE || op == OPT_INFO)
- print_usage_and_die(argv[0]);
- break;
- case 1:
- if (op != OPT_REPORT && op != OPT_DELETE && op != OPT_INFO)
- print_usage_and_die(argv[0]);
- dump_dir_name = argv[optind];
- break;
- default:
- print_usage_and_die(argv[0]);
- }
-
- /* Check if we have an operation.
- * Limit --full and --always to certain operations.
- */
- if ((full && op != OPT_GET_LIST) ||
- (always && op != OPT_REPORT) ||
- (backtrace && op != OPT_INFO) ||
- op == -1)
- {
- print_usage_and_die(argv[0]);
- }
-
- /* Do the selected operation. */
- int exitcode = 0;
- switch (op)
- {
- case OPT_GET_LIST:
- {
- vector_of_crash_data_t *ci = new_vector_of_crash_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_crash_data(ci);
- 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:
- {
- if (run_analyze_event(dump_dir_name) != 0)
- return 1;
-
- /* Load crash_data from (possibly updated by analyze) dump dir */
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return -1;
- crash_data_t *crash_data = create_crash_data_from_dump_dir(dd);
- dd_close(dd);
- add_to_crash_data_ext(crash_data, CD_DUMPDIR, dump_dir_name,
- CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE);
-
- print_crash_info(crash_data, backtrace);
- free_crash_data(crash_data);
-
- break;
- }
- }
-
- return exitcode;
-}