summaryrefslogtreecommitdiffstats
path: root/src/Daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/Daemon')
-rw-r--r--src/Daemon/CommLayerServer.h2
-rw-r--r--src/Daemon/CommLayerServerDBus.cpp53
-rw-r--r--src/Daemon/CommLayerServerDBus.h2
-rw-r--r--src/Daemon/CommLayerServerSocket.cpp23
-rw-r--r--src/Daemon/CrashWatcher.cpp66
-rw-r--r--src/Daemon/CrashWatcher.h8
-rw-r--r--src/Daemon/Daemon.cpp351
-rw-r--r--src/Daemon/Daemon.h2
-rw-r--r--src/Daemon/Makefile.am6
-rw-r--r--src/Daemon/MiddleWare.cpp194
-rw-r--r--src/Daemon/MiddleWare.h45
-rw-r--r--src/Daemon/PluginManager.cpp5
-rw-r--r--src/Daemon/Settings.cpp52
-rwxr-xr-xsrc/Daemon/abrt-debuginfo-install144
-rw-r--r--src/Daemon/abrt.conf17
-rw-r--r--src/Daemon/com.redhat.abrt.service3
16 files changed, 553 insertions, 420 deletions
diff --git a/src/Daemon/CommLayerServer.h b/src/Daemon/CommLayerServer.h
index 6ede5815..21c1b304 100644
--- a/src/Daemon/CommLayerServer.h
+++ b/src/Daemon/CommLayerServer.h
@@ -13,7 +13,7 @@ class CCommLayerServer {
virtual ~CCommLayerServer();
/* just stubs to be called when not implemented in specific comm layer */
- virtual void Crash(const std::string& progname, const std::string& uid) {}
+ virtual void Crash(const char *progname, const char *uid_str) {}
virtual void JobDone(const char* pDest, const char* pUUID) = 0;
virtual void QuotaExceed(const char* str) {}
diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp
index cc98fc2c..ed7e3858 100644
--- a/src/Daemon/CommLayerServerDBus.cpp
+++ b/src/Daemon/CommLayerServerDBus.cpp
@@ -28,7 +28,7 @@
static DBusMessage* new_signal_msg(const char* member, const char* peer = NULL)
{
/* path, interface, member name */
- DBusMessage* msg = dbus_message_new_signal(CC_DBUS_PATH, CC_DBUS_IFACE, member);
+ DBusMessage* msg = dbus_message_new_signal(ABRTD_DBUS_PATH, ABRTD_DBUS_IFACE, member);
if (!msg)
die_out_of_memory();
/* Send unicast dbus signal if peer is known */
@@ -46,16 +46,24 @@ static void send_flush_and_unref(DBusMessage* msg)
}
/* Notify the clients (UI) about a new crash */
-void CCommLayerServerDBus::Crash(const std::string& progname, const std::string& uid)
+void CCommLayerServerDBus::Crash(const char *progname, const char *uid_str)
{
DBusMessage* msg = new_signal_msg("Crash");
- const char* c_progname = progname.c_str();
- const char* c_uid = uid.c_str();
- dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &c_progname,
- DBUS_TYPE_STRING, &c_uid,
- DBUS_TYPE_INVALID);
- VERB2 log("Sending signal Crash('%s','%s')", c_progname, c_uid);
+ if (uid_str)
+ {
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &progname,
+ DBUS_TYPE_STRING, &uid_str,
+ DBUS_TYPE_INVALID);
+ VERB2 log("Sending signal Crash('%s','%s')", progname, uid_str);
+ }
+ else
+ {
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &progname,
+ DBUS_TYPE_INVALID);
+ VERB2 log("Sending signal Crash('%s')", progname);
+ }
send_flush_and_unref(msg);
}
@@ -127,7 +135,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));
+ vector_crash_infos_t argout1 = GetCrashInfos(to_string(unix_uid).c_str());
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter);
@@ -246,16 +254,14 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply)
}
}
- const char * sender = dbus_message_get_sender(call);
+ //const char * sender = dbus_message_get_sender(call);
if (!user_conf_data.empty())
{
std::string PluginName;
- map_plugin_settings_t plugin_settings;
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;
- plugin_settings = it_user_conf_data->second;
#if DEBUG
std::cout << "plugin name: " << it_user_conf_data->first;
map_string_t::const_iterator it_plugin_config;
@@ -266,21 +272,21 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply)
std::cout << " key: " << it_plugin_config->first << " value: " << it_plugin_config->second << std::endl;
}
#endif
- g_pPluginManager->SetPluginSettings(PluginName, sender, plugin_settings);
+ // this would overwrite the default settings
+ //g_pPluginManager->SetPluginSettings(PluginName, sender, plugin_settings);
}
}
-//so far, user_conf_data is unused
long unix_uid = get_remote_uid(call);
report_status_t argout1;
try
{
- argout1 = Report(argin1, to_string(unix_uid));
+ argout1 = Report(argin1, user_conf_data, to_string(unix_uid).c_str());
}
catch (CABRTException &e)
{
dbus_message_unref(reply);
- reply = dbus_message_new_error(call, DBUS_ERROR_FAILED, e.what().c_str());
+ reply = dbus_message_new_error(call, DBUS_ERROR_FAILED, e.what());
if (!reply)
die_out_of_memory();
send_flush_and_unref(reply);
@@ -309,7 +315,7 @@ static int handle_DeleteDebugDump(DBusMessage* call, DBusMessage* reply)
}
long unix_uid = get_remote_uid(call);
- bool argout1 = DeleteDebugDump(argin1, to_string(unix_uid));
+ bool argout1 = DeleteDebugDump(argin1, to_string(unix_uid).c_str());
dbus_message_append_args(reply,
DBUS_TYPE_BOOLEAN, &argout1,
@@ -377,7 +383,12 @@ static int handle_SetPluginSettings(DBusMessage* call, DBusMessage* reply)
long unix_uid = get_remote_uid(call);
VERB1 log("got %s('%s',...) call from uid %ld", "SetPluginSettings", PluginName.c_str(), unix_uid);
- g_pPluginManager->SetPluginSettings(PluginName, to_string(unix_uid), plugin_settings);
+ /* Disabled, as we don't use it, we use only temporary user settings while reporting
+ this method should be used to change the default setting and thus should
+ be protected by polkit
+ */
+ //FIXME: protect with polkit
+// g_pPluginManager->SetPluginSettings(PluginName, to_string(unix_uid), plugin_settings);
send_flush_and_unref(reply);
return 0;
@@ -534,7 +545,7 @@ static void handle_dbus_err(bool error_flag, DBusError *err)
error_msg_and_die(
"Error requesting DBus name %s, possible reasons: "
"abrt run by non-root; dbus config is incorrect",
- CC_DBUS_NAME);
+ ABRTD_DBUS_NAME);
}
CCommLayerServerDBus::CCommLayerServerDBus()
@@ -550,7 +561,7 @@ CCommLayerServerDBus::CCommLayerServerDBus()
attach_dbus_conn_to_glib_main_loop(conn, "/com/redhat/abrt", message_received);
VERB3 log("dbus_bus_request_name");
- int rc = dbus_bus_request_name(conn, CC_DBUS_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
+ int rc = dbus_bus_request_name(conn, ABRTD_DBUS_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
//maybe check that r == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER instead?
handle_dbus_err(rc < 0, &err);
VERB3 log("dbus init done");
diff --git a/src/Daemon/CommLayerServerDBus.h b/src/Daemon/CommLayerServerDBus.h
index 7b2e31d7..f159c732 100644
--- a/src/Daemon/CommLayerServerDBus.h
+++ b/src/Daemon/CommLayerServerDBus.h
@@ -11,7 +11,7 @@ class CCommLayerServerDBus
virtual ~CCommLayerServerDBus();
/* DBus signal senders */
- virtual void Crash(const std::string& progname, const std::string& uid);
+ virtual void Crash(const char *progname, const char *uid_str);
virtual void JobDone(const char* pDest, const char* pUUID);
virtual void QuotaExceed(const char* str);
diff --git a/src/Daemon/CommLayerServerSocket.cpp b/src/Daemon/CommLayerServerSocket.cpp
index 6b62928b..ee775c6d 100644
--- a/src/Daemon/CommLayerServerSocket.cpp
+++ b/src/Daemon/CommLayerServerSocket.cpp
@@ -26,7 +26,7 @@ void CCommLayerServerSocket::Send(const std::string& pData, GIOChannel *pDestina
ret = g_io_channel_write_chars(pDestination, message + offset, strlen(message + offset), &len, &err);
if (ret == G_IO_STATUS_ERROR)
{
- warn_client("Error during sending data.");
+ error_msg("Error during sending data");
}
}
@@ -72,7 +72,7 @@ gboolean CCommLayerServerSocket::client_socket_cb(GIOChannel *source, GIOConditi
ret = g_io_channel_read_chars(source, buff, 1, &len, &err);
if (ret == G_IO_STATUS_ERROR)
{
- warn_client(std::string("Error while reading data from client socket: ") + err->message);
+ error_msg("Error while reading data from client socket: %s", err->message);
return FALSE;
}
message += buff[0];
@@ -101,13 +101,13 @@ gboolean CCommLayerServerSocket::server_socket_cb(GIOChannel *source, GIOConditi
condition & G_IO_ERR ||
condition & G_IO_NVAL)
{
- warn_client("Server socket error.");
+ error_msg("Server socket error");
return FALSE;
}
if ((socket = accept(serverSocket->m_nSocket, (struct sockaddr *)&remote, &len)) == -1)
{
- warn_client("Server can not accept client.");
+ error_msg("Server can not accept client");
return TRUE;
}
log("New socket client connected");
@@ -117,7 +117,7 @@ gboolean CCommLayerServerSocket::server_socket_cb(GIOChannel *source, GIOConditi
static_cast<GIOFunc>(client_socket_cb),
data))
{
- warn_client("Can not init g_io_channel.");
+ error_msg("Can not init g_io_channel");
return TRUE;
}
serverSocket->m_mapClientChannels[socket] = gSocket;
@@ -138,7 +138,9 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan
{
std::string message = pMessage.substr(sizeof(MESSAGE_REPORT) - 1);
map_crash_report_t report = string_to_crash_report(message);
- Report(report, UID);
+ map_plugin_settings_t plugin_settings;
+ //FIXME: another hack to make this compile
+// Report(report, plugin_settings, UID);
}
else if (!strncmp(pMessage.c_str(), MESSAGE_CREATE_REPORT, sizeof(MESSAGE_CREATE_REPORT) - 1))
{
@@ -155,7 +157,7 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan
}
else
{
- warn_client("Received unknown message type.");
+ error_msg("Received unknown message type");
}
}
@@ -227,7 +229,12 @@ vector_crash_infos_t CCommLayerServerSocket::GetCrashInfos(const std::string &pS
report_status_t CCommLayerServerSocket::Report(const map_crash_report_t& pReport, const std::string& pSender)
{
report_status_t rs;
- rs = ::Report(pReport, pSender);
+ //FIXME: a hack to make this compile, but we don't use sockets anyway
+ /* we could probably remove the sockets and rely only on dbus,
+ as it will become mandatory even on servers, but this needs some investigation
+ and more opinions
+ */
+ //rs = ::Report(pReport, pSettings, pSender);
return rs;
}
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
index 94fb9d79..e684277c 100644
--- a/src/Daemon/CrashWatcher.cpp
+++ b/src/Daemon/CrashWatcher.cpp
@@ -22,16 +22,16 @@
#include "ABRTException.h"
#include "CrashWatcher.h"
-void CCrashWatcher::Status(const std::string& pMessage, const char* peer, uint64_t pJobID)
+void CCrashWatcher::Status(const char *pMessage, const char* peer, uint64_t pJobID)
{
- VERB1 log("Update('%s'): %s", peer, pMessage.c_str());
+ VERB1 log("Update('%s'): %s", peer, pMessage);
if (g_pCommLayer != NULL)
g_pCommLayer->Update(pMessage, peer, pJobID);
}
-void CCrashWatcher::Warning(const std::string& pMessage, const char* peer, uint64_t pJobID)
+void CCrashWatcher::Warning(const char *pMessage, const char* peer, uint64_t pJobID)
{
- VERB1 log("Warning('%s'): %s", peer, pMessage.c_str());
+ VERB1 log("Warning('%s'): %s", peer, pMessage);
if (g_pCommLayer != NULL)
g_pCommLayer->Warning(pMessage, peer, pJobID);
}
@@ -44,7 +44,7 @@ CCrashWatcher::~CCrashWatcher()
{
}
-vector_crash_infos_t GetCrashInfos(const std::string &pUID)
+vector_crash_infos_t GetCrashInfos(const char *pUID)
{
vector_crash_infos_t retval;
log("Getting crash infos...");
@@ -58,25 +58,24 @@ vector_crash_infos_t GetCrashInfos(const std::string &pUID)
{
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 = GetCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second, info);
+ res = GetCrashInfo(uuid, uid, info);
switch (res)
{
case MW_OK:
retval.push_back(info);
break;
case MW_ERROR:
- warn_client("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- update_client("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
+ error_msg("Can't find dump directory for UUID %s, deleting from database", uuid);
+ DeleteCrashInfo(uuid, uid);
break;
case MW_FILE_ERROR:
+ error_msg("Can't open file in dump directory for UUID %s, deleting", uuid);
{
- std::string debugDumpDir;
- warn_client("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting");
- update_client("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting");
- debugDumpDir = DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
- DeleteDebugDumpDir(debugDumpDir);
+ std::string debugDumpDir = DeleteCrashInfo(uuid, uid);
+ DeleteDebugDumpDir(debugDumpDir.c_str());
}
break;
default:
@@ -90,8 +89,7 @@ vector_crash_infos_t GetCrashInfos(const std::string &pUID)
{
throw e;
}
- warn_client(e.what());
- update_client(e.what());
+ error_msg("%s", e.what());
}
//retval = GetCrashInfos(pUID);
@@ -124,17 +122,17 @@ map_crash_report_t GetJobResult(const char* pUUID, const char* pUID, int force)
case MW_OK:
break;
case MW_IN_DB_ERROR:
- warn_client(std::string("Did not find crash with UUID ") + pUUID + " in database");
+ error_msg("Can't find crash with UUID %s in database", pUUID);
break;
case MW_PLUGIN_ERROR:
- warn_client("Particular analyzer plugin isn't loaded or there is an error within plugin(s)");
+ error_msg("Particular analyzer plugin isn't loaded or there is an error within plugin(s)");
break;
case MW_CORRUPTED:
case MW_FILE_ERROR:
default:
- warn_client(std::string("Corrupted crash with UUID ") + pUUID + ", deleting");
+ error_msg("Corrupted crash with UUID %s, deleting", pUUID);
std::string debugDumpDir = DeleteCrashInfo(pUUID, pUID);
- DeleteDebugDumpDir(debugDumpDir);
+ DeleteDebugDumpDir(debugDumpDir.c_str());
break;
}
return crashReport;
@@ -163,18 +161,9 @@ static void* create_report(void* arg)
}
catch (CABRTException& e)
{
- if (e.type() == EXCEP_FATAL)
- {
- set_client_name(NULL);
- /* free strduped strings */
- free(thread_data->UUID);
- free(thread_data->UID);
- free(thread_data->peer);
- free(thread_data);
- throw e;
- }
- warn_client(e.what());
+ error_msg("%s", e.what());
}
+ catch (...) {}
set_client_name(NULL);
/* free strduped strings */
@@ -193,10 +182,12 @@ int CreateReportThread(const char* pUUID, const char* pUID, int force, const cha
thread_data->UID = xstrdup(pUID);
thread_data->force = force;
thread_data->peer = xstrdup(pSender);
+
//TODO: do we need this?
//pthread_attr_t attr;
//pthread_attr_init(&attr);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
int r = pthread_create(&thread_data->thread_id, NULL, create_report, thread_data);
if (r != 0)
{
@@ -208,21 +199,19 @@ int CreateReportThread(const char* pUUID, const char* pUID, int force, const cha
* or ulimit is exceeded (someone floods us with CreateReport() dbus calls?)
*/
error_msg("Can't create thread");
+ return r;
}
- else
- {
- VERB3 log("Thread %llx created", (unsigned long long)thread_data->thread_id);
- }
+ VERB3 log("Thread %llx created", (unsigned long long)thread_data->thread_id);
//pthread_attr_destroy(&attr);
return r;
}
-bool DeleteDebugDump(const std::string& pUUID, const std::string& pUID)
+bool DeleteDebugDump(const char *pUUID, const char *pUID)
{
try
{
std::string debugDumpDir = DeleteCrashInfo(pUUID, pUID);
- DeleteDebugDumpDir(debugDumpDir);
+ DeleteDebugDumpDir(debugDumpDir.c_str());
}
catch (CABRTException& e)
{
@@ -230,8 +219,7 @@ bool DeleteDebugDump(const std::string& pUUID, const std::string& pUID)
{
throw e;
}
- warn_client(e.what());
- update_client(e.what());
+ error_msg("%s", e.what());
return false;
}
return true;
diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h
index d8c7c28a..995d2a12 100644
--- a/src/Daemon/CrashWatcher.h
+++ b/src/Daemon/CrashWatcher.h
@@ -44,13 +44,13 @@ class CCrashWatcher
public:
/* Observer methods */
- virtual void Status(const std::string& pMessage, const char* peer, uint64_t pJobID);
- virtual void Warning(const std::string& pMessage, const char* peer, uint64_t pJobID);
+ virtual void Status(const char *pMessage, const char* peer, uint64_t pJobID);
+ virtual void Warning(const char *pMessage, const char* peer, uint64_t pJobID);
};
-vector_crash_infos_t GetCrashInfos(const std::string &pUID);
+vector_crash_infos_t GetCrashInfos(const char *pUID);
int CreateReportThread(const char* pUUID, const char* pUID, int force, const char* pSender);
map_crash_report_t GetJobResult(const char* pUUID, const char* pUID, int force);
-bool DeleteDebugDump(const std::string& pUUID, const std::string& pUID);
+bool DeleteDebugDump(const char *pUUID, const char *pUID);
#endif /*CRASHWATCHER_H_*/
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index d1ab188e..67e72cca 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -18,10 +18,14 @@
*/
#include <syslog.h>
-#include <sys/inotify.h>
-#include <glib.h>
#include <pthread.h>
+#include <resolv.h> /* res_init */
#include <string>
+#include <limits.h>
+#include <sys/inotify.h>
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/client.h>
+#include <glib.h>
#if HAVE_CONFIG_H
#include <config.h>
#endif
@@ -105,24 +109,14 @@ typedef struct cron_callback_data_t
} cron_callback_data_t;
-static uint8_t s_sig_caught;
-static GMainLoop* g_pMainloop;
+static uint8_t s_sig_caught; /* must be one byte */
+static int s_signal_pipe[2];
+static int s_signal_pipe_write = -1;
+static unsigned s_timeout;
+static bool s_exiting;
CCommLayerServer* g_pCommLayer;
-pthread_mutex_t g_pJobsMutex;
-
-
-/* Is it "." or ".."? */
-/* abrtlib candidate */
-static bool dot_or_dotdot(const char *filename)
-{
- if (filename[0] != '.') return false;
- if (filename[1] == '\0') return true;
- if (filename[1] != '.') return false;
- if (filename[2] == '\0') return true;
- return false;
-}
static double GetDirSize(const std::string &pPath, std::string *worst_dir = NULL, const char *excluded = NULL)
{
@@ -171,6 +165,18 @@ static double GetDirSize(const std::string &pPath, std::string *worst_dir = NULL
return size;
}
+static bool analyzer_has_InformAllUsers(const char *analyzer_name)
+{
+ CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(analyzer_name);
+ if (!analyzer)
+ return false;
+ map_plugin_settings_t settings = analyzer->GetSettings();
+ map_plugin_settings_t::const_iterator it = settings.find("InformAllUsers");
+ if (it == settings.end())
+ return false;
+ return string_to_bool(it->second.c_str());
+}
+
static void cron_delete_callback_data_cb(gpointer data)
{
cron_callback_data_t* cronDeleteCallbackData = static_cast<cron_callback_data_t*>(data);
@@ -182,8 +188,9 @@ static gboolean cron_activation_periodic_cb(gpointer data)
cron_callback_data_t* cronPeriodicCallbackData = static_cast<cron_callback_data_t*>(data);
VERB1 log("Activating plugin: %s", cronPeriodicCallbackData->m_sPluginName.c_str());
RunAction(DEBUG_DUMPS_DIR,
- cronPeriodicCallbackData->m_sPluginName,
- cronPeriodicCallbackData->m_sPluginArgs);
+ cronPeriodicCallbackData->m_sPluginName.c_str(),
+ cronPeriodicCallbackData->m_sPluginArgs.c_str()
+ );
return TRUE;
}
static gboolean cron_activation_one_cb(gpointer data)
@@ -191,8 +198,9 @@ static gboolean cron_activation_one_cb(gpointer data)
cron_callback_data_t* cronOneCallbackData = static_cast<cron_callback_data_t*>(data);
VERB1 log("Activating plugin: %s", cronOneCallbackData->m_sPluginName.c_str());
RunAction(DEBUG_DUMPS_DIR,
- cronOneCallbackData->m_sPluginName,
- cronOneCallbackData->m_sPluginArgs);
+ cronOneCallbackData->m_sPluginName.c_str(),
+ cronOneCallbackData->m_sPluginArgs.c_str()
+ );
return FALSE;
}
static gboolean cron_activation_reshedule_cb(gpointer data)
@@ -206,7 +214,8 @@ static gboolean cron_activation_reshedule_cb(gpointer data)
cronPeriodicCallbackData->m_nTimeout,
cron_activation_periodic_cb,
static_cast<gpointer>(cronPeriodicCallbackData),
- cron_delete_callback_data_cb);
+ cron_delete_callback_data_cb
+ );
return FALSE;
}
@@ -232,7 +241,7 @@ static void SetUpMW()
vector_pair_string_string_t::iterator it_ar = g_settings_vectorActionsAndReporters.begin();
for (; it_ar != g_settings_vectorActionsAndReporters.end(); it_ar++)
{
- AddActionOrReporter(it_ar->first, it_ar->second);
+ AddActionOrReporter(it_ar->first.c_str(), it_ar->second.c_str());
}
VERB1 log("Adding analyzers, actions or reporters");
map_analyzer_actions_and_reporters_t::iterator it_aar = g_settings_mapAnalyzerActionsAndReporters.begin();
@@ -241,7 +250,7 @@ static void SetUpMW()
vector_pair_string_string_t::iterator it_ar = it_aar->second.begin();
for (; it_ar != it_aar->second.end(); it_ar++)
{
- AddAnalyzerActionOrReporter(it_aar->first, it_ar->first, it_ar->second);
+ AddAnalyzerActionOrReporter(it_aar->first.c_str(), it_ar->first.c_str(), it_ar->second.c_str());
}
}
}
@@ -322,13 +331,13 @@ static int SetUpCron()
vector_pair_string_string_t::iterator it_ar = it_c->second.begin();
for (; it_ar != it_c->second.end(); it_ar++)
{
- cron_callback_data_t* cronOneCallbackData = new cron_callback_data_t((*it_ar).first, (*it_ar).second, timeout);
+ cron_callback_data_t* cronOneCallbackData = new cron_callback_data_t(it_ar->first, it_ar->second, timeout);
g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
timeout,
cron_activation_one_cb,
static_cast<gpointer>(cronOneCallbackData),
cron_delete_callback_data_cb);
- cron_callback_data_t* cronResheduleCallbackData = new cron_callback_data_t((*it_ar).first, (*it_ar).second, 24 * 60 * 60);
+ cron_callback_data_t* cronResheduleCallbackData = new cron_callback_data_t(it_ar->first, it_ar->second, 24 * 60 * 60);
g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
timeout,
cron_activation_reshedule_cb,
@@ -375,13 +384,12 @@ static void FindNewDumps(const char* pPath)
map_crash_info_t crashinfo;
try
{
- mw_result_t res;
- res = SaveDebugDump(*itt, crashinfo);
+ mw_result_t res = SaveDebugDump(itt->c_str(), crashinfo);
switch (res)
{
case MW_OK:
VERB1 log("Saving into database (%s)", itt->c_str());
- RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
+ RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str());
break;
case MW_IN_DB:
VERB1 log("Already saved in database (%s)", itt->c_str());
@@ -397,7 +405,7 @@ static void FindNewDumps(const char* pPath)
//Perhaps corrupted & bad needs to be logged unconditionally,
//already saved one - only on VERB1
VERB1 log("Corrupted, bad or already saved crash, deleting");
- DeleteDebugDumpDir(*itt);
+ DeleteDebugDumpDir(itt->c_str());
break;
}
}
@@ -407,7 +415,7 @@ static void FindNewDumps(const char* pPath)
{
throw e;
}
- error_msg("%s", e.what().c_str());
+ error_msg("%s", e.what());
}
}
}
@@ -453,63 +461,44 @@ static int Lock()
/* we leak opened lfd intentionally */
}
-static void handle_fatal_signal(int signal)
+static void handle_fatal_signal(int signo)
{
- s_sig_caught = signal;
+ s_sig_caught = signo;
+ VERB3 log("Got signal %d", signo);
+ if (s_signal_pipe_write >= 0)
+ write(s_signal_pipe_write, &s_sig_caught, 1);
}
-/* One of our event sources is s_sig_caught when it becomes != 0.
- * glib machinery we need to hook it up to the main loop:
- * prepare():
- * If the source can determine that it is ready here (without waiting
- * for the results of the poll() call) it should return TRUE. It can also
- * return a timeout_ value which should be the maximum timeout (in milliseconds)
- * which should be passed to the poll() call.
- * check():
- * Called after all the file descriptors are polled. The source should
- * return TRUE if it is ready to be dispatched.
- * dispatch():
- * Called to dispatch the event source, after it has returned TRUE
- * in either its prepare or its check function. The dispatch function
- * is passed in a callback function and data. The callback function
- * may be NULL if the source was never connected to a callback using
- * g_source_set_callback(). The dispatch function should
- * call the callback function with user_data and whatever additional
- * parameters are needed for this type of event source.
- */
-static gboolean waitsignal_prepare(GSource *source, gint *timeout_)
+/* Signal pipe handler */
+static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
{
- /* We depend on the fact that in Unix, poll() is interrupted
- * by caught signals (in returns EINTR). Thus we do not need to set
- * a small timeout here: infinite timeout (-1) works too */
- *timeout_ = -1;
- return s_sig_caught != 0;
-}
-static gboolean waitsignal_check(GSource *source)
-{
- return s_sig_caught != 0;
-}
-static gboolean waitsignal_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
-{
- g_main_quit(g_pMainloop);
- return 1;
+ char signo;
+ gsize len = 0;
+ g_io_channel_read(gio, &signo, 1, &len);
+ if (len == 1)
+ {
+ /* we did receive a signal */
+ VERB3 log("Got signal %d through signal pipe", signo);
+ s_exiting = 1;
+ return TRUE;
+ }
+ return FALSE;
}
/* Inotify handler */
-static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
+static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
{
/* 128 simultaneous actions */
#define INOTIFY_BUFF_SIZE ((sizeof(struct inotify_event) + FILENAME_MAX)*128)
- GIOError err;
- char *buf = new char[INOTIFY_BUFF_SIZE];
+ char *buf = (char*)xmalloc(INOTIFY_BUFF_SIZE);
gsize len;
gsize i = 0;
errno = 0;
- err = g_io_channel_read(gio, buf, INOTIFY_BUFF_SIZE, &len);
+ GIOError err = g_io_channel_read(gio, buf, INOTIFY_BUFF_SIZE, &len);
if (err != G_IO_ERROR_NONE)
{
perror_msg("Error reading inotify fd");
- delete[] buf;
+ free(buf);
return FALSE;
}
/* reconstruct each event and send message to the dbus */
@@ -540,29 +529,34 @@ static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointe
) {
log("Size of '%s' >= %u MB, deleting '%s'", DEBUG_DUMPS_DIR, g_settings_nMaxCrashReportsSize, worst_dir.c_str());
g_pCommLayer->QuotaExceed(_("Report size exceeded the quota. Please check system's MaxCrashReportsSize value in abrt.conf."));
- DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + worst_dir);
+ DeleteDebugDumpDir(concat_path_file(DEBUG_DUMPS_DIR, worst_dir.c_str()).c_str());
worst_dir = "";
}
map_crash_info_t crashinfo;
try
{
- mw_result_t res;
- res = SaveDebugDump(std::string(DEBUG_DUMPS_DIR) + "/" + name, crashinfo);
+ std::string fullname = concat_path_file(DEBUG_DUMPS_DIR, name);
+
+ mw_result_t res = SaveDebugDump(fullname.c_str(), crashinfo);
switch (res)
{
case MW_OK:
- log("New crash, saving...");
- RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
- /* Send dbus signal */
- g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT], crashinfo[CD_UID][CD_CONTENT]);
- break;
+ log("New crash, saving");
+ RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str());
+ /* Fall through to "send dbus signal" */
case MW_REPORTED:
case MW_OCCURED:
- log("Already saved crash, deleting...");
+ if (res != MW_OK)
+ log("Already saved crash, just sending dbus signal");
/* Send dbus signal */
- g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT], crashinfo[CD_UID][CD_CONTENT]);
- DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
+ {
+ const char *uid_str = analyzer_has_InformAllUsers(crashinfo[CD_MWANALYZER][CD_CONTENT].c_str())
+ ? NULL
+ : crashinfo[CD_UID][CD_CONTENT].c_str();
+ g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT].c_str(), uid_str);
+ }
+ //DeleteDebugDumpDir(fullname.c_str());
break;
case MW_BLACKLISTED:
case MW_CORRUPTED:
@@ -571,31 +565,96 @@ static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointe
case MW_IN_DB:
case MW_FILE_ERROR:
default:
- log("Corrupted or bad crash, deleting...");
- DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
+ log("Corrupted or bad crash, deleting");
+ DeleteDebugDumpDir(fullname.c_str());
break;
}
}
catch (CABRTException& e)
{
- warn_client(e.what());
+ error_msg(e.what());
if (e.type() == EXCEP_FATAL)
{
- delete[] buf;
+ free(buf);
return -1;
}
}
catch (...)
{
- delete[] buf;
+ free(buf);
throw;
}
} /* while */
- delete[] buf;
+ free(buf);
return TRUE;
}
+/* Run main loop with idle timeout.
+ * Basically, almost like glib's g_main_run(loop)
+ */
+static void run_main_loop(GMainLoop* loop)
+{
+ GMainContext *context = g_main_loop_get_context(loop);
+ time_t old_time = 0;
+ time_t dns_conf_hash = 0;
+
+ while (!s_exiting)
+ {
+ /* we have just a handful of sources, 32 should be ample */
+ const unsigned NUM_POLLFDS = 32;
+ GPollFD fds[NUM_POLLFDS];
+ gboolean some_ready;
+ gint max_priority;
+ gint timeout;
+
+ some_ready = g_main_context_prepare(context, &max_priority);
+ if (some_ready)
+ g_main_context_dispatch(context);
+
+ gint nfds = g_main_context_query(context, max_priority, &timeout, fds, NUM_POLLFDS);
+ if (nfds > NUM_POLLFDS)
+ error_msg_and_die("Internal error");
+
+ if (s_timeout)
+ alarm(s_timeout);
+ g_poll(fds, nfds, timeout);
+ if (s_timeout)
+ alarm(0);
+
+ /* res_init() makes glibc reread /etc/resolv.conf.
+ * I'd think libc should be clever enough to do it itself
+ * at every name resolution attempt, but no...
+ * We need to guess ourself whether we want to do it.
+ */
+ time_t now = time(NULL) >> 2;
+ if (old_time != now) /* check once in 4 seconds */
+ {
+ old_time = now;
+
+ time_t hash = 0;
+ struct stat sb;
+ if (stat("/etc/resolv.conf", &sb) == 0)
+ hash = sb.st_mtime;
+ if (stat("/etc/host.conf", &sb) == 0)
+ hash += sb.st_mtime;
+ if (stat("/etc/hosts", &sb) == 0)
+ hash += sb.st_mtime;
+ if (stat("/etc/nsswitch.conf", &sb) == 0)
+ hash += sb.st_mtime;
+ if (dns_conf_hash != hash)
+ {
+ dns_conf_hash = hash;
+ res_init();
+ }
+ }
+
+ some_ready = g_main_context_check(context, max_priority, fds, nfds);
+ if (some_ready)
+ g_main_context_dispatch(context);
+ }
+}
+
static void start_syslog_logging()
{
/* Open stdin to /dev/null */
@@ -611,23 +670,29 @@ static void start_syslog_logging()
logmode = LOGMODE_SYSLOG;
}
-static void sanitize_dump_dir_rights()
+static void ensure_root_writable_dir(const char *dir)
{
struct stat sb;
- if (mkdir(DEBUG_DUMPS_DIR, 0755) != 0 && errno != EEXIST)
- perror_msg_and_die("Can't create '%s'", DEBUG_DUMPS_DIR);
- if (stat(DEBUG_DUMPS_DIR, &sb) != 0 || !S_ISDIR(sb.st_mode))
- error_msg_and_die("'%s' is not a directory", DEBUG_DUMPS_DIR);
-
- if (sb.st_uid != 0 || sb.st_gid != 0 || chown(DEBUG_DUMPS_DIR, 0, 0) != 0)
- perror_msg_and_die("Can't set owner 0:0 on '%s'", DEBUG_DUMPS_DIR);
+ if (mkdir(dir, 0755) != 0 && errno != EEXIST)
+ perror_msg_and_die("Can't create '%s'", dir);
+ if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
+ error_msg_and_die("'%s' is not a directory", dir);
+ if ((sb.st_uid != 0 || sb.st_gid != 0) && chown(dir, 0, 0) != 0)
+ perror_msg_and_die("Can't set owner 0:0 on '%s'", dir);
/* We can't allow anyone to create dumps: otherwise users can flood
* us with thousands of bogus or malicious dumps */
/* 07000 bits are setuid, setgit, and sticky, and they must be unset */
- /* 00777 bits are usual "rwx" access rights */
- if ((sb.st_mode & 07777) != 0755 && chmod(DEBUG_DUMPS_DIR, 0755) != 0)
- perror_msg_and_die("Can't set mode rwxr-xr-x on '%s'", DEBUG_DUMPS_DIR);
+ /* 00777 bits are usual "rwxrwxrwx" access rights */
+ if ((sb.st_mode & 07777) != 0755 && chmod(dir, 0755) != 0)
+ perror_msg_and_die("Can't set mode rwxr-xr-x on '%s'", dir);
+}
+
+static void sanitize_dump_dir_rights()
+{
+ ensure_root_writable_dir(DEBUG_DUMPS_DIR);
+ ensure_root_writable_dir(DEBUG_DUMPS_DIR"-di"); /* debuginfo cache */
+ ensure_root_writable_dir(VAR_RUN"/abrt"); /* temp dir */
}
int main(int argc, char** argv)
@@ -643,8 +708,10 @@ int main(int argc, char** argv)
textdomain(PACKAGE);
#endif
- while ((opt = getopt(argc, argv, "dsv")) != -1)
+ while ((opt = getopt(argc, argv, "dsvt:")) != -1)
{
+ unsigned long ul;
+
switch (opt)
{
case 'd':
@@ -656,20 +723,32 @@ int main(int argc, char** argv)
case 'v':
g_verbose++;
break;
+ case 't':
+ char *end;
+ errno = 0;
+ s_timeout = ul = strtoul(optarg, &end, 0);
+ if (errno == 0 && *end == '\0' && ul <= INT_MAX)
+ break;
+ /* fall through to error */
default:
error_msg_and_die(
"Usage: abrtd [-dv]\n"
- "\nOptions:"
+ "\nOptions:"
"\n\t-d\tDo not daemonize"
"\n\t-s\tLog to syslog even with -d"
+ "\n\t-t SEC\tExit after SEC seconds of inactivity"
"\n\t-v\tVerbose"
);
}
}
msg_prefix = "abrtd: "; /* for log(), error_msg() and such */
+
+ xpipe(s_signal_pipe);
signal(SIGTERM, handle_fatal_signal);
- signal(SIGINT, handle_fatal_signal);
+ signal(SIGINT, handle_fatal_signal);
+ if (s_timeout)
+ signal(SIGALRM, handle_fatal_signal);
/* Daemonize unless -d */
if (daemonize)
@@ -705,7 +784,9 @@ int main(int argc, char** argv)
start_syslog_logging();
}
- GIOChannel* pGio = NULL;
+ GMainLoop* pMainloop = NULL;
+ GIOChannel* pGiochannel_inotify = NULL;
+ GIOChannel* pGiochannel_signal = NULL;
bool lockfile_created = false;
bool pidfile_created = false;
CCrashWatcher watcher;
@@ -713,17 +794,24 @@ int main(int argc, char** argv)
/* Initialization */
try
{
- pthread_mutex_init(&g_pJobsMutex, NULL); /* never fails */
init_daemon_logging(&watcher);
+
+ VERB1 log("Initializing XML-RPC library");
+ xmlrpc_env env;
+ xmlrpc_env_init(&env);
+ xmlrpc_client_setup_global_const(&env);
+ if (env.fault_occurred)
+ error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code);
VERB1 log("Creating glib main loop");
- g_pMainloop = g_main_loop_new(NULL, FALSE);
+ pMainloop = g_main_loop_new(NULL, FALSE);
/* Watching DEBUG_DUMPS_DIR for new files... */
VERB1 log("Initializing inotify");
- /*FIXME: python hook runs with ordinary user privileges,
- so it fails if everyone doesn't have write acces
- to DEBUG_DUMPS_DIR
- */
- //sanitize_dump_dir_rights();
+// Enabled again since we have new abrt-pyhook-helper, remove comment when verified to work
+ /* FIXME: python hook runs with ordinary user privileges,
+ * so it fails if everyone doesn't have write acces
+ * to DEBUG_DUMPS_DIR
+ */
+ sanitize_dump_dir_rights();
errno = 0;
int inotify_fd = inotify_init();
if (inotify_fd == -1)
@@ -738,7 +826,7 @@ int main(int argc, char** argv)
SetUpMW(); /* logging is inside */
if (SetUpCron() != 0)
throw 1;
-#ifdef ENABLE_DBUS
+#if 1 //def ENABLE_DBUS
VERB1 log("Initializing dbus");
g_pCommLayer = new CCommLayerServerDBus();
#elif ENABLE_SOCKET
@@ -747,18 +835,12 @@ int main(int argc, char** argv)
if (g_pCommLayer->m_init_error)
throw 1;
VERB1 log("Adding inotify watch to glib main loop");
- pGio = g_io_channel_unix_new(inotify_fd);
- g_io_add_watch(pGio, G_IO_IN, handle_event_cb, NULL);
+ pGiochannel_inotify = g_io_channel_unix_new(inotify_fd);
+ g_io_add_watch(pGiochannel_inotify, G_IO_IN, handle_inotify_cb, NULL);
/* Add an event source which waits for INT/TERM signal */
- VERB1 log("Adding signal watch to glib main loop");
- GSourceFuncs waitsignal_funcs;
- memset(&waitsignal_funcs, 0, sizeof(waitsignal_funcs));
- waitsignal_funcs.prepare = waitsignal_prepare;
- waitsignal_funcs.check = waitsignal_check;
- waitsignal_funcs.dispatch = waitsignal_dispatch;
- /*waitsignal_funcs.finalize = NULL; - already done */
- GSource *waitsignal_src = (GSource*) g_source_new(&waitsignal_funcs, sizeof(*waitsignal_src));
- g_source_attach(waitsignal_src, g_main_context_default());
+ VERB1 log("Adding signal pipe watch to glib main loop");
+ pGiochannel_signal = g_io_channel_unix_new(s_signal_pipe[0]);
+ g_io_add_watch(pGiochannel_signal, G_IO_IN, handle_signal_cb, NULL);
/* Mark the territory */
VERB1 log("Creating lock file");
if (Lock() != 0)
@@ -788,17 +870,20 @@ int main(int argc, char** argv)
start_syslog_logging();
}
+ /* Only now we want signal pipe to work */
+ s_signal_pipe_write = s_signal_pipe[1];
+
/* Enter the event loop */
try
{
/* This may take a while, therefore we don't do it in init section */
FindNewDumps(DEBUG_DUMPS_DIR);
log("Running...");
- g_main_run(g_pMainloop);
+ run_main_loop(pMainloop);
}
catch (CABRTException& e)
{
- error_msg("Error: %s", e.what().c_str());
+ error_msg("Error: %s", e.what());
}
catch (std::exception& e)
{
@@ -813,8 +898,12 @@ int main(int argc, char** argv)
unlink(VAR_RUN_PIDFILE);
if (lockfile_created)
unlink(VAR_RUN_LOCK_FILE);
- if (pGio)
- g_io_channel_unref(pGio);
+
+ if (pGiochannel_signal)
+ g_io_channel_unref(pGiochannel_signal);
+ if (pGiochannel_inotify)
+ g_io_channel_unref(pGiochannel_inotify);
+
delete g_pCommLayer;
if (g_pPluginManager)
{
@@ -822,13 +911,11 @@ int main(int argc, char** argv)
g_pPluginManager->UnLoadPlugins();
delete g_pPluginManager;
}
- if (g_pMainloop)
- g_main_loop_unref(g_pMainloop);
- if (pthread_mutex_destroy(&g_pJobsMutex) != 0)
- error_msg("Threading error: job mutex locked");
+ if (pMainloop)
+ g_main_loop_unref(pMainloop);
/* Exiting */
- if (s_sig_caught)
+ if (s_sig_caught && s_sig_caught != SIGALRM)
{
error_msg_and_die("Got signal %d, exiting", s_sig_caught);
signal(s_sig_caught, SIG_DFL);
diff --git a/src/Daemon/Daemon.h b/src/Daemon/Daemon.h
index c9a653ac..ac998b93 100644
--- a/src/Daemon/Daemon.h
+++ b/src/Daemon/Daemon.h
@@ -39,6 +39,4 @@ extern CPluginManager* g_pPluginManager;
*/
extern set_string_t g_setBlackList;
-extern pthread_mutex_t g_pJobsMutex;
-
#endif
diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am
index 0067e5dd..a5bb64f6 100644
--- a/src/Daemon/Makefile.am
+++ b/src/Daemon/Makefile.am
@@ -2,6 +2,7 @@ bin_SCRIPTS = abrt-debuginfo-install
sbin_PROGRAMS = abrtd
+# disabled: CommLayerServerSocket.h CommLayerServerSocket.cpp
abrtd_SOURCES = \
ABRTPlugin.h ABRTPlugin.cpp \
PluginManager.h PluginManager.cpp \
@@ -9,7 +10,6 @@ abrtd_SOURCES = \
MiddleWare.h MiddleWare.cpp \
CrashWatcher.h CrashWatcher.cpp \
CommLayerServer.h CommLayerServer.cpp \
- CommLayerServerSocket.h CommLayerServerSocket.cpp \
CommLayerServerDBus.h CommLayerServerDBus.cpp \
Daemon.h Daemon.cpp \
Settings.h Settings.cpp
@@ -24,13 +24,15 @@ abrtd_CPPFLAGS = \
-DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
+ $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \
$(ENABLE_SOCKET_OR_DBUS) \
-D_GNU_SOURCE
abrtd_LDADD = \
../../lib/Utils/libABRTUtils.la \
$(DL_LIBS) \
$(DBUS_LIBS) \
- $(RPM_LIBS)
+ $(RPM_LIBS) \
+ $(XMLRPC_LIBS) $(XMLRPC_CLIENT_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
index 2ccd5890..6a635642 100644
--- a/src/Daemon/MiddleWare.cpp
+++ b/src/Daemon/MiddleWare.cpp
@@ -20,6 +20,7 @@
*/
#include "abrtlib.h"
+#include "abrt_types.h"
#include "Daemon.h"
#include "Settings.h"
#include "RPM.h"
@@ -60,7 +61,7 @@ static map_analyzer_actions_and_reporters_t s_mapAnalyzerActionsAndReporters;
static vector_pair_string_string_t s_vectorActionsAndReporters;
-static void RunAnalyzerActions(const std::string& pAnalyzer, const std::string& pDebugDumpDir);
+static void RunAnalyzerActions(const char *pAnalyzer, const char *pDebugDumpDir);
/**
@@ -69,7 +70,7 @@ static void RunAnalyzerActions(const std::string& pAnalyzer, const std::string&
* @param pDebugDumpDir A debugdump dir containing all necessary data.
* @param pCrashReport A created crash report.
*/
-static void DebugDumpToCrashReport(const std::string& pDebugDumpDir, map_crash_report_t& pCrashReport)
+static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_report_t& pCrashReport)
{
std::string fileName;
std::string content;
@@ -84,19 +85,22 @@ static void DebugDumpToCrashReport(const std::string& pDebugDumpDir, map_crash_r
!dd.Exist(FILENAME_RELEASE) ||
!dd.Exist(FILENAME_EXECUTABLE))
{
- throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): One or more of important file(s)'re missing.");
+ throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): One or more of important file(s)'re missing");
}
+
pCrashReport.clear();
dd.InitGetNextFile();
while (dd.GetNextFile(fileName, content, isTextFile))
{
+ //VERB3 log(" file:'%s' text:%d", fileName.c_str(), isTextFile);
if (!isTextFile)
{
add_crash_data_to_crash_report(pCrashReport,
fileName,
CD_BIN,
CD_ISNOTEDITABLE,
- pDebugDumpDir + "/" + fileName);
+ concat_path_file(pDebugDumpDir, fileName.c_str())
+ );
}
else
{
@@ -135,8 +139,8 @@ static void DebugDumpToCrashReport(const std::string& pDebugDumpDir, map_crash_r
* @param pDebugDumpDir A debugdump dir containing all necessary data.
* @return A local UUID.
*/
-static std::string GetLocalUUID(const std::string& pAnalyzer,
- const std::string& pDebugDumpDir)
+static std::string GetLocalUUID(const char *pAnalyzer,
+ const char *pDebugDumpDir)
{
CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(pAnalyzer);
return analyzer->GetLocalUUID(pDebugDumpDir);
@@ -148,8 +152,8 @@ static std::string GetLocalUUID(const std::string& pAnalyzer,
* @param pDebugDumpDir A debugdump dir containing all necessary data.
* @return A global UUID.
*/
-static std::string GetGlobalUUID(const std::string& pAnalyzer,
- const std::string& pDebugDumpDir)
+static std::string GetGlobalUUID(const char *pAnalyzer,
+ const char *pDebugDumpDir)
{
CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(pAnalyzer);
return analyzer->GetGlobalUUID(pDebugDumpDir);
@@ -162,32 +166,32 @@ static std::string GetGlobalUUID(const std::string& pAnalyzer,
* @param pAnalyzer A name of an analyzer plugin.
* @param pDebugDumpPath A debugdump dir containing all necessary data.
*/
-static void CreateReport(const std::string& pAnalyzer,
- const std::string& pDebugDumpDir,
+static void CreateReport(const char *pAnalyzer,
+ const char *pDebugDumpDir,
int force)
{
CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(pAnalyzer);
analyzer->CreateReport(pDebugDumpDir, force);
}
-mw_result_t CreateCrashReport(const std::string& pUUID,
- const std::string& pUID,
+mw_result_t CreateCrashReport(const char *pUUID,
+ const char *pUID,
int force,
map_crash_report_t& pCrashReport)
{
- VERB2 log("CreateCrashReport('%s','%s',result)", pUUID.c_str(), pUID.c_str());
+ VERB2 log("CreateCrashReport('%s','%s',result)", pUUID, pUID);
database_row_t row;
- if (pUUID != "")
+ if (pUUID[0] != '\0')
{
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
database->Connect();
row = database->GetUUIDData(pUUID, pUID);
database->DisConnect();
}
- if (pUUID == "" || row.m_sUUID != pUUID)
+ if (pUUID[0] == '\0' || row.m_sUUID != pUUID)
{
- warn_client("CreateCrashReport(): UUID '"+pUUID+"' is not in database");
+ error_msg("UUID '%s' is not in database", pUUID);
return MW_IN_DB_ERROR;
}
@@ -200,7 +204,7 @@ mw_result_t CreateCrashReport(const std::string& pUUID,
std::string reproduce = "1.\n2.\n3.\n";
VERB3 log(" LoadText(FILENAME_ANALYZER,'%s')", row.m_sDebugDumpDir.c_str());
- dd.Open(row.m_sDebugDumpDir);
+ dd.Open(row.m_sDebugDumpDir.c_str());
dd.LoadText(FILENAME_ANALYZER, analyzer);
if (dd.Exist(FILENAME_COMMENT))
{
@@ -213,15 +217,15 @@ mw_result_t CreateCrashReport(const std::string& pUUID,
dd.Close();
VERB3 log(" CreateReport('%s')", analyzer.c_str());
- CreateReport(analyzer, row.m_sDebugDumpDir, force);
+ CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force);
- gUUID = GetGlobalUUID(analyzer, row.m_sDebugDumpDir);
+ gUUID = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str());
VERB3 log(" GetGlobalUUID:'%s'", gUUID.c_str());
VERB3 log(" RunAnalyzerActions");
- RunAnalyzerActions(analyzer, row.m_sDebugDumpDir);
+ RunAnalyzerActions(analyzer.c_str(), row.m_sDebugDumpDir.c_str());
VERB3 log(" DebugDumpToCrashReport");
- DebugDumpToCrashReport(row.m_sDebugDumpDir, pCrashReport);
+ 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);
@@ -232,16 +236,16 @@ mw_result_t CreateCrashReport(const std::string& pUUID,
}
catch (CABRTException& e)
{
- warn_client("CreateCrashReport(): " + e.what());
+ error_msg("%s", e.what());
if (e.type() == EXCEP_DD_OPEN)
{
return MW_ERROR;
}
- else if (e.type() == EXCEP_DD_LOAD)
+ if (e.type() == EXCEP_DD_LOAD)
{
return MW_FILE_ERROR;
}
- else if (e.type() == EXCEP_PLUGIN)
+ if (e.type() == EXCEP_PLUGIN)
{
return MW_PLUGIN_ERROR;
}
@@ -251,48 +255,46 @@ mw_result_t CreateCrashReport(const std::string& pUUID,
return MW_OK;
}
-void RunAction(const std::string& pActionDir,
- const std::string& pPluginName,
- const std::string& pPluginArgs)
+void RunAction(const char *pActionDir,
+ const char *pPluginName,
+ const char *pPluginArgs)
{
try
{
CAction* action = g_pPluginManager->GetAction(pPluginName);
-
action->Run(pActionDir, pPluginArgs);
}
catch (CABRTException& e)
{
- warn_client("RunAction(): " + e.what());
- update_client("Execution of '"+pPluginName+"' was not successful: " + e.what());
+ error_msg("Execution of '%s' was not successful: %s", pPluginName, e.what());
}
}
-void RunActionsAndReporters(const std::string& pDebugDumpDir)
+void RunActionsAndReporters(const char *pDebugDumpDir)
{
vector_pair_string_string_t::iterator it_ar = s_vectorActionsAndReporters.begin();
+ map_plugin_settings_t plugin_settings;
for (; it_ar != s_vectorActionsAndReporters.end(); it_ar++)
{
try
{
- if (g_pPluginManager->GetPluginType((*it_ar).first) == REPORTER)
+ if (g_pPluginManager->GetPluginType(it_ar->first) == REPORTER)
{
- CReporter* reporter = g_pPluginManager->GetReporter((*it_ar).first);
+ CReporter* reporter = g_pPluginManager->GetReporter(it_ar->first);
map_crash_report_t crashReport;
DebugDumpToCrashReport(pDebugDumpDir, crashReport);
- reporter->Report(crashReport, (*it_ar).second);
+ reporter->Report(crashReport, plugin_settings, it_ar->second);
}
- else if (g_pPluginManager->GetPluginType((*it_ar).first) == ACTION)
+ else if (g_pPluginManager->GetPluginType(it_ar->first) == ACTION)
{
- CAction* action = g_pPluginManager->GetAction((*it_ar).first);
- action->Run(pDebugDumpDir, (*it_ar).second);
+ CAction* action = g_pPluginManager->GetAction(it_ar->first);
+ action->Run(pDebugDumpDir, it_ar->second.c_str());
}
}
catch (CABRTException& e)
{
- warn_client("RunActionsAndReporters(): " + e.what());
- update_client("Activation of plugin '"+(*it_ar).first+"' was not successful: " + e.what());
+ error_msg("Activation of plugin '%s' was not successful: %s", it_ar->first.c_str(), e.what());
}
}
}
@@ -312,6 +314,11 @@ static bool CheckReport(const map_crash_report_t& pCrashReport)
map_crash_report_t::const_iterator it_executable = pCrashReport.find(FILENAME_EXECUTABLE);
map_crash_report_t::const_iterator end = pCrashReport.end();
+
+ // 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 ||
@@ -334,7 +341,8 @@ static bool CheckReport(const map_crash_report_t& pCrashReport)
}
report_status_t Report(const map_crash_report_t& pCrashReport,
- const std::string& pUID)
+ map_map_string_t& pSettings,
+ const char *pUID)
{
report_status_t ret;
@@ -352,18 +360,18 @@ report_status_t Report(const map_crash_report_t& pCrashReport,
// Save comments and how to reproduciton
map_crash_report_t::const_iterator it_comment = pCrashReport.find(CD_COMMENT);
map_crash_report_t::const_iterator it_reproduce = pCrashReport.find(CD_REPRODUCE);
- std::string pDumpDir = getDebugDumpDir(UUID,UID);
+ std::string pDumpDir = getDebugDumpDir(UUID.c_str(), UID.c_str());
{
CDebugDump dd;
- dd.Open(pDumpDir);
+ dd.Open(pDumpDir.c_str());
if (it_comment != pCrashReport.end())
{
- dd.SaveText(FILENAME_COMMENT, it_comment->second[CD_CONTENT]);
+ dd.SaveText(FILENAME_COMMENT, it_comment->second[CD_CONTENT].c_str());
}
if (it_reproduce != pCrashReport.end())
{
- dd.SaveText(FILENAME_REPRODUCE, it_reproduce->second[CD_CONTENT]);
+ dd.SaveText(FILENAME_REPRODUCE, it_reproduce->second[CD_CONTENT].c_str());
}
}
@@ -407,7 +415,8 @@ report_status_t Report(const map_crash_report_t& pCrashReport,
}
}
#endif
- std::string res = reporter->Report(pCrashReport, it_r->second);
+ map_plugin_settings_t plugin_settings = pSettings[pluginName];
+ std::string res = reporter->Report(pCrashReport, plugin_settings, it_r->second);
#if 0 /* Using ~user/.abrt/ is bad wrt security */
if (home != "")
@@ -424,8 +433,7 @@ report_status_t Report(const map_crash_report_t& pCrashReport,
{
ret[pluginName].push_back("0");
ret[pluginName].push_back(e.what());
- warn_client("Report(): " + e.what());
- update_client("Reporting via '" + pluginName + "' was not successful: " + e.what());
+ update_client("Reporting via %s' was not successful: %s", pluginName.c_str(), e.what());
}
}
}
@@ -438,15 +446,15 @@ report_status_t Report(const map_crash_report_t& pCrashReport,
return ret;
}
-void DeleteDebugDumpDir(const std::string& pDebugDumpDir)
+void DeleteDebugDumpDir(const char *pDebugDumpDir)
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
dd.Delete();
}
-std::string DeleteCrashInfo(const std::string& pUUID,
- const std::string& pUID)
+std::string DeleteCrashInfo(const char *pUUID,
+ const char *pUID)
{
database_row_t row;
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
@@ -466,8 +474,8 @@ std::string DeleteCrashInfo(const std::string& pUUID,
* @return It returns true if debugdump dir is already saved, otherwise
* it returns false.
*/
-static bool IsDebugDumpSaved(const std::string& pUID,
- const std::string& pDebugDumpDir)
+static bool IsDebugDumpSaved(const char *pUID,
+ const char *pDebugDumpDir)
{
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
database->Connect();
@@ -501,19 +509,19 @@ void LoadOpenGPGPublicKey(const char* key)
* @param pDebugDumpDir A debugdump dir containing all necessary data.
* @return It return results of operation. See mw_result_t.
*/
-static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecutable,
- const std::string& pDebugDumpDir)
+static mw_result_t SavePackageDescriptionToDebugDump(const char *pExecutable,
+ const char *pDebugDumpDir)
{
std::string package;
std::string packageName;
- if (pExecutable == "kernel")
+ if (strcmp(pExecutable, "kernel") == 0)
{
packageName = package = "kernel";
}
else
{
- package = GetPackage(pExecutable.c_str());
+ package = GetPackage(pExecutable);
packageName = package.substr(0, package.rfind("-", package.rfind("-") - 1));
if (packageName == "" ||
(g_setBlackList.find(packageName) != g_setBlackList.end()))
@@ -533,7 +541,7 @@ static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecuta
error_msg("package isn't signed with proper key");
return MW_GPG_ERROR;
}
- if (!CheckHash(packageName.c_str(), pExecutable.c_str()))
+ if (!CheckHash(packageName.c_str(), pExecutable))
{
error_msg("executable has bad hash");
return MW_GPG_ERROR;
@@ -542,19 +550,19 @@ static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecuta
}
std::string description = GetDescription(packageName.c_str());
- std::string component = GetComponent(pExecutable.c_str());
+ std::string component = GetComponent(pExecutable);
try
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
- dd.SaveText(FILENAME_PACKAGE, package);
- dd.SaveText(FILENAME_DESCRIPTION, description);
- dd.SaveText(FILENAME_COMPONENT, component);
+ dd.SaveText(FILENAME_PACKAGE, package.c_str());
+ dd.SaveText(FILENAME_DESCRIPTION, description.c_str());
+ dd.SaveText(FILENAME_COMPONENT, component.c_str());
}
catch (CABRTException& e)
{
- warn_client("SavePackageDescriptionToDebugDump(): " + e.what());
+ error_msg("%s", e.what());
if (e.type() == EXCEP_DD_SAVE)
{
return MW_FILE_ERROR;
@@ -571,7 +579,7 @@ static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecuta
* @param pAnalyzer A name of an analyzer plugin.
* @param pDebugDumpPath A debugdump dir containing all necessary data.
*/
-static void RunAnalyzerActions(const std::string& pAnalyzer, const std::string& pDebugDumpDir)
+static void RunAnalyzerActions(const char *pAnalyzer, const char *pDebugDumpDir)
{
map_analyzer_actions_and_reporters_t::iterator analyzer = s_mapAnalyzerActionsAndReporters.find(pAnalyzer);
if (analyzer != s_mapAnalyzerActionsAndReporters.end())
@@ -585,13 +593,12 @@ static void RunAnalyzerActions(const std::string& pAnalyzer, const std::string&
if (g_pPluginManager->GetPluginType(pluginName) == ACTION)
{
CAction* action = g_pPluginManager->GetAction(pluginName);
- action->Run(pDebugDumpDir, it_a->second);
+ action->Run(pDebugDumpDir, it_a->second.c_str());
}
}
catch (CABRTException& e)
{
- warn_client("RunAnalyzerActions(): " + e.what());
- update_client("Action performed by '" + pluginName + "' was not successful: " + e.what());
+ update_client("Action performed by '%s' was not successful: %s", pluginName.c_str(), e.what());
}
}
}
@@ -608,10 +615,10 @@ static void RunAnalyzerActions(const std::string& pAnalyzer, const std::string&
* @param pCrashInfo A filled crash info.
* @return It return results of operation. See mw_result_t.
*/
-static mw_result_t SaveDebugDumpToDatabase(const std::string& pUUID,
- const std::string& pUID,
- const std::string& pTime,
- const std::string& pDebugDumpDir,
+static mw_result_t SaveDebugDumpToDatabase(const char *pUUID,
+ const char *pUID,
+ const char *pTime,
+ const char *pDebugDumpDir,
map_crash_info_t& pCrashInfo)
{
mw_result_t res;
@@ -635,8 +642,8 @@ static mw_result_t SaveDebugDumpToDatabase(const std::string& pUUID,
return res;
}
-std::string getDebugDumpDir( const std::string& pUUID,
- const std::string& pUID)
+std::string getDebugDumpDir(const char *pUUID,
+ const char *pUID)
{
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
database_row_t row;
@@ -646,13 +653,13 @@ std::string getDebugDumpDir( const std::string& pUUID,
return row.m_sDebugDumpDir;
}
-mw_result_t SaveDebugDump(const std::string& pDebugDumpDir)
+mw_result_t SaveDebugDump(const char *pDebugDumpDir)
{
map_crash_info_t info;
return SaveDebugDump(pDebugDumpDir, info);
}
-mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
+mw_result_t SaveDebugDump(const char *pDebugDumpDir,
map_crash_info_t& pCrashInfo)
{
std::string lUUID;
@@ -673,7 +680,7 @@ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
}
catch (CABRTException& e)
{
- warn_client("SaveDebugDump(): " + e.what());
+ error_msg("%s", e.what());
if (e.type() == EXCEP_DD_SAVE)
{
return MW_FILE_ERROR;
@@ -681,24 +688,24 @@ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
return MW_ERROR;
}
- if (IsDebugDumpSaved(UID, pDebugDumpDir))
+ if (IsDebugDumpSaved(UID.c_str(), pDebugDumpDir))
{
return MW_IN_DB;
}
- res = SavePackageDescriptionToDebugDump(executable, pDebugDumpDir);
+ res = SavePackageDescriptionToDebugDump(executable.c_str(), pDebugDumpDir);
if (res != MW_OK)
{
return res;
}
- lUUID = GetLocalUUID(analyzer, pDebugDumpDir);
+ lUUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir);
- return SaveDebugDumpToDatabase(lUUID, UID, time, pDebugDumpDir, pCrashInfo);
+ return SaveDebugDumpToDatabase(lUUID.c_str(), UID.c_str(), time.c_str(), pDebugDumpDir, pCrashInfo);
}
-mw_result_t GetCrashInfo(const std::string& pUUID,
- const std::string& pUID,
- map_crash_info_t& pCrashInfo)
+mw_result_t GetCrashInfo(const char *pUUID,
+ const char *pUID,
+ map_crash_info_t& pCrashInfo)
{
pCrashInfo.clear();
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
@@ -710,18 +717,20 @@ mw_result_t GetCrashInfo(const std::string& pUUID,
std::string package;
std::string executable;
std::string description;
+ std::string analyzer;
try
{
CDebugDump dd;
- dd.Open(row.m_sDebugDumpDir);
+ 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);
}
catch (CABRTException& e)
{
- warn_client("GetCrashInfo(): " + e.what());
+ error_msg("%s", e.what());
if (e.type() == EXCEP_DD_LOAD)
{
return MW_FILE_ERROR;
@@ -738,11 +747,12 @@ mw_result_t GetCrashInfo(const std::string& pUUID,
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);
return MW_OK;
}
-vector_pair_string_string_t GetUUIDsOfCrash(const std::string& pUID)
+vector_pair_string_string_t GetUUIDsOfCrash(const char *pUID)
{
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
vector_database_rows_t rows;
@@ -760,15 +770,15 @@ vector_pair_string_string_t GetUUIDsOfCrash(const std::string& pUID)
return UUIDsUIDs;
}
-void AddAnalyzerActionOrReporter(const std::string& pAnalyzer,
- const std::string& pAnalyzerOrReporter,
- const std::string& pArgs)
+void AddAnalyzerActionOrReporter(const char *pAnalyzer,
+ const char *pAnalyzerOrReporter,
+ const char *pArgs)
{
- s_mapAnalyzerActionsAndReporters[pAnalyzer].push_back(make_pair(pAnalyzerOrReporter, pArgs));
+ s_mapAnalyzerActionsAndReporters[pAnalyzer].push_back(make_pair(std::string(pAnalyzerOrReporter), std::string(pArgs)));
}
-void AddActionOrReporter(const std::string& pActionOrReporter,
- const std::string& pArgs)
+void AddActionOrReporter(const char *pActionOrReporter,
+ const char *pArgs)
{
- s_vectorActionsAndReporters.push_back(make_pair(pActionOrReporter, pArgs));
+ s_vectorActionsAndReporters.push_back(make_pair(std::string(pActionOrReporter), std::string(pArgs)));
}
diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h
index fab822fe..0671dd02 100644
--- a/src/Daemon/MiddleWare.h
+++ b/src/Daemon/MiddleWare.h
@@ -63,8 +63,8 @@ void LoadOpenGPGPublicKey(const char* key);
* @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,
+mw_result_t CreateCrashReport(const char *pUUID,
+ const char *pUID,
int force,
map_crash_report_t& pCrashReport);
/**
@@ -73,15 +73,15 @@ mw_result_t CreateCrashReport(const std::string& pUUID,
* @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);
+void RunAction(const char *pActionDir,
+ const char *pPluginName,
+ const char *pPluginArgs);
/**
* Activates all action and reporter plugins when any
* crash occurs.
* @param pDebugDumpDir A debugdump dir containing all necessary data.
*/
-void RunActionsAndReporters(const std::string& pDebugDumpDir);
+void RunActionsAndReporters(const char *pDebugDumpDir);
/**
* Reports a crash report to particular receiver. It
* takes an user uid, tries to find user config file and load it. If it
@@ -93,7 +93,8 @@ void RunActionsAndReporters(const std::string& pDebugDumpDir);
* @return A report status, which reporters ends successfuly with messages.
*/
report_status_t Report(const map_crash_report_t& pCrashReport,
- const std::string& pUID);
+ map_map_string_t& pSettings,
+ const char *pUID);
/**
* Get debugdump direcotory. If debugdump is not found
* in database it will return empty string.
@@ -101,13 +102,13 @@ report_status_t Report(const map_crash_report_t& pCrashReport,
* @param pUID An UID of an user.
* @return A debugdump directory.
*/
-std::string getDebugDumpDir( const std::string& pUUID,
- const std::string& pUID);
+std::string getDebugDumpDir( const char *pUUID,
+ const char *pUID);
/**
* Deletes particular debugdump directory.
* @param pDebugDumpDir A debugdump directory.
*/
-void DeleteDebugDumpDir(const std::string& pDebugDumpDir);
+void DeleteDebugDumpDir(const char *pDebugDumpDir);
/**
* Deletes a row from database. If a deleting is
* successfull, it returns a debugdump directort, which is not
@@ -116,14 +117,14 @@ void DeleteDebugDumpDir(const std::string& pDebugDumpDir);
* @param pUID An UID of an user.
* @return A debugdump directory.
*/
-std::string DeleteCrashInfo(const std::string& pUUID,
- const std::string& pUID);
+std::string DeleteCrashInfo(const char *pUUID,
+ const char *pUID);
/**
* 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);
+mw_result_t SaveDebugDump(const char *pDebugDumpDir);
/**
* Saves debugdump into database. If saving is successful,
* it fills crash info.
@@ -131,7 +132,7 @@ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir);
* @param pCrashInfo A crash info.
* @return It return results of operation. See mw_result_t.
*/
-mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
+mw_result_t SaveDebugDump(const char *pDebugDumpDir,
map_crash_info_t& pCrashInfo);
/**
* Get one crash info. If getting is successful,
@@ -141,8 +142,8 @@ mw_result_t SaveDebugDump(const std::string& pDebugDumpDir,
* @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,
+mw_result_t GetCrashInfo(const char *pUUID,
+ const char *pUID,
map_crash_info_t& pCrashInfo);
/**
* Gets all local UUIDs and UIDs of crashes. These crashes
@@ -150,7 +151,7 @@ mw_result_t GetCrashInfo(const std::string& pUUID,
* @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);
+vector_pair_string_string_t GetUUIDsOfCrash(const char *pUID);
/**
* Adds one association among alanyzer plugin and its
* action and reporter plugins.
@@ -158,17 +159,17 @@ vector_pair_string_string_t GetUUIDsOfCrash(const std::string& pUID);
* @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);
+void AddAnalyzerActionOrReporter(const char *pAnalyzer,
+ const char *pActionOrReporter,
+ const char *pArgs);
/**
* Add 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);
+void AddActionOrReporter(const char *pActionOrReporter,
+ const char *pArgs);
#endif /*MIDDLEWARE_H_*/
diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp
index 2363308a..5b871515 100644
--- a/src/Daemon/PluginManager.cpp
+++ b/src/Daemon/PluginManager.cpp
@@ -179,8 +179,7 @@ void CPluginManager::LoadPlugin(const std::string& pName)
catch (CABRTException& e)
{
delete abrtPlugin;
- warn_client("CPluginManager::LoadPlugin(): " + e.what());
- warn_client("Failed to load plugin " + pName);
+ error_msg("Failed to load plugin %s: %s", pName.c_str(), e.what());
}
}
}
@@ -218,7 +217,7 @@ void CPluginManager::RegisterPlugin(const std::string& pName)
log("Can't initialize plugin %s(%s): %s",
pName.c_str(),
plugin_type_str[abrt_plugin->second->GetType()],
- e.what().c_str()
+ e.what()
);
UnLoadPlugin(pName);
return;
diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp
index 1eb42263..d9c9a98b 100644
--- a/src/Daemon/Settings.cpp
+++ b/src/Daemon/Settings.cpp
@@ -54,12 +54,12 @@ map_cron_t g_settings_mapCron;
* Loading
*/
-static set_string_t ParseList(const std::string& pList)
+static set_string_t ParseList(const char* pList)
{
- unsigned int ii;
- std::string item = "";
+ unsigned ii;
+ std::string item;
set_string_t set;
- for (ii = 0; ii < pList.size(); ii++)
+ for (ii = 0; pList[ii]; ii++)
{
if (pList[ii] == ',')
{
@@ -78,19 +78,19 @@ static set_string_t ParseList(const std::string& pList)
return set;
}
-static vector_pair_string_string_t ParseListWithArgs(const std::string& pValue)
+static vector_pair_string_string_t ParseListWithArgs(const char *pValue)
{
vector_pair_string_string_t pluginsWithArgs;
unsigned int ii;
- std::string item = "";
- std::string action = "";
+ std::string item;
+ std::string action;
bool is_quote = false;
bool is_arg = false;
- for (ii = 0; ii < pValue.size(); ii++)
+ for (ii = 0; pValue[ii]; ii++)
{
if (pValue[ii] == '\"')
{
- is_quote = is_quote == true ? false : true;
+ is_quote = !is_quote;
item += pValue[ii];
}
else if (pValue[ii] == '(' && !is_quote)
@@ -137,12 +137,12 @@ static void ParseCommon()
it = s_mapSectionCommon.find("OpenGPGPublicKeys");
if (it != end)
{
- g_settings_setOpenGPGPublicKeys = ParseList(it->second);
+ g_settings_setOpenGPGPublicKeys = ParseList(it->second.c_str());
}
it = s_mapSectionCommon.find("BlackList");
if (it != end)
{
- g_settings_mapBlackList = ParseList(it->second);
+ g_settings_mapBlackList = ParseList(it->second.c_str());
}
it = s_mapSectionCommon.find("Database");
if (it != end)
@@ -152,7 +152,7 @@ static void ParseCommon()
it = s_mapSectionCommon.find("EnabledPlugins");
if (it != end)
{
- g_settings_setEnabledPlugins = ParseList(it->second);
+ g_settings_setEnabledPlugins = ParseList(it->second.c_str());
}
it = s_mapSectionCommon.find("MaxCrashReportsSize");
if (it != end)
@@ -162,7 +162,7 @@ static void ParseCommon()
it = s_mapSectionCommon.find("ActionsAndReporters");
if (it != end)
{
- g_settings_vectorActionsAndReporters = ParseListWithArgs(it->second);
+ g_settings_vectorActionsAndReporters = ParseListWithArgs(it->second.c_str());
}
}
@@ -171,23 +171,23 @@ static void ParseCron()
map_string_t::iterator it = s_mapSectionCron.begin();
for (; it != s_mapSectionCron.end(); it++)
{
- vector_pair_string_string_t actionsAndReporters = ParseListWithArgs(it->second);
+ vector_pair_string_string_t actionsAndReporters = ParseListWithArgs(it->second.c_str());
g_settings_mapCron[it->first] = actionsAndReporters;
}
}
-static set_string_t ParseKey(const std::string& Key)
+static set_string_t ParseKey(const char *Key)
{
unsigned int ii;
- std::string item = "";
- std::string key = "";
+ std::string item;
+ std::string key;
set_string_t set;
bool is_quote = false;
- for (ii = 0; ii < Key.size(); ii++)
+ for (ii = 0; Key[ii]; ii++)
{
if (Key[ii] == '\"')
{
- is_quote = is_quote == true ? false : true;
+ is_quote = !is_quote;
}
else if (Key[ii] == ':' && !is_quote)
{
@@ -223,8 +223,8 @@ static void ParseAnalyzerActionsAndReporters()
map_string_t::iterator it = s_mapSectionAnalyzerActionsAndReporters.begin();
for (; it != s_mapSectionAnalyzerActionsAndReporters.end(); it++)
{
- set_string_t keys = ParseKey(it->first);
- vector_pair_string_string_t actionsAndReporters = ParseListWithArgs(it->second);
+ set_string_t keys = ParseKey(it->first.c_str());
+ vector_pair_string_string_t actionsAndReporters = ParseListWithArgs(it->second.c_str());
set_string_t::iterator it_keys = keys.begin();
for (; it_keys != keys.end(); it_keys++)
{
@@ -241,7 +241,7 @@ void LoadSettings()
if (fIn.is_open())
{
std::string line;
- std::string section = "";
+ std::string section;
while (!fIn.eof())
{
getline(fIn, line);
@@ -250,8 +250,8 @@ void LoadSettings()
bool is_key = true;
bool is_section = false;
bool is_quote = false;
- std::string key = "";
- std::string value = "";
+ std::string key;
+ std::string value;
for (ii = 0; ii < line.length(); ii++)
{
if (isspace(line[ii]) && !is_quote)
@@ -269,7 +269,7 @@ void LoadSettings()
}
else if (line[ii] == '\"')
{
- is_quote = is_quote == true ? false : true;
+ is_quote = !is_quote;
value += line[ii];
}
else if (is_section)
@@ -434,7 +434,7 @@ void SetSettings(const map_abrt_settings_t& pSettings, const char *dbus_sender)
"org.fedoraproject.abrt.change-daemon-settings");
if (polkit_result != PolkitYes)
{
- log("user %s not authorized, returned %d", dbus_sender, polkit_result);
+ error_msg("user %s not authorized, returned %d", dbus_sender, polkit_result);
return;
}
log("user %s succesfully authorized", dbus_sender);
diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install
index fc5380ba..6070b74d 100755
--- a/src/Daemon/abrt-debuginfo-install
+++ b/src/Daemon/abrt-debuginfo-install
@@ -13,9 +13,10 @@
# If CACHEDIR is specified, debuginfos should be installed there.
# If not, debuginfos should be installed into TEMPDIR.
#
-# Currently, we are called with CACHEDIR set to "/", but in the future
-# it may be omitted or set to something else. script must be ready
-# for those cases too.
+# Currently, we are called with CACHEDIR set to "/var/cache/abrt-di",
+# but in the future it may be omitted or set to something else.
+# Script must be ready for those cases too. Consider, for example,
+# corner cases of "" and "/".
#
# Output goes to GUI as debuginfo install log. The script should be careful
# to give useful, but not overly cluttered info to stdout.
@@ -62,10 +63,6 @@ tempdir=$2
cachedir=$3
debug=false
-count_words() {
- echo $#
-}
-
exec 2>&1
test -f "$core" || exit 2
@@ -74,10 +71,41 @@ test x"$cachedir" = x"" || test -d "$cachedir" || exit 2
# tempdir must not exist
test -e "$tempdir" && exit 2
-mkdir "$tempdir" || exit 2
+mkdir -- "$tempdir" || exit 2
cd "$tempdir" || exit 2
$debug && echo "Installing rpms to $tempdir"
+
+count_words() {
+ echo $#
+}
+
+cleanup_and_report_missing() {
+# Which debuginfo files are still missing, including those we just unpacked?
+ missing_build_ids=`for build_id in $build_ids; do
+ build_id1=${build_id:0:2}
+ build_id2=${build_id:2}
+ file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
+ test -f "/$file" && continue
+ test -f "$cachedir/$file" && continue
+ echo -n "$build_id "
+ done`
+ $debug && echo "missing_build_ids:$missing_build_ids"
+
+ # If cachedir is specified, tempdir is just a staging area. Delete it
+ if test x"$cachedir" != x""; then
+ $debug && echo "Removing $tempdir"
+ rm -rf "$tempdir"
+ fi
+
+ for missing in $missing_build_ids; do
+ echo "MISSING:$missing"
+ done
+
+ test x"$missing_build_ids" != x"" && echo "`count_words $missing_build_ids` debuginfos can't be found"
+}
+
+
# eu-unstrip output example:
# 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe]
# or
@@ -86,7 +114,9 @@ $debug && echo "Installing rpms to $tempdir"
# 0x3d15600000+0x208000 20196628d1bc062279622615cc9955554e5bb227@0x3d156001a0 /usr/lib64/libnotify.so.1.1.3 /usr/lib/debug/usr/lib64/libnotify.so.1.1.3.debug libnotify.so.1
# 0x7fd8ae931000+0x62d000 dd49f44f958b5a11a1635523b2f09cb2e45c1734@0x7fd8ae9311a0 /usr/lib64/libgtk-x11-2.0.so.0.1600.6 /usr/lib/debug/usr/lib64/libgtk-x11-2.0.so.0.1600.6.debug
echo "Getting list of build IDs"
-eu_unstrip_OUT=`eu-unstrip "--core=$core" -n 2>&1`
+# Observed errors:
+# eu-unstrip: /var/cache/abrt/ccpp-1256301004-2754/coredump: Callback returned failure
+eu_unstrip_OUT=`eu-unstrip "--core=$core" -n 2>eu_unstrip.ERR`
err=$?
printf "%s\nexitcode:%s\n" "$eu_unstrip_OUT" $err >eu_unstrip.OUT
test $err = 0 || exit 2
@@ -112,24 +142,19 @@ $debug && echo "build_ids:$build_ids"
missing_debuginfo_files=`for build_id in $build_ids; do
build_id1=${build_id:0:2}
build_id2=${build_id:2}
-
file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
if test x"$cachedir" != x"" && test x"$cachedir" != x"/" ; then
test -f "$cachedir/$file" && continue
- if test -f "/$file"; then
- mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1"
- # Note: this does not preserve symlinks. This is intentional
- $debug && echo Copying "$file" to "$cachedir/$file" >&2
- cp "$file" "$cachedir/$file"
- continue
- fi
fi
test -f "/$file" && continue
echo -n "/$file "
done`
$debug && echo "missing_debuginfo_files:$missing_debuginfo_files"
-test x"$missing_debuginfo_files" = x"" && exit 0
+if test x"$missing_debuginfo_files" = x""; then
+ cleanup_and_report_missing
+ exit 0
+fi
# We'll run something like:
# yum --enablerepo='*debuginfo*' --quiet provides \
@@ -162,14 +187,31 @@ $debug && echo "packages:$packages"
# yum may return "" here if it found no packages (say, if coredump is from a new,
# unreleased package fresh from koji).
-test x"$packages" = x"" && exit 1
+if test x"$packages" = x""; then
+ cleanup_and_report_missing
+ exit 1
+fi
-# Redirecting, since progress bar stuff only messes up our output
-echo "Downloading `count_words $packages` packages"
-yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1
-err=$?
-echo "exitcode:$err" >>yumdownloader.OUT
-test $err = 0 || exit 2
+num_packages=`count_words $packages`
+echo "Downloading $num_packages packages"
+## Download with one command (too silent):
+## Redirecting, since progress bar stuff only messes up our output
+##yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1
+##err=$?
+##echo "exitcode:$err" >>yumdownloader.OUT
+##test $err = 0 || exit 2
+>yumdownloader.OUT
+i=1
+for pkg in $packages; do
+ echo "Download $i/$num_packages: $pkg"
+ echo "Download $i/$num_packages: $pkg" >>yumdownloader.OUT
+ yumdownloader --enablerepo='*debuginfo*' --quiet $pkg >>yumdownloader.OUT 2>&1
+ err=$?
+ echo "exitcode:$err" >>yumdownloader.OUT
+ echo >>yumdownloader.OUT
+ test $err = 0 || { echo "Download of $pkg failed!"; sleep 1; }
+ : $((i++))
+done
for f in *.rpm; do
# Happens if no .rpm's were downloaded (yumdownloader problem)
@@ -180,45 +222,31 @@ for f in *.rpm; do
rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1
done
-# Which debuginfo files are still missing, including those we just unpacked?
-missing_build_ids=`for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
+# Copy debuginfo files to cachedir
+if test x"$cachedir" != x"" && test -d "$cachedir"; then
+ for build_id in $build_ids; do
+ build_id1=${build_id:0:2}
+ build_id2=${build_id:2}
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
+ file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
- test -f "/$file" && continue
- test x"$cachedir" != x"" \
- && test x"$cachedir" != x"/" \
- && test -f "$cachedir/$file" && continue
-
- if test -f "$file"; then
- # file is one of those we just installed.
- # Cache it if cachedir is specified.
- if test x"$cachedir" != x"" && test -d "$cachedir"; then
+ test -f "/$file" && continue
+ test x"$cachedir" != x"/" && test -f "$cachedir/$file" && continue
+
+ if test -f "$file"; then
+ # file is one of those we just installed.
+ # Cache it if cachedir is specified.
mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1"
# Note: this does not preserve symlinks. This is intentional
- $debug && echo Copying "$file" to "$cachedir/$file" >&2
+ $debug && echo Copying2 "$file" to "$cachedir/$file" >&2
cp --remove-destination "$file" "$cachedir/$file"
+ continue
fi
- continue
- fi
- echo -n "$build_id "
-done`
-$debug && echo "missing_build_ids:$missing_build_ids"
-
-# If cachedir is specified, tempdir is just a staging area. Delete it
-if test x"$cachedir" != x""; then
- $debug && echo "Removing $tempdir"
- rm -rf "$tempdir"
+ done
fi
+$debug && echo "missing_build_ids:$missing_build_ids"
-test x"$missing_build_ids" = x"" && exit 0
-
-for missing in $missing_build_ids; do
- echo "MISSING:$missing"
-done
-
-echo "`count_words $missing_build_ids` debuginfos can't be found"
+cleanup_and_report_missing
-exit 1
+test x"$missing_build_ids" != x"" && exit 1
+exit 0
diff --git a/src/Daemon/abrt.conf b/src/Daemon/abrt.conf
index 1fe6123b..e9845e58 100644
--- a/src/Daemon/abrt.conf
+++ b/src/Daemon/abrt.conf
@@ -1,32 +1,31 @@
# test conf file. it will be generated in the future
-# common abrt settings
+# Common abrt settings
[ Common ]
# With this option set to "yes",
# only crashes in signed packages will be analyzed.
OpenGPGCheck = no
# GPG keys
OpenGPGPublicKeys = /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora
-# blacklisted packages
-BlackList =
-# enabled plugins
-# there has to be exactly one database plugin
+# Blacklisted packages
+BlackList = nspluginwrapper
+# Enabled plugins. There has to be exactly one database plugin
EnabledPlugins = SQLite3, CCpp, Logger, Kerneloops, KerneloopsScanner, KerneloopsReporter, Bugzilla, Python
# Database
Database = SQLite3
-# max size for crash storage [MiB]
+# 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
# ActionsAndReporters = Mailx("[abrt] new crash was detected")
-# reporters association with analyzers
+# Reporters association with analyzers
[ AnalyzerActionsAndReporters ]
Kerneloops = KerneloopsReporter
CCpp = Bugzilla, Logger
Python = Bugzilla, Logger
# CCpp : xorg-x11-apps = RunApp("date", "RunApp")
-# repeated calling of Action plugins
+# Repeated calling of Action plugins
[ Cron ]
# h:m - at h:m an action plugin is activated
# s - every s seconds is an action plugin activated
diff --git a/src/Daemon/com.redhat.abrt.service b/src/Daemon/com.redhat.abrt.service
index 163f276c..b251ef7f 100644
--- a/src/Daemon/com.redhat.abrt.service
+++ b/src/Daemon/com.redhat.abrt.service
@@ -1,4 +1,7 @@
[D-BUS Service]
Name=com.redhat.abrt
+# For testing, you may add -t33 to use small timeout of 33 seconds.
+# This will make "abrtd exited while clients existed but were idle"
+# situations easy to trigger
Exec=/usr/sbin/abrtd -ds
User=root