summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2010-06-29 16:53:14 +0200
committerKarel Klic <kklic@redhat.com>2010-06-29 16:53:14 +0200
commit8f7b587963763d06790ea028f16994eff31f9358 (patch)
tree29666f0dee5a9dd969dcefc7f84dc1701ecf809a
parent8b2e49a8152d49831e357d1f128848d6c4dab889 (diff)
parent213dedf33bca5b2b51457999ac79cc64140af5c8 (diff)
downloadabrt-8f7b587963763d06790ea028f16994eff31f9358.tar.gz
abrt-8f7b587963763d06790ea028f16994eff31f9358.tar.xz
abrt-8f7b587963763d06790ea028f16994eff31f9358.zip
Merge branch 'cli'
-rw-r--r--src/CLI/CLI.cpp240
-rw-r--r--src/CLI/abrt-cli.123
-rw-r--r--src/CLI/abrt-cli.bash26
3 files changed, 176 insertions, 113 deletions
diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp
index cd530e75..d882161a 100644
--- a/src/CLI/CLI.cpp
+++ b/src/CLI/CLI.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2009 RedHat inc.
+ 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
@@ -35,55 +35,54 @@
# define _(S) (S)
#endif
-/* Program options */
-enum
+/** Prints basic information about a crash to stdout. */
+static void print_crash(const map_crash_data_t &crash)
{
- OPT_VERSION,
- OPT_HELP,
- OPT_GET_LIST,
- OPT_GET_LIST_FULL,
- OPT_REPORT,
- OPT_REPORT_ALWAYS,
- OPT_DELETE
-};
+ /* Create a localized string from crash time. */
+ const char *timestr = get_crash_data_item_content(crash, FILENAME_TIME).c_str();
+ long time = xatou(timestr);
+ char timeloc[256];
+ int success = strftime(timeloc, 128, "%c", localtime(&time));
+ if (!success)
+ error_msg_and_die("Error while converting time to string.");
+
+ printf(_("\tUID : %s\n"
+ "\tUUID : %s\n"
+ "\tPackage : %s\n"
+ "\tExecutable : %s\n"
+ "\tCrash Time : %s\n"
+ "\tCrash Count: %s\n"),
+ get_crash_data_item_content(crash, CD_UID).c_str(),
+ get_crash_data_item_content(crash, CD_UUID).c_str(),
+ get_crash_data_item_content(crash, FILENAME_PACKAGE).c_str(),
+ get_crash_data_item_content(crash, FILENAME_EXECUTABLE).c_str(),
+ timeloc,
+ get_crash_data_item_content(crash, CD_COUNT).c_str());
+}
-static void print_crash_infos(vector_map_crash_data_t& pCrashInfos, int pMode)
+/**
+ * Prints a list containing "crashes" to stdout.
+ * @param include_reported
+ * Do not skip entries marked as already reported.
+ */
+static void print_crash_list(const vector_map_crash_data_t& crash_list, bool include_reported)
{
- unsigned int ii;
- for (ii = 0; ii < pCrashInfos.size(); ii++)
+ for (unsigned i = 0; i < crash_list.size(); ++i)
{
- map_crash_data_t& info = pCrashInfos[ii];
- if (pMode == OPT_GET_LIST_FULL || get_crash_data_item_content(info, CD_REPORTED) != "1")
- {
- const char *timestr = get_crash_data_item_content(info, FILENAME_TIME).c_str();
- long time = strtol(timestr, NULL, 10);
- if (time == 0)
- error_msg_and_die("Error while converting time string.");
-
- char timeloc[256];
- int success = strftime(timeloc, 128, "%c", localtime(&time));
- if (!success)
- error_msg_and_die("Error while converting time to string.");
+ const map_crash_data_t& crash = crash_list[i];
+ if (get_crash_data_item_content(crash, CD_REPORTED) == "1" && !include_reported)
+ continue;
- printf(_("%u.\n"
- "\tUID : %s\n"
- "\tUUID : %s\n"
- "\tPackage : %s\n"
- "\tExecutable : %s\n"
- "\tCrash Time : %s\n"
- "\tCrash Count: %s\n"),
- ii,
- get_crash_data_item_content(info, CD_UID).c_str(),
- get_crash_data_item_content(info, CD_UUID).c_str(),
- get_crash_data_item_content(info, FILENAME_PACKAGE).c_str(),
- get_crash_data_item_content(info, FILENAME_EXECUTABLE).c_str(),
- timeloc,
- get_crash_data_item_content(info, CD_COUNT).c_str()
- );
- }
+ printf("%u.\n", i);
+ print_crash(crash);
}
}
+/**
+ * Converts crash reference from user's input to unique crash identification
+ * in form UID:UUID.
+ * The returned string must be released by caller.
+ */
static char *guess_crash_id(const char *str)
{
vector_map_crash_data_t ci = call_GetCrashInfos();
@@ -122,16 +121,32 @@ static char *guess_crash_id(const char *str)
return result;
}
+/* Program options */
+enum
+{
+ OPT_GET_LIST,
+ OPT_REPORT,
+ OPT_DELETE
+};
+
+/**
+ * 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, OPT_HELP },
- { "version" , no_argument , NULL, OPT_VERSION },
- { "get-list" , no_argument , NULL, OPT_GET_LIST },
- { "get-list-full", no_argument , NULL, OPT_GET_LIST_FULL },
- { "report" , required_argument, NULL, OPT_REPORT },
- { "report-always", required_argument, NULL, OPT_REPORT_ALWAYS },
- { "delete" , required_argument, NULL, OPT_DELETE },
+ { "help" , no_argument, NULL, '?' },
+ { "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' },
{ 0, 0, 0, 0 } /* prevents crashes for unknown options*/
};
@@ -144,7 +159,10 @@ static const char *progname(const char *argv0)
return argv0;
}
-/* Prints abrt-cli version and some help text. */
+/**
+ * Prints abrt-cli version and some help text.
+ * Then exits the program with return value 1.
+ */
static void usage(char *argv0)
{
const char *name = progname(argv0);
@@ -156,23 +174,27 @@ static void usage(char *argv0)
" -V, --version display the version of %s and exit\n"
" -?, --help print this help\n\n"
"Actions:\n"
- " --get-list print list of crashes which are not reported yet\n"
- " --get-list-full print list of all crashes\n"
- " --report CRASH_ID create and send a report\n"
- " --report-always CRASH_ID create and send a report without asking\n"
- " --delete CRASH_ID remove crash\n"
+ " -l, --list print list of crashes which are not reported yet\n"
+ " -f, --full list all crashes, including already reported ones\n"
+ " -r, --report CRASH_ID create and send a report\n"
+ " -y, --always create and send a report without asking\n"
+ " -d, --delete CRASH_ID remove crash\n"
"CRASH_ID can be:\n"
" UID:UUID pair,\n"
" unique UUID prefix - the crash with matching UUID will be acted upon\n"
- " @N - N'th crash (as displayed by --get-list-full) will be acted upon\n"
+ " @N - N'th crash (as displayed by --list --full) will be acted upon\n"
),
name, name);
+
+ exit(1);
}
int main(int argc, char** argv)
{
const char* crash_id = NULL;
int op = -1;
+ bool full = false;
+ bool always = false;
setlocale(LC_ALL, "");
#if ENABLE_NLS
@@ -183,70 +205,96 @@ int main(int argc, char** argv)
while (1)
{
int option_index;
- int c = getopt_long_only(argc, argv, "?V", longopts, &option_index);
+ /* Do not use colons, arguments are handled after parsing all options. */
+ int c = getopt_long_only(argc, argv, "?Vrdlfy",
+ longopts, &option_index);
+
+#define SET_OP(newop) \
+ if (op != -1 && op != newop) \
+ { \
+ error_msg(_("You must specify exactly one operation.")); \
+ return 1; \
+ } \
+ op = newop;
+
switch (c)
{
- case OPT_REPORT:
- case OPT_REPORT_ALWAYS:
- case OPT_DELETE:
- crash_id = optarg;
- /* fall through */
- case OPT_GET_LIST:
- case OPT_GET_LIST_FULL:
- if (op == -1)
- break;
- error_msg(_("You must specify exactly one operation."));
- return 1;
- case -1: /* end of options */
- if (op != -1) /* if some operation was specified... */
- break;
- /* fall through */
- default:
- case '?':
- case OPT_HELP:
- usage(argv[0]);
- return 1;
- case 'V':
- case OPT_VERSION:
- printf("%s "VERSION"\n", progname(argv[0]));
- return 0;
+ case 'r': SET_OP(OPT_REPORT); break;
+ case 'd': SET_OP(OPT_DELETE); break;
+ case 'l': SET_OP(OPT_GET_LIST); break;
+ case 'f': full = true; break;
+ case 'y': always = true; break;
+ case -1: /* end of options */ break;
+ default: /* some error */
+ case '?':
+ usage(argv[0]); /* exits app */
+ case 'V':
+ printf("%s "VERSION"\n", progname(argv[0]));
+ return 0;
}
+#undef SET_OP
if (c == -1)
break;
- op = c;
}
-#ifdef ENABLE_DBUS
+ /* Handle option arguments. */
+ int arg_count = argc - optind;
+ switch (arg_count)
+ {
+ case 0:
+ if (op == OPT_REPORT || op == OPT_DELETE)
+ usage(argv[0]);
+ break;
+ case 1:
+ if (op != OPT_REPORT && op != OPT_DELETE)
+ usage(argv[0]);
+ crash_id = argv[optind];
+ break;
+ default:
+ usage(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) ||
+ op == -1)
+ {
+ usage(argv[0]);
+ return 1;
+ }
+
DBusError err;
dbus_error_init(&err);
s_dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
handle_dbus_err(s_dbus_conn == NULL, &err);
-#elif ENABLE_SOCKET
- CABRTSocket ABRTDaemon;
- ABRTDaemon.Connect(VAR_RUN"/abrt.socket");
-#endif
+ /* Do the selected operation. */
int exitcode = 0;
switch (op)
{
case OPT_GET_LIST:
- case OPT_GET_LIST_FULL:
{
vector_map_crash_data_t ci = call_GetCrashInfos();
- print_crash_infos(ci, op);
+ print_crash_list(ci, full);
break;
}
case OPT_REPORT:
- case OPT_REPORT_ALWAYS:
- exitcode = report(crash_id, (op == OPT_REPORT_ALWAYS)*CLI_REPORT_BATCH + CLI_REPORT_SILENT_IF_NOT_FOUND);
+ {
+ int flags = CLI_REPORT_SILENT_IF_NOT_FOUND;
+ if (always)
+ flags |= CLI_REPORT_BATCH;
+ exitcode = report(crash_id, flags);
if (exitcode == -1) /* no such crash_id */
{
crash_id = guess_crash_id(crash_id);
- exitcode = report(crash_id, (op == OPT_REPORT_ALWAYS) * CLI_REPORT_BATCH);
+ exitcode = report(crash_id, always ? CLI_REPORT_BATCH : 0);
if (exitcode == -1)
error_msg_and_die("Crash '%s' not found", crash_id);
}
break;
+ }
case OPT_DELETE:
{
exitcode = call_DeleteDebugDump(crash_id);
@@ -255,21 +303,13 @@ int main(int argc, char** argv)
crash_id = guess_crash_id(crash_id);
exitcode = call_DeleteDebugDump(crash_id);
if (exitcode == ENOENT)
- {
error_msg_and_die("Crash '%s' not found", crash_id);
- }
}
if (exitcode != 0)
- {
error_msg_and_die("Can't delete debug dump '%s'", crash_id);
- }
break;
}
}
-#if ENABLE_SOCKET
- ABRTDaemon.Disconnect();
-#endif
-
return exitcode;
}
diff --git a/src/CLI/abrt-cli.1 b/src/CLI/abrt-cli.1
index 4fe4bb42..dc3bf06d 100644
--- a/src/CLI/abrt-cli.1
+++ b/src/CLI/abrt-cli.1
@@ -19,18 +19,26 @@ Print a help message describing all of abrt-cli’s command-line options.
.PP
.B Crash action options
-.IP "\-\-get\-list"
+.IP "\-l, \-\-list"
Prints list of crashes which are not reported yet.
-.IP "\-\-get-list-full"
-Prints list of all crashes.
-.IP "\-\-report \fIUUID\fR"
+.IP "\-r, \-\-report \fIUUID\fR"
Creates a crash report and then the text editor is invoked on that
report. When you are done with editing the report just exit the editor
and then you will be asked if you want to send the report.
-.IP "\-\-report-always \fIUUID\fR"
-Creates and sends the crash report without asking.
-.IP "\-\-delete \fIUUID\fR"
+.IP "\-d, \-\-delete \fIUUID\fR"
Removes data about particular crash.
+
+.PP
+.B Listing options
+.IP "\-f, \-\-full"
+List all crashes, including already reported.
+
+.PP
+.B Report options
+.IP "\-y, \-\-always"
+Creates and sends the crash report automatically, without asking
+any questions.
+
.SH ENVIRONMENT VARIABLES
The editor used to edit the crash report is chosen from the ABRT_EDITOR
environment variable, the VISUAL environment variable, or the EDITOR
@@ -39,4 +47,3 @@ environment variable, in that order.
.IR abrtd (8),
.IR abrt.conf (5),
.IR abrt-plugins (7)
-
diff --git a/src/CLI/abrt-cli.bash b/src/CLI/abrt-cli.bash
index 10b086ae..fd0a85f3 100644
--- a/src/CLI/abrt-cli.bash
+++ b/src/CLI/abrt-cli.bash
@@ -1,22 +1,38 @@
# bash-completion add-on for abrt-cli(1)
# http://bash-completion.alioth.debian.org/
+# $1 = additional options for abrt-cli
+_abrt_list()
+{
+ echo $(abrt-cli --list $1 | grep UUID | awk '{print $3}')
+ return 0
+}
+
_abrt_cli()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
- opts="--help --version --get-list --get-list-full --report --report-always --delete"
+ opts="--help --version --list --report --delete"
#
# Complete the arguments to some of the basic commands.
#
case "${prev}" in
- --report|--report-always|--delete)
- local uuids=$(abrt-cli --get-list | grep UUID | awk '{print $3}')
- COMPREPLY=( $(compgen -W "${uuids}" -- ${cur}) )
- return 0
+ --list)
+ opts="--full"
+ ;;
+ --report)
+ # Include only not-yet-reported crashes.
+ opts="--always $(_abrt_list)"
+ ;;
+ --always) # This is for --report --always
+ # Include only not-yet-reported crashes.
+ opts=$(_abrt_list)
+ ;;
+ --delete)
+ opts=$(_abrt_list "--full")
;;
esac