summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2009-08-06 16:19:07 +0200
committerJiri Moskovcak <jmoskovc@redhat.com>2009-08-06 16:19:07 +0200
commit84348ccea878d509f838927e1bf393e5443d3ac8 (patch)
treed7dc8bdc80b18a6137f94415761ec95c1df8e005 /src
parent9a3268d970142f0dfb4e3e77c66c9637bf87fbda (diff)
parent26c6665308b5a99d02308099118b23b2716dacc0 (diff)
downloadabrt-84348ccea878d509f838927e1bf393e5443d3ac8.tar.gz
abrt-84348ccea878d509f838927e1bf393e5443d3ac8.tar.xz
abrt-84348ccea878d509f838927e1bf393e5443d3ac8.zip
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Conflicts: lib/CommLayer/DBusServerProxy.h
Diffstat (limited to 'src')
-rw-r--r--src/Applet/Applet.cpp34
-rw-r--r--src/Applet/Makefile.am25
-rw-r--r--src/CLI/CLI.cpp2
-rw-r--r--src/Daemon/CrashWatcher.cpp1
-rw-r--r--src/Daemon/CrashWatcher.h4
-rw-r--r--src/Daemon/Makefile.am34
-rw-r--r--src/Daemon/MiddleWare.cpp616
-rw-r--r--src/Daemon/MiddleWare.h350
-rw-r--r--src/Daemon/PluginManager.cpp287
-rw-r--r--src/Daemon/PluginManager.h156
-rw-r--r--src/Daemon/abrt.82
-rw-r--r--src/Daemon/abrt.conf.58
-rw-r--r--src/Daemon/exported-symbols4
-rw-r--r--src/Hooks/CCpp.cpp200
-rw-r--r--src/Hooks/abrt_exception_handler.py.in2
15 files changed, 1575 insertions, 150 deletions
diff --git a/src/Applet/Applet.cpp b/src/Applet/Applet.cpp
index adcfb47..53f0043 100644
--- a/src/Applet/Applet.cpp
+++ b/src/Applet/Applet.cpp
@@ -1,20 +1,20 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
- 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.
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "CCApplet.h"
diff --git a/src/Applet/Makefile.am b/src/Applet/Makefile.am
index 2665850..f0ec5ed 100644
--- a/src/Applet/Makefile.am
+++ b/src/Applet/Makefile.am
@@ -1,13 +1,22 @@
bin_PROGRAMS = abrt-applet
-abrt_applet_SOURCES = Applet.cpp CCApplet.cpp CCApplet.h
-abrt_applet_CPPFLAGS = -Wall -Werror -I../Daemon/ \
- -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
- -DBIN_DIR=\"$(bindir)\" \
- $(DBUS_GLIB_CFLAGS) $(GTK_CFLAGS) $(DBUSCPP_CFLAGS) $(LIBNOTIFY_CFLAGS)\
- -I$(srcdir)/../../inc -I../../lib/CommLayer \
- -I../../lib/MiddleWare -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
-abrt_applet_LDADD = $(DL_LIBS) $(GTK_LIBS) -lglib-2.0 -lgthread-2.0 $(DBUSCPP_LIBS) $(LIBNOTIFY_LIBS)
+abrt_applet_SOURCES = Applet.cpp CCApplet.cpp CCApplet.h
+abrt_applet_CPPFLAGS = \
+ -Wall -Werror \
+ -I../Daemon/ \
+ -I$(srcdir)/../../inc \
+ -I$(srcdir)/../../lib/CommLayer \
+ -I$(srcdir)/../../lib/MiddleWare \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
+ -DBIN_DIR=\"$(bindir)\" \
+ $(DBUS_GLIB_CFLAGS) $(GTK_CFLAGS) $(DBUSCPP_CFLAGS) $(LIBNOTIFY_CFLAGS) \
+ -I/usr/include/glib-2.0 \
+ -I/usr/lib/glib-2.0/include
+abrt_applet_LDADD = \
+ ../../lib/CommLayer/libABRTCommLayer.la \
+ $(DL_LIBS) $(GTK_LIBS) \
+ -lglib-2.0 -lgthread-2.0 \
+ $(DBUSCPP_LIBS) $(LIBNOTIFY_LIBS)
EXTRA_DIST = abrt-applet.desktop
diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp
index 251407b..aaaef5b 100644
--- a/src/CLI/CLI.cpp
+++ b/src/CLI/CLI.cpp
@@ -136,7 +136,7 @@ int main(int argc, char** argv)
dispatcher.attach(NULL);
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SystemBus();
- CCommLayerClientDBus ABRTDaemon(conn, CC_DBUS_PATH, CC_DBUS_NAME);
+ CCommLayerClientDBus ABRTDaemon(conn, CC_DBUS_PATH, CC_DBUS_NAME);
if(!conn.has_name(CC_DBUS_NAME)){
std::cout << "Daemon is not running!" << std::endl;
return -1;
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
index 108db19..c64e22a 100644
--- a/src/Daemon/CrashWatcher.cpp
+++ b/src/Daemon/CrashWatcher.cpp
@@ -516,6 +516,7 @@ CCrashWatcher::~CCrashWatcher()
/* delete lock file */
unlink(VAR_RUN_LOCK_FILE);
}
+
void CCrashWatcher::FindNewDumps(const std::string& pPath)
{
Debug("Scanning for unsaved entries...");
diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h
index 71ed014..420acc4 100644
--- a/src/Daemon/CrashWatcher.h
+++ b/src/Daemon/CrashWatcher.h
@@ -69,7 +69,7 @@ class CCrashWatcher
{}
} cron_callback_data_t;
-
+
typedef struct SThreadData{
pthread_t thread_id;
char* UUID;
@@ -77,7 +77,7 @@ class CCrashWatcher
char *dest;
CCrashWatcher *daemon;
} thread_data_t;
-
+
/**
* Map to cache the results from CreateReport_t
* <UID, <UUID, result>>
diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am
index b6a66f6..41d60a7 100644
--- a/src/Daemon/Makefile.am
+++ b/src/Daemon/Makefile.am
@@ -1,15 +1,29 @@
sbin_PROGRAMS = abrt
-abrt_SOURCES = CrashWatcher.cpp CrashWatcher.h Daemon.cpp \
- DBusCommon.h Settings.h Settings.cpp
-abrt_CPPFLAGS = -I$(srcdir)/../../lib/MiddleWare -I$(srcdir)/../../lib/CommLayer\
- -I$(srcdir)/../../inc -I$(srcdir)/../../lib/Utils \
- -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(GLIB_CFLAGS) $(DBUSCPP_CFLAGS) \
- -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
- -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
- -DCONF_DIR=\"$(CONF_DIR)\" \
- -DVAR_RUN=\"$(VAR_RUN)\" $(ENABLE_SOCKET_OR_DBUS)
-abrt_LDADD = ../../lib/MiddleWare/libABRTMiddleWare.la ../../lib/CommLayer/libABRTCommLayer.la $(DL_LIBS) $(DBUSCPP_LIBS) $(RPM_LIBS)
+abrt_SOURCES = \
+ PluginManager.cpp PluginManager.h \
+ MiddleWare.cpp MiddleWare.h \
+ CrashWatcher.cpp CrashWatcher.h \
+ Daemon.cpp \
+ DBusCommon.h \
+ Settings.h Settings.cpp
+abrt_CPPFLAGS = \
+ -I$(srcdir)/../../inc \
+ -I$(srcdir)/../../lib/MiddleWare \
+ -I$(srcdir)/../../lib/CommLayer \
+ -I$(srcdir)/../../lib/Utils \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
+ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
+ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
+ -DCONF_DIR=\"$(CONF_DIR)\" \
+ -DVAR_RUN=\"$(VAR_RUN)\" \
+ $(GLIB_CFLAGS) $(DBUSCPP_CFLAGS) \
+ $(ENABLE_SOCKET_OR_DBUS)
+abrt_LDADD = \
+ ../../lib/MiddleWare/libABRTMiddleWare.la \
+ ../../lib/CommLayer/libABRTCommLayer.la \
+ $(DL_LIBS) $(DBUSCPP_LIBS) $(RPM_LIBS)
+
dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/
dist_dbusabrtconf_DATA = dbus-abrt.conf
diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp
new file mode 100644
index 0000000..2a8688e
--- /dev/null
+++ b/src/Daemon/MiddleWare.cpp
@@ -0,0 +1,616 @@
+/*
+ MiddleWare.cpp
+
+ Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "abrtlib.h"
+#include "MiddleWare.h"
+#include "DebugDump.h"
+#include "ABRTException.h"
+#include "CommLayerInner.h"
+
+CMiddleWare::CMiddleWare(const std::string& pPluginsConfDir,
+ const std::string& pPluginsLibDir) :
+ m_pPluginManager(NULL),
+ m_bOpenGPGCheck(true),
+ m_sPluginsConfDir(pPluginsConfDir)
+{
+ m_pPluginManager = new CPluginManager(pPluginsConfDir, pPluginsLibDir);
+ m_pPluginManager->LoadPlugins();
+}
+
+CMiddleWare::~CMiddleWare()
+{
+ m_pPluginManager->UnLoadPlugins();
+ delete m_pPluginManager;
+}
+
+void CMiddleWare::DebugDumpToCrashReport(const std::string& pDebugDumpDir, map_crash_report_t& pCrashReport)
+{
+ std::string fileName;
+ std::string content;
+ bool isTextFile;
+ CDebugDump dd;
+ dd.Open(pDebugDumpDir);
+
+ if (!dd.Exist(FILENAME_ARCHITECTURE) ||
+ !dd.Exist(FILENAME_KERNEL) ||
+ !dd.Exist(FILENAME_PACKAGE) ||
+ !dd.Exist(FILENAME_RELEASE) ||
+ !dd.Exist(FILENAME_EXECUTABLE))
+ {
+ dd.Close();
+ throw CABRTException(EXCEP_ERROR, "CMiddleWare::DebugDumpToCrashReport(): One or more of important file(s)'re missing.");
+ }
+ pCrashReport.clear();
+ dd.InitGetNextFile();
+ while (dd.GetNextFile(fileName, content, isTextFile))
+ {
+ if (!isTextFile)
+ {
+ add_crash_data_to_crash_report(pCrashReport,
+ fileName,
+ CD_BIN,
+ CD_ISNOTEDITABLE,
+ pDebugDumpDir + "/" + fileName);
+ }
+ else
+ {
+ if (fileName == FILENAME_ARCHITECTURE ||
+ fileName == FILENAME_KERNEL ||
+ fileName == FILENAME_PACKAGE ||
+ fileName == FILENAME_RELEASE ||
+ fileName == FILENAME_EXECUTABLE)
+ {
+ add_crash_data_to_crash_report(pCrashReport, fileName, CD_TXT, CD_ISNOTEDITABLE, content);
+ }
+ else if (fileName != FILENAME_UID &&
+ fileName != FILENAME_ANALYZER &&
+ fileName != FILENAME_TIME &&
+ fileName != FILENAME_DESCRIPTION )
+ {
+ if (content.length() < CD_ATT_SIZE)
+ {
+ add_crash_data_to_crash_report(pCrashReport, fileName, CD_TXT, CD_ISEDITABLE, content);
+ }
+ else
+ {
+ add_crash_data_to_crash_report(pCrashReport, fileName, CD_ATT, CD_ISEDITABLE, content);
+ }
+ }
+ }
+ }
+ dd.Close();
+}
+
+void CMiddleWare::RegisterPlugin(const std::string& pName)
+{
+ m_pPluginManager->RegisterPlugin(pName);
+}
+
+void CMiddleWare::UnRegisterPlugin(const std::string& pName)
+{
+ m_pPluginManager->UnRegisterPlugin(pName);
+}
+
+void CMiddleWare::SetPluginSettings(const std::string& pName,
+ const map_plugin_settings_t& pSettings)
+{
+ m_pPluginManager->SetPluginSettings(pName, pSettings);
+}
+
+map_plugin_settings_t CMiddleWare::GetPluginSettings(const std::string& pName)
+{
+ return m_pPluginManager->GetPluginSettings(pName);
+}
+
+std::string CMiddleWare::GetLocalUUID(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir)
+{
+ CAnalyzer* analyzer = m_pPluginManager->GetAnalyzer(pAnalyzer);
+ return analyzer->GetLocalUUID(pDebugDumpDir);
+}
+
+std::string CMiddleWare::GetGlobalUUID(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir)
+{
+ CAnalyzer* analyzer = m_pPluginManager->GetAnalyzer(pAnalyzer);
+ return analyzer->GetGlobalUUID(pDebugDumpDir);
+}
+
+void CMiddleWare::CreateReport(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir)
+{
+ CAnalyzer* analyzer = m_pPluginManager->GetAnalyzer(pAnalyzer);
+ analyzer->CreateReport(pDebugDumpDir);
+}
+
+CMiddleWare::mw_result_t CMiddleWare::CreateCrashReport(const std::string& pUUID,
+ const std::string& pUID,
+ map_crash_report_t& pCrashReport)
+{
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ database_row_t row;
+ database->Connect();
+ row = database->GetUUIDData(pUUID, pUID);
+ database->DisConnect();
+ CDebugDump dd;
+
+ if (pUUID == "" || row.m_sUUID != pUUID)
+ {
+ comm_layer_inner_warning("CMiddleWare::CreateCrashReport(): UUID '"+pUUID+"' is not in database.");
+ return MW_IN_DB_ERROR;
+ }
+
+ try
+ {
+ std::string analyzer;
+ std::string gUUID;
+
+ dd.Open(row.m_sDebugDumpDir);
+ dd.LoadText(FILENAME_ANALYZER, analyzer);
+ dd.Close();
+
+ CreateReport(analyzer, row.m_sDebugDumpDir);
+
+ gUUID = GetGlobalUUID(analyzer, row.m_sDebugDumpDir);
+
+ RunAnalyzerActions(analyzer, row.m_sDebugDumpDir);
+ DebugDumpToCrashReport(row.m_sDebugDumpDir, 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, "");
+ add_crash_data_to_crash_report(pCrashReport, CD_REPRODUCE, CD_TXT, CD_ISEDITABLE, "1.\n2.\n3.\n");
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::CreateCrashReport(): " + e.what());
+ if (e.type() == EXCEP_DD_OPEN)
+ {
+ return MW_ERROR;
+ }
+ else if (e.type() == EXCEP_DD_LOAD)
+ {
+ return MW_FILE_ERROR;
+ }
+ return MW_CORRUPTED;
+ }
+
+ return MW_OK;
+}
+
+void CMiddleWare::RunAction(const std::string& pActionDir,
+ const std::string& pPluginName,
+ const std::string& pPluginArgs)
+{
+ try
+ {
+ CAction* action = m_pPluginManager->GetAction(pPluginName);
+
+ action->Run(pActionDir, pPluginArgs);
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::RunAction(): " + e.what());
+ comm_layer_inner_status("Execution of '"+pPluginName+"' was not successful: " + e.what());
+ }
+
+}
+
+void CMiddleWare::RunActionsAndReporters(const std::string& pDebugDumpDir)
+{
+ vector_actions_and_reporters_t::iterator it_ar;
+ for (it_ar = m_vectorActionsAndReporters.begin(); it_ar != m_vectorActionsAndReporters.end(); it_ar++)
+ {
+ try
+ {
+ if (m_pPluginManager->GetPluginType((*it_ar).first) == REPORTER)
+ {
+ CReporter* reporter = m_pPluginManager->GetReporter((*it_ar).first);
+
+ map_crash_report_t crashReport;
+ DebugDumpToCrashReport(pDebugDumpDir, crashReport);
+ reporter->Report(crashReport, (*it_ar).second);
+ }
+ else if (m_pPluginManager->GetPluginType((*it_ar).first) == ACTION)
+ {
+ CAction* action = m_pPluginManager->GetAction((*it_ar).first);
+ action->Run(pDebugDumpDir, (*it_ar).second);
+ }
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::RunActionsAndReporters(): " + e.what());
+ comm_layer_inner_status("Activation of plugin '"+(*it_ar).first+"' was not successful: " + e.what());
+ }
+ }
+}
+
+void CMiddleWare::Report(const map_crash_report_t& pCrashReport)
+{
+ Report(pCrashReport, m_sPluginsConfDir);
+}
+
+void CMiddleWare::Report(const map_crash_report_t& pCrashReport,
+ const std::string& pPluginsConfDir)
+{
+ if (pCrashReport.find(CD_MWANALYZER) == pCrashReport.end() ||
+ pCrashReport.find(CD_MWUID) == pCrashReport.end() ||
+ pCrashReport.find(CD_MWUUID) == pCrashReport.end())
+ {
+ throw CABRTException(EXCEP_ERROR, "CMiddleWare::Report(): System data are missing in crash report.");
+ }
+ 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];
+
+ if (m_mapAnalyzerActionsAndReporters.find(analyzer) != m_mapAnalyzerActionsAndReporters.end())
+ {
+ vector_actions_and_reporters_t::iterator it_r;
+ for (it_r = m_mapAnalyzerActionsAndReporters[analyzer].begin();
+ it_r != m_mapAnalyzerActionsAndReporters[analyzer].end();
+ it_r++)
+ {
+ try
+ {
+ if (m_pPluginManager->GetPluginType((*it_r).first) == REPORTER)
+ {
+ CReporter* reporter = m_pPluginManager->GetReporter((*it_r).first);
+
+ if (pPluginsConfDir == m_sPluginsConfDir)
+ {
+ reporter->Report(pCrashReport, (*it_r).second);
+ }
+ else
+ {
+ reporter->LoadSettings(pPluginsConfDir + "/" + (*it_r).first + "." + PLUGINS_CONF_EXTENSION);
+ reporter->Report(pCrashReport, (*it_r).second);
+ reporter->LoadSettings(m_sPluginsConfDir + "/" + (*it_r).first + "." + PLUGINS_CONF_EXTENSION);
+ }
+ }
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::Report(): " + e.what());
+ comm_layer_inner_status("Reporting via '"+(*it_r).first+"' was not successful: " + e.what());
+ }
+ }
+ }
+
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ database->Connect();
+ database->SetReported(UUID, UID);
+ database->DisConnect();
+}
+
+void CMiddleWare::DeleteDebugDumpDir(const std::string& pDebugDumpDir)
+{
+ CDebugDump dd;
+ dd.Open(pDebugDumpDir);
+ dd.Delete();
+ dd.Close();
+}
+
+std::string CMiddleWare::DeleteCrashInfo(const std::string& pUUID,
+ const std::string& pUID)
+{
+ database_row_t row;
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ database->Connect();
+ row = database->GetUUIDData(pUUID, pUID);
+ database->Delete(pUUID, pUID);
+ database->DisConnect();
+
+ return row.m_sDebugDumpDir;
+}
+
+
+bool CMiddleWare::IsDebugDumpSaved(const std::string& pUID,
+ const std::string& pDebugDumpDir)
+{
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ vector_database_rows_t rows;
+ database->Connect();
+ rows = database->GetUIDData(pUID);
+ database->DisConnect();
+
+ int ii;
+ bool found = false;
+ for (ii = 0; ii < rows.size(); ii++)
+ {
+ if (rows[ii].m_sDebugDumpDir == pDebugDumpDir)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+CMiddleWare::mw_result_t CMiddleWare::SavePackageDescriptionToDebugDump(const std::string& pExecutable,
+ const std::string& pDebugDumpDir)
+{
+ std::string package;
+ std::string packageName;
+
+ if (pExecutable == "kernel")
+ {
+ packageName = package = "kernel";
+ }
+ else
+ {
+ package = m_RPM.GetPackage(pExecutable);
+ packageName = package.substr(0, package.rfind("-", package.rfind("-") - 1));
+ if (packageName == "" ||
+ (m_setBlackList.find(packageName) != m_setBlackList.end()))
+ {
+ if (packageName == "")
+ {
+ comm_layer_inner_debug("Executable doesn't belong to any package");
+ return MW_PACKAGE_ERROR;
+ }
+ comm_layer_inner_debug("Blacklisted package");
+ return MW_BLACKLISTED;
+ }
+ if (m_bOpenGPGCheck)
+ {
+ if (!m_RPM.CheckFingerprint(packageName) ||
+ !m_RPM.CheckHash(packageName, pExecutable))
+ {
+ comm_layer_inner_debug("Can not find package");
+ return MW_GPG_ERROR;
+ }
+ }
+ }
+
+ std::string description = m_RPM.GetDescription(packageName);
+
+ CDebugDump dd;
+ try
+ {
+ dd.Open(pDebugDumpDir);
+ dd.SaveText(FILENAME_PACKAGE, package);
+ dd.SaveText(FILENAME_DESCRIPTION, description);
+ dd.Close();
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::SavePackageDescriptionToDebugDump(): " + e.what());
+ if (e.type() == EXCEP_DD_SAVE)
+ {
+ dd.Close();
+ return MW_FILE_ERROR;
+ }
+ return MW_ERROR;
+ }
+
+ return MW_OK;
+}
+
+void CMiddleWare::RunAnalyzerActions(const std::string& pAnalyzer, const std::string& pDebugDumpDir)
+{
+ if (m_mapAnalyzerActionsAndReporters.find(pAnalyzer) != m_mapAnalyzerActionsAndReporters.end())
+ {
+ vector_actions_and_reporters_t::iterator it_a;
+ for (it_a = m_mapAnalyzerActionsAndReporters[pAnalyzer].begin();
+ it_a != m_mapAnalyzerActionsAndReporters[pAnalyzer].end();
+ it_a++)
+ {
+ try
+ {
+ if (m_pPluginManager->GetPluginType((*it_a).first) == ACTION)
+ {
+ CAction* action = m_pPluginManager->GetAction((*it_a).first);
+
+ action->Run(pDebugDumpDir, (*it_a).second);
+ }
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::RunAnalyzerActions(): " + e.what());
+ comm_layer_inner_status("Action performed by '"+(*it_a).first+"' was not successful: " + e.what());
+ }
+ }
+ }
+}
+
+CMiddleWare::mw_result_t CMiddleWare::SaveDebugDumpToDatabase(const std::string& pUUID,
+ const std::string& pUID,
+ const std::string& pTime,
+ const std::string& pDebugDumpDir,
+ map_crash_info_t& pCrashInfo)
+{
+ mw_result_t res;
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ database_row_t row;
+ database->Connect();
+ database->Insert(pUUID, pUID, pDebugDumpDir, pTime);
+ row = database->GetUUIDData(pUUID, pUID);
+ database->DisConnect();
+ res = GetCrashInfo(pUUID, pUID, pCrashInfo);
+ if (row.m_sReported == "1")
+ {
+ comm_layer_inner_debug("Crash is already reported");
+ return MW_REPORTED;
+ }
+ if (row.m_sCount != "1")
+ {
+ comm_layer_inner_debug("Crash is in database already");
+ return MW_OCCURED;
+ }
+ return res;
+}
+
+CMiddleWare::mw_result_t CMiddleWare::SaveDebugDump(const std::string& pDebugDumpDir)
+{
+ map_crash_info_t info;
+ return SaveDebugDump(pDebugDumpDir, info);
+}
+
+CMiddleWare::mw_result_t CMiddleWare::SaveDebugDump(const std::string& pDebugDumpDir,
+ map_crash_info_t& pCrashInfo)
+{
+ std::string lUUID;
+ std::string UID;
+ std::string time;
+ std::string analyzer;
+ std::string executable;
+ CDebugDump dd;
+ mw_result_t res;
+
+ try
+ {
+ dd.Open(pDebugDumpDir);
+ dd.LoadText(FILENAME_TIME, time);
+ dd.LoadText(FILENAME_UID, UID);
+ dd.LoadText(FILENAME_ANALYZER, analyzer);
+ dd.LoadText(FILENAME_EXECUTABLE, executable);
+ dd.Close();
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::SaveDebugDump(): " + e.what());
+ if (e.type() == EXCEP_DD_SAVE)
+ {
+ dd.Close();
+ return MW_FILE_ERROR;
+ }
+ return MW_ERROR;
+ }
+
+ if (IsDebugDumpSaved(UID, pDebugDumpDir))
+ {
+ return MW_IN_DB;
+ }
+ if ((res = SavePackageDescriptionToDebugDump(executable, pDebugDumpDir)) != MW_OK)
+ {
+ return res;
+ }
+
+ lUUID = GetLocalUUID(analyzer, pDebugDumpDir);
+
+ return SaveDebugDumpToDatabase(lUUID, UID, time, pDebugDumpDir, pCrashInfo);
+}
+
+CMiddleWare::mw_result_t CMiddleWare::GetCrashInfo(const std::string& pUUID,
+ const std::string& pUID,
+ map_crash_info_t& pCrashInfo)
+{
+ pCrashInfo.clear();
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ database_row_t row;
+ database->Connect();
+ row = database->GetUUIDData(pUUID, pUID);
+ database->DisConnect();
+
+ CDebugDump dd;
+ std::string package;
+ std::string executable;
+ std::string description;
+
+ try
+ {
+ dd.Open(row.m_sDebugDumpDir);
+ dd.LoadText(FILENAME_EXECUTABLE, executable);
+ dd.LoadText(FILENAME_PACKAGE, package);
+ dd.LoadText(FILENAME_DESCRIPTION, description);
+ dd.Close();
+ }
+ catch (CABRTException& e)
+ {
+ comm_layer_inner_warning("CMiddleWare::GetCrashInfo(): " + e.what());
+ if (e.type() == EXCEP_DD_LOAD)
+ {
+ dd.Close();
+ return MW_FILE_ERROR;
+ }
+ return MW_ERROR;
+ }
+ 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_MWDDD, row.m_sDebugDumpDir);
+
+ return MW_OK;
+}
+
+vector_pair_string_string_t CMiddleWare::GetUUIDsOfCrash(const std::string& pUID)
+{
+ CDatabase* database = m_pPluginManager->GetDatabase(m_sDatabase);
+ vector_database_rows_t rows;
+ database->Connect();
+ rows = database->GetUIDData(pUID);
+ database->DisConnect();
+
+ vector_pair_string_string_t UUIDsUIDs;
+ int ii;
+ for (ii = 0; ii < rows.size(); ii++)
+ {
+ UUIDsUIDs.push_back(make_pair(rows[ii].m_sUUID, rows[ii].m_sUID));
+ }
+
+ return UUIDsUIDs;
+}
+
+vector_map_string_string_t CMiddleWare::GetPluginsInfo()
+{
+ return m_pPluginManager->GetPluginsInfo();
+}
+
+void CMiddleWare::SetOpenGPGCheck(bool pCheck)
+{
+ m_bOpenGPGCheck = pCheck;
+}
+
+void CMiddleWare::SetDatabase(const std::string& pDatabase)
+{
+ m_sDatabase = pDatabase;
+}
+
+void CMiddleWare::AddOpenGPGPublicKey(const std::string& pKey)
+{
+ m_RPM.LoadOpenGPGPublicKey(pKey);
+}
+
+void CMiddleWare::AddBlackListedPackage(const std::string& pPackage)
+{
+ m_setBlackList.insert(pPackage);
+}
+
+void CMiddleWare::AddAnalyzerActionOrReporter(const std::string& pAnalyzer,
+ const std::string& pAnalyzerOrReporter,
+ const std::string& pArgs)
+{
+ m_mapAnalyzerActionsAndReporters[pAnalyzer].push_back(make_pair(pAnalyzerOrReporter, pArgs));
+}
+
+void CMiddleWare::AddActionOrReporter(const std::string& pActionOrReporter,
+ const std::string& pArgs)
+{
+ m_vectorActionsAndReporters.push_back(make_pair(pActionOrReporter, pArgs));
+}
diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h
new file mode 100644
index 0000000..050844c
--- /dev/null
+++ b/src/Daemon/MiddleWare.h
@@ -0,0 +1,350 @@
+/*
+ MiddleWare.h - header file for MiddleWare library. It wraps plugins and
+ take case of them.
+
+ Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
+ 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 MIDDLEWARE_H_
+#define MIDDLEWARE_H_
+
+#include "PluginManager.h"
+#include "CrashTypes.h"
+#include "MiddleWareTypes.h"
+#include "RPM.h"
+
+/**
+ * A very important class :-). It manages part of user demands like creating
+ * reports, or reporting stuff somewhere etc.
+ */
+class CMiddleWare
+{
+ public:
+ /**
+ * An emun contains all return codes.
+ */
+ typedef enum {
+ MW_ERROR, /**< Common error.*/
+ MW_OK, /**< No error.*/
+ MW_BLACKLISTED, /**< Package is blacklisted.*/
+ MW_CORRUPTED, /**< Debugdump directory is corrupted.*/
+ MW_PACKAGE_ERROR, /**< Cannot determine package name.*/
+ MW_GPG_ERROR, /**< Package is not signed properly.*/
+ MW_REPORTED, /**< Crash is already reported.*/
+ MW_OCCURED, /**< Crash occurred in the past, but it is not reported yet.*/
+ MW_IN_DB, /**< Debugdump directory is already saved in a database.*/
+ MW_IN_DB_ERROR, /**< Error while working with a database.*/
+ MW_FILE_ERROR /**< Error when trying open debugdump directory or
+ when trying open file in debug dump directory..*/
+ } mw_result_t;
+
+ private:
+ typedef set_strings_t set_blacklist_t;
+ typedef set_strings_t set_enabled_plugins_t;
+ typedef std::vector<pair_string_string_t> vector_pairt_strings_t;
+ typedef vector_pairt_strings_t vector_actions_and_reporters_t;
+ typedef std::map<std::string, vector_actions_and_reporters_t> map_analyzer_actions_and_reporters_t;
+
+ /**
+ * An instance of CPluginManager. When MiddleWare wants to do something
+ * with plugins, it calls the plugin manager.
+ * @see PluginManager.h
+ */
+ CPluginManager* m_pPluginManager;
+ /**
+ * An instance of CRPM used for package checking.
+ * @see RPM.h
+ */
+ CRPM m_RPM;
+ /**
+ * A set of blacklisted packages.
+ */
+ set_blacklist_t m_setBlackList;
+ /**
+ * A name of database plugin, which is used for metadata.
+ */
+ std::string m_sDatabase;
+ /**
+ * A map, which associates particular analyzer to one or more
+ * action or reporter plugins. These are activated when a crash, which
+ * is maintained by particular analyzer, occurs.
+ */
+ map_analyzer_actions_and_reporters_t m_mapAnalyzerActionsAndReporters;
+ /**
+ * A vector of one or more action or reporter plugins. These are
+ * activated when any crash occurs.
+ */
+ vector_actions_and_reporters_t m_vectorActionsAndReporters;
+ /**
+ * Plugins configuration directory (e.g. /etc/abrt/plugins, ...).
+ */
+ std::string m_sPluginsConfDir;
+ /**
+ * Check GPG finger print?
+ */
+ bool m_bOpenGPGCheck;
+ /**
+ * A method, which gets a local UUID from particular analyzer plugin.
+ * @param pAnalyzer A name of an analyzer plugin.
+ * @param pDebugDumpDir A debugdump dir containing all necessary data.
+ * @return A local UUID.
+ */
+ std::string GetLocalUUID(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which gets a global UUID from particular analyzer plugin.
+ * @param pAnalyzer A name of an analyzer plugin.
+ * @param pDebugDumpDir A debugdump dir containing all necessary data.
+ * @return A global UUID.
+ */
+ std::string GetGlobalUUID(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which takes care of getting all additional data needed
+ * for computing UUIDs and creating a report for particular analyzer
+ * plugin. This report could be send somewhere afterwards.
+ * @param pAnalyzer A name of an analyzer plugin.
+ * @param pDebugDumpPath A debugdump dir containing all necessary data.
+ */
+ void CreateReport(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which executes all action plugins, which are associated to
+ * particular analyzer plugin.
+ * @param pAnalyzer A name of an analyzer plugin.
+ * @param pDebugDumpPath A debugdump dir containing all necessary data.
+ */
+ void RunAnalyzerActions(const std::string& pAnalyzer,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which 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.
+ */
+ void DebugDumpToCrashReport(const std::string& pDebugDumpDir,
+ map_crash_report_t& pCrashReport);
+ /**
+ * A method, which checks is particular debugdump directory is saved
+ * in database. This check is done together with an UID of an user.
+ * @param pUID an UID of an user.
+ * @param pDebugDumpDir A debugdump dir containing all necessary data.
+ * @return It returns true if debugdump dir is already saved, otherwise
+ * it returns false.
+ */
+ bool IsDebugDumpSaved(const std::string& pUID,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which gets a package name from executable name and saves
+ * package description to particular debugdump directory of a crash.
+ * @param pExecutable A name of crashed application.
+ * @param pDebugDumpDir A debugdump dir containing all necessary data.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecutable,
+ const std::string& pDebugDumpDir);
+ /**
+ * A method, which save a debugdump into database. If a saving is
+ * successful, then a crash info is filled. Otherwise the crash info is
+ * not changed.
+ * @param pUUID A local UUID of a crash.
+ * @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.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t SaveDebugDumpToDatabase(const std::string& pUUID,
+ const std::string& pUID,
+ const std::string& pTime,
+ const std::string& pDebugDumpDir,
+ map_crash_info_t& pCrashInfo);
+
+ public:
+ /**
+ * A constructor.
+ * @param pPluginsConfDir A plugins configuration directory.
+ * @param pPluginsLibDir A plugins library directory.
+ */
+ CMiddleWare(const std::string& pPluginsConfDir,
+ const std::string& pPluginsLibDir);
+ /**
+ * A destructor.
+ */
+ ~CMiddleWare();
+ /**
+ * A method, which registers particular plugin.
+ * @param pName A plugin name.
+ */
+ void RegisterPlugin(const std::string& pName);
+ /**
+ * A method, which unregister particular plugin.
+ * @param pName A plugin name.
+ */
+ void UnRegisterPlugin(const std::string& pName);
+ /**
+ * A method, which sets up a plugin.
+ * @param pName A plugin name.
+ * @param pSettings A plugin's settings.
+ */
+ void SetPluginSettings(const std::string& pName,
+ const map_plugin_settings_t& pSettings);
+ /**
+ * A method, which returns plugin's settings.
+ * @param pName A plugin name.
+ * @return Plugin's settings
+ */
+ map_plugin_settings_t GetPluginSettings(const std::string& pName);
+ /**
+ * A method, which gets all plugins info (event those plugins which are
+ * disabled). It can be send via DBus to GUI and displayed to an user.
+ * Then a user can fill all needed informations like URLs etc.
+ * @return A vector of maps <key, vaule>
+ */
+ vector_map_string_string_t GetPluginsInfo();
+ /**
+ * A method, which takes care of getting all additional data needed
+ * for computing UUIDs and creating a report for particular analyzer
+ * plugin. This report could be send somewhere afterwards. If a creation
+ * 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.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t CreateCrashReport(const std::string& pUUID,
+ const std::string& pUID,
+ map_crash_report_t& pCrashReport);
+ /**
+ * A method, which activate particular action plugin.
+ * @param pActionDir A directory, which is passed as working to a action plugin.
+ * @param pPluginName An action plugin name.
+ * @param pPluginArgs Action plugin's arguments.
+ */
+ void RunAction(const std::string& pActionDir,
+ const std::string& pPluginName,
+ const std::string& pPluginArgs);
+ /**
+ * A method, which activate all action and reporter plugins when any
+ * crash occurs.
+ * @param pDebugDumpDir A debugdump dir containing all necessary data.
+ */
+ void RunActionsAndReporters(const std::string& pDebugDumpDir);
+ /**
+ * A method, which reports a crash report to particular receiver.
+ * @param pCrashReport A crash report.
+ */
+ void Report(const map_crash_report_t& pCrashReport);
+ /**
+ * A method, which reports a crash report to particular receiver. It
+ * takes a path where settings of reporter are stored (e.g. $HOME/.abrt,
+ * ...).
+ * @param pCrashReport A crash report.
+ * @param pSettingsPath A path to setting files.
+ */
+ void Report(const map_crash_report_t& pCrashReport,
+ const std::string& pSettingsPath);
+ /**
+ * A method, which deletes particular debugdump directory.
+ * @param pDebugDumpDir A debugdump directory.
+ */
+ void DeleteDebugDumpDir(const std::string& pDebugDumpDir);
+ /**
+ * A method, which delete a row from database. If a deleting is
+ * successfull, it returns a debugdump directort, which is not
+ * deleted. Otherwise, it returns empty string.
+ * @param pUUID A local UUID of a crash.
+ * @param pUID An UID of an user.
+ * @return A debugdump directory.
+ */
+ std::string DeleteCrashInfo(const std::string& pUUID,
+ const std::string& pUID);
+ /**
+ * A method, whis saves debugdump into database.
+ * @param pDebugDumpDir A debugdump directory.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir);
+ /**
+ * A method, whis saves debugdump into database. If saving is sucessful
+ * it fills crash info.
+ * @param pDebugDumpDir A debugdump directory.
+ * @param pCrashInfo A crash info.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
+ map_crash_info_t& pCrashInfo);
+ /**
+ * A method, which gets one crash info. If a getting is successful,
+ * then a crash info is filled.
+ * @param pUUID A local UUID of a crash.
+ * @param pUID An UID of an user.
+ * @param pCrashInfo A crash info.
+ * @return It return results of operation. See mw_result_t.
+ */
+ mw_result_t GetCrashInfo(const std::string& pUUID,
+ const std::string& pUID,
+ map_crash_info_t& pCrashInfo);
+ /**
+ * A method, which gets all local UUIDs and UIDs of crashes. These crashes
+ * occurred when a particular user was logged in.
+ * @param pUID an UID of an user.
+ * @return A vector of pairs (local UUID, UID).
+ */
+ vector_pair_string_string_t GetUUIDsOfCrash(const std::string& pUID);
+ /**
+ * A method, which set a GPG finger print check.
+ * @param pCheck Is it enabled?
+ */
+ void SetOpenGPGCheck(bool pCheck);
+ /**
+ * A method, which sets a name of database.
+ * @param pDatabase A database name.
+ */
+ void SetDatabase(const std::string& pDatabase);
+ /**
+ * A method, which adds one path to a GPG public key into MW's set.
+ * @param pKey A path to a GPG public key.
+ */
+ void AddOpenGPGPublicKey(const std::string& pKey);
+ /**
+ * A method, which adds one blacklisted package.
+ */
+ void AddBlackListedPackage(const std::string& pPackage);
+ /**
+ * A method, which adds one association among alanyzer plugin and its
+ * action and reporter plugins.
+ * @param pAnalyzer A name of an analyzer plugin.
+ * @param pActionOrReporter A name of an action or reporter plugin.
+ * @param pArgs An arguments for action or reporter plugin.
+ */
+ void AddAnalyzerActionOrReporter(const std::string& pAnalyzer,
+ const std::string& pActionOrReporter,
+ const std::string& pArgs);
+ /**
+ * A method, which adds action and reporter plugins, which are activated
+ * when any crash occurs.
+ * @param pActionOrReporter A name of an action or reporter plugin.
+ * @param pArgs An arguments for action or reporter plugin.
+ */
+ void AddActionOrReporter(const std::string& pActionOrReporter,
+ const std::string& pArgs);
+};
+
+#endif /*MIDDLEWARE_H_*/
diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp
new file mode 100644
index 0000000..b0ba0db
--- /dev/null
+++ b/src/Daemon/PluginManager.cpp
@@ -0,0 +1,287 @@
+/*
+ PluginManager.cpp
+
+ Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <iostream>
+#include "PluginManager.h"
+#include "ABRTException.h"
+#include "CommLayerInner.h"
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+/**
+ * Text representation of plugin types.
+ */
+static const char* const plugin_type_str_t[] = {
+ "Analyzer",
+ "Action",
+ "Reporter",
+ "Database"
+};
+
+
+CPluginManager::CPluginManager(
+ const std::string& pPluginsConfDir,
+ const std::string& pPluginsLibDir)
+:
+ m_sPluginsConfDir(pPluginsConfDir),
+ m_sPluginsLibDir(pPluginsLibDir)
+{}
+
+CPluginManager::~CPluginManager()
+{}
+
+void CPluginManager::LoadPlugins()
+{
+ DIR *dir = opendir(m_sPluginsLibDir.c_str());
+ struct dirent *dent = NULL;
+ if (dir != NULL)
+ {
+ while ((dent = readdir(dir)) != NULL)
+ {
+ // FIXME: need to handle DT_UNKNOWN too
+ if (dent->d_type == DT_REG)
+ {
+ std::string name = dent->d_name;
+ std::string extension = name.substr(name.length() - sizeof(PLUGINS_LIB_EXTENSION) + 1);
+ if (extension == PLUGINS_LIB_EXTENSION)
+ {
+ name.erase(0, sizeof(PLUGINS_LIB_PREFIX) - 1);
+ name.erase(name.length() - sizeof(PLUGINS_LIB_EXTENSION));
+ LoadPlugin(name);
+ }
+ }
+ }
+ closedir(dir);
+ }
+}
+
+void CPluginManager::UnLoadPlugins()
+{
+ map_abrt_plugins_t::iterator it_p;
+ while ((it_p = m_mapABRTPlugins.begin()) != m_mapABRTPlugins.end())
+ {
+ std::string pluginName = it_p->first;
+ UnLoadPlugin(pluginName);
+ }
+}
+
+void CPluginManager::LoadPlugin(const std::string& pName)
+{
+ if (m_mapABRTPlugins.find(pName) == m_mapABRTPlugins.end())
+ {
+ CABRTPlugin* abrtPlugin = NULL;
+ try
+ {
+ std::string libPath = m_sPluginsLibDir + "/" + PLUGINS_LIB_PREFIX + pName + "." + PLUGINS_LIB_EXTENSION;
+ abrtPlugin = new CABRTPlugin(libPath);
+ if (abrtPlugin->GetMagicNumber() != PLUGINS_MAGIC_NUMBER ||
+ (abrtPlugin->GetType() < ANALYZER && abrtPlugin->GetType() > DATABASE))
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::LoadPlugin(): non-compatible plugin");
+ }
+ comm_layer_inner_debug("Plugin " + pName + " (" + abrtPlugin->GetVersion() + ") succesfully loaded.");
+ m_mapABRTPlugins[pName] = abrtPlugin;
+ }
+ catch (CABRTException& e)
+ {
+ if (abrtPlugin != NULL)
+ {
+ delete abrtPlugin;
+ }
+ comm_layer_inner_warning("CPluginManager::LoadPlugin(): " + e.what());
+ comm_layer_inner_warning("Failed to load plugin " + pName);
+ }
+ }
+}
+
+void CPluginManager::UnLoadPlugin(const std::string& pName)
+{
+ if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end())
+ {
+ UnRegisterPlugin(pName);
+ delete m_mapABRTPlugins[pName];
+ m_mapABRTPlugins.erase(pName);
+ comm_layer_inner_debug("Plugin " + pName + " sucessfully unloaded.");
+ }
+}
+
+void CPluginManager::RegisterPlugin(const std::string& pName)
+{
+ if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end())
+ {
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ std::string path = m_sPluginsConfDir + "/" + pName + "." + PLUGINS_CONF_EXTENSION;
+ CPlugin* plugin = m_mapABRTPlugins[pName]->PluginNew();
+ try
+ {
+ plugin->Init();
+ plugin->LoadSettings(path);
+ }
+ catch (std::string sError)
+ {
+ comm_layer_inner_warning("Can not initialize plugin " + pName + "("
+ + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()])
+ + ")");
+ UnLoadPlugin(pName);
+ return;
+ }
+ m_mapPlugins[pName] = plugin;
+ comm_layer_inner_debug("Registered plugin " + pName + "("
+ + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()])
+ + ")");
+ }
+ }
+}
+
+void CPluginManager::UnRegisterPlugin(const std::string& pName)
+{
+ if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end())
+ {
+ if (m_mapPlugins.find(pName) != m_mapPlugins.end())
+ {
+ m_mapPlugins[pName]->DeInit();
+ delete m_mapPlugins[pName];
+ m_mapPlugins.erase(pName);
+ comm_layer_inner_debug("UnRegistred plugin " + pName + "("
+ + std::string(plugin_type_str_t[m_mapABRTPlugins[pName]->GetType()])
+ + ")");
+ }
+ }
+}
+
+CAnalyzer* CPluginManager::GetAnalyzer(const std::string& pName)
+{
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAnalyzer():"
+ "Analyzer plugin: '"+pName+"' is not registered.");
+ }
+ if (m_mapABRTPlugins[pName]->GetType() != ANALYZER)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAnalyzer():"
+ "Plugin: '"+pName+"' is not analyzer plugin.");
+ }
+ return (CAnalyzer*)(m_mapPlugins[pName]);
+}
+
+CReporter* CPluginManager::GetReporter(const std::string& pName)
+{
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetReporter():"
+ "Reporter plugin: '"+pName+"' is not registered.");
+ }
+ if (m_mapABRTPlugins[pName]->GetType() != REPORTER)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetReporter():"
+ "Plugin: '"+pName+"' is not reporter plugin.");
+ }
+ return (CReporter*)(m_mapPlugins[pName]);
+}
+
+CAction* CPluginManager::GetAction(const std::string& pName)
+{
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAction():"
+ "Action plugin: '"+pName+"' is not registered.");
+ }
+ if (m_mapABRTPlugins[pName]->GetType() != ACTION)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetAction():"
+ "Plugin: '"+pName+"' is not action plugin.");
+ }
+ return (CAction*)(m_mapPlugins[pName]);
+}
+
+CDatabase* CPluginManager::GetDatabase(const std::string& pName)
+{
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetDatabase():"
+ "Database plugin: '"+pName+"' is not registered.");
+ }
+ if (m_mapABRTPlugins[pName]->GetType() != DATABASE)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetDatabase():"
+ "Plugin: '"+pName+"' is not database plugin.");
+ }
+ return (CDatabase*)(m_mapPlugins[pName]);
+}
+
+plugin_type_t CPluginManager::GetPluginType(const std::string& pName)
+{
+ if (m_mapPlugins.find(pName) == m_mapPlugins.end())
+ {
+ throw CABRTException(EXCEP_PLUGIN, "CPluginManager::GetPluginType():"
+ "Plugin: '"+pName+"' is not registered.");
+ }
+ return m_mapABRTPlugins[pName]->GetType();
+}
+
+vector_map_string_string_t CPluginManager::GetPluginsInfo()
+{
+ vector_map_string_string_t ret;
+ map_abrt_plugins_t::iterator it_abrt_plugin;
+ for (it_abrt_plugin = m_mapABRTPlugins.begin(); it_abrt_plugin != m_mapABRTPlugins.end(); it_abrt_plugin++)
+ {
+ map_string_string_t plugin_info;
+
+ plugin_info["Enabled"] = (m_mapPlugins.find(it_abrt_plugin->second->GetName()) != m_mapPlugins.end()) ?
+ "yes" : "no";
+ plugin_info["Type"] = plugin_type_str_t[it_abrt_plugin->second->GetType()];
+ plugin_info["Name"] = it_abrt_plugin->second->GetName();
+ plugin_info["Version"] = it_abrt_plugin->second->GetVersion();
+ plugin_info["Description"] = it_abrt_plugin->second->GetDescription();
+ plugin_info["Email"] = it_abrt_plugin->second->GetEmail();
+ plugin_info["WWW"] = it_abrt_plugin->second->GetWWW();
+ plugin_info["GTKBuilder"] = it_abrt_plugin->second->GetGTKBuilder();
+ ret.push_back(plugin_info);
+ }
+ return ret;
+}
+
+void CPluginManager::SetPluginSettings(const std::string& pName,
+ const map_plugin_settings_t& pSettings)
+{
+ if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end())
+ {
+ if (m_mapPlugins.find(pName) != m_mapPlugins.end())
+ {
+ m_mapPlugins[pName]->SetSettings(pSettings);
+ }
+ }
+}
+
+map_plugin_settings_t CPluginManager::GetPluginSettings(const std::string& pName)
+{
+ map_plugin_settings_t ret;
+ if (m_mapABRTPlugins.find(pName) != m_mapABRTPlugins.end())
+ {
+ if (m_mapPlugins.find(pName) != m_mapPlugins.end())
+ {
+ ret = m_mapPlugins[pName]->GetSettings();
+ }
+ }
+ return ret;
+}
diff --git a/src/Daemon/PluginManager.h b/src/Daemon/PluginManager.h
new file mode 100644
index 0000000..53ec77c
--- /dev/null
+++ b/src/Daemon/PluginManager.h
@@ -0,0 +1,156 @@
+/*
+ PluginManager.h - header file for plugin manager. it takes care about
+ (un)loading plugins
+
+ Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
+ 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 PLUGINMANAGER_H_
+#define PLUGINMANAGER_H_
+
+#include <map>
+#include <string>
+#include "ABRTPlugin.h"
+#include "Plugin.h"
+#include "Analyzer.h"
+#include "Reporter.h"
+#include "Database.h"
+#include "Action.h"
+#include "MiddleWareTypes.h"
+
+/**
+ * A class. It takes care of loading, registering and manipulating with
+ * plugins. When a plugin is loaded, its library is opened, but no plugin
+ * instance is created. It is possible after plugin registration.
+ */
+class CPluginManager
+{
+ private:
+ typedef std::map<std::string, CABRTPlugin*> map_abrt_plugins_t;
+ typedef std::map<std::string, CPlugin*> map_plugins_t;
+
+ /**
+ * Loaded plugins. A key is a plugin name.
+ */
+ map_abrt_plugins_t m_mapABRTPlugins;
+ /**
+ * Registered plugins. A key is a plugin name.
+ */
+ map_plugins_t m_mapPlugins;
+ /**
+ * Plugins configuration directory (e.g. /etc/abrt/plugins, ...).
+ */
+ std::string m_sPluginsConfDir;
+ /**
+ * Plugins library directory (e.g. /usr/lib/abrt/plugins, ...).
+ */
+ std::string m_sPluginsLibDir;
+
+ public:
+ /**
+ * A constructor.
+ * @param pPluginsConfDir A plugins configuration directory.
+ * @param pPluginsLibDir A plugins library directory.
+ */
+ CPluginManager(const std::string& pPluginsConfDir,
+ const std::string& pPluginsLibDir);
+ /**
+ * A destructor.
+ */
+ ~CPluginManager();
+ /**
+ * A method, which loads all plugins in plugins library direcotry.
+ */
+ void LoadPlugins();
+ /**
+ * A method, which unregister and unload all loaded plugins.
+ */
+ void UnLoadPlugins();
+ /**
+ * A method, which loads particular plugin.
+ * @param pName A plugin name.
+ */
+ void LoadPlugin(const std::string& pName);
+ /**
+ * A method, which unloads particular plugin.
+ * @param pName A plugin name.
+ */
+ void UnLoadPlugin(const std::string& pName);
+ /**
+ * A method, which registers particular plugin.
+ * @param pName A plugin name.
+ */
+ void RegisterPlugin(const std::string& pName);
+ /**
+ * A method, which unregister particular plugin.
+ * @param pName A plugin name.
+ */
+ void UnRegisterPlugin(const std::string& pName);
+ /**
+ * A method, which returns instance of particular analyzer plugin.
+ * @param pName A plugin name.
+ * @return An analyzer plugin.
+ */
+ CAnalyzer* GetAnalyzer(const std::string& pName);
+ /**
+ * A method, which returns instance of particular reporter plugin.
+ * @param pName A plugin name.
+ * @return A reporter plugin.
+ */
+ CReporter* GetReporter(const std::string& pName);
+ /**
+ * A method, which returns instance of particular action plugin.
+ * @param pName A plugin name.
+ * @return An action plugin.
+ */
+ CAction* GetAction(const std::string& pName);
+ /**
+ * A method, which returns instance of particular database plugin.
+ * @param pName A plugin name.
+ * @return A database plugin.
+ */
+ CDatabase* GetDatabase(const std::string& pName);
+ /**
+ * A method, which returns type of particular plugin.
+ * @param pName A plugin name.
+ * @return A plugin type.
+ */
+ plugin_type_t GetPluginType(const std::string& pName);
+ /**
+ * A method, which gets all plugins info (event those plugins which are
+ * disabled). It can be send via DBus to GUI and displayed to an user.
+ * Then a user can fill all needed informations like URLs etc.
+ * @return A vector of maps <key, vaule>
+ */
+ vector_map_string_string_t GetPluginsInfo();
+ /**
+ * A method, which sets up a plugin.
+ * @param pName A plugin name.
+ * @param pSettings A plugin's settings.
+ */
+ void SetPluginSettings(const std::string& pName,
+ const map_plugin_settings_t& pSettings);
+ /**
+ * A method, which returns plugin's settings.
+ * @param pName A plugin name.
+ * @return Plugin's settings
+ */
+ map_plugin_settings_t GetPluginSettings(const std::string& pName);
+};
+
+#endif /*PLUGINMANAGER_H_*/
diff --git a/src/Daemon/abrt.8 b/src/Daemon/abrt.8
index f3ae127..b106041 100644
--- a/src/Daemon/abrt.8
+++ b/src/Daemon/abrt.8
@@ -27,7 +27,7 @@ to print more debugging information when the daemon is started.
When you use some other crash-catching tool, specific for an application
or an application type (for example BugBuddy for GNOME applications),
crashes of this type will be handled by that tool and
-not by \fIabrt\fP. If you want \fIabrt\fP to handle these crashes,
+not by \fIabrt\fP. If you want \fIabrt\fP to handle these crashes,
turn off the higher-level crash-catching tool.
.SH "SEE ALSO"
.IR abrt.conf (5),
diff --git a/src/Daemon/abrt.conf.5 b/src/Daemon/abrt.conf.5
index edccb59..3b172bc 100644
--- a/src/Daemon/abrt.conf.5
+++ b/src/Daemon/abrt.conf.5
@@ -5,11 +5,11 @@ abrt.conf \- configuration file for abrt
.P
.I abrt
is a daemon that watches for application crashes. When a crash occurs,
-it collects the crash data and takes action according to
+it collects the crash data and takes action according to
its configuration. This manual page describes \fIabrt\fP's configuration
file.
.P
-The configuration file consists of sections, each section contains
+The configuration file consists of sections, each section contains
several items in the format "Option = Value". A description of each
section follows:
.SS [Common]
@@ -21,7 +21,7 @@ will report crashes only in GPG signed packages. When set to "no",
it will report crashes also in unsigned packages.
.TP
.B OpenGPGPublicKeys = \fIfilename\fP , \fIfilename\fP ...
-These are the trusted GPG keys with which packages have to be
+These are the trusted GPG keys with which packages have to be
signed for
.I abrt
to report them if "EnableOpenGPG = yes".
@@ -35,7 +35,7 @@ will ignore packages in this list and will not handle their crashes.
will only load plugins in this list.
.TP
.B Database = \fIdatabasePlugin\fP
-This specifies which database plugin
+This specifies which database plugin
.I abrt
uses to store metadata about the crash.
.TP
diff --git a/src/Daemon/exported-symbols b/src/Daemon/exported-symbols
index 511b598..2810010 100644
--- a/src/Daemon/exported-symbols
+++ b/src/Daemon/exported-symbols
@@ -1,3 +1,3 @@
-{
- get_commlayer;
+{
+ get_commlayer;
};
diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp
index 6a8b1d6..b5b576b 100644
--- a/src/Hooks/CCpp.cpp
+++ b/src/Hooks/CCpp.cpp
@@ -22,14 +22,6 @@
#include "DebugDump.h"
#include "ABRTException.h"
-//#include <stdlib.h>
-//#include <string.h>
-//#include <limits.h>
-//#include <stdio.h>
-//#include <sys/types.h>
-//#include <sys/stat.h>
-//#include <unistd.h>
-//#include <time.h>
#include <syslog.h>
#include <string>
@@ -39,32 +31,17 @@
#define VAR_RUN_PID_FILE VAR_RUN"/abrt.pid"
-static void write_success_log(const char* pid)
+static char* get_executable(pid_t pid)
{
- openlog("abrt", 0, LOG_DAEMON);
- syslog(LOG_WARNING, "CCpp Language Hook: Crashed pid: %s", pid);
- closelog();
-}
-
-static void write_faliure_log(const char* msg)
-{
- openlog("abrt", 0, LOG_DAEMON);
- syslog(LOG_WARNING, "CCpp Language Hook: Exception occur: %s", msg);
- closelog();
-}
-
-
-char* get_executable(const char* pid)
-{
- char path[PATH_MAX];
- char executable[PATH_MAX];
+ char buf[PATH_MAX + 1];
int len;
- snprintf(path, sizeof(path), "/proc/%s/exe", pid);
- if ((len = readlink(path, executable, PATH_MAX)) != -1)
+ snprintf(buf, sizeof(buf), "/proc/%u/exe", (int)pid);
+ len = readlink(buf, buf, sizeof(buf)-1);
+ if (len >= 0)
{
- executable[len] = '\0';
- return xstrdup(executable);
+ buf[len] = '\0';
+ return xstrdup(buf);
}
return NULL;
}
@@ -72,49 +49,62 @@ char* get_executable(const char* pid)
// taken from kernel
#define COMMAND_LINE_SIZE 2048
-char* get_cmdline(const char* pid)
+static char* get_cmdline(pid_t pid)
{
char path[PATH_MAX];
char cmdline[COMMAND_LINE_SIZE];
- snprintf(path, sizeof(path), "/proc/%s/cmdline", pid);
- FILE* fp = fopen(path, "r");
- int ch;
- int ii = 0;
- if (fp)
+ snprintf(path, sizeof(path), "/proc/%u/cmdline", (int)pid);
+ int dst = 0;
+
+ int fd = open(path, O_RDONLY);
+ if (fd >= 0)
{
- while ((ch = fgetc(fp)) != EOF && ii < COMMAND_LINE_SIZE-1)
+ int len = read(fd, cmdline, sizeof(cmdline) - 1);
+ if (len >= 0)
{
- if (ch == 0)
+ int src = 0;
+ while (src < len)
{
- cmdline[ii] = ' ';
+ char ch = cmdline[src++];
+ if (ch == '\0')
+ {
+ cmdline[dst++] = ' ';
+ }
+ /* TODO: maybe just ch >= ' '? */
+ else if (isspace(ch) || (isascii(ch) && !iscntrl(ch)))
+ {
+ cmdline[dst++] = ch;
+ }
}
- else if (isspace(ch) || (isascii(ch) && !iscntrl(ch)))
- {
- cmdline[ii] = ch;
- }
- ii++;
}
- fclose(fp);
+ close(fd);
}
- cmdline[ii] = '\0';
+ cmdline[dst] = '\0';
+
return xstrdup(cmdline);
}
-#define PID_MAX 16
-
-int daemon_is_ok()
+static int daemon_is_ok()
{
- char pid[PID_MAX];
+ char pid[sizeof(pid_t)*3 + 2];
char path[PATH_MAX];
struct stat buff;
- FILE* fp = fopen(VAR_RUN_PID_FILE, "r");
- if (fp == NULL)
+ int fd = open(VAR_RUN_PID_FILE, O_RDONLY);
+ if (fd < 0)
{
return 0;
}
- fgets(pid, sizeof(pid), fp);
- fclose(fp);
+ int len = read(fd, pid, sizeof(pid)-1);
+ close(fd);
+ if (len <= 0)
+ return 0;
+ pid[len] = '\0';
*strchrnul(pid, '\n') = '\0';
+ /* paranoia: we don't want to check /proc//stat or /proc///stat */
+ if (pid[0] == '\0' || pid[0] == '/')
+ return 0;
+
+ /* TODO: maybe readlink and check that it is "xxx/abrt"? */
snprintf(path, sizeof(path), "/proc/%s/stat", pid);
if (stat(path, &buff) == -1)
{
@@ -129,27 +119,33 @@ int main(int argc, char** argv)
const char* program_name = argv[0];
if (argc < 4)
{
- fprintf(stderr, "Usage: %s: <dddir> <pid> <signal> <uid>\n",
- program_name);
- return -1;
+ error_msg_and_die("Usage: %s: <dddir> <pid> <signal> <uid>", program_name);
}
+ openlog("abrt", 0, LOG_DAEMON);
logmode = LOGMODE_SYSLOG;
const char* dddir = argv[1];
- const char* pid = argv[2];
- const char* signal = argv[3];
- const char* uid = argv[4];
-
- if (strcmp(signal, "3") != 0 && // SIGQUIT
- strcmp(signal, "4") != 0 && // SIGILL
- strcmp(signal, "6") != 0 && // SIGABRT
- strcmp(signal, "8") != 0 && // SIGFPE
- strcmp(signal, "11") != 0) // SIGSEGV
- {
+ pid_t pid = atoi(argv[2]);
+ const char* signal_str = argv[3];
+ int signal = atoi(argv[3]);
+ uid_t uid = atoi(argv[4]);
+
+ if (signal != SIGQUIT
+ && signal != SIGILL
+ && signal != SIGABRT
+ && signal != SIGFPE
+ && signal != SIGSEGV
+ ) {
+ /* not an error, exit silently */
return 0;
}
+ if (pid <= 0 || uid < 0)
+ {
+ error_msg_and_die("pid '%s' or uid '%s' are bogus", argv[2], argv[4]);
+ }
if (!daemon_is_ok())
{
+ /* not an error, exit with exitcode 0 */
log("abrt daemon is not running. If it crashed, "
"/proc/sys/kernel/core_pattern contains a stale value, "
"consider resetting it to 'core'"
@@ -159,68 +155,64 @@ int main(int argc, char** argv)
try
{
- FILE* fp;
- CDebugDump dd;
- int byte;
- char path[PATH_MAX];
- char* executable = NULL;
- char* cmdline = NULL;
-
+ char* executable;
+ char* cmdline;
executable = get_executable(pid);
cmdline = get_cmdline(pid);
-
- if (executable == NULL ||
- cmdline == NULL)
+ if (executable == NULL || cmdline == NULL)
+ {
+ error_msg_and_die("can not get proc info for pid %u", (int)pid);
+ }
+ if (strstr(executable, "/abrt"))
{
- free(executable);
- free(cmdline);
- throw CABRTException(EXCEP_FATAL, "Can not get proc info.");
+ /* free(executable); - why bother? */
+ /* free(cmdline); */
+ error_msg_and_die("pid %u is '%s', not dumping it to avoid abrt recursion",
+ (int)pid, executable);
}
- snprintf(path, sizeof(path), "%s/ccpp-%ld-%s", dddir, time(NULL), pid);
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/ccpp-%ld-%u", dddir, (long)time(NULL), (int)pid);
+
+ CDebugDump dd;
dd.Create(path, uid);
dd.SaveText(FILENAME_ANALYZER, "CCpp");
dd.SaveText(FILENAME_EXECUTABLE, executable);
dd.SaveText(FILENAME_CMDLINE, cmdline);
- dd.SaveText(FILENAME_REASON, std::string("Process was terminated by signal ") + signal);
+ dd.SaveText(FILENAME_REASON, std::string("Process was terminated by signal ") + signal_str);
snprintf(path + strlen(path), sizeof(path), "/%s", FILENAME_COREDUMP);
- if ((fp = fopen(path, "w")) == NULL)
+ int fd;
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
{
dd.Delete();
dd.Close();
- throw CABRTException(EXCEP_FATAL, std::string("Can not open the file ") + path);
+ perror_msg_and_die("can't open '%s'", path);
}
- // TODO: rewrite this
- while ((byte = getc(stdin)) != EOF)
+ if (copyfd_eof(STDIN_FILENO, fd) < 0)
{
- if (putc(byte, fp) == EOF)
- {
- fclose(fp);
- dd.Delete();
- dd.Close();
- throw CABRTException(EXCEP_FATAL, "Can not write to the file %s.");
- }
+ /* close(fd); - why bother? */
+ dd.Delete();
+ dd.Close();
+ /* copyfd_eof logs the error including errno string,
+ * but it does not log file name */
+ error_msg_and_die("error saving coredump to %s", path);
}
-
- free(executable);
- free(cmdline);
- fclose(fp);
+ /* close(fd); - why bother? */
+ /* free(executable); */
+ /* free(cmdline); */
dd.Close();
- write_success_log(pid);
+ log("saved core dump of pid %u to %s", (int)pid, path);
}
catch (CABRTException& e)
{
- fprintf(stderr, "%s: %s\n", program_name, e.what().c_str());
- write_faliure_log(e.what().c_str());
- return -2;
+ error_msg_and_die("%s", e.what().c_str());
}
catch (std::exception& e)
{
- fprintf(stderr, "%s: %s\n", program_name, e.what());
- write_faliure_log(e.what());
- return -2;
+ error_msg_and_die("%s", e.what());
}
return 0;
}
diff --git a/src/Hooks/abrt_exception_handler.py.in b/src/Hooks/abrt_exception_handler.py.in
index 148573d..f4ebbb5 100644
--- a/src/Hooks/abrt_exception_handler.py.in
+++ b/src/Hooks/abrt_exception_handler.py.in
@@ -200,7 +200,7 @@ def handleMyException((etype, value, tb)):
progname - the name of the application
version - the version of the application
"""
-
+
# restore original exception handler
sys.excepthook = sys.__excepthook__ # pylint: disable-msg=E1101