summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikola Pajkovsky <npajkovs@redhat.com>2010-02-15 18:09:55 +0100
committerNikola Pajkovsky <npajkovs@redhat.com>2010-02-15 18:09:55 +0100
commitd93fc21129f08a149d7a1bb042179942485fcedb (patch)
tree72ec4eb636b15d8e2385f068881f86a6aa88db2b
parentdeef343e0372b0a167f1d35f9ef9d18694aa9a0e (diff)
parent3a0729e697b24d4d30e3a1a008f83ca605aaad5d (diff)
downloadabrt-d93fc21129f08a149d7a1bb042179942485fcedb.tar.gz
abrt-d93fc21129f08a149d7a1bb042179942485fcedb.tar.xz
abrt-d93fc21129f08a149d7a1bb042179942485fcedb.zip
Merge branch 'master' into bugzilla
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am11
-rw-r--r--abrt.init10
-rw-r--r--abrt.spec36
-rw-r--r--configure.ac2
-rw-r--r--doc/HOW_TO_TEST15
-rw-r--r--inc/CrashTypes.h3
-rw-r--r--inc/abrtlib.h4
-rw-r--r--lib/Plugins/Bugzilla.conf2
-rw-r--r--lib/Plugins/Makefile.am30
-rw-r--r--lib/Plugins/Python.cpp23
-rw-r--r--lib/Plugins/Python_hash.cpp17
-rw-r--r--lib/Utils/Plugin.cpp69
-rw-r--r--lib/Utils/Plugin.h18
-rw-r--r--lib/Utils/make_descr.cpp1
-rw-r--r--lib/Utils/xfuncs.cpp2
-rw-r--r--po/es.po100
-rw-r--r--po/id.po633
-rwxr-xr-xscripts/abrt-bz-ratingfixer91
-rwxr-xr-xsrc/Backtrace/abrt-bz-dupchecker127
-rw-r--r--src/CLI/report.cpp309
-rw-r--r--src/Daemon/PluginManager.cpp54
-rw-r--r--src/Daemon/PluginManager.h9
-rw-r--r--src/Daemon/Settings.cpp12
-rwxr-xr-xsrc/Daemon/abrt-debuginfo-install83
-rw-r--r--src/Gui/CCMainWindow.py43
-rw-r--r--src/Gui/CCReporterDialog.py10
-rw-r--r--src/Gui/CC_gui_functions.py3
-rw-r--r--src/Gui/PluginsSettingsDialog.py16
-rw-r--r--src/Gui/ccgui.glade4
-rw-r--r--src/Gui/report.glade4
-rw-r--r--src/Hooks/abrt-hook-ccpp.cpp60
-rw-r--r--src/Hooks/abrt-hook-python.cpp15
-rw-r--r--src/Hooks/abrt_exception_handler.py.in14
34 files changed, 1412 insertions, 423 deletions
diff --git a/.gitignore b/.gitignore
index 63932d69..fa420738 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,10 @@ cscope.out
*.o
*.lo
*.la
+abrt-*.rpm
+abrt-?.?.?.tar.gz
+abrt-?.?.?/
+i686/
po/*.gmo
.deps
.libs
@@ -40,6 +44,7 @@ po/remove-potcdate.sed
po/remove-potcdate.sin
po/stamp-po
py-compile
+scripts/*.bt
src/Applet/abrt-applet
src/CLI/abrt-cli
src/Backtrace/abrt-backtrace
diff --git a/Makefile.am b/Makefile.am
index a934526c..ef369e63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,3 +9,14 @@ rpm: dist
--define "_builddir `pwd`" \
--define "_srcrpmdir `pwd`" \
-ba abrt.spec
+
+srpm: dist
+ rpmbuild --define "_sourcedir `pwd`" \
+ --define "_rpmdir `pwd`" \
+ --define "_specdir `pwd`" \
+ --define "_builddir `pwd`" \
+ --define "_srcrpmdir `pwd`" \
+ -bs abrt.spec
+
+scratch-build: srpm
+ koji build --scratch dist-f12 $(PACKAGE)-$(VERSION)-1.fc12.src.rpm
diff --git a/abrt.init b/abrt.init
index 62567677..c286c644 100644
--- a/abrt.init
+++ b/abrt.init
@@ -11,7 +11,7 @@
# Default-Stop: 0 1 2 6
# Default-Start: 3 5
# Short-Description: start and stop abrt daemon
-# Description: Listen and dispatch crash events
+# Description: Listen to and dispatch crash events
### END INIT INFO
# Source function library.
@@ -21,12 +21,18 @@ LOCK="/var/lock/subsys/abrtd"
RETVAL=0
#
+# Set these variables if you are behind proxy
+#
+#export http_proxy=
+#export https_proxy=
+
+#
# See how we were called.
#
check() {
# Check that we're a privileged user
- [ `id -u` = 0 ] || exit 4
+ [ "`id -u`" = 0 ] || exit 4
# Check if abrt is executable
test -x $ABRT_BIN || exit 5
diff --git a/abrt.spec b/abrt.spec
index 5e9f636b..bd4ac2e2 100644
--- a/abrt.spec
+++ b/abrt.spec
@@ -3,7 +3,7 @@
%{!?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: 1.0.7
+Version: 1.0.8
Release: 1%{?dist}
License: GPLv2+
Group: Applications/System
@@ -334,9 +334,9 @@ fi
%{_libdir}/%{name}/libKerneloops.so*
%{_libdir}/%{name}/libKerneloopsScanner.so*
%{_mandir}/man7/%{name}-KerneloopsScanner.7.gz
-#%{_libdir}/%{name}/libKerneloopsReporter.so*
-#%{_libdir}/%{name}/KerneloopsReporter.GTKBuilder
-#%{_mandir}/man7/%{name}-KerneloopsReporter.7.gz
+%{_libdir}/%{name}/libKerneloopsReporter.so*
+%{_libdir}/%{name}/KerneloopsReporter.GTKBuilder
+%{_mandir}/man7/%{name}-KerneloopsReporter.7.gz
%files plugin-logger
%defattr(-,root,root,-)
@@ -408,6 +408,34 @@ fi
%defattr(-,root,root,-)
%changelog
+* Fri Feb 12 2010 Jiri Moskovcak <jmoskovc@redhat.com> 1.0.7-1
+- enabled column sorting rhbz#541853
+- Load plugin settings also from ~/.abrt/*.conf (kklic@redhat.com)
+- fix bz#541088 "abrt should not catch python excp EPIPE" (vda.linux@googlemail.com)
+- fix bz#554242 "Cannot tab between input areas in report dialog" (vda.linux@googlemail.com)
+- fix bz#563484 "abrt uses unnecessary disk space when getting debug info" (vda.linux@googlemail.com)
+- Don't show empty 'Not loaded plugins' section - fix#2 rhbz#560971 (jmoskovc@redhat.com)
+- fix big-endian build problem (vda.linux@googlemail.com)
+- Fixes, displays package owners (kklic@redhat.com)
+- GUI: fixed exception in plugin settings dialog rhbz#560851 (jmoskovc@redhat.com)
+- GUI: respect system settings for toolbars rhbz#552161 (jmoskovc@redhat.com)
+- python hook: move UUID generation to abrtd; generate REASON, add it to bz title (vda.linux@googlemail.com)
+- make "reason" field less verbose; bz reporter: include it in "summary" (vda.linux@googlemail.com)
+- added avant-window-navigator to blacklist per maintainer request (jmoskovc@redhat.com)
+- CCpp analyzer: fix rhbz#552435 (bt rating misinterpreting # chars) (vda.linux@googlemail.com)
+- Ask for login and password if missing from reporter plugin. (kklic@redhat.com)
+- abrtd: fix handling of dupes (weren't deleting dup's directory); better logging (vda.linux@googlemail.com)
+- abrtd: handle "perl -w /usr/bin/script" too (vda.linux@googlemail.com)
+- Component-wise duplicates (kklic@redhat.com)
+- abrtd: fix rhbz#560642 - don't die on bad plugin names (vda.linux@googlemail.com)
+- Fixed parsing backtrace from rhbz#549293 (kklic@redhat.com)
+- GUI: fixed scrolling in reporter dialog rhbz#559687 (jmoskovc@redhat.com)
+- fixed button order in plugins windows rhbz#560961 (jmoskovc@redhat.com)
+- GUI: fixed windows icons and titles rhbz#537240, rhbz#560964 (jmoskovc@redhat.com)
+- Fix to successfully parse a backtrace from rhbz#550642 (kklic@redhat.com)
+- cli: fix the problem of not showing oops text in editor (vda.linux@googlemail.com)
+- GUI: fix rhbz#560971 "Don't show empty 'Not loaded plugins' section" (vda.linux@googlemail.com)
+
* Tue Feb 2 2010 Jiri Moskovcak <jmoskovc@redhat.com> 1.0.6-1
- print __glib_assert_msg (rhbz#549735);
- SPEC: added some requires to abrt-cli to make it work out-of-the-box (jmoskovc@redhat.com)
diff --git a/configure.ac b/configure.ac
index 425c5ac5..a635ddc8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([abrt], [1.0.7], [crash-catcher@fedorahosted.org])
+AC_INIT([abrt], [1.0.8], [crash-catcher@fedorahosted.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
diff --git a/doc/HOW_TO_TEST b/doc/HOW_TO_TEST
index d11c6d89..05641b1d 100644
--- a/doc/HOW_TO_TEST
+++ b/doc/HOW_TO_TEST
@@ -4,7 +4,9 @@ I. Build and install
===================
a) build the packages as scratch in koji
b) download and install (the best is to create a local repo and try to install it using yum)
-c) start the daemon and check logs for any sign of a problem
+c) create a repository and try to update from previous packages
+d) start the daemon and check logs for any sign of a problem
+e) try to update from previous Fedora version using created repository
II. Crash detection
=====================
@@ -16,7 +18,9 @@ II. Crash detection
== 2. Advanced crash detection ==
a) crash some app that comes from unsigned package - abrt should ignore it
- b) disable the gpg chcek and try repeat step a) - abrt shouldn't ignore it
+ b) disable the gpg check and try repeat step a) - abrt shouldn't ignore it
+
+- try to add some crash-time action and test if it works
III. Reporting
=============
@@ -29,4 +33,9 @@ III. Reporting
- crash should be reported after filling the right credentials
- login+pass won't be saved
c) try to report every supported crash abrt detects C/C++, oops, python script
- d) repeat this with cli
+ d) try to report some crash with bad backtrace - this should fail
+ e) repeat this with cli
+
+- test reporting with all reporters plugins like: ticketuploader, filetransport, etc..
+ repeating the step 'a' to 'e'
+
diff --git a/inc/CrashTypes.h b/inc/CrashTypes.h
index b14413d5..af106cff 100644
--- a/inc/CrashTypes.h
+++ b/inc/CrashTypes.h
@@ -26,9 +26,6 @@
#define FILENAME_KERNEL "kernel"
#define FILENAME_TIME "time"
#define FILENAME_UID "uid"
-// uuid _file_ exists for Python analyzer only - remove, follow ccpp's example?
-// (ccpp keeps uuid in DB)
-#define FILENAME_UUID "uuid"
#define FILENAME_PACKAGE "package"
#define FILENAME_COMPONENT "component"
#define FILENAME_DESCRIPTION "description"
diff --git a/inc/abrtlib.h b/inc/abrtlib.h
index 97aa28b8..7b00fe35 100644
--- a/inc/abrtlib.h
+++ b/inc/abrtlib.h
@@ -52,6 +52,7 @@ int vdprintf(int d, const char *format, va_list ap);
#define NORETURN __attribute__ ((noreturn))
+#undef ARRAY_SIZE
#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
@@ -76,6 +77,7 @@ void log_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
/* error_msg family will use g_custom_logger. log_msg does not. */
void error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
void error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
+/* Reports error message with libc's errno error description attached. */
void perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
void perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
void perror_nomsg_and_die(void) NORETURN;
@@ -254,7 +256,7 @@ bool string_to_bool(const char *s);
/* C++ style stuff */
std::string ssprintf(const char *format, ...);
-std::string get_home_dir(int uid);
+std::string get_home_dir(uid_t uid);
std::string concat_path_file(const char *path, const char *filename);
double get_dirsize(const char *pPath);
double get_dirsize_find_largest_dir(
diff --git a/lib/Plugins/Bugzilla.conf b/lib/Plugins/Bugzilla.conf
index 14fc92c1..ff2f8286 100644
--- a/lib/Plugins/Bugzilla.conf
+++ b/lib/Plugins/Bugzilla.conf
@@ -1,4 +1,4 @@
-Enabled = 1
+Enabled = yes
# Bugzilla URL
BugzillaURL = https://bugzilla.redhat.com/
# yes means that ssl certificates will not be checked
diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am
index 4fc0efe5..fe3969f1 100644
--- a/lib/Plugins/Makefile.am
+++ b/lib/Plugins/Makefile.am
@@ -7,6 +7,7 @@ pluginslib_LTLIBRARIES = \
libLogger.la \
libKerneloopsScanner.la\
libKerneloops.la \
+ libKerneloopsReporter.la \
libRunApp.la \
libSOSreport.la \
libBugzilla.la \
@@ -18,8 +19,11 @@ pluginslib_LTLIBRARIES = \
dist_pluginslib_DATA = \
Logger.GTKBuilder \
- Mailx.GTKBuilder Bugzilla.GTKBuilder \
- TicketUploader.GTKBuilder Catcut.GTKBuilder
+ Mailx.GTKBuilder \
+ Bugzilla.GTKBuilder \
+ TicketUploader.GTKBuilder \
+ Catcut.GTKBuilder \
+ KerneloopsReporter.GTKBuilder
pluginsconfdir = $(PLUGINS_CONF_DIR)
dist_pluginsconf_DATA = \
@@ -35,9 +39,17 @@ dist_pluginsconf_DATA = \
Python.conf \
SOSreport.conf
-man_MANS = abrt-FileTransfer.7 abrt-Bugzilla.7 \
- abrt-KerneloopsScanner.7 abrt-Logger.7 abrt-Mailx.7 abrt-plugins.7 \
- abrt-SQLite3.7 abrt-RunApp.7 abrt-TicketUploader.7
+man_MANS = \
+ abrt-FileTransfer.7 \
+ abrt-Bugzilla.7 \
+ abrt-KerneloopsScanner.7 \
+ abrt-KerneloopsReporter.7 \
+ abrt-Logger.7 abrt-Mailx.7 \
+ abrt-plugins.7 \
+ abrt-SQLite3.7 \
+ abrt-RunApp.7 \
+ abrt-TicketUploader.7
+
# + abrt-Catcut.7
EXTRA_DIST = $(man_MANS)
@@ -78,10 +90,10 @@ libKerneloops_la_LDFLAGS = -avoid-version
libKerneloops_la_CPPFLAGS = -I$(srcdir)/../../inc -I$(srcdir)/../Utils
# KerneloopsReporter
-#libKerneloopsReporter_la_SOURCES = KerneloopsReporter.cpp KerneloopsReporter.h
-#libKerneloopsReporter_la_LDFLAGS = -avoid-version
-#libKerneloopsReporter_la_LIBADD = $(CURL_LIBS)
-#libKerneloopsReporter_la_CPPFLAGS = -I$(srcdir)/../../inc -I$(srcdir)/../Utils $(CURL_CFLAGS) -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\"
+libKerneloopsReporter_la_SOURCES = KerneloopsReporter.cpp KerneloopsReporter.h
+libKerneloopsReporter_la_LDFLAGS = -avoid-version
+libKerneloopsReporter_la_LIBADD = $(CURL_LIBS)
+libKerneloopsReporter_la_CPPFLAGS = -I$(srcdir)/../../inc -I$(srcdir)/../Utils $(CURL_CFLAGS) -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\"
# KerneloopsScanner
libKerneloopsScanner_la_SOURCES = KerneloopsScanner.cpp KerneloopsScanner.h KerneloopsSysLog.cpp KerneloopsSysLog.h
diff --git a/lib/Plugins/Python.cpp b/lib/Plugins/Python.cpp
index d6a3084d..12cc47ef 100644
--- a/lib/Plugins/Python.cpp
+++ b/lib/Plugins/Python.cpp
@@ -38,7 +38,27 @@ string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir)
unsigned char hash2[MD5_RESULT_LEN];
md5_ctx_t md5ctx;
md5_begin(&md5ctx);
- md5_hash(bt_str, bt_end - bt_str, &md5ctx);
+ // Better:
+ // "example.py:1:<module>:ZeroDivisionError: integer division or modulo by zero"
+ //md5_hash(bt_str, bt_end - bt_str, &md5ctx);
+ // For now using compat version:
+ {
+ char *copy = xstrndup(bt_str, bt_end - bt_str);
+ char *s = copy;
+ char *d = copy;
+ unsigned colon_cnt = 0;
+ while (*s && colon_cnt < 3) {
+ if (*s != ':')
+ *d++ = *s;
+ else
+ colon_cnt++;
+ s++;
+ }
+ // "example.py1<module>"
+ md5_hash(copy, d - copy, &md5ctx);
+//*d = '\0'; log("str:'%s'", copy);
+ free(copy);
+ }
md5_end(hash2, &md5ctx);
// Hash is MD5_RESULT_LEN bytes long, but we use only first 4
@@ -56,7 +76,6 @@ string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir)
//log("hash2:%s str:'%.*s'", hash_str, (int)(bt_end - bt_str), bt_str);
return hash_str;
-
}
string CAnalyzerPython::GetGlobalUUID(const char *pDebugDumpDir)
{
diff --git a/lib/Plugins/Python_hash.cpp b/lib/Plugins/Python_hash.cpp
index ae246b38..36ddacdc 100644
--- a/lib/Plugins/Python_hash.cpp
+++ b/lib/Plugins/Python_hash.cpp
@@ -14,6 +14,7 @@
*/
#include "abrtlib.h"
#include "Python_hash.h"
+#include <byteswap.h>
#if defined(__BIG_ENDIAN__) && __BIG_ENDIAN__
# define MD5_BIG_ENDIAN 1
@@ -28,6 +29,16 @@
# error "Can't determine endianness"
#endif
+/* SWAP_LEnn means "convert CPU<->little_endian if needed (by swapping bytes)" */
+#if MD5_BIG_ENDIAN
+# define SWAP_BE32(x) (x)
+# define SWAP_LE32(x) bswap_32(x)
+#else
+# define SWAP_BE32(x) bswap_32(x)
+# define SWAP_LE32(x) (x)
+#endif
+
+
/* 0: fastest, 3: smallest */
#define MD5_SIZE_VS_SPEED 3
@@ -123,11 +134,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
uint32_t temp;
for (i = 0; i < 16; i++) {
-#if MD5_BIG_ENDIAN
- cwp[i] = bswap_32(words[i]);
-#else
- cwp[i] = words[i];
-#endif
+ cwp[i] = SWAP_LE32(words[i]);
}
words += 16;
diff --git a/lib/Utils/Plugin.cpp b/lib/Utils/Plugin.cpp
index 2865027f..40cd2a02 100644
--- a/lib/Utils/Plugin.cpp
+++ b/lib/Utils/Plugin.cpp
@@ -17,6 +17,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Plugin.h"
+#include "abrtlib.h"
CPlugin::CPlugin() {}
@@ -33,3 +34,71 @@ const map_plugin_settings_t& CPlugin::GetSettings()
{
return m_pSettings;
}
+
+bool LoadPluginSettings(const char *pPath, map_plugin_settings_t& pSettings,
+ bool skipKeysWithoutValue /*= true*/)
+{
+ FILE *fp = fopen(pPath, "r");
+ if (!fp)
+ return false;
+
+ char line[512];
+ while (fgets(line, sizeof(line), fp))
+ {
+ strchrnul(line, '\n')[0] = '\0';
+ unsigned ii;
+ bool is_value = false;
+ bool valid = false;
+ bool in_quote = false;
+ std::string key;
+ std::string value;
+ for (ii = 0; line[ii] != '\0'; ii++)
+ {
+ if (line[ii] == '"')
+ {
+ in_quote = !in_quote;
+ }
+ if (isspace(line[ii]) && !in_quote)
+ {
+ continue;
+ }
+ if (line[ii] == '#' && !in_quote && key == "")
+ {
+ break;
+ }
+ if (line[ii] == '=' && !in_quote)
+ {
+ is_value = true;
+ valid = true;
+ continue;
+ }
+ if (!is_value)
+ {
+ key += line[ii];
+ }
+ else
+ {
+ value += line[ii];
+ }
+ }
+
+ /* Skip broken or empty lines. */
+ if (!valid)
+ continue;
+
+ /* Skip lines with empty key. */
+ if (key.length() == 0)
+ continue;
+
+ if (skipKeysWithoutValue && value.length() == 0)
+ continue;
+
+ /* Skip lines with unclosed quotes. */
+ if (in_quote)
+ continue;
+
+ pSettings[key] = value;
+ }
+ fclose(fp);
+ return true;
+}
diff --git a/lib/Utils/Plugin.h b/lib/Utils/Plugin.h
index 1eefac6a..3ae3d62d 100644
--- a/lib/Utils/Plugin.h
+++ b/lib/Utils/Plugin.h
@@ -118,10 +118,26 @@ typedef struct SPluginInfo
PLUGINS_MAGIC_NUMBER,\
};
-/* helper finctions */
+/* helper functions */
std::string make_description_bz(const map_crash_data_t& pCrashData);
std::string make_description_reproduce_comment(const map_crash_data_t& pCrashData);
std::string make_description_logger(const map_crash_data_t& pCrashData);
std::string make_description_catcut(const map_crash_data_t& pCrashData);
+/**
+ * Loads settings and stores it in second parameter. On success it
+ * returns true, otherwise returns false.
+ *
+ * @param path A path of config file.
+ * Config file consists of "key=value" lines.
+ * @param settings A readed plugin's settings.
+ * @param skipKeysWithoutValue
+ * If true, lines in format "key=" (without value) are skipped.
+ * Otherwise empty value "" is inserted into pSettings.
+ * @return if it success it returns true, otherwise it returns false.
+ */
+extern bool LoadPluginSettings(const char *pPath,
+ map_plugin_settings_t& pSettings,
+ bool skipKeysWithoutValue = true);
+
#endif
diff --git a/lib/Utils/make_descr.cpp b/lib/Utils/make_descr.cpp
index d04bf955..80198965 100644
--- a/lib/Utils/make_descr.cpp
+++ b/lib/Utils/make_descr.cpp
@@ -71,7 +71,6 @@ static void add_content(bool &was_multiline, string& description, const char *he
static const char *const blacklisted_items_bz[] = {
FILENAME_TIME ,
FILENAME_UID ,
- FILENAME_UUID ,
FILENAME_ANALYZER ,
FILENAME_COREDUMP ,
FILENAME_DESCRIPTION, /* package description - basically useless */
diff --git a/lib/Utils/xfuncs.cpp b/lib/Utils/xfuncs.cpp
index 16f4cb0e..7301d7f0 100644
--- a/lib/Utils/xfuncs.cpp
+++ b/lib/Utils/xfuncs.cpp
@@ -252,7 +252,7 @@ void xstat(const char *name, struct stat *stat_buf)
perror_msg_and_die("can't stat '%s'", name);
}
-std::string get_home_dir(int uid)
+std::string get_home_dir(uid_t uid)
{
struct passwd* pw = getpwuid(uid);
return pw ? pw->pw_dir : "";
diff --git a/po/es.po b/po/es.po
index 07092ea2..7f02f3fd 100644
--- a/po/es.po
+++ b/po/es.po
@@ -9,9 +9,9 @@ msgid ""
msgstr ""
"Project-Id-Version: abrt.master.es\n"
"Report-Msgid-Bugs-To: jmoskovc@redhat.com\n"
-"POT-Creation-Date: 2010-02-04 10:01+0000\n"
-"PO-Revision-Date: 2010-02-04 10:19-0300\n"
-"Last-Translator: Claudio Rodrigo Pereyra Diaz <claudio@pereyradiaz.com.ar>\n"
+"POT-Creation-Date: 2010-02-09 10:00+0000\n"
+"PO-Revision-Date: 2010-02-09 09:23-0400\n"
+"Last-Translator: Dennis Tobar <dennis.tobar@gmail.com>\n"
"Language-Team: Fedora Spanish <fedora-trans-es@redhat.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -26,7 +26,7 @@ msgstr "Otro cliente ya está siendo ejecutado, intentando despertarlo."
#: ../src/Gui/ABRTExceptions.py:13
msgid "Got unexpected data from daemon (is the database properly updated?)."
-msgstr "Se obtienen datos inesperados desde el demonio (¿está la Base de Datos correctamente actualizada?)"
+msgstr "Se obtienen datos inesperados desde el demonio (¿está la base de datos correctamente actualizada?)"
#: ../src/Gui/ABRTPlugin.py:62
msgid "Not loaded plugins"
@@ -46,7 +46,7 @@ msgstr "Complementos de informes"
#: ../src/Gui/ABRTPlugin.py:66
msgid "Database plugins"
-msgstr "Complementos de Bases de Datos"
+msgstr "Complementos de bases de datos"
#: ../src/Gui/CCDBusBackend.py:74
#: ../src/Gui/CCDBusBackend.py:97
@@ -185,7 +185,7 @@ msgid ""
"Error while loading the dumplist.\n"
"%s"
msgstr ""
-"Error intentando cargar la lista de volcado.\n"
+"Error intentando cargar la lista de volcado.\n"
"%s"
#: ../src/Gui/CCMainWindow.py:230
@@ -205,7 +205,7 @@ msgid ""
"Unable to get report!\n"
"Debuginfo is missing?"
msgstr ""
-"Incapaz de conseguir el informe!\n"
+"¡Incapaz de conseguir el informe!\n"
"¿Falta la información de la depuración?"
#: ../src/Gui/CCMainWindow.py:318
@@ -277,7 +277,7 @@ msgstr "No se encuentra el control visual de PluginDialog en la descripción de
#: ../src/Gui/PluginSettingsUI.py:24
#, python-format
msgid "No UI for plugin %s"
-msgstr "No hay interfase del usuario para el complemento %s"
+msgstr "No hay interfaz de usuario para el complemento %s"
#: ../src/Gui/PluginSettingsUI.py:55
#: ../src/Gui/PluginSettingsUI.py:81
@@ -318,31 +318,31 @@ msgstr "<span color=\"white\">Arquitectura</span>"
#: ../src/Gui/report.glade.h:8
msgid "<span fgcolor=\"blue\">Cmdline:</span>"
-msgstr "<span color=\"white\">Línea de comandos</span>"
+msgstr "<span color=\"white\">Línea de comandos:</span>"
#: ../src/Gui/report.glade.h:9
msgid "<span fgcolor=\"blue\">Component:</span>"
-msgstr "<span color=\"white\">Componente</span>"
+msgstr "<span color=\"white\">Componente:</span>"
#: ../src/Gui/report.glade.h:10
msgid "<span fgcolor=\"blue\">Executable:</span>"
-msgstr "<span color=\"white\">Ejecutable</span>"
+msgstr "<span color=\"white\">Ejecutable:</span>"
#: ../src/Gui/report.glade.h:11
msgid "<span fgcolor=\"blue\">Kernel:</span>"
-msgstr "<span color=\"white\">Núcleo</span>"
+msgstr "<span color=\"white\">Núcleo:</span>"
#: ../src/Gui/report.glade.h:12
msgid "<span fgcolor=\"blue\">Package:</span>"
-msgstr "<span color=\"white\">Paquete</span>"
+msgstr "<span color=\"white\">Paquete:</span>"
#: ../src/Gui/report.glade.h:13
msgid "<span fgcolor=\"blue\">Reason:</span>"
-msgstr "<span color=\"white\">Razón</span>"
+msgstr "<span color=\"white\">Razón:</span>"
#: ../src/Gui/report.glade.h:14
msgid "<span fgcolor=\"blue\">Release:</span>"
-msgstr "<span color=\"white\">Release</span>"
+msgstr "<span color=\"white\">Release:</span>"
#: ../src/Gui/report.glade.h:16
msgid "I checked backtrace and removed sensitive data (passwords, etc)"
@@ -354,7 +354,7 @@ msgstr "N/A"
#: ../src/Gui/report.glade.h:18
msgid "Send report"
-msgstr "Enviando informe"
+msgstr "Enviar informe"
#: ../src/Gui/report.glade.h:19
msgid "Show log"
@@ -427,7 +427,7 @@ msgstr "Cron"
#: ../src/Gui/settings.glade.h:13
msgid "Database backend: "
-msgstr "Backend de la Base de Datos"
+msgstr "Backend de la base de datos"
#: ../src/Gui/settings.glade.h:14
msgid "Description:"
@@ -465,70 +465,70 @@ msgstr "Página Web:"
msgid "View and report application crashes"
msgstr "Ver y reportar las caídas de las aplicaciones"
-#: ../src/Applet/Applet.cpp:78
+#: ../src/Applet/Applet.cpp:77
#, c-format
msgid "A crash in package %s has been detected"
msgstr "Ha sido detectado una caída en el paquete %s."
-#: ../src/Applet/Applet.cpp:253
+#: ../src/Applet/Applet.cpp:252
msgid "ABRT service is not running"
msgstr "El servicio ABRT no se está ejecutando"
-#: ../src/Applet/CCApplet.cpp:200
+#: ../src/Applet/CCApplet.cpp:199
msgid "Warning"
msgstr "Aviso"
-#: ../src/Daemon/Daemon.cpp:474
+#: ../src/Daemon/Daemon.cpp:483
msgid "Report size exceeded the quota. Please check system's MaxCrashReportsSize value in abrt.conf."
msgstr "El tamaño del informe excede la cuota. Por favor, verifique el valor de MaxCrashReportsSize del sistema en abrt.conf."
-#: ../lib/Plugins/Bugzilla.cpp:124
+#: ../lib/Plugins/Bugzilla.cpp:142
msgid "Missing member 'reporter'"
msgstr "No se encuentra el miembro 'informante'"
-#: ../lib/Plugins/Bugzilla.cpp:176
+#: ../lib/Plugins/Bugzilla.cpp:194
msgid "Missing member 'cc'"
msgstr "Facltante de miembro 'cc'"
-#: ../lib/Plugins/Bugzilla.cpp:262
+#: ../lib/Plugins/Bugzilla.cpp:280
#, c-format
msgid "Bug is already reported: %i"
msgstr "El error ya ha sido informado: %i"
-#: ../lib/Plugins/Bugzilla.cpp:274
+#: ../lib/Plugins/Bugzilla.cpp:292
msgid "Missing member 'bug_id'"
msgstr "Faltante de miembro 'bug_id'"
-#: ../lib/Plugins/Bugzilla.cpp:283
+#: ../lib/Plugins/Bugzilla.cpp:301
msgid "Missing member 'bugs'"
msgstr "Faltante de miembro 'bugs'"
-#: ../lib/Plugins/Bugzilla.cpp:346
+#: ../lib/Plugins/Bugzilla.cpp:370
#, c-format
msgid "New bug id: %i"
msgstr "Nuevo id del error: %i"
-#: ../lib/Plugins/Bugzilla.cpp:440
+#: ../lib/Plugins/Bugzilla.cpp:464
msgid "Checking for duplicates..."
msgstr "Chequeando si hay duplicados..."
-#: ../lib/Plugins/Bugzilla.cpp:446
+#: ../lib/Plugins/Bugzilla.cpp:470
msgid "Empty login and password. Please check Bugzilla.conf"
-msgstr "Usuario y contraseña vacios. Por favor compruebe el archivo Bugzilla.conf"
+msgstr "Usuario y contraseña vacíos. Por favor compruebe el archivo Bugzilla.conf"
-#: ../lib/Plugins/Bugzilla.cpp:449
+#: ../lib/Plugins/Bugzilla.cpp:473
msgid "Logging into bugzilla..."
msgstr "Ingresando a bugzilla..."
-#: ../lib/Plugins/Bugzilla.cpp:454
+#: ../lib/Plugins/Bugzilla.cpp:478
msgid "Checking CC..."
msgstr "Chequeando CC..."
-#: ../lib/Plugins/Bugzilla.cpp:465
+#: ../lib/Plugins/Bugzilla.cpp:489
msgid "Creating new bug..."
msgstr "Creando un nuevo informe..."
-#: ../lib/Plugins/Bugzilla.cpp:469
+#: ../lib/Plugins/Bugzilla.cpp:493
msgid "Logging out..."
msgstr "Saliendo..."
@@ -536,23 +536,19 @@ msgstr "Saliendo..."
msgid "Getting local universal unique identification"
msgstr "Obteniendo la identificación única universal local"
-#: ../lib/Plugins/CCpp.cpp:253
+#: ../lib/Plugins/CCpp.cpp:266
msgid "Generating backtrace"
msgstr "Generando seguimiento..."
-#: ../lib/Plugins/CCpp.cpp:415
+#: ../lib/Plugins/CCpp.cpp:428
msgid "Starting debuginfo installation"
msgstr "Iniciando la instalación de la información de depuración"
-#: ../lib/Plugins/CCpp.cpp:564
-msgid "Getting local universal unique identification..."
-msgstr "Obteniendo la identificación única universal local..."
-
-#: ../lib/Plugins/CCpp.cpp:613
+#: ../lib/Plugins/CCpp.cpp:624
msgid "Getting global universal unique identification..."
msgstr "Obteniendo la identificación única universal global..."
-#: ../lib/Plugins/CCpp.cpp:791
+#: ../lib/Plugins/CCpp.cpp:802
msgid "Skipping debuginfo installation"
msgstr "Omita la instalación de la información de depuración"
@@ -560,30 +556,30 @@ msgstr "Omita la instalación de la información de depuración"
msgid "Creating and submitting a report..."
msgstr "Creando y enviando un informe..."
-#: ../lib/Plugins/Logger.cpp:76
+#: ../lib/Plugins/Logger.cpp:73
#, c-format
msgid "Writing report to '%s'"
msgstr "Escribiendo reporte en '%s'"
-#: ../lib/Plugins/FileTransfer.cpp:54
+#: ../lib/Plugins/FileTransfer.cpp:53
msgid "FileTransfer: URL not specified"
msgstr "Transferencia de archivo: URL no especificada"
-#: ../lib/Plugins/FileTransfer.cpp:58
+#: ../lib/Plugins/FileTransfer.cpp:57
#, c-format
msgid "Sending archive %s to %s"
msgstr "Enviando archivo %s a %s"
-#: ../lib/Plugins/FileTransfer.cpp:289
+#: ../lib/Plugins/FileTransfer.cpp:288
msgid "File Transfer: Creating a report..."
msgstr "Transferencia de archivo: Creando un informe..."
-#: ../lib/Plugins/FileTransfer.cpp:323
+#: ../lib/Plugins/FileTransfer.cpp:322
#, c-format
msgid "Can't create and send an archive: %s"
msgstr "No se puede crear y enviar un archivo: %s"
-#: ../lib/Plugins/FileTransfer.cpp:352
+#: ../lib/Plugins/FileTransfer.cpp:351
#, c-format
msgid "Can't create and send an archive %s"
msgstr "No se puede crear y enviar un archivo %s"
@@ -592,19 +588,21 @@ msgstr "No se puede crear y enviar un archivo %s"
msgid "Creating kernel oops crash reports..."
msgstr "Creando un informe de caída de kernel oops..."
-#: ../lib/Plugins/Mailx.cpp:137
+#: ../lib/Plugins/Mailx.cpp:134
msgid "Sending an email..."
msgstr "Enviando un correo..."
-#: ../lib/Plugins/SOSreport.cpp:103
+#: ../lib/Plugins/SOSreport.cpp:101
#, c-format
msgid "Running sosreport: %s"
msgstr "Corriendo sosreport: %s"
-#: ../lib/Plugins/SOSreport.cpp:109
+#: ../lib/Plugins/SOSreport.cpp:107
msgid "Done running sosreport"
msgstr "Sosreport ya esta corriendo"
+#~ msgid "Getting local universal unique identification..."
+#~ msgstr "Obteniendo la identificación única universal local..."
#~ msgid "Global Settings"
#~ msgstr "Preferencias globales"
#~ msgid "Settings"
diff --git a/po/id.po b/po/id.po
new file mode 100644
index 00000000..61dfb189
--- /dev/null
+++ b/po/id.po
@@ -0,0 +1,633 @@
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# , 2010.
+# Dichi Al Faridi <dichi@alfaridi.info>, 2010.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: jmoskovc@redhat.com\n"
+"POT-Creation-Date: 2010-02-01 11:41+0000\n"
+"PO-Revision-Date: 2010-02-10 10:36+0700\n"
+"Last-Translator: Dichi Al Faridi <dichi@alfaridi.info>\n"
+"Language-Team: Fedora-id\n"
+"Language: id\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Virtaal 0.5.1\n"
+
+#: ../src/Gui/ABRTExceptions.py:6
+#, fuzzy
+msgid "Another client is already running, trying to wake it."
+msgstr "Client lain sedang berjalan, mencoba untuk membangunkannya."
+
+#: ../src/Gui/ABRTExceptions.py:13
+msgid "Got unexpected data from daemon (is the database properly updated?)."
+msgstr ""
+"Mendapatkan data yang tidak diharapkan dari daemon (apakah database "
+"terperbaharui dengan benar?)."
+
+#: ../src/Gui/ABRTPlugin.py:62
+msgid "Not loaded plugins"
+msgstr "Tidak mengunggah pengaya."
+
+#: ../src/Gui/ABRTPlugin.py:63
+msgid "Analyzer plugins"
+msgstr "Pengaya penganalis"
+
+#: ../src/Gui/ABRTPlugin.py:64
+msgid "Action plugins"
+msgstr "Pengaya aksi"
+
+#: ../src/Gui/ABRTPlugin.py:65
+msgid "Reporter plugins"
+msgstr "Pengaya laporan"
+
+#: ../src/Gui/ABRTPlugin.py:66
+msgid "Database plugins"
+msgstr "Pengaya database"
+
+#: ../src/Gui/CCDBusBackend.py:74 ../src/Gui/CCDBusBackend.py:97
+msgid "Can't connect to system dbus"
+msgstr "Tidak dapat terhubung dengan sistem dbus"
+
+#: ../src/Gui/CCDBusBackend.py:120 ../src/Gui/CCDBusBackend.py:123
+msgid "Please check if abrt daemon is running"
+msgstr "Harap diperiksa jika abrt daemon sudah berjalan"
+
+#: ../src/Gui/CCDBusBackend.py:175
+msgid ""
+"Daemon didn't return valid report info\n"
+"Debuginfo is missing?"
+msgstr ""
+"Daemon tidak mengembalikan info laporan yang sah\n"
+"Debuginfo hilang?"
+
+#: ../src/Gui/ccgui.glade.h:1
+msgid "(C) 2009 Red Hat, Inc."
+msgstr "(C) 2009 Red Hat, Inc."
+
+#: ../src/Gui/ccgui.glade.h:2
+msgid "About ABRT"
+msgstr "Tentang ABRT"
+
+#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/CCMainWindow.py:8
+#: ../src/Gui/report.glade.h:15 ../src/Gui/abrt.desktop.in.h:1
+msgid "Automatic Bug Reporting Tool"
+msgstr "Automatic Bug Reporting Tool"
+
+#: ../src/Gui/ccgui.glade.h:4
+msgid "Delete"
+msgstr "Hapus"
+
+#: ../src/Gui/ccgui.glade.h:5
+msgid "Details"
+msgstr "Rincian"
+
+#: ../src/Gui/ccgui.glade.h:6
+msgid "Not Reported"
+msgstr "Tidak Dilaporkan"
+
+#: ../src/Gui/ccgui.glade.h:7
+msgid "Please wait.."
+msgstr "Harap tunggu.."
+
+#: ../src/Gui/ccgui.glade.h:8
+msgid "Plugins"
+msgstr "Pengaya"
+
+#: ../src/Gui/ccgui.glade.h:9
+msgid "Report"
+msgstr "Laporan"
+
+#: ../src/Gui/ccgui.glade.h:10
+msgid ""
+"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.\n"
+"\n"
+"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.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program. If not, see <http://www.gnu.org/licenses/>."
+msgstr ""
+"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.\n"
+"\n"
+"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.\n"
+"\n"
+"You should have received a copy of the GNU General Public License along with "
+"this program. If not, see <http://www.gnu.org/licenses/>."
+
+#: ../src/Gui/ccgui.glade.h:15
+msgid "_Edit"
+msgstr "_Sunting"
+
+#: ../src/Gui/ccgui.glade.h:16
+msgid "_File"
+msgstr "_Berkas"
+
+#: ../src/Gui/ccgui.glade.h:17
+msgid "_Help"
+msgstr "_Bantuan"
+
+#. add pixbuff separatelly
+#: ../src/Gui/CCMainWindow.py:74
+msgid "Icon"
+msgstr "Ikon"
+
+#: ../src/Gui/CCMainWindow.py:82
+msgid "Package"
+msgstr "Paket"
+
+#: ../src/Gui/CCMainWindow.py:83
+msgid "Application"
+msgstr "Aplikasi"
+
+#: ../src/Gui/CCMainWindow.py:84
+msgid "Date"
+msgstr "Tanggal"
+
+#: ../src/Gui/CCMainWindow.py:85
+msgid "Crash count"
+msgstr "Jumlah crash"
+
+#: ../src/Gui/CCMainWindow.py:86
+msgid "User"
+msgstr "Pengguna"
+
+#: ../src/Gui/CCMainWindow.py:154
+#, python-format
+msgid ""
+"Can't show the settings dialog\n"
+"%s"
+msgstr ""
+"Tidak dapat menampilkan dialog setting\n"
+"%s"
+
+#: ../src/Gui/CCMainWindow.py:165
+#, python-format
+msgid ""
+"Unable to finish current task!\n"
+"%s"
+msgstr ""
+"Tidak dapat mengakhiri tugas saat ini!\n"
+"%s"
+
+#. there is something wrong with the daemon if we cant get the dumplist
+#: ../src/Gui/CCMainWindow.py:192
+#, python-format
+msgid ""
+"Error while loading the dumplist.\n"
+"%s"
+msgstr ""
+"Error ketika memuat dumplist.\n"
+"%s"
+
+#: ../src/Gui/CCMainWindow.py:230
+msgid "This crash has been reported:\n"
+msgstr "Crash ini sudah dilaporkan:\n"
+
+#: ../src/Gui/CCMainWindow.py:231
+msgid "<b>This crash has been reported:</b>\n"
+msgstr "<b>Crash ini telah dilaporkan:</b>\n"
+
+#: ../src/Gui/CCMainWindow.py:250
+msgid "<b>Not reported!</b>"
+msgstr "<b>Tidak dilaporkan!</b>"
+
+#: ../src/Gui/CCMainWindow.py:298
+msgid ""
+"Unable to get report!\n"
+"Debuginfo is missing?"
+msgstr ""
+"Tidak dapat memperoleh laporan!\n"
+"Debuginfo yang hilang?"
+
+#: ../src/Gui/CCMainWindow.py:318
+#, python-format
+msgid ""
+"Reporting failed!\n"
+"%s"
+msgstr ""
+"Pelaporan gagal!\n"
+"%s"
+
+#: ../src/Gui/CCMainWindow.py:337 ../src/Gui/CCMainWindow.py:364
+#, python-format
+msgid "Error getting the report: %s"
+msgstr "Gagal mendapatkan laporan: %s"
+
+#. default texts
+#: ../src/Gui/CCReporterDialog.py:24
+msgid "Brief description how to reproduce this or what you did..."
+msgstr ""
+"Deskripsi singkat bagaimana untuk mereproduksi ini atau apa yang Anda "
+"lakukan..."
+
+#: ../src/Gui/CCReporterDialog.py:99
+msgid "You must check backtrace for sensitive data"
+msgstr "Anda harus memeriksa backtrace untuk data sensitif"
+
+#: ../src/Gui/CCReporterDialog.py:110
+#, python-format
+msgid ""
+"Reporting disabled because the backtrace is unusable.\n"
+"Please try to install debuginfo manually using command: <b>debuginfo-install "
+"%s</b> \n"
+"then use Refresh button to regenerate the backtrace."
+msgstr ""
+"Pelaporan dinonaktifkan karena backtrace tidak dapat digunakan. \n"
+"Silakan mencoba menginstal debuginfo secara manual menggunakan perintah: <b"
+">debuginfo-install% s</b> kemudian gunakan tombol Refresh untuk membuat "
+"backtrace."
+
+#: ../src/Gui/CCReporterDialog.py:112
+msgid "The backtrace is unusable, you can't report this!"
+msgstr ""
+"The backtrace ini tidak dapat digunakan, Anda tidak dapat melaporkan ini!"
+
+#: ../src/Gui/CCReporterDialog.py:116
+msgid ""
+"The backtrace is incomplete, please make sure you provide good steps to "
+"reproduce."
+msgstr ""
+"Backtrace tidak lengkap, pastikan Anda memberikan langkah-langkah yang baik "
+"untuk mereproduksi."
+
+#: ../src/Gui/CCReporterDialog.py:158
+#, python-format
+msgid ""
+"Can't save plugin settings:\n"
+" %s"
+msgstr ""
+"Tidak dapat menyimpan pengaturan plugin:\n"
+"%s"
+
+#: ../src/Gui/dialogs.glade.h:1
+msgid "Log"
+msgstr "Catatan"
+
+#: ../src/Gui/dialogs.glade.h:2
+msgid "Report done"
+msgstr "Laporan selesai"
+
+#: ../src/Gui/PluginSettingsUI.py:18
+msgid "Can't find PluginDialog widget in UI description!"
+msgstr "Tidak dapat menemukan widget PluginDialog di deskripsi UI!"
+
+#. we shouldn't get here, but just to be safe
+#: ../src/Gui/PluginSettingsUI.py:24
+#, python-format
+msgid "No UI for plugin %s"
+msgstr "Tidak UI untuk plugin %s"
+
+#: ../src/Gui/PluginSettingsUI.py:55 ../src/Gui/PluginSettingsUI.py:81
+msgid "combo box is not implemented"
+msgstr "combo bos tidak diimplementasikan"
+
+#: ../src/Gui/PluginSettingsUI.py:64
+msgid "Nothing to hydrate!"
+msgstr "Tidak ada yang hidrat!"
+
+#: ../src/Gui/report.glade.h:1
+msgid " "
+msgstr ""
+
+#: ../src/Gui/report.glade.h:2
+msgid "<b>Attachments</b>"
+msgstr ""
+
+#: ../src/Gui/report.glade.h:3
+msgid "<b>Backtrace</b>"
+msgstr "<b>Backtrace</b>"
+
+#: ../src/Gui/report.glade.h:4
+msgid "<b>Comment</b>"
+msgstr "<b>Komentar</b>"
+
+#: ../src/Gui/report.glade.h:5
+msgid "<b>How to reproduce (in a few simple steps)</b>"
+msgstr "<b>Bagaimana untuk mereproduksi (dalam beberapa langkah sederhana)</b>"
+
+#: ../src/Gui/report.glade.h:6
+msgid "<b>Please fix the following problems</b>"
+msgstr "<b>Mohon selesai masalah berikut</b>"
+
+#: ../src/Gui/report.glade.h:7
+msgid "<span fgcolor=\"blue\">Architecture:</span>"
+msgstr "<span fgcolor=\"blue\">Arsitektur</span>"
+
+#: ../src/Gui/report.glade.h:8
+msgid "<span fgcolor=\"blue\">Cmdline:</span>"
+msgstr "<span fgcolor=\"blue\">Cmdline:</span>"
+
+#: ../src/Gui/report.glade.h:9
+msgid "<span fgcolor=\"blue\">Component:</span>"
+msgstr "<span fgcolor=\"blue\">Komponen:</span>"
+
+#: ../src/Gui/report.glade.h:10
+msgid "<span fgcolor=\"blue\">Executable:</span>"
+msgstr "<span fgcolor=\"blue\">Executable:</span>"
+
+#: ../src/Gui/report.glade.h:11
+msgid "<span fgcolor=\"blue\">Kernel:</span>"
+msgstr "<span fgcolor=\"blue\">Kernel:</span>"
+
+#: ../src/Gui/report.glade.h:12
+msgid "<span fgcolor=\"blue\">Package:</span>"
+msgstr "<span fgcolor=\"blue\">Paket:</span>"
+
+#: ../src/Gui/report.glade.h:13
+msgid "<span fgcolor=\"blue\">Reason:</span>"
+msgstr "<span fgcolor=\"blue\">Alasan:</span>"
+
+#: ../src/Gui/report.glade.h:14
+msgid "<span fgcolor=\"blue\">Release:</span>"
+msgstr "<span fgcolor=\"blue\">Rilis:</span>"
+
+#: ../src/Gui/report.glade.h:16
+msgid "I checked backtrace and removed sensitive data (passwords, etc)"
+msgstr "Aku memeriksa backtrace dan mengeluarkan data sensitif (password, dll)"
+
+#: ../src/Gui/report.glade.h:17
+msgid "N/A"
+msgstr "T/A"
+
+#: ../src/Gui/report.glade.h:18
+msgid "Send report"
+msgstr "Kirim laporan"
+
+#: ../src/Gui/report.glade.h:19
+msgid "Show log"
+msgstr "Tampilkan log"
+
+#: ../src/Gui/SettingsDialog.py:33 ../src/Gui/SettingsDialog.py:50
+msgid "<b>Select plugin</b>"
+msgstr "<b>Pilih plugin</b>"
+
+#: ../src/Gui/SettingsDialog.py:36
+msgid "<b>Select database backend</b>"
+msgstr "<b>Pilih database backend</b>"
+
+#: ../src/Gui/SettingsDialog.py:169
+msgid "Remove this job"
+msgstr "Hapus pekerjaan ini"
+
+#: ../src/Gui/SettingsDialog.py:213
+msgid "Remove this action"
+msgstr "Hapus tindakan ini"
+
+#: ../src/Gui/settings.glade.h:1
+msgid "<b>Analyzer plugin</b>"
+msgstr "<b>Analyzer plugin</b>"
+
+#: ../src/Gui/settings.glade.h:2
+msgid "<b>Associated action</b>"
+msgstr "<b>Tindakan terkait</b>"
+
+#: ../src/Gui/settings.glade.h:3
+msgid "<b>Plugin details</b>"
+msgstr "<b>Plugin details</b>"
+
+#: ../src/Gui/settings.glade.h:4
+msgid "<b>Plugin</b>"
+msgstr "<b>Plugin</b>"
+
+#: ../src/Gui/settings.glade.h:5
+msgid "<b>Time (or period)</b>"
+msgstr "<b>Waktu (atau periode)</b>"
+
+#: ../src/Gui/settings.glade.h:6
+msgid "Analyzers, Actions, Reporters"
+msgstr "Penganalisis, Tindakan, Pelapor"
+
+#: ../src/Gui/settings.glade.h:7
+msgid "Author:"
+msgstr "Penulis:"
+
+#: ../src/Gui/settings.glade.h:8
+msgid "Blacklisted packages: "
+msgstr "Paket yang di-blacklist:"
+
+#: ../src/Gui/settings.glade.h:9
+msgid "C_onfigure plugin"
+msgstr ""
+
+#: ../src/Gui/settings.glade.h:10
+msgid "Check package GPG signature"
+msgstr "Periksa tanda tangan GPG paket"
+
+#: ../src/Gui/settings.glade.h:11
+msgid "Common"
+msgstr "Umum"
+
+#: ../src/Gui/settings.glade.h:12
+msgid "Cron"
+msgstr "Cron"
+
+#: ../src/Gui/settings.glade.h:13
+msgid "Database backend: "
+msgstr "Database backend:"
+
+#: ../src/Gui/settings.glade.h:14
+msgid "Description:"
+msgstr "Keterangan:"
+
+#: ../src/Gui/settings.glade.h:15
+msgid "GPG Keys"
+msgstr "GPG Keys"
+
+#: ../src/Gui/settings.glade.h:16
+msgid "GPG keys: "
+msgstr "GPG keys:"
+
+#: ../src/Gui/settings.glade.h:17
+msgid "Global Settings"
+msgstr "Pengaturan global"
+
+#: ../src/Gui/settings.glade.h:18
+msgid "Max coredump storage size(MB):"
+msgstr "Maks ukuran penyimpanan coredump(MB):"
+
+#: ../src/Gui/settings.glade.h:19
+msgid "Name:"
+msgstr "Nama:"
+
+#: ../src/Gui/settings.glade.h:20
+msgid "Settings"
+msgstr "Pengaturan"
+
+#: ../src/Gui/settings.glade.h:21
+msgid "Version:"
+msgstr "Versi:"
+
+#: ../src/Gui/settings.glade.h:22
+msgid "Web Site:"
+msgstr "Web Site:"
+
+#: ../src/Gui/settings.glade.h:23
+msgid "gtk-cancel"
+msgstr "gtk-cancel"
+
+#: ../src/Gui/settings.glade.h:24
+msgid "gtk-ok"
+msgstr "gtk-ok"
+
+#: ../src/Gui/abrt.desktop.in.h:2
+msgid "View and report application crashes"
+msgstr "Lihat dan laporkan crash applikasi"
+
+#: ../src/Applet/Applet.cpp:78
+#, c-format
+msgid "A crash in package %s has been detected"
+msgstr "Sebuah crash di paket %s telah terdeteksi"
+
+#: ../src/Applet/Applet.cpp:253
+msgid "ABRT service is not running"
+msgstr "Layanan ABRT tidak berjalan"
+
+#: ../src/Applet/CCApplet.cpp:200
+msgid "Warning"
+msgstr "Peringatan"
+
+#: ../src/Daemon/Daemon.cpp:473
+msgid ""
+"Report size exceeded the quota. Please check system's MaxCrashReportsSize "
+"value in abrt.conf."
+msgstr ""
+"Laporan ukuran melebihi kuota. Silahkan cek MaxCrashReportsSize nilai sistem "
+"abrt.conf."
+
+#: ../lib/Plugins/Bugzilla.cpp:124
+msgid "Missing member 'reporter'"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:176
+msgid "Missing member 'cc'"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:262
+#, c-format
+msgid "Bug is already reported: %i"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:274
+msgid "Missing member 'bug_id'"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:283
+msgid "Missing member 'bugs'"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:346
+#, c-format
+msgid "New bug id: %i"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:440
+msgid "Checking for duplicates..."
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:446
+msgid "Empty login and password. Please check Bugzilla.conf"
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:449
+msgid "Logging into bugzilla..."
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:454
+msgid "Checking CC..."
+msgstr ""
+
+#: ../lib/Plugins/Bugzilla.cpp:465
+msgid "Creating new bug..."
+msgstr "Membuat bug baru..."
+
+#: ../lib/Plugins/Bugzilla.cpp:469
+msgid "Logging out..."
+msgstr "Keluar..."
+
+#: ../lib/Plugins/Kerneloops.cpp:35
+msgid "Getting local universal unique identification"
+msgstr "Mendapatkan identifikasi unik universal lokal"
+
+#: ../lib/Plugins/CCpp.cpp:253
+msgid "Generating backtrace"
+msgstr "Membangkitkan backtra"
+
+#: ../lib/Plugins/CCpp.cpp:375
+msgid "Starting debuginfo installation"
+msgstr "Memulai instalasi debuginfo"
+
+#: ../lib/Plugins/CCpp.cpp:524
+msgid "Getting local universal unique identification..."
+msgstr "Mendapatkan identifikasi unik universal lokal"
+
+#: ../lib/Plugins/CCpp.cpp:543
+msgid "Getting global universal unique identification..."
+msgstr "Mendapatkan identifikasi unik universal global"
+
+#: ../lib/Plugins/CCpp.cpp:721
+msgid "Skipping debuginfo installation"
+msgstr "Melewatkan instalasi debuginfo"
+
+#: ../lib/Plugins/KerneloopsReporter.cpp:100
+msgid "Creating and submitting a report..."
+msgstr "Membuat dan menyampaikan laporan..."
+
+#: ../lib/Plugins/Logger.cpp:76
+#, c-format
+msgid "Writing report to '%s'"
+msgstr "Menulis laporan untuk '%s'"
+
+#: ../lib/Plugins/FileTransfer.cpp:54
+msgid "FileTransfer: URL not specified"
+msgstr ""
+
+#: ../lib/Plugins/FileTransfer.cpp:58
+#, c-format
+msgid "Sending archive %s to %s"
+msgstr "Mengirimkan arsip %s ke %s"
+
+#: ../lib/Plugins/FileTransfer.cpp:289
+msgid "File Transfer: Creating a report..."
+msgstr "Transfer Berkas: Membuat sebuah laporan..."
+
+#: ../lib/Plugins/FileTransfer.cpp:323
+#, c-format
+msgid "Can't create and send an archive: %s"
+msgstr "Tidak bisa membuat dan mengirimkan sebuah arsip: %s"
+
+#: ../lib/Plugins/FileTransfer.cpp:352
+#, c-format
+msgid "Can't create and send an archive %s"
+msgstr "Tidak bisa membuat dan mengirimkan sebuah arsip %s"
+
+#: ../lib/Plugins/KerneloopsScanner.cpp:79
+msgid "Creating kernel oops crash reports..."
+msgstr "Membuat laporan kernel oops crash"
+
+#: ../lib/Plugins/Mailx.cpp:137
+msgid "Sending an email..."
+msgstr "Mengirimkan sebuah email..."
+
+#: ../lib/Plugins/SOSreport.cpp:103
+#, c-format
+msgid "Running sosreport: %s"
+msgstr "Menjalankan sosreport: %s"
+
+#: ../lib/Plugins/SOSreport.cpp:109
+msgid "Done running sosreport"
+msgstr "Selesai menjalankan sosreport"
diff --git a/scripts/abrt-bz-ratingfixer b/scripts/abrt-bz-ratingfixer
index 86f4c0c7..15f1a750 100755
--- a/scripts/abrt-bz-ratingfixer
+++ b/scripts/abrt-bz-ratingfixer
@@ -1,6 +1,9 @@
#!/usr/bin/python
# -*- mode:python -*-
#
+# Finds bugs with incomplete backtraces in Buzilla.
+# Incomplete backtraces are caused by missing debuginfo.
+#
# Please do not run this script unless it's neccessary to do so.
# It forces Bugzilla to send data related to thousands of bug reports.
@@ -10,17 +13,24 @@ import sys
import os.path
import subprocess
import cPickle
+import urllib
+import json
+#
+# Parse command line options.
+# Exit if mandatory options are missing.
+#
parser = OptionParser(version="%prog 1.0")
parser.add_option("-u", "--user", dest="user",
help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
parser.add_option("-p", "--password", dest="password",
help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla",
+parser.add_option("-b", "--bugzilla", dest="bugzilla", default="https://bugzilla.redhat.com/xmlrpc.cgi",
help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
parser.add_option("-i", "--wiki", help="Generate output in wiki syntax",
action="store_true", default=False, dest="wiki")
-
+parser.add_option("-c", "--close", help="Close some of the bugs in Bugzilla (DANGEROUS)",
+ action="store_true", default=False, dest="close")
(options, args) = parser.parse_args()
if not options.user or len(options.user) == 0:
@@ -29,19 +39,18 @@ if not options.user or len(options.user) == 0:
if not options.password or len(options.password) == 0:
parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-if not options.bugzilla or len(options.bugzilla) == 0:
- options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
-
+#
+# Connect to the Bugzilla and get all bugs reported by ABRT
+#
bz = RHBugzilla()
bz.connect(options.bugzilla)
bz.login(options.user, options.password)
buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
-
print "{0} bugs found.".format(len(buginfos))
#
-# Load cache from previous run. Speeds up the case Bugzilla closes connection.
+# Load cache from previous run. It speeds up the case Bugzilla closes connection.
# The cache should be manually removed after a day or so, because the data in it
# are no longer valid.
#
@@ -58,21 +67,35 @@ def save_to_cache():
cPickle.dump(ids, f, 2)
f.close()
+#
+# Go through all bugs, and get the rating for their backtraces.
+# The result is stored into ids map.
+#
count = 0
for buginfo in buginfos:
+ # The progress indicator.
count += 1
print "{0}/{1}".format(count, len(buginfos))
+
+ # Save to cache for the case the connection will be closed by the Bugzilla.
+ # This happens pretty often.
if count % 100 == 0:
save_to_cache()
+ # Skip the bugs already loaded from cache.
if ids.has_key(buginfo.bug_id):
continue
+ # We handle only unprocessed bugs.
if not buginfo.bug_status in ["NEW", "ASSIGNED"]:
continue
# By default: rating 4, no comments. Do not touch strange bugs.
- ids[buginfo.bug_id] = ( 4, 0 )
+ ids[buginfo.bug_id] = {
+ 'rating': 4,
+ 'comment_count': 0,
+ 'component': buginfo.component
+ }
# Skip bugs with already downloaded backtraces.
filename = "{0}.bt".format(buginfo.bug_id)
@@ -94,26 +117,40 @@ for buginfo in buginfos:
if not downloaded:
continue
+ # Rate the backtrace using external program.
command = ["./abrt-rate-backtrace"]
command.append(filename)
-
helper = subprocess.Popen(command, stdout=subprocess.PIPE)
rating, err = helper.communicate()
helper.wait()
-
if helper.returncode != 0:
print "Problems with rating {0}".format(filename)
continue
-
+
+ # Get the comment count. We do not want to close bugs which
+ # are in the middle of a discussion.
bug = bz.getbug(buginfo.bug_id)
- comments = 0
+ comment_count = 0
for comment in bug.longdescs:
# Do not count "rawhide" comments from Bug Zappers
if comment["body"].find("against 'rawhide' during") > 0:
continue
- comments += 1
-
- ids[buginfo.bug_id] = ( int(rating), comments )
+ comment_count += 1
+
+ # Put the result to the database.
+ ids[buginfo.bug_id] = {
+ 'rating': int(rating),
+ 'comment_count': comment_count,
+ 'component': buginfo.component
+ }
+
+ # Close the bug if it's appropriate.
+ if options.close and comment_count <= 2 and int(rating) < 3:
+ print "Closing bug #{0} with {1} comments and rating {2}/4.".format(buginfo.bug_id, comment_count, int(rating))
+ bug.close("INSUFFICIENT_DATA", 0, "",
+ "This bug appears to have been filled using a buggy version of ABRT, because\n" +
+ "it contains unusable backtrace. Sorry for the inconvenience.\n\n" +
+ "Closing as INSUFFICIENT_DATA.")
bz.logout()
@@ -124,19 +161,31 @@ bugids = ids.keys()
bugids.sort()
if options.wiki:
print "{|"
- print " ! Bug !! Backtrace rating !! Comment count"
+ print " ! Bug !! Backtrace rating !! Comment count !! Component !! Owner"
print " |-"
for bugid in bugids:
- rating = ids[bugid]
- if rating[0] < 3:
+ bug = ids[bugid]
+ if bug['rating'] < 3:
count += 1
- if rating[1] <= 2:
+ if bug['comment_count'] <= 2:
closedcount += 1
+
+ # Get the component owner
+ owner = "Failed to get component owner"
+ try:
+ component_info = json.load(urllib.urlopen("https://admin.fedoraproject.org/pkgdb/packages/name/{0}?tg_format=json".format(bug['component'])))
+ component_packages = component_info['packageListings']
+ component_f12 = filter(lambda x:x["collection"]["version"]=="12", component_packages)
+ if len(component_f12) == 1:
+ owner = component_f12[0]["owner"]
+ except KeyError:
+ pass
+
if options.wiki:
- print " | #[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] || {1}/4 || {2}".format(bugid, rating[0], rating[1])
+ print " | #[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] || {1}/4 || {2} || {3} || {4}".format(bugid, bug['rating'], bug['comment_count'], bug['component'], owner)
print " |-"
else:
- print "#{0} has a backtrace with rating {1}/4 and {2} comments".format(bugid, rating[0], rating[1])
+ print "#{0} has a backtrace with rating {1}/4 and {2} comments, component {3}, owner {4}".format(bugid, bug['rating'], bug['comment_count'], bug['component'], owner)
if options.wiki:
print " |}"
diff --git a/src/Backtrace/abrt-bz-dupchecker b/src/Backtrace/abrt-bz-dupchecker
index cbdafc53..dc2ef8ea 100755
--- a/src/Backtrace/abrt-bz-dupchecker
+++ b/src/Backtrace/abrt-bz-dupchecker
@@ -25,16 +25,20 @@ import sys
import os.path
import subprocess
import cPickle
+import urllib
+import json
parser = OptionParser(version="%prog 1.0")
parser.add_option("-u", "--user", dest="user",
help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
parser.add_option("-p", "--password", dest="password",
help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla",
+parser.add_option("-b", "--bugzilla", dest="bugzilla", default="https://bugzilla.redhat.com/xmlrpc.cgi",
help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
parser.add_option("-v", "--verbose", dest="verbose",
help="Detailed output")
+parser.add_option("-c", "--close", help="Close some of the bugs in Bugzilla (DANGEROUS)",
+ action="store_true", default=False, dest="close")
parser.add_option("-i", "--wiki", help="Generate output in wiki syntax",
action="store_true", default=False, dest="wiki")
@@ -46,9 +50,6 @@ if not options.user or len(options.user) == 0:
if not options.password or len(options.password) == 0:
parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-if not options.bugzilla or len(options.bugzilla) == 0:
- options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
-
bz = RHBugzilla()
bz.connect(options.bugzilla)
bz.login(options.user, options.password)
@@ -87,6 +88,7 @@ for buginfo in buginfos:
if ids.has_key(buginfo.bug_id):
continue
+
ids[buginfo.bug_id] = True
if not buginfo.bug_status in ["NEW", "ASSIGNED", "MODIFIED", "VERIFIED"]:
@@ -152,11 +154,6 @@ for buginfo in buginfos:
else:
database[backtrace] = { buginfo.component: [ bugitem ] }
-bz.logout()
-
-print "SUMMARY"
-print "=========================================================================="
-
# The number of duplicates.
dupcount = 0
# The number of duplicates that can be closed.
@@ -168,29 +165,99 @@ for backtrace, components in database.items():
map(lambda x: x["comments"],
bugitems))),
len(bugitems) - 1)
+
+# Get the component owner.
+# Sort the duplicates by the component owner, and
+# filter out those which should not be printed.
+dups = []
+for backtrace, components in database.items():
+ for component, bugitems in components.items():
+ if len(bugitems) <= 1:
+ continue
+
+ # Get the component owner
+ owner = "Failed to get component owner"
+ try:
+ component_info = json.load(urllib.urlopen("https://admin.fedoraproject.org/pkgdb/packages/name/{0}?tg_format=json".format(component)))
+ component_packages = component_info['packageListings']
+ component_f12 = filter(lambda x:x["collection"]["version"]=="12", component_packages)
+ if len(component_f12) == 1:
+ owner = component_f12[0]["owner"]
+ except KeyError:
+ pass
+
+ dups.append((component, owner, bugitems, backtrace))
+ print "."
+
+# Close all bugs where it is appropriate.
+if options.close:
+ for (component, owner, bugitems, backtrace) in dups:
+ # Find the master bug item
+ # Its the one with the most comments.
+ # Sort function sorting by comment count.
+ def commentCmp(x, y):
+ if x['comments'] < y['comments']:
+ return 1
+ elif x['comments'] == y['comments']:
+ # Sort by bug id, older bugs should became the master bug
+ if x['id'] > y['id']:
+ return 1
+ elif x['id'] == y['id']:
+ return 0
+ else:
+ return -1
+ else:
+ return -1
+
+ sorteditems = sorted(bugitems, commentCmp)
+
+ master = sorteditems[0]
+ for item in sorteditems[1:]:
+ if item['comments'] > 2:
+ continue
+
+ print "Closing bug #{0} with {1} comments as a duplicate of #{2}.".format(item['id'], item['comments'], master['id'])
+ bug = bz.getbug(int(item['id']))
+ bug.close("DUPLICATE", int(master['id']), "",
+ "This bug appears to have been filled using a buggy version of ABRT, because\n" +
+ "it contains a backtrace which is considered as a duplicate of the backtrace in #{0}." +
+ "Sorry for the inconvenience.\n\n" +
+ "Closing as a duplicate of #{0}.".format(master['id']))
+
+bz.logout()
+
+print
+print "SUMMARY"
+print "=========================================================================="
print "Total number of duplicate bugs detected: {0}".format(dupcount)
print "Number of duplicate bugs that will be closed : {0}".format(dupclosecount)
print "------------------------------"
-# Print the duplicates
-for backtrace, components in database.items():
- for component, bugitems in components.items():
- if len(bugitems) > 1:
- if options.wiki:
- print "----"
- print "* component: '''{0}'''".format(component)
- print "* duplicates: {0}".format(
- reduce(lambda x,y: x+", "+y,
- map(lambda x: "#[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] ({1} comments)".format(x['id'],x['comments']),
- bugitems)))
- print "* backtrace:"
- for line in backtrace.replace("Thread\n", "").splitlines():
- print "*# {0}".format(line)
- else:
- print "Component: {0}".format(component)
- print "Duplicates: {0}".format(
- reduce(lambda x,y: x+", "+y,
- map(lambda x: "{0} ({1})".format(x['id'],x['comments']),
- bugitems)))
- print "Backtrace: {0}".format(backtrace)
+# Print the duplicates sorted by package owner.
+def cmp(x, y):
+ if x[1] < y[1]:
+ return -1
+ elif x[1] == y[1]:
+ return 0
+ else:
+ return 1
+
+for (component, owner, bugitems, backtrace) in sorted(dups, cmp):
+ if options.wiki:
+ print "----"
+ print "* component: '''{0}''' ({1})".format(component, owner)
+ print "* duplicates: {0}".format(
+ reduce(lambda x,y: x+", "+y,
+ map(lambda x: "#[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] ({1} comments)".format(x['id'],x['comments']),
+ bugitems)))
+ print "* backtrace:"
+ for line in backtrace.replace("Thread\n", "").splitlines():
+ print "*# {0}".format(line)
+ else:
+ print "Component: {0} ({1})".format(component, owner)
+ print "Duplicates: {0}".format(
+ reduce(lambda x,y: x+", "+y,
+ map(lambda x: "{0} ({1})".format(x['id'],x['comments']),
+ bugitems)))
+ print "Backtrace: {0}".format(backtrace)
diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp
index 7ef33acf..ebade16b 100644
--- a/src/CLI/report.cpp
+++ b/src/CLI/report.cpp
@@ -21,6 +21,7 @@
#include "abrtlib.h"
#include "DebugDump.h"
#include "CrashTypes.h" // FILENAME_* defines
+#include "Plugin.h" // LoadPluginSettings
#if HAVE_CONFIG_H
# include <config.h>
#endif
@@ -300,7 +301,12 @@ static int read_crash_report(map_crash_data_t &report, const char *text)
return result;
}
-/* Runs external editor. */
+/**
+ * Runs external editor.
+ * Returns:
+ * 0 if the launch was successful
+ * 1 if it failed. The error reason is logged using error_msg()
+ */
static int launch_editor(const char *path)
{
const char *editor, *terminal;
@@ -330,76 +336,216 @@ static int launch_editor(const char *path)
return 0;
}
-/* Reports the crash with corresponding uuid over DBus. */
-int report(const char *uuid, bool always)
+/**
+ * Returns:
+ * 0 on success, crash data has been updated
+ * 2 on failure, unable to create, open, or close temporary file
+ * 3 on failure, cannot launch text editor
+ */
+static int run_report_editor(map_crash_data_t &cr)
{
- // Ask for an initial report.
- map_crash_data_t cr = call_CreateReport(uuid);
-//TODO: error check?
-
- if (!always)
+ /* Open a temporary file and write the crash report to it. */
+ char filename[] = "/tmp/abrt-report.XXXXXX";
+ int fd = mkstemp(filename);
+ if (fd == -1) /* errno is set */
{
- /* 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("can't generate temporary file name");
- return 1;
- }
+ perror_msg("can't generate temporary file name");
+ return 2;
+ }
+
+ FILE *fp = fdopen(fd, "w");
+ if (!fp) /* errno is set */
+ {
+ perror_msg("can't open '%s' to save the crash report", filename);
+ return 2;
+ }
+
+ write_crash_report(cr, fp);
+
+ if (fclose(fp)) /* errno is set */
+ {
+ perror_msg("can't close '%s'", filename);
+ return 2;
+ }
+
+ // Start a text editor on the temporary file.
+ if (launch_editor(filename) != 0)
+ return 3; /* exit with error */
+
+ // Read the file back and update the report from the file.
+ fp = fopen(filename, "r");
+ if (!fp) /* errno is set */
+ {
+ perror_msg("can't open '%s' to read the crash report", filename);
+ return 2;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ long size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ char *text = (char*)xmalloc(size + 1);
+ if (fread(text, 1, size, fp) != size)
+ {
+ error_msg("can't read '%s'", filename);
+ return 2;
+ }
+ text[size] = '\0';
+ if (fclose(fp) != 0) /* errno is set */
+ {
+ perror_msg("can't close '%s'", filename);
+ return 2;
+ }
+
+ // Delete the tempfile.
+ if (unlink(filename) == -1) /* errno is set */
+ {
+ perror_msg("can't unlink %s", filename);
+ }
- FILE *fp = fdopen(fd, "w");
- if (!fp)
- {
- error_msg("can't open '%s' to save the crash report", filename);
- return 1;
- }
+ remove_comments_and_unescape(text);
+ // Updates the crash report from the file text.
+ int report_changed = read_crash_report(cr, text);
+ free(text);
+ if (report_changed)
+ puts(_("\nThe report has been updated."));
+ else
+ puts(_("\nNo changes were detected in the report."));
+
+ return 0;
+}
- write_crash_report(cr, fp);
+/**
+ * Asks user for a text response.
+ * @param question
+ * Question displayed to user.
+ * @param result
+ * Output array.
+ * @param result_size
+ * Maximum byte count to be written.
+ */
+static void read_from_stdin(const char *question, char *result, int result_size)
+{
+ printf(question);
+ fflush(NULL);
+ fgets(result, result_size, stdin);
+ // Remove the newline from the login.
+ char *newline = strchr(result, '\n');
+ if (newline)
+ *newline = '\0';
+}
+
+/**
+ * Gets reporter plugin settings.
+ * @param ask_user
+ * If it's set to true and some reporter plugin settings are found to be missing
+ * (like login name or password), user is asked to provide the missing parts.
+ * @param settings
+ * A structure filled with reporter plugin settings.
+ */
+static void get_reporter_plugin_settings(map_map_string_t &settings, bool ask_user)
+{
+ /* First of all, load system-wide report plugin settings. */
+ // Get informations about all plugins.
+ map_map_string_t plugins = call_GetPluginsInfo();
+ // Check the configuration of each enabled Reporter plugin.
+ map_map_string_t::iterator it, itend = plugins.end();
+ for (it = plugins.begin(); it != itend; ++it)
+ {
+ // Skip disabled plugins.
+ if (0 != strcmp(it->second["Enabled"].c_str(), "yes"))
+ continue;
+ // Skip nonReporter plugins.
+ if (0 != strcmp(it->second["Type"].c_str(), "Reporter"))
+ continue;
+ map_string_t single_plugin_settings = call_GetPluginSettings(it->first.c_str());
+ // Copy the received settings as defaults.
+ // Plugins won't work without it, if some value is missing
+ // they use their default values for all fields.
+ settings[it->first] = single_plugin_settings;
+ }
- if (fclose(fp))
+ /* Second, load user-specific settings, which override
+ the system-wide settings. */
+ struct passwd* pw = getpwuid(geteuid());
+ const char* homedir = pw ? pw->pw_dir : NULL;
+ if (homedir)
+ {
+ itend = settings.end();
+ for (it = settings.begin(); it != itend; ++it)
{
- error_msg("can't close '%s'", filename);
- return 2;
+ map_string_t single_plugin_settings;
+ std::string path = std::string(homedir) + "/.abrt/"
+ + it->first + "."PLUGINS_CONF_EXTENSION;
+ /* Load plugin config in the home dir. Do not skip lines with empty value (but containing a "key="),
+ because user may want to override password from /etc/abrt/plugins/*.conf, but he prefers to
+ enter it every time he reports. */
+ bool success = LoadPluginSettings(path.c_str(), single_plugin_settings, false);
+ if (!success)
+ continue;
+ // Merge user's plugin settings into already loaded settings.
+ map_string_t::const_iterator valit, valitend = single_plugin_settings.end();
+ for (valit = single_plugin_settings.begin(); valit != valitend; ++valit)
+ it->second[valit->first] = valit->second;
}
+ }
- // Start a text editor on the temporary file.
- launch_editor(filename);
+ if (!ask_user)
+ return;
- // Read the file back and update the report from the file.
- fp = fopen(filename, "r");
- if (!fp)
+ /* Third, check if a login or password is missing,
+ and ask for it. */
+ itend = settings.end();
+ for (it = settings.begin(); it != itend; ++it)
+ {
+ map_string_t &single_plugin_settings = it->second;
+ // Login information is missing.
+ bool loginMissing = single_plugin_settings.find("Login") != single_plugin_settings.end()
+ && 0 == strcmp(single_plugin_settings["Login"].c_str(), "");
+ bool passwordMissing = single_plugin_settings.find("Password") != single_plugin_settings.end()
+ && 0 == strcmp(single_plugin_settings["Password"].c_str(), "");
+ if (!loginMissing && !passwordMissing)
+ continue;
+
+ // Read the missing information and push it to plugin settings.
+ printf(_("Wrong settings were detected for plugin %s.\n"), it->first.c_str());
+ char result[64];
+ if (loginMissing)
{
- error_msg("can't open '%s' to read the crash report", filename);
- return 1;
+ read_from_stdin(_("Enter your login: "), result, 64);
+ single_plugin_settings["Login"] = std::string(result);
}
-
- fseek(fp, 0, SEEK_END);
- long size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- char *text = (char*)xmalloc(size + 1);
- if (fread(text, 1, size, fp) != size)
+ if (passwordMissing)
{
- error_msg("can't read '%s'", filename);
- return 1;
+// TODO: echo off, see http://fixunix.com/unix/84474-echo-off.html
+ read_from_stdin(_("Enter your password: "), result, 64);
+ single_plugin_settings["Password"] = std::string(result);
}
- text[size] = '\0';
- fclose(fp);
+ }
+}
- remove_comments_and_unescape(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."));
+/* Reports the crash with corresponding uuid over DBus. */
+int report(const char *uuid, bool always)
+{
+ // Ask for an initial report.
+ map_crash_data_t cr = call_CreateReport(uuid);
+//TODO: error check?
- free(text);
+ /* Open text editor and give a chance to review the backtrace etc. */
+ if (!always)
+ {
+ int result = run_report_editor(cr);
+ if (result != 0)
+ return result;
+ }
- if (unlink(filename) != 0) // Delete the tempfile.
- perror_msg("can't unlink %s", filename);
+ /* Read the plugin settings. */
+ map_map_string_t pluginSettings;
+ get_reporter_plugin_settings(pluginSettings, !always);
+ /* Ask if user really want to send the report. */
+ if (!always)
+ {
// Report only if the user is sure.
printf(_("Do you want to send the report? [y/N]: "));
fflush(NULL);
@@ -412,59 +558,6 @@ int report(const char *uuid, bool always)
}
}
- map_map_string_t pluginSettings;
- if (!always)
- {
- // Get informations about all plugins.
- map_map_string_t plugins = call_GetPluginsInfo();
- // Check the configuration of each enabled Reporter plugin.
- map_map_string_t::iterator it, itend = plugins.end();
- for (it = plugins.begin(); it != itend; ++it)
- {
- // Skip disabled plugins.
- if (0 != strcmp(it->second["Enabled"].c_str(), "yes"))
- continue;
- // Skip nonReporter plugins.
- if (0 != strcmp(it->second["Type"].c_str(), "Reporter"))
- continue;
-
- map_string_t settings = call_GetPluginSettings(it->first.c_str());
- // Login information is missing.
- bool loginMissing = settings.find("Login") != settings.end()
- && 0 == strcmp(settings["Login"].c_str(), "");
- bool passwordMissing = settings.find("Password") != settings.end()
- && 0 == strcmp(settings["Password"].c_str(), "");
- if (!loginMissing && !passwordMissing)
- continue;
-
- // Copy the received settings as defaults.
- // Plugins won't work without it, if some value is missing
- // they use their default values for all fields.
- pluginSettings[it->first] = settings;
-
- printf(_("Wrong settings were detected for plugin %s.\n"), it->second["Name"].c_str());
- if (loginMissing)
- {
- printf(_("Enter your login: "));
- fflush(NULL);
- char answer[64] = "";
- fgets(answer, sizeof(answer), stdin);
- if (strlen(answer) > 0)
- pluginSettings[it->first]["Login"] = answer;
- }
- if (passwordMissing)
- {
-// TODO: echo off, see http://fixunix.com/unix/84474-echo-off.html
- printf(_("Enter your password: "));
- fflush(NULL);
- char answer[64] = "";
- fgets(answer, sizeof(answer), stdin);
- if (strlen(answer) > 0)
- pluginSettings[it->first]["Password"] = answer;
- }
- }
- }
-
int errors = 0;
int plugins = 0;
puts(_("Reporting..."));
@@ -475,7 +568,7 @@ int report(const char *uuid, bool always)
vector_string_t &v = it->second;
printf("%s: %s\n", it->first.c_str(), v[REPORT_STATUS_IDX_MSG].c_str());
plugins++;
- if (v[REPORT_STATUS_IDX_FLAG] != "0")
+ if (v[REPORT_STATUS_IDX_FLAG] == "0")
errors++;
it++;
}
diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp
index e63cb3ac..f01d9435 100644
--- a/src/Daemon/PluginManager.cpp
+++ b/src/Daemon/PluginManager.cpp
@@ -80,60 +80,6 @@ static const char *const plugin_type_str[] = {
};
-bool LoadPluginSettings(const char *pPath, map_plugin_settings_t& pSettings)
-{
- FILE *fp = fopen(pPath, "r");
- if (!fp)
- return false;
-
- char line[512];
- while (fgets(line, sizeof(line), fp))
- {
- strchrnul(line, '\n')[0] = '\0';
- unsigned ii;
- bool is_value = false;
- bool valid = false;
- bool in_quote = false;
- string key;
- string value;
- for (ii = 0; line[ii] != '\0'; ii++)
- {
- if (line[ii] == '"')
- {
- in_quote = !in_quote;
- }
- if (isspace(line[ii]) && !in_quote)
- {
- continue;
- }
- if (line[ii] == '#' && !in_quote && key == "")
- {
- break;
- }
- if (line[ii] == '=' && !in_quote)
- {
- is_value = true;
- continue;
- }
- if (!is_value)
- {
- key += line[ii];
- }
- else
- {
- valid = true;
- value += line[ii];
- }
- }
- if (valid && !in_quote)
- {
- pSettings[key] = value;
- }
- }
- fclose(fp);
- return true;
-}
-
/**
* A function. It saves settings. On success it returns true, otherwise returns false.
* @param path A path of config file.
diff --git a/src/Daemon/PluginManager.h b/src/Daemon/PluginManager.h
index b5dcebc5..bf6952f4 100644
--- a/src/Daemon/PluginManager.h
+++ b/src/Daemon/PluginManager.h
@@ -154,13 +154,4 @@ class CPluginManager
map_plugin_settings_t GetPluginSettings(const char *pName);
};
-/**
- * Loads settings and stores it in second parameter. On success it
- * returns true, otherwise returns false.
- * @param path A path of config file.
- * @param settings A readed plugin's settings.
- * @return if it success it returns true, otherwise it returns false.
- */
-bool LoadPluginSettings(const char *pPath,
- map_plugin_settings_t& pSettings);
#endif /*PLUGINMANAGER_H_*/
diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp
index 9b0376b3..5644d370 100644
--- a/src/Daemon/Settings.cpp
+++ b/src/Daemon/Settings.cpp
@@ -376,8 +376,16 @@ void LoadSettings()
ParseCommon();
ParseAnalyzerActionsAndReporters();
ParseCron();
- if(g_settings_bOpenGPGCheck)
- LoadGPGKeys();
+
+ /*
+ loading gpg keys will invoke LoadOpenGPGPublicKey() from rpm.cpp
+ pgpReadPkts which makes nss to re-init and thus makes
+ bugzilla plugin work :-/
+ */
+
+ //FIXME FIXME FIXME FIXME FIXME FIXME!!!
+ //if(g_settings_bOpenGPGCheck)
+ LoadGPGKeys();
}
/* dbus call to retrieve .conf file data from daemon */
diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install
index 35f4d6a1..3bb9c415 100755
--- a/src/Daemon/abrt-debuginfo-install
+++ b/src/Daemon/abrt-debuginfo-install
@@ -145,7 +145,9 @@ print_package_names() {
fi
# when we look for debuginfo we need only -debuginfo* repos, so we can disable the rest and thus make it faster
# also we want only fedora repositories, because abrt won't work for other packages anyway
- local cmd="yum $yumopts '--disablerepo=*' '--enablerepo=fedora-debuginfo*' '--enablerepo=updates-debuginfo*' --quiet provides $missing_debuginfo_files"
+ # --showduplicates: do not just show the latest package
+ # -R2: wait two minutes max (hopefully this prevents infinite hang on yum lock)
+ local cmd="yum $yumopts '--disablerepo=*' '--enablerepo=fedora-debuginfo*' '--enablerepo=updates-debuginfo*' --showduplicates -R2 --quiet provides $missing_debuginfo_files"
echo "$cmd" >"yum_provides.$1.OUT"
# eval is needed to strip away ''s; cant remove them above and just use
# $cmd, that would perform globbing on '*'
@@ -194,53 +196,56 @@ download_packages() {
for pkg in $packages; do
echo "Download $i/$num_packages: $pkg"
echo "Download $i/$num_packages: $pkg" >>yumdownloader.OUT
- # we can't handle packages from non Fedora repos, so we look and download only
+ # We can't handle packages from non Fedora repos, so we look and download only
# from Fedora repos which makes it faster
yumdownloader --disablerepo="*" --enablerepo="fedora-debuginfo*" --enablerepo="updates-debuginfo*" --quiet $pkg >>yumdownloader.OUT 2>&1
err=$?
echo "exitcode:$err" >>yumdownloader.OUT
echo >>yumdownloader.OUT
test $err = 0 || { echo "Download of $pkg failed!"; sleep 1; }
- : $((i++))
- done
-
- for file in *.rpm; do
- # Happens if no .rpm's were downloaded (yumdownloader problem)
- # In this case, $f is the literal "*.rpm" string
- test -f "$file" || error_msg_and_die "not a rpm file: '$file'"
- echo "Unpacking: $file"
- echo "Processing: $file" >>unpack.OUT
- rpm2cpio <"$file" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1
-#TODO: error check?
- done
-
- # Copy debuginfo files to cachedir
- if test x"$cachedir" != x"" && test -d "$cachedir"; then
- 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"
-
- # Do not copy it if it can be found in any of $debuginfodirs
- test -f "/$file" && continue
- if test x"$cachedir" != x""; then
- for d in $debuginfodirs; do
- test -f "$d/$file" && continue 2
+ # Process and delete the *.rpm file just downloaded
+ # We do it right after download: some users have smallish disks...
+ for file in *.rpm; do
+ # Happens if no .rpm's were downloaded (yumdownloader problem)
+ # In this case, $f is the literal "*.rpm" string
+ test -f "$file" || { echo "No rpm file downloaded"; continue; }
+ echo "Unpacking: $file"
+ echo "Processing: $file" >>unpack.OUT
+ rpm2cpio <"$file" >"unpacked.cpio" 2>>unpack.OUT || error_msg_and_die "Can't convert '$file' to cpio"
+ rm "$file"
+ cpio -id <"unpacked.cpio" >>unpack.OUT 2>&1 || error_msg_and_die "Can't unpack '$file' cpio archive"
+ rm "unpacked.cpio"
+ # Copy debuginfo files to cachedir
+ if test x"$cachedir" != x"" && test -d "$cachedir"; then
+ # For every needed debuginfo, check whether we have it
+ 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"
+ # Do not copy it if it can be found in any of $debuginfodirs
+ test -f "/$file" && continue
+ if test x"$cachedir" != x""; then
+ for d in $debuginfodirs; do
+ test -f "$d/$file" && continue 2
+ done
+ fi
+ if test -f "$file"; then
+ # File is one of those we just installed, cache it
+ 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
+ echo "Caching debuginfo: $file"
+ cp --remove-destination "$file" "$cachedir/$file" || error_msg_and_die "Can't copy $file (disk full?)"
+ continue
+ fi
done
fi
-
- if test -f "$file"; then
- # File is one of those we just installed, cache it.
- 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 --remove-destination "$file" "$cachedir/$file"
-#TODO: error check?
- continue
- fi
+ # Delete remaining files unpacked from .cpio
+ # which we didn't need after all
+ rm -r etc bin sbin usr var opt 2>/dev/null
done
- fi
+ : $((i++))
+ done
}
diff --git a/src/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py
index 0d9b0a2e..dfcfaf15 100644
--- a/src/Gui/CCMainWindow.py
+++ b/src/Gui/CCMainWindow.py
@@ -2,6 +2,7 @@
import sys
import pwd
import getopt
+from glib import markup_escape_text
from abrt_utils import _, init_logging, log, log1, log2
import gobject
@@ -64,12 +65,18 @@ class MainWindow():
#init the dumps treeview
self.dlist = self.wTree.get_widget("tvDumps")
#rows of items with:
- #icon, package_name, application, date, crash_rate, user, is_reported, ?object?
- self.dumpsListStore = gtk.ListStore(gtk.gdk.Pixbuf, str,str,str,str,str,bool, object)
- # set filter
- modelfilter = self.dumpsListStore.filter_new()
- modelfilter.set_visible_func(self.filter_dumps, None)
- self.dlist.set_model(modelfilter)
+ ICON_COL = 0
+ PACKAGE_COL = 1
+ APPLICATION_COL = 2
+ TIME_STR_COL = 3
+ CRASH_RATE_COL = 4
+ USER_COL = 5
+ IS_REPORTED_COL = 6
+ UNIX_TIME_COL = 7
+ DUMP_OBJECT_COL = 8
+ #icon, package_name, application, date, crash_rate, user, is_reported, time_in_sec ?object?
+ self.dumpsListStore = gtk.ListStore(gtk.gdk.Pixbuf, str,str,str,str,str,bool, int, object)
+ self.dlist.set_model(self.dumpsListStore)
# add pixbuff separatelly
icon_column = gtk.TreeViewColumn(_("Icon"))
icon_column.cell = gtk.CellRendererPixbuf()
@@ -78,13 +85,17 @@ class MainWindow():
icon_column.pack_start(icon_column.cell, False)
icon_column.set_attributes(icon_column.cell, pixbuf=(n-1), cell_background_set=6)
# ===============================================
- columns = [None]*4
- columns[0] = gtk.TreeViewColumn(_("Package"))
- columns[1] = gtk.TreeViewColumn(_("Application"))
- columns[2] = gtk.TreeViewColumn(_("Date"))
- columns[3] = gtk.TreeViewColumn(_("Crash count"))
- column = gtk.TreeViewColumn(_("User"))
- columns.append(column)
+ columns = []
+ columns.append(gtk.TreeViewColumn(_("Package")))
+ columns[-1].set_sort_column_id(PACKAGE_COL)
+ columns.append(gtk.TreeViewColumn(_("Application")))
+ columns[-1].set_sort_column_id(APPLICATION_COL)
+ columns.append(gtk.TreeViewColumn(_("Date")))
+ columns[-1].set_sort_column_id(UNIX_TIME_COL)
+ columns.append(gtk.TreeViewColumn(_("Crash count")))
+ columns[-1].set_sort_column_id(CRASH_RATE_COL)
+ columns.append(gtk.TreeViewColumn(_("User")))
+ columns[-1].set_sort_column_id(USER_COL)
# create list
for column in columns:
n = self.dlist.append_column(column)
@@ -204,7 +215,7 @@ class MainWindow():
except Exception, ex:
user = "UID: %s" % entry.getUID()
n = self.dumpsListStore.append([icon, entry.getPackage(), entry.getExecutable(),
- entry.getTime("%c"), entry.getCount(), user, entry.isReported(), entry])
+ entry.getTime("%c"), entry.getCount(), user, entry.isReported(), entry.getTime(""), entry])
# activate the first row if any..
if n:
# we can use (0,) as path for the first row, but what if API changes?
@@ -233,8 +244,8 @@ class MainWindow():
# it is not informative (no URL to the report)
for message in dump.getMessage().split(';'):
if message:
- message_clean = message.strip()
- if "http" in message_clean[0:5] or "file:///"[0:8] in message_clean:
+ message_clean = markup_escape_text(message.strip())
+ if "http" in message_clean[0:5] or "file:///" in message_clean[0:8]:
report_message = "<a href=\"%s\">%s</a>" % (message_clean, message_clean)
else:
report_message = message_clean
diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py
index 816164b6..bc4a1e0e 100644
--- a/src/Gui/CCReporterDialog.py
+++ b/src/Gui/CCReporterDialog.py
@@ -290,11 +290,11 @@ class ReporterDialog():
self.tevHowToReproduce.set_buffer(buff)
def dehydrate(self):
- # handle attachments
- vbAttachments = self.builder.get_object("vbAttachments")
- for attachment in vbAttachments.get_children():
- #print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label())
- del self.report[attachment.item]
+ ## # handle attachments
+ ## vbAttachments = self.builder.get_object("vbAttachments")
+ ## for attachment in vbAttachments.get_children():
+ ## #print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label())
+ ## del self.report[attachment.item]
# handle comment
buff = self.tvComment.get_buffer()
diff --git a/src/Gui/CC_gui_functions.py b/src/Gui/CC_gui_functions.py
index 9378de52..acfd2a53 100644
--- a/src/Gui/CC_gui_functions.py
+++ b/src/Gui/CC_gui_functions.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+from glib import markup_escape_text
import gtk
import pango
import subprocess
@@ -66,7 +67,7 @@ def gui_report_dialog ( report_status_dict, parent_dialog,
# this first one is actually a fallback to set at least
# a raw text in case when set_markup() fails
status_label.set_text(report_status_dict[plugin][MESSAGE])
- status_label.set_markup("<span foreground='red'>%s</span>" % report_status_dict[plugin][MESSAGE])
+ status_label.set_markup("<span foreground='red'>%s</span>" % markup_escape_text(report_status_dict[plugin][MESSAGE]))
# if the report was not succesful then this won't pass so this runs only
# if report succeds and gets overwriten by the status message
if report_status_dict[plugin][STATUS] == '1':
diff --git a/src/Gui/PluginsSettingsDialog.py b/src/Gui/PluginsSettingsDialog.py
index 0ba390da..787faee6 100644
--- a/src/Gui/PluginsSettingsDialog.py
+++ b/src/Gui/PluginsSettingsDialog.py
@@ -107,7 +107,7 @@ class PluginsSettingsDialog:
# cell_text, toggle_active, toggle_visible, group_name_visible, color, plugin
["<b>%s</b>" % PluginInfo.types[plugin_type], 0, 0, 1, "gray", None])
plugin_rows[plugin_type] = it
- group_empty[plugin_type] = 1
+ group_empty[plugin_type] = it
for entry in pluginlist:
if entry.Description:
text = "<b>%s</b>\n%s" % (entry.getName(), entry.Description)
@@ -118,13 +118,13 @@ class PluginsSettingsDialog:
self.pluginsListStore.append(plugin_rows[plugin_type],
# cell_text, toggle_active, toggle_visible, group_name_visible, color, plugin
[text, entry.Enabled == "yes", 1, 0, "white", entry])
- group_empty[plugin_type] = 0
+ if group_empty.has_key(plugin_type):
+ del group_empty[plugin_type]
# rhbz#560971 "Don't show empty 'Not loaded plugins' section"
- for plugin_type in group_empty.keys():
- if group_empty[plugin_type]:
- self.pluginsListStore.append(plugin_rows[plugin_type],
- # cell_text, toggle_active, toggle_visible, group_name_visible, color, plugin
- ["(none)", 0, 1, 0, "white", None])
+ # don't show any empty groups
+ for it in group_empty.values():
+ self.pluginsListStore.remove(it)
+
self.pluginlist.expand_all()
def dehydrate(self):
@@ -141,7 +141,7 @@ class PluginsSettingsDialog:
def on_bConfigurePlugin_clicked(self, button, pluginview):
pluginsListStore, path = pluginview.get_selection().get_selected_rows()
if not path:
- self.builder.get_object("lDescription").set_label(_("Can't get plugin description"))
+ gui_info_dialog(_("Please select a plugin from the list to edit it's options."), self.window)
return
# this should work until we keep the row object in the last position
pluginfo = pluginsListStore.get_value(pluginsListStore.get_iter(path[0]), pluginsListStore.get_n_columns()-1)
diff --git a/src/Gui/ccgui.glade b/src/Gui/ccgui.glade
index 237f23a1..3050d656 100644
--- a/src/Gui/ccgui.glade
+++ b/src/Gui/ccgui.glade
@@ -208,7 +208,6 @@ Patrick Connelly &lt;pcon@fedoraproject.org&gt;</property>
<child>
<widget class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
- <property name="toolbar_style">both</property>
<child>
<widget class="GtkToolButton" id="bDelete">
<property name="visible">True</property>
@@ -225,7 +224,6 @@ Patrick Connelly &lt;pcon@fedoraproject.org&gt;</property>
<child>
<widget class="GtkToolButton" id="bReport">
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="tooltip" translatable="yes">Report</property>
<property name="label" translatable="yes">Report</property>
<property name="stock_id">gtk-go-up</property>
@@ -267,6 +265,8 @@ Patrick Connelly &lt;pcon@fedoraproject.org&gt;</property>
<widget class="GtkTreeView" id="tvDumps">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="reorderable">True</property>
+ <property name="search_column">1</property>
</widget>
</child>
</widget>
diff --git a/src/Gui/report.glade b/src/Gui/report.glade
index e7f37ec0..7b3aac4a 100644
--- a/src/Gui/report.glade
+++ b/src/Gui/report.glade
@@ -297,12 +297,12 @@
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="tvBacktrace">
<property name="height_request">200</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="accepts_tab">False</property>
</object>
</child>
</object>
@@ -378,6 +378,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="wrap_mode">word-char</property>
+ <property name="accepts_tab">False</property>
</object>
</child>
</object>
@@ -415,6 +416,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="wrap_mode">word-char</property>
+ <property name="accepts_tab">False</property>
</object>
</child>
</object>
diff --git a/src/Hooks/abrt-hook-ccpp.cpp b/src/Hooks/abrt-hook-ccpp.cpp
index 9d1dc19c..d21b8e6b 100644
--- a/src/Hooks/abrt-hook-ccpp.cpp
+++ b/src/Hooks/abrt-hook-ccpp.cpp
@@ -82,31 +82,52 @@ int main(int argc, char** argv)
/* set to max possible >0 value */
ulimit_c = ~((off_t)1 << (sizeof(off_t)*8-1));
}
- off_t core_size = 0;
-
if (errno || pid <= 0)
{
error_msg_and_die("pid '%s' or limit '%s' is bogus", argv[2], argv[5]);
}
+ char* executable = get_executable(pid);
+ if (executable == NULL)
+ {
+ error_msg_and_die("can't read /proc/%lu/exe link", (long)pid);
+ }
+ if (strstr(executable, "/abrt-hook-ccpp"))
+ {
+ error_msg_and_die("pid %lu is '%s', not dumping it to avoid recursion",
+ (long)pid, executable);
+ }
+
+ char *user_pwd = get_cwd(pid); /* may be NULL on error */
+
+ /* Parse abrt.conf and plugins/CCpp.conf */
+ unsigned setting_MaxCrashReportsSize = 0;
+ bool setting_MakeCompatCore = false;
+ parse_conf(CONF_DIR"/plugins/CCpp.conf", &setting_MaxCrashReportsSize, &setting_MakeCompatCore);
+
+ int core_fd = STDIN_FILENO;
+ off_t core_size = 0;
+
const char *signame = NULL;
/* Tried to use array for this but C++ does not support v[] = { [IDX] = "str" } */
switch (signal_no)
{
- case SIGQUIT: signame = "QUIT"; break;
case SIGILL : signame = "ILL" ; break;
- case SIGABRT: signame = "ABRT"; break;
case SIGFPE : signame = "FPE" ; break;
case SIGSEGV: signame = "SEGV"; break;
+ case SIGBUS : signame = "BUS" ; break; //Bus error (bad memory access)
+ case SIGABRT: signame = "ABRT"; break; //usually when abort() was called
+ //case SIGQUIT: signame = "QUIT"; break; //Quit from keyboard
+ //case SIGSYS : signame = "SYS" ; break; //Bad argument to routine (SVr4)
+ //case SIGTRAP: signame = "TRAP"; break; //Trace/breakpoint trap
+ //case SIGXCPU: signame = "XCPU"; break; //CPU time limit exceeded (4.2BSD)
+ //case SIGXFSZ: signame = "XFSZ"; break; //File size limit exceeded (4.2BSD)
}
if (signame == NULL) {
- /* not a signal we care about, exit silently */
- return 0;
+ /* not a signal we care about */
+ goto create_user_core;
}
- char *user_pwd = get_cwd(pid); /* may be NULL on error */
- int core_fd = STDIN_FILENO;
-
if (!daemon_is_ok())
{
/* not an error, exit with exitcode 0 */
@@ -119,22 +140,6 @@ int main(int argc, char** argv)
try
{
- char* executable = get_executable(pid);
- if (executable == NULL)
- {
- error_msg_and_die("can't read /proc/%lu/exe link", (long)pid);
- }
- if (strstr(executable, "/abrt-hook-ccpp"))
- {
- error_msg_and_die("pid %lu is '%s', not dumping it to avoid recursion",
- (long)pid, executable);
- }
-
- /* Parse abrt.conf and plugins/CCpp.conf */
- unsigned setting_MaxCrashReportsSize = 0;
- bool setting_MakeCompatCore = false;
- parse_conf(CONF_DIR"/plugins/CCpp.conf", &setting_MaxCrashReportsSize, &setting_MakeCompatCore);
-
if (setting_MaxCrashReportsSize > 0)
{
check_free_space(setting_MaxCrashReportsSize);
@@ -267,8 +272,6 @@ int main(int argc, char** argv)
trim_debug_dumps(setting_MaxCrashReportsSize, path);
}
- if (!setting_MakeCompatCore)
- return 0;
/* fall through to creating user core */
}
catch (CABRTException& e)
@@ -282,6 +285,9 @@ int main(int argc, char** argv)
create_user_core:
+ if (!setting_MakeCompatCore)
+ return 0;
+
/* note: core_size may be == 0 ("unknown") */
if (core_size > ulimit_c || ulimit_c == 0)
return 0;
diff --git a/src/Hooks/abrt-hook-python.cpp b/src/Hooks/abrt-hook-python.cpp
index 356174f8..34459540 100644
--- a/src/Hooks/abrt-hook-python.cpp
+++ b/src/Hooks/abrt-hook-python.cpp
@@ -37,21 +37,6 @@
static char *pid;
static char *executable;
-// Note: "" will return false
-static bool isxdigit_str(const char *str)
-{
- do {
- if ((*str < '0' || *str > '9') // not a digit
- && ((*str | 0x20) < 'a' || (*str | 0x20) > 'f') // not A-F or a-f
- )
- {
- return false;
- }
- str++;
- } while (*str);
- return true;
-}
-
static bool printable_str(const char *str)
{
do {
diff --git a/src/Hooks/abrt_exception_handler.py.in b/src/Hooks/abrt_exception_handler.py.in
index 89f30132..b5e15b80 100644
--- a/src/Hooks/abrt_exception_handler.py.in
+++ b/src/Hooks/abrt_exception_handler.py.in
@@ -59,8 +59,22 @@ def handleMyException((etype, value, tb)):
return sys.__excepthook__(etype, value, tb)
try:
+ import os
import os.path
import traceback
+ import errno
+
+ # EPIPE is not a crash, it happens all the time
+ # Testcase: script.py | true, where script.py is:
+ ## #!/usr/bin/python
+ ## import os
+ ## import time
+ ## time.sleep(1)
+ ## os.write(1, "Hello\n") # print "Hello" wouldn't be the same
+ #
+ if etype == IOError or etype == OSError:
+ if value.errno == errno.EPIPE:
+ return sys.__excepthook__(etype, value, tb)
# "-c" appears in this case:
# $ python -c 'import sys; print "argv0 is:%s" % sys.argv[0]'