summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2009-10-30 23:47:27 +0100
committerKarel Klic <kklic@redhat.com>2009-10-30 23:47:27 +0100
commitd0962176b885a32b1c5aecd5ac3c0d23447c3d09 (patch)
treea876da5cefe940264b97d35e80b9cd3a7ef7e64a /lib
parent0843e750bce39df0e69e4962b3c7f98294d0739b (diff)
parent276a9017d63445dd322f9a93ff34e67cbdf97dc9 (diff)
downloadabrt-d0962176b885a32b1c5aecd5ac3c0d23447c3d09.tar.gz
abrt-d0962176b885a32b1c5aecd5ac3c0d23447c3d09.tar.xz
abrt-d0962176b885a32b1c5aecd5ac3c0d23447c3d09.zip
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'lib')
-rw-r--r--lib/Plugins/Bugzilla.cpp203
-rw-r--r--lib/Plugins/CCpp.cpp3
-rw-r--r--lib/Plugins/Catcut.cpp4
-rw-r--r--lib/Plugins/Logger.cpp80
-rw-r--r--lib/Utils/DebugDump.cpp26
-rw-r--r--lib/Utils/Makefile.am3
-rw-r--r--lib/Utils/Plugin.h21
-rw-r--r--lib/Utils/make_descr.cpp125
8 files changed, 263 insertions, 202 deletions
diff --git a/lib/Plugins/Bugzilla.cpp b/lib/Plugins/Bugzilla.cpp
index 7827113..84c7934 100644
--- a/lib/Plugins/Bugzilla.cpp
+++ b/lib/Plugins/Bugzilla.cpp
@@ -40,11 +40,15 @@ static void get_product_and_version(const std::string& pRelease,
std::string& pVersion);
+// FIXME: we still leak memmory if this function detects a fault:
+// many instances when we leave non-freed or non-xmlrpc_DECREF'ed data behind.
static void throw_if_xml_fault_occurred()
{
if (env.fault_occurred)
{
std::string errmsg = ssprintf("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code);
+ xmlrpc_env_clean(&env);
+ xmlrpc_env_init(&env);
error_msg("%s", errmsg.c_str()); // show error in daemon log
throw CABRTException(EXCEP_PLUGIN, errmsg);
}
@@ -95,49 +99,49 @@ CReporterBugzilla::~CReporterBugzilla()
static void login(const char* login, const char* passwd)
{
- xmlrpc_value* result = NULL;
- xmlrpc_value* param = NULL;
-
- param = xmlrpc_build_value(&env, "({s:s,s:s})", "login", login, "password", passwd);
+ xmlrpc_value* param = xmlrpc_build_value(&env, "({s:s,s:s})", "login", login, "password", passwd);
throw_if_xml_fault_occurred();
+ xmlrpc_value* result = NULL;
xmlrpc_client_call2(&env, client, server_info, "User.login", param, &result);
- throw_if_xml_fault_occurred();
-
- xmlrpc_DECREF(result);
xmlrpc_DECREF(param);
+ if (result)
+ xmlrpc_DECREF(result);
+
+ if (env.fault_occurred)
+ {
+ std::string errmsg = ssprintf("Can't login. Check Edit->Plugins->Bugzilla and /etc/abrt/plugins/Bugzilla.conf. Server said: %s", env.fault_string);
+ xmlrpc_env_clean(&env);
+ xmlrpc_env_init(&env);
+ error_msg("%s", errmsg.c_str()); // show error in daemon log
+ throw CABRTException(EXCEP_PLUGIN, errmsg);
+ }
}
static void logout()
{
- xmlrpc_value* result = NULL;
- xmlrpc_value* param = NULL;
-
- param = xmlrpc_build_value(&env, "(s)", "");
+ xmlrpc_value* param = xmlrpc_build_value(&env, "(s)", "");
throw_if_xml_fault_occurred();
+ xmlrpc_value* result = NULL;
xmlrpc_client_call2(&env, client, server_info, "User.logout", param, &result);
- throw_if_xml_fault_occurred();
-
- xmlrpc_DECREF(result);
xmlrpc_DECREF(param);
+ if (result)
+ xmlrpc_DECREF(result);
+ throw_if_xml_fault_occurred();
}
static bool check_cc_and_reporter(const uint32_t bug_id, const char* login)
{
- xmlrpc_value* param = NULL;
- xmlrpc_value* result = NULL;
- xmlrpc_value* reporter_member = NULL;
- xmlrpc_value* cc_member = NULL;
-
- const char* bug = to_string(bug_id).c_str();
-
- param = xmlrpc_build_value(&env, "(s)", bug);
+ xmlrpc_value* param = xmlrpc_build_value(&env, "(s)", to_string(bug_id).c_str());
throw_if_xml_fault_occurred();
+ xmlrpc_value* result = NULL;
xmlrpc_client_call2(&env, client, server_info, "bugzilla.getBug", param, &result);
throw_if_xml_fault_occurred();
+ xmlrpc_DECREF(param);
+ xmlrpc_value* reporter_member = NULL;
xmlrpc_struct_find_value(&env, result, "reporter", &reporter_member);
throw_if_xml_fault_occurred();
@@ -147,26 +151,27 @@ static bool check_cc_and_reporter(const uint32_t bug_id, const char* login)
xmlrpc_read_string(&env, reporter_member, &reporter);
throw_if_xml_fault_occurred();
- if (strcmp(reporter, login) == 0 )
+ bool eq = (strcmp(reporter, login) == 0);
+ free((void*)reporter);
+ xmlrpc_DECREF(reporter_member);
+ if (eq)
{
- xmlrpc_DECREF(param);
xmlrpc_DECREF(result);
- xmlrpc_DECREF(reporter_member);
- free((void*)reporter);
return true;
}
}
+ xmlrpc_value* cc_member = NULL;
xmlrpc_struct_find_value(&env, result, "cc", &cc_member);
throw_if_xml_fault_occurred();
if (cc_member)
{
- xmlrpc_value* item = NULL;
uint32_t array_size = xmlrpc_array_size(&env, cc_member);
for (uint32_t i = 0; i < array_size; i++)
{
+ xmlrpc_value* item = NULL;
xmlrpc_array_read_item(&env, cc_member, i, &item); // Correct
throw_if_xml_fault_occurred();
@@ -174,33 +179,29 @@ static bool check_cc_and_reporter(const uint32_t bug_id, const char* login)
xmlrpc_read_string(&env, item, &cc);
throw_if_xml_fault_occurred();
- if (strcmp(cc, login) == 0)
+ bool eq = (strcmp(cc, login) == 0);
+ free((void*)cc);
+ xmlrpc_DECREF(item);
+ if (eq)
{
- xmlrpc_DECREF(param);
- xmlrpc_DECREF(result);
- xmlrpc_DECREF(reporter_member);
xmlrpc_DECREF(cc_member);
- xmlrpc_DECREF(item);
- free((void*)cc);
+ xmlrpc_DECREF(result);
return true;
}
}
+ xmlrpc_DECREF(cc_member);
}
- xmlrpc_DECREF(cc_member);
- xmlrpc_DECREF(param);
+
xmlrpc_DECREF(result);
- xmlrpc_DECREF(reporter_member);
return false;
}
static void add_plus_one_cc(const uint32_t bug_id, const char* login)
{
- xmlrpc_value* param = NULL;
- xmlrpc_value* result = NULL;
-
- param = xmlrpc_build_value(&env, "({s:i,s:{s:(s)}})", "ids", bug_id, "updates", "add_cc", login);
+ xmlrpc_value* param = xmlrpc_build_value(&env, "({s:i,s:{s:(s)}})", "ids", bug_id, "updates", "add_cc", login);
throw_if_xml_fault_occurred();
+ xmlrpc_value* result = NULL;
xmlrpc_client_call2(&env, client, server_info, "Bug.update", param, &result);
throw_if_xml_fault_occurred();
@@ -210,21 +211,17 @@ static void add_plus_one_cc(const uint32_t bug_id, const char* login)
static int32_t check_uuid_in_bugzilla(const char* component, const char* UUID)
{
- xmlrpc_value* param = NULL;
- xmlrpc_value* result = NULL;
- xmlrpc_value* bugs_member = NULL;
-
- xmlrpc_int bug_id;
-
- char query[1024];
- snprintf(query, 1023, "ALL component:\"%s\" statuswhiteboard:\"%s\"", component, UUID);
+ std::string query = ssprintf("ALL component:\"%s\" statuswhiteboard:\"%s\"", component, UUID);
- param = xmlrpc_build_value(&env, "({s:s})", "quicksearch", query);
+ xmlrpc_value* param = xmlrpc_build_value(&env, "({s:s})", "quicksearch", query.c_str());
throw_if_xml_fault_occurred();
+ xmlrpc_value* result = NULL;
xmlrpc_client_call2(&env, client, server_info, "Bug.search", param, &result);
throw_if_xml_fault_occurred();
+ xmlrpc_DECREF(param);
+ xmlrpc_value* bugs_member = NULL;
xmlrpc_struct_find_value(&env, result, "bugs", &bugs_member);
throw_if_xml_fault_occurred();
@@ -233,89 +230,45 @@ static int32_t check_uuid_in_bugzilla(const char* component, const char* UUID)
// when array size is equal 0 that means no bug reported
uint32_t array_size = xmlrpc_array_size(&env, bugs_member);
throw_if_xml_fault_occurred();
- if( array_size == 0 )
+ if (array_size == 0)
+ {
+ xmlrpc_DECREF(bugs_member);
+ xmlrpc_DECREF(result);
return -1;
+ }
xmlrpc_value* item = NULL;
xmlrpc_array_read_item(&env, bugs_member, 0, &item); // Correct
throw_if_xml_fault_occurred();
-
xmlrpc_value* bug = NULL;
- xmlrpc_struct_find_value(&env, item,"bug_id", &bug);
+ xmlrpc_struct_find_value(&env, item, "bug_id", &bug);
throw_if_xml_fault_occurred();
+
if (bug)
{
+ xmlrpc_int bug_id;
xmlrpc_read_int(&env, bug, &bug_id);
- log("Bug is already reported: %i", bug_id);
+ log("Bug is already reported: %i", (int)bug_id);
update_client(_("Bug is already reported: ") + to_string(bug_id));
- xmlrpc_DECREF(result);
xmlrpc_DECREF(bug);
xmlrpc_DECREF(item);
xmlrpc_DECREF(bugs_member);
- xmlrpc_DECREF(param);
+ xmlrpc_DECREF(result);
return bug_id;
}
+ xmlrpc_DECREF(item);
+ xmlrpc_DECREF(bugs_member);
}
xmlrpc_DECREF(result);
- xmlrpc_DECREF(bugs_member);
- xmlrpc_DECREF(param);
return -1;
}
static void create_new_bug_description(const map_crash_report_t& pCrashReport, std::string& pDescription)
{
- std::string howToReproduce;
- std::string comment;
-
- if (pCrashReport.find(CD_REPRODUCE) != pCrashReport.end())
- {
- howToReproduce = "\n\nHow to reproduce\n"
- "-----\n" +
- pCrashReport.find(CD_REPRODUCE)->second[CD_CONTENT];
- }
- if (pCrashReport.find(CD_COMMENT) != pCrashReport.end())
- {
- comment = "\n\nComment\n"
- "-----\n" +
- pCrashReport.find(CD_COMMENT)->second[CD_CONTENT];
- }
- pDescription = "\nabrt detected a crash.\n" +
- howToReproduce +
- comment +
- "\n\nAdditional information\n"
- "======\n";
-
- map_crash_report_t::const_iterator it = pCrashReport.begin();
- for (; it != pCrashReport.end(); it++)
- {
- if (it->second[CD_TYPE] == CD_TXT)
- {
- if (it->first != CD_UUID &&
- it->first != FILENAME_ARCHITECTURE &&
- it->first != FILENAME_RELEASE &&
- it->first != CD_REPRODUCE &&
- it->first != CD_COMMENT)
- {
- pDescription += "\n" + it->first + "\n";
- pDescription += "-----\n";
- pDescription += it->second[CD_CONTENT] + "\n\n";
- }
- }
- else if (it->second[CD_TYPE] == CD_ATT)
- {
- pDescription += "\n\nAttached files\n"
- "----\n";
- pDescription += it->first + "\n";
- }
- else if (it->second[CD_TYPE] == CD_BIN)
- {
- std::string msg = ssprintf(_("Binary file %s will not be reported."), it->first.c_str());
- warn_client(msg);
- //update_client(_("Binary file ")+it->first+_(" will not be reported."));
- }
- }
+ pDescription = "abrt detected a crash.\n\n";
+ pDescription += make_description_bz(pCrashReport);
}
static void get_product_and_version(const std::string& pRelease,
@@ -445,7 +398,7 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, co
bug_id = check_uuid_in_bugzilla(component.c_str(), uuid.c_str());
update_client(_("Logging into bugzilla..."));
- if ((m_sLogin == "") && (m_sPassword==""))
+ if ((m_sLogin == "") && (m_sPassword == ""))
{
VERB3 log("Empty login and password");
throw CABRTException(EXCEP_PLUGIN, std::string(_("Empty login and password. Please check Bugzilla.conf")));
@@ -474,7 +427,7 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, co
catch (CABRTException& e)
{
destroy_xmlrpc_client();
- throw CABRTException(EXCEP_PLUGIN, std::string("CReporterBugzilla::Report(): ") + e.what());
+ throw CABRTException(EXCEP_PLUGIN, e.what());
}
destroy_xmlrpc_client();
@@ -488,13 +441,24 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, co
void CReporterBugzilla::SetSettings(const map_plugin_settings_t& pSettings)
{
- if (pSettings.find("BugzillaURL") != pSettings.end())
+//BUG! This gets called when user's keyring contains login data,
+//then it takes precedence over /etc/abrt/plugins/Bugzilla.conf.
+//I got a case when keyring had a STALE password, and there was no way
+//for me to know that it is being used. Moreover, when I discovered it
+//(by hacking abrt source!), I don't know how to purge it from the keyring.
+//At the very least, log("SOMETHING") here.
+
+ map_plugin_settings_t::const_iterator it;
+ map_plugin_settings_t::const_iterator end = pSettings.end();
+
+ it = pSettings.find("BugzillaURL");
+ if (it != end)
{
- m_sBugzillaURL = pSettings.find("BugzillaURL")->second;
+ m_sBugzillaURL = it->second;
//remove the /xmlrpc.cgi part from old settings
//FIXME: can be removed after users are informed about new config format
std::string::size_type pos = m_sBugzillaURL.find(XML_RPC_SUFFIX);
- if(pos != std::string::npos)
+ if (pos != std::string::npos)
{
m_sBugzillaURL.erase(pos);
}
@@ -511,17 +475,20 @@ void CReporterBugzilla::SetSettings(const map_plugin_settings_t& pSettings)
*/
m_sBugzillaXMLRPC = m_sBugzillaURL + XML_RPC_SUFFIX;
}
- if (pSettings.find("Login") != pSettings.end())
+ it = pSettings.find("Login");
+ if (it != end)
{
- m_sLogin = pSettings.find("Login")->second;
+ m_sLogin = it->second;
}
- if (pSettings.find("Password") != pSettings.end())
+ it = pSettings.find("Password");
+ if (it != end)
{
- m_sPassword = pSettings.find("Password")->second;
+ m_sPassword = it->second;
}
- if (pSettings.find("NoSSLVerify") != pSettings.end())
+ it = pSettings.find("NoSSLVerify");
+ if (it != end)
{
- m_bNoSSLVerify = pSettings.find("NoSSLVerify")->second == "yes";
+ m_bNoSSLVerify = (it->second == "yes");
}
}
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp
index 4eacdd2..23bd9db 100644
--- a/lib/Plugins/CCpp.cpp
+++ b/lib/Plugins/CCpp.cpp
@@ -671,7 +671,8 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui
setsid();
char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir.c_str());
- char *tempdir = xasprintf("/tmp/abrt-%u-%lu", (int)getpid(), (long)time(NULL));
+ /* SELinux guys are not happy with /tmp, using /var/run/abrt */
+ char *tempdir = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%u-%lu", (int)getpid(), (long)time(NULL));
/* log() goes to stderr/syslog, it's ok to use it here */
VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, LOCALSTATEDIR"/cache/abrt-di");
execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, LOCALSTATEDIR"/cache/abrt-di", NULL);
diff --git a/lib/Plugins/Catcut.cpp b/lib/Plugins/Catcut.cpp
index ad55b2a..c833a57 100644
--- a/lib/Plugins/Catcut.cpp
+++ b/lib/Plugins/Catcut.cpp
@@ -92,6 +92,9 @@ static string login(const char* login, const char* passwd)
xmlrpc_read_string(&env, cookie_xml, &cookie);
throw_if_xml_fault_occurred();
cookie_str = cookie;
+ /* xmlrpc_read_string returns *malloc'ed ptr*.
+ * doc is not very clear on it, but I looked in xmlrpc sources. */
+ free((void*)cookie);
xmlrpc_DECREF(cookie_xml);
xmlrpc_DECREF(result);
@@ -240,6 +243,7 @@ static string new_bug(const char *auth_cookie, const map_crash_report_t& pCrashR
bug_id_str = bug_id;
log("New bug id: %s", bug_id);
update_client(_("New bug id: ") + bug_id_str);
+ free((void*)bug_id);
xmlrpc_DECREF(bug_id_xml);
xmlrpc_DECREF(result);
diff --git a/lib/Plugins/Logger.cpp b/lib/Plugins/Logger.cpp
index ff7bbb8..eb9c240 100644
--- a/lib/Plugins/Logger.cpp
+++ b/lib/Plugins/Logger.cpp
@@ -57,85 +57,27 @@ std::string CLogger::Report(const map_crash_report_t& pCrashReport, const std::s
{
update_client(_("Creating a report..."));
- std::stringstream binaryFiles, commonFiles, bigTextFiles, additionalFiles, UUIDFile;
- std::ofstream fOut;
-
- map_crash_report_t::const_iterator it;
- for (it = pCrashReport.begin(); it != pCrashReport.end(); it++)
- {
- if (it->second[CD_TYPE] == CD_TXT)
- {
- if (it->first != CD_UUID &&
- it->first != FILENAME_ARCHITECTURE &&
- it->first != FILENAME_KERNEL &&
- it->first != FILENAME_PACKAGE)
- {
- additionalFiles << it->first << std::endl;
- additionalFiles << "-----" << std::endl;
- additionalFiles << it->second[CD_CONTENT] << std::endl << std::endl;
- }
- else if (it->first == CD_UUID)
- {
- UUIDFile << it->first << std::endl;
- UUIDFile << "-----" << std::endl;
- UUIDFile << it->second[CD_CONTENT] << std::endl << std::endl;
- }
- else
- {
- commonFiles << it->first << std::endl;
- commonFiles << "-----" << std::endl;
- commonFiles << it->second[CD_CONTENT] << std::endl << std::endl;
- }
- }
- if (it->second[CD_TYPE] == CD_ATT)
- {
- bigTextFiles << it->first << std::endl;
- bigTextFiles << "-----" << std::endl;
- bigTextFiles << it->second[CD_CONTENT] << std::endl << std::endl;
- }
- if (it->second[CD_TYPE] == CD_BIN)
- {
- binaryFiles << it->first << std::endl;
- binaryFiles << "-----" << std::endl;
- binaryFiles << it->second[CD_CONTENT] << std::endl << std::endl;
- }
- }
-
+ std::string description = make_description_logger(pCrashReport);
+ description += "\n\n\n";
+ FILE *fOut;
if (m_bAppendLogs)
{
- fOut.open(m_sLogPath.c_str(), std::ios::app);
+ fOut = fopen(m_sLogPath.c_str(), "a");
}
else
{
- fOut.open(m_sLogPath.c_str());
+ fOut = fopen(m_sLogPath.c_str(), "w");
}
- if (fOut.is_open())
- {
- fOut << "Duplicity check" << std::endl;
- fOut << "======" << std::endl << std::endl;
- fOut << UUIDFile.str() << std::endl;
- fOut << "Common information" << std::endl;
- fOut << "======" << std::endl << std::endl;
- fOut << commonFiles.str() << std::endl;
- fOut << "Additional information" << std::endl;
- fOut << "======" << std::endl << std::endl;
- fOut << additionalFiles.str() << std::endl;
- fOut << "Big Text Files" << std::endl;
- fOut << "======" << std::endl;
- fOut << bigTextFiles.str() << std::endl;
- fOut << "Binary files" << std::endl;
- fOut << "======" << std::endl;
- fOut << binaryFiles.str() << std::endl;
- fOut << std::endl;
- fOut.close();
- }
- else
+ if (fOut)
{
- throw CABRTException(EXCEP_PLUGIN, "CLogger::Report(): Cannot open file: " + m_sLogPath);
+ fputs(description.c_str(), fOut);
+ fclose(fOut);
+ return "file://" + m_sLogPath;
}
- return "file://" + m_sLogPath;
+
+ throw CABRTException(EXCEP_PLUGIN, "CLogger::Report(): Cannot open file: " + m_sLogPath);
}
PLUGIN_INFO(REPORTER,
diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp
index ecd6d05..5017d86 100644
--- a/lib/Utils/DebugDump.cpp
+++ b/lib/Utils/DebugDump.cpp
@@ -23,7 +23,7 @@
#include <iostream>
#include <sstream>
#include <sys/utsname.h>
-#include <magic.h>
+//#include <magic.h>
#include "abrtlib.h"
#include "DebugDump.h"
#include "ABRTException.h"
@@ -290,8 +290,10 @@ static void DeleteFileDir(const std::string& pDir)
}
}
-static bool IsTextFile(const std::string& pName)
+static bool IsTextFile(const char *name)
{
+/* This idiotic library thinks that file containing just "0" is not text (!!)
+
magic_t m = magic_open(MAGIC_MIME_TYPE);
if (m == NULL)
@@ -320,6 +322,24 @@ static bool IsTextFile(const std::string& pName)
magic_close(m);
return isText;
+ */
+ int fd = open(name, O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ unsigned char buf[4*1024];
+ int r = full_read(fd, buf, sizeof(buf));
+ close(fd);
+
+ while (--r >= 0)
+ {
+ if (buf[r] >= 0x7f)
+ return false;
+ /* Among control chars, only '\t','\n' etc are allowed */
+ if (buf[r] < ' ' && !isspace(buf[r]))
+ return false;
+ }
+ return true;
}
static std::string RemoveBackSlashes(const std::string& pDir)
@@ -532,7 +552,7 @@ bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool
std::string fullname = m_sDebugDumpDir + "/" + dent->d_name;
pFileName = dent->d_name;
- if (IsTextFile(fullname))
+ if (IsTextFile(fullname.c_str()))
{
LoadText(dent->d_name, pContent);
pIsTextFile = true;
diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am
index 3c51085..88df68f 100644
--- a/lib/Utils/Makefile.am
+++ b/lib/Utils/Makefile.am
@@ -15,7 +15,7 @@ libABRTUtils_la_SOURCES = \
DebugDump.h DebugDump.cpp \
CommLayerInner.h CommLayerInner.cpp \
abrt_dbus.h abrt_dbus.cpp \
- Plugin.h Plugin.cpp \
+ Plugin.h Plugin.cpp make_descr.cpp \
Polkit.h Polkit.cpp \
Action.h Database.h Reporter.h Analyzer.h \
Observer.h \
@@ -37,7 +37,6 @@ libABRTUtils_la_LDFLAGS = \
$(DL_LIBS) \
$(DBUS_LIBS)
libABRTUtils_la_LIBADD = \
- -lmagic \
$(POLKIT_LIBS)
install-data-local:
diff --git a/lib/Utils/Plugin.h b/lib/Utils/Plugin.h
index 3929023..00c7e5b 100644
--- a/lib/Utils/Plugin.h
+++ b/lib/Utils/Plugin.h
@@ -24,17 +24,10 @@
#define PLUGIN_H_
#include "abrt_types.h"
-
-#define PLUGINS_MAGIC_NUMBER 6
-
-#define PLUGINS_CONF_EXTENSION "conf"
-#define PLUGINS_LIB_EXTENSION "so"
-#define PLUGINS_LIB_PREFIX "lib"
-
+#include "CrashTypes.h"
#if HAVE_CONFIG_H
#include <config.h>
#endif
-
#if ENABLE_NLS
#include <libintl.h>
#define _(S) gettext(S)
@@ -42,6 +35,12 @@
#define _(S) (S)
#endif
+#define PLUGINS_MAGIC_NUMBER 6
+
+#define PLUGINS_CONF_EXTENSION "conf"
+#define PLUGINS_LIB_EXTENSION "so"
+#define PLUGINS_LIB_PREFIX "lib"
+
/**
* An abstract class. The class defines a common plugin interface. If a plugin
* has some settings, then a *Settings(*) method has to be written.
@@ -115,4 +114,8 @@ typedef struct SPluginInfo
PLUGINS_MAGIC_NUMBER,\
};
-#endif /* PLUGIN_H_ */
+/* helper finctions */
+std::string make_description_bz(const map_crash_report_t& pCrashReport);
+std::string make_description_logger(const map_crash_report_t& pCrashReport);
+
+#endif
diff --git a/lib/Utils/make_descr.cpp b/lib/Utils/make_descr.cpp
new file mode 100644
index 0000000..71b9191
--- /dev/null
+++ b/lib/Utils/make_descr.cpp
@@ -0,0 +1,125 @@
+#include "abrtlib.h"
+//#include "abrt_types.h"
+#include "CrashTypes.h"
+#include "DebugDump.h" /* FILENAME_ARCHITECTURE etc */
+
+using namespace std;
+
+static void add_content(bool &was_multiline, string& description, const char *header, const char *content)
+{
+ /* We separate multiline contents with emply line */
+ if (was_multiline)
+ description += '\n';
+
+ while (content[0] == '\n')
+ content++;
+
+ if (strchr(content, '\n') == NULL)
+ {
+ /* one string value, like OS release */
+ description += header;
+ description += ": ";
+ description += content;
+ description += '\n';
+ was_multiline = 0;
+ }
+ else
+ {
+ /* multi-string value, like backtrace */
+ if (!was_multiline && description.size() != 0) /* if wasn't yet separated */
+ description += '\n'; /* do it now */
+ description += header;
+ description += "\n-----\n";
+ description += content;
+ if (content[strlen(content) - 1] != '\n')
+ description += '\n';
+ was_multiline = 1;
+ }
+}
+
+string make_description_bz(const map_crash_report_t& pCrashReport)
+{
+ string 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++)
+ {
+ const string &filename = it->first;
+ const string &type = it->second[CD_TYPE];
+ const string &content = it->second[CD_CONTENT];
+ if (type == CD_TXT)
+ {
+ 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());
+ }
+ }
+ else if (type == CD_ATT)
+ {
+ add_content(was_multiline, description, "Attached file", filename.c_str());
+ }
+ }
+
+ return description;
+}
+
+string make_description_logger(const map_crash_report_t& pCrashReport)
+{
+ string description;
+ string long_description;
+
+ map_crash_report_t::const_iterator it = pCrashReport.begin();
+ for (; it != pCrashReport.end(); it++)
+ {
+ const string &filename = it->first;
+ const string &type = it->second[CD_TYPE];
+ const string &content = it->second[CD_CONTENT];
+ if (type == CD_TXT
+ || type == CD_ATT
+ || type == CD_BIN
+ ) {
+ bool was_multiline = 0;
+ string tmp;
+ add_content(was_multiline, tmp, filename.c_str(), content.c_str());
+
+ if (was_multiline)
+ {
+ if (long_description.size() != 0)
+ long_description += '\n';
+ long_description += tmp;
+ }
+ else
+ {
+ description += tmp;
+ }
+ }
+ }
+
+ if (long_description.size() != 0)
+ {
+ description += '\n';
+ description += long_description;
+ }
+
+ return description;
+}