diff options
| author | Nikola Pajkovsky <npajkovs@redhat.com> | 2011-03-11 13:18:03 +0100 |
|---|---|---|
| committer | Nikola Pajkovsky <npajkovs@redhat.com> | 2011-03-11 13:18:03 +0100 |
| commit | d9cd2ab6ef3ebe4bb7883690efeb1b8dcb4c3c65 (patch) | |
| tree | 6bbc245bd8fdea789094d1b40e54af0c8c436689 /src/cli/CLI.cpp | |
| parent | 2c1ca7753ca7d11640c14491c3d76124d2cba7d8 (diff) | |
| download | abrt-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.cpp | 432 |
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; -} |
