diff options
72 files changed, 1780 insertions, 1252 deletions
@@ -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.3 +Version: 1.0.4 Release: 1%{?dist} License: GPLv2+ Group: Applications/System @@ -401,6 +401,34 @@ fi %defattr(-,root,root,-) %changelog +* Wed Jan 20 2010 Jiri Moskovcak <jmoskovc@redhat.com> 1.0.4-1 +- GUI: redesign of reporter dialog (jmoskovc@redhat.com) +- Set the prgname to "Automatic Bug Reporting Tool" fixes rhbz#550357 (jmoskovc@redhat.com) +- CCpp analyzer: display __abort_msg in backtrace. closes rhbz#549735 (vda.linux@googlemail.com) +- s/os.exit/sys.exit - closes rhbz#556313 (vda.linux@googlemail.com) +- use repr() to print variable values in python hook rhbz#545070 (jmoskovc@redhat.com) +- gui: add logging infrastructure (vda.linux@googlemail.com) +- Added "Enabled = yes" to all plugin's config files (jmoskovc@redhat.com) +- *: disable plugin loading/unloading through GUI. Document keyring a bit (vda.linux@googlemail.com) +- fix memory leaks in catcut plugin (npajkovs@redhat.com) +- fix memory leaks in bugzilla (npajkovs@redhat.com) +- abrt-hook-python: sanitize input more; log to syslog (vda.linux@googlemail.com) +- Fixed /var/cache/abrt/ permissions (kklic@redhat.com) +- Kerneloops: we require commandline for every crash, save dummy one for oopses (vda.linux@googlemail.com) +- *: remove nss dependencies (vda.linux@googlemail.com) +- CCpp: use our own sha1 implementation (less pain with nss libs) (vda.linux@googlemail.com) +- DebugDump: more consistent logic in setting mode and uid:gid on dump dir (vda.linux@googlemail.com) +- fixes based on security review (vda.linux@googlemail.com) +- SOSreport/TicketUploader: use more restrictive file modes (vda.linux@googlemail.com) +- abrt-hook-python: add input sanitization and directory size guard (vda.linux@googlemail.com) +- RunApp: safer chdir. Overhauled "sparn a child and get its output" in general (vda.linux@googlemail.com) +- DebugDump: use more restrictive modes (vda.linux@googlemail.com) +- SQLite3: check for SQL injection (vda.linux@googlemail.com) +- replace plugin enabling via EnabledPlugins by par-plugin Enabled = yes/no (vda.linux@googlemail.com) +- abrt.spec: move "requires: gdb" to abrt-desktop (vda.linux@googlemail.com) +- ccpp: add a possibility to disable backtrace generation (vda.linux@googlemail.com) +- abrtd: limit the number of frames in backtrace to 3000 (vda.linux@googlemail.com) + * Tue Jan 5 2010 Jiri Moskovcak <jmoskovc@redhat.com> 1.0.3-1 - speed optimalization of abrt-debuginfo-install (jmoskovc@redhat.com) - updated credits (jmoskovc@redhat.com) diff --git a/configure.ac b/configure.ac index 4f73d07a..6cc65a8a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([abrt], [1.0.3], [crash-catcher@fedorahosted.org]) +AC_INIT([abrt], [1.0.4], [crash-catcher@fedorahosted.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) @@ -84,7 +84,7 @@ if no new dbus calls are arriving to it. The key dbus calls served by abrt-process are: -- GetCrashInfos(): returns a vector_crash_infos_t (vector_map_vector_string_t) +- GetCrashInfos(): returns a vector_map_crash_data_t (vector_map_vector_string_t) of crashes for given uid v[N]["executable"/"uid"/"kernel"/"backtrace"][N] = "contents" [see above the problem with producing this list] @@ -97,8 +97,8 @@ The key dbus calls served by abrt-process are: abrt should be run by root anyway - debuginfo gets installed using pk-debuginfo-install, which cares about privileges itself, so no problem here -- GetJobResult(UUID): returns map_crash_report_t (map_vector_string_t) -- Report(map_crash_report_t (map_vector_string_t)): +- GetJobResult(UUID): returns map_crash_data_t (map_vector_string_t) +- Report(map_crash_data_t (map_vector_string_t)): "Please report this crash": calls Report() of all registered reporter plugins Returns report_status_t (map_vector_string_t) - the status of each call - DeleteDebugDump(UUID): delete corresponding /var/cache/abrt/DIR. Returns bool diff --git a/doc/PLUGINS-HOWTO b/doc/PLUGINS-HOWTO index d8467801..a7c08088 100644 --- a/doc/PLUGINS-HOWTO +++ b/doc/PLUGINS-HOWTO @@ -74,8 +74,8 @@ it on some web tool...) You have to override this method: -virtual void Report(const crash_report_t& pCrashReport, - const std::string& pArgs); +virtual void Report(const map_crash_data_t& pCrashData, + const char *pArgs); -It is self-explanatory, that this method takes the report and presents it somewhere to the world. The second argument is a string with arguments specified for the reporter. diff --git a/inc/CrashTypes.h b/inc/CrashTypes.h index ccbdd929..b14413d5 100644 --- a/inc/CrashTypes.h +++ b/inc/CrashTypes.h @@ -1,68 +1,98 @@ +/* + Copyright (C) 2009 Abrt team. + 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 CRASHTYPES_H_ #define CRASHTYPES_H_ #include "abrt_types.h" +// Filenames in dump directory +#define FILENAME_ARCHITECTURE "architecture" +#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" +#define FILENAME_ANALYZER "analyzer" +#define FILENAME_RELEASE "release" +#define FILENAME_EXECUTABLE "executable" +#define FILENAME_REASON "reason" +#define FILENAME_COMMENT "comment" +#define FILENAME_REPRODUCE "reproduce" +#define FILENAME_RATING "rating" +#define FILENAME_CMDLINE "cmdline" +#define FILENAME_COREDUMP "coredump" +#define FILENAME_BACKTRACE "backtrace" +#define FILENAME_MEMORYMAP "memorymap" +#define FILENAME_KERNELOOPS "kerneloops" + +#define CD_DUPHASH "DUPHASH" +#define CD_UUID "UUID" +#define CD_DUMPDIR "DumpDir" +#define CD_COUNT "Count" +#define CD_REPORTED "Reported" +#define CD_MESSAGE "Message" + + +// Crash data is a map of 3-element vectors of strings: type, editable, content +#define CD_TYPE 0 +#define CD_EDITABLE 1 +#define CD_CONTENT 2 + // SYS - system value, should not be displayed // BIN - binary data // TXT - text data, can be displayed #define CD_SYS "s" #define CD_BIN "b" #define CD_TXT "t" - -/* Text bigger than this usually is attached, not added inline */ +// Text bigger than this usually is attached, not added inline #define CD_TEXT_ATT_SIZE (2*1024) -#define CD_ISEDITABLE "y" -#define CD_ISNOTEDITABLE "n" +#define CD_ISEDITABLE "y" +#define CD_ISNOTEDITABLE "n" -#define CD_TYPE (0) -#define CD_EDITABLE (1) -#define CD_CONTENT (2) -#define CD_UUID "UUID" -#define CD_UID "UID" -#define CD_COUNT "Count" -#define CD_EXECUTABLE "Executable" -#define CD_PACKAGE "Package" -#define CD_DESCRIPTION "Description" -#define CD_TIME "Time" -#define CD_REPORTED "Reported" -#define CD_MESSAGE "Message" -#define CD_COMMENT "Comment" -#define CD_REPRODUCE "How to reproduce" -#define CD_MWANALYZER "_MWAnalyzer" -#define CD_MWUID "_MWUID" -#define CD_MWUUID "_MWUUID" -#define CD_MWDDD "_MWDDD" - -// currently, vector always has exactly 3 elements -> <type, editable, content> +extern const char *const must_have_files[]; + +bool is_editable_file(const char *file_name); + // <key, data> typedef map_vector_string_t map_crash_data_t; +typedef std::vector<map_crash_data_t> vector_map_crash_data_t; + +void add_to_crash_data_ext(map_crash_data_t& pCrashData, + const char *pItem, + const char *pType, + const char *pEditable, + const char *pContent); +// Uses type:CD_TXT, editable:CD_ISNOTEDITABLE +void add_to_crash_data(map_crash_data_t& pCrashData, + const char *pItem, + const char *pContent); + +const char *get_crash_data_item_content_or_NULL(const map_crash_data_t& crash_data, const char *key); +// Aborts if key is not found: +const std::string& get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key); + +void log_map_crash_data(const map_crash_data_t& data, const char *name); -typedef map_crash_data_t map_crash_info_t; -typedef map_crash_data_t map_crash_report_t; -typedef std::vector<map_crash_info_t> vector_crash_infos_t; - -inline void add_crash_data_to_crash_info(map_crash_info_t& pCrashInfo, - const std::string& pItem, - const std::string& pContent) -{ - pCrashInfo[pItem].push_back(CD_TXT); - pCrashInfo[pItem].push_back(CD_ISNOTEDITABLE); - pCrashInfo[pItem].push_back(pContent); -} - -inline void add_crash_data_to_crash_report(map_crash_report_t& pCrashReport, - const std::string& pItem, - const std::string& pType, - const std::string& pEditable, - const std::string& pContent) -{ - pCrashReport[pItem].push_back(pType); - pCrashReport[pItem].push_back(pEditable); - pCrashReport[pItem].push_back(pContent); -} - - -#endif /* CRASHTYPES_H_ */ +#endif diff --git a/inc/CrashTypesSocket.h b/inc/CrashTypesSocket.h index 166a8a81..db3ee44e 100644 --- a/inc/CrashTypesSocket.h +++ b/inc/CrashTypesSocket.h @@ -70,19 +70,19 @@ #define MESSAGE_CREATE_REPORT "(CREATE_REPORT)" #define MESSAGE_END_MARKER 23 -std::string crash_infos_to_string(const vector_crash_infos_t& pCrashInfos); +std::string crash_infos_to_string(const vector_map_crash_data_t& pCrashDatas); std::string crash_data_to_string(const map_crash_data_t& pCrashData); -inline std::string crash_report_to_string(const map_crash_report_t& pCrashReport) +inline std::string crash_report_to_string(const map_crash_data_t& pCrashData) { - return crash_data_to_string(pCrashReport); + return crash_data_to_string(pCrashData); } -vector_crash_infos_t string_to_crash_infos(const std::string& pMessage); +vector_map_crash_data_t string_to_crash_infos(const std::string& pMessage); map_crash_data_t string_to_crash_data(const std::string& pMessage, int& len); -inline map_crash_report_t string_to_crash_report(const std::string& pMessage) +inline map_crash_data_t string_to_crash_report(const std::string& pMessage) { int len; return string_to_crash_data(pMessage, len); } -#endif /* SOCKETCRASHTYPES_H_ */ +#endif diff --git a/lib/Plugins/Bugzilla.conf b/lib/Plugins/Bugzilla.conf index 6e98c9d5..14fc92c1 100644 --- a/lib/Plugins/Bugzilla.conf +++ b/lib/Plugins/Bugzilla.conf @@ -1,3 +1,4 @@ +Enabled = 1 # Bugzilla URL BugzillaURL = https://bugzilla.redhat.com/ # yes means that ssl certificates will not be checked diff --git a/lib/Plugins/Bugzilla.cpp b/lib/Plugins/Bugzilla.cpp index f963eb9c..0197a7bf 100644 --- a/lib/Plugins/Bugzilla.cpp +++ b/lib/Plugins/Bugzilla.cpp @@ -11,7 +11,9 @@ # include <config.h> #endif -#define XML_RPC_SUFFIX "/xmlrpc.cgi" +#define XML_RPC_SUFFIX "/xmlrpc.cgi" +#define NEW_BUG -1 +#define MISSING_MEMBER -2 /* * TODO: npajkovs: better deallocation of xmlrpc value @@ -32,8 +34,8 @@ struct ctx: public abrt_xmlrpc_conn { int32_t check_uuid_in_bugzilla(const char* component, const char* UUID); bool check_cc_and_reporter(uint32_t bug_id, const char* login); void add_plus_one_cc(uint32_t bug_id, const char* login); - uint32_t new_bug(const map_crash_report_t& pCrashReport); - void add_attachments(const char* bug_id_str, const map_crash_report_t& pCrashReport); + uint32_t new_bug(const map_crash_data_t& pCrashData); + void add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData); }; void ctx::login(const char* login, const char* passwd) @@ -123,6 +125,12 @@ bool ctx::check_cc_and_reporter(uint32_t bug_id, const char* login) return true; } } + else + { + VERB3 log("Missing member 'reporter'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bugs'")); + } xmlrpc_value* cc_member = NULL; xmlrpc_struct_find_value(&env, result, "cc", &cc_member); @@ -169,6 +177,12 @@ bool ctx::check_cc_and_reporter(uint32_t bug_id, const char* login) } xmlrpc_DECREF(cc_member); } + else + { + VERB3 log("Missing member 'bugs'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'cc'")); + } xmlrpc_DECREF(result); return false; @@ -235,7 +249,7 @@ int32_t ctx::check_uuid_in_bugzilla(const char* component, const char* UUID) { xmlrpc_DECREF(result); xmlrpc_DECREF(bugs_member); - return -1; + return NEW_BUG; } xmlrpc_value* item = NULL; @@ -270,30 +284,42 @@ int32_t ctx::check_uuid_in_bugzilla(const char* component, const char* UUID) xmlrpc_DECREF(result); return bug_id; } + else + { + VERB3 log("Missing member 'bug_id'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bug_id'")); + } xmlrpc_DECREF(item); xmlrpc_DECREF(bugs_member); } + else + { + VERB3 log("Missing member 'bugs'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bugs'")); + } xmlrpc_DECREF(result); - return -1; + return MISSING_MEMBER; } -uint32_t ctx::new_bug(const map_crash_report_t& pCrashReport) +uint32_t ctx::new_bug(const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); - std::string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - std::string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - std::string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT]; - std::string arch = pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]; - std::string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const std::string& package = get_crash_data_item_content(pCrashData, FILENAME_PACKAGE); + const std::string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const std::string& release = get_crash_data_item_content(pCrashData, FILENAME_RELEASE); + const std::string& arch = get_crash_data_item_content(pCrashData, FILENAME_ARCHITECTURE); + const std::string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); std::string summary = "[abrt] crash in " + package; std::string status_whiteboard = "abrt_hash:" + uuid; std::string description = "abrt "VERSION" detected a crash.\n\n"; - description += make_description_bz(pCrashReport); + description += make_description_bz(pCrashData); std::string product; std::string version; @@ -346,28 +372,29 @@ uint32_t ctx::new_bug(const map_crash_report_t& pCrashReport) return bug_id; } -void ctx::add_attachments(const char* bug_id_str, const map_crash_report_t& pCrashReport) +void ctx::add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); xmlrpc_value* result = NULL; - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { - const std::string &filename = it->first; + const std::string &itemname = it->first; const std::string &type = it->second[CD_TYPE]; const std::string &content = it->second[CD_CONTENT]; - if (type == CD_TXT && content.length() > CD_TEXT_ATT_SIZE) - { + if (type == CD_TXT + && (content.length() > CD_TEXT_ATT_SIZE || itemname == FILENAME_BACKTRACE) + ) { char *encoded64 = encode_base64(content.c_str(), content.length()); // fails only when you write query. when it's done it never fails. xmlrpc_value* param = xmlrpc_build_value(&env, "(s{s:s,s:s,s:s,s:s})", bug_id_str, - "description", ("File: " + filename).c_str(), - "filename", filename.c_str(), + "description", ("File: " + itemname).c_str(), + "filename", itemname.c_str(), "contenttype", "text/plain", "data", encoded64 ); @@ -404,7 +431,7 @@ CReporterBugzilla::CReporterBugzilla() : CReporterBugzilla::~CReporterBugzilla() {} -std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, +std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -433,8 +460,8 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, NoSSLVerify = m_bNoSSLVerify; } - std::string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - std::string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const std::string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const std::string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); try { ctx bz_server(BugzillaXMLRPC.c_str(), NoSSLVerify); @@ -442,12 +469,13 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, update_client(_("Checking for duplicates...")); bug_id = bz_server.check_uuid_in_bugzilla(component.c_str(), uuid.c_str()); - update_client(_("Logging into bugzilla...")); if ((Login == "") && (Password == "")) { VERB3 log("Empty login and password"); throw CABRTException(EXCEP_PLUGIN, _("Empty login and password. Please check Bugzilla.conf")); } + + update_client(_("Logging into bugzilla...")); bz_server.login(Login.c_str(), Password.c_str()); if (bug_id > 0) @@ -458,12 +486,14 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, bz_server.add_plus_one_cc(bug_id, Login.c_str()); } bz_server.logout(); - return BugzillaURL + "/show_bug.cgi?id=" + to_string(bug_id); + BugzillaURL += "/show_bug.cgi?id="; + BugzillaURL += to_string(bug_id); + return BugzillaURL; } update_client(_("Creating new bug...")); - bug_id = bz_server.new_bug(pCrashReport); - bz_server.add_attachments(to_string(bug_id).c_str(), pCrashReport); + bug_id = bz_server.new_bug(pCrashData); + bz_server.add_attachments(to_string(bug_id).c_str(), pCrashData); update_client(_("Logging out...")); bz_server.logout(); @@ -475,12 +505,16 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, if (bug_id > 0) { - return BugzillaURL + "/show_bug.cgi?id=" + to_string(bug_id); + BugzillaURL += "/show_bug.cgi?id="; + BugzillaURL += to_string(bug_id); + return BugzillaURL; } - return BugzillaURL + "/show_bug.cgi?id="; + BugzillaURL += "/show_bug.cgi?id="; + return BugzillaURL; } +//todo: make static map_plugin_settings_t CReporterBugzilla::parse_settings(const map_plugin_settings_t& pSettings) { map_plugin_settings_t plugin_settings; diff --git a/lib/Plugins/Bugzilla.h b/lib/Plugins/Bugzilla.h index ee6bc6a5..571d0c60 100644 --- a/lib/Plugins/Bugzilla.h +++ b/lib/Plugins/Bugzilla.h @@ -20,7 +20,7 @@ class CReporterBugzilla : public CReporter CReporterBugzilla(); virtual ~CReporterBugzilla(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index ab29fbbe..5838bc45 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -40,10 +40,6 @@ using namespace std; #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" #define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u %c" -#define FILENAME_COREDUMP "coredump" -#define FILENAME_BACKTRACE "backtrace" -#define FILENAME_MEMORYMAP "memorymap" - #define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di" CAnalyzerCCpp::CAnalyzerCCpp() : @@ -233,7 +229,7 @@ static int rate_backtrace(const char *backtrace) } } - /* Bogus "backtrace" with zero frames? */ + /* Bogus 'backtrace' with zero frames? */ if (best_possible_rating == 0) return 0; @@ -421,9 +417,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir, char buff[1024]; while (fgets(buff, sizeof(buff), pipeout_fp)) { - int last = strlen(buff) - 1; - if (last >= 0 && buff[last] == '\n') - buff[last] = '\0'; + strchrnul(buff, '\n')[0] = '\0'; if (strncmp(buff, "MISSING:", 8) == 0) { diff --git a/lib/Plugins/Catcut.conf b/lib/Plugins/Catcut.conf index a0249fd1..858d1346 100644 --- a/lib/Plugins/Catcut.conf +++ b/lib/Plugins/Catcut.conf @@ -1,4 +1,5 @@ -Enabled=1 +Enabled = 0 + # Catcut URL CatcutURL = http://127.0.0.1:8080/catcut/xmlrpc # yes means that ssl certificates will not be checked @@ -7,4 +8,3 @@ NoSSLVerify = no Login = gavin # your password Password = junk -Enabled = yes
\ No newline at end of file diff --git a/lib/Plugins/Catcut.cpp b/lib/Plugins/Catcut.cpp index b69038fb..3580a3b4 100644 --- a/lib/Plugins/Catcut.cpp +++ b/lib/Plugins/Catcut.cpp @@ -215,13 +215,13 @@ struct ctx: public abrt_xmlrpc_conn { ctx(const char* url, bool no_ssl_verify): abrt_xmlrpc_conn(url, no_ssl_verify) {} string login(const char* login, const char* passwd); - string new_bug(const char *auth_cookie, const map_crash_report_t& pCrashReport); + string new_bug(const char *auth_cookie, const map_crash_data_t& pCrashData); string request_upload(const char* auth_cookie, const char* pTicketName, const char* fileName, const char* description); void add_attachments(const char* xmlrpc_URL, const char* auth_cookie, const char* pTicketName, - const map_crash_report_t& pCrashReport, + const map_crash_data_t& pCrashData, int retryCount, int retryDelaySeconds); }; @@ -263,21 +263,21 @@ ctx::login(const char* login, const char* passwd) } string -ctx::new_bug(const char *auth_cookie, const map_crash_report_t& pCrashReport) +ctx::new_bug(const char *auth_cookie, const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); - string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT]; - string arch = pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]; - string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const string& package = get_crash_data_item_content(pCrashData, FILENAME_PACKAGE); + const string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const string& release = get_crash_data_item_content(pCrashData, FILENAME_RELEASE); + const string& arch = get_crash_data_item_content(pCrashData, FILENAME_ARCHITECTURE); + const string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); string summary = "[abrt] crash in " + package; string status_whiteboard = "abrt_hash:" + uuid; - string description = make_description_catcut(pCrashReport); + string description = make_description_catcut(pCrashData); string product; string version; @@ -382,13 +382,13 @@ void ctx::add_attachments(const char* xmlrpc_URL, const char* auth_cookie, const char* pTicketName, - const map_crash_report_t& pCrashReport, + const map_crash_data_t& pCrashData, int retryCount, int retryDelaySeconds) { - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { if (it->second[CD_TYPE] == CD_TXT && it->second[CD_TYPE].size() > CD_TEXT_ATT_SIZE) { @@ -446,7 +446,7 @@ CReporterCatcut::CReporterCatcut() : CReporterCatcut::~CReporterCatcut() {} -string CReporterCatcut::Report(const map_crash_report_t& pCrashReport, +string CReporterCatcut::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -459,14 +459,14 @@ string CReporterCatcut::Report(const map_crash_report_t& pCrashReport, string message; if (auth_cookie != "") { - string ticket_name = catcut_server.new_bug(auth_cookie.c_str(), pCrashReport); + string ticket_name = catcut_server.new_bug(auth_cookie.c_str(), pCrashData); if (ticket_name != "") { catcut_server.add_attachments( m_sCatcutURL.c_str(), auth_cookie.c_str(), ticket_name.c_str(), - pCrashReport, + pCrashData, m_nRetryCount, m_nRetryDelay ); diff --git a/lib/Plugins/Catcut.h b/lib/Plugins/Catcut.h index 00f486c0..65c70444 100644 --- a/lib/Plugins/Catcut.h +++ b/lib/Plugins/Catcut.h @@ -20,7 +20,7 @@ class CReporterCatcut : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *Args); }; diff --git a/lib/Plugins/FileTransfer.conf b/lib/Plugins/FileTransfer.conf index c92eaeec..1ceccece 100644 --- a/lib/Plugins/FileTransfer.conf +++ b/lib/Plugins/FileTransfer.conf @@ -1,3 +1,5 @@ +Enabled = yes + # Configuration of the file transfer reporter plugin # it takes one parameter: # store - just save information about crash @@ -17,4 +19,3 @@ RetryCount = 3 #how long we wait between we retry the upload (in seconds) RetryDelay = 20 -Enabled = yes
\ No newline at end of file diff --git a/lib/Plugins/FileTransfer.cpp b/lib/Plugins/FileTransfer.cpp index b08ecd51..4d317c8d 100644 --- a/lib/Plugins/FileTransfer.cpp +++ b/lib/Plugins/FileTransfer.cpp @@ -22,15 +22,6 @@ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif -#include <iostream> -#include <sstream> -#include <fstream> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <zip.h> #include <libtar.h> #include <bzlib.h> @@ -66,22 +57,21 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename) update_client(_("Sending archive %s to %s"), pFilename, pURL); - string wholeURL = concat_path_file(pURL, pFilename); + string wholeURL = concat_path_file(pURL, strrchr(pFilename, '/') ? : pFilename); int count = m_nRetryCount; while (1) { - FILE *f; - struct stat buf; - CURL *curl; - - f = fopen(pFilename, "r"); + FILE *f = fopen(pFilename, "r"); if (!f) { throw CABRTException(EXCEP_PLUGIN, "Can't open archive file '%s'", pFilename); } + + struct stat buf; fstat(fileno(f), &buf); /* never fails */ - curl = xcurl_easy_init(); + + CURL *curl = xcurl_easy_init(); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ @@ -89,8 +79,10 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename) /* FILE handle: passed to the default callback, it will fread() it */ curl_easy_setopt(curl, CURLOPT_READDATA, f); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)buf.st_size); + /* everything is done here; result 0 means success */ int result = curl_easy_perform(curl); + curl_easy_cleanup(curl); fclose(f); if (result == 0 || --count <= 0) @@ -101,11 +93,9 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename) } /* -walks through the directory and applies a function with one -parameter "something" to each filename, -now used in create_zip, but can be useful for some future -archivers as well -*/ + * Walks through the directory and applies a function with one + * parameter "something" to each filename. + */ static void traverse_directory(const char *directory, void *something, void (*func)(void *, const char *)) { @@ -128,20 +118,26 @@ static void traverse_directory(const char *directory, void *something, closedir(dp); } -static void add_to_zip(void * z, const char * filename) +static void add_to_zip(void *z, const char *filename) { struct zip_source *s; - s = zip_source_file( (struct zip *)z, filename, 0, 0); - zip_add( (struct zip *)z, filename, s); + s = zip_source_file((struct zip *)z, filename, /*start:*/ 0, /*len:*/ 0); + if (s) + { + if (zip_add((struct zip *)z, filename, s) == -1) + { + zip_source_free(s); + } + /* else: don't call zip_source_free(s), successful zip_add consumes it */ + } } - -static void create_zip(const char * archive_name, const char * directory) +static void create_zip(const char *archive_name, const char *directory) { - struct zip * z; + struct zip *z; - z = zip_open(archive_name, ZIP_CREATE, NULL); + z = zip_open(archive_name, ZIP_CREATE, /*errorp:*/ NULL); if (z == NULL) { return; @@ -150,7 +146,7 @@ static void create_zip(const char * archive_name, const char * directory) zip_close(z); } -static void create_tar(const char * archive_name, const char * directory) +static void create_tar(const char *archive_name, const char *directory) { TAR *tar; @@ -162,89 +158,86 @@ static void create_tar(const char * archive_name, const char * directory) tar_close(tar); } -static void create_targz(const char * archive_name, const char * directory) +static void create_targz(const char *archive_name, const char *directory) { - char * name_without_gz; - char buf[BUFSIZ]; - FILE * f; - ssize_t bytesRead; - gzFile gz; - - name_without_gz = xstrdup(archive_name); + char *name_without_gz = xstrdup(archive_name); strrchr(name_without_gz, '.')[0] = '\0'; + create_tar(name_without_gz, directory); - f = fopen(name_without_gz, "r"); - if (f == NULL) + int fd = open(name_without_gz, O_RDONLY); + if (fd < 0) { -//TODO: we leak uncompressed tar file on disk?? + remove(name_without_gz); free(name_without_gz); return; } - gz = gzopen(archive_name, "w"); + + gzFile gz = gzopen(archive_name, "w"); if (gz == NULL) { - fclose(f); + close(fd); + remove(name_without_gz); free(name_without_gz); return; } - while ((bytesRead = fread(buf, 1, BUFSIZ, f)) > 0) + char buf[BUFSIZ]; + ssize_t bytesRead; + while ((bytesRead = full_read(fd, buf, BUFSIZ)) > 0) { - gzwrite(gz, buf, bytesRead); + gzwrite(gz, buf, bytesRead); // TODO: check that return value == bytesRead } + gzclose(gz); - fclose(f); + close(fd); remove(name_without_gz); free(name_without_gz); } static void create_tarbz2(const char * archive_name, const char * directory) { - char * name_without_bz2; - char buf[BUFSIZ]; - FILE * f; - ssize_t bytesRead; - int tarFD; - int bzError; - BZFILE * bz; -#define BLOCK_MULTIPLIER 7 - - name_without_bz2 = xstrdup(archive_name); + char *name_without_bz2 = xstrdup(archive_name); strrchr(name_without_bz2, '.')[0] = '\0'; + create_tar(name_without_bz2, directory); - tarFD = open(name_without_bz2, O_RDONLY); + int tarFD = open(name_without_bz2, O_RDONLY); if (tarFD == -1) { + remove(name_without_bz2); free(name_without_bz2); return; } - f = fopen(archive_name, "w"); + FILE *f = fopen(archive_name, "w"); if (f == NULL) { -//TODO: we leak uncompressed tar file on disk?? close(tarFD); + remove(name_without_bz2); free(name_without_bz2); return; } - bz = BZ2_bzWriteOpen(&bzError, f, BLOCK_MULTIPLIER, 0, 0); + int bzError; + BZFILE *bz = BZ2_bzWriteOpen(&bzError, f, /*BLOCK_MULTIPLIER:*/ 7, 0, 0); if (bz == NULL) { - close(tarFD); fclose(f); + close(tarFD); + remove(name_without_bz2); free(name_without_bz2); return; } + char buf[BUFSIZ]; + ssize_t bytesRead; while ((bytesRead = read(tarFD, buf, BUFSIZ)) > 0) { BZ2_bzWrite(&bzError, bz, buf, bytesRead); } - BZ2_bzWriteClose(&bzError, bz, 0, NULL, NULL); - close(tarFD); + BZ2_bzWriteClose(&bzError, bz, 0, NULL, NULL); fclose(f); + close(tarFD); remove(name_without_bz2); free(name_without_bz2); } @@ -295,23 +288,31 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs) { update_client(_("File Transfer: Creating a report...")); + if (strcmp(pArgs, "store") == 0) + { + /* Remember pActiveDir for later sending */ + FILE *dirlist = fopen(FILETRANSFER_DIRLIST, "a"); + fprintf(dirlist, "%s\n", pActionDir); + fclose(dirlist); + VERB3 log("Remembered '%s' for future file transfer", pActionDir); + return; + } + char hostname[HBLEN]; gethostname(hostname, HBLEN-1); hostname[HBLEN-1] = '\0'; - fstream dirlist; - if (strcmp(pArgs, "store") == 0) + char tmpdir_name[] = "/tmp/abrtuploadXXXXXX"; + /* mkdtemp does mkdir(xxx, 0700), should be safe (is it?) */ + if (mkdtemp(tmpdir_name) == NULL) { - /* store pActiveDir for later sending */ - dirlist.open(FILETRANSFER_DIRLIST, fstream::out | fstream::app); - dirlist << pActionDir << endl; - dirlist.close(); + throw CABRTException(EXCEP_PLUGIN, "Can't mkdir a temporary directory in /tmp"); } - else if (strcmp(pArgs, "one") == 0) + + if (strcmp(pArgs, "one") == 0) { - /* just send one archive */ -//TODO: where are we creating it??!! In cwd, which may well be / ??!!! - string archivename = ssprintf("%s-%s%s", hostname, DirBase(pActionDir).c_str(), m_sArchiveType.c_str()); + /* Just send one archive */ + string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname, DirBase(pActionDir).c_str(), m_sArchiveType.c_str()); try { CreateArchive(archivename.c_str(), pActionDir); @@ -325,35 +326,43 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs) } else { - dirlist.open(FILETRANSFER_DIRLIST, fstream::in); - if (dirlist.fail()) + /* Tar up and send all remebered directories */ + FILE *dirlist = fopen(FILETRANSFER_DIRLIST, "r"); + if (!dirlist) { - /* this means there are no reports to send (no crashes, hurray) - which is perfectly OK */ - return; + /* not an error */ + VERB3 log("No saved crashes to transfer"); + goto del_tmp_dir; } - string dirname; - while (getline(dirlist, dirname), dirlist.good()) + char dirname[PATH_MAX]; + while (fgets(dirname, sizeof(dirname), dirlist) != NULL) { - string archivename = ssprintf("%s-%s%s", hostname, DirBase(dirname.c_str()).c_str(), m_sArchiveType.c_str()); + strchrnul(dirname, '\n')[0] = '\0'; + string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname, DirBase(dirname).c_str(), m_sArchiveType.c_str()); try { - CreateArchive(archivename.c_str(), dirname.c_str()); + VERB3 log("Creating archive '%s' of dir '%s'", archivename.c_str(), dirname); + CreateArchive(archivename.c_str(), dirname); + VERB3 log("Sending archive to '%s'", m_sURL.c_str()); SendFile(m_sURL.c_str(), archivename.c_str()); } catch (CABRTException& e) { error_msg(_("Can't create and send an archive %s"), e.what()); } + VERB3 log("Deleting archive '%s'", archivename.c_str()); unlink(archivename.c_str()); } - dirlist.close(); + fclose(dirlist); /* all the files we're able to send should be sent now, starting over with clean table */ unlink(FILETRANSFER_DIRLIST); } + + del_tmp_dir: + rmdir(tmpdir_name); } void CFileTransfer::SetSettings(const map_plugin_settings_t& pSettings) @@ -367,10 +376,6 @@ void CFileTransfer::SetSettings(const map_plugin_settings_t& pSettings) { m_sURL = it->second; } - else - { - error_msg(_("FileTransfer: URL not specified")); - } it = pSettings.find("RetryCount"); if (it != end) diff --git a/lib/Plugins/Firefox.cpp b/lib/Plugins/Firefox.cpp index d9807556..98d892b7 100644 --- a/lib/Plugins/Firefox.cpp +++ b/lib/Plugins/Firefox.cpp @@ -36,10 +36,6 @@ #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" #define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u" -#define FILENAME_COREDUMP "coredump" -#define FILENAME_BACKTRACE "backtrace" -#define FILENAME_MEMORYMAP "memorymap" - #define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di" CAnalyzerFirefox::CAnalyzerFirefox() : @@ -227,7 +223,7 @@ static int rate_backtrace(const char *backtrace) } } - /* Bogus "backtrace" with zero frames? */ + /* Bogus 'backtrace' with zero frames? */ if (best_possible_rating == 0) return 0; @@ -627,9 +623,7 @@ Another application is holding the yum lock, cannot continue 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'; + strchrnul(buff, '\n')[0] = '\0'; log("%s", buff); update_client("%s", buff); /* maybe only if buff != ""? */ @@ -716,9 +710,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids) char buff[1024]; while (fgets(buff, sizeof(buff), pipeout_fp)) { - int last = strlen(buff) - 1; - if (last >= 0 && buff[last] == '\n') - buff[last] = '\0'; + strchrnul(buff, '\n')[0] = '\0'; if (strncmp(buff, "MISSING:", 8) == 0) { diff --git a/lib/Plugins/Kerneloops.conf b/lib/Plugins/Kerneloops.conf index 1db2436f..4d6bd469 100644 --- a/lib/Plugins/Kerneloops.conf +++ b/lib/Plugins/Kerneloops.conf @@ -1,3 +1,5 @@ +Enabled = yes + # Do we want kernel oopses to be visible to any user? # Set to "yes" for compatibility with kerneloops.org tool. InformAllUsers = yes @@ -15,4 +17,3 @@ SysLogFile = /var/log/messages # KerneloopsReporter configuration ################################## SubmitURL = http://submit.kerneloops.org/submitoops.php -Enabled = yes
\ No newline at end of file diff --git a/lib/Plugins/Kerneloops.cpp b/lib/Plugins/Kerneloops.cpp index 2e28cf4a..bcb7a723 100644 --- a/lib/Plugins/Kerneloops.cpp +++ b/lib/Plugins/Kerneloops.cpp @@ -30,8 +30,6 @@ #include "ABRTException.h" #include "CommLayerInner.h" -#define FILENAME_KERNELOOPS "kerneloops" - std::string CAnalyzerKerneloops::GetLocalUUID(const char *pDebugDumpDir) { log(_("Getting local universal unique identification")); diff --git a/lib/Plugins/KerneloopsReporter.cpp b/lib/Plugins/KerneloopsReporter.cpp index 5cb525bc..18932aea 100644 --- a/lib/Plugins/KerneloopsReporter.cpp +++ b/lib/Plugins/KerneloopsReporter.cpp @@ -30,8 +30,6 @@ #include "CommLayerInner.h" #include "ABRTException.h" -#define FILENAME_KERNELOOPS "kerneloops" - /* helpers */ static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) { @@ -93,7 +91,7 @@ CKerneloopsReporter::CKerneloopsReporter() : m_sSubmitURL("http://submit.kerneloops.org/submitoops.php") {} -std::string CKerneloopsReporter::Report(const map_crash_report_t& pCrashReport, +std::string CKerneloopsReporter::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -101,8 +99,8 @@ std::string CKerneloopsReporter::Report(const map_crash_report_t& pCrashReport, update_client(_("Creating and submitting a report...")); - map_crash_report_t::const_iterator it = pCrashReport.find(FILENAME_KERNELOOPS); - if (it != pCrashReport.end()) { + map_crash_data_t::const_iterator it = pCrashData.find(FILENAME_KERNELOOPS); + if (it != pCrashData.end()) { ret = http_post_to_kerneloops_site( m_sSubmitURL.c_str(), it->second[CD_CONTENT].c_str() diff --git a/lib/Plugins/KerneloopsReporter.h b/lib/Plugins/KerneloopsReporter.h index 10e5e644..91326526 100644 --- a/lib/Plugins/KerneloopsReporter.h +++ b/lib/Plugins/KerneloopsReporter.h @@ -43,7 +43,7 @@ class CKerneloopsReporter : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; diff --git a/lib/Plugins/KerneloopsScanner.cpp b/lib/Plugins/KerneloopsScanner.cpp index 1bb45aba..42ffd409 100644 --- a/lib/Plugins/KerneloopsScanner.cpp +++ b/lib/Plugins/KerneloopsScanner.cpp @@ -34,10 +34,6 @@ #include "KerneloopsSysLog.h" #include "KerneloopsScanner.h" -#include <limits.h> - -#define FILENAME_KERNELOOPS "kerneloops" - // TODO: https://fedorahosted.org/abrt/ticket/78 CKerneloopsScanner::CKerneloopsScanner() @@ -54,8 +50,7 @@ void CKerneloopsScanner::Run(const char *pActionDir, const char *pArgs) { const char *syslog_file = "/var/log/messages"; map_plugin_settings_t::const_iterator it = m_pSettings.find("SysLogFile"); - if (it != m_pSettings.end()) - { + if (it != m_pSettings.end()) { syslog_file = it->second.c_str(); } @@ -205,4 +200,4 @@ void save_oops_to_debug_dump(CKerneloopsScanner *This) This->SaveOopsToDebugDump(); } -} +} /* extern "C" */ diff --git a/lib/Plugins/Logger.conf b/lib/Plugins/Logger.conf index 8809963c..f96c5b80 100644 --- a/lib/Plugins/Logger.conf +++ b/lib/Plugins/Logger.conf @@ -1,6 +1,6 @@ # Configuration for Logger plugin +Enabled = yes LogPath = /var/log/abrt.log AppendLogs = yes -Enabled = yes diff --git a/lib/Plugins/Logger.cpp b/lib/Plugins/Logger.cpp index d6cc124e..f428aec5 100644 --- a/lib/Plugins/Logger.cpp +++ b/lib/Plugins/Logger.cpp @@ -59,12 +59,12 @@ void CLogger::SetSettings(const map_plugin_settings_t& pSettings) // return m_pSettings; //} -std::string CLogger::Report(const map_crash_report_t& pCrashReport, +std::string CLogger::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { - std::string description = make_description_logger(pCrashReport); + std::string description = make_description_logger(pCrashData); description += "\n\n\n"; FILE *fOut; diff --git a/lib/Plugins/Logger.h b/lib/Plugins/Logger.h index c7d76798..02429b2c 100644 --- a/lib/Plugins/Logger.h +++ b/lib/Plugins/Logger.h @@ -1,6 +1,6 @@ /* Logger.h - header file for Logger reporter plugin - - it simple writes report to specific file + - it simply writes report to specific file Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) Copyright (C) 2009 RedHat inc. @@ -37,7 +37,7 @@ class CLogger : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; diff --git a/lib/Plugins/Mailx.conf b/lib/Plugins/Mailx.conf index de19709f..ccd14292 100644 --- a/lib/Plugins/Mailx.conf +++ b/lib/Plugins/Mailx.conf @@ -1,8 +1,8 @@ # Configuration to Email reporter plugin -# it takes one parameter: subject in "", if it isn't specified, then a default -# subject is taken +Enabled = yes -# Subject of an emain +# In abrt.conf, plugin takes one parameter: subject (in "" if you need to embed spaces). +# If it isn't specified, then a default subject is taken from this file Subject = "[abrt] crash report" # Your Email @@ -13,4 +13,3 @@ EmailTo = root@localhost # Warning! enabling this may cause sending a lot of MB via email SendBinaryData = no -Enabled = yes
\ No newline at end of file diff --git a/lib/Plugins/Mailx.cpp b/lib/Plugins/Mailx.cpp index 2f8448f5..2ee96455 100644 --- a/lib/Plugins/Mailx.cpp +++ b/lib/Plugins/Mailx.cpp @@ -65,7 +65,7 @@ static char** append_str_to_vector(char **vec, unsigned &size, const char *str) return vec; } -std::string CMailx::Report(const map_crash_report_t& pCrashReport, +std::string CMailx::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -74,13 +74,13 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, args = append_str_to_vector(args, arg_size, MAILX_COMMAND); //TODO: move email body generation to make_descr.cpp - std::string binaryFiles, commonFiles, additionalFiles, UUIDFile; - map_crash_report_t::const_iterator it; - for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + std::string binaryFiles, commonFiles, additionalFiles, DUPHASHFile; + map_crash_data_t::const_iterator it; + for (it = pCrashData.begin(); it != pCrashData.end(); it++) { if (it->second[CD_TYPE] == CD_TXT) { - if (it->first != CD_UUID + if (it->first != CD_DUPHASH && it->first != FILENAME_ARCHITECTURE && it->first != FILENAME_KERNEL && it->first != FILENAME_PACKAGE @@ -90,12 +90,12 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, additionalFiles += it->second[CD_CONTENT]; additionalFiles += "\n\n"; } - else if (it->first == CD_UUID) + else if (it->first == CD_DUPHASH) { - UUIDFile += it->first; - UUIDFile += "\n-----\n"; - UUIDFile += it->second[CD_CONTENT]; - UUIDFile += "\n\n"; + DUPHASHFile += it->first; + DUPHASHFile += "\n-----\n"; + DUPHASHFile += it->second[CD_CONTENT]; + DUPHASHFile += "\n\n"; } else { @@ -117,9 +117,9 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, } } - std::string emailBody = "Duplicity check\n"; + std::string emailBody = "Duplicate check\n"; emailBody += "=====\n\n"; - emailBody += UUIDFile; + emailBody += DUPHASHFile; emailBody += "\nCommon information\n"; emailBody += "=====\n\n"; emailBody += commonFiles; @@ -135,7 +135,7 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, args = append_str_to_vector(args, arg_size, m_sEmailTo.c_str()); update_client(_("Sending an email...")); - const char *uid_str = pCrashReport.find(CD_MWUID)->second[CD_CONTENT].c_str(); + const char *uid_str = get_crash_data_item_content(pCrashData, FILENAME_UID).c_str(); exec_and_feed_input(xatoi_u(uid_str), emailBody.c_str(), args); while (*args) diff --git a/lib/Plugins/Mailx.h b/lib/Plugins/Mailx.h index 1ddb5ff0..619e349c 100644 --- a/lib/Plugins/Mailx.h +++ b/lib/Plugins/Mailx.h @@ -41,7 +41,7 @@ class CMailx : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; diff --git a/lib/Plugins/Python.conf b/lib/Plugins/Python.conf index 75d22298..3201c6da 100644 --- a/lib/Plugins/Python.conf +++ b/lib/Plugins/Python.conf @@ -1 +1 @@ -Enabled = yes
\ No newline at end of file +Enabled = yes diff --git a/lib/Plugins/Python.cpp b/lib/Plugins/Python.cpp index 23d6f5c0..ad954681 100644 --- a/lib/Plugins/Python.cpp +++ b/lib/Plugins/Python.cpp @@ -1,15 +1,14 @@ +#include "abrtlib.h" #include "Python.h" #include "DebugDump.h" #include "ABRTException.h" -#define FILENAME_BACKTRACE "backtrace" - static std::string CreateHash(const char *pDebugDumpDir) { - std::string uuid; CDebugDump dd; dd.Open(pDebugDumpDir); - dd.LoadText("uuid", uuid); + std::string uuid; + dd.LoadText(FILENAME_UUID, uuid); return uuid; } diff --git a/lib/Plugins/RunApp.cpp b/lib/Plugins/RunApp.cpp index e2147e26..77f5d3c8 100644 --- a/lib/Plugins/RunApp.cpp +++ b/lib/Plugins/RunApp.cpp @@ -19,7 +19,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - +#include "abrtlib.h" #include "RunApp.h" #include "DebugDump.h" #include "ABRTException.h" diff --git a/lib/Plugins/TicketUploader.conf b/lib/Plugins/TicketUploader.conf index ad5f6d28..b6e9c5f3 100644 --- a/lib/Plugins/TicketUploader.conf +++ b/lib/Plugins/TicketUploader.conf @@ -1,5 +1,3 @@ - - # Customer = "Example Inc." # Ticket = IT12345 # Encrypt = yes @@ -16,7 +14,3 @@ #how long we wait between we retry the upload (in seconds) #RetryDelay = 20 - - - - diff --git a/lib/Plugins/TicketUploader.cpp b/lib/Plugins/TicketUploader.cpp index 7483768d..c85a329b 100644 --- a/lib/Plugins/TicketUploader.cpp +++ b/lib/Plugins/TicketUploader.cpp @@ -18,8 +18,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <string> -#include <fstream> -#include <sstream> #include "abrtlib.h" #include "abrt_xmlrpc.h" /* for xcurl_easy_init */ #include "TicketUploader.h" @@ -41,18 +39,12 @@ CTicketUploader::~CTicketUploader() {} -static void Error(const char *msg) -{ - update_client("%s", msg); - throw CABRTException(EXCEP_PLUGIN, msg); -} - static void RunCommand(const char *cmd) { int retcode = system(cmd); if (retcode) { - Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str()); + throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode); } } @@ -61,20 +53,21 @@ static string ReadCommand(const char *cmd) FILE* fp = popen(cmd, "r"); if (!fp) { - Error(ssprintf("error running '%s'", cmd).c_str()); + throw CABRTException(EXCEP_PLUGIN, "Error running '%s'", cmd); } string result; char buff[1024]; while (fgets(buff, sizeof(buff), fp) != NULL) { + strchrnul(buff, '\n')[0] = '\0'; result += buff; } int retcode = pclose(fp); if (retcode) { - Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str()); + throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode); } return result; @@ -85,7 +78,7 @@ static void WriteCommand(const char *cmd, const char *input) FILE* fp = popen(cmd, "w"); if (!fp) { - Error(ssprintf("error running '%s'", cmd).c_str()); + throw CABRTException(EXCEP_PLUGIN, "error running '%s'", cmd); } /* Hoping it's not too big to get us forever blocked... */ @@ -94,11 +87,11 @@ static void WriteCommand(const char *cmd, const char *input) int retcode = pclose(fp); if (retcode) { - Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str()); + throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode); } } -void CTicketUploader::SendFile(const char *pURL, const char *pFilename) +void CTicketUploader::SendFile(const char *pURL, const char *pFilename, int retry_count, int retry_delay) { if (pURL[0] == '\0') { @@ -110,7 +103,7 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) const char *base = (strrchr(pFilename, '/') ? : pFilename-1) + 1; string wholeURL = concat_path_file(pURL, base); - int count = m_nRetryCount; + int count = retry_count; int result; while (1) { @@ -140,7 +133,7 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) if (result == 0 || --count <= 0) break; /* retry the upload if not succesful, wait a bit before next try */ - sleep(m_nRetryDelay); + sleep(retry_delay); } if (count <= 0 && result != 0) @@ -150,78 +143,101 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) } -string CTicketUploader::Report(const map_crash_report_t& pCrashReport, +static void write_str_to_file(const char *str, const char *path, const char *fname) +{ + string ofile_name = concat_path_file(path, fname); + FILE *ofile = fopen(ofile_name.c_str(), "w"); + if (!ofile) + { + throw CABRTException(EXCEP_PLUGIN, "Can't open '%s'", ofile_name.c_str()); + } + fprintf(ofile, "%s\n", str); + fclose(ofile); +} + +string CTicketUploader::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { - update_client(_("Creating an TicketUploader report...")); - + string customer_name; + string ticket_name; + string upload_url; + bool do_encrypt; + bool do_upload; + int retry_count; + int retry_delay; + + /* if parse_settings fails it returns an empty map so we need to use defaults */ + map_plugin_settings_t settings = parse_settings(pSettings); // Get ticket name, customer name, and do_encrypt from config settings - string customer_name = m_sCustomer; - string ticket_name = m_sTicket; - string upload_url = m_sURL; - bool do_encrypt = m_bEncrypt; - bool do_upload = m_bUpload; - - bool have_ticket_name = false; - if (ticket_name == "") + if (!settings.empty()) { - ticket_name = "TicketUploader-newticket"; + customer_name = settings["Customer"]; + ticket_name = settings["Ticket"]; + upload_url = settings["URL"]; + do_encrypt = string_to_bool(settings["Encrypt"].c_str()); + do_upload = string_to_bool(settings["Upload"].c_str()); + retry_count = xatoi_u(settings["RetryCount"].c_str()); + retry_delay = xatoi_u(settings["RetryDelay"].c_str()); } else { - have_ticket_name = true; + customer_name = m_sCustomer; + ticket_name = m_sTicket; + upload_url = m_sURL; + do_encrypt = m_bEncrypt; + do_upload = m_bUpload; + retry_count = m_nRetryCount; + retry_delay = m_nRetryDelay; } + update_client(_("Creating an TicketUploader report...")); - // Format the time to add to the file name - const int timebufmax = 256; - char timebuf[timebufmax]; - time_t curtime = time(NULL); - if (!strftime(timebuf, timebufmax, "-%G%m%d%k%M%S", gmtime(&curtime))) + bool have_ticket_name = (ticket_name != ""); + if (!have_ticket_name) { - Error("Can't format time"); + ticket_name = "TicketUploader-newticket"; } - // Create a tmp work directory, and within that the directory - // that will be the root of the tarball + // Format the time to add to the file name + char timebuf[256]; + time_t curtime = time(NULL); + strftime(timebuf, sizeof(timebuf), "-%Y%m%d%H%M%S", gmtime(&curtime)); + + // Create a tmp work directory, and within that + // create the "<ticketname>-yyyymmddhhmmss" directory + // which will be the root of the tarball string file_name = ticket_name + timebuf; - char tmpdir_name[] = "/tmp/rhuploadXXXXXX"; + char tmpdir_name[] = "/tmp/abrtuploadXXXXXX"; if (mkdtemp(tmpdir_name) == NULL) { - Error("Can't mkdir a temporary directory in /tmp"); + throw CABRTException(EXCEP_PLUGIN, "Can't mkdir a temporary directory in /tmp"); } string tmptar_name = concat_path_file(tmpdir_name, file_name.c_str()); - if (mkdir(tmptar_name.c_str(), S_IRWXU)) + if (mkdir(tmptar_name.c_str(), 0700)) { - Error(ssprintf("Can't mkdir '%s'", tmptar_name.c_str()).c_str()); + throw CABRTException(EXCEP_PLUGIN, "Can't mkdir '%s'", tmptar_name.c_str()); } - // Copy each entry into the tarball root, - // files are simply copied, strings are written to a file - map_crash_report_t::const_iterator it; - for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + // Copy each entry into the tarball root. + // Files are simply copied, strings are written to a file + map_crash_data_t::const_iterator it; + for (it = pCrashData.begin(); it != pCrashData.end(); it++) { + const char *content = it->second[CD_CONTENT].c_str(); if (it->second[CD_TYPE] == CD_TXT) { - string ofile_name = concat_path_file(tmptar_name.c_str(), it->first.c_str()); - ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary); - if (!ofile) - { - Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str()); - } - ofile << it->second[CD_CONTENT] << endl; - ofile.close(); + write_str_to_file(content, tmptar_name.c_str(), it->first.c_str()); } else if (it->second[CD_TYPE] == CD_BIN) { string ofile_name = concat_path_file(tmptar_name.c_str(), it->first.c_str()); - if (copy_file(it->second[CD_CONTENT].c_str(), ofile_name.c_str(), 0644) < 0) + if (copy_file(content, ofile_name.c_str(), 0644) < 0) { throw CABRTException(EXCEP_PLUGIN, "Can't copy '%s' to '%s'", - it->second[CD_CONTENT].c_str(), + content, ofile_name.c_str() ); } @@ -231,25 +247,11 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, // add ticket_name and customer name to tarball if (have_ticket_name) { - string ofile_name = tmptar_name + "/TICKET"; - ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary); - if (!ofile) - { - Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str()); - } - ofile << ticket_name << endl; - ofile.close(); + write_str_to_file(ticket_name.c_str(), tmptar_name.c_str(), "TICKET"); } if (customer_name != "") { - string ofile_name = tmptar_name + "/CUSTOMER"; - ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary); - if (!ofile) - { - Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str()); - } - ofile << customer_name << endl; - ofile.close(); + write_str_to_file(customer_name.c_str(), tmptar_name.c_str(), "CUSTOMER"); } // Create the compressed tarball @@ -280,7 +282,7 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, if (do_upload) { // FIXME: SendFile isn't working sometime (scp) - SendFile(upload_url.c_str(), outfile_name.c_str()); + SendFile(upload_url.c_str(), outfile_name.c_str(), retry_count, retry_delay); } else { @@ -328,21 +330,19 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, } msg += "END:\n"; - /* warn the client: */ + // warn the client (why _warn_? it's not an error, maybe update_client?): error_msg("%s", msg.c_str()); string ret; if (do_upload) { - string xx = _("report sent to ") + upload_url + '/' + outfile_basename; - update_client("%s", xx.c_str()); - ret = xx; + ret = _("report sent to ") + upload_url + '/' + outfile_basename; + update_client("%s", ret.c_str()); } else { - string xx = _("report copied to /tmp/") + outfile_basename; - update_client("%s", xx.c_str()); - ret = xx; + ret = _("report copied to /tmp/") + outfile_basename; + update_client("%s", ret.c_str()); } // delete the temporary directory @@ -352,6 +352,28 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, return ret; } +static bool is_string_safe(const char *str) +{ + const char *p = str; + while (*p) + { + unsigned char c = *p; + if ((c < '0' || c > '9') + && c != '_' + && c != '-' + ) { + c |= 0x20; // tolower + if (c < 'a' || c > 'z') + { + return false; + } + } + // only 0-9, -, _, A-Z, a-z reach this point + p++; + } + return true; +} + void CTicketUploader::SetSettings(const map_plugin_settings_t& pSettings) { m_pSettings = pSettings; @@ -363,8 +385,11 @@ void CTicketUploader::SetSettings(const map_plugin_settings_t& pSettings) { m_sCustomer = it->second; } + // We use m_sTicket as part of filename, + // and we use resulting filename in system("cd %s; ...", filename) etc, + // so we are very paraniod about allowed chars it = pSettings.find("Ticket"); - if (it != end) + if (it != end && is_string_safe(it->second.c_str())) { m_sTicket = it->second; } @@ -401,13 +426,81 @@ const map_plugin_settings_t& CTicketUploader::GetSettings() m_pSettings["Ticket"] = m_sTicket; m_pSettings["URL"] = m_sURL; m_pSettings["Encrypt"] = m_bEncrypt ? "yes" : "no"; - m_pSettings["Upload"] = m_bEncrypt ? "yes" : "no"; + m_pSettings["Upload"] = m_bUpload ? "yes" : "no"; m_pSettings["RetryCount"] = to_string(m_nRetryCount); m_pSettings["RetryDelay"] = to_string(m_nRetryDelay); return m_pSettings; } +//todo: make static +map_plugin_settings_t CTicketUploader::parse_settings(const map_plugin_settings_t& pSettings) +{ + map_plugin_settings_t plugin_settings; + + map_plugin_settings_t::const_iterator end = pSettings.end(); + map_plugin_settings_t::const_iterator it; + + it = pSettings.find("Customer"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Customer"] = it->second; + + it = pSettings.find("Ticket"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Ticket"] = it->second; + + it = pSettings.find("URL"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["URL"] = it->second; + + it = pSettings.find("Encrypt"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Encrypt"] = it->second; + + it = pSettings.find("Upload"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Upload"] = it->second; + + it = pSettings.find("RetryCount"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["RetryCount"] = it->second; + + it = pSettings.find("RetryDelay"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["RetryDelay"] = it->second; + + VERB1 log("User settings ok, using them instead of defaults"); + return plugin_settings; +} + PLUGIN_INFO(REPORTER, CTicketUploader, "TicketUploader", diff --git a/lib/Plugins/TicketUploader.h b/lib/Plugins/TicketUploader.h index 1bc8f6ba..a719d0bd 100644 --- a/lib/Plugins/TicketUploader.h +++ b/lib/Plugins/TicketUploader.h @@ -27,7 +27,6 @@ #include "Plugin.h" #include "Reporter.h" -//#include "CrashTypes.h" class CTicketUploader : public CReporter { @@ -40,7 +39,8 @@ class CTicketUploader : public CReporter int m_nRetryCount; int m_nRetryDelay; - void SendFile(const char *pURL, const char *pFilename); + void SendFile(const char *pURL, const char *pFilename, int retry_count, int retry_delay); + map_plugin_settings_t parse_settings(const map_plugin_settings_t& pSettings); public: CTicketUploader(); @@ -48,7 +48,7 @@ class CTicketUploader : public CReporter virtual const map_plugin_settings_t& GetSettings(); virtual void SetSettings(const map_plugin_settings_t& pSettings); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; diff --git a/lib/Plugins/abrt-FileTransfer.7 b/lib/Plugins/abrt-FileTransfer.7 index 132bfcde..a721dd81 100644 --- a/lib/Plugins/abrt-FileTransfer.7 +++ b/lib/Plugins/abrt-FileTransfer.7 @@ -18,24 +18,17 @@ The plugin is invoked in the \fIabrt.conf\fP file, usually in the \fIActionsAndReporters\fP option and/or the \fI[cron]\fP section. There are two modes of invocation: .P -* If you use the parameter -\fI"store"\fP, the plugin stores a record of the occurrence of -the crash in its internal list. +* Specify \fIFileTransfer(one)\fP in ActionsAndReporters directive. +Immediately after crash is detected, the plugin transfers crash data +to the server specified in the \fIFileTransfer.conf\fP configuration file. .P -* If you use the parameter -\fI"one"\fP, the plugin will transfer this specific crash, -on which it was invoked, without storing it in the internal -list. -.P -* If you use some other parameter, or no parameter at all, the -plugin will iterate through the internal list and will send -every recorded crash to the server specified in the \fIFileTransfer.conf\fP -configuration file. After that, the internal list is cleared. -.P -On a production machine, you probably do not want the daemon to send crash -data at times that the machine is busy working. This second mode allows you -to send crash reports at a quieter time (at night, perhaps) that you -schedule in the \fI[cron]\fP section of \fIabrt.conf\fP. +* Specify \fIFileTransfer(store)\fP in ActionsAndReporters directive +and add \fIHH:MM = FileTransfer\fP line in [cron] section. +At the time of the crash, +the plugin stores a record of it in its internal list. +When specified time is reached, the plugin iterates through +its internal list and sends every recorded crash to the specified URL. +After that, the internal list is cleared. .SH CONFIGURATION The \fIFileTransfer.conf\fP configuration file contains several entries in the format "Option = Value". The options are: @@ -48,24 +41,16 @@ URL = ftp://user:passwd@server.com/path .SS ArchiveType The type of the archive in which to pack the crash data. Currently, \fI.tar\fP, \fI.tar.gz\fP, \fI.tar.bz2\fP and \fI.zip\fP -are supported. -The plugin uses archive creation libraries for this. -The default is -.br -ArchiveType = .tar.gz +are supported. The default is \fI.tar.gz\fP .SS RetryCount This specifies how many times the plugin will try to resend the file if the transfer was not succesful. The plugin -waits a while before it retries the transfer: see \fIRetryDelay\fP -The default is -.br -RetryCount = 3 +waits a while before it retries the transfer: see \fIRetryDelay\fP. +The default is 3 .SS RetryDelay If the transfer was not succesful, the plugin will wait some time before sending the file again. This configuration -option specifies the time in seconds. The default is -.br -RetryDelay = 20 +option specifies the time in seconds. The default is 20. .SH EXAMPLES .P Typical configuration in \fIabrt.conf\fP. The crash is stored @@ -74,7 +59,7 @@ is transferred to a central server. .P [common] .br -ActionsAndReporters = FileTransfer("store") +ActionsAndReporters = FileTransfer(store) .br [cron] .br diff --git a/lib/Utils/CrashTypes.cpp b/lib/Utils/CrashTypes.cpp new file mode 100644 index 00000000..4fc93337 --- /dev/null +++ b/lib/Utils/CrashTypes.cpp @@ -0,0 +1,132 @@ +/* + Copyright (C) 2010 Denys Vlasenko (dvlasenk@redhat.com) + Copyright (C) 2010 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 "abrt_types.h" +#include "abrtlib.h" +#include "CrashTypes.h" + +const char *const must_have_files[] = { + FILENAME_ARCHITECTURE, + FILENAME_KERNEL , + FILENAME_PACKAGE , + FILENAME_COMPONENT , + FILENAME_RELEASE , + FILENAME_EXECUTABLE , + NULL +}; + +static const char *const editable_files[] = { + FILENAME_DESCRIPTION, + FILENAME_COMMENT , + FILENAME_REPRODUCE , + FILENAME_BACKTRACE , + NULL +}; + +static bool is_editable(const char *name, const char *const *v) +{ + while (*v) { + if (strcmp(*v, name) == 0) + return true; + v++; + } + return false; +} + +bool is_editable_file(const char *file_name) +{ + return is_editable(file_name, editable_files); +} + + +void add_to_crash_data_ext(map_crash_data_t& pCrashData, + const char *pItem, + const char *pType, + const char *pEditable, + const char *pContent) +{ + map_crash_data_t::iterator it = pCrashData.find(pItem); + if (it == pCrashData.end()) { + vector_string_t& v = pCrashData[pItem]; /* create empty vector */ + v.push_back(pType); + v.push_back(pEditable); + v.push_back(pContent); + return; + } + vector_string_t& v = it->second; + while (v.size() < 3) + v.push_back(""); + v[CD_TYPE] = pType; + v[CD_EDITABLE] = pEditable; + v[CD_CONTENT] = pContent; +} + +void add_to_crash_data(map_crash_data_t& pCrashData, + const char *pItem, + const char *pContent) +{ + add_to_crash_data_ext(pCrashData, pItem, CD_TXT, CD_ISNOTEDITABLE, pContent); +} + +static const std::string* helper_get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) +{ + map_crash_data_t::const_iterator it = crash_data.find(key); + if (it == crash_data.end()) { + return NULL; + } + if (it->second.size() <= CD_CONTENT) { + return NULL; + } + return &it->second[CD_CONTENT]; +} + +const std::string& get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) +{ + const std::string* sp = helper_get_crash_data_item_content(crash_data, key); + if (sp == NULL) { + if (crash_data.find(key) == crash_data.end()) + error_msg_and_die("Error accessing crash data: no ['%s']", key); + error_msg_and_die("Error accessing crash data: no ['%s'][%d]", key, CD_CONTENT); + } + return *sp; +} + +const char *get_crash_data_item_content_or_NULL(const map_crash_data_t& crash_data, const char *key) +{ + const std::string* sp = helper_get_crash_data_item_content(crash_data, key); + if (!sp) { + return NULL; + } + return sp->c_str(); +} + +void log_map_crash_data(const map_crash_data_t& data, const char *name) +{ + map_crash_data_t::const_iterator it = data.begin(); + while (it != data.end()) + { + ssize_t sz = it->second.size(); + log("%s[%s]:%s/%s/'%.20s'", + name, it->first.c_str(), + sz > 0 ? it->second[0].c_str() : "<NO [0]>", + sz > 1 ? it->second[1].c_str() : "<NO [1]>", + sz > 2 ? it->second[2].c_str() : "<NO [2]>" + ); + it++; + } +} diff --git a/lib/Utils/CrashTypesSocket.cpp b/lib/Utils/CrashTypesSocket.cpp index 3525c6a5..d555571b 100644 --- a/lib/Utils/CrashTypesSocket.cpp +++ b/lib/Utils/CrashTypesSocket.cpp @@ -87,13 +87,13 @@ std::string crash_data_to_string(const map_crash_data_t& pCrashData) return sCD.str(); } -std::string crash_infos_to_string(const vector_crash_infos_t& pCrashInfos) +std::string crash_infos_to_string(const vector_map_crash_data_t& pCrashDatas) { std::stringstream sCI; unsigned int ii; - for (ii = 0; ii < pCrashInfos.size(); ii++) + for (ii = 0; ii < pCrashDatas.size(); ii++) { - sCI << crash_data_to_string(pCrashInfos[ii]); + sCI << crash_data_to_string(pCrashDatas[ii]); } return sCI.str(); } @@ -164,15 +164,15 @@ map_crash_data_t string_to_crash_data(const std::string& pMessage, int& len) return ci; } -vector_crash_infos_t string_to_crash_infos(const std::string& pMessage) +vector_map_crash_data_t string_to_crash_infos(const std::string& pMessage) { - vector_crash_infos_t vci; + vector_map_crash_data_t vci; std::string message = pMessage; int len; while (message != "") { - map_crash_info_t crash_info = string_to_crash_data(message, len); + map_crash_data_t crash_info = string_to_crash_data(message, len); if (crash_info.size() == 0) { return vci; diff --git a/lib/Utils/DebugDump.h b/lib/Utils/DebugDump.h index d3eebb45..60d3bd3b 100644 --- a/lib/Utils/DebugDump.h +++ b/lib/Utils/DebugDump.h @@ -24,25 +24,6 @@ #define DEBUGDUMP_H_ #include <string> -#include <dirent.h> -#include <stdint.h> - -#define FILENAME_ARCHITECTURE "architecture" -#define FILENAME_KERNEL "kernel" -#define FILENAME_TIME "time" -#define FILENAME_UID "uid" -#define FILENAME_PACKAGE "package" -#define FILENAME_COMPONENT "component" -#define FILENAME_DESCRIPTION "description" -#define FILENAME_ANALYZER "analyzer" -#define FILENAME_RELEASE "release" -#define FILENAME_EXECUTABLE "executable" -#define FILENAME_REASON "reason" -#define FILENAME_COMMENT "comment" -#define FILENAME_REPRODUCE "reproduce" -#define FILENAME_RATING "rating" -#define FILENAME_CMDLINE "cmdline" - class CDebugDump { diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index a944d977..59607104 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -20,6 +20,7 @@ libABRTUtils_la_SOURCES = \ stringops.cpp \ dirsize.cpp \ DebugDump.h DebugDump.cpp \ + CrashTypes.cpp \ ABRTException.cpp libABRTUtils_la_CPPFLAGS = \ -Wall -Werror \ diff --git a/lib/Utils/Plugin.h b/lib/Utils/Plugin.h index d7108ce9..e8464032 100644 --- a/lib/Utils/Plugin.h +++ b/lib/Utils/Plugin.h @@ -120,8 +120,8 @@ typedef struct SPluginInfo }; /* helper finctions */ -std::string make_description_bz(const map_crash_report_t& pCrashReport); -std::string make_description_logger(const map_crash_report_t& pCrashReport); -std::string make_description_catcut(const map_crash_report_t& pCrashReport); +std::string make_description_bz(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); #endif diff --git a/lib/Utils/Reporter.h b/lib/Utils/Reporter.h index 0a06a7c9..e9445f93 100644 --- a/lib/Utils/Reporter.h +++ b/lib/Utils/Reporter.h @@ -36,11 +36,11 @@ class CReporter : public CPlugin * A method, which reports a crash report to particular receiver. * The plugin can takes arguments, but the plugin has to parse them * by itself. - * @param pCrashReport A crash report. + * @param pCrashData A crash report. * @param pArgs Plugin's arguments. * @retun A message which can be displayed after a report is created. */ - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) = 0; }; diff --git a/lib/Utils/daemon.cpp b/lib/Utils/daemon.cpp index 05270624..7d60ce31 100644 --- a/lib/Utils/daemon.cpp +++ b/lib/Utils/daemon.cpp @@ -16,7 +16,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "abrtlib.h" -#define FILENAME_CMDLINE "cmdline" + #define VAR_RUN_PID_FILE VAR_RUN"/abrt.pid" static char *append_escaped(char *start, const char *s) diff --git a/lib/Utils/make_descr.cpp b/lib/Utils/make_descr.cpp index 2a0d4a99..b67dfe65 100644 --- a/lib/Utils/make_descr.cpp +++ b/lib/Utils/make_descr.cpp @@ -50,60 +50,95 @@ static void add_content(bool &was_multiline, string& description, const char *he } } -string make_description_bz(const map_crash_report_t& pCrashReport) +static const char *const blacklisted_items_bz[] = { + FILENAME_TIME , + FILENAME_UID , + FILENAME_UUID , + FILENAME_ANALYZER , + FILENAME_COREDUMP , + FILENAME_DESCRIPTION, /* package description - basically useless */ + CD_DUPHASH , + CD_UUID , + CD_DUMPDIR , + CD_COUNT , + CD_REPORTED , + CD_MESSAGE , + NULL +}; + +string make_description_bz(const map_crash_data_t& pCrashData) { string description; + string long_description; - map_crash_report_t::const_iterator it; - map_crash_report_t::const_iterator end = pCrashReport.end(); - - bool was_multiline = 0; - it = pCrashReport.find(CD_REPRODUCE); - if (it != end && it->second[CD_CONTENT] != "1.\n2.\n3.\n") - { - add_content(was_multiline, description, "How to reproduce", it->second[CD_CONTENT].c_str()); - } - - it = pCrashReport.find(CD_COMMENT); - if (it != end) - { - add_content(was_multiline, description, "Comment", it->second[CD_CONTENT].c_str()); - } - - it = pCrashReport.begin(); - for (; it != end; it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { - const string &filename = it->first; - const string &type = it->second[CD_TYPE]; - const string &content = it->second[CD_CONTENT]; + const string& itemname = it->first; + const string& type = it->second[CD_TYPE]; + const string& content = it->second[CD_CONTENT]; if (type == CD_TXT) { + /* Skip items we are not interested in */ + const char *const *bl = blacklisted_items_bz; + while (*bl) + { + if (itemname == *bl) + break; + bl++; + } + if (*bl) + continue; /* blacklisted */ + if (content == "1.\n2.\n3.\n") + continue; /* user did not change default "How to reproduce" */ + if (content.size() <= CD_TEXT_ATT_SIZE) { - if (filename != CD_UUID - && filename != FILENAME_ARCHITECTURE - && filename != FILENAME_RELEASE - && filename != CD_REPRODUCE - && filename != CD_COMMENT - ) { - add_content(was_multiline, description, filename.c_str(), content.c_str()); + /* Add small (less than few kb) text items inline */ + bool was_multiline = 0; + string tmp; + add_content(was_multiline, + tmp, + /* "reproduce: blah" looks ugly, fixing: */ + itemname == FILENAME_REPRODUCE ? "How to reproduce" : itemname.c_str(), + content.c_str() + ); + + if (was_multiline) + { + /* Not one-liner */ + if (long_description.size() != 0) + long_description += '\n'; + long_description += tmp; + } + else + { + description += tmp; } } else { - add_content(was_multiline, description, "Attached file", filename.c_str()); + bool was_multiline = 0; + add_content(was_multiline, description, "Attached file", itemname.c_str()); } } } + /* One-liners go first, then multi-line items */ + if (description.size() != 0 && long_description.size() != 0) + { + description += '\n'; + } + description += long_description; + return description; } -string make_description_logger(const map_crash_report_t& pCrashReport) +string make_description_logger(const map_crash_data_t& pCrashData) { string description; string long_description; - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { const string &filename = it->first; const string &type = it->second[CD_TYPE]; @@ -134,20 +169,20 @@ string make_description_logger(const map_crash_report_t& pCrashReport) if (description.size() != 0 && long_description.size() != 0) { description += '\n'; - description += long_description; } + description += long_description; return description; } /* This needs more work to make the result less ugly */ -string make_description_catcut(const map_crash_report_t& pCrashReport) +string make_description_catcut(const map_crash_data_t& pCrashData) { - map_crash_report_t::const_iterator end = pCrashReport.end(); - map_crash_report_t::const_iterator it; + map_crash_data_t::const_iterator end = pCrashData.end(); + map_crash_data_t::const_iterator it; string howToReproduce; - it = pCrashReport.find(CD_REPRODUCE); + it = pCrashData.find(FILENAME_REPRODUCE); if (it != end) { howToReproduce = "\n\nHow to reproduce\n" @@ -155,7 +190,7 @@ string make_description_catcut(const map_crash_report_t& pCrashReport) howToReproduce += it->second[CD_CONTENT]; } string comment; - it = pCrashReport.find(CD_COMMENT); + it = pCrashData.find(FILENAME_COMMENT); if (it != end) { comment = "\n\nComment\n" @@ -169,7 +204,7 @@ string make_description_catcut(const map_crash_report_t& pCrashReport) pDescription += "\n\nAdditional information\n" "======\n"; - for (it = pCrashReport.begin(); it != end; it++) + for (it = pCrashData.begin(); it != end; it++) { const string &filename = it->first; const string &type = it->second[CD_TYPE]; @@ -178,11 +213,11 @@ string make_description_catcut(const map_crash_report_t& pCrashReport) { if (content.length() <= CD_TEXT_ATT_SIZE) { - if (filename != CD_UUID + if (filename != CD_DUPHASH && filename != FILENAME_ARCHITECTURE && filename != FILENAME_RELEASE - && filename != CD_REPRODUCE - && filename != CD_COMMENT + && filename != FILENAME_REPRODUCE + && filename != FILENAME_COMMENT ) { pDescription += '\n'; pDescription += filename; diff --git a/lib/Utils/spawn.cpp b/lib/Utils/spawn.cpp index 43c4b4a9..54d08a4a 100644 --- a/lib/Utils/spawn.cpp +++ b/lib/Utils/spawn.cpp @@ -115,7 +115,7 @@ char *run_in_shell_and_save_output(int flags, flags |= EXECFLG_OUTPUT; flags &= ~EXECFLG_INPUT; - const char *argv[] = { "/bin/sh", "sh", "-c", cmd, NULL }; + const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; int pipeout[2]; pid_t child = fork_execv_on_steroids(flags, (char **)argv, pipeout, /*unsetenv_vec:*/ NULL, dir, /*uid (unused):*/ 0); diff --git a/lib/Utils/test.cpp b/lib/Utils/test.cpp index fbad1db9..3711ef18 100644 --- a/lib/Utils/test.cpp +++ b/lib/Utils/test.cpp @@ -80,20 +80,20 @@ int main(int argc, char** argv) std::cout << "-------------------------------------------" << std::endl; } /* Try to save it into DB */ - map_crash_info_t crashInfo; + map_crash_data_t crashInfo; if (middleWare.SaveDebugDump(argv[1], crashInfo)) { std::cout << "Application Crashed! " << - crashInfo[CD_PACKAGE][CD_CONTENT] << ", " << - crashInfo[CD_EXECUTABLE][CD_CONTENT] << ", " << + crashInfo[FILENAME_PACKAGE][CD_CONTENT] << ", " << + crashInfo[FILENAME_EXECUTABLE][CD_CONTENT] << ", " << crashInfo[CD_COUNT][CD_CONTENT] << ", " << std::endl; /* Get Report, so user can change data (remove private stuff) * If we do not want user interaction, just send data immediately */ - map_crash_report_t crashReport; - middleWare.CreateCrashReport(crashInfo[CD_UUID][CD_CONTENT], - crashInfo[CD_UID][CD_CONTENT], + map_crash_data_t crashReport; + middleWare.CreateCrashReport(crashInfo[CD_DUPHASH][CD_CONTENT], + crashInfo[FILENAME_UID][CD_CONTENT], crashReport); /* Report crash */ middleWare.Report(crashReport); @@ -7,13 +7,12 @@ # Geert Warrink <geert.warrink@onsnet.nu>, 2009. # Richard van der Luit <nippur@fedoraproject.org>, 2009. # Geert Warrink <geert.warrink@onsnet.nu>, 2009, 2010. -#: ../src/Gui/CCReporterDialog.py:208 msgid "" msgstr "" "Project-Id-Version: abrt.master\n" "Report-Msgid-Bugs-To: jmoskovc@redhat.com\n" -"POT-Creation-Date: 2010-01-14 15:35+0000\n" -"PO-Revision-Date: 2010-01-14 17:50+0100\n" +"POT-Creation-Date: 2010-01-21 04:02+0000\n" +"PO-Revision-Date: 2010-01-21 15:21+0100\n" "Last-Translator: Geert Warrink <geert.warrink@onsnet.nu>\n" "Language-Team: nl <fedora-trans-list@redhat.com>\n" "MIME-Version: 1.0\n" @@ -51,10 +50,6 @@ msgstr "Rapporteer plugins" msgid "Database plugins" msgstr "Databse plugins" -#: ../src/Gui/ABRTPlugin.py:99 -msgid "Plugin name is not set, can't load its settings" -msgstr "Plugin naam is niet ingesteld, kan zijn instellingen niet laden" - #: ../src/Gui/CCDBusBackend.py:74 ../src/Gui/CCDBusBackend.py:97 msgid "Can't connect to system dbus" msgstr "Kan niet verbinden met systeem dbus" @@ -79,7 +74,8 @@ msgstr "(C) 2009 Red Hat, Inc." msgid "About ABRT" msgstr "Over ABRT" -#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/abrt.desktop.in.h:1 +#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/CCMainWindow.py:9 +#: ../src/Gui/report.glade.h:15 ../src/Gui/abrt.desktop.in.h:1 msgid "Automatic Bug Reporting Tool" msgstr "Automatisch bug rapporteer gereedschap" @@ -103,7 +99,7 @@ msgstr "Wacht a.u.b..." msgid "Plugins" msgstr "Plugins" -#: ../src/Gui/ccgui.glade.h:9 ../src/Gui/report.glade.h:6 +#: ../src/Gui/ccgui.glade.h:9 msgid "Report" msgstr "Rapport" @@ -148,31 +144,31 @@ msgid "_Help" msgstr "_Hulp" #. add pixbuff separatelly -#: ../src/Gui/CCMainWindow.py:76 +#: ../src/Gui/CCMainWindow.py:78 msgid "Icon" msgstr "Icoon" -#: ../src/Gui/CCMainWindow.py:84 +#: ../src/Gui/CCMainWindow.py:86 msgid "Package" msgstr "Pakket" -#: ../src/Gui/CCMainWindow.py:85 +#: ../src/Gui/CCMainWindow.py:87 msgid "Application" msgstr "Toepassing" -#: ../src/Gui/CCMainWindow.py:86 +#: ../src/Gui/CCMainWindow.py:88 msgid "Date" msgstr "Datum" -#: ../src/Gui/CCMainWindow.py:87 +#: ../src/Gui/CCMainWindow.py:89 msgid "Crash count" msgstr "Crash count" -#: ../src/Gui/CCMainWindow.py:88 +#: ../src/Gui/CCMainWindow.py:90 msgid "User" msgstr "Gebruiker" -#: ../src/Gui/CCMainWindow.py:156 +#: ../src/Gui/CCMainWindow.py:158 #, python-format msgid "" "Can't show the settings dialog\n" @@ -181,7 +177,7 @@ msgstr "" "Kan de instellingen dialoog niet tonen\n" "%s" -#: ../src/Gui/CCMainWindow.py:167 +#: ../src/Gui/CCMainWindow.py:169 #, python-format msgid "" "Unable to finish current task!\n" @@ -191,7 +187,7 @@ msgstr "" "%s" #. there is something wrong with the daemon if we cant get the dumplist -#: ../src/Gui/CCMainWindow.py:194 +#: ../src/Gui/CCMainWindow.py:196 #, python-format msgid "" "Error while loading the dumplist.\n" @@ -200,15 +196,19 @@ msgstr "" "Fout tijdens het laden van de dumplijst.\n" "%s" -#: ../src/Gui/CCMainWindow.py:231 +#: ../src/Gui/CCMainWindow.py:233 +msgid "This crash has been reported:\n" +msgstr "Deze crash is gerapporteerd:\n" + +#: ../src/Gui/CCMainWindow.py:234 msgid "<b>This crash has been reported:</b>\n" msgstr "<b>Deze crash is gerapporteerd:</b>\n" -#: ../src/Gui/CCMainWindow.py:241 +#: ../src/Gui/CCMainWindow.py:250 msgid "<b>Not reported!</b>" msgstr "<b>Niet gerapporteerd!</b>" -#: ../src/Gui/CCMainWindow.py:290 +#: ../src/Gui/CCMainWindow.py:298 msgid "" "Unable to get report!\n" "Debuginfo is missing?" @@ -216,7 +216,7 @@ msgstr "" "Kan geen rapport krijgen!\n" "Mist debuginfo?" -#: ../src/Gui/CCMainWindow.py:309 +#: ../src/Gui/CCMainWindow.py:318 #, python-format msgid "" "Reporting failed!\n" @@ -225,25 +225,16 @@ msgstr "" "Rapporteren mislukte!\n" "%s" -#: ../src/Gui/CCMainWindow.py:328 ../src/Gui/CCMainWindow.py:355 +#: ../src/Gui/CCMainWindow.py:337 ../src/Gui/CCMainWindow.py:364 #, python-format msgid "Error getting the report: %s" msgstr "Fout tijdens het verkrijgen van het rapport: %s" -#: ../src/Gui/CCReporterDialog.py:136 -#, python-format -msgid "" -"Can't save plugin settings:\n" -" %s" -msgstr "" -"Kan de plugin instellingen niet opslaan:\n" -" %s" - -#: ../src/Gui/CCReporterDialog.py:194 -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:90 +msgid "You must agree with submitting the backtrace." +msgstr "Je moet het goed vinden om de backtrace op te sturen." -#: ../src/Gui/CCReporterDialog.py:239 +#: ../src/Gui/CCReporterDialog.py:101 #, python-format msgid "" "Reporting disabled because the backtrace is unusable.\n" @@ -256,11 +247,11 @@ msgstr "" "<b>debuginfo-install %s</b> \n" "en gebruik dan de Verversen knop om de backtrace opnieuw te genereren." -#: ../src/Gui/CCReporterDialog.py:241 +#: ../src/Gui/CCReporterDialog.py:103 msgid "The backtrace is unusable, you can't report this!" msgstr "De backtrace in niet bruikbaar, je kunt dit niet rapporteren!" -#: ../src/Gui/CCReporterDialog.py:246 +#: ../src/Gui/CCReporterDialog.py:106 msgid "" "The backtrace is incomplete, please make sure you provide good steps to " "reproduce." @@ -268,18 +259,20 @@ msgstr "" "De backtrace is niet compleet, wees er zeker van om voor het genereren de " "juiste stappen op te volgen." -#: ../src/Gui/CCReporterDialog.py:296 +#: ../src/Gui/CCReporterDialog.py:148 #, python-format msgid "" -"<b>WARNING</b>, you're about to send data which might contain sensitive " -"information.\n" -"Do you really want to send <b>%s</b>?\n" +"Can't save plugin settings:\n" +" %s" msgstr "" -"<b>WAARSCHUWING</b>, je staat op het punt om data te versturen die gevoelige " -"informatie kan bevatten\n" -"Wil je <b>%s</b> echt versturen?\n" +"Kan de plugin instellingen niet opslaan:\n" +" %s" + +#: ../src/Gui/CCReporterDialog.py:266 +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 ../src/Gui/report.glade.h:5 +#: ../src/Gui/dialogs.glade.h:1 ../src/Gui/report.glade.h:17 msgid "Log" msgstr "Log" @@ -310,18 +303,68 @@ msgid " " msgstr " " #: ../src/Gui/report.glade.h:2 -msgid "<b>Comment</b>" -msgstr "<b>Commentaar</b>" +msgid "<b>Attachments</b>" +msgstr "<b>Bijlagen</b>" #: ../src/Gui/report.glade.h:3 -msgid "<b>Following items will be sent</b>" -msgstr "<b>De volgende items zullen verzonden worden</b>" +msgid "<b>Backtrace</b>" +msgstr "<b>Backtrace</b>" #: ../src/Gui/report.glade.h:4 +msgid "<b>Comment</b>" +msgstr "<b>Commentaar</b>" + +#: ../src/Gui/report.glade.h:5 msgid "<b>How to reproduce (in a few simple steps)</b>" msgstr "<b>Hoe het te reproduceren (in een paar eenvoudige stappen)</b>" +#: ../src/Gui/report.glade.h:6 +msgid "<b>Please fix the following problems</b>" +msgstr "<b>Los a.u.b. de volgende problemen op</b>" + #: ../src/Gui/report.glade.h:7 +msgid "<span fgcolor=\"blue\">Architecture:</span>" +msgstr "<span fgcolor=\"blue\">Architectuur:</span>" + +#: ../src/Gui/report.glade.h:8 +msgid "<span fgcolor=\"blue\">Cmdline:</span>" +msgstr "<span fgcolor=\"blue\">Cmdregel:</span>" + +#: ../src/Gui/report.glade.h:9 +msgid "<span fgcolor=\"blue\">Component:</span>" +msgstr "<span fgcolor=\"blue\">Onderdeel:</span>" + +#: ../src/Gui/report.glade.h:10 +msgid "<span fgcolor=\"blue\">Executable:</span>" +msgstr "<span fgcolor=\"blue\">Uitvoerbaar programma:</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\">Pakket:</span>" + +#: ../src/Gui/report.glade.h:13 +msgid "<span fgcolor=\"blue\">Reason:</span>" +msgstr "<span fgcolor=\"blue\">Reden:</span>" + +#: ../src/Gui/report.glade.h:14 +msgid "<span fgcolor=\"blue\">Release:</span>" +msgstr "<span fgcolor=\"blue\">Vrijgave:</span>" + +#: ../src/Gui/report.glade.h:16 +msgid "I agree to submit this backtrace, which could contain sensitive data" +msgstr "" +"Ik ben er mee eens om deze backtrace in te dienen, hoewel hij gevoelige data " +"kan bevatten" + +#: ../src/Gui/report.glade.h:18 +msgid "N/A" +msgstr "n.v.t." + +#: ../src/Gui/report.glade.h:19 msgid "Send" msgstr "Verzenden" @@ -441,12 +484,12 @@ msgstr "gtk-ok" msgid "View and report application crashes" msgstr "Bekijk en rapporteer crashes van toepassingen" -#: ../src/Applet/Applet.cpp:79 +#: ../src/Applet/Applet.cpp:78 #, c-format msgid "A crash in package %s has been detected" msgstr "Een crash in pakket %s is ontdekt" -#: ../src/Applet/Applet.cpp:254 +#: ../src/Applet/Applet.cpp:253 msgid "ABRT service is not running" msgstr "ABRT service draait niet" @@ -454,7 +497,7 @@ msgstr "ABRT service draait niet" msgid "Warning" msgstr "Waarschuwing" -#: ../src/Daemon/Daemon.cpp:474 +#: ../src/Daemon/Daemon.cpp:473 msgid "" "Report size exceeded the quota. Please check system's MaxCrashReportsSize " "value in abrt.conf." @@ -476,51 +519,51 @@ msgstr "Nieuwe bug id: %i" msgid "Checking for duplicates..." msgstr "Controleren voor dubbele..." -#: ../lib/Plugins/Bugzilla.cpp:445 -msgid "Logging into bugzilla..." -msgstr "Inloggen bij bugzilla..." - -#: ../lib/Plugins/Bugzilla.cpp:449 +#: ../lib/Plugins/Bugzilla.cpp:448 msgid "Empty login and password. Please check Bugzilla.conf" msgstr "Leeg login en wachtwoord. Check a.u.b. Bugzilla.conf" +#: ../lib/Plugins/Bugzilla.cpp:450 +msgid "Logging into bugzilla..." +msgstr "Inloggen bij bugzilla..." + #: ../lib/Plugins/Bugzilla.cpp:455 msgid "Checking CC..." msgstr "Controleren van CC..." -#: ../lib/Plugins/Bugzilla.cpp:464 +#: ../lib/Plugins/Bugzilla.cpp:466 msgid "Creating new bug..." msgstr "Nieuwe bug aanmaken..." -#: ../lib/Plugins/Bugzilla.cpp:468 +#: ../lib/Plugins/Bugzilla.cpp:470 msgid "Logging out..." msgstr "Uitloggen..." -#: ../lib/Plugins/Kerneloops.cpp:37 +#: ../lib/Plugins/Kerneloops.cpp:35 msgid "Getting local universal unique identification" msgstr "Verkrijgen van locale universele unieke identificatie" -#: ../lib/Plugins/CCpp.cpp:257 +#: ../lib/Plugins/CCpp.cpp:253 msgid "Generating backtrace" msgstr "Aangemaakte backtrace" -#: ../lib/Plugins/CCpp.cpp:376 +#: ../lib/Plugins/CCpp.cpp:375 msgid "Starting debuginfo installation" msgstr "Start debuginfo installatie" -#: ../lib/Plugins/CCpp.cpp:527 +#: ../lib/Plugins/CCpp.cpp:526 msgid "Getting local universal unique identification..." msgstr "Verkrijgen van locale universele unieke identificatie..." -#: ../lib/Plugins/CCpp.cpp:546 +#: ../lib/Plugins/CCpp.cpp:545 msgid "Getting global universal unique identification..." msgstr "Verkrijgen van golbale universele unieke identificatie..." -#: ../lib/Plugins/CCpp.cpp:725 +#: ../lib/Plugins/CCpp.cpp:723 msgid "Skipping debuginfo installation" msgstr "Sla debuginfo installatie over" -#: ../lib/Plugins/KerneloopsReporter.cpp:102 +#: ../lib/Plugins/KerneloopsReporter.cpp:100 msgid "Creating and submitting a report..." msgstr "Aanmaken en indienen van rapport..." @@ -552,11 +595,11 @@ msgstr "Kan geen archief maken en versturen: %s" msgid "Can't create and send an archive %s" msgstr "Kan archief %s niet aanmaken en versturen" -#: ../lib/Plugins/KerneloopsScanner.cpp:84 +#: ../lib/Plugins/KerneloopsScanner.cpp:79 msgid "Creating kernel oops crash reports..." msgstr "Aanmaken van kernel oops crash rapporten..." -#: ../lib/Plugins/Mailx.cpp:147 +#: ../lib/Plugins/Mailx.cpp:137 msgid "Sending an email..." msgstr "Versturen van email..." @@ -573,6 +616,21 @@ msgstr "sosreport draaien: %s" msgid "done running sosreport" msgstr "klaar met het draaien van sosreport" +#~ msgid "Plugin name is not set, can't load its settings" +#~ msgstr "Plugin naam is niet ingesteld, kan zijn instellingen niet laden" + +#~ msgid "" +#~ "<b>WARNING</b>, you're about to send data which might contain sensitive " +#~ "information.\n" +#~ "Do you really want to send <b>%s</b>?\n" +#~ msgstr "" +#~ "<b>WAARSCHUWING</b>, je staat op het punt om data te versturen die " +#~ "gevoelige informatie kan bevatten\n" +#~ "Wil je <b>%s</b> echt versturen?\n" + +#~ msgid "<b>Following items will be sent</b>" +#~ msgstr "<b>De volgende items zullen verzonden worden</b>" + #~ msgid "Searching for debug-info packages..." #~ msgstr "Zoeken naar debug-info pakketten..." @@ -585,9 +643,6 @@ msgstr "klaar met het draaien van sosreport" #~ msgid "Starting report creation..." #~ msgstr "Beginnen met rapport aanmaken..." -#~ msgid "<span color=\"white\">Description</span>" -#~ msgstr "<span color=\"white\">Beschrijving</span>" - #~ msgid "Working..." #~ msgstr "Ben bezig..." @@ -2,58 +2,57 @@ # Piotr Drąg <piotrdrag@gmail.com>, 2009. # Tomasz Chrzczonowicz <chrzczonowicz@gmail.com>, 2009. # -#: ../src/Gui/CCReporterDialog.py:208 msgid "" msgstr "" "Project-Id-Version: pl\n" "Report-Msgid-Bugs-To: jmoskovc@redhat.com\n" -"POT-Creation-Date: 2010-01-14 20:43+0000\n" -"PO-Revision-Date: 2010-01-14 22:51+0100\n" +"POT-Creation-Date: 2010-01-21 17:08+0000\n" +"PO-Revision-Date: 2010-01-21 18:09+0100\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/Gui/ABRTExceptions.py:6 +#: src/Gui/ABRTExceptions.py:6 msgid "Another client is already running, trying to wake it." msgstr "Inny klient jest już uruchomiony, próba przebudzenia go." -#: ../src/Gui/ABRTExceptions.py:13 +#: src/Gui/ABRTExceptions.py:13 msgid "Got unexpected data from daemon (is the database properly updated?)." msgstr "" "Otrzymano nieoczekiwane dane od demona (czy baza danych została właściwie " "zaktualizowana?)." -#: ../src/Gui/ABRTPlugin.py:56 +#: src/Gui/ABRTPlugin.py:56 msgid "Not loaded plugins" msgstr "Nie wczytano wtyczek" -#: ../src/Gui/ABRTPlugin.py:57 +#: src/Gui/ABRTPlugin.py:57 msgid "Analyzer plugins" msgstr "Wtyczki analizy" -#: ../src/Gui/ABRTPlugin.py:58 +#: src/Gui/ABRTPlugin.py:58 msgid "Action plugins" msgstr "Wtyczki działań" -#: ../src/Gui/ABRTPlugin.py:59 +#: src/Gui/ABRTPlugin.py:59 msgid "Reporter plugins" msgstr "Wtyczki zgłaszania" -#: ../src/Gui/ABRTPlugin.py:60 +#: src/Gui/ABRTPlugin.py:60 msgid "Database plugins" msgstr "Wtyczki baz danych" -#: ../src/Gui/CCDBusBackend.py:74 ../src/Gui/CCDBusBackend.py:97 +#: src/Gui/CCDBusBackend.py:74 src/Gui/CCDBusBackend.py:97 msgid "Can't connect to system dbus" msgstr "Nie można połączyć się z systemową magistralą D-Bus" -#: ../src/Gui/CCDBusBackend.py:104 ../src/Gui/CCDBusBackend.py:107 +#: src/Gui/CCDBusBackend.py:104 src/Gui/CCDBusBackend.py:107 msgid "Please check if abrt daemon is running" msgstr "Proszę sprawdzić, czy demon abrt jest uruchomiony" -#: ../src/Gui/CCDBusBackend.py:159 +#: src/Gui/CCDBusBackend.py:159 msgid "" "Daemon didn't return valid report info\n" "Debuginfo is missing?" @@ -61,43 +60,23 @@ msgstr "" "Demon nie zwrócił prawidłowych informacji o raporcie\n" "Brak pakietów debuginfo?" -#: ../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 "Informacje o ABRT" - -#: ../src/Gui/ccgui.glade.h:3 ../src/Gui/abrt.desktop.in.h:1 -msgid "Automatic Bug Reporting Tool" -msgstr "Narzędzie do automatycznego zgłaszania błędów" - -#: ../src/Gui/ccgui.glade.h:4 -msgid "Delete" -msgstr "Usuń" +#: src/Gui/ccgui.glade:8 +msgid "Please wait.." +msgstr "Proszę czekać..." -#: ../src/Gui/ccgui.glade.h:5 +#: src/Gui/ccgui.glade:60 msgid "Details" msgstr "Szczegóły" -#: ../src/Gui/ccgui.glade.h:6 -msgid "Not Reported" -msgstr "Nie zgłoszono" - -#: ../src/Gui/ccgui.glade.h:7 -msgid "Please wait.." -msgstr "Proszę czekać..." - -#: ../src/Gui/ccgui.glade.h:8 -msgid "Plugins" -msgstr "Wtyczki" +#: src/Gui/ccgui.glade:76 +msgid "About ABRT" +msgstr "Informacje o ABRT" -#: ../src/Gui/ccgui.glade.h:9 ../src/Gui/report.glade.h:6 -msgid "Report" -msgstr "Zgłoś" +#: src/Gui/ccgui.glade:82 +msgid "(C) 2009 Red Hat, Inc." +msgstr "(C) 2009 Red Hat, Inc." -#: ../src/Gui/ccgui.glade.h:10 +#: src/Gui/ccgui.glade:83 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 " @@ -127,44 +106,63 @@ msgstr "" "Powszechnej Licencji Publicznej GNU (GNU General Public License); jeśli nie " "- proszę odwiedzić stronę internetową <http://www.gnu.org/licenses/>." -#: ../src/Gui/ccgui.glade.h:15 -msgid "_Edit" -msgstr "_Edycja" +#: src/Gui/ccgui.glade:121 src/Gui/CCMainWindow.py:9 src/Gui/report.glade:7 +msgid "Automatic Bug Reporting Tool" +msgstr "Narzędzie do automatycznego zgłaszania błędów" -#: ../src/Gui/ccgui.glade.h:16 +#: src/Gui/ccgui.glade:134 msgid "_File" msgstr "_Plik" -#: ../src/Gui/ccgui.glade.h:17 +#: src/Gui/ccgui.glade:155 +msgid "_Edit" +msgstr "_Edycja" + +#: src/Gui/ccgui.glade:163 +msgid "Plugins" +msgstr "Wtyczki" + +#: src/Gui/ccgui.glade:182 msgid "_Help" msgstr "Pomo_c" -#. add pixbuff separatelly -#: ../src/Gui/CCMainWindow.py:77 +#: src/Gui/ccgui.glade:214 src/Gui/ccgui.glade:215 +msgid "Delete" +msgstr "Usuń" + +#: src/Gui/ccgui.glade:227 src/Gui/ccgui.glade:228 src/Gui/ccgui.glade:342 +msgid "Report" +msgstr "Zgłoś" + +#: src/Gui/ccgui.glade:298 +msgid "Not Reported" +msgstr "Nie zgłoszono" + +#: src/Gui/CCMainWindow.py:78 msgid "Icon" msgstr "Ikona" -#: ../src/Gui/CCMainWindow.py:85 +#: src/Gui/CCMainWindow.py:86 msgid "Package" msgstr "Pakiet" -#: ../src/Gui/CCMainWindow.py:86 +#: src/Gui/CCMainWindow.py:87 msgid "Application" msgstr "Aplikacja" -#: ../src/Gui/CCMainWindow.py:87 +#: src/Gui/CCMainWindow.py:88 msgid "Date" msgstr "Data" -#: ../src/Gui/CCMainWindow.py:88 +#: src/Gui/CCMainWindow.py:89 msgid "Crash count" msgstr "Liczba awarii" -#: ../src/Gui/CCMainWindow.py:89 +#: src/Gui/CCMainWindow.py:90 msgid "User" msgstr "Użytkownik" -#: ../src/Gui/CCMainWindow.py:157 +#: src/Gui/CCMainWindow.py:158 #, python-format msgid "" "Can't show the settings dialog\n" @@ -173,7 +171,7 @@ msgstr "" "Nie można wyświetlić okna dialogowego ustawień\n" "%s" -#: ../src/Gui/CCMainWindow.py:168 +#: src/Gui/CCMainWindow.py:169 #, python-format msgid "" "Unable to finish current task!\n" @@ -182,8 +180,7 @@ msgstr "" "Nie można ukończyć bieżącego zadania.\n" "%s" -#. there is something wrong with the daemon if we cant get the dumplist -#: ../src/Gui/CCMainWindow.py:195 +#: src/Gui/CCMainWindow.py:196 #, python-format msgid "" "Error while loading the dumplist.\n" @@ -192,15 +189,19 @@ msgstr "" "Błąd podczas wczytywania listy zrzutów.\n" "%s" -#: ../src/Gui/CCMainWindow.py:232 +#: ../src/Gui/CCMainWindow.py:234 +msgid "This crash has been reported:\n" +msgstr "Ta awaria została zgłoszona:\n" + +#: ../src/Gui/CCMainWindow.py:235 msgid "<b>This crash has been reported:</b>\n" msgstr "<b>Ta awaria została zgłoszona:</b>\n" -#: ../src/Gui/CCMainWindow.py:242 +#: ../src/Gui/CCMainWindow.py:254 msgid "<b>Not reported!</b>" msgstr "<b>Nie zgłoszono.</b>" -#: ../src/Gui/CCMainWindow.py:291 +#: ../src/Gui/CCMainWindow.py:302 msgid "" "Unable to get report!\n" "Debuginfo is missing?" @@ -208,7 +209,7 @@ msgstr "" "Nie można uzyskać raportu.\n" "Brak pakietów debuginfo?" -#: ../src/Gui/CCMainWindow.py:310 +#: src/Gui/CCMainWindow.py:322 #, python-format msgid "" "Reporting failed!\n" @@ -217,27 +218,16 @@ msgstr "" "Zgłoszenie nie powiodło się.\n" "%s" -#: ../src/Gui/CCMainWindow.py:329 ../src/Gui/CCMainWindow.py:356 +#: src/Gui/CCMainWindow.py:341 src/Gui/CCMainWindow.py:368 #, python-format msgid "Error getting the report: %s" msgstr "Błąd podczas uzyskiwania raportu: %s" -#: ../src/Gui/CCReporterDialog.py:136 -#, python-format -msgid "" -"Can't save plugin settings:\n" -" %s" -msgstr "" -"Nie można zapisać ustawień wtyczki:\n" -" %s" - -#: ../src/Gui/CCReporterDialog.py:194 -msgid "Brief description how to reproduce this or what you did..." -msgstr "" -"Krótki opis, jak ponownie wywołać tę awarię lub co robił użytkownik (w " -"języku angielskim)..." +#: ../src/Gui/CCReporterDialog.py:90 +msgid "You must agree with submitting the backtrace." +msgstr "Należy wyrazić zgodę na wysłanie wyjątku." -#: ../src/Gui/CCReporterDialog.py:239 +#: ../src/Gui/CCReporterDialog.py:101 #, python-format msgid "" "Reporting disabled because the backtrace is unusable.\n" @@ -250,11 +240,11 @@ msgstr "" "<b>debuginfo-install %s</b>, \n" "a następnie nacisnąć przycisk Odśwież, aby ponownie utworzyć wyjątek." -#: ../src/Gui/CCReporterDialog.py:241 +#: ../src/Gui/CCReporterDialog.py:103 msgid "The backtrace is unusable, you can't report this!" msgstr "Nie można użyć tego wyjątku, więc nie można tego zgłosić." -#: ../src/Gui/CCReporterDialog.py:246 +#: ../src/Gui/CCReporterDialog.py:106 msgid "" "The backtrace is incomplete, please make sure you provide good steps to " "reproduce." @@ -262,196 +252,246 @@ msgstr "" "Wyjątek jest niepełny. Proszę upewnić się, że podano właściwe kroki " "ponownego wywołania awarii." -#: ../src/Gui/CCReporterDialog.py:296 +#: ../src/Gui/CCReporterDialog.py:148 #, python-format msgid "" -"<b>WARNING</b>, you're about to send data which might contain sensitive " -"information.\n" -"Do you really want to send <b>%s</b>?\n" +"Can't save plugin settings:\n" +" %s" msgstr "" -"<b>OSTRZEŻENIE:</b> za chwilę zostaną wysłane dane, które mogą zawierać " -"poufne informacje.\n" -"Na pewno wysłać <b>%s</b>?\n" +"Nie można zapisać ustawień wtyczki:\n" +" %s" -#: ../src/Gui/dialogs.glade.h:1 ../src/Gui/report.glade.h:5 -msgid "Log" -msgstr "Dziennik" +#: ../src/Gui/CCReporterDialog.py:266 +msgid "Brief description how to reproduce this or what you did..." +msgstr "" +"Krótki opis, jak ponownie wywołać tę awarię lub co robił użytkownik (w " +"języku angielskim)..." -#: ../src/Gui/dialogs.glade.h:2 +#: src/Gui/dialogs.glade:7 msgid "Report done" msgstr "Raport ukończony" -#: ../src/Gui/PluginSettingsUI.py:18 +#: src/Gui/dialogs.glade:80 src/Gui/report.glade:586 +msgid "Log" +msgstr "Dziennik" + +#: src/Gui/PluginSettingsUI.py:18 msgid "Can't find PluginDialog widget in UI description!" msgstr "" "Nie można odnaleźć widgetu PluginDialog w opisie interfejsu użytkownika." -#. we shouldn't get here, but just to be safe -#: ../src/Gui/PluginSettingsUI.py:24 +#: src/Gui/PluginSettingsUI.py:24 #, python-format msgid "No UI for plugin %s" msgstr "Brak interfejsu użytkownika dla wtyczki %s" -#: ../src/Gui/PluginSettingsUI.py:55 ../src/Gui/PluginSettingsUI.py:81 +#: src/Gui/PluginSettingsUI.py:55 src/Gui/PluginSettingsUI.py:81 msgid "combo box is not implemented" msgstr "pole kombinowane nie jest zaimplementowane" -#: ../src/Gui/PluginSettingsUI.py:64 +#: src/Gui/PluginSettingsUI.py:64 msgid "Nothing to hydrate!" msgstr "Brak danych do wyświetlenia." -#: ../src/Gui/report.glade.h:1 -msgid " " -msgstr " " +#: src/Gui/report.glade:41 +msgid "<span fgcolor=\"blue\">Package:</span>" +msgstr "<span fgcolor=\"blue\">Pakiet:</span>" -#: ../src/Gui/report.glade.h:2 -msgid "<b>Comment</b>" -msgstr "<b>Komentarz</b>" +#: src/Gui/report.glade:52 +msgid "<span fgcolor=\"blue\">Component:</span>" +msgstr "<span fgcolor=\"blue\">Składnik:</span>" + +#: src/Gui/report.glade:63 +msgid "<span fgcolor=\"blue\">Executable:</span>" +msgstr "<span fgcolor=\"blue\">Plik wykonywalny:</span>" + +#: src/Gui/report.glade:74 +msgid "<span fgcolor=\"blue\">Cmdline:</span>" +msgstr "<span fgcolor=\"blue\">Wiersz poleceń:</span>" -#: ../src/Gui/report.glade.h:3 -msgid "<b>Following items will be sent</b>" -msgstr "<b>Następujące elementy zostaną wysłane</b>" +#: src/Gui/report.glade:98 src/Gui/report.glade:110 src/Gui/report.glade:122 +#: src/Gui/report.glade:134 src/Gui/report.glade:211 src/Gui/report.glade:223 +#: src/Gui/report.glade:235 src/Gui/report.glade:247 +msgid "N/A" +msgstr "Nie dotyczy" -#: ../src/Gui/report.glade.h:4 +#: src/Gui/report.glade:155 +msgid "<span fgcolor=\"blue\">Architecture:</span>" +msgstr "<span fgcolor=\"blue\">Architektura:</span>" + +#: src/Gui/report.glade:166 +msgid "<span fgcolor=\"blue\">Kernel:</span>" +msgstr "<span fgcolor=\"blue\">Jądro:</span>" + +#: src/Gui/report.glade:177 +msgid "<span fgcolor=\"blue\">Release:</span>" +msgstr "<span fgcolor=\"blue\">Wydanie:</span>" + +#: src/Gui/report.glade:188 +msgid "<span fgcolor=\"blue\">Reason:</span>" +msgstr "<span fgcolor=\"blue\">Przyczyna:</span>" + +#: src/Gui/report.glade:306 +msgid "I agree to submit this backtrace, which could contain sensitive data" +msgstr "" +"Wyrażam zgodę na wysłanie tego wyjątku, który może zawierać prywatne dane" + +#: src/Gui/report.glade:325 +msgid "<b>Backtrace</b>" +msgstr "<b>Wyjątek</b>" + +#: src/Gui/report.glade:388 msgid "<b>How to reproduce (in a few simple steps)</b>" msgstr "" "<b>Jak ponownie wywołać tę awarię (w kilku prostych krokach, w języku " "angielskim)</b>" -#: ../src/Gui/report.glade.h:7 +#: src/Gui/report.glade:432 +msgid "<b>Comment</b>" +msgstr "<b>Komentarz</b>" + +#: src/Gui/report.glade:480 +msgid "<b>Attachments</b>" +msgstr "<b>Załączniki</b>" + +#: src/Gui/report.glade:529 +msgid "<b>Please fix the following problems</b>" +msgstr "<b>Proszę naprawić następujące problemy</b>" + +#: src/Gui/report.glade:539 +msgid " " +msgstr " " + +#: src/Gui/report.glade:627 msgid "Send" msgstr "Wyślij" -#: ../src/Gui/SettingsDialog.py:33 ../src/Gui/SettingsDialog.py:50 +#: src/Gui/SettingsDialog.py:33 src/Gui/SettingsDialog.py:50 msgid "<b>Select plugin</b>" msgstr "<b>Wybór wtyczki</b>" -#: ../src/Gui/SettingsDialog.py:36 +#: src/Gui/SettingsDialog.py:36 msgid "<b>Select database backend</b>" msgstr "<b>Wybór zaplecza bazy danych</b>" -#: ../src/Gui/SettingsDialog.py:166 +#: src/Gui/SettingsDialog.py:166 msgid "Remove this job" msgstr "Usuń te zadanie" -#: ../src/Gui/SettingsDialog.py:210 +#: src/Gui/SettingsDialog.py:210 msgid "Remove this action" msgstr "Usuń tę czynność" -#: ../src/Gui/settings.glade.h:1 -msgid "<b>Analyzer plugin</b>" -msgstr "<b>Wtyczka analizy</b>" - -#: ../src/Gui/settings.glade.h:2 -msgid "<b>Associated action</b>" -msgstr "<b>Powiązane działanie</b>" +#: src/Gui/settings.glade:6 +msgid "Settings" +msgstr "Ustawienia" -#: ../src/Gui/settings.glade.h:3 -msgid "<b>Plugin details</b>" -msgstr "<b>Szczegóły wtyczki</b>" +#: src/Gui/settings.glade:63 +msgid "Web Site:" +msgstr "Strona WWW:" -#: ../src/Gui/settings.glade.h:4 -msgid "<b>Plugin</b>" -msgstr "<b>Wtyczka</b>" +#: src/Gui/settings.glade:75 +msgid "Author:" +msgstr "Autor:" -#: ../src/Gui/settings.glade.h:5 -msgid "<b>Time (or period)</b>" -msgstr "<b>Czas (lub okres czasu)</b>" +#: src/Gui/settings.glade:87 +msgid "Version:" +msgstr "Wersja:" -#: ../src/Gui/settings.glade.h:6 -msgid "Analyzers, Actions, Reporters" -msgstr "Analizy, działania, zgłaszający" +#: src/Gui/settings.glade:141 +msgid "Description:" +msgstr "Opis:" -#: ../src/Gui/settings.glade.h:7 -msgid "Author:" -msgstr "Autor:" +#: src/Gui/settings.glade:153 +msgid "Name:" +msgstr "Nazwa:" -#: ../src/Gui/settings.glade.h:8 -msgid "Blacklisted packages: " -msgstr "Czarna lista pakietów: " +#: src/Gui/settings.glade:197 +msgid "<b>Plugin details</b>" +msgstr "<b>Szczegóły wtyczki</b>" -#: ../src/Gui/settings.glade.h:9 +#: src/Gui/settings.glade:220 msgid "C_onfigure plugin" msgstr "Sk_onfiguruj wtyczkę" -#: ../src/Gui/settings.glade.h:10 +#: src/Gui/settings.glade:257 +msgid "Global Settings" +msgstr "Ustawienia globalne" + +#: src/Gui/settings.glade:283 msgid "Check package GPG signature" msgstr "Sprawdzanie podpisu GPG pakietu" -#: ../src/Gui/settings.glade.h:11 -msgid "Common" -msgstr "Wspólne" - -#: ../src/Gui/settings.glade.h:12 -msgid "Cron" -msgstr "Cron" - -#: ../src/Gui/settings.glade.h:13 +#: src/Gui/settings.glade:299 msgid "Database backend: " msgstr "Zaplecze bazy danych: " -#: ../src/Gui/settings.glade.h:14 -msgid "Description:" -msgstr "Opis:" +#: src/Gui/settings.glade:325 +msgid "Blacklisted packages: " +msgstr "Czarna lista pakietów: " -#: ../src/Gui/settings.glade.h:15 -msgid "GPG Keys" -msgstr "Klucze GPG" +#: src/Gui/settings.glade:339 +msgid "Max coredump storage size(MB):" +msgstr "Ograniczenie miejsca na zrzuty pamięci (MB):" -#: ../src/Gui/settings.glade.h:16 +#: src/Gui/settings.glade:353 msgid "GPG keys: " msgstr "klucze GPG: " -#: ../src/Gui/settings.glade.h:17 -msgid "Global Settings" -msgstr "Ustawienia globalne" +#: src/Gui/settings.glade:456 +msgid "Common" +msgstr "Wspólne" -#: ../src/Gui/settings.glade.h:18 -msgid "Max coredump storage size(MB):" -msgstr "Ograniczenie miejsca na zrzuty pamięci (MB):" +#: src/Gui/settings.glade:489 +msgid "<b>Plugin</b>" +msgstr "<b>Wtyczka</b>" -#: ../src/Gui/settings.glade.h:19 -msgid "Name:" -msgstr "Nazwa:" +#: src/Gui/settings.glade:499 +msgid "<b>Time (or period)</b>" +msgstr "<b>Czas (lub okres czasu)</b>" -#: ../src/Gui/settings.glade.h:20 -msgid "Settings" -msgstr "Ustawienia" +#: src/Gui/settings.glade:567 +msgid "Cron" +msgstr "Cron" -#: ../src/Gui/settings.glade.h:21 -msgid "Version:" -msgstr "Wersja:" +#: src/Gui/settings.glade:601 +msgid "<b>Analyzer plugin</b>" +msgstr "<b>Wtyczka analizy</b>" -#: ../src/Gui/settings.glade.h:22 -msgid "Web Site:" -msgstr "Strona WWW:" +#: src/Gui/settings.glade:611 +msgid "<b>Associated action</b>" +msgstr "<b>Powiązane działanie</b>" + +#: src/Gui/settings.glade:690 +msgid "Analyzers, Actions, Reporters" +msgstr "Analizy, działania, zgłaszający" -#: ../src/Gui/settings.glade.h:23 +#: src/Gui/settings.glade:709 msgid "gtk-cancel" msgstr "gtk-cancel" -#: ../src/Gui/settings.glade.h:24 +#: src/Gui/settings.glade:723 msgid "gtk-ok" msgstr "gtk-ok" -#: ../src/Gui/abrt.desktop.in.h:2 -msgid "View and report application crashes" -msgstr "Wyświetlanie i zgłaszanie awarii aplikacji" +#: src/Gui/settings.glade:751 +msgid "GPG Keys" +msgstr "Klucze GPG" -#: ../src/Applet/Applet.cpp:79 +#: src/Applet/Applet.cpp:78 #, c-format msgid "A crash in package %s has been detected" msgstr "Wykryto awarię pakietu %s" -#: ../src/Applet/Applet.cpp:254 +#: src/Applet/Applet.cpp:253 msgid "ABRT service is not running" msgstr "Usługa ABRT nie jest uruchomiona" -#: ../src/Applet/CCApplet.cpp:200 +#: src/Applet/CCApplet.cpp:200 msgid "Warning" msgstr "Ostrzeżenie" -#: ../src/Daemon/Daemon.cpp:474 +#: src/Daemon/Daemon.cpp:473 msgid "" "Report size exceeded the quota. Please check system's MaxCrashReportsSize " "value in abrt.conf." @@ -459,113 +499,116 @@ msgstr "" "Wielkość raportu przekroczyła dozwolone ograniczenie. Proszę sprawdzić " "wartość zmiennej MaxCrashReportsSize w pliku abrt.conf" -#: ../lib/Plugins/Bugzilla.cpp:265 +#: ../lib/Plugins/Bugzilla.cpp:267 #, c-format msgid "Bug is already reported: %i" msgstr "Błąd został już wcześniej zgłoszony: %i" -#: ../lib/Plugins/Bugzilla.cpp:341 +#: ../lib/Plugins/Bugzilla.cpp:351 #, c-format msgid "New bug id: %i" msgstr "Identyfikator nowego błędu: %i" -#: ../lib/Plugins/Bugzilla.cpp:442 +#: ../lib/Plugins/Bugzilla.cpp:452 msgid "Checking for duplicates..." msgstr "Sprawdzanie duplikatów..." -#: ../lib/Plugins/Bugzilla.cpp:445 -msgid "Logging into bugzilla..." -msgstr "Logowanie do Bugzilli..." - -#: ../lib/Plugins/Bugzilla.cpp:449 +#: ../lib/Plugins/Bugzilla.cpp:458 msgid "Empty login and password. Please check Bugzilla.conf" msgstr "Pola login i hasło są puste. Proszę sprawdzić plik Bugzilla.conf" -#: ../lib/Plugins/Bugzilla.cpp:455 +#: ../lib/Plugins/Bugzilla.cpp:461 +msgid "Logging into bugzilla..." +msgstr "Logowanie do Bugzilli..." + +#: ../lib/Plugins/Bugzilla.cpp:466 msgid "Checking CC..." msgstr "Sprawdzanie listy CC..." -#: ../lib/Plugins/Bugzilla.cpp:464 +#: ../lib/Plugins/Bugzilla.cpp:479 msgid "Creating new bug..." msgstr "Dodawanie nowego błędu..." -#: ../lib/Plugins/Bugzilla.cpp:468 +#: ../lib/Plugins/Bugzilla.cpp:484 msgid "Logging out..." msgstr "Wylogowywanie..." -#: ../lib/Plugins/Kerneloops.cpp:37 +#: lib/Plugins/Kerneloops.cpp:35 msgid "Getting local universal unique identification" msgstr "Uzyskiwanie lokalnego uniwersalnego, unikalnego identyfikatora" -#: ../lib/Plugins/CCpp.cpp:257 +#: lib/Plugins/CCpp.cpp:253 msgid "Generating backtrace" msgstr "Tworzenie wyjątku" -#: ../lib/Plugins/CCpp.cpp:376 +#: lib/Plugins/CCpp.cpp:375 msgid "Starting debuginfo installation" msgstr "Uruchamianie instalacji pakietów debuginfo" -#: ../lib/Plugins/CCpp.cpp:527 +#: lib/Plugins/CCpp.cpp:526 msgid "Getting local universal unique identification..." msgstr "Uzyskiwanie lokalnego uniwersalnego, unikalnego identyfikatora..." -#: ../lib/Plugins/CCpp.cpp:546 +#: lib/Plugins/CCpp.cpp:545 msgid "Getting global universal unique identification..." msgstr "Uzyskiwanie globalnego uniwersalnego, unikalnego identyfikatora..." -#: ../lib/Plugins/CCpp.cpp:725 +#: lib/Plugins/CCpp.cpp:723 msgid "Skipping debuginfo installation" msgstr "Pomijanie instalacji pakietu debuginfo" -#: ../lib/Plugins/KerneloopsReporter.cpp:102 +#: lib/Plugins/KerneloopsReporter.cpp:100 msgid "Creating and submitting a report..." msgstr "Tworzenie i wysyłanie raportu..." -#: ../lib/Plugins/Logger.cpp:82 +#: lib/Plugins/Logger.cpp:82 #, c-format msgid "Writing report to '%s'" msgstr "Zapisywanie raportu do \"%s\"" -#: ../lib/Plugins/FileTransfer.cpp:63 ../lib/Plugins/FileTransfer.cpp:372 +#: ../lib/Plugins/FileTransfer.cpp:57 ../lib/Plugins/FileTransfer.cpp:366 msgid "FileTransfer: URL not specified" msgstr "Wtyczka przesyłania plików: nie podano adresu URL" -#: ../lib/Plugins/FileTransfer.cpp:67 +#: ../lib/Plugins/FileTransfer.cpp:61 #, c-format msgid "Sending archive %s to %s" msgstr "Wysyłanie archiwum %s do %s" -#: ../lib/Plugins/FileTransfer.cpp:296 +#: ../lib/Plugins/FileTransfer.cpp:290 msgid "File Transfer: Creating a report..." msgstr "Wtyczka przesyłania plików: tworzenie raportu..." -#: ../lib/Plugins/FileTransfer.cpp:322 +#: ../lib/Plugins/FileTransfer.cpp:316 #, c-format msgid "Can't create and send an archive: %s" msgstr "Nie można utworzyć i wysłać archiwum: %s" -#: ../lib/Plugins/FileTransfer.cpp:347 +#: ../lib/Plugins/FileTransfer.cpp:341 #, c-format msgid "Can't create and send an archive %s" msgstr "Nie można utworzyć i wysłać archiwum %s" -#: ../lib/Plugins/KerneloopsScanner.cpp:84 +#: ../lib/Plugins/KerneloopsScanner.cpp:79 msgid "Creating kernel oops crash reports..." msgstr "Tworzenie raportów awarii \"kernel oops\"" -#: ../lib/Plugins/Mailx.cpp:147 +#: lib/Plugins/Mailx.cpp:137 msgid "Sending an email..." msgstr "Wysłanie wiadomości e-mail..." -#: ../lib/Plugins/SOSreport.cpp:69 +#: lib/Plugins/SOSreport.cpp:69 msgid "Executing SOSreport plugin..." msgstr "Wykonywanie wtyczki SOSreport..." -#: ../lib/Plugins/SOSreport.cpp:91 +#: lib/Plugins/SOSreport.cpp:91 #, c-format msgid "running sosreport: %s" msgstr "wykonywanie sosreport: %s" -#: ../lib/Plugins/SOSreport.cpp:97 +#: lib/Plugins/SOSreport.cpp:97 msgid "done running sosreport" msgstr "ukończono wykonywanie sosreport" + +#~ msgid "View and report application crashes" +#~ msgstr "Wyświetlanie i zgłaszanie awarii aplikacji" diff --git a/scripts/abrt-bz-stats b/scripts/abrt-bz-stats index 3fb02bca..fd222dc9 100755 --- a/scripts/abrt-bz-stats +++ b/scripts/abrt-bz-stats @@ -13,6 +13,9 @@ import subprocess import datetime import pickle +# +# Parse the command line input +# parser = OptionParser(version="%prog 1.0") parser.add_option("-u", "--user", dest="user", help="Bugzilla user name (REQUIRED)", metavar="USERNAME") @@ -21,7 +24,6 @@ parser.add_option("-p", "--password", dest="password", parser.add_option("-b", "--bugzilla", dest="bugzilla", help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL") (options, args) = parser.parse_args() - if not options.user or len(options.user) == 0: parser.error("User name is required.\nTry {0} --help".format(sys.argv[0])) if not options.password or len(options.password) == 0: @@ -29,6 +31,9 @@ if not options.password or len(options.password) == 0: if not options.bugzilla or len(options.bugzilla) == 0: options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi" +# +# Connect to Bugzilla and get the list of all bugs reported by ABRT +# bz = RHBugzilla() bz.connect(options.bugzilla) bz.login(options.user, options.password) @@ -37,47 +42,150 @@ buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboar total = len(buginfos) print "{0} bugs found.".format(total) +# +# Load cache from previous run. Speeds up the case Bugzilla closes connection. +# buginfos_loaded = {} if os.path.isfile("cache"): f = open("cache", 'r') buginfos_loaded = pickle.load(f) f.close() +def save_to_cache(): + global buginfos_loaded + f = open("cache", 'w') + pickle.dump(buginfos_loaded, f, 2) + f.close() + +# +# Load data from Bugzilla +# count = 0 for buginfo in buginfos: count += 1 print "{0}/{1}".format(count, total) - dtkey = buginfo.delta_ts[0:7] # YEAR-MONTH - statuskey = buginfo.bug_status - if buginfo.resolution != "": - statuskey += "_" + buginfo.resolution - if not buginfos_loaded.has_key(buginfo.bug_id): - buginfos_loaded[buginfo.bug_id] = (dtkey, statuskey) + if count % 100 == 0: - f = open("cache", 'w') - pickle.dump(buginfos_loaded, f, 2) - f.close() + save_to_cache() + + if buginfos_loaded.has_key(buginfo.bug_id): + continue + + # creation date, format YEAR-MONTH + created = buginfo.creation_ts[0:7].replace(".", "-") + # last change to bug, format YEAR-MONTH + lastchange = buginfo.delta_ts[0:7].replace(".", "-") + status = buginfo.bug_status # status during the last change + if buginfo.resolution != "": + status += "_" + buginfo.resolution + buginfos_loaded[buginfo.bug_id] = { + 'created':created, + 'lastchange':lastchange, + 'status':status, + 'component':buginfo.component} + bz.logout() +save_to_cache() -stats = {} -for buginfo in buginfos_loaded.values(): - if buginfo[0] in stats: - stat = stats[buginfo[0]] - if buginfo[1] in stat: - stat[buginfo[1]] += 1 +# +# Interpret data from Bugzilla +# +# Bugs reported this month by ABRT +# Bugs closed as useful this month by ABRT +# Bugs closed as waste this month by ABRT +# Top crashers this month. +# +class Month: + def __init__(self): + # Number of bugs reported to certain component this month. + self.components = {} + + self.closed_as_useful = 0 + self.closed_as_waste = 0 + self.closed_as_other = 0 + + def bugs_reported(self): + result = 0 + for component in self.components.values(): + result += component + return result + + def top_crashers(self): + """ + Top five components causing crash this month. + Returns list of tuples (component, number of crashes) + """ + result = sorted(self.components.items(), key=lambda x: x[1]) + result.reverse() + return result[0:5] + + def closed_as_useful_percentage(self): + return int(100 * self.closed_as_useful / self.closed()) + + def closed_as_waste_percentage(self): + return int(100 * self.closed_as_waste / self.closed()) + + def closed_as_other_percentage(self): + return int(100 * self.closed_as_other / self.closed()) + + def closed(self): + return self.closed_as_useful + self.closed_as_waste + self.closed_as_other + + def add_component_crash(self, component): + if component in self.components: + self.components[component] += 1 else: - stat[buginfo[1]] = 1 + self.components[component] = 1 + + def add_resolution(self, resolution): + if resolution in ["CLOSED_NOTABUG", "CLOSED_WONTFIX", "CLOSED_DEFERRED", "CLOSED_WORKSFORME"]: + self.closed_as_other += 1 + elif resolution in ["CLOSED_CURRENTRELEASE", "CLOSED_RAWHIDE", "CLOSED_ERRATA", \ + "CLOSED_UPSTREAM", "CLOSED_NEXTRELEASE"]: + self.closed_as_useful += 1 + elif resolution in ["CLOSED_DUPLICATE", "CLOSED_CANTFIX", "CLOSED_INSUFFICIENT_DATA"]: + self.closed_as_waste += 1 + + +stats = {} # key == YEAR-MONTH, value == Month() + +def get_month(month): + global stats + if month in stats: + return stats[month] else: - stats[buginfo[0]] = { buginfo[1]:1 } + stats[month] = Month() + return stats[month] +for buginfo in buginfos_loaded.values(): + # Bugs reported this month by ABRT + # Top crashers this month + month = get_month(buginfo['created']) + month.add_component_crash(buginfo['component']) + + # Bugs closed as useful this month by ABRT + # Bugs closed as waste this month by ABRT + month = get_month(buginfo['lastchange']) + month.add_resolution(buginfo['status']) + +# +# Print interpreted data +# print "STATS" print "==========================================================================" months = stats.keys() months.sort() for month in months: - stat = stats[month] - statuses = stat.keys() - statuses.sort() - print "Month ", month - for status in statuses: - print status, stat[status] + m = stats[month] + print "MONTH ", month + print " -", m.bugs_reported(), "bugs reported" + if m.closed_as_useful > 0: + print " -", m.closed_as_useful, "bugs (" + str(m.closed_as_useful_percentage()) + "%) closed (ABRT was useful)" + if m.closed_as_waste > 0: + print " -", m.closed_as_waste, "bugs (" + str(m.closed_as_waste_percentage())+ "%) closed (ABRT was not useful)" + if m.closed_as_other > 0: + print " -", m.closed_as_other, "bugs (" + str(m.closed_as_other_percentage()) + "%) closed other way" + if len(m.top_crashers()) > 0: + print " - top crashers:" + for (component, num_crashes) in m.top_crashers(): + print " # ", component + ":", num_crashes, "crashes" diff --git a/src/CLI/ABRTSocket.cpp b/src/CLI/ABRTSocket.cpp index 13531342..82c304ee 100644 --- a/src/CLI/ABRTSocket.cpp +++ b/src/CLI/ABRTSocket.cpp @@ -106,7 +106,7 @@ void CABRTSocket::Disconnect() close(m_nSocket); } -vector_crash_infos_t CABRTSocket::GetCrashInfos() +vector_map_crash_data_t CABRTSocket::GetCrashInfos() { std::string message = MESSAGE_GET_CRASH_INFOS; Send(message); @@ -115,7 +115,7 @@ vector_crash_infos_t CABRTSocket::GetCrashInfos() return string_to_crash_infos(message); } -map_crash_report_t CABRTSocket::CreateReport(const std::string &pUUID) +map_crash_data_t CABRTSocket::CreateReport(const std::string &pUUID) { std::string message = MESSAGE_CREATE_REPORT + pUUID; Send(message); @@ -124,7 +124,7 @@ map_crash_report_t CABRTSocket::CreateReport(const std::string &pUUID) return string_to_crash_report(message); } -void CABRTSocket::Report(const map_crash_report_t& pReport) +void CABRTSocket::Report(const map_crash_data_t& pReport) { std::string message = MESSAGE_REPORT + crash_report_to_string(pReport); Send(message); diff --git a/src/CLI/ABRTSocket.h b/src/CLI/ABRTSocket.h index c3a63e51..d4905be1 100644 --- a/src/CLI/ABRTSocket.h +++ b/src/CLI/ABRTSocket.h @@ -20,9 +20,9 @@ class CABRTSocket void Connect(const char *pPath); void Disconnect(); - vector_crash_infos_t GetCrashInfos(); - map_crash_report_t CreateReport(const char *pUUID); - void Report(const map_crash_report_t& pReport); + vector_map_crash_data_t GetCrashInfos(); + map_crash_data_t CreateReport(const char *pUUID); + void Report(const map_crash_data_t& pReport); int32_t DeleteDebugDump(const char *pUUID); }; diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index bc8ddf60..a8786e99 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -47,15 +47,15 @@ enum OPT_DELETE }; -static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) +static void print_crash_infos(vector_map_crash_data_t& pCrashInfos, int pMode) { unsigned int ii; for (ii = 0; ii < pCrashInfos.size(); ii++) { - map_crash_info_t& info = pCrashInfos[ii]; - if (pMode == OPT_GET_LIST_FULL || info[CD_REPORTED][CD_CONTENT] != "1") + map_crash_data_t& info = pCrashInfos[ii]; + if (pMode == OPT_GET_LIST_FULL || get_crash_data_item_content(info, CD_REPORTED) != "1") { - const char *timestr = info[CD_TIME][CD_CONTENT].c_str(); + const char *timestr = get_crash_data_item_content(info, FILENAME_TIME).c_str(); long time = strtol(timestr, NULL, 10); if (time == 0) error_msg_and_die("Error while converting time string."); @@ -72,13 +72,13 @@ static void print_crash_infos(vector_crash_infos_t& pCrashInfos, int pMode) "\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() + ii, + get_crash_data_item_content(info, FILENAME_UID).c_str(), + get_crash_data_item_content(info, CD_UUID).c_str(), + get_crash_data_item_content(info, FILENAME_PACKAGE).c_str(), + get_crash_data_item_content(info, FILENAME_EXECUTABLE).c_str(), + timeloc, + get_crash_data_item_content(info, CD_COUNT).c_str() ); } } @@ -189,7 +189,7 @@ int main(int argc, char** argv) case OPT_GET_LIST: case OPT_GET_LIST_FULL: { - vector_crash_infos_t ci = call_GetCrashInfos(); + vector_map_crash_data_t ci = call_GetCrashInfos(); print_crash_infos(ci, op); break; } diff --git a/src/CLI/dbus.cpp b/src/CLI/dbus.cpp index 0d03c4d7..ffd1157e 100644 --- a/src/CLI/dbus.cpp +++ b/src/CLI/dbus.cpp @@ -104,7 +104,7 @@ static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) } } -vector_crash_infos_t call_GetCrashInfos() +vector_map_crash_data_t call_GetCrashInfos() { DBusMessage* msg = new_call_msg(__func__ + 5); DBusMessage *reply = send_get_reply_and_unref(msg); @@ -112,7 +112,7 @@ vector_crash_infos_t call_GetCrashInfos() DBusMessageIter in_iter; dbus_message_iter_init(reply, &in_iter); - vector_crash_infos_t argout; + vector_map_crash_data_t argout; 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", __func__ + 5); @@ -121,7 +121,7 @@ vector_crash_infos_t call_GetCrashInfos() return argout; } -map_crash_report_t call_CreateReport(const char* uuid) +map_crash_data_t call_CreateReport(const char* uuid) { DBusMessage* msg = new_call_msg(__func__ + 5); dbus_message_append_args(msg, @@ -133,7 +133,7 @@ map_crash_report_t call_CreateReport(const char* uuid) DBusMessageIter in_iter; dbus_message_iter_init(reply, &in_iter); - map_crash_report_t argout; + map_crash_data_t argout; 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", __func__ + 5); @@ -142,7 +142,7 @@ map_crash_report_t call_CreateReport(const char* uuid) return argout; } -report_status_t call_Report(const map_crash_report_t& report) +report_status_t call_Report(const map_crash_data_t& report) { DBusMessage* msg = new_call_msg(__func__ + 5); DBusMessageIter out_iter; diff --git a/src/CLI/dbus.h b/src/CLI/dbus.h index c692e198..c6fd7a4d 100644 --- a/src/CLI/dbus.h +++ b/src/CLI/dbus.h @@ -23,9 +23,9 @@ extern DBusConnection* s_dbus_conn; -vector_crash_infos_t call_GetCrashInfos(); -map_crash_report_t call_CreateReport(const char *uuid); -report_status_t call_Report(const map_crash_report_t& report); +vector_map_crash_data_t call_GetCrashInfos(); +map_crash_data_t call_CreateReport(const char *uuid); +report_status_t call_Report(const map_crash_data_t& report); int32_t call_DeleteDebugDump(const char* uuid); #ifdef UNUSED diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index bc8f9008..76cd3d5a 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -19,7 +19,8 @@ #include "run-command.h" #include "dbus.h" #include "abrtlib.h" -#include "DebugDump.h" // FILENAME_* defines +#include "DebugDump.h" +#include "CrashTypes.h" // FILENAME_* defines #if HAVE_CONFIG_H # include <config.h> #endif @@ -151,10 +152,10 @@ static void remove_comments_and_unescape(char *str) * 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_data_t &report, const char *field, const char *description) { - const map_crash_report_t::const_iterator it = report.find(field); + const map_crash_data_t::const_iterator it = report.find(field); if (it == report.end()) { // exit silently, all fields are optional for now @@ -186,22 +187,22 @@ static void write_crash_report_field(FILE *fp, const map_crash_report_t &report, * If the report is successfully stored to the file, a zero value is returned. * On failure, nonzero value is returned. */ -static void write_crash_report(const map_crash_report_t &report, FILE *fp) +static void write_crash_report(const map_crash_data_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, FILENAME_COMMENT, _("# Describe the circumstances of this crash below.")); - write_crash_report_field(fp, report, CD_REPRODUCE, + write_crash_report_field(fp, report, FILENAME_REPRODUCE, _("# How to reproduce the crash?")); - write_crash_report_field(fp, report, "backtrace", + write_crash_report_field(fp, report, FILENAME_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, CD_UUID, _("# UUID")); + write_crash_report_field(fp, report, CD_DUPHASH, "# DUPHASH"); write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture")); - write_crash_report_field(fp, report, "cmdline", _("# Command line")); + write_crash_report_field(fp, report, FILENAME_CMDLINE, _("# Command line")); write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component")); - write_crash_report_field(fp, report, "coredump", _("# Core dump")); + write_crash_report_field(fp, report, FILENAME_COREDUMP, _("# Core dump")); 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")); @@ -217,7 +218,7 @@ static void write_crash_report(const map_crash_report_t &report, FILE *fp) * 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_data_t &report, const char *field) { char separator[strlen("\n" FIELD_SEP) + strlen(field) + 2]; // 2 = '\n\0' @@ -234,7 +235,7 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, else length = end - textfield; - const map_crash_report_t::iterator it = report.find(field); + const map_crash_data_t::iterator it = report.find(field); if (it == report.end()) { error_msg("Field %s not found.\n", field); @@ -278,17 +279,17 @@ static int read_crash_report_field(const char *text, map_crash_report_t &report, * 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) +static int read_crash_report(map_crash_data_t &report, const char *text) { int result = 0; - 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, CD_UUID); + result |= read_crash_report_field(text, report, FILENAME_COMMENT); + result |= read_crash_report_field(text, report, FILENAME_REPRODUCE); + result |= read_crash_report_field(text, report, FILENAME_BACKTRACE); + result |= read_crash_report_field(text, report, CD_DUPHASH); result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE); - result |= read_crash_report_field(text, report, "cmdline"); + result |= read_crash_report_field(text, report, FILENAME_CMDLINE); result |= read_crash_report_field(text, report, FILENAME_COMPONENT); - result |= read_crash_report_field(text, report, "coredump"); + result |= read_crash_report_field(text, report, FILENAME_COREDUMP); 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); @@ -331,7 +332,7 @@ static int launch_editor(const char *path) int report(const char *uuid, bool always) { // Ask for an initial report. - map_crash_report_t cr = call_CreateReport(uuid); + map_crash_data_t cr = call_CreateReport(uuid); //TODO: error check? if (!always) diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp index 182aa6c2..f1f10e50 100644 --- a/src/Daemon/CommLayerServerDBus.cpp +++ b/src/Daemon/CommLayerServerDBus.cpp @@ -133,7 +133,7 @@ static long get_remote_uid(DBusMessage* call, const char** ppSender = NULL) static int handle_GetCrashInfos(DBusMessage* call, DBusMessage* reply) { long unix_uid = get_remote_uid(call); - vector_crash_infos_t argout1 = GetCrashInfos(to_string(unix_uid).c_str()); + vector_map_crash_data_t argout1 = GetCrashInfos(to_string(unix_uid).c_str()); DBusMessageIter out_iter; dbus_message_iter_init_append(reply, &out_iter); @@ -190,7 +190,8 @@ static int handle_CreateReport(DBusMessage* call, DBusMessage* reply) } long unix_uid = get_remote_uid(call); - map_crash_report_t report = CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0); + map_crash_data_t report; + CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0, report); DBusMessageIter out_iter; dbus_message_iter_init_append(reply, &out_iter); @@ -206,7 +207,7 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) DBusMessageIter in_iter; dbus_message_iter_init(call, &in_iter); - map_crash_report_t argin1; + map_crash_data_t argin1; r = load_val(&in_iter, argin1); if (r == ABRT_DBUS_ERROR) { @@ -214,9 +215,9 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) return -1; } - map_crash_report_t::const_iterator it_comment = argin1.find(CD_COMMENT); - map_crash_report_t::const_iterator it_reproduce = argin1.find(CD_REPRODUCE); + map_crash_data_t::const_iterator it_comment = argin1.find(FILENAME_COMMENT); const char* comment = (it_comment != argin1.end()) ? it_comment->second[CD_CONTENT].c_str() : ""; + map_crash_data_t::const_iterator it_reproduce = argin1.find(FILENAME_REPRODUCE); const char* reproduce = (it_reproduce != argin1.end()) ? it_reproduce->second[CD_CONTENT].c_str() : ""; const char* errmsg = NULL; if (strlen(comment) > LIMIT_MESSAGE) @@ -249,15 +250,14 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) } } +#if 0 //const char * sender = dbus_message_get_sender(call); if (!user_conf_data.empty()) { - std::string PluginName; map_map_string_t::const_iterator it_user_conf_data = user_conf_data.begin(); for (; it_user_conf_data != user_conf_data.end(); it_user_conf_data++) { - PluginName = it_user_conf_data->first; -#if DEBUG + std::string PluginName = it_user_conf_data->first; std::cout << "plugin name: " << it_user_conf_data->first; map_string_t::const_iterator it_plugin_config; for (it_plugin_config = it_user_conf_data->second.begin(); @@ -266,11 +266,11 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) { std::cout << " key: " << it_plugin_config->first << " value: " << it_plugin_config->second << std::endl; } -#endif // this would overwrite the default settings //g_pPluginManager->SetPluginSettings(PluginName, sender, plugin_settings); } } +#endif long unix_uid = get_remote_uid(call); report_status_t argout1; diff --git a/src/Daemon/CommLayerServerSocket.cpp b/src/Daemon/CommLayerServerSocket.cpp index 0c5f2e31..ab880fb2 100644 --- a/src/Daemon/CommLayerServerSocket.cpp +++ b/src/Daemon/CommLayerServerSocket.cpp @@ -130,14 +130,14 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan if (!strncmp(pMessage.c_str(), MESSAGE_GET_CRASH_INFOS, sizeof(MESSAGE_GET_CRASH_INFOS) - 1)) { - vector_crash_infos_t crashInfos = GetCrashInfos(UID); + vector_map_crash_data_t crashInfos = GetCrashInfos(UID); std::string message = MESSAGE_GET_CRASH_INFOS + crash_infos_to_string(crashInfos); Send(message, pSource); } else if (!strncmp(pMessage.c_str(), MESSAGE_REPORT, sizeof(MESSAGE_REPORT) - 1)) { std::string message = pMessage.substr(sizeof(MESSAGE_REPORT) - 1); - map_crash_report_t report = string_to_crash_report(message); + map_crash_data_t report = string_to_crash_report(message); map_plugin_settings_t plugin_settings; //FIXME: another hack to make this compile // Report(report, plugin_settings, UID); @@ -145,7 +145,8 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan else if (!strncmp(pMessage.c_str(), MESSAGE_CREATE_REPORT, sizeof(MESSAGE_CREATE_REPORT) - 1)) { // std::string UUID = pMessage.substr(sizeof(MESSAGE_CREATE_REPORT) - 1); -// map_crash_report_t crashReport = CreateReport(UUID, UID); +// map_crash_data_t crashReport; +// CreateReport(UUID, UID, crashReport); //use CreateReportThread instead of CreateReport? // std::string message = MESSAGE_CREATE_REPORT + crash_report_to_string(crashReport); // Send(message, pSource); @@ -211,22 +212,22 @@ CCommLayerServerSocket::~CCommLayerServerSocket() close(m_nSocket); } -vector_crash_infos_t CCommLayerServerSocket::GetCrashInfos(const std::string &pSender) +vector_map_crash_data_t CCommLayerServerSocket::GetCrashInfos(const std::string &pSender) { - vector_crash_infos_t crashInfos; + vector_map_crash_data_t crashInfos; crashInfos = ::GetCrashInfos(pSender); return crashInfos; } //reimplement as CreateReportThread(...)? -//map_crash_report_t CCommLayerServerSocket::CreateReport(const std::string &pUUID, const std::string &pSender) +//map_crash_data_t CCommLayerServerSocket::CreateReport(const std::string &pUUID, const std::string &pSender) //{ -// map_crash_report_t crashReport; +// map_crash_data_t crashReport; // crashReport = ::CreateReport(pUUID, pSender); // return crashReport; //} -report_status_t CCommLayerServerSocket::Report(const map_crash_report_t& pReport, const std::string& pSender) +report_status_t CCommLayerServerSocket::Report(const map_crash_data_t& pReport, const std::string& pSender) { report_status_t rs; //FIXME: a hack to make this compile, but we don't use sockets anyway diff --git a/src/Daemon/CommLayerServerSocket.h b/src/Daemon/CommLayerServerSocket.h index 753b67af..c511954c 100644 --- a/src/Daemon/CommLayerServerSocket.h +++ b/src/Daemon/CommLayerServerSocket.h @@ -26,8 +26,8 @@ class CCommLayerServerSocket : public CCommLayerServer CCommLayerServerSocket(); virtual ~CCommLayerServerSocket(); - virtual vector_crash_infos_t GetCrashInfos(const char *pSender); - virtual report_status_t Report(const map_crash_report_t& pReport, const char *pSender); + virtual vector_map_crash_data_t GetCrashInfos(const char *pSender); + virtual report_status_t Report(const map_crash_data_t& pReport, const char *pSender); virtual void DeleteDebugDump(const char *pUUID, const char *pSender); virtual void Crash(const char *arg1); diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp index 59f9e65b..93365f3b 100644 --- a/src/Daemon/CrashWatcher.cpp +++ b/src/Daemon/CrashWatcher.cpp @@ -45,9 +45,9 @@ CCrashWatcher::~CCrashWatcher() { } -vector_crash_infos_t GetCrashInfos(const char *pUID) +vector_map_crash_data_t GetCrashInfos(const char *pUID) { - vector_crash_infos_t retval; + vector_map_crash_data_t retval; log("Getting crash infos..."); try { @@ -57,12 +57,11 @@ vector_crash_infos_t GetCrashInfos(const char *pUID) unsigned int ii; for (ii = 0; ii < UUIDsUIDs.size(); ii++) { - mw_result_t res; - map_crash_info_t info; const char *uuid = UUIDsUIDs[ii].first.c_str(); const char *uid = UUIDsUIDs[ii].second.c_str(); - res = FillCrashInfo(uuid, uid, info); + map_crash_data_t info; + mw_result_t res = FillCrashInfo(uuid, uid, info); switch (res) { case MW_OK: @@ -96,10 +95,8 @@ vector_crash_infos_t GetCrashInfos(const char *pUID) * StartJob dbus call already did all the processing, and we just retrieve * the result from dump directory, which is fast. */ -map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) +void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t& crashReport) { - map_crash_info_t crashReport; - /* FIXME: starting from here, any shared data must be protected with a mutex. * For example, CreateCrashReport does: * g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); @@ -109,6 +106,7 @@ map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) switch (res) { case MW_OK: + VERB2 log_map_crash_data(crashReport, "crashReport"); break; case MW_IN_DB_ERROR: error_msg("Can't find crash with UUID %s in database", pUUID); @@ -121,7 +119,6 @@ map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force) DeleteDebugDump(pUUID, pUID); break; } - return crashReport; } typedef struct thread_data_t { @@ -141,7 +138,8 @@ static void* create_report(void* arg) try { log("Creating report..."); - map_crash_info_t crashReport = CreateReport(thread_data->UUID, thread_data->UID, thread_data->force); + map_crash_data_t crashReport; + CreateReport(thread_data->UUID, thread_data->UID, thread_data->force, crashReport); g_pCommLayer->JobDone(thread_data->peer, thread_data->UUID); } catch (CABRTException& e) diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h index 8d56c4ec..31b72e08 100644 --- a/src/Daemon/CrashWatcher.h +++ b/src/Daemon/CrashWatcher.h @@ -48,9 +48,9 @@ class CCrashWatcher virtual void Warning(const char *pMessage, const char* peer, uint64_t pJobID); }; -vector_crash_infos_t GetCrashInfos(const char *pUID); +vector_map_crash_data_t GetCrashInfos(const char *pUID); int CreateReportThread(const char* pUUID, const char* pUID, int force, const char* pSender); -map_crash_report_t CreateReport(const char* pUUID, const char* pUID, int force); +void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t&); int DeleteDebugDump(const char *pUUID, const char *pUID); void DeleteDebugDump_by_dir(const char *dump_dir); diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index dc547af3..83b1ceef 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -51,15 +51,15 @@ * - signal: we got SIGTERM or SIGINT * * DBus methods we have: - * - GetCrashInfos(): returns a vector_crash_infos_t (vector_map_vector_string_t) + * - GetCrashInfos(): returns a vector_map_crash_data_t (vector_map_vector_string_t) * of crashes for given uid * v[N]["executable"/"uid"/"kernel"/"backtrace"][N] = "contents" * - StartJob(UUID,force): starts creating a report for /var/cache/abrt/DIR with this UUID. * Returns job id (uint64). * After thread returns, when report creation thread has finished, * JobDone(client_dbus_ID,UUID) dbus signal is emitted. - * - CreateReport(UUID): returns map_crash_report_t (map_vector_string_t) - * - Report(map_crash_report_t (map_vector_string_t[, map_map_string_t])): + * - CreateReport(UUID): returns map_crash_data_t (map_vector_string_t) + * - Report(map_crash_data_t (map_vector_string_t[, map_map_string_t])): * "Please report this crash": calls Report() of all registered reporter plugins. * Returns report_status_t (map_vector_string_t) - the status of each call. * 2nd parameter is the contents of user's abrt.conf. @@ -320,15 +320,15 @@ static void FindNewDumps(const char* pPath) vector_string_t::iterator itt = dirs.begin(); for (; itt != dirs.end(); ++itt) { - map_crash_info_t crashinfo; try { + map_crash_data_t crashinfo; mw_result_t res = SaveDebugDump(itt->c_str(), crashinfo); switch (res) { case MW_OK: VERB1 log("Saving %s into database", itt->c_str()); - RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str()); + RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str()); break; case MW_IN_DB: VERB1 log("%s is already saved in database", itt->c_str()); @@ -476,17 +476,17 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin worst_dir = ""; } - map_crash_info_t crashinfo; try { std::string fullname = concat_path_file(DEBUG_DUMPS_DIR, name); - +//todo: rename SaveDebugDump to ???? it does not save crashinfo, it FETCHES crashinfo + map_crash_data_t crashinfo; mw_result_t res = SaveDebugDump(fullname.c_str(), crashinfo); switch (res) { case MW_OK: log("New crash, saving"); - RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str()); + RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str()); /* Fall through */ case MW_REPORTED: case MW_OCCURED: @@ -494,16 +494,16 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin if (res != MW_OK) log("Already saved crash, just sending dbus signal"); - const char *analyzer = crashinfo[CD_MWANALYZER][CD_CONTENT].c_str(); - const char *uid_str = crashinfo[CD_UID][CD_CONTENT].c_str(); + const char *analyzer = get_crash_data_item_content(crashinfo, FILENAME_ANALYZER).c_str(); + const char *uid_str = get_crash_data_item_content(crashinfo, FILENAME_UID).c_str(); /* Autoreport it if configured to do so */ if (analyzer_has_AutoReportUIDs(analyzer, uid_str)) { VERB1 log("Reporting the crash automatically"); - map_crash_report_t crash_report; + map_crash_data_t crash_report; mw_result_t crash_result = CreateCrashReport( - crashinfo[CD_UUID][CD_CONTENT].c_str(), + get_crash_data_item_content(crashinfo, CD_UUID).c_str(), uid_str, /*force:*/ 0, crash_report ); if (crash_result == MW_OK) @@ -525,7 +525,7 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin /* Send dbus signal */ if (analyzer_has_InformAllUsers(analyzer)) uid_str = NULL; - g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT].c_str(), uid_str); + g_pCommLayer->Crash(get_crash_data_item_content(crashinfo, FILENAME_PACKAGE).c_str(), uid_str); break; } case MW_BLACKLISTED: diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp index c2a122a7..9abb737b 100644 --- a/src/Daemon/MiddleWare.cpp +++ b/src/Daemon/MiddleWare.cpp @@ -85,8 +85,8 @@ static char* is_text_file(const char *name, ssize_t *sz) } /* Some files in our dump directories are known to always be textual */ - if (strcmp(name, "backtrace") == 0 - || strcmp(name, "cmdline") == 0 + if (strcmp(name, FILENAME_BACKTRACE) == 0 + || strcmp(name, FILENAME_CMDLINE) == 0 ) { return buf; } @@ -120,29 +120,11 @@ static char* is_text_file(const char *name, ssize_t *sz) return NULL; /* it's binary */ } -/** - * Transforms a debugdump direcortry to inner crash - * report form. This form is used for later reporting. - * @param pDebugDumpDir A debugdump dir containing all necessary data. - * @param pCrashReport A created crash report. - */ -static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t& pCrashReport) +static void load_crash_data_from_debug_dump(CDebugDump& dd, map_crash_data_t& data) { - CDebugDump dd; - dd.Open(pDebugDumpDir); - if (!dd.Exist(FILENAME_ARCHITECTURE) - || !dd.Exist(FILENAME_KERNEL) - || !dd.Exist(FILENAME_PACKAGE) - || !dd.Exist(FILENAME_COMPONENT) - || !dd.Exist(FILENAME_RELEASE) - || !dd.Exist(FILENAME_EXECUTABLE) - ) { - throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): One or more of important file(s) are missing"); - } - std::string short_name; std::string full_name; - pCrashReport.clear(); + dd.InitGetNextFile(); while (dd.GetNextFile(&short_name, &full_name)) { @@ -150,11 +132,11 @@ static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t char *text = is_text_file(full_name.c_str(), &sz); if (!text) { - add_crash_data_to_crash_report(pCrashReport, - short_name, - CD_BIN, - CD_ISNOTEDITABLE, - full_name + add_to_crash_data_ext(data, + short_name.c_str(), + CD_BIN, + CD_ISNOTEDITABLE, + full_name.c_str() ); continue; } @@ -166,33 +148,39 @@ static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t dd.LoadText(short_name.c_str(), content); free(text); - if (short_name == FILENAME_ARCHITECTURE - || short_name == FILENAME_KERNEL - || short_name == FILENAME_PACKAGE - || short_name == FILENAME_COMPONENT - || short_name == FILENAME_RELEASE - || short_name == FILENAME_EXECUTABLE - ) { - add_crash_data_to_crash_report(pCrashReport, short_name, CD_TXT, CD_ISNOTEDITABLE, content); - continue; - } + add_to_crash_data_ext(data, + short_name.c_str(), + CD_TXT, + is_editable_file(short_name.c_str()) ? CD_ISEDITABLE : CD_ISNOTEDITABLE, + content.c_str() + ); + } +} - if (short_name != FILENAME_UID - && short_name != FILENAME_ANALYZER - && short_name != FILENAME_TIME - && short_name != FILENAME_DESCRIPTION - && short_name != FILENAME_REPRODUCE - && short_name != FILENAME_COMMENT - ) { - add_crash_data_to_crash_report( - pCrashReport, - short_name, - CD_TXT, - CD_ISEDITABLE, - content - ); +/** + * Transforms a debugdump directory to inner crash + * report form. This form is used for later reporting. + * @param pDebugDumpDir A debugdump dir containing all necessary data. + * @param pCrashData A created crash report. + */ +static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_data_t& pCrashData) +{ + VERB3 log(" DebugDumpToCrashReport('%s')", pDebugDumpDir); + + CDebugDump dd; + dd.Open(pDebugDumpDir); + + const char *const *v = must_have_files; + while (*v) + { + if (!dd.Exist(*v)) + { + throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): important file '%s' is missing", *v); } + v++; } + + load_crash_data_from_debug_dump(dd, pCrashData); } /** @@ -235,7 +223,7 @@ static std::string GetGlobalUUID(const char *pAnalyzer, * @param pAnalyzer A name of an analyzer plugin. * @param pDebugDumpPath A debugdump dir containing all necessary data. */ -static void CreateReport(const char *pAnalyzer, +static void run_analyser_CreateReport(const char *pAnalyzer, const char *pDebugDumpDir, int force) { @@ -250,7 +238,7 @@ static void CreateReport(const char *pAnalyzer, mw_result_t CreateCrashReport(const char *pUUID, const char *pUID, int force, - map_crash_report_t& pCrashReport) + map_crash_data_t& pCrashData) { VERB2 log("CreateCrashReport('%s','%s',result)", pUUID, pUID); @@ -268,64 +256,56 @@ mw_result_t CreateCrashReport(const char *pUUID, return MW_IN_DB_ERROR; } + mw_result_t r = MW_OK; try { - CDebugDump dd; - std::string analyzer; - std::string gUUID; - std::string comment; - std::string reproduce = "1.\n2.\n3.\n"; - - VERB3 log(" LoadText(FILENAME_ANALYZER,'%s')", row.m_sDebugDumpDir.c_str()); - dd.Open(row.m_sDebugDumpDir.c_str()); - dd.LoadText(FILENAME_ANALYZER, analyzer); - if (dd.Exist(FILENAME_COMMENT)) - { - dd.LoadText(FILENAME_COMMENT, comment); - } - if (dd.Exist(FILENAME_REPRODUCE)) { - dd.LoadText(FILENAME_REPRODUCE, reproduce); + CDebugDump dd; + dd.Open(row.m_sDebugDumpDir.c_str()); + load_crash_data_from_debug_dump(dd, pCrashData); } - dd.Close(); - VERB3 log(" CreateReport('%s')", analyzer.c_str()); - CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force); + std::string analyzer = get_crash_data_item_content(pCrashData, FILENAME_ANALYZER); - gUUID = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); - VERB3 log(" GetGlobalUUID:'%s'", gUUID.c_str()); + // TODO: explain what run_analyser_CreateReport and RunAnalyzerActions are expected to do. + // Do they potentially add more files to dump dir? + // Why we calculate dup_hash after run_analyser_CreateReport but before RunAnalyzerActions? + // Why do we reload dump dir's data via DebugDumpToCrashReport? - VERB3 log(" RunAnalyzerActions"); + VERB3 log(" run_analyser_CreateReport('%s')", analyzer.c_str()); + run_analyser_CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force); + + std::string dup_hash = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); + VERB3 log(" DUPHASH:'%s'", dup_hash.c_str()); + + VERB3 log(" RunAnalyzerActions('%s','%s')", analyzer.c_str(), row.m_sDebugDumpDir.c_str()); RunAnalyzerActions(analyzer.c_str(), row.m_sDebugDumpDir.c_str()); - VERB3 log(" DebugDumpToCrashReport"); - DebugDumpToCrashReport(row.m_sDebugDumpDir.c_str(), pCrashReport); - add_crash_data_to_crash_report(pCrashReport, CD_UUID, CD_TXT, CD_ISNOTEDITABLE, gUUID); - add_crash_data_to_crash_report(pCrashReport, CD_MWANALYZER, CD_SYS, CD_ISNOTEDITABLE, analyzer); - add_crash_data_to_crash_report(pCrashReport, CD_MWUID, CD_SYS, CD_ISNOTEDITABLE, pUID); - add_crash_data_to_crash_report(pCrashReport, CD_MWUUID, CD_SYS, CD_ISNOTEDITABLE, pUUID); - add_crash_data_to_crash_report(pCrashReport, CD_COMMENT, CD_TXT, CD_ISEDITABLE, comment); - add_crash_data_to_crash_report(pCrashReport, CD_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce); + DebugDumpToCrashReport(row.m_sDebugDumpDir.c_str(), pCrashData); + + add_to_crash_data_ext(pCrashData, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, dup_hash.c_str()); + add_to_crash_data_ext(pCrashData, CD_UUID , CD_SYS, CD_ISNOTEDITABLE, pUUID); } catch (CABRTException& e) { + r = MW_CORRUPTED; error_msg("%s", e.what()); if (e.type() == EXCEP_DD_OPEN) { - return MW_ERROR; + r = MW_ERROR; } - if (e.type() == EXCEP_DD_LOAD) + else if (e.type() == EXCEP_DD_LOAD) { - return MW_FILE_ERROR; + r = MW_FILE_ERROR; } - if (e.type() == EXCEP_PLUGIN) + else if (e.type() == EXCEP_PLUGIN) { - return MW_PLUGIN_ERROR; + r = MW_PLUGIN_ERROR; } - return MW_CORRUPTED; } - return MW_OK; + VERB3 log("CreateCrashReport() returns %d", r); + return r; } void RunAction(const char *pActionDir, @@ -362,7 +342,7 @@ void RunActionsAndReporters(const char *pDebugDumpDir) if (tp == REPORTER) { CReporter* reporter = g_pPluginManager->GetReporter(plugin_name); /* can't be NULL */ - map_crash_report_t crashReport; + map_crash_data_t crashReport; DebugDumpToCrashReport(pDebugDumpDir, crashReport); VERB2 log("%s.Report(...)", plugin_name); reporter->Report(crashReport, plugin_settings, it_ar->second.c_str()); @@ -382,88 +362,70 @@ void RunActionsAndReporters(const char *pDebugDumpDir) } -static bool CheckReport(const map_crash_report_t& pCrashReport) -{ - map_crash_report_t::const_iterator it_analyzer = pCrashReport.find(CD_MWANALYZER); - map_crash_report_t::const_iterator it_mwuid = pCrashReport.find(CD_MWUID); - map_crash_report_t::const_iterator it_mwuuid = pCrashReport.find(CD_MWUUID); - - map_crash_report_t::const_iterator it_package = pCrashReport.find(FILENAME_PACKAGE); - map_crash_report_t::const_iterator it_architecture = pCrashReport.find(FILENAME_ARCHITECTURE); - map_crash_report_t::const_iterator it_kernel = pCrashReport.find(FILENAME_KERNEL); - map_crash_report_t::const_iterator it_component = pCrashReport.find(FILENAME_COMPONENT); - map_crash_report_t::const_iterator it_release = pCrashReport.find(FILENAME_RELEASE); - map_crash_report_t::const_iterator it_executable = pCrashReport.find(FILENAME_EXECUTABLE); - - map_crash_report_t::const_iterator end = pCrashReport.end(); - - if (it_package == end) - { - return false; - } - - // FIXME: bypass the test if it's kerneloops - if (it_package->second[CD_CONTENT] == "kernel") - return true; - - if (it_analyzer == end || it_mwuid == end || - it_mwuuid == end || /* it_package == end || */ - it_architecture == end || it_kernel == end || - it_component == end || it_release == end || - it_executable == end) - { - return false; - } - - if (it_analyzer->second[CD_CONTENT] == "" || it_mwuid->second[CD_CONTENT] == "" || - it_mwuuid->second[CD_CONTENT] == "" || it_package->second[CD_CONTENT] == "" || - it_architecture->second[CD_CONTENT] == "" || it_kernel->second[CD_CONTENT] == "" || - it_component->second[CD_CONTENT] == "" || it_release->second[CD_CONTENT] == "" || - it_executable->second[CD_CONTENT] == "") - { - return false; - } - - return true; -} - -report_status_t Report(const map_crash_report_t& pCrashReport, +// We must not trust client_report here! +// dbus handler passes it from user without checking +report_status_t Report(const map_crash_data_t& client_report, map_map_string_t& pSettings, const char *pUID) { - report_status_t ret; - - /* dbus handler passes pCrashReport from user without checking it */ - - if (!CheckReport(pCrashReport)) - { - throw CABRTException(EXCEP_ERROR, "Report(): Some of mandatory report data are missing."); - } - - std::string analyzer = pCrashReport.find(CD_MWANALYZER)->second[CD_CONTENT]; - std::string UID = pCrashReport.find(CD_MWUID)->second[CD_CONTENT]; - std::string UUID = pCrashReport.find(CD_MWUUID)->second[CD_CONTENT]; - std::string packageNVR = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1)); - - // Save comment and "how to reproduce" - map_crash_report_t::const_iterator it_comment = pCrashReport.find(CD_COMMENT); - map_crash_report_t::const_iterator it_reproduce = pCrashReport.find(CD_REPRODUCE); - if (it_comment != pCrashReport.end() || it_reproduce != pCrashReport.end()) + // Get ID fields + const char *UID = get_crash_data_item_content_or_NULL(client_report, FILENAME_UID); + const char *UUID = get_crash_data_item_content_or_NULL(client_report, CD_UUID); + if (!UID || !UUID) { + throw CABRTException(EXCEP_ERROR, "Report(): UID or UUID is missing in client's report data"); + } + + // Retrieve corresponding stored record + map_crash_data_t stored_report; + mw_result_t r = FillCrashInfo(UUID, UID, stored_report); + if (r != MW_OK) + return report_status_t(); + const std::string& pDumpDir = get_crash_data_item_content(stored_report, CD_DUMPDIR); + + // Save comment, "how to reproduce", backtrace + const char *comment = get_crash_data_item_content_or_NULL(client_report, FILENAME_COMMENT); + const char *reproduce = get_crash_data_item_content_or_NULL(client_report, FILENAME_REPRODUCE); + const char *backtrace = get_crash_data_item_content_or_NULL(client_report, FILENAME_BACKTRACE); + if (comment || reproduce || backtrace) { - std::string pDumpDir = getDebugDumpDir(UUID.c_str(), UID.c_str()); CDebugDump dd; dd.Open(pDumpDir.c_str()); - if (it_comment != pCrashReport.end()) + if (comment) + { + dd.SaveText(FILENAME_COMMENT, comment); + add_to_crash_data_ext(stored_report, FILENAME_COMMENT, CD_TXT, CD_ISEDITABLE, comment); + } + if (reproduce) { - dd.SaveText(FILENAME_COMMENT, it_comment->second[CD_CONTENT].c_str()); + dd.SaveText(FILENAME_REPRODUCE, reproduce); + add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce); } - if (it_reproduce != pCrashReport.end()) + if (backtrace) { - dd.SaveText(FILENAME_REPRODUCE, it_reproduce->second[CD_CONTENT].c_str()); + dd.SaveText(FILENAME_BACKTRACE, backtrace); + add_to_crash_data_ext(stored_report, FILENAME_BACKTRACE, CD_TXT, CD_ISEDITABLE, backtrace); } } + const std::string& analyzer = get_crash_data_item_content(stored_report, FILENAME_ANALYZER); + + std::string dup_hash = GetGlobalUUID(analyzer.c_str(), pDumpDir.c_str()); + VERB3 log(" DUPHASH:'%s'", dup_hash.c_str()); + add_to_crash_data_ext(stored_report, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, dup_hash.c_str()); + + // Run reporters + + VERB3 { + log("Run reporters"); + log_map_crash_data(client_report, " client_report"); + log_map_crash_data(stored_report, " stored_report"); + } +#define client_report client_report_must_not_be_used_below + + map_crash_data_t::const_iterator its_PACKAGE = stored_report.find(FILENAME_PACKAGE); + std::string packageNVR = its_PACKAGE->second[CD_CONTENT]; + std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1)); + // analyzer with package name (CCpp:xorg-x11-app) has higher priority std::string key = analyzer + ":" + packageName; map_analyzer_actions_and_reporters_t::iterator end = s_mapAnalyzerActionsAndReporters.end(); @@ -475,6 +437,7 @@ report_status_t Report(const map_crash_report_t& pCrashReport, key = analyzer; } + report_status_t ret; std::string message; if (keyPtr != end) { @@ -509,7 +472,7 @@ report_status_t Report(const map_crash_report_t& pCrashReport, } #endif map_plugin_settings_t plugin_settings = pSettings[plugin_name]; - std::string res = reporter->Report(pCrashReport, plugin_settings, it_r->second.c_str()); + std::string res = reporter->Report(stored_report, plugin_settings, it_r->second.c_str()); #if 0 /* Using ~user/.abrt/ is bad wrt security */ if (home != "") @@ -535,10 +498,11 @@ report_status_t Report(const map_crash_report_t& pCrashReport, CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); - database->SetReported(UUID.c_str(), UID.c_str(), message.c_str()); + database->SetReported(UUID, UID, message.c_str()); database->DisConnect(); return ret; +#undef client_report } /** @@ -767,7 +731,7 @@ bool analyzer_has_AutoReportUIDs(const char *analyzer_name, const char* uid) return false; } -void autoreport(const pair_string_string_t& reporter_options, const map_crash_report_t& crash_report) +void autoreport(const pair_string_string_t& reporter_options, const map_crash_data_t& crash_report) { CReporter* reporter = g_pPluginManager->GetReporter(reporter_options.first.c_str()); if (!reporter) @@ -821,14 +785,14 @@ static void RunAnalyzerActions(const char *pAnalyzer, const char *pDebugDumpDir) * @param pUID An UID of an user. * @param pTime Time when a crash occurs. * @param pDebugDumpPath A debugdump path. - * @param pCrashInfo A filled crash info. + * @param pCrashData A filled crash info. * @return It return results of operation. See mw_result_t. */ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, const char *pUID, const char *pTime, const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -837,7 +801,7 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, database_row_t row = database->GetRow(pUUID, pUID); database->DisConnect(); - mw_result_t res = FillCrashInfo(pUUID, pUID, pCrashInfo); + mw_result_t res = FillCrashInfo(pUUID, pUID, pCrashData); if (res == MW_OK) { if (row.m_sReported == "1") @@ -854,8 +818,7 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID, return res; } -std::string getDebugDumpDir(const char *pUUID, - const char *pUID) +std::string getDebugDumpDir(const char *pUUID, const char *pUID) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -865,7 +828,7 @@ std::string getDebugDumpDir(const char *pUUID, } mw_result_t SaveDebugDump(const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { std::string UID; std::string time; @@ -907,12 +870,12 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, const char *uid_str = analyzer_has_InformAllUsers(analyzer.c_str()) ? "-1" : UID.c_str(); - return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashInfo); + return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashData); } mw_result_t FillCrashInfo(const char *pUUID, const char *pUID, - map_crash_info_t& pCrashInfo) + map_crash_data_t& pCrashData) { CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str()); database->Connect(); @@ -927,10 +890,7 @@ mw_result_t FillCrashInfo(const char *pUUID, { CDebugDump dd; dd.Open(row.m_sDebugDumpDir.c_str()); - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - dd.LoadText(FILENAME_DESCRIPTION, description); - dd.LoadText(FILENAME_ANALYZER, analyzer); + load_crash_data_from_debug_dump(dd, pCrashData); } catch (CABRTException& e) { @@ -938,18 +898,14 @@ mw_result_t FillCrashInfo(const char *pUUID, return MW_ERROR; } - pCrashInfo.clear(); - add_crash_data_to_crash_info(pCrashInfo, CD_EXECUTABLE, executable); - add_crash_data_to_crash_info(pCrashInfo, CD_PACKAGE, package); - add_crash_data_to_crash_info(pCrashInfo, CD_DESCRIPTION, description); - add_crash_data_to_crash_info(pCrashInfo, CD_UUID, row.m_sUUID); - add_crash_data_to_crash_info(pCrashInfo, CD_UID, row.m_sUID); - add_crash_data_to_crash_info(pCrashInfo, CD_COUNT, row.m_sCount); - add_crash_data_to_crash_info(pCrashInfo, CD_TIME, row.m_sTime); - add_crash_data_to_crash_info(pCrashInfo, CD_REPORTED, row.m_sReported); - add_crash_data_to_crash_info(pCrashInfo, CD_MESSAGE, row.m_sMessage); - add_crash_data_to_crash_info(pCrashInfo, CD_MWDDD, row.m_sDebugDumpDir); - add_crash_data_to_crash_info(pCrashInfo, CD_MWANALYZER, analyzer); + add_to_crash_data(pCrashData, CD_UUID , row.m_sUUID.c_str() ); + add_to_crash_data(pCrashData, CD_COUNT , row.m_sCount.c_str() ); + add_to_crash_data(pCrashData, CD_REPORTED , row.m_sReported.c_str() ); + add_to_crash_data(pCrashData, CD_MESSAGE , row.m_sMessage.c_str() ); + add_to_crash_data(pCrashData, CD_DUMPDIR , row.m_sDebugDumpDir.c_str()); +//TODO: why do we keep uid and time in DB and in dumpdir?! + add_to_crash_data(pCrashData, FILENAME_UID , row.m_sUID.c_str() ); + add_to_crash_data(pCrashData, FILENAME_TIME , row.m_sTime.c_str() ); return MW_OK; } diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h index b2b58dcd..5fab84d3 100644 --- a/src/Daemon/MiddleWare.h +++ b/src/Daemon/MiddleWare.h @@ -60,13 +60,13 @@ void LoadOpenGPGPublicKey(const char* key); * is successful, then a crash report is filled. * @param pAnalyzer A name of an analyzer plugin. * @param pDebugDumpPath A debugdump dir containing all necessary data. - * @param pCrashReport A filled crash report. + * @param pCrashData A filled crash report. * @return It return results of operation. See mw_result_t. */ mw_result_t CreateCrashReport(const char *pUUID, const char *pUID, int force, - map_crash_report_t& pCrashReport); + map_crash_data_t& pCrashData); /** * Activates particular action plugin. * @param pActionDir A directory, which is passed as working to a action plugin. @@ -88,11 +88,11 @@ void RunActionsAndReporters(const char *pDebugDumpDir); * fails, then default config is used. If pUID is emply string, default * config is used. * ...). - * @param pCrashReport A crash report. + * @param pCrashData A crash report. * @param pUID An user uid * @return A report status, which reporters ends successfuly with messages. */ -report_status_t Report(const map_crash_report_t& pCrashReport, +report_status_t Report(const map_crash_data_t& pCrashData, map_map_string_t& pSettings, const char *pUID); /** @@ -108,22 +108,22 @@ std::string getDebugDumpDir( const char *pUUID, * Saves debugdump into database. If saving is successful, * it fills crash info. * @param pDebugDumpDir A debugdump directory. - * @param pCrashInfo A crash info. + * @param pCrashData A crash info. * @return It return results of operation. See mw_result_t. */ mw_result_t SaveDebugDump(const char *pDebugDumpDir, - map_crash_info_t& pCrashInfo); + map_crash_data_t& pCrashData); /** * Get one crash info. If getting is successful, * then crash info is filled. * @param pUUID A local UUID of a crash. * @param pUID An UID of an user. - * @param pCrashInfo A crash info. + * @param pCrashData A crash info. * @return It return results of operation. See mw_result_t. */ mw_result_t FillCrashInfo(const char *pUUID, const char *pUID, - map_crash_info_t& pCrashInfo); + map_crash_data_t& pCrashData); /** * Gets all local UUIDs and UIDs of crashes. These crashes * occurred when a particular user was logged in. @@ -154,5 +154,5 @@ bool analyzer_has_InformAllUsers(const char *analyzer_name); bool analyzer_has_AutoReportUIDs(const char *analyzer_name, const char* uid); -void autoreport(const pair_string_string_t& reporter_options, const map_crash_report_t& crash_report); +void autoreport(const pair_string_string_t& reporter_options, const map_crash_data_t& crash_report); #endif /*MIDDLEWARE_H_*/ diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp index 48658e28..6cf32a68 100644 --- a/src/Daemon/Settings.cpp +++ b/src/Daemon/Settings.cpp @@ -77,7 +77,7 @@ static set_string_t ParseList(const char* pList) return set; } -/* (What format do we parse here?) */ +/* Format: name, name(param),name("param with spaces \"and quotes\"") */ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) { VERB3 log(" ParseListWithArgs(%s)", pValue); @@ -92,7 +92,6 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) { if (is_quote && pValue[ii] == '\\' && pValue[ii+1]) { - item += pValue[ii]; ii++; item += pValue[ii]; continue; @@ -100,7 +99,7 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) if (pValue[ii] == '"') { is_quote = !is_quote; - item += pValue[ii]; + /*item += pValue[ii]; - wrong! name("param") must be == name(param) */ continue; } if (is_quote) @@ -146,8 +145,8 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue) static void ParseCommon() { - map_string_t::const_iterator it = s_mapSectionCommon.find("OpenGPGCheck"); map_string_t::const_iterator end = s_mapSectionCommon.end(); + map_string_t::const_iterator it = s_mapSectionCommon.find("OpenGPGCheck"); if (it != end) { g_settings_bOpenGPGCheck = string_to_bool(it->second.c_str()); diff --git a/src/Daemon/abrt.conf b/src/Daemon/abrt.conf index f7811845..53e71a37 100644 --- a/src/Daemon/abrt.conf +++ b/src/Daemon/abrt.conf @@ -14,10 +14,11 @@ BlackList = nspluginwrapper Database = SQLite3 # Max size for crash storage [MiB] MaxCrashReportsSize = 1000 -# Vector of actions and reporters which are activated immediately after a crash occurs +# Vector of actions and reporters which are activated immediately after a crash occurs, +# comma separated. #ActionsAndReporters = Mailx("[abrt] new crash was detected") -# What actions or reporters to run on specified crash type +# What actions or reporters to run on each crash type [ AnalyzerActionsAndReporters ] Kerneloops = TicketUploader CCpp = TicketUploader @@ -29,3 +30,4 @@ Python = TicketUploader # h:m - at h:m an action plugin is activated # s - every s seconds is an action plugin activated 120 = KerneloopsScanner +#02:00 = FileTransfer diff --git a/src/Gui/CCDump.py b/src/Gui/CCDump.py index 96d036c4..1f290929 100644 --- a/src/Gui/CCDump.py +++ b/src/Gui/CCDump.py @@ -3,20 +3,55 @@ from datetime import datetime from abrt_utils import _, init_logging, log, log1, log2 +# Should match CrashTypes.h! CD_TYPE = 0 CD_EDITABLE = 1 CD_CONTENT = 2 +CD_SYS = "s" +CD_BIN = "b" +CD_TXT = "t" + +FILENAME_ARCHITECTURE = "architecture" +FILENAME_KERNEL = "kernel" +FILENAME_TIME = "time" +FILENAME_UID = "uid" +FILENAME_PACKAGE = "package" +FILENAME_COMPONENT = "component" +FILENAME_DESCRIPTION = "description" +FILENAME_ANALYZER = "analyzer" +FILENAME_RELEASE = "release" +FILENAME_EXECUTABLE = "executable" +FILENAME_REASON = "reason" +FILENAME_COMMENT = "comment" +FILENAME_REPRODUCE = "reproduce" +FILENAME_RATING = "rating" +FILENAME_CMDLINE = "cmdline" +FILENAME_COREDUMP = "coredump" +FILENAME_BACKTRACE = "backtrace" +FILENAME_MEMORYMAP = "memorymap" +FILENAME_KERNELOOPS = "kerneloops" + +CD_DUPHASH = "DUPHASH" +CD_UUID = "UUID" +CD_DUMPDIR = "DumpDir" +CD_COUNT = "Count" +CD_REPORTED = "Reported" +CD_MESSAGE = "Message" + +# FIXME - create method or smth that returns type|editable|content + + class Dump(): """Class for mapping the debug dump to python object""" def __init__(self): self.UUID = None - self.UID = None + self.uid = None self.Count = None - self.Executable = None - self.Package = None - self.Time = None - self.Description = None + self.executable = None + self.package = None + self.time = None + self.description = None self.Message = None self.Reported = None @@ -24,16 +59,16 @@ class Dump(): return self.UUID[CD_CONTENT] def getUID(self): - return self.UID[CD_CONTENT] + return self.uid[CD_CONTENT] def getCount(self): return self.Count[CD_CONTENT] def getExecutable(self): - return self.Executable[CD_CONTENT] + return self.executable[CD_CONTENT] def getPackage(self): - return self.Package[CD_CONTENT] + return self.package[CD_CONTENT] def isReported(self): return self.Reported[CD_CONTENT] == "1" @@ -44,17 +79,17 @@ class Dump(): #return self.Message[CD_CONTENT].split('\n') return self.Message[CD_CONTENT] - def getTime(self,format): + def getTime(self, format): #print format if format: try: - return datetime.fromtimestamp(int(self.Time[CD_CONTENT])).strftime(format) + return datetime.fromtimestamp(int(self.time[CD_CONTENT])).strftime(format) except Exception, e: print e - return int(self.Time[CD_CONTENT]) + return int(self.time[CD_CONTENT]) def getPackageName(self): - return self.Package[CD_CONTENT][:self.Package[CD_CONTENT].find("-")] + return self.package[CD_CONTENT][:self.package[CD_CONTENT].find("-")] def getDescription(self): - return self.Description[CD_CONTENT] + return self.description[CD_CONTENT] diff --git a/src/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py index a8101d49..b7b571d1 100644 --- a/src/Gui/CCMainWindow.py +++ b/src/Gui/CCMainWindow.py @@ -25,6 +25,7 @@ from ConfBackend import getCurrentConfBackend, ConfBackendInitError import CCDBusBackend from CC_gui_functions import * from CCDumpList import getDumpList, DumpList +from CCDump import * # FILENAME_xxx, CD_xxx from CCReporterDialog import ReporterDialog from PluginsSettingsDialog import PluginsSettingsDialog from SettingsDialog import SettingsDialog @@ -229,21 +230,29 @@ class MainWindow(): # this should work until we keep the row object in the last position dump = dumpsListStore.get_value(dumpsListStore.get_iter(path[0]), dumpsListStore.get_n_columns()-1) #move this to Dump class + lReported = self.wTree.get_widget("lReported") if dump.isReported(): + report_label_raw = _("This crash has been reported:\n") report_label = _("<b>This crash has been reported:</b>\n") # plugin message follows, but at least in case of kerneloops, # it is not informative (no URL to the report) - for message in dump.getMessage().split('\n'): + for message in dump.getMessage().split(';'): if message: - #Doesn't work (far too easy to make it worse, not better): - #if "http" in message[0:5] or "file:///"[0:8] in message: - # message = "<a href=\"%s\">%s</a>" % (message, message) - report_label += "%s\n" % message + message_clean = message.strip() + if "http" in message_clean[0:5] or "file:///"[0:8] in message_clean: + report_message = "<a href=\"%s\">%s</a>" % (message_clean, message_clean) + else: + report_message = message_clean + report_label += "%s\n" % report_message + report_label_raw += "%s\n" % message_clean log2("setting markup '%s'", report_label) - self.wTree.get_widget("lReported").set_markup(report_label) + lReported.set_text(report_label_raw) + # Sometimes (!) set_markup() fails with + # "GtkWarning: Failed to set text from markup due to error parsing markup: Unknown tag 'a'" + # If it does, then set_text() above acts as a fallback + lReported.set_markup(report_label) else: - self.wTree.get_widget("lReported").set_markup(_("<b>Not reported!</b>")) - lPackage = self.wTree.get_widget("lPackage") + lReported.set_markup(_("<b>Not reported!</b>")) def on_bDelete_clicked(self, button, treeview): dumpsListStore, path = self.dlist.get_selection().get_selected_rows() @@ -301,14 +310,8 @@ class MainWindow(): try: self.pBarWindow.show_all() self.timer = gobject.timeout_add(100, self.progress_update_cb) - # Old way: it needs to talk to daemon - #reporters_settings = {} - ## self.pluginlist = getPluginInfoList(self.ccdaemon, refresh=True) - ## don't force refresh! - #self.pluginlist = getPluginInfoList(self.ccdaemon) - #for plugin in self.pluginlist.getReporterPlugins(): - # reporters_settings[str(plugin)] = plugin.Settings - reporters_settings = getCurrentConfBackend().load_all() + pluginlist = getPluginInfoList(self.ccdaemon) + reporters_settings = pluginlist.getReporterPluginsSettings() log2("Report(result,settings):") log2(" result:%s", str(result)) # Careful, this will print reporters_settings["Password"] too @@ -329,7 +332,7 @@ class MainWindow(): # show the report window with selected report try: - self.ccdaemon.getReport(report["_MWUUID"][2], force=1) + self.ccdaemon.getReport(report[CD_UUID][CD_CONTENT], force=1) except Exception, e: # FIXME #3 dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply # do this async and wait for yum to end with debuginfoinstal diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py index 2cba6074..023cc6e5 100644 --- a/src/Gui/CCReporterDialog.py +++ b/src/Gui/CCReporterDialog.py @@ -11,16 +11,10 @@ from ABRTPlugin import PluginInfo from PluginSettingsUI import PluginSettingsUI from PluginList import getPluginInfoList #from CCDumpList import getDumpList, DumpList +from CCDump import * # FILENAME_xxx, CD_xxx from abrt_utils import _, log, log1, log2 # FIXME - create method or smth that returns type|editable|content -CD_TYPE = 0 -CD_EDITABLE = 1 -CD_CONTENT = 2 - -CD_SYS = "s" -CD_BIN = "b" -CD_TXT = "t" # response REFRESH = -50 @@ -34,12 +28,11 @@ class ReporterDialog(): self.report = report #Set the Glade file # FIXME add to path - builderfile = "%s%sreport.glade" % (sys.path[0],"/") + builderfile = "%s/report.glade" % sys.path[0] self.builder = gtk.Builder() self.builder.add_from_file(builderfile) #Get the Main Window, and connect the "destroy" event self.window = self.builder.get_object("reporter_dialog") - self.window.set_default_size(640, 480) self.window.connect("response", self.on_response, daemon) if parent: self.window.set_transient_for(parent) @@ -48,24 +41,23 @@ class ReporterDialog(): # comment textview self.tvComment = self.builder.get_object("tvComment") self.tvComment.connect("focus-in-event", self.on_comment_focus_cb) - self.comment_changed = False + self.show_hint_comment = 1 # "how to reproduce" textview self.tevHowToReproduce = self.builder.get_object("tevHowToReproduce") - self.how_to_changed = False - self.builder.get_object("ebErrors").hide() + self.builder.get_object("fErrors").hide() self.builder.get_object("bLog").connect("clicked", self.show_log_cb, log) self.builder.get_object("cbSendBacktrace").connect("toggled", self.on_send_backtrace_toggled) self.allow_send() self.hydrate() - + def check_backtrace(self): print "checking backtrace" - + def warn_user(self, warnings): # FIXME: show in lError - ebErrors = self.builder.get_object("ebErrors") + fErrors = self.builder.get_object("fErrors") lErrors = self.builder.get_object("lErrors") warning_lbl = None for warning in warnings: @@ -74,13 +66,13 @@ class ReporterDialog(): else: warning_lbl = "* %s" % warning lErrors.set_label(warning_lbl) - ebErrors.show_all() - + fErrors.show_all() + def hide_warning(self): - ebErrors = self.builder.get_object("ebErrors") + fErrors = self.builder.get_object("fErrors") lErrors = self.builder.get_object("lErrors") - ebErrors.hide() - + fErrors.hide() + def allow_send(self): self.hide_warning() bSend = self.builder.get_object("bSend") @@ -88,7 +80,7 @@ class ReporterDialog(): send = True error_msgs = [] try: - rating = self.report["rating"] + rating = self.report[FILENAME_RATING] except: rating = None # active buttons acording to required fields @@ -97,31 +89,32 @@ class ReporterDialog(): send = False error_msgs.append(_("You must agree with submitting the backtrace.")) # we have both SendBacktrace and rating - elif rating: + if rating: try: - package = self.report["package"][CD_CONTENT] + package = self.report[FILENAME_PACKAGE][CD_CONTENT] # if we don't have package for some reason except: package = None # not usable report - if int(self.report["rating"][CD_CONTENT]) < 3: + if int(self.report[FILENAME_RATING][CD_CONTENT]) < 3: if package: error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: <b>debuginfo-install %s</b> \nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) else: error_msgs.append(_("The backtrace is unusable, you can't report this!")) # probably usable 3 - elif int(self.report["rating"][CD_CONTENT]) < 4: + elif int(self.report[FILENAME_RATING][CD_CONTENT]) < 4: error_msgs.append(_("The backtrace is incomplete, please make sure you provide good steps to reproduce.")) - + if error_msgs: self.warn_user(error_msgs) bSend.set_sensitive(send) - + def on_send_backtrace_toggled(self, toggle_button): self.allow_send() - + def show_log_cb(self, widget, log): show_log(log, parent=self.window) + # this callback is called when user press Cancel or Report button in Report dialog def on_response(self, dialog, response_id, daemon): # the button has been pressed (probably) @@ -137,9 +130,10 @@ class ReporterDialog(): model[path][3] = not model[path][3] def on_comment_focus_cb(self, widget, event): - if not self.comment_changed: + if self.show_hint_comment: + # clear "hint" text by supplying a fresh, empty TextBuffer widget.set_buffer(gtk.TextBuffer()) - self.comment_changed = True + self.show_hint_comment = 0 def on_config_plugin_clicked(self, button, plugin, image): ui = PluginSettingsUI(plugin, parent=self.window) @@ -201,66 +195,85 @@ class ReporterDialog(): return True return True + def set_label(self, label_widget, text): + if len(text) > label_widget.get_max_width_chars(): + label_widget.set_tooltip_text(text) + label_widget.set_text(text) def hydrate(self): self.editable = [] + self.old_comment = "" + self.old_how_to_reproduce = "" for item in self.report: - if item == "backtrace": + try: + log2("report[%s]:%s/%s/%s", item, self.report[item][0], self.report[item][1], self.report[item][2][0:20]) + except: + pass + + if item == FILENAME_BACKTRACE: buff = gtk.TextBuffer() tvBacktrace = self.builder.get_object("tvBacktrace") buff.set_text(self.report[item][CD_CONTENT]) tvBacktrace.set_buffer(buff) continue - if item == "Comment": - buff = gtk.TextBuffer() - comment = _("Brief description how to reproduce this or what you did...") + + if item == FILENAME_COMMENT: try: if self.report[item][CD_CONTENT]: - comment = self.report[item][CD_CONTENT] - self.comment_changed = True + self.old_comment = self.report[item][CD_CONTENT] except Exception, e: pass - - buff.set_text(comment) - - self.tvComment.set_buffer(buff) continue - if item == "How to reproduce": - buff = gtk.TextBuffer() - how_to_reproduce = _("") + + if item == FILENAME_REPRODUCE: try: if self.report[item][CD_CONTENT]: - how_to_reproduce = self.report[item][CD_CONTENT] - self.how_to_changed = True + self.old_how_to_reproduce = self.report[item][CD_CONTENT] except Exception, e: pass + continue - buff.set_text(how_to_reproduce) + if self.report[item][CD_TYPE] == CD_SYS: + continue - self.tevHowToReproduce.set_buffer(buff) + # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 + # FIXME: handle editable fields + if self.report[item][CD_TYPE] == CD_BIN: + self.builder.get_object("fAttachment").show() + vbAttachments = self.builder.get_object("vbAttachments") + toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) + vbAttachments.pack_start(toggle) + # bind item to checkbox + toggle.item = item + toggle.show() continue - if self.report[item][CD_TYPE] != CD_SYS: - # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 - # FIXME: handle editable fields - if self.report[item][CD_TYPE] == CD_BIN: - self.builder.get_object("fAttachment").show() - vbAttachments = self.builder.get_object("vbAttachments") - toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) - vbAttachments.pack_start(toggle) - # bind item to checkbox - toggle.item = item - toggle.show() - continue - item_label = self.builder.get_object("l%s" % item) - if item_label: - item_label.set_text(self.report[item][CD_CONTENT]) - else: - # no widget to show this item - # probably some new item need to adjust the GUI! - # FIXME: add some window+button to show all the info - # in raw form (smth like the old report dialog) - pass + # It must be CD_TXT field + item_label = self.builder.get_object("l%s" % item) + if item_label: + self.set_label(item_label, self.report[item][CD_CONTENT]) + else: + # no widget to show this item + # probably some new item need to adjust the GUI! + # FIXME: add some window+button to show all the info + # in raw form (smth like the old report dialog) + pass + #end for + + buff = gtk.TextBuffer() + self.show_hint_comment = (self.old_comment == "") + if self.show_hint_comment: + buff.set_text(_("Brief description how to reproduce this or what you did...")) + else: + buff.set_text(self.old_comment) + self.tvComment.set_buffer(buff) + + buff = gtk.TextBuffer() + if self.old_how_to_reproduce == "": + buff.set_text("1.\n2.\n3.\n") + else: + buff.set_text(self.old_how_to_reproduce) + self.tevHowToReproduce.set_buffer(buff) def dehydrate(self): # handle attachments @@ -268,23 +281,22 @@ class ReporterDialog(): 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 - if self.comment_changed: - buff = self.tvComment.get_buffer() - self.report["Comment"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] - else: - del self.report["Comment"] + buff = self.tvComment.get_buffer() + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + if self.old_comment != text: + self.report[FILENAME_COMMENT] = [CD_TXT, 'y', text] # handle how to reproduce - if self.how_to_changed: - buff = self.tevHowToReproduce.get_buffer() - self.report["How to reproduce"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] - else: - del self.report["How to reproduce"] + buff = self.tevHowToReproduce.get_buffer() + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + if self.old_how_to_reproduce != text: + self.report[FILENAME_REPRODUCE] = [CD_TXT, 'y', text] #handle backtrace tev_backtrace = self.builder.get_object("tvBacktrace") buff = tev_backtrace.get_buffer() - self.report["backtrace"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] + text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) + self.report[FILENAME_BACKTRACE] = [CD_TXT, 'y', text] def check_report(self): # FIXME: check the report for passwords and some other potentially @@ -296,4 +308,3 @@ class ReporterDialog(): result = self.window.run() self.window.destroy() return (result, self.report) - diff --git a/src/Gui/CC_gui_functions.py b/src/Gui/CC_gui_functions.py index a9c47faf..e2260210 100644 --- a/src/Gui/CC_gui_functions.py +++ b/src/Gui/CC_gui_functions.py @@ -56,9 +56,14 @@ def gui_report_dialog ( report_status_dict, parent_dialog, status_hbox.pack_start(plugin_label, expand=False) status_hbox.pack_start(status_label, expand=False) # 0 means not succesfull - if report_status_dict[plugin][0] == '0': - status_label.set_markup("<span foreground='red'>%s</span>" % report_status_dict[plugin][1]) - elif report_status_dict[plugin][0] == '1': + #if report_status_dict[plugin][0] == '0': + # 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][1]) + status_label.set_markup("<span foreground='red'>%s</span>" % report_status_dict[plugin][1]) + # 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][0] == '1': if "http" in report_status_dict[plugin][1][0:4] or "file://" in report_status_dict[plugin][1][0:7]: status_label.set_markup("<a href=\"%s\">%s</a>" % (report_status_dict[plugin][1], report_status_dict[plugin][1])) # FIXME: make a new branch for rawhide with gtk 2.17 and remove this diff --git a/src/Gui/PluginList.py b/src/Gui/PluginList.py index d2232bbc..82759ae3 100644 --- a/src/Gui/PluginList.py +++ b/src/Gui/PluginList.py @@ -38,6 +38,11 @@ class PluginInfoList(list): def getReporterPlugins(self): return [x for x in self if x["Enabled"] == 'yes' and x["Type"] == 'Reporter'] + def getReporterPluginsSettings(self): + reporters_settings = {} + for plugin in self.getReporterPlugins(): + reporters_settings[str(plugin)] = plugin.Settings + return reporters_settings __PFList = None diff --git a/src/Gui/report.glade b/src/Gui/report.glade index d3bf5eb0..d6fec06b 100644 --- a/src/Gui/report.glade +++ b/src/Gui/report.glade @@ -16,11 +16,12 @@ <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="spacing">5</property> <child> <object class="GtkFrame" id="fSysInfo"> <property name="visible">True</property> <property name="label_xalign">0</property> - <property name="shadow_type">none</property> + <property name="shadow_type">in</property> <child> <object class="GtkAlignment" id="alignment1"> <property name="visible">True</property> @@ -32,6 +33,7 @@ <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="homogeneous">True</property> <child> <object class="GtkLabel" id="l"> <property name="visible">True</property> @@ -78,6 +80,8 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">0</property> </packing> </child> @@ -92,6 +96,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">0</property> @@ -103,6 +108,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">1</property> @@ -114,6 +120,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">2</property> @@ -125,6 +132,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">3</property> @@ -139,6 +147,7 @@ <object class="GtkVBox" id="vbox5"> <property name="visible">True</property> <property name="orientation">vertical</property> + <property name="homogeneous">True</property> <child> <object class="GtkLabel" id="label4"> <property name="visible">True</property> @@ -185,6 +194,8 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child> @@ -198,6 +209,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">0</property> @@ -209,6 +221,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">1</property> @@ -220,6 +233,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">2</property> @@ -231,6 +245,7 @@ <property name="xalign">0</property> <property name="xpad">5</property> <property name="label" translatable="yes">N/A</property> + <property name="max_width_chars">40</property> </object> <packing> <property name="position">3</property> @@ -245,13 +260,8 @@ </child> </object> </child> - <child type="label"> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="ypad">5</property> - <property name="label" translatable="yes"><b>General information</b></property> - <property name="use_markup">True</property> - </object> + <child type="label_item"> + <placeholder/> </child> </object> <packing> @@ -322,7 +332,7 @@ </packing> </child> <child> - <object class="GtkFrame" id="frame2"> + <object class="GtkFrame" id="fUserInfo"> <property name="visible">True</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> @@ -381,8 +391,6 @@ </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> <property name="position">0</property> </packing> </child> @@ -427,8 +435,6 @@ </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> <property name="position">1</property> </packing> </child> @@ -441,13 +447,8 @@ </child> </object> </child> - <child type="label"> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="ypad">5</property> - <property name="label" translatable="yes"><b>User information</b></property> - <property name="use_markup">True</property> - </object> + <child type="label_item"> + <placeholder/> </child> </object> <packing> @@ -482,75 +483,87 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">3</property> </packing> </child> <child> - <object class="GtkHBox" id="ebErrors"> + <object class="GtkFrame" id="fErrors"> <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">in</property> <child> - <object class="GtkAlignment" id="alignment7"> - <property name="visible">True</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-dialog-warning</property> - <property name="icon-size">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox8"> + <object class="GtkHBox" id="ebErrors"> <property name="visible">True</property> - <property name="orientation">vertical</property> <child> - <object class="GtkLabel" id="label12"> + <object class="GtkAlignment" id="alignment7"> <property name="visible">True</property> - <property name="label" translatable="yes"><b>Please fix the following problems</b></property> - <property name="use_markup">True</property> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">0</property> </packing> </child> <child> - <object class="GtkLabel" id="lErrors"> + <object class="GtkImage" id="image1"> <property name="visible">True</property> - <property name="label" translatable="yes"> </property> - <property name="use_markup">True</property> - <property name="selectable">True</property> + <property name="stock">gtk-dialog-warning</property> + <property name="icon-size">6</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment8"> - <property name="visible">True</property> <child> - <placeholder/> + <object class="GtkVBox" id="vbox8"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Please fix the following problems</b></property> + <property name="use_markup">True</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="lErrors"> + <property name="visible">True</property> + <property name="label" translatable="yes"> </property> + <property name="use_markup">True</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment8"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">3</property> + </packing> </child> </object> - <packing> - <property name="position">3</property> - </packing> + </child> + <child type="label_item"> + <placeholder/> </child> </object> <packing> diff --git a/src/Hooks/abrt-hook-ccpp.cpp b/src/Hooks/abrt-hook-ccpp.cpp index 1c91dc8a..b844be70 100644 --- a/src/Hooks/abrt-hook-ccpp.cpp +++ b/src/Hooks/abrt-hook-ccpp.cpp @@ -21,12 +21,10 @@ #include "abrtlib.h" #include "hooklib.h" #include "DebugDump.h" +#include "CrashTypes.h" #include "ABRTException.h" #include <syslog.h> -#define FILENAME_EXECUTABLE "executable" -#define FILENAME_COREDUMP "coredump" - using namespace std; static char* malloc_readlink(const char *linkname) diff --git a/src/Hooks/abrt-hook-python.cpp b/src/Hooks/abrt-hook-python.cpp index c8a25e39..90197ccf 100644 --- a/src/Hooks/abrt-hook-python.cpp +++ b/src/Hooks/abrt-hook-python.cpp @@ -26,6 +26,7 @@ #include "abrtlib.h" #include "hooklib.h" #include "DebugDump.h" +#include "CrashTypes.h" #include "ABRTException.h" #if HAVE_CONFIG_H # include <config.h> @@ -149,14 +150,14 @@ int main(int argc, char** argv) dd.SaveText(FILENAME_ANALYZER, "Python"); dd.SaveText(FILENAME_EXECUTABLE, executable); - dd.SaveText("backtrace", bt); + dd.SaveText(FILENAME_BACKTRACE, bt); free(bt); - dd.SaveText("cmdline", cmdline); + dd.SaveText(FILENAME_CMDLINE, cmdline); free(cmdline); - dd.SaveText("uuid", uuid); + dd.SaveText(FILENAME_UUID, uuid); char uid[sizeof(long) * 3 + 2]; sprintf(uid, "%lu", (long)getuid()); - dd.SaveText("uid", uid); + dd.SaveText(FILENAME_UID, uid); dd.Close(); log("saved python crash dump of pid %s to %s", pid, path); diff --git a/src/Hooks/hooklib.cpp b/src/Hooks/hooklib.cpp index 41b9627f..06bde974 100644 --- a/src/Hooks/hooklib.cpp +++ b/src/Hooks/hooklib.cpp @@ -47,9 +47,7 @@ void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSi break; } - unsigned len = strlen(line); - if (len > 0 && line[len-1] == '\n') - line[--len] = '\0'; + strchrnul(line, '\n')[0] = '\0'; const char *p = skip_whitespace(line); #undef DIRECTIVE #define DIRECTIVE "MaxCrashReportsSize" |