From 3d8d0cad460722317a1b95d99c669b98042056d6 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 13 Oct 2009 14:34:42 +0200 Subject: Manpage registered in autotools. --- src/CLI/Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CLI/Makefile.am b/src/CLI/Makefile.am index 9447791b..a428c740 100644 --- a/src/CLI/Makefile.am +++ b/src/CLI/Makefile.am @@ -3,6 +3,7 @@ bin_PROGRAMS = abrt-cli abrt_cli_SOURCES = \ CLI.cpp \ ABRTSocket.h ABRTSocket.cpp + abrt_cli_CPPFLAGS = \ -I$(srcdir)/../../inc \ -I$(srcdir)/../../lib/Utils \ @@ -11,5 +12,10 @@ abrt_cli_CPPFLAGS = \ $(DBUS_CFLAGS) \ -D_GNU_SOURCE # $(GTK_CFLAGS) + abrt_cli_LDADD = \ ../../lib/Utils/libABRTUtils.la + +man_MANS = abrt-cli.1 +EXTRA_DIST = $(man_MANS) + -- cgit From 02181285b7cd564baa3898641798c66fdacddfaf Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 13 Oct 2009 15:36:30 +0200 Subject: Initial bash completition file for abrt-cli --- src/CLI/abrt-cli.bash-completition | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/CLI/abrt-cli.bash-completition diff --git a/src/CLI/abrt-cli.bash-completition b/src/CLI/abrt-cli.bash-completition new file mode 100644 index 00000000..089d5a3f --- /dev/null +++ b/src/CLI/abrt-cli.bash-completition @@ -0,0 +1,34 @@ +# bash-completion add-on for abrt-cli(1) +# http://bash-completion.alioth.debian.org/ + +_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" + + # + # 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 + ;; + esac + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 +} +complete -F _abrt_cli abrt-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh \ No newline at end of file -- cgit From 83098ad13a244a5d64595750764b88dc4371bc71 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 13 Oct 2009 15:45:41 +0200 Subject: Better name for the bash completion script --- src/CLI/abrt-cli.bash | 34 ++++++++++++++++++++++++++++++++++ src/CLI/abrt-cli.bash-completition | 34 ---------------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 src/CLI/abrt-cli.bash delete mode 100644 src/CLI/abrt-cli.bash-completition diff --git a/src/CLI/abrt-cli.bash b/src/CLI/abrt-cli.bash new file mode 100644 index 00000000..089d5a3f --- /dev/null +++ b/src/CLI/abrt-cli.bash @@ -0,0 +1,34 @@ +# bash-completion add-on for abrt-cli(1) +# http://bash-completion.alioth.debian.org/ + +_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" + + # + # 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 + ;; + esac + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 +} +complete -F _abrt_cli abrt-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh \ No newline at end of file diff --git a/src/CLI/abrt-cli.bash-completition b/src/CLI/abrt-cli.bash-completition deleted file mode 100644 index 089d5a3f..00000000 --- a/src/CLI/abrt-cli.bash-completition +++ /dev/null @@ -1,34 +0,0 @@ -# bash-completion add-on for abrt-cli(1) -# http://bash-completion.alioth.debian.org/ - -_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" - - # - # 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 - ;; - esac - - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 -} -complete -F _abrt_cli abrt-cli - -# Local variables: -# mode: shell-script -# sh-basic-offset: 4 -# sh-indent-comment: t -# indent-tabs-mode: nil -# End: -# ex: ts=4 sw=4 et filetype=sh \ No newline at end of file -- cgit From 52a0b7b894c1e7882e5e576d960539f823c8d95b Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Tue, 13 Oct 2009 15:46:14 +0200 Subject: new version --- abrt.spec | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/abrt.spec b/abrt.spec index 892653cb..2cb077bf 100644 --- a/abrt.spec +++ b/abrt.spec @@ -3,8 +3,8 @@ %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} Summary: Automatic bug detection and reporting tool Name: abrt -Version: 0.0.9 -Release: 3%{?dist} +Version: 0.0.10 +Release: 1%{?dist} License: GPLv2+ Group: Applications/System URL: https://fedorahosted.org/abrt/ diff --git a/configure.ac b/configure.ac index c8c03889..aa9579ba 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([abrt], [0.0.9], [jmoskovc@redhat.com]) +AC_INIT([abrt], [0.0.10], [jmoskovc@redhat.com]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) -- cgit From 9675b33dd8e0f4b5fe4fe1ac41b3bd147b49c20f Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 13 Oct 2009 15:51:35 +0200 Subject: Bash completion installed during "make install" --- src/CLI/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CLI/Makefile.am b/src/CLI/Makefile.am index a428c740..0167149b 100644 --- a/src/CLI/Makefile.am +++ b/src/CLI/Makefile.am @@ -19,3 +19,6 @@ abrt_cli_LDADD = \ man_MANS = abrt-cli.1 EXTRA_DIST = $(man_MANS) +completiondir = $(sysconfdir)/bash_completion.d +completion_DATA = abrt-cli.bash + -- cgit From 04def0de8ab5854b82d48f7f72fe9076a5a7d24f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Oct 2009 12:27:08 +0200 Subject: better logging of execv parameters Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 34201174..04db283e 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -87,6 +87,18 @@ static std::string CreateHash(const std::string& pInput) return hash_str; } +static std::string concat_str_vector(char **strings) +{ + std::string result; + while (*strings) + { + result += *strings++; + if (*strings) + result += ' '; + } + return result; +} + static pid_t ExecVP(char** pArgs, uid_t uid, std::string& pOutput) { int pipeout[2]; @@ -107,11 +119,7 @@ static pid_t ExecVP(char** pArgs, uid_t uid, std::string& pOutput) } if (child == 0) { - VERB1 log("Executing: %s %s %s %s", pArgs[0] - ,pArgs[1] ? pArgs[1] : "" - ,pArgs[1] && pArgs[2] ? pArgs[2] : "" - ,pArgs[1] && pArgs[2] && pArgs[3] ? pArgs[3] : "" - ); + VERB1 log("Executing: %s", concat_str_vector(pArgs).c_str()); close(pipeout[0]); /* read side of the pipe */ xmove_fd(pipeout[1], STDOUT_FILENO); /* Make sure stdin is safely open to nothing */ -- cgit From ba6ab638512e5619b9955470b7158b3b1035de90 Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Thu, 15 Oct 2009 14:11:23 +0200 Subject: made polkit policy to be more permissive - debuginfo install only worked under root --- src/Daemon/org.fedoraproject.abrt.policy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Daemon/org.fedoraproject.abrt.policy b/src/Daemon/org.fedoraproject.abrt.policy index 1c2c0bb0..9261acdc 100644 --- a/src/Daemon/org.fedoraproject.abrt.policy +++ b/src/Daemon/org.fedoraproject.abrt.policy @@ -30,9 +30,9 @@ Copyright (c) 2009 Red Hat inc. Install debuginfos Installing debuginfos requires authentication - no + yes yes - no + yes -- cgit From 545141b166159c9bc39358c50ed3e9f31da0a97a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Oct 2009 14:49:53 +0200 Subject: lib/Plugins/CCpp.cpp: log polkit_check_authorization failures Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 04db283e..c6d3b557 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -600,35 +600,29 @@ std::string CAnalyzerCCpp::GetGlobalUUID(const std::string& pDebugDumpDir) static bool DebuginfoCheckPolkit(int uid) { - PolkitResult result; - int child_pid; - - child_pid = fork(); - + int child_pid = fork(); + if (child_pid < 0) + { + perror_msg_and_die("fork"); + } if (child_pid == 0) { //child - setuid(uid); - result = polkit_check_authorization(getpid(), + if (setuid(uid)) + exit(1); //paranoia + PolkitResult result = polkit_check_authorization(getpid(), "org.fedoraproject.abrt.install-debuginfos"); - if (result == PolkitYes) - { - exit(0); //authentication OK - } - exit(1); - } else - { - //parent - int status; - - waitpid(child_pid, &status, 0); - if (WEXITSTATUS(status) == 0) - { - return true; //authentication OK - } - return false; + exit(result != PolkitYes); //exit 1 (failure) if not allowed } + //parent + int status; + if (waitpid(child_pid, &status, 0) > 0 && WEXITSTATUS(status) == 0) + { + return true; //authorization OK + } + log("UID %d is not authorized to install debuginfos", uid); + return false; } void CAnalyzerCCpp::CreateReport(const std::string& pDebugDumpDir, int force) -- cgit From ee55e34836dbfbb0379ed3a2715648731d50a666 Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Thu, 15 Oct 2009 17:25:09 +0200 Subject: Added changelog --- abrt.spec | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/abrt.spec b/abrt.spec index 2cb077bf..dbb20a34 100644 --- a/abrt.spec +++ b/abrt.spec @@ -358,7 +358,31 @@ fi %defattr(-,root,root,-) %changelog -* Wed Sep 23 2009 jiri Moskovcak 0.0.9-2 +* Thu Oct 15 2009 Jiri Moskovcak 0.0.10-1 +- new version +- added more logging (vda.linux@googlemail.com) +- made polkit policy to be more permissive when installing debuginfo (jmoskovc@redhat.com) +- lib/Plugins/CCpp.cpp: add build-ids to backtrace (vda.linux@googlemail.com) +- lib/Plugins/CCpp.cpp: do not use temp file for gdb commands - use -ex CMD instead (vda.linux@googlemail.com) +- GUI: added refresh button, added sanity check to plugin settings (jmoskovc@redhat.com) +- Initial man page for abrt-cli (kklic@redhat.com) +- Added --version, -V, --help, -? options. Fixed crash caused by unknown option. (kklic@redhat.com) +- Date/time honors current system locale (kklic@redhat.com) +- fixed saving/reading user config (jmoskovc@redhat.com) +- SPEC: added gnome-python2-gnomekeyring to requirements (jmoskovc@redhat.com) +- GUI: call Report() with the latest pluginsettings (jmoskovc@redhat.com) +- Fix Bug 526220 - [abrt] crash detected in abrt-gui-0.0.9-2.fc12 (vda.linux@googlemail.com) +- removed unsecure reading/writting from ~HOME directory rhbz#522878 (jmoskovc@redhat.com) +- error checking added to archive creation (danny@rawhide.localdomain) +- try using pk-debuginfo-install before falling back to debuginfo-install (vda.linux@googlemail.com) +- abrt-gui: make "report" toolbar button work even if abrtd is not running (vda.linux@googlemail.com) +- set LIMIT_MESSAGE to 16k, typo fix and daemon now reads config information from dbus (npajkovs@redhat.com) +- add support for abrtd autostart (vda.linux@googlemail.com) +- GUI: reversed the dumplist, so the latest crashes are at the top (jmoskovc@redhat.com) +- rewrite FileTransfer to use library calls instead of commandline calls for compression (dnovotny@redhat.com) +- and many minor fixes .. + +* Wed Sep 23 2009 Jiri Moskovcak 0.0.9-2 - added bug-buddy to provides rhbz#524934 * Tue Sep 22 2009 Jiri Moskovcak 0.0.9-1 -- cgit From 87eef1ad558b1d5b61e81ef21c03b754b1524513 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Oct 2009 14:37:50 +0200 Subject: lib/Plugins/CCpp.cpp: fix a bug with detecting missing debuginfos Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 6 +++--- src/CLI/abrt-cli.1 | 4 ++-- src/Gui/ABRTExceptions.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index c6d3b557..0718323c 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -376,9 +376,10 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui log("Getting module names, file names, build IDs from core file"); std::string unstrip_list = run_unstrip_n(pDebugDumpDir); - log("Builting list of missing debuginfos"); + log("Building list of missing debuginfos"); // lines look like this: // 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe] + // or // 0x400000+0x209000 ab3c8286aac6c043fd1bb1cc2a0b88ec29517d3e@0x40024c /bin/sleep /usr/lib/debug/bin/sleep.debug [exe] // 0x7fff313ff000+0x1000 389c7475e3d5401c55953a425a2042ef62c4c7df@0x7fff313ff2f8 . - linux-vdso.so.1 vector_string_t missing; @@ -390,6 +391,7 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui c = *end; *end = '\0'; char* word2 = strchr(p, ' '); + p = end + 1; if (!word2) continue; word2++; @@ -420,8 +422,6 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui log("build_id:%s exists:%d", word2, (int)file_exists); if (!file_exists) missing.push_back(word2); - - p = end + 1; } while (c); free(dup); diff --git a/src/CLI/abrt-cli.1 b/src/CLI/abrt-cli.1 index fb0a7c89..5f132dfa 100644 --- a/src/CLI/abrt-cli.1 +++ b/src/CLI/abrt-cli.1 @@ -2,12 +2,12 @@ .SH NAME abrt\-cli \- a command line interface to abrt .SH SYNOPSIS -.B abrt\-cli +.B abrt\-cli [option] .SH DESCRIPTION .I abrt\-cli is a command line tool that manages application crashes catched by -.I abrtd +.I abrtd daemon. It enables access to crash data, and allows to report crashes depending on active abrt plugins. .SH OPTIONS diff --git a/src/Gui/ABRTExceptions.py b/src/Gui/ABRTExceptions.py index 30496384..0d357a30 100644 --- a/src/Gui/ABRTExceptions.py +++ b/src/Gui/ABRTExceptions.py @@ -14,11 +14,11 @@ class WrongData(Exception): def __str__(self): return self.what - + class ConfBackendInitError(Exception): def __init__(self, msg): Exception.__init__(self) self.what = msg - + def __str__(self): return self.what -- cgit From d61b353da2093a6dba08e11d08f786f407f8588d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Oct 2009 17:48:39 +0200 Subject: adding abrt-debuginfo-install script Signed-off-by: Denys Vlasenko --- abrt.spec | 1 + src/Daemon/Makefile.am | 5 +- src/Daemon/abrt-debuginfo-install | 135 ++++++++++++++++++++++++++++++++++++++ src/Gui/abrt-gui | 2 +- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100755 src/Daemon/abrt-debuginfo-install mode change 100644 => 100755 src/Gui/abrt-gui diff --git a/abrt.spec b/abrt.spec index dbb20a34..841bfe67 100644 --- a/abrt.spec +++ b/abrt.spec @@ -243,6 +243,7 @@ fi %defattr(-,root,root,-) %doc README COPYING %{_sbindir}/%{name}d +%{_bindir}/%{name}-debuginfo-install %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf %config(noreplace) %{_sysconfdir}/dbus-1/system.d/dbus-%{name}.conf %{_initrddir}/%{name}d diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am index 29c7f1be..0067e5dd 100644 --- a/src/Daemon/Makefile.am +++ b/src/Daemon/Makefile.am @@ -1,3 +1,5 @@ +bin_SCRIPTS = abrt-debuginfo-install + sbin_PROGRAMS = abrtd abrtd_SOURCES = \ @@ -43,7 +45,8 @@ comredhatabrtservicedir = ${datadir}/dbus-1/system-services dist_comredhatabrtservice_DATA = com.redhat.abrt.service man_MANS = abrtd.8 abrt.conf.5 -EXTRA_DIST = $(man_MANS) + +EXTRA_DIST = $(man_MANS) abrt-debuginfo-install DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install new file mode 100755 index 00000000..d8d306a6 --- /dev/null +++ b/src/Daemon/abrt-debuginfo-install @@ -0,0 +1,135 @@ +#!/bin/sh + +core=$1 +tempdir=$2 +cachedir=$3 +debug=false + +# Exitcodes: +# 0 - all debuginfos are installed +# 1 - not all debuginfos are installed +# 2+ - serious problem + +test -f "$core" || exit 2 +# cahcedir is optional +test x"$cachedir" = x"" || test -d "$cachedir" || exit 2 +# tempdir must not exist +test -d "$tempdir" && exit 2 +mkdir "$tempdir" || exit 2 +cd "$tempdir" || exit 2 + +$debug && echo "Installing rpms to $tempdir" + +# eu-unstrip output example: +# 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe] +# or +# 0x400000+0x20d000 233aa1a57e9ffda65f53efdaf5e5058657a39993@0x40024c /usr/libexec/im-settings-daemon /usr/lib/debug/usr/libexec/im-settings-daemon.debug [exe] +# 0x7fff5cdff000+0x1000 0d3eb4326fd7489fcf9b598269f1edc420e2c560@0x7fff5cdff2f8 . - linux-vdso.so.1 +# 0x3d15600000+0x208000 20196628d1bc062279622615cc9955554e5bb227@0x3d156001a0 /usr/lib64/libnotify.so.1.1.3 /usr/lib/debug/usr/lib64/libnotify.so.1.1.3.debug libnotify.so.1 +# 0x7fd8ae931000+0x62d000 dd49f44f958b5a11a1635523b2f09cb2e45c1734@0x7fd8ae9311a0 /usr/lib64/libgtk-x11-2.0.so.0.1600.6 /usr/lib/debug/usr/lib64/libgtk-x11-2.0.so.0.1600.6.debug +eu_unstrip_OUT=`eu-unstrip "--core=$core" -n 2>&1` +err=$? +printf "%s\nexitcode:%s\n" "$eu_unstrip_OUT" $err >eu_unstrip.OUT +test $err = 0 || exit 2 + +# Get space-separated list of all build-ids +# There can be duplicates (observed in real world) +build_ids=`printf "%s\n" "$eu_unstrip_OUT" \ +| while read junk1 build_id binary_file di_file lib_name junk2; do + build_id=${build_id%%@*} + + # This filters out linux-vdso.so, among others + test x"$lib_name" != x"[exe]" && test x"${binary_file:0:1}" != x"/" && continue + # Sanitize build_id: must be longer than 2 chars + test ${#build_id} -le 2 && continue + # Sanitize build_id: must have only hex digits + test x"${build_id//[0-9a-f]/}" != x"" && continue + + echo "$build_id" +done | sort | uniq | xargs` +$debug && echo "build_ids:$build_ids" + +# Which debuginfo files are missing? +missing_debuginfo_files=`for build_id in $build_ids; do + build_id1=${build_id:0:2} + build_id2=${build_id:2} + file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + test -f "/$file" && continue + test x"$cachedir" != x"" && test -f "$cachedir/$file" && continue + echo -n "/$file " +done` +$debug && echo "missing_debuginfo_files:$missing_debuginfo_files" + +test x"$missing_debuginfo_files" = x"" && exit 0 + +# We'll run something like: +# yum --enablerepo='*debuginfo*' --quiet provides \ +# /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \ +# /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ... +yum_provides_OUT=`yum --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files 2>&1` +err=$? +printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >yum_provides.OUT +test $err = 0 || exit 2 + +# The output is pretty machine-unfriendly: +# glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc +# Repo : rawhide-debuginfo +# Matched from: +# Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug +# +# 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus +# Repo : updates-debuginfo +# Matched from: +# Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug +# Need to massage it a lot. +# There can be duplicates (one package may provide many debuginfos). +packages=`printf "%s\n" "$yum_provides_OUT" \ +| grep -- -debuginfo- \ +| sed 's/^[0-9]*://' \ +| sed -e 's/ .*//' -e 's/:.*//' \ +| sort | uniq | xargs` +$debug && echo "packages:$packages" + +# yum may return "" here if it found no packages (say, if coredump is from a new, +# unreleased package fresh from koji). +test x"$packages" = x"" && exit 1 + +# Redirecting, since progress bar stuff only messes up our output +yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1 +err=$? +echo "exitcode:$err" >>yumdownloader.OUT +test $err = 0 || exit 2 + +for f in *.rpm; do + # Happens if no .rpm's were downloaded (yumdownloader problem) + # In this case, $f is the literal "*.rpm" string + test -f "$f" || exit 2 + $debug && echo "Processing: $f" + echo "Processing: $f" >>unpack.OUT + rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1 +done + +# Which debuginfo files are still missing, including those we just unpacked? +missing_debuginfo_files2=`for build_id in $build_ids; do + build_id1=${build_id:0:2} + build_id2=${build_id:2} + file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + test -f "/$file" && continue + test x"$cachedir" != x"" && test -f "$cachedir/$file" && continue + if test -f "$file"; then + # file is one of those we just installed. + # Cache it if cachedir is specified. + if test x"$cachedir" != x"" && test -d "$cachedir"; then + mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1" + # Note: this does not preserve symlinks. This is intentional + cp "$file" "$cachedir/$file" + fi + continue + fi + echo -n "/$file " +done` +$debug && echo "missing_debuginfo_files2:$missing_debuginfo_files2" + +test x"$missing_debuginfo_files2" = x"" && exit 0 + +exit 1 diff --git a/src/Gui/abrt-gui b/src/Gui/abrt-gui old mode 100644 new mode 100755 index dd0897c0..85bdebbc --- a/src/Gui/abrt-gui +++ b/src/Gui/abrt-gui @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/sh export PYTHONPATH=/usr/share/abrt export XLOGNAME=$LOGNAME exec /usr/bin/python /usr/share/abrt/CCMainWindow.py "$@" -- cgit From a0ad2aada47afdc78d6b807e7c51c854d50accda Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2009 01:40:28 +0200 Subject: wire up abrt-debuginfo-install to lib/Plugins/CCpp.cpp Tested. Seems to work better than what we had before. Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 154 ++++++-------------------------------- src/Daemon/abrt-debuginfo-install | 62 ++++++++++++--- 2 files changed, 72 insertions(+), 144 deletions(-) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 0718323c..40aadd24 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -172,10 +172,10 @@ static void GetBacktrace(const std::string& pDebugDumpDir, std::string& pBacktra char* args[9]; args[0] = (char*)"gdb"; args[1] = (char*)"-batch"; - // when/if we'll add support for networked debuginfos + // when/if gdb supports it: // (https://bugzilla.redhat.com/show_bug.cgi?id=528668): - //args[] = (char*)"-ex"; - //args[] = xasprintf("set debug-file-directory %s", dir); + //args[2] = (char*)"-ex"; + //args[3] = "set debug-file-directory /usr/lib/debug/.build-id:/var/cache/abrt-di/usr/lib/debug/.build-id"; /* * Unfortunately, "file BINARY_FILE" doesn't work well if BINARY_FILE * was deleted (as often happens during system updates): @@ -373,75 +373,9 @@ static std::string run_unstrip_n(const std::string& pDebugDumpDir) static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& build_ids) { - log("Getting module names, file names, build IDs from core file"); - std::string unstrip_list = run_unstrip_n(pDebugDumpDir); - - log("Building list of missing debuginfos"); - // lines look like this: - // 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe] - // or - // 0x400000+0x209000 ab3c8286aac6c043fd1bb1cc2a0b88ec29517d3e@0x40024c /bin/sleep /usr/lib/debug/bin/sleep.debug [exe] - // 0x7fff313ff000+0x1000 389c7475e3d5401c55953a425a2042ef62c4c7df@0x7fff313ff2f8 . - linux-vdso.so.1 - vector_string_t missing; - char *dup = xstrdup(unstrip_list.c_str()); - char *p = dup; - char c; - do { - char* end = strchrnul(p, '\n'); - c = *end; - *end = '\0'; - char* word2 = strchr(p, ' '); - p = end + 1; - if (!word2) - continue; - word2++; - char* endsp = strchr(word2, ' '); - if (!endsp) - continue; - /* endsp points to 2nd space in the line now*/ - - /* This filters out linux-vdso.so, among others */ - if (strstr(endsp, "[exe]") == NULL && endsp[1] != '/') - continue; - *endsp = '\0'; - char* at = strchrnul(word2, '@'); - *at = '\0'; - - bool file_exists = 1; - if (word2[0] && word2[1] && is_hexstr(word2)) - { - struct stat sb; - char *fn = xasprintf("/usr/lib/debug/.build-id/%.2s/%s.debug", word2, word2 + 2); - /* Not lstat: this is a symlink and we want link's TARGET to exist */ - file_exists = stat(fn, &sb) == 0 && S_ISREG(sb.st_mode); - free(fn); - build_ids += "build-id "; - build_ids += word2; - build_ids += file_exists ? " (debuginfo present)\n" : " (debuginfo absent)\n"; - } - log("build_id:%s exists:%d", word2, (int)file_exists); - if (!file_exists) - missing.push_back(word2); - } while (c); - free(dup); - - if (missing.size() == 0) - { - log("All debuginfos are present, not installing debuginfo packages"); - return; - } - //missing vector is unused for now, but TODO: use it to install only needed debuginfos - - std::string package; - { - CDebugDump dd; - dd.Open(pDebugDumpDir); - dd.LoadText(FILENAME_PACKAGE, package); - } - update_client(_("Searching for debug-info packages...")); - int pipein[2], pipeout[2]; + int pipein[2], pipeout[2]; //TODO: get rid of pipein xpipe(pipein); xpipe(pipeout); @@ -462,45 +396,18 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui /*close(STDERR_FILENO);*/ setsid(); -/* Honestly, I do not know what is worse, pk-debuginfo-install or debuginfo-install: - -# pk-debuginfo-install -y -- coreutils-7.2-4.fc11 -1. Getting sources list...OK. Found 16 enabled and 23 disabled sources. -2. Finding debugging sources...OK. Found 0 disabled debuginfo repos. -3. Enabling debugging sources...OK. Enabled 0 debugging sources. -4. Finding debugging packages...Failed to find the package : more than one package found for -Failed to find the package : more than one package found for -FAILED. Found no packages to install. -5. Disabling sources previously enabled...OK. Disabled 0 debugging sources. - -:( FAIL! - -# debuginfo-install -y -- coreutils-7.2-4.fc11 -Loaded plugins: refresh-packagekit -Another application is holding the yum lock, cannot continue - -:( FAIL! - -# debuginfo-install -y -- coreutils-7.2-4.fc11 -(second time in a row - it worked) -*/ + char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir.c_str()); + char *tempdir = xasprintf("/tmp/abrt-%u-%lu", (int)getpid(), (long)time(NULL)); /* log() goes to stderr/syslog, it's ok to use it here */ - VERB1 log("Executing: %s %s %s %s", "pk-debuginfo-install", "-y", "--", package.c_str()); - execlp("pk-debuginfo-install", "pk-debuginfo-install", "-y", "--", package.c_str(), NULL); - /* fall back */ - VERB1 log("Executing: %s %s %s %s", "debuginfo-install", "-y", "--", package.c_str()); - execlp("debuginfo-install", "debuginfo-install", "-y", "--", package.c_str(), NULL); + VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, "/"); // "/var/cache/abrt-di" + execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, "/", NULL); exit(1); } close(pipein[0]); close(pipeout[1]); - /* Should not be needed (we use -y option), but just in case: */ - safe_write(pipein[1], "y\n", sizeof("y\n")-1); - close(pipein[1]); - update_client(_("Downloading and installing debug-info packages...")); FILE *pipeout_fp = fdopen(pipeout[0], "r"); @@ -511,50 +418,30 @@ Another application is holding the yum lock, cannot continue return; } -/* glx-utils, for example, do not have glx-utils-debuginfo package. - * Disabled code was causing failures in backtrace decoding. - * This does not seem to be useful. - */ -#ifdef COMPLAIN_IF_NO_DEBUGINFO - bool already_installed = false; -#endif char buff[1024]; - std::string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1)); while (fgets(buff, sizeof(buff), pipeout_fp)) { int last = strlen(buff) - 1; if (last >= 0 && buff[last] == '\n') buff[last] = '\0'; - /* log(buff); - update_client logs it too */ - update_client(buff); /* maybe only if buff != ""? */ - -#ifdef COMPLAIN_IF_NO_DEBUGINFO - if (already_installed == false) + if (strncmp(buff, "MISSING:", 8) == 0) { - /* "Package foo-debuginfo-1.2-5.ARCH already installed and latest version" */ - char* pn = strstr(buff, packageName.c_str()); - if (pn) - { - char* already_str = strstr(pn, "already installed and latest version"); - if (already_str) - { - already_installed = true; - } - } + build_ids += "Debuginfo absent: "; + build_ids += buff + 8; + build_ids += "\n"; } - if (already_installed == false && - (strstr(buff, "No debuginfo packages available to install") != NULL || - strstr(buff, "Could not find debuginfo for main pkg") != NULL || - strstr(buff, "Could not find debuginfo pkg for dependency package") != NULL)) + const char *p = buff; + while (*p == ' ' || *p == '\t') + { + p++; + } + if (*p) { - fclose(pipeout_fp); - kill(child, SIGTERM); - wait(NULL); - throw CABRTException(EXCEP_PLUGIN, std::string(__func__) + ": cannot install debuginfos for " + pPackage); + /* log(buff); - update_client logs it too */ + update_client(buff); } -#endif } fclose(pipeout_fp); @@ -665,6 +552,7 @@ void CAnalyzerCCpp::CreateReport(const std::string& pDebugDumpDir, int force) dd.Open(pDebugDumpDir); dd.SaveText(FILENAME_BACKTRACE, build_ids + backtrace); +log("BACKTRACE:'%s'", (build_ids + backtrace).c_str()); if (m_bMemoryMap) { dd.SaveText(FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install index d8d306a6..fe55250a 100755 --- a/src/Daemon/abrt-debuginfo-install +++ b/src/Daemon/abrt-debuginfo-install @@ -5,19 +5,28 @@ tempdir=$2 cachedir=$3 debug=false +count_words() { + echo $# +} + +exec 2>&1 + +# Output goes to GUI as debigunfo install log. +# "MISSING:xxxx" messages result in xxxx being prepended to backtrace + # Exitcodes: # 0 - all debuginfos are installed # 1 - not all debuginfos are installed # 2+ - serious problem test -f "$core" || exit 2 -# cahcedir is optional +# cachedir is optional test x"$cachedir" = x"" || test -d "$cachedir" || exit 2 # tempdir must not exist -test -d "$tempdir" && exit 2 +test -e "$tempdir" && exit 2 + mkdir "$tempdir" || exit 2 cd "$tempdir" || exit 2 - $debug && echo "Installing rpms to $tempdir" # eu-unstrip output example: @@ -27,6 +36,7 @@ $debug && echo "Installing rpms to $tempdir" # 0x7fff5cdff000+0x1000 0d3eb4326fd7489fcf9b598269f1edc420e2c560@0x7fff5cdff2f8 . - linux-vdso.so.1 # 0x3d15600000+0x208000 20196628d1bc062279622615cc9955554e5bb227@0x3d156001a0 /usr/lib64/libnotify.so.1.1.3 /usr/lib/debug/usr/lib64/libnotify.so.1.1.3.debug libnotify.so.1 # 0x7fd8ae931000+0x62d000 dd49f44f958b5a11a1635523b2f09cb2e45c1734@0x7fd8ae9311a0 /usr/lib64/libgtk-x11-2.0.so.0.1600.6 /usr/lib/debug/usr/lib64/libgtk-x11-2.0.so.0.1600.6.debug +echo "Getting list of build IDs" eu_unstrip_OUT=`eu-unstrip "--core=$core" -n 2>&1` err=$? printf "%s\nexitcode:%s\n" "$eu_unstrip_OUT" $err >eu_unstrip.OUT @@ -53,9 +63,19 @@ $debug && echo "build_ids:$build_ids" missing_debuginfo_files=`for build_id in $build_ids; do build_id1=${build_id:0:2} build_id2=${build_id:2} + file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + if test x"$cachedir" != x"" && test x"$cachedir" != x"/" ; then + test -f "$cachedir/$file" && continue + if test -f "/$file"; then + mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1" + # Note: this does not preserve symlinks. This is intentional + $debug && echo Copying "$file" to "$cachedir/$file" >&2 + cp "$file" "$cachedir/$file" + continue + fi + fi test -f "/$file" && continue - test x"$cachedir" != x"" && test -f "$cachedir/$file" && continue echo -n "/$file " done` $debug && echo "missing_debuginfo_files:$missing_debuginfo_files" @@ -66,6 +86,7 @@ test x"$missing_debuginfo_files" = x"" && exit 0 # yum --enablerepo='*debuginfo*' --quiet provides \ # /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \ # /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ... +echo "Determining list of packages for `count_words $missing_debuginfo_files` missing debuginfos" yum_provides_OUT=`yum --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files 2>&1` err=$? printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >yum_provides.OUT @@ -95,6 +116,7 @@ $debug && echo "packages:$packages" test x"$packages" = x"" && exit 1 # Redirecting, since progress bar stuff only messes up our output +echo "Downloading `count_words $packages` packages" yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1 err=$? echo "exitcode:$err" >>yumdownloader.OUT @@ -104,32 +126,50 @@ for f in *.rpm; do # Happens if no .rpm's were downloaded (yumdownloader problem) # In this case, $f is the literal "*.rpm" string test -f "$f" || exit 2 - $debug && echo "Processing: $f" + echo "Unpacking: $f" echo "Processing: $f" >>unpack.OUT rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1 done # Which debuginfo files are still missing, including those we just unpacked? -missing_debuginfo_files2=`for build_id in $build_ids; do +missing_build_ids=`for build_id in $build_ids; do build_id1=${build_id:0:2} build_id2=${build_id:2} + file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + test -f "/$file" && continue - test x"$cachedir" != x"" && test -f "$cachedir/$file" && continue + test x"$cachedir" != x"" \ + && test x"$cachedir" != x"/" \ + && test -f "$cachedir/$file" && continue + if test -f "$file"; then # file is one of those we just installed. # Cache it if cachedir is specified. if test x"$cachedir" != x"" && test -d "$cachedir"; then mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1" # Note: this does not preserve symlinks. This is intentional - cp "$file" "$cachedir/$file" + $debug && echo Copying "$file" to "$cachedir/$file" >&2 + cp --remove-destination "$file" "$cachedir/$file" fi continue fi - echo -n "/$file " + echo -n "$build_id " done` -$debug && echo "missing_debuginfo_files2:$missing_debuginfo_files2" +$debug && echo "missing_build_ids:$missing_build_ids" + +# If cachedir is specified, tempdir is just a staging area. Delete it +if test x"$cachedir" != x""; then + $debug && echo "Removing $tempdir" + rm -rf "$tempdir" +fi + +test x"$missing_build_ids" = x"" && exit 0 + +for missing in $missing_build_ids; do + echo "MISSING:$missing" +done -test x"$missing_debuginfo_files2" = x"" && exit 0 +echo "`count_words $missing_build_ids` debuginfos can't be found" exit 1 -- cgit From c9f43d22c5bf1d1bb392ee426c72d383b2241bbe Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Mon, 19 Oct 2009 12:02:25 +0200 Subject: ABRTSocket renamed DisConnect to Disconnect, CLI added localization support and commandline editor work in progress --- src/CLI/ABRTSocket.cpp | 9 +- src/CLI/ABRTSocket.h | 2 +- src/CLI/CLI.cpp | 219 ++++++++++++++++++++++++++++++++++++------------- src/CLI/Makefile.am | 1 + 4 files changed, 169 insertions(+), 62 deletions(-) diff --git a/src/CLI/ABRTSocket.cpp b/src/CLI/ABRTSocket.cpp index 1f90f63a..d31c7a4f 100644 --- a/src/CLI/ABRTSocket.cpp +++ b/src/CLI/ABRTSocket.cpp @@ -8,13 +8,12 @@ #include #include -CABRTSocket::CABRTSocket() : - m_nSocket(-1) +CABRTSocket::CABRTSocket() : m_nSocket(-1) {} CABRTSocket::~CABRTSocket() { - DisConnect(); + Disconnect(); } void CABRTSocket::Send(const std::string& pMessage) @@ -91,12 +90,10 @@ void CABRTSocket::Connect(const std::string& pPath) } } -void CABRTSocket::DisConnect() +void CABRTSocket::Disconnect() { if (m_nSocket != -1) - { close(m_nSocket); - } } vector_crash_infos_t CABRTSocket::GetCrashInfos() diff --git a/src/CLI/ABRTSocket.h b/src/CLI/ABRTSocket.h index d476411c..5d5383fa 100644 --- a/src/CLI/ABRTSocket.h +++ b/src/CLI/ABRTSocket.h @@ -18,7 +18,7 @@ class CABRTSocket ~CABRTSocket(); void Connect(const std::string& pPath); - void DisConnect(); + void Disconnect(); vector_crash_infos_t GetCrashInfos(); map_crash_report_t CreateReport(const std::string& pUUID); diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index 33272df5..d4e2bb4b 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -24,6 +24,15 @@ #if HAVE_CONFIG_H #include #endif +#if HAVE_LOCALE_H + #include +#endif +#if ENABLE_NLS + #include + #define _(S) gettext(S) +#else + #define _(S) (S) +#endif /* Program options */ enum @@ -47,25 +56,54 @@ static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) map_crash_info_t& info = pCrashInfos[ii]; if (pMode == OPT_GET_LIST_FULL || info.find(CD_REPORTED)->second[CD_CONTENT] != "1") { - printf("%u.\n" - "\tUID : %s\n" - "\tUUID : %s\n" - "\tPackage : %s\n" - "\tExecutable: %s\n" - "\tCrash time: %s\n" - "\tCrash Rate: %s\n", - ii, - info[CD_UID][CD_CONTENT].c_str(), - info[CD_UUID][CD_CONTENT].c_str(), - info[CD_PACKAGE][CD_CONTENT].c_str(), - info[CD_EXECUTABLE][CD_CONTENT].c_str(), - info[CD_TIME][CD_CONTENT].c_str(), - info[CD_COUNT][CD_CONTENT].c_str() - ); + const char *timestr = info[CD_TIME][CD_CONTENT].c_str(); + long time = strtol(timestr, 0, 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."); + + printf(_("%u.\n" + "\tUID : %s\n" + "\tUUID : %s\n" + "\tPackage : %s\n" + "\tExecutable : %s\n" + "\tCrash Time : %s\n" + "\tCrash Count: %s\n"), + ii, + info[CD_UID][CD_CONTENT].c_str(), + info[CD_UUID][CD_CONTENT].c_str(), + info[CD_PACKAGE][CD_CONTENT].c_str(), + info[CD_EXECUTABLE][CD_CONTENT].c_str(), + timeloc, + info[CD_COUNT][CD_CONTENT].c_str() + ); } } } +/* Saves the crash report to a file. + * Fp must be opened before write_crash_report is called. + * Returned Value: + * If the report is successfully stored to the file, a zero value is returned. + * On failure, nonzero value is returned. + */ +static int write_crash_report(const map_crash_report_t& report, FILE *fp) +{ + for (map_crash_report_t::const_iterator it = report.begin(); it != report.end(); it++) + { + if (it->second[CD_TYPE] == CD_SYS) + continue; + + fprintf(fp, "\n%s\n-----\n%s\n", it->first.c_str(), it->second[CD_CONTENT].c_str()); + } + + return 0; +} + static void print_crash_report(const map_crash_report_t& pCrashReport) { map_crash_report_t::const_iterator it = pCrashReport.begin(); @@ -92,6 +130,7 @@ static DBusMessage* new_call_msg(const char* method) die_out_of_memory(); return msg; } + static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) { DBusError err; @@ -99,7 +138,7 @@ static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) DBusMessage *reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, msg, /*timeout*/ -1, &err); if (reply == NULL) { -//TODO: analyse err + //TODO: analyse err error_msg_and_die("Error sending DBus message"); } dbus_message_unref(msg); @@ -109,7 +148,6 @@ static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) static vector_crash_infos_t call_GetCrashInfos() { DBusMessage* msg = new_call_msg("GetCrashInfos"); - DBusMessage *reply = send_get_reply_and_unref(msg); vector_crash_infos_t argout; @@ -189,6 +227,76 @@ static void handle_dbus_err(bool error_flag, DBusError *err) CC_DBUS_NAME); } +int launch_editor(const char *path, const char *report, char **output) +{ + const char *editor, *terminal; + + editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + + terminal = getenv("TERM"); + if (!editor && (!terminal || !strcmp(terminal, "dumb"))) + { + error_msg(_("Terminal is dumb but no VISUAL nor EDITOR defined.")); + return 1; + } + + if (!editor) + editor = "vi"; + + return 0; +} + +/* Reports the crash with corresponding uuid over DBus. */ +int report(const char *uuid, bool always) +{ + map_crash_report_t cr = call_CreateReport(uuid); + + if (always) + { + call_Report(cr); + return 0; + } + + print_crash_report(cr); + + /* Open a temporary file and write the crash report to it. */ + char filename[] = "/tmp/abrt-report.XXXXXX"; + int fd = mkstemp(filename); + if (fd == -1) + { + error_msg("could not generate temporary file name"); + return 1; + } + + FILE *fp = fdopen(fd, "w"); + if (!fp) + { + error_msg("could not open '%s' to save the crash report", filename); + return 1; + } + + write_crash_report(cr, fp); + + if (fclose(fp)) + { + error_msg("could not close '%s'", filename); + return 2; + } + + printf(_("\nDo you want to send the report? [y/n]: ")); + fflush(NULL); + char answer[16] = "n"; + fgets(answer, sizeof(answer), stdin); + if (answer[0] == 'Y' || answer[0] == 'y') + { + call_Report(cr); + } + + return 0; +} + static const struct option longopts[] = { /* name, has_arg, flag, val */ @@ -202,7 +310,7 @@ static const struct option longopts[] = { 0, 0, 0, 0 } /* prevents crashes for unknown options*/ }; -/* Gets program name from command line argument. */ +/* Gets the program name from the first command line argument. */ static char *progname(char *argv0) { char* name = strrchr(argv0, '/'); @@ -212,12 +320,38 @@ static char *progname(char *argv0) return argv0; } +/* Prints abrt-cli version and some help text. */ +static void usage(char *argv0) +{ + char *name = progname(argv0); + printf("%s " VERSION "\n\n", name); + + /* Message has embedded tabs. */ + printf(_("Usage: %s [OPTION]\n\n" + "Startup:\n" + " -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 UUID create and send a report\n" + " --report-always UUID create and send a report without asking\n" + " --delete UUID remove crash\n"), + name, name); +} + int main(int argc, char** argv) { char* uuid = NULL; int op = -1; char *name; + setlocale(LC_ALL,""); +#if ENABLE_NLS + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); +#endif + while (1) { int option_index; @@ -233,7 +367,7 @@ int main(int argc, char** argv) case OPT_GET_LIST_FULL: if (op == -1) break; - error_msg("You must specify exactly one operation."); + error_msg(_("You must specify exactly one operation.")); return 1; case -1: /* end of options */ if (op != -1) /* if some operation was specified... */ @@ -242,25 +376,12 @@ int main(int argc, char** argv) default: case '?': case OPT_HELP: - name = progname(argv[0]); - printf("%s " VERSION "\n\n", name); - /* note: message has embedded tabs */ - printf("Usage: %s [OPTION]\n\n" - "Startup:\n" - " -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 UUID create and send a report\n" - " --report-always UUID create and send a report without asking\n" - " --delete UUID remove crash\n", - name, name); - return 1; + usage(argv[0]); + return 1; case 'V': case OPT_VERSION: - printf("%s " VERSION "\n", progname(argv[0])); - return 0; + printf("%s " VERSION "\n", progname(argv[0])); + return 0; } if (c == -1) break; @@ -276,6 +397,7 @@ int main(int argc, char** argv) CABRTSocket ABRTDaemon; ABRTDaemon.Connect(VAR_RUN"/abrt.socket"); #endif + switch (op) { case OPT_GET_LIST: @@ -286,33 +408,20 @@ int main(int argc, char** argv) break; } case OPT_REPORT: - { - map_crash_report_t cr = call_CreateReport(uuid); - print_crash_report(cr); - printf("\nDo you want to send the report? [y/n]: "); - fflush(NULL); - char answer[16] = "n"; - fgets(answer, sizeof(answer), stdin); - if (answer[0] == 'Y' || answer[0] == 'y') - { - call_Report(cr); - } - break; - } + report(uuid, false); + break; case OPT_REPORT_ALWAYS: - { - map_crash_report_t cr = call_CreateReport(uuid); - call_Report(cr); - break; - } + report(uuid, true); + break; case OPT_DELETE: { call_DeleteDebugDump(uuid); break; } } + #if ENABLE_SOCKET - ABRTDaemon.DisConnect(); + ABRTDaemon.Disconnect(); #endif return 0; diff --git a/src/CLI/Makefile.am b/src/CLI/Makefile.am index 0167149b..68109534 100644 --- a/src/CLI/Makefile.am +++ b/src/CLI/Makefile.am @@ -22,3 +22,4 @@ EXTRA_DIST = $(man_MANS) completiondir = $(sysconfdir)/bash_completion.d completion_DATA = abrt-cli.bash +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ -- cgit From 3fbf763781ebe31b8f970aa197db0d06dc421d9b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2009 15:06:39 +0200 Subject: abrt-debuginfo-install: add mini-doc Signed-off-by: Denys Vlasenko --- src/Daemon/abrt-debuginfo-install | 58 +++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install index fe55250a..e9b398a8 100755 --- a/src/Daemon/abrt-debuginfo-install +++ b/src/Daemon/abrt-debuginfo-install @@ -1,4 +1,54 @@ #!/bin/sh +# Called by abrtd before producing a backtrace. +# The task of this script is to install debuginfos. +# +# Just using [pk-]debuginfo-install does not work well. +# - they can't install more than one version of debuginfo +# for a package +# - their output is unsuitable for scripting +# - debuginfo-install aborts if yum lock is busy +# - pk-debuginfo-install was observed to hang +# +# Usage: abrt-debuginfo-install CORE TEMPDIR [CACHEDIR] +# If CACHEDIR is specified, debuginfos should be installed there. +# If not, debuginfos should be installed into TEMPDIR. +# +# Currently, we are called with CACHEDIR set to "/", but in the future +# it may be omitted or set to something else. script must be ready +# for those cases too. +# +# Algorithm: +# - Create TEMPDIR +# - Extract build-ids from coredump +# - For every build-id, check /usr/lib/debug/.build-id/XX/XXXX.debug +# and CACHEDIR/usr/lib/debug/.build-id/XX/XXXX.debug +# - If they all exist, exit 0 +# - Using "yum provides /usr/lib/debug/.build-id/XX/XXXX.debug", +# figure out which debuginfo packages are needed +# - Download them using "yumdownloader PACKAGE..." +# - Unpack them with rpm2cpio | cpio to TEMPDIR +# - If CACHEDIR is specified, copy usr/lib/debug/.build-id/XX/XXXX.debug +# to CACHEDIR/usr/lib/debug/.build-id/XX/XXXX.debug and delete TEMPDIR +# - Report which XX/XXXX.debug are still missing. +# +# In the future, we may want to use a separate CACHEDIR (say, /var/cache/abrt-di) +# and use it with this gdb command: +# set debug-file-directory /usr/lib/debug/.build-id:CACHEDIR/usr/lib/debug/.build-id +# but current gdb can't handle DIR1:DIR2. +# So, currently we are called with CACHEDIR set to "/", and don't pass +# "set debug-file-directory" to gdb. +# This is ugly, since it messes up /usr/lib/debug/.build-id over time +# by piling up debuginfos there without any means to control their amount, +# but it's the only way to make it work with current gdb. +# +# Output goes to GUI as debigunfo install log. +# "MISSING:xxxx" messages result in xxxx being prepended to backtrace +# +# Exitcodes: +# 0 - all debuginfos are installed +# 1 - not all debuginfos are installed +# 2+ - serious problem + core=$1 tempdir=$2 @@ -11,14 +61,6 @@ count_words() { exec 2>&1 -# Output goes to GUI as debigunfo install log. -# "MISSING:xxxx" messages result in xxxx being prepended to backtrace - -# Exitcodes: -# 0 - all debuginfos are installed -# 1 - not all debuginfos are installed -# 2+ - serious problem - test -f "$core" || exit 2 # cachedir is optional test x"$cachedir" = x"" || test -d "$cachedir" || exit 2 -- cgit From f10e69f4ebcd403a6c68f5feea9e1111ae338f2a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2009 16:00:29 +0200 Subject: revert abrt-debuginfo-install usage for now Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 195 insertions(+), 3 deletions(-) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 40aadd24..3fedd947 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -371,11 +371,202 @@ static std::string run_unstrip_n(const std::string& pDebugDumpDir) return output; } +static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& build_ids) +{ + log("Getting module names, file names, build IDs from core file"); + std::string unstrip_list = run_unstrip_n(pDebugDumpDir); + + log("Builting list of missing debuginfos"); + // lines look like this: + // 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe] + // 0x400000+0x209000 ab3c8286aac6c043fd1bb1cc2a0b88ec29517d3e@0x40024c /bin/sleep /usr/lib/debug/bin/sleep.debug [exe] + // 0x7fff313ff000+0x1000 389c7475e3d5401c55953a425a2042ef62c4c7df@0x7fff313ff2f8 . - linux-vdso.so.1 + vector_string_t missing; + char *dup = xstrdup(unstrip_list.c_str()); + char *p = dup; + char c; + do { + char* end = strchrnul(p, '\n'); + c = *end; + *end = '\0'; + char* word2 = strchr(p, ' '); + if (!word2) + continue; + word2++; + char* endsp = strchr(word2, ' '); + if (!endsp) + continue; + /* endsp points to 2nd space in the line now*/ + + /* This filters out linux-vdso.so, among others */ + if (strstr(endsp, "[exe]") == NULL && endsp[1] != '/') + continue; + *endsp = '\0'; + char* at = strchrnul(word2, '@'); + *at = '\0'; + + bool file_exists = 1; + if (word2[0] && word2[1] && is_hexstr(word2)) + { + struct stat sb; + char *fn = xasprintf("/usr/lib/debug/.build-id/%.2s/%s.debug", word2, word2 + 2); + /* Not lstat: this is a symlink and we want link's TARGET to exist */ + file_exists = stat(fn, &sb) == 0 && S_ISREG(sb.st_mode); + free(fn); + build_ids += "build-id "; + build_ids += word2; + build_ids += file_exists ? " (debuginfo present)\n" : " (debuginfo absent)\n"; + } + log("build_id:%s exists:%d", word2, (int)file_exists); + if (!file_exists) + missing.push_back(word2); + + p = end + 1; + } while (c); + free(dup); + + if (missing.size() == 0) + { + log("All debuginfos are present, not installing debuginfo packages"); + return; + } + //missing vector is unused for now, but TODO: use it to install only needed debuginfos + + std::string package; + { + CDebugDump dd; + dd.Open(pDebugDumpDir); + dd.LoadText(FILENAME_PACKAGE, package); + } + + update_client(_("Searching for debug-info packages...")); + + int pipein[2], pipeout[2]; + xpipe(pipein); + xpipe(pipeout); + + pid_t child = fork(); + if (child < 0) + { + /*close(pipein[0]); close(pipeout[0]); - why bother */ + /*close(pipein[1]); close(pipeout[1]); */ + perror_msg_and_die("fork"); + } + if (child == 0) + { + close(pipein[1]); + close(pipeout[0]); + xmove_fd(pipein[0], STDIN_FILENO); + xmove_fd(pipeout[1], STDOUT_FILENO); + /* Not a good idea, we won't see any error messages */ + /*close(STDERR_FILENO);*/ + + setsid(); +/* Honestly, I do not know what is worse, pk-debuginfo-install or debuginfo-install: + +# pk-debuginfo-install -y -- coreutils-7.2-4.fc11 +1. Getting sources list...OK. Found 16 enabled and 23 disabled sources. +2. Finding debugging sources...OK. Found 0 disabled debuginfo repos. +3. Enabling debugging sources...OK. Enabled 0 debugging sources. +4. Finding debugging packages...Failed to find the package : more than one package found for +Failed to find the package : more than one package found for +FAILED. Found no packages to install. +5. Disabling sources previously enabled...OK. Disabled 0 debugging sources. + +:( FAIL! + +# debuginfo-install -y -- coreutils-7.2-4.fc11 +Loaded plugins: refresh-packagekit +Another application is holding the yum lock, cannot continue + +:( FAIL! + +# debuginfo-install -y -- coreutils-7.2-4.fc11 +(second time in a row - it worked) + +*/ + /* log() goes to stderr/syslog, it's ok to use it here */ + VERB1 log("Executing: %s %s %s %s", "pk-debuginfo-install", "-y", "--", package.c_str()); + execlp("pk-debuginfo-install", "pk-debuginfo-install", "-y", "--", package.c_str(), NULL); + /* fall back */ + VERB1 log("Executing: %s %s %s %s", "debuginfo-install", "-y", "--", package.c_str()); + execlp("debuginfo-install", "debuginfo-install", "-y", "--", package.c_str(), NULL); + exit(1); + } + + close(pipein[0]); + close(pipeout[1]); + + /* Should not be needed (we use -y option), but just in case: */ + safe_write(pipein[1], "y\n", sizeof("y\n")-1); + close(pipein[1]); + + update_client(_("Downloading and installing debug-info packages...")); + + FILE *pipeout_fp = fdopen(pipeout[0], "r"); + if (pipeout_fp == NULL) /* never happens */ + { + close(pipeout[0]); + wait(NULL); + return; + } + +/* glx-utils, for example, do not have glx-utils-debuginfo package. + * Disabled code was causing failures in backtrace decoding. + * This does not seem to be useful. + */ +#ifdef COMPLAIN_IF_NO_DEBUGINFO + bool already_installed = false; +#endif + char buff[1024]; + std::string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1)); + while (fgets(buff, sizeof(buff), pipeout_fp)) + { + int last = strlen(buff) - 1; + if (last >= 0 && buff[last] == '\n') + buff[last] = '\0'; + + /* log(buff); - update_client logs it too */ + update_client(buff); /* maybe only if buff != ""? */ + +#ifdef COMPLAIN_IF_NO_DEBUGINFO + if (already_installed == false) + { + /* "Package foo-debuginfo-1.2-5.ARCH already installed and latest version" */ + char* pn = strstr(buff, packageName.c_str()); + if (pn) + { + char* already_str = strstr(pn, "already installed and latest version"); + if (already_str) + { + already_installed = true; + } + } + } + + if (already_installed == false && + (strstr(buff, "No debuginfo packages available to install") != NULL || + strstr(buff, "Could not find debuginfo for main pkg") != NULL || + strstr(buff, "Could not find debuginfo pkg for dependency package") != NULL)) + { + fclose(pipeout_fp); + kill(child, SIGTERM); + wait(NULL); + throw CABRTException(EXCEP_PLUGIN, std::string(__func__) + ": cannot install debuginfos for " + pPackage); + } +#endif + } + + fclose(pipeout_fp); + wait(NULL); +} +#if 0 +/* Needs gdb feature from here: https://bugzilla.redhat.com/show_bug.cgi?id=528668 */ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& build_ids) { update_client(_("Searching for debug-info packages...")); - int pipein[2], pipeout[2]; //TODO: get rid of pipein + int pipein[2], pipeout[2]; //TODO: get rid of pipein. Can we use ExecVP? xpipe(pipein); xpipe(pipeout); @@ -400,8 +591,8 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir.c_str()); char *tempdir = xasprintf("/tmp/abrt-%u-%lu", (int)getpid(), (long)time(NULL)); /* log() goes to stderr/syslog, it's ok to use it here */ - VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, "/"); // "/var/cache/abrt-di" - execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, "/", NULL); + VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, "/var/cache/abrt-di"); + execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, "/var/cache/abrt-di", NULL); exit(1); } @@ -447,6 +638,7 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui fclose(pipeout_fp); wait(NULL); } +#endif std::string CAnalyzerCCpp::GetLocalUUID(const std::string& pDebugDumpDir) { -- cgit From 4df20906ef57432edb505ce28179fd979729c975 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2009 18:12:39 +0200 Subject: abrt-debuginfo-install: expand doc Signed-off-by: Denys Vlasenko --- src/Daemon/abrt-debuginfo-install | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install index e9b398a8..fc5380ba 100755 --- a/src/Daemon/abrt-debuginfo-install +++ b/src/Daemon/abrt-debuginfo-install @@ -17,6 +17,17 @@ # it may be omitted or set to something else. script must be ready # for those cases too. # +# Output goes to GUI as debuginfo install log. The script should be careful +# to give useful, but not overly cluttered info to stdout. +# Additionally, abrt daemon handles "MISSING:xxxx" messages specially: +# xxxx will be prepended to backtrace. This is used to inform about +# missing debuginfos. +# +# Exitcodes: +# 0 - all debuginfos are installed +# 1 - not all debuginfos are installed +# 2+ - serious problem +# # Algorithm: # - Create TEMPDIR # - Extract build-ids from coredump @@ -31,6 +42,10 @@ # to CACHEDIR/usr/lib/debug/.build-id/XX/XXXX.debug and delete TEMPDIR # - Report which XX/XXXX.debug are still missing. # +# For better debuggability, eu_unstrip.OUT, yum_provides.OUT etc files +# are saved in TEMPDIR, and TEMPDIR is not deleted if we exit with exitcode 2 +# ("serious problem"). +# # In the future, we may want to use a separate CACHEDIR (say, /var/cache/abrt-di) # and use it with this gdb command: # set debug-file-directory /usr/lib/debug/.build-id:CACHEDIR/usr/lib/debug/.build-id @@ -40,14 +55,6 @@ # This is ugly, since it messes up /usr/lib/debug/.build-id over time # by piling up debuginfos there without any means to control their amount, # but it's the only way to make it work with current gdb. -# -# Output goes to GUI as debigunfo install log. -# "MISSING:xxxx" messages result in xxxx being prepended to backtrace -# -# Exitcodes: -# 0 - all debuginfos are installed -# 1 - not all debuginfos are installed -# 2+ - serious problem core=$1 -- cgit From 030681a9ff92b27d9b38ec908b0b05e53e26c6ce Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 15:51:38 +0200 Subject: Do not ignore .po files because they belong to the repository. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index f2f6f00c..08508aa8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ *.o *.lo *.la -po/*.po po/*.gmo .deps .libs -- cgit From b7f40a3f601e60fc342cad87cf40849ee4e2c153 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 15:52:24 +0200 Subject: Allow abrt_dbus.h to be included multiple times. --- lib/Utils/abrt_dbus.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Utils/abrt_dbus.h b/lib/Utils/abrt_dbus.h index 09063c5a..b31a015c 100644 --- a/lib/Utils/abrt_dbus.h +++ b/lib/Utils/abrt_dbus.h @@ -1,3 +1,6 @@ +#ifndef ABRT_UTIL_DBUS_H +#define ABRT_UTIL_DBUS_H + #include #include #include @@ -269,3 +272,5 @@ template static inline int load_val(DBusMessageIter* iter, std::vector& val) { return load_vector(iter, val); } template static inline int load_val(DBusMessageIter* iter, std::map& val) { return load_map(iter, val); } + +#endif -- cgit From 9e8a1ba0c9ddfa0108050f6fedc88de63b4b7c3f Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 15:54:05 +0200 Subject: Initial implementation of crash report editor. Splitted CLI.cpp into multiple files for clarity. --- src/CLI/CLI.cpp | 226 +------------------------------ src/CLI/Makefile.am | 9 +- src/CLI/dbus.cpp | 130 ++++++++++++++++++ src/CLI/dbus.h | 34 +++++ src/CLI/report.cpp | 344 ++++++++++++++++++++++++++++++++++++++++++++++++ src/CLI/report.h | 24 ++++ src/CLI/run-command.cpp | 87 ++++++++++++ src/CLI/run-command.h | 23 ++++ 8 files changed, 657 insertions(+), 220 deletions(-) create mode 100644 src/CLI/dbus.cpp create mode 100644 src/CLI/dbus.h create mode 100644 src/CLI/report.cpp create mode 100644 src/CLI/report.h create mode 100644 src/CLI/run-command.cpp create mode 100644 src/CLI/run-command.h diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index d4e2bb4b..a782a59a 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -21,17 +21,19 @@ #include "abrtlib.h" #include "abrt_dbus.h" #include "DBusCommon.h" +#include "report.h" +#include "dbus.h" #if HAVE_CONFIG_H - #include +#include #endif #if HAVE_LOCALE_H - #include +#include #endif #if ENABLE_NLS - #include - #define _(S) gettext(S) +#include +#define _(S) gettext(S) #else - #define _(S) (S) +#define _(S) (S) #endif /* Program options */ @@ -46,8 +48,6 @@ enum OPT_DELETE }; -static DBusConnection* s_dbus_conn; - static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) { unsigned int ii; @@ -85,218 +85,6 @@ static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) } } -/* Saves the crash report to a file. - * Fp must be opened before write_crash_report is called. - * Returned Value: - * If the report is successfully stored to the file, a zero value is returned. - * On failure, nonzero value is returned. - */ -static int write_crash_report(const map_crash_report_t& report, FILE *fp) -{ - for (map_crash_report_t::const_iterator it = report.begin(); it != report.end(); it++) - { - if (it->second[CD_TYPE] == CD_SYS) - continue; - - fprintf(fp, "\n%s\n-----\n%s\n", it->first.c_str(), it->second[CD_CONTENT].c_str()); - } - - return 0; -} - -static void print_crash_report(const map_crash_report_t& pCrashReport) -{ - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) - { - if (it->second[CD_TYPE] != CD_SYS) - { - printf("\n%s\n" - "-----\n" - "%s\n", it->first.c_str(), it->second[CD_CONTENT].c_str()); - } - } -} - -/* - * DBus member calls - */ - -/* helpers */ -static DBusMessage* new_call_msg(const char* method) -{ - DBusMessage* msg = dbus_message_new_method_call(CC_DBUS_NAME, CC_DBUS_PATH, CC_DBUS_IFACE, method); - if (!msg) - die_out_of_memory(); - return msg; -} - -static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) -{ - DBusError err; - dbus_error_init(&err); - DBusMessage *reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, msg, /*timeout*/ -1, &err); - if (reply == NULL) - { - //TODO: analyse err - error_msg_and_die("Error sending DBus message"); - } - dbus_message_unref(msg); - return reply; -} - -static vector_crash_infos_t call_GetCrashInfos() -{ - DBusMessage* msg = new_call_msg("GetCrashInfos"); - DBusMessage *reply = send_get_reply_and_unref(msg); - - vector_crash_infos_t argout; - DBusMessageIter in_iter; - dbus_message_iter_init(reply, &in_iter); - int r = load_val(&in_iter, argout); - if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ - error_msg_and_die("dbus call %s: return type mismatch", "GetCrashInfos"); - dbus_message_unref(reply); - return argout; -} - -static map_crash_report_t call_CreateReport(const char* uuid) -{ - /* Yes, call name is not "CreateReport" but "GetJobResult". - * We need to clean up the names one day. */ - DBusMessage* msg = new_call_msg("GetJobResult"); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - DBusMessage *reply = send_get_reply_and_unref(msg); - - map_crash_report_t argout; - DBusMessageIter in_iter; - dbus_message_iter_init(reply, &in_iter); - int r = load_val(&in_iter, argout); - if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ - error_msg_and_die("dbus call %s: return type mismatch", "GetJobResult"); - dbus_message_unref(reply); - return argout; -} - -static void call_Report(const map_crash_report_t& report) -{ - DBusMessage* msg = new_call_msg("Report"); - DBusMessageIter out_iter; - dbus_message_iter_init_append(msg, &out_iter); - store_val(&out_iter, report); - - DBusMessage *reply = send_get_reply_and_unref(msg); - //it returns a single value of report_status_t type, - //but we don't use it (yet?) - - dbus_message_unref(reply); - return; -} - -static void call_DeleteDebugDump(const char* uuid) -{ - DBusMessage* msg = new_call_msg("DeleteDebugDump"); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - DBusMessage *reply = send_get_reply_and_unref(msg); - //it returns a single boolean value, - //but we don't use it (yet?) - - dbus_message_unref(reply); - return; -} - -static void handle_dbus_err(bool error_flag, DBusError *err) -{ - if (dbus_error_is_set(err)) - { - error_msg("dbus error: %s", err->message); - /* dbus_error_free(&err); */ - error_flag = true; - } - if (!error_flag) - return; - error_msg_and_die( - "error requesting DBus name %s, possible reasons: " - "abrt run by non-root; dbus config is incorrect", - CC_DBUS_NAME); -} - -int launch_editor(const char *path, const char *report, char **output) -{ - const char *editor, *terminal; - - editor = getenv("VISUAL"); - if (!editor) - editor = getenv("EDITOR"); - - terminal = getenv("TERM"); - if (!editor && (!terminal || !strcmp(terminal, "dumb"))) - { - error_msg(_("Terminal is dumb but no VISUAL nor EDITOR defined.")); - return 1; - } - - if (!editor) - editor = "vi"; - - return 0; -} - -/* Reports the crash with corresponding uuid over DBus. */ -int report(const char *uuid, bool always) -{ - map_crash_report_t cr = call_CreateReport(uuid); - - if (always) - { - call_Report(cr); - return 0; - } - - print_crash_report(cr); - - /* Open a temporary file and write the crash report to it. */ - char filename[] = "/tmp/abrt-report.XXXXXX"; - int fd = mkstemp(filename); - if (fd == -1) - { - error_msg("could not generate temporary file name"); - return 1; - } - - FILE *fp = fdopen(fd, "w"); - if (!fp) - { - error_msg("could not open '%s' to save the crash report", filename); - return 1; - } - - write_crash_report(cr, fp); - - if (fclose(fp)) - { - error_msg("could not close '%s'", filename); - return 2; - } - - printf(_("\nDo you want to send the report? [y/n]: ")); - fflush(NULL); - char answer[16] = "n"; - fgets(answer, sizeof(answer), stdin); - if (answer[0] == 'Y' || answer[0] == 'y') - { - call_Report(cr); - } - - return 0; -} - static const struct option longopts[] = { /* name, has_arg, flag, val */ diff --git a/src/CLI/Makefile.am b/src/CLI/Makefile.am index 68109534..7b10bfb8 100644 --- a/src/CLI/Makefile.am +++ b/src/CLI/Makefile.am @@ -2,7 +2,14 @@ bin_PROGRAMS = abrt-cli abrt_cli_SOURCES = \ CLI.cpp \ - ABRTSocket.h ABRTSocket.cpp + ABRTSocket.h \ + ABRTSocket.cpp \ + run-command.h \ + run-command.cpp \ + report.h \ + report.cpp \ + dbus.h \ + dbus.cpp abrt_cli_CPPFLAGS = \ -I$(srcdir)/../../inc \ diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp new file mode 100644 index 00000000..3a2999e2 --- /dev/null +++ b/src/CLI/dbus.cpp @@ -0,0 +1,130 @@ +/* + Copyright (C) 2009 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 "dbus.h" +#include "DBusCommon.h" + +DBusConnection* s_dbus_conn; + +/* + * DBus member calls + */ + +/* helpers */ +DBusMessage* new_call_msg(const char* method) +{ + DBusMessage* msg = dbus_message_new_method_call(CC_DBUS_NAME, CC_DBUS_PATH, CC_DBUS_IFACE, method); + if (!msg) + die_out_of_memory(); + return msg; +} + +DBusMessage* send_get_reply_and_unref(DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, + msg, /*timeout*/ -1, &err); + if (reply == NULL) + { + //TODO: analyse err + error_msg_and_die("Error sending DBus message"); + } + dbus_message_unref(msg); + return reply; +} + +vector_crash_infos_t call_GetCrashInfos() +{ + DBusMessage* msg = new_call_msg("GetCrashInfos"); + DBusMessage *reply = send_get_reply_and_unref(msg); + + vector_crash_infos_t argout; + DBusMessageIter in_iter; + dbus_message_iter_init(reply, &in_iter); + int r = load_val(&in_iter, argout); + if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ + error_msg_and_die("dbus call %s: return type mismatch", "GetCrashInfos"); + dbus_message_unref(reply); + return argout; +} + +map_crash_report_t call_CreateReport(const char* uuid) +{ + /* Yes, call name is not "CreateReport" but "GetJobResult". + * We need to clean up the names one day. */ + DBusMessage* msg = new_call_msg("GetJobResult"); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + DBusMessage *reply = send_get_reply_and_unref(msg); + + map_crash_report_t argout; + DBusMessageIter in_iter; + dbus_message_iter_init(reply, &in_iter); + int r = load_val(&in_iter, argout); + if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ + error_msg_and_die("dbus call %s: return type mismatch", "GetJobResult"); + dbus_message_unref(reply); + return argout; +} + +void call_Report(const map_crash_report_t& report) +{ + DBusMessage* msg = new_call_msg("Report"); + DBusMessageIter out_iter; + dbus_message_iter_init_append(msg, &out_iter); + store_val(&out_iter, report); + + DBusMessage *reply = send_get_reply_and_unref(msg); + //it returns a single value of report_status_t type, + //but we don't use it (yet?) + + dbus_message_unref(reply); +} + +void call_DeleteDebugDump(const char* uuid) +{ + DBusMessage* msg = new_call_msg("DeleteDebugDump"); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + DBusMessage *reply = send_get_reply_and_unref(msg); + //it returns a single boolean value, + //but we don't use it (yet?) + + dbus_message_unref(reply); +} + +void handle_dbus_err(bool error_flag, DBusError *err) +{ + if (dbus_error_is_set(err)) + { + error_msg("dbus error: %s", err->message); + /* dbus_error_free(&err); */ + error_flag = true; + } + if (!error_flag) + return; + error_msg_and_die( + "error requesting DBus name %s, possible reasons: " + "abrt run by non-root; dbus config is incorrect", + CC_DBUS_NAME); +} diff --git a/src/CLI/dbus.h b/src/CLI/dbus.h new file mode 100644 index 00000000..febcb942 --- /dev/null +++ b/src/CLI/dbus.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2009 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. +*/ +#ifndef ABRT_CLI_DBUS_H +#define ABRT_CLI_DBUS_H + +#include "abrt_dbus.h" +#include "CrashTypes.h" + +extern DBusConnection* s_dbus_conn; + +extern DBusMessage* new_call_msg(const char* method); +extern DBusMessage* send_get_reply_and_unref(DBusMessage* msg); +extern vector_crash_infos_t call_GetCrashInfos(); +extern map_crash_report_t call_CreateReport(const char* uuid); +extern void call_Report(const map_crash_report_t& report); +extern void call_DeleteDebugDump(const char* uuid); +extern void handle_dbus_err(bool error_flag, DBusError *err); + +#endif diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp new file mode 100644 index 00000000..6f2ba6a2 --- /dev/null +++ b/src/CLI/report.cpp @@ -0,0 +1,344 @@ +/* + Copyright (C) 2009 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 "report.h" +#include "run-command.h" +#include "dbus.h" +#include "abrtlib.h" +#if HAVE_CONFIG_H +#include +#endif +#if ENABLE_NLS +#include +#define _(S) gettext(S) +#else +#define _(S) (S) +#endif + +#define FIELD_SEP "%----" + +/* Escapes the field content string to avoid confusion with file comments. + Returned field must be free()d by caller. */ +static char *escape(const char *str) +{ + // Determine the size of resultant string. + // Count the required number of escape characters. + // 1. NEWLINE followed by # + // 2. NEWLINE followed by \# (escaped version) + const char *ptr = str; + bool newline = true; + int count = 0; + while (*ptr) + { + if (newline) + { + if (*ptr == '#') + ++count; + if (*ptr == '\\' && *(ptr + 1) == '#') + ++count; + } + + newline = (*ptr == '\n'); + ++ptr; + } + + // Copy the input string to the resultant string, and escape all + // occurences of \# and #. + char *result = (char*)malloc(strlen(str) + 1 + count); + if (!result) + error_msg_and_die("Memory error while escaping a field."); + + const char *src = str; + char *dest = result; + newline = true; + while (*src) + { + if (newline) + { + if (*src == '#') + *dest++ = '\\'; + else if (*src == '\\' && *(src + 1) == '#') + *dest++ = '\\'; + } + + newline = (*src == '\n'); + *dest++ = *src++; + } + *dest = '\0'; + return result; +} + +/* Removes all comment lines, and unescapes the string previously escaped + by escape(). Works in-place. */ +static char *remove_comments_and_unescape(char *str) +{ + char *src = str, *dest = str; + bool newline = true; + while (*src) + { + if (newline) + { + if (*src == '#') + { // Skip the comment line! + while (*src && *src != '\n') + ++src; + + if (*src == '\0') + break; + + ++src; + continue; + } + else if (*src == '\\' && + (*(src + 1) == '#' || + (*(src + 1) == '\\' && *(src + 2) == '#'))) + { + ++src; // Unescape escaped char. + } + } + + newline = (*src == '\n'); + *dest++ = *src++; + } + *dest = '\0'; +} + +/* Writes a field of crash report to a file. + * Field must be writable. + */ +static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, + const char *field, const char *description) +{ + const map_crash_report_t::const_iterator it = report.find(field); + if (it == report.end()) + { + error_msg("Field %s not found.\n", field); + return; + } + + if (it->second[CD_TYPE] == CD_SYS) + { + error_msg("Cannot write field %s because it is a system value\n", field); + return; + } + + fprintf(fp, "%s%s\n", FIELD_SEP, it->first.c_str()); + + bool readonly = (it->second[CD_EDITABLE] != CD_ISEDITABLE); + fprintf(fp, readonly ? _("# %s (read only)\n") : "# %s\n", description); + + char *escaped_content = escape(it->second[CD_CONTENT].c_str()); + fprintf(fp, "%s\n", escaped_content); + free(escaped_content); +} + +/* Saves the crash report to a file. + * Fp must be opened before write_crash_report is called. + * Returned Value: + * If the report is successfully stored to the file, a zero value is returned. + * On failure, nonzero value is returned. + */ +static int write_crash_report(const map_crash_report_t &report, FILE *fp) +{ + fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" + "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); + + write_crash_report_field(fp, report, "Comment", + _("Describe the circumstances of this crash below.")); + write_crash_report_field(fp, report, "How to reproduce", + _("How to reproduce the crash?")); + write_crash_report_field(fp, report, "backtrace", + _("Backtrace. Check that it does not contain any sensitive data such as passwords.")); + write_crash_report_field(fp, report, "UUID", "UUID"); + write_crash_report_field(fp, report, "architecture", "Architecture"); + write_crash_report_field(fp, report, "cmdline", "Command line"); + write_crash_report_field(fp, report, "component", "Component"); + write_crash_report_field(fp, report, "coredump", "Core dump"); + write_crash_report_field(fp, report, "executable", "Executable"); + write_crash_report_field(fp, report, "kernel", "Kernel"); + write_crash_report_field(fp, report, "package", "Package"); + write_crash_report_field(fp, report, "reason", "Reason"); + write_crash_report_field(fp, report, "release", "Release"); + + return 0; +} + +/* + * Updates appropriate field in the report from the text. The text can + * contain multiple fields. + */ +static void read_crash_report_field(const char *text, map_crash_report_t &report, + const char *field) +{ + char separator[strlen("\n" FIELD_SEP) + strlen(field) + 2]; // 2 = '\n\0' + sprintf(separator, "\n%s%s\n", FIELD_SEP, field); + const char *textfield = strstr(text, separator); + if (!textfield) + return; + + textfield += strlen(separator); + int length = 0; + const char *end = strstr(textfield, "\n" FIELD_SEP); + if (!end) + length = strlen(textfield); + else + length = end - textfield; + + const map_crash_report_t::iterator it = report.find(field); + if (it == report.end()) + { + error_msg("Field %s not found.\n", field); + return; + } + + if (it->second[CD_TYPE] == CD_SYS) + { + error_msg("Cannot update field %s because it is a system value.\n", field); + return; + } + + if (it->second[CD_EDITABLE] == CD_ISEDITABLE) + it->second[CD_CONTENT].assign(textfield, length); +} + +/* + * Updates the crash report 'report' from the text. The text must not contain + * any comments. + */ +static int read_crash_report(map_crash_report_t &report, const char *text) +{ + read_crash_report_field(text, report, "Comment"); + read_crash_report_field(text, report, "How to reproduce"); + read_crash_report_field(text, report, "backtrace"); + read_crash_report_field(text, report, "UUID"); + read_crash_report_field(text, report, "architecture"); + read_crash_report_field(text, report, "cmdline"); + read_crash_report_field(text, report, "component"); + read_crash_report_field(text, report, "coredump"); + read_crash_report_field(text, report, "executable"); + read_crash_report_field(text, report, "kernel"); + read_crash_report_field(text, report, "package"); + read_crash_report_field(text, report, "reason"); + read_crash_report_field(text, report, "release"); + + return 0; +} + +/* Runs external editor. */ +int launch_editor(const char *path) +{ + const char *editor, *terminal; + + editor = getenv("ABRT_EDITOR"); + if (!editor) + editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + + terminal = getenv("TERM"); + if (!editor && (!terminal || !strcmp(terminal, "dumb"))) + { + error_msg(_("Terminal is dumb but no VISUAL nor EDITOR defined.")); + return 1; + } + + if (!editor) + editor = "vi"; + + const char *args[6]; + args[0] = editor; + args[1] = path; + run_command(args); + + return 0; +} + +/* Reports the crash with corresponding uuid over DBus. */ +int report(const char *uuid, bool always) +{ + map_crash_report_t cr = call_CreateReport(uuid); + + if (always) + { + call_Report(cr); + return 0; + } + + /* Open a temporary file and write the crash report to it. */ + char filename[] = "/tmp/abrt-report.XXXXXX"; + int fd = mkstemp(filename); + if (fd == -1) + { + error_msg("could not generate temporary file name"); + return 1; + } + + FILE *fp = fdopen(fd, "w"); + if (!fp) + { + error_msg("could not open '%s' to save the crash report", filename); + return 1; + } + + write_crash_report(cr, fp); + + if (fclose(fp)) + { + error_msg("could not close '%s'", filename); + return 2; + } + + launch_editor(filename); + + fp = fopen(filename, "r"); + if (!fp) + { + error_msg("could not open '%s' to read the crash report", filename); + return 1; + } + + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + printf("%d", size); + fseek(fp, 0, SEEK_SET); + + char *text = (char*)malloc(size + 1); + if (fread(text, 1, size, fp) != size) + { + error_msg("could not read '%s'", filename); + return 1; + } + text[size] = '\0'; + fclose(fp); + + remove_comments_and_unescape(text); + read_crash_report(cr, text); + free(text); + + /*int result = */unlink(filename); + + printf(_("\nReport has been updated.\nDo you want to send the report? [y/n]: ")); + fflush(NULL); + char answer[16] = "n"; + fgets(answer, sizeof(answer), stdin); + if (answer[0] == 'Y' || answer[0] == 'y') + { + call_Report(cr); + } + + return 0; +} diff --git a/src/CLI/report.h b/src/CLI/report.h new file mode 100644 index 00000000..888babf3 --- /dev/null +++ b/src/CLI/report.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2009 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. +*/ +#ifndef ABRT_CLI_REPORT_H +#define ABRT_CLI_REPORT_H + +/* Reports the crash with corresponding uuid over DBus. */ +extern int report(const char *uuid, bool always); + +#endif diff --git a/src/CLI/run-command.cpp b/src/CLI/run-command.cpp new file mode 100644 index 00000000..df29b0e1 --- /dev/null +++ b/src/CLI/run-command.cpp @@ -0,0 +1,87 @@ +/* + Copyright (C) 2009 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 "run-command.h" +#include "abrtlib.h" + +/* + Inspired by git code. + http://git.kernel.org/?p=git/git.git;a=blob;f=run-command.c;hb=HEAD +*/ + +struct child_process +{ + const char **argv; + pid_t pid; +}; + +static int start_command(struct child_process *cmd) +{ + cmd->pid = fork(); + if (cmd->pid == 0) + { // new process + execvp(cmd->argv[0], (char *const*)cmd->argv); + exit(127); + } + if (cmd->pid < 0) + { + error_msg_and_die("Unable to fork for %s: %s", cmd->argv[0], strerror(errno)); + return -1; + } + return 0; +} + +static int finish_command(struct child_process *cmd) +{ + pid_t waiting; + int status, code = -1; + while ((waiting = waitpid(cmd->pid, &status, 0)) < 0 && errno == EINTR) + ; /* nothing */ + + if (waiting < 0) + error_msg_and_die("waitpid for %s failed: %s", cmd->argv[0], strerror(errno)); + else if (waiting != cmd->pid) + error_msg_and_die("waitpid is confused (%s)", cmd->argv[0]); + else if (WIFSIGNALED(status)) + { + code = WTERMSIG(status); + error_msg("%s died of signal %d", cmd->argv[0], code); + } + else if (WIFEXITED(status)) + { + code = WEXITSTATUS(status); + if (code == 127) + { + code = -1; + error_msg_and_die("cannot run %s: %s", cmd->argv[0], strerror(ENOENT)); + } + } + else + error_msg_and_die("waitpid is confused (%s)", cmd->argv[0]); + + return code; +} + +int run_command(const char **argv) +{ + struct child_process cmd; + cmd.argv = argv; + int code = start_command(&cmd); + if (code) + return code; + return finish_command(&cmd); +} diff --git a/src/CLI/run-command.h b/src/CLI/run-command.h new file mode 100644 index 00000000..45a85af5 --- /dev/null +++ b/src/CLI/run-command.h @@ -0,0 +1,23 @@ +/* + Copyright (C) 2009 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. +*/ +#ifndef ABRT_CLI_RUN_COMMAND_H +#define ABRT_CLI_RUN_COMMAND_H + +int run_command(const char **argv); + +#endif -- cgit From 44013dfebfe8f837255f8fe5d5b48ccddbc02f10 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 16:00:39 +0200 Subject: Ignore cscope database for sources. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 08508aa8..f92001af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ \#* +cscope.out *.o *.lo *.la -- cgit From b1e759fb921564afd675721f6ad67edb35eb738f Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 16:14:46 +0200 Subject: Manpage documents environment variable usage. --- src/CLI/abrt-cli.1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/CLI/abrt-cli.1 b/src/CLI/abrt-cli.1 index 5f132dfa..9ccc6159 100644 --- a/src/CLI/abrt-cli.1 +++ b/src/CLI/abrt-cli.1 @@ -24,11 +24,17 @@ Prints list of crashes which are not reported yet. .IP "\-\-get-list-full" Prints list of all crashes. .IP "\-\-report \fIUUID\fR" -Creates and sends a report. +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 a report without asking. +Creates and sends the crash report without asking. .IP "\-\-delete \fIUUID\fR" -Removes crash. +Removes data about particular crash. +.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 +environment variable, in that order. .SH "SEE ALSO" .IR abrtd (8), .IR abrt.conf (5), -- cgit From f16349195d117198603d6c951b7af434afda2339 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 16:45:15 +0200 Subject: Code comments. Better UI texts. --- src/CLI/report.cpp | 58 +++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 6f2ba6a2..57dc6251 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -29,10 +29,13 @@ #define _(S) (S) #endif +/* Field separator for the crash report file that is edited by user. */ #define FIELD_SEP "%----" -/* Escapes the field content string to avoid confusion with file comments. - Returned field must be free()d by caller. */ +/* + * Escapes the field content string to avoid confusion with file comments. + * Returned field must be free()d by caller. + */ static char *escape(const char *str) { // Determine the size of resultant string. @@ -82,8 +85,10 @@ static char *escape(const char *str) return result; } -/* Removes all comment lines, and unescapes the string previously escaped - by escape(). Works in-place. */ +/* + * Removes all comment lines, and unescapes the string previously escaped + * by escape(). Works in-place. + */ static char *remove_comments_and_unescape(char *str) { char *src = str, *dest = str; @@ -138,17 +143,19 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, fprintf(fp, "%s%s\n", FIELD_SEP, it->first.c_str()); - bool readonly = (it->second[CD_EDITABLE] != CD_ISEDITABLE); - fprintf(fp, readonly ? _("# %s (read only)\n") : "# %s\n", description); + fprintf(fp, "%s\n", description); + if (it->second[CD_EDITABLE] != CD_ISEDITABLE) + fprintf(fp, _("# This field is read only.\n")); char *escaped_content = escape(it->second[CD_CONTENT].c_str()); fprintf(fp, "%s\n", escaped_content); free(escaped_content); } -/* Saves the crash report to a file. - * Fp must be opened before write_crash_report is called. - * Returned Value: +/* + * Saves the crash report to a file. + * Parameter 'fp' must be opened before write_crash_report is called. + * Returned value: * If the report is successfully stored to the file, a zero value is returned. * On failure, nonzero value is returned. */ @@ -158,22 +165,22 @@ static int write_crash_report(const map_crash_report_t &report, FILE *fp) "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); write_crash_report_field(fp, report, "Comment", - _("Describe the circumstances of this crash below.")); + _("# Describe the circumstances of this crash below.")); write_crash_report_field(fp, report, "How to reproduce", - _("How to reproduce the crash?")); + _("# How to reproduce the crash?")); write_crash_report_field(fp, report, "backtrace", - _("Backtrace. Check that it does not contain any sensitive data such as passwords.")); - write_crash_report_field(fp, report, "UUID", "UUID"); - write_crash_report_field(fp, report, "architecture", "Architecture"); - write_crash_report_field(fp, report, "cmdline", "Command line"); - write_crash_report_field(fp, report, "component", "Component"); - write_crash_report_field(fp, report, "coredump", "Core dump"); - write_crash_report_field(fp, report, "executable", "Executable"); - write_crash_report_field(fp, report, "kernel", "Kernel"); - write_crash_report_field(fp, report, "package", "Package"); - write_crash_report_field(fp, report, "reason", "Reason"); - write_crash_report_field(fp, report, "release", "Release"); - + _("# Stack trace: a list of active stack frames at the time the crash occurred\n# Check that it does not contain any sensitive data such as passwords.")); + write_crash_report_field(fp, report, "UUID", _("# UUID")); + write_crash_report_field(fp, report, "architecture", _("# Architecture")); + write_crash_report_field(fp, report, "cmdline", _("# Command line")); + write_crash_report_field(fp, report, "component", _("# Component")); + write_crash_report_field(fp, report, "coredump", _("# Core dump")); + write_crash_report_field(fp, report, "executable", _("# Executable")); + write_crash_report_field(fp, report, "kernel", _("# Kernel version")); + write_crash_report_field(fp, report, "package", _("# Package")); + write_crash_report_field(fp, report, "reason", _("# Reason of crash")); + write_crash_report_field(fp, report, "release", _("# Release string of the operating system")); + return 0; } @@ -313,7 +320,6 @@ int report(const char *uuid, bool always) fseek(fp, 0, SEEK_END); long size = ftell(fp); - printf("%d", size); fseek(fp, 0, SEEK_SET); char *text = (char*)malloc(size + 1); @@ -331,14 +337,12 @@ int report(const char *uuid, bool always) /*int result = */unlink(filename); - printf(_("\nReport has been updated.\nDo you want to send the report? [y/n]: ")); + printf(_("\nThe report has been updated.\nDo you want to send the report? [y/N]: ")); fflush(NULL); char answer[16] = "n"; fgets(answer, sizeof(answer), stdin); if (answer[0] == 'Y' || answer[0] == 'y') - { call_Report(cr); - } return 0; } -- cgit From 8ea7097910579362f994ceaf17b9d256ce894826 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 16:49:10 +0200 Subject: Print error on unlink failure. --- src/CLI/report.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 57dc6251..e1a0cd2f 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -335,7 +335,8 @@ int report(const char *uuid, bool always) read_crash_report(cr, text); free(text); - /*int result = */unlink(filename); + if (unlink(filename) != 0) + error_msg("could not unlink %s: %s", filename, strerror(errno)); printf(_("\nThe report has been updated.\nDo you want to send the report? [y/N]: ")); fflush(NULL); -- cgit From 8f5fdfffdb74a69b5008f11d4d922eba11c842ac Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 16:56:27 +0200 Subject: new_call_msg and send_get_reply_and_unref made static --- src/CLI/dbus.cpp | 4 ++-- src/CLI/dbus.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp index 3a2999e2..64dac094 100644 --- a/src/CLI/dbus.cpp +++ b/src/CLI/dbus.cpp @@ -25,7 +25,7 @@ DBusConnection* s_dbus_conn; */ /* helpers */ -DBusMessage* new_call_msg(const char* method) +static DBusMessage* new_call_msg(const char* method) { DBusMessage* msg = dbus_message_new_method_call(CC_DBUS_NAME, CC_DBUS_PATH, CC_DBUS_IFACE, method); if (!msg) @@ -33,7 +33,7 @@ DBusMessage* new_call_msg(const char* method) return msg; } -DBusMessage* send_get_reply_and_unref(DBusMessage* msg) +static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) { DBusError err; dbus_error_init(&err); diff --git a/src/CLI/dbus.h b/src/CLI/dbus.h index febcb942..c6cb82a9 100644 --- a/src/CLI/dbus.h +++ b/src/CLI/dbus.h @@ -23,8 +23,6 @@ extern DBusConnection* s_dbus_conn; -extern DBusMessage* new_call_msg(const char* method); -extern DBusMessage* send_get_reply_and_unref(DBusMessage* msg); extern vector_crash_infos_t call_GetCrashInfos(); extern map_crash_report_t call_CreateReport(const char* uuid); extern void call_Report(const map_crash_report_t& report); -- cgit From c88b42d31d786dddf4dda5a4beb6bc34a405fecc Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 17:11:08 +0200 Subject: More comments. --- src/CLI/report.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index e1a0cd2f..88cb1cef 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -122,7 +122,8 @@ static char *remove_comments_and_unescape(char *str) *dest = '\0'; } -/* Writes a field of crash report to a file. +/* + * Writes a field of crash report to a file. * Field must be writable. */ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, @@ -277,10 +278,12 @@ int launch_editor(const char *path) /* Reports the crash with corresponding uuid over DBus. */ int report(const char *uuid, bool always) { + // Ask for an initial report. map_crash_report_t cr = call_CreateReport(uuid); if (always) { + // Send the report immediately. call_Report(cr); return 0; } @@ -308,9 +311,11 @@ int report(const char *uuid, bool always) error_msg("could not close '%s'", filename); return 2; } - + + // Start a text editor on the temporary file. launch_editor(filename); + // Read the file back and update the report from the file. fp = fopen(filename, "r"); if (!fp) { @@ -332,12 +337,13 @@ int report(const char *uuid, bool always) fclose(fp); remove_comments_and_unescape(text); - read_crash_report(cr, text); + read_crash_report(cr, text); // Updates the crash report from the file text. free(text); - if (unlink(filename) != 0) + if (unlink(filename) != 0) // Delete the tempfile. error_msg("could not unlink %s: %s", filename, strerror(errno)); + // Report only if the user is sure. printf(_("\nThe report has been updated.\nDo you want to send the report? [y/N]: ")); fflush(NULL); char answer[16] = "n"; -- cgit From e1a887790d3e98f695f9f88e4d12dd675c7211b9 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 17:47:59 +0200 Subject: Inform whether some changes were detected in the crash report. --- src/CLI/report.cpp | 108 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 88cb1cef..55065321 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -32,6 +32,33 @@ /* Field separator for the crash report file that is edited by user. */ #define FIELD_SEP "%----" +/* + * Trims whitespace characters both from left and right side of a string. + * Modifies the string in-place. Returns the trimmed string. + */ +char *trim(char *str) +{ + if (!str) + return NULL; + + // Remove leading spaces. + char *ibuf; + for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf) + ; + if (str != ibuf) + memmove(str, ibuf, ibuf - str); + + // Remove trailing spaces. + int i = strlen(str); + while (--i >= 0) + { + if (!isspace(str[i])) + break; + } + str[++i] = NULL; + return str; +} + /* * Escapes the field content string to avoid confusion with file comments. * Returned field must be free()d by caller. @@ -188,15 +215,19 @@ static int write_crash_report(const map_crash_report_t &report, FILE *fp) /* * Updates appropriate field in the report from the text. The text can * contain multiple fields. + * Returns: + * 0 if no change to the field was detected. + * 1 if the field was changed. + * Changes to read-only fields are ignored. */ -static void read_crash_report_field(const char *text, map_crash_report_t &report, - const char *field) +static int read_crash_report_field(const char *text, map_crash_report_t &report, + const char *field) { char separator[strlen("\n" FIELD_SEP) + strlen(field) + 2]; // 2 = '\n\0' sprintf(separator, "\n%s%s\n", FIELD_SEP, field); const char *textfield = strstr(text, separator); if (!textfield) - return; + return 0; textfield += strlen(separator); int length = 0; @@ -210,40 +241,63 @@ static void read_crash_report_field(const char *text, map_crash_report_t &report if (it == report.end()) { error_msg("Field %s not found.\n", field); - return; + return 0; } if (it->second[CD_TYPE] == CD_SYS) { error_msg("Cannot update field %s because it is a system value.\n", field); - return; + return 0; } - if (it->second[CD_EDITABLE] == CD_ISEDITABLE) - it->second[CD_CONTENT].assign(textfield, length); + // Do not change noneditable fields. + if (it->second[CD_EDITABLE] != CD_ISEDITABLE) + return 0; + + // Compare the old field contents with the new field contents. + char newvalue[length + 1]; + strncpy(newvalue, textfield, length); + newvalue[length] = '\0'; + trim(newvalue); + + char oldvalue[it->second[CD_CONTENT].length() + 1]; + strcpy(oldvalue, it->second[CD_CONTENT].c_str()); + trim(oldvalue); + + // Return if no change in the contents detected. + int cmp = strcmp(newvalue, oldvalue); + if (!cmp) + return 0; + + it->second[CD_CONTENT].assign(newvalue); + return 1; } /* * Updates the crash report 'report' from the text. The text must not contain * any comments. + * Returns: + * 0 if no field was changed. + * 1 if any field was changed. + * Changes to read-only fields are ignored. */ static int read_crash_report(map_crash_report_t &report, const char *text) { - read_crash_report_field(text, report, "Comment"); - read_crash_report_field(text, report, "How to reproduce"); - read_crash_report_field(text, report, "backtrace"); - read_crash_report_field(text, report, "UUID"); - read_crash_report_field(text, report, "architecture"); - read_crash_report_field(text, report, "cmdline"); - read_crash_report_field(text, report, "component"); - read_crash_report_field(text, report, "coredump"); - read_crash_report_field(text, report, "executable"); - read_crash_report_field(text, report, "kernel"); - read_crash_report_field(text, report, "package"); - read_crash_report_field(text, report, "reason"); - read_crash_report_field(text, report, "release"); - - return 0; + int result = 0; + result |= read_crash_report_field(text, report, "Comment"); + result |= read_crash_report_field(text, report, "How to reproduce"); + result |= read_crash_report_field(text, report, "backtrace"); + result |= read_crash_report_field(text, report, "UUID"); + result |= read_crash_report_field(text, report, "architecture"); + result |= read_crash_report_field(text, report, "cmdline"); + result |= read_crash_report_field(text, report, "component"); + result |= read_crash_report_field(text, report, "coredump"); + result |= read_crash_report_field(text, report, "executable"); + result |= read_crash_report_field(text, report, "kernel"); + result |= read_crash_report_field(text, report, "package"); + result |= read_crash_report_field(text, report, "reason"); + result |= read_crash_report_field(text, report, "release"); + return result; } /* Runs external editor. */ @@ -337,14 +391,20 @@ int report(const char *uuid, bool always) fclose(fp); remove_comments_and_unescape(text); - read_crash_report(cr, text); // Updates the crash report from the file text. + // Updates the crash report from the file text. + int report_changed = read_crash_report(cr, text); + if (report_changed) + puts(_("\nThe report has been updated.")); + else + puts(_("\nNo changes were detected in the report.")); + free(text); if (unlink(filename) != 0) // Delete the tempfile. error_msg("could not unlink %s: %s", filename, strerror(errno)); // Report only if the user is sure. - printf(_("\nThe report has been updated.\nDo you want to send the report? [y/N]: ")); + printf(_("Do you want to send the report? [y/N]: ")); fflush(NULL); char answer[16] = "n"; fgets(answer, sizeof(answer), stdin); -- cgit From 908ba185ac9651945f4c4c4f8fb5155875cd246c Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Tue, 20 Oct 2009 17:54:53 +0200 Subject: Tell user about sending the report. --- src/CLI/report.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 55065321..b9c6d414 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -409,7 +409,13 @@ int report(const char *uuid, bool always) char answer[16] = "n"; fgets(answer, sizeof(answer), stdin); if (answer[0] == 'Y' || answer[0] == 'y') + { + puts(_("Reporting...")); call_Report(cr); + puts(_("Crash report was successfully sent.")); + } + else + puts(_("Crash report was not sent.")); return 0; } -- cgit From 321a278ea5b1e5defd6e4dd35a108c0838fc8f98 Mon Sep 17 00:00:00 2001 From: kristho Date: Wed, 21 Oct 2009 00:06:51 +0000 Subject: Sending translation for Danish --- po/da.po | 143 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/po/da.po b/po/da.po index 3f201c35..f2f6aa20 100644 --- a/po/da.po +++ b/po/da.po @@ -7,47 +7,51 @@ msgid "" msgstr "" "Project-Id-Version: abrt\n" "Report-Msgid-Bugs-To: jmoskovc@redhat.com\n" -"POT-Creation-Date: 2009-09-22 19:32+0000\n" -"PO-Revision-Date: 2009-09-22 22:27+0200\n" +"POT-Creation-Date: 2009-10-15 09:50+0000\n" +"PO-Revision-Date: 2009-10-16 22:53+0200\n" "Last-Translator: Kris Thomsen \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/Gui/ABRTExceptions.py:4 +#: ../src/Gui/ABRTExceptions.py:6 msgid "Another client is already running, trying to wake it." msgstr "En anden klient kører allerede, prøver at vække den." -#: ../src/Gui/ABRTExceptions.py:10 +#: ../src/Gui/ABRTExceptions.py:13 msgid "Got unexpected data from daemon (is the database properly updated?)." msgstr "Modtog uventede data fra dæmon (er databasen opdateret rigtigt?)." -#: ../src/Gui/ABRTPlugin.py:26 +#: ../src/Gui/ABRTPlugin.py:48 msgid "Analyzer plugins" msgstr "Analyseringsudvidelsesmoduler" -#: ../src/Gui/ABRTPlugin.py:27 +#: ../src/Gui/ABRTPlugin.py:49 msgid "Action plugins" msgstr "Handlingsudvidelsesmoduler" -#: ../src/Gui/ABRTPlugin.py:28 +#: ../src/Gui/ABRTPlugin.py:50 msgid "Reporter plugins" msgstr "Rapporteringsudvidelsesmoduler" -#: ../src/Gui/ABRTPlugin.py:29 +#: ../src/Gui/ABRTPlugin.py:51 msgid "Database plugins" msgstr "Databaseudvidelsesmoduler" -#: ../src/Gui/CCDBusBackend.py:140 -msgid "Can't connect to dbus" -msgstr "Kan ikke forbinde til dbus" +#: ../src/Gui/ABRTPlugin.py:90 +msgid "Plugin name is not set, can't load it's settings" +msgstr "Navn for udvidelsesmodul er ikke indstillet, kan ikke indlæse dets indstillinger" -#: ../src/Gui/CCDBusBackend.py:144 ../src/Gui/CCDBusBackend.py:164 -msgid "Please check if abrt daemon is running." -msgstr "Kontrollér om abrt-dæmonen kører." +#: ../src/Gui/CCDBusBackend.py:74 ../src/Gui/CCDBusBackend.py:97 +msgid "Can't connect to system dbus" +msgstr "Kan ikke forbinde til system-dbus" -#: ../src/Gui/CCDBusBackend.py:182 +#: ../src/Gui/CCDBusBackend.py:100 ../src/Gui/CCDBusBackend.py:103 +msgid "Please check if abrt daemon is running" +msgstr "Kontrollér venligst om abrt-dæmonen kører" + +#: ../src/Gui/CCDBusBackend.py:155 msgid "" "Daemon did't return valid report info\n" "Debuginfo is missing?" @@ -63,7 +67,7 @@ msgstr " " msgid "(C) 2009 Red Hat, Inc." msgstr "(C) 2009 Red Hat, Inc." -#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/CCMainWindow.py:236 +#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/CCMainWindow.py:240 msgid "Not reported!" msgstr "Ikke rapporteret!" @@ -140,31 +144,31 @@ msgid "_Help" msgstr "_Hjælp" #. add pixbuff separatelly -#: ../src/Gui/CCMainWindow.py:79 +#: ../src/Gui/CCMainWindow.py:80 msgid "Icon" msgstr "Ikon" -#: ../src/Gui/CCMainWindow.py:87 +#: ../src/Gui/CCMainWindow.py:88 msgid "Package" msgstr "Pakke" -#: ../src/Gui/CCMainWindow.py:88 +#: ../src/Gui/CCMainWindow.py:89 msgid "Application" msgstr "Program" -#: ../src/Gui/CCMainWindow.py:89 +#: ../src/Gui/CCMainWindow.py:90 msgid "Date" msgstr "Dato" -#: ../src/Gui/CCMainWindow.py:90 +#: ../src/Gui/CCMainWindow.py:91 msgid "Crash Rate" msgstr "Nedbrudsrate" -#: ../src/Gui/CCMainWindow.py:92 +#: ../src/Gui/CCMainWindow.py:93 msgid "User" msgstr "Bruger" -#: ../src/Gui/CCMainWindow.py:174 +#: ../src/Gui/CCMainWindow.py:178 #, python-format msgid "" "Unable to finish current task!\n" @@ -173,7 +177,7 @@ msgstr "" "Kunne ikke afslutte nuværende handling!\n" "%s" -#: ../src/Gui/CCMainWindow.py:191 +#: ../src/Gui/CCMainWindow.py:195 #, python-format msgid "" "Error while loading the dumplist, please check if abrt daemon is running\n" @@ -183,17 +187,17 @@ msgstr "" "kører\n" " %s" -#: ../src/Gui/CCMainWindow.py:201 +#: ../src/Gui/CCMainWindow.py:205 #, python-format msgid "Can't get username for uid %s" msgstr "Kan ikke hente brugernavn for uid %s" -#: ../src/Gui/CCMainWindow.py:228 +#: ../src/Gui/CCMainWindow.py:232 msgid "This crash has been reported, you can find the report(s) at:\n" msgstr "" "Dette nedbrud er blevet rapporteret, du kan finde rapporten på: \n" -#: ../src/Gui/CCMainWindow.py:288 +#: ../src/Gui/CCMainWindow.py:292 msgid "" "Unable to get report!\n" "Debuginfo is missing?" @@ -201,7 +205,7 @@ msgstr "" "Kunne ikke hente rapport!\n" "Mangler fejlsøgningsinformation?" -#: ../src/Gui/CCMainWindow.py:300 +#: ../src/Gui/CCMainWindow.py:310 #, python-format msgid "" "Reporting failed!\n" @@ -210,12 +214,17 @@ msgstr "" "Rapportering fejlede!\n" "%s" -#: ../src/Gui/CCMainWindow.py:332 +#: ../src/Gui/CCMainWindow.py:329 ../src/Gui/CCMainWindow.py:356 #, python-format msgid "Error getting the report: %s" msgstr "Fejl under hentning af rapporten: %s" -#: ../src/Gui/CCReporterDialog.py:98 +#: ../src/Gui/CCReporterDialog.py:167 +msgid "Brief description how to reproduce this or what you did..." +msgstr "" +"Kort beskrivelse om hvordan fejlen kan gentages eller hvad du gjorde..." + +#: ../src/Gui/CCReporterDialog.py:211 #, python-format msgid "" "WARNING, you're about to send data which might contain sensitive " @@ -226,11 +235,6 @@ msgstr "" "information!\n" "Vil du virkelig sende %s?\n" -#: ../src/Gui/CCReporterDialog.py:111 -msgid "Brief description how to reproduce this or what you did..." -msgstr "" -"Kort beskrivelse om hvordan fejlen kan gentages eller hvad du gjorde..." - #: ../src/Gui/dialogs.glade.h:1 msgid "Report done" msgstr "Rapportering færdiggjort" @@ -239,21 +243,21 @@ msgstr "Rapportering færdiggjort" msgid "gtk-ok" msgstr "gtk-ok" -#: ../src/Gui/PluginSettingsUI.py:17 +#: ../src/Gui/PluginSettingsUI.py:18 msgid "Can't find PluginDialog widget in UI description!" msgstr "Kan ikke finde PluginDialog-widget i UI-beskrivelse!" #. we shouldn't get here, but just to be safe -#: ../src/Gui/PluginSettingsUI.py:21 +#: ../src/Gui/PluginSettingsUI.py:24 #, python-format msgid "No UI for plugin %s" msgstr "Ingen UI for udvidelsesmodul %s" -#: ../src/Gui/PluginSettingsUI.py:38 ../src/Gui/PluginSettingsUI.py:64 +#: ../src/Gui/PluginSettingsUI.py:55 ../src/Gui/PluginSettingsUI.py:81 msgid "combo box is not implemented" msgstr "comboboks er ikke implementeret" -#: ../src/Gui/PluginSettingsUI.py:47 +#: ../src/Gui/PluginSettingsUI.py:64 msgid "Nothing to hydrate!" msgstr "Intet at hydrere!" @@ -269,6 +273,10 @@ msgstr "Send" msgid "gtk-cancel" msgstr "gtk-cancel" +#: ../src/Gui/report.glade.h:5 +msgid "gtk-refresh" +msgstr "gtk-refresh" + #: ../src/Gui/SettingsDialog.py:34 ../src/Gui/SettingsDialog.py:51 msgid "Select plugin" msgstr "Vælg udvidelsesmodul" @@ -277,11 +285,11 @@ msgstr "Vælg udvidelsesmodul" msgid "Select database backend" msgstr "Vælg databasebackend" -#: ../src/Gui/SettingsDialog.py:165 +#: ../src/Gui/SettingsDialog.py:168 msgid "Remove this job" msgstr "Fjern dette job" -#: ../src/Gui/SettingsDialog.py:208 +#: ../src/Gui/SettingsDialog.py:211 msgid "Remove this action" msgstr "Fjern denne handling" @@ -389,16 +397,16 @@ msgstr "gtk-close" msgid "gtk-remove" msgstr "gtk-remove" -#: ../src/Applet/Applet.cpp:76 +#: ../src/Applet/Applet.cpp:71 #, c-format msgid "A crash in package %s has been detected" msgstr "Der blev fundet et nedbrud i pakke %s" -#: ../src/Applet/Applet.cpp:145 +#: ../src/Applet/Applet.cpp:130 msgid "ABRT service has been started" msgstr "ABRT-tjenesten er blevet startet" -#: ../src/Applet/Applet.cpp:147 ../src/Applet/Applet.cpp:261 +#: ../src/Applet/Applet.cpp:132 ../src/Applet/Applet.cpp:246 msgid "ABRT service is not running" msgstr "ABRT-service kører ikke" @@ -406,7 +414,7 @@ msgstr "ABRT-service kører ikke" msgid "Warning" msgstr "Advarsel" -#: ../src/Daemon/Daemon.cpp:545 +#: ../src/Daemon/Daemon.cpp:542 msgid "" "Report size exceeded the quota. Please check system's MaxCrashReportsSize " "value in abrt.conf." @@ -418,36 +426,36 @@ msgstr "" msgid "Empty login and password. Please check Bugzilla.conf" msgstr "Tom logind og adgangskode. Kontrollér Bugzilla.conf" -#: ../lib/Plugins/Bugzilla.cpp:227 +#: ../lib/Plugins/Bugzilla.cpp:205 msgid "Bug is already reported: " msgstr "Fejl er allerede rapporteret: " -#: ../lib/Plugins/Bugzilla.cpp:282 +#: ../lib/Plugins/Bugzilla.cpp:260 #, c-format msgid "Binary file %s will not be reported." msgstr "Binærfil %s vil ikke blive rapporteret." -#: ../lib/Plugins/Bugzilla.cpp:352 +#: ../lib/Plugins/Bugzilla.cpp:330 msgid "New bug id: " msgstr "Ny bug-id: " -#: ../lib/Plugins/Bugzilla.cpp:421 +#: ../lib/Plugins/Bugzilla.cpp:399 msgid "Checking for duplicates..." msgstr "Kontrollerer for dubletter..." -#: ../lib/Plugins/Bugzilla.cpp:424 ../lib/Plugins/Bugzilla.cpp:436 +#: ../lib/Plugins/Bugzilla.cpp:402 ../lib/Plugins/Bugzilla.cpp:413 msgid "Logging into bugzilla..." msgstr "Logger ind på bugzilla..." -#: ../lib/Plugins/Bugzilla.cpp:427 -msgid "Check CC and add coment +1..." -msgstr "Kontrollér CC og tilføj kommentar +1..." +#: ../lib/Plugins/Bugzilla.cpp:405 +msgid "Checking CC..." +msgstr "Kontrollerer for CC..." -#: ../lib/Plugins/Bugzilla.cpp:448 +#: ../lib/Plugins/Bugzilla.cpp:425 msgid "Creating new bug..." msgstr "Opretter ny fejl..." -#: ../lib/Plugins/Bugzilla.cpp:453 +#: ../lib/Plugins/Bugzilla.cpp:430 msgid "Logging out..." msgstr "Logger ud..." @@ -455,31 +463,31 @@ msgstr "Logger ud..." msgid "Getting local universal unique identification" msgstr "Henter lokal, universal, unik identifikation" -#: ../lib/Plugins/CCpp.cpp:146 +#: ../lib/Plugins/CCpp.cpp:153 msgid "Getting backtrace..." msgstr "Henter backtrace..." -#: ../lib/Plugins/CCpp.cpp:384 +#: ../lib/Plugins/CCpp.cpp:434 msgid "Searching for debug-info packages..." msgstr "Søger efter pakker med fejlsøgningsinformation..." -#: ../lib/Plugins/CCpp.cpp:418 +#: ../lib/Plugins/CCpp.cpp:496 msgid "Downloading and installing debug-info packages..." msgstr "Henter og installerer pakker med fejlsøgningsinformation..." -#: ../lib/Plugins/CCpp.cpp:480 +#: ../lib/Plugins/CCpp.cpp:558 msgid "Getting local universal unique identification..." msgstr "Henter lokal, universal, unik identifikation..." -#: ../lib/Plugins/CCpp.cpp:499 +#: ../lib/Plugins/CCpp.cpp:577 msgid "Getting global universal unique identification..." msgstr "Henter global, universal, unik identifikation..." -#: ../lib/Plugins/CCpp.cpp:551 +#: ../lib/Plugins/CCpp.cpp:628 msgid "Starting report creation..." msgstr "Starter rapportoprettelse..." -#: ../lib/Plugins/CCpp.cpp:580 +#: ../lib/Plugins/CCpp.cpp:659 msgid "Skipping debuginfo installation" msgstr "Springer over fejlsøgningsinfo-installation" @@ -495,20 +503,20 @@ msgstr "Opretter en rapport..." msgid "Executing RunApp plugin..." msgstr "Udfører RunApp-udvidelsesmodul..." -#: ../lib/Plugins/FileTransfer.cpp:60 ../lib/Plugins/FileTransfer.cpp:355 +#: ../lib/Plugins/FileTransfer.cpp:63 ../lib/Plugins/FileTransfer.cpp:409 msgid "FileTransfer: URL not specified" msgstr "Filoverførsel: URL ikke angivet" -#: ../lib/Plugins/FileTransfer.cpp:77 +#: ../lib/Plugins/FileTransfer.cpp:81 #, c-format msgid "Sending archive %s via %s" msgstr "Sender arkiv %s via %s" -#: ../lib/Plugins/FileTransfer.cpp:284 +#: ../lib/Plugins/FileTransfer.cpp:336 msgid "File Transfer: Creating a report..." msgstr "Filoverførsel: Opretter en rapport..." -#: ../lib/Plugins/FileTransfer.cpp:305 ../lib/Plugins/FileTransfer.cpp:334 +#: ../lib/Plugins/FileTransfer.cpp:358 ../lib/Plugins/FileTransfer.cpp:386 msgid "CFileTransfer::Run(): Cannot create and send an archive: " msgstr "CFileTransfer::Run(): Kan ikke oprette og sende et arkiv: " @@ -532,6 +540,9 @@ msgstr "kører sosreport: " msgid "done running sosreport" msgstr "færdig med at køre sosreport" +#~ msgid "Check CC and add coment +1..." +#~ msgstr "Kontrollér CC og tilføj kommentar +1..." + #~ msgid "Pending events: %i" #~ msgstr "Ventende handlinger: %i" -- cgit From af6c31428ca04e05f982b730d24c621fe54e1372 Mon Sep 17 00:00:00 2001 From: warrink Date: Wed, 21 Oct 2009 09:59:46 +0000 Subject: Sending translation for Dutch --- po/nl.po | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/po/nl.po b/po/nl.po index 902abd99..12f8903b 100644 --- a/po/nl.po +++ b/po/nl.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: abrt\n" "Report-Msgid-Bugs-To: jmoskovc@redhat.com\n" -"POT-Creation-Date: 2009-10-08 17:38+0000\n" -"PO-Revision-Date: 2009-10-08 21:12+0200\n" +"POT-Creation-Date: 2009-10-16 16:11+0000\n" +"PO-Revision-Date: 2009-10-16 21:12+0200\n" "Last-Translator: Geert Warrink \n" "Language-Team: nl \n" "MIME-Version: 1.0\n" @@ -207,7 +207,7 @@ msgstr "" "Kan geen rapport krijgen!\n" "Mist debuginfo?" -#: ../src/Gui/CCMainWindow.py:308 +#: ../src/Gui/CCMainWindow.py:310 #, python-format msgid "" "Reporting failed!\n" @@ -216,12 +216,16 @@ msgstr "" "Rapporteren mislukte!\n" "%s" -#: ../src/Gui/CCMainWindow.py:340 +#: ../src/Gui/CCMainWindow.py:329 ../src/Gui/CCMainWindow.py:356 #, python-format msgid "Error getting the report: %s" msgstr "Fout tijdens het verkrijgen van het rapport: %s" -#: ../src/Gui/CCReporterDialog.py:98 +#: ../src/Gui/CCReporterDialog.py:167 +msgid "Brief description how to reproduce this or what you did..." +msgstr "Korte beschrijving hoe dit te reproduceren is of wat je deed..." + +#: ../src/Gui/CCReporterDialog.py:211 #, python-format msgid "" "WARNING, you're about to send data which might contain sensitive " @@ -232,10 +236,6 @@ msgstr "" "informatie kan bevatten\n" "Wil je %s echt versturen?\n" -#: ../src/Gui/CCReporterDialog.py:111 -msgid "Brief description how to reproduce this or what you did..." -msgstr "Korte beschrijving hoe dit te reproduceren is of wat je deed..." - #: ../src/Gui/dialogs.glade.h:1 msgid "Report done" msgstr "Rapport klaar" @@ -274,6 +274,10 @@ msgstr "Verzenden" msgid "gtk-cancel" msgstr "gtk-cancel" +#: ../src/Gui/report.glade.h:5 +msgid "gtk-refresh" +msgstr "gtk-refresh" + #: ../src/Gui/SettingsDialog.py:34 ../src/Gui/SettingsDialog.py:51 msgid "Select plugin" msgstr "Selecteer een plugin" @@ -411,7 +415,7 @@ msgstr "ABRT service draait niet" msgid "Warning" msgstr "Waarschuwing" -#: ../src/Daemon/Daemon.cpp:546 +#: ../src/Daemon/Daemon.cpp:542 msgid "" "Report size exceeded the quota. Please check system's MaxCrashReportsSize " "value in abrt.conf." @@ -460,31 +464,31 @@ msgstr "Uitloggen..." msgid "Getting local universal unique identification" msgstr "Verkrijgen van locale universele unieke identificatie" -#: ../lib/Plugins/CCpp.cpp:146 +#: ../lib/Plugins/CCpp.cpp:161 msgid "Getting backtrace..." msgstr "Backtrace ophalen..." -#: ../lib/Plugins/CCpp.cpp:415 +#: ../lib/Plugins/CCpp.cpp:442 msgid "Searching for debug-info packages..." msgstr "Zoeken naar debug-info pakketten..." -#: ../lib/Plugins/CCpp.cpp:451 +#: ../lib/Plugins/CCpp.cpp:504 msgid "Downloading and installing debug-info packages..." msgstr "Downloaden en installeren van debug-info pakketten..." -#: ../lib/Plugins/CCpp.cpp:513 +#: ../lib/Plugins/CCpp.cpp:566 msgid "Getting local universal unique identification..." msgstr "Verkrijgen van locale universele unieke identificatie..." -#: ../lib/Plugins/CCpp.cpp:532 +#: ../lib/Plugins/CCpp.cpp:585 msgid "Getting global universal unique identification..." msgstr "Verkrijgen van golbale universele unieke identificatie..." -#: ../lib/Plugins/CCpp.cpp:583 +#: ../lib/Plugins/CCpp.cpp:630 msgid "Starting report creation..." msgstr "Beginnen met rapport aanmaken..." -#: ../lib/Plugins/CCpp.cpp:612 +#: ../lib/Plugins/CCpp.cpp:661 msgid "Skipping debuginfo installation" msgstr "Sla debuginfo installatie over" -- cgit From c5cbf4ac39edb168810eb94a55c3282aa30b0620 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Wed, 21 Oct 2009 14:55:32 +0200 Subject: Use defines instead of strings where possible. --- src/CLI/report.cpp | 46 ++++++++++++++++++++++++---------------------- src/Daemon/MiddleWare.cpp | 2 +- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index b9c6d414..8dedf036 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -19,6 +19,7 @@ #include "run-command.h" #include "dbus.h" #include "abrtlib.h" +#include "DebugDump.h" // FILENAME_* defines #if HAVE_CONFIG_H #include #endif @@ -159,7 +160,8 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, const map_crash_report_t::const_iterator it = report.find(field); if (it == report.end()) { - error_msg("Field %s not found.\n", field); + // exit silently, all fields are optional for now + //error_msg("Field %s not found.\n", field); return; } @@ -192,22 +194,22 @@ static int write_crash_report(const map_crash_report_t &report, FILE *fp) fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); - write_crash_report_field(fp, report, "Comment", + write_crash_report_field(fp, report, CD_COMMENT, _("# Describe the circumstances of this crash below.")); - write_crash_report_field(fp, report, "How to reproduce", + write_crash_report_field(fp, report, CD_REPRODUCE, _("# How to reproduce the crash?")); write_crash_report_field(fp, report, "backtrace", _("# Stack trace: a list of active stack frames at the time the crash occurred\n# Check that it does not contain any sensitive data such as passwords.")); - write_crash_report_field(fp, report, "UUID", _("# UUID")); - write_crash_report_field(fp, report, "architecture", _("# Architecture")); + write_crash_report_field(fp, report, CD_UUID, _("# UUID")); + write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture")); write_crash_report_field(fp, report, "cmdline", _("# Command line")); - write_crash_report_field(fp, report, "component", _("# Component")); + write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component")); write_crash_report_field(fp, report, "coredump", _("# Core dump")); - write_crash_report_field(fp, report, "executable", _("# Executable")); - write_crash_report_field(fp, report, "kernel", _("# Kernel version")); - write_crash_report_field(fp, report, "package", _("# Package")); - write_crash_report_field(fp, report, "reason", _("# Reason of crash")); - write_crash_report_field(fp, report, "release", _("# Release string of the operating system")); + write_crash_report_field(fp, report, FILENAME_EXECUTABLE, _("# Executable")); + write_crash_report_field(fp, report, FILENAME_KERNEL, _("# Kernel version")); + write_crash_report_field(fp, report, FILENAME_PACKAGE, _("# Package")); + write_crash_report_field(fp, report, FILENAME_REASON, _("# Reason of crash")); + write_crash_report_field(fp, report, FILENAME_RELEASE, _("# Release string of the operating system")); return 0; } @@ -227,7 +229,7 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, sprintf(separator, "\n%s%s\n", FIELD_SEP, field); const char *textfield = strstr(text, separator); if (!textfield) - return 0; + return 0; // exit silently because all fields are optional textfield += strlen(separator); int length = 0; @@ -284,19 +286,19 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, static int read_crash_report(map_crash_report_t &report, const char *text) { int result = 0; - result |= read_crash_report_field(text, report, "Comment"); - result |= read_crash_report_field(text, report, "How to reproduce"); + result |= read_crash_report_field(text, report, CD_COMMENT); + result |= read_crash_report_field(text, report, CD_REPRODUCE); result |= read_crash_report_field(text, report, "backtrace"); - result |= read_crash_report_field(text, report, "UUID"); - result |= read_crash_report_field(text, report, "architecture"); + result |= read_crash_report_field(text, report, CD_UUID); + result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE); result |= read_crash_report_field(text, report, "cmdline"); - result |= read_crash_report_field(text, report, "component"); + result |= read_crash_report_field(text, report, FILENAME_COMPONENT); result |= read_crash_report_field(text, report, "coredump"); - result |= read_crash_report_field(text, report, "executable"); - result |= read_crash_report_field(text, report, "kernel"); - result |= read_crash_report_field(text, report, "package"); - result |= read_crash_report_field(text, report, "reason"); - result |= read_crash_report_field(text, report, "release"); + result |= read_crash_report_field(text, report, FILENAME_EXECUTABLE); + result |= read_crash_report_field(text, report, FILENAME_KERNEL); + result |= read_crash_report_field(text, report, FILENAME_PACKAGE); + result |= read_crash_report_field(text, report, FILENAME_REASON); + result |= read_crash_report_field(text, report, FILENAME_RELEASE); return result; } diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp index 05abc9b5..9060d79a 100644 --- a/src/Daemon/MiddleWare.cpp +++ b/src/Daemon/MiddleWare.cpp @@ -499,7 +499,7 @@ void LoadOpenGPGPublicKey(const char* key) * @return It return results of operation. See mw_result_t. */ static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecutable, - const std::string& pDebugDumpDir) + const std::string& pDebugDumpDir) { std::string package; std::string packageName; -- cgit From 4fdccf0281cb9158988e504151d6b7bfb89b465c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 21 Oct 2009 14:58:59 +0200 Subject: lib/Plugins/CCpp.cpp: add a workaround for gdb bug Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 3fedd947..0e0eb3b3 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -169,6 +169,11 @@ static void GetBacktrace(const std::string& pDebugDumpDir, std::string& pBacktra dd.LoadText(FILENAME_UID, UID); } + // Workaround for + // http://sourceware.org/bugzilla/show_bug.cgi?id=9622 + unsetenv("TERM"); + putenv((char*)"TERM=dumb"); + char* args[9]; args[0] = (char*)"gdb"; args[1] = (char*)"-batch"; -- cgit From cbe239d9d7a13b7b39f5adaae704ffcf586b3f52 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Wed, 21 Oct 2009 15:36:19 +0200 Subject: Added abrt-cli manpage and completion script to the spec file. --- abrt.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/abrt.spec b/abrt.spec index 841bfe67..72be3e44 100644 --- a/abrt.spec +++ b/abrt.spec @@ -354,6 +354,8 @@ fi %files cli %defattr(-,root,root,-) %{_bindir}/abrt-cli +%{_mandir}/man1/abrt-cli.1.gz +%{_sysconfdir}/bash_completion.d/abrt-cli.bash %files desktop %defattr(-,root,root,-) -- cgit From 520c3bb42371d2b461a031e5b783a62b66c0ad6f Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Wed, 21 Oct 2009 15:38:26 +0200 Subject: - fixed case when root couldn't properly report others bugs - if root reports other bugs the SetReported() failed because it was looking for dump using UUID and UID which doesn't work for root, so I changed it to use only UUID if abrt-gui is run by root --- lib/Plugins/SQLite3.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/Plugins/SQLite3.cpp b/lib/Plugins/SQLite3.cpp index 797ed2db..a2dc426f 100644 --- a/lib/Plugins/SQLite3.cpp +++ b/lib/Plugins/SQLite3.cpp @@ -321,7 +321,16 @@ void CSQLite3::Delete(const std::string& pUUID, const std::string& pUID) void CSQLite3::SetReported(const std::string& pUUID, const std::string& pUID, const std::string& pMessage) { - if (Exist(pUUID, pUID)) + if(pUID == "0") + { + Exec("UPDATE "ABRT_TABLE" " + "SET "DATABASE_COLUMN_REPORTED" = 1 " + "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + Exec("UPDATE "ABRT_TABLE" " + "SET "DATABASE_COLUMN_MESSAGE" = '" + pMessage + "' " + "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + } + else if (Exist(pUUID, pUID)) { Exec("UPDATE "ABRT_TABLE" " "SET "DATABASE_COLUMN_REPORTED" = 1 " -- cgit From f824969d3a8e77a41dac30997b47a0268cc01cbd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 21 Oct 2009 15:49:01 +0200 Subject: fix warning and whitespace damage Signed-off-by: Denys Vlasenko --- src/CLI/CLI.cpp | 3 +- src/CLI/abrt-cli.1 | 10 +++---- src/CLI/abrt-cli.bash | 2 +- src/CLI/dbus.cpp | 2 +- src/CLI/report.cpp | 78 ++++++++++++++++++++++++------------------------- src/CLI/run-command.cpp | 22 +++++++------- 6 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index a782a59a..18e99dcf 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -65,7 +65,7 @@ static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) int success = strftime(timeloc, 128, "%c", localtime(&time)); if (!success) error_msg_and_die("Error while converting time to string."); - + printf(_("%u.\n" "\tUID : %s\n" "\tUUID : %s\n" @@ -132,7 +132,6 @@ int main(int argc, char** argv) { char* uuid = NULL; int op = -1; - char *name; setlocale(LC_ALL,""); #if ENABLE_NLS diff --git a/src/CLI/abrt-cli.1 b/src/CLI/abrt-cli.1 index 9ccc6159..4fe4bb42 100644 --- a/src/CLI/abrt-cli.1 +++ b/src/CLI/abrt-cli.1 @@ -24,16 +24,16 @@ Prints list of crashes which are not reported yet. .IP "\-\-get-list-full" Prints list of all crashes. .IP "\-\-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. +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" Removes data about particular crash. .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 +The editor used to edit the crash report is chosen from the ABRT_EDITOR +environment variable, the VISUAL environment variable, or the EDITOR environment variable, in that order. .SH "SEE ALSO" .IR abrtd (8), diff --git a/src/CLI/abrt-cli.bash b/src/CLI/abrt-cli.bash index 089d5a3f..10b086ae 100644 --- a/src/CLI/abrt-cli.bash +++ b/src/CLI/abrt-cli.bash @@ -1,7 +1,7 @@ # bash-completion add-on for abrt-cli(1) # http://bash-completion.alioth.debian.org/ -_abrt_cli() +_abrt_cli() { local cur prev opts COMPREPLY=() diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp index 64dac094..420fe703 100644 --- a/src/CLI/dbus.cpp +++ b/src/CLI/dbus.cpp @@ -38,7 +38,7 @@ static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) DBusError err; dbus_error_init(&err); DBusMessage *reply; - reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, + reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, msg, /*timeout*/ -1, &err); if (reply == NULL) { diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 8dedf036..b9a13914 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -33,15 +33,15 @@ /* Field separator for the crash report file that is edited by user. */ #define FIELD_SEP "%----" -/* - * Trims whitespace characters both from left and right side of a string. +/* + * Trims whitespace characters both from left and right side of a string. * Modifies the string in-place. Returns the trimmed string. */ char *trim(char *str) { if (!str) return NULL; - + // Remove leading spaces. char *ibuf; for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf) @@ -60,9 +60,9 @@ char *trim(char *str) return str; } -/* - * Escapes the field content string to avoid confusion with file comments. - * Returned field must be free()d by caller. +/* + * Escapes the field content string to avoid confusion with file comments. + * Returned field must be free()d by caller. */ static char *escape(const char *str) { @@ -87,12 +87,12 @@ static char *escape(const char *str) ++ptr; } - // Copy the input string to the resultant string, and escape all + // Copy the input string to the resultant string, and escape all // occurences of \# and #. char *result = (char*)malloc(strlen(str) + 1 + count); if (!result) error_msg_and_die("Memory error while escaping a field."); - + const char *src = str; char *dest = result; newline = true; @@ -109,15 +109,15 @@ static char *escape(const char *str) newline = (*src == '\n'); *dest++ = *src++; } - *dest = '\0'; + *dest = '\0'; return result; } /* - * Removes all comment lines, and unescapes the string previously escaped - * by escape(). Works in-place. + * Removes all comment lines, and unescapes the string previously escaped + * by escape(). Works in-place. */ -static char *remove_comments_and_unescape(char *str) +static void remove_comments_and_unescape(char *str) { char *src = str, *dest = str; bool newline = true; @@ -125,7 +125,7 @@ static char *remove_comments_and_unescape(char *str) { if (newline) { - if (*src == '#') + if (*src == '#') { // Skip the comment line! while (*src && *src != '\n') ++src; @@ -136,25 +136,25 @@ static char *remove_comments_and_unescape(char *str) ++src; continue; } - else if (*src == '\\' && - (*(src + 1) == '#' || + else if (*src == '\\' && + (*(src + 1) == '#' || (*(src + 1) == '\\' && *(src + 2) == '#'))) { ++src; // Unescape escaped char. } } - + newline = (*src == '\n'); *dest++ = *src++; } *dest = '\0'; } -/* +/* * Writes a field of crash report to a file. * Field must be writable. */ -static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, +static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, const char *field, const char *description) { const map_crash_report_t::const_iterator it = report.find(field); @@ -168,9 +168,9 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, if (it->second[CD_TYPE] == CD_SYS) { error_msg("Cannot write field %s because it is a system value\n", field); - return; + return; } - + fprintf(fp, "%s%s\n", FIELD_SEP, it->first.c_str()); fprintf(fp, "%s\n", description); @@ -182,8 +182,8 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, free(escaped_content); } -/* - * Saves the crash report to a file. +/* + * Saves the crash report to a file. * Parameter 'fp' must be opened before write_crash_report is called. * Returned value: * If the report is successfully stored to the file, a zero value is returned. @@ -194,7 +194,7 @@ static int write_crash_report(const map_crash_report_t &report, FILE *fp) fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); - write_crash_report_field(fp, report, CD_COMMENT, + write_crash_report_field(fp, report, CD_COMMENT, _("# Describe the circumstances of this crash below.")); write_crash_report_field(fp, report, CD_REPRODUCE, _("# How to reproduce the crash?")); @@ -210,19 +210,19 @@ static int write_crash_report(const map_crash_report_t &report, FILE *fp) write_crash_report_field(fp, report, FILENAME_PACKAGE, _("# Package")); write_crash_report_field(fp, report, FILENAME_REASON, _("# Reason of crash")); write_crash_report_field(fp, report, FILENAME_RELEASE, _("# Release string of the operating system")); - + return 0; } -/* +/* * Updates appropriate field in the report from the text. The text can - * contain multiple fields. + * contain multiple fields. * Returns: * 0 if no change to the field was detected. * 1 if the field was changed. * Changes to read-only fields are ignored. */ -static int read_crash_report_field(const char *text, map_crash_report_t &report, +static int read_crash_report_field(const char *text, map_crash_report_t &report, const char *field) { char separator[strlen("\n" FIELD_SEP) + strlen(field) + 2]; // 2 = '\n\0' @@ -236,9 +236,9 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, const char *end = strstr(textfield, "\n" FIELD_SEP); if (!end) length = strlen(textfield); - else + else length = end - textfield; - + const map_crash_report_t::iterator it = report.find(field); if (it == report.end()) { @@ -249,7 +249,7 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, if (it->second[CD_TYPE] == CD_SYS) { error_msg("Cannot update field %s because it is a system value.\n", field); - return 0; + return 0; } // Do not change noneditable fields. @@ -275,12 +275,12 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, return 1; } -/* - * Updates the crash report 'report' from the text. The text must not contain - * any comments. +/* + * Updates the crash report 'report' from the text. The text must not contain + * any comments. * Returns: * 0 if no field was changed. - * 1 if any field was changed. + * 1 if any field was changed. * Changes to read-only fields are ignored. */ static int read_crash_report(map_crash_report_t &report, const char *text) @@ -306,20 +306,20 @@ static int read_crash_report(map_crash_report_t &report, const char *text) int launch_editor(const char *path) { const char *editor, *terminal; - + editor = getenv("ABRT_EDITOR"); if (!editor) editor = getenv("VISUAL"); if (!editor) editor = getenv("EDITOR"); - + terminal = getenv("TERM"); if (!editor && (!terminal || !strcmp(terminal, "dumb"))) { error_msg(_("Terminal is dumb but no VISUAL nor EDITOR defined.")); return 1; } - + if (!editor) editor = "vi"; @@ -367,7 +367,7 @@ int report(const char *uuid, bool always) error_msg("could not close '%s'", filename); return 2; } - + // Start a text editor on the temporary file. launch_editor(filename); @@ -394,7 +394,7 @@ int report(const char *uuid, bool always) remove_comments_and_unescape(text); // Updates the crash report from the file text. - int report_changed = read_crash_report(cr, text); + int report_changed = read_crash_report(cr, text); if (report_changed) puts(_("\nThe report has been updated.")); else diff --git a/src/CLI/run-command.cpp b/src/CLI/run-command.cpp index df29b0e1..80184cfa 100644 --- a/src/CLI/run-command.cpp +++ b/src/CLI/run-command.cpp @@ -23,7 +23,7 @@ http://git.kernel.org/?p=git/git.git;a=blob;f=run-command.c;hb=HEAD */ -struct child_process +struct child_process { const char **argv; pid_t pid; @@ -51,28 +51,28 @@ static int finish_command(struct child_process *cmd) int status, code = -1; while ((waiting = waitpid(cmd->pid, &status, 0)) < 0 && errno == EINTR) ; /* nothing */ - - if (waiting < 0) + + if (waiting < 0) error_msg_and_die("waitpid for %s failed: %s", cmd->argv[0], strerror(errno)); - else if (waiting != cmd->pid) + else if (waiting != cmd->pid) error_msg_and_die("waitpid is confused (%s)", cmd->argv[0]); - else if (WIFSIGNALED(status)) + else if (WIFSIGNALED(status)) { code = WTERMSIG(status); error_msg("%s died of signal %d", cmd->argv[0], code); - } - else if (WIFEXITED(status)) + } + else if (WIFEXITED(status)) { code = WEXITSTATUS(status); - if (code == 127) + if (code == 127) { code = -1; error_msg_and_die("cannot run %s: %s", cmd->argv[0], strerror(ENOENT)); } - } - else + } + else error_msg_and_die("waitpid is confused (%s)", cmd->argv[0]); - + return code; } -- cgit