diff options
author | Karel Klic <kklic@redhat.com> | 2009-11-11 22:30:27 +0100 |
---|---|---|
committer | Karel Klic <kklic@redhat.com> | 2009-11-11 22:30:27 +0100 |
commit | 07a12979cbf321c03c615f921aec601492e8d196 (patch) | |
tree | a0eba8c5b0cf06be829c378ca8704470e37a036b /src | |
parent | 4bb5f0163c1cf3c65745ea06f1b42545ecaa35d7 (diff) | |
parent | 640af192338643b3c9e6fbe0304726e951239c2b (diff) | |
download | abrt-07a12979cbf321c03c615f921aec601492e8d196.tar.gz abrt-07a12979cbf321c03c615f921aec601492e8d196.tar.xz abrt-07a12979cbf321c03c615f921aec601492e8d196.zip |
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'src')
-rw-r--r-- | src/Applet/Applet.cpp | 23 | ||||
-rw-r--r-- | src/Daemon/CommLayerServer.h | 2 | ||||
-rw-r--r-- | src/Daemon/CommLayerServerDBus.cpp | 32 | ||||
-rw-r--r-- | src/Daemon/CommLayerServerDBus.h | 2 | ||||
-rw-r--r-- | src/Daemon/CommLayerServerSocket.cpp | 12 | ||||
-rw-r--r-- | src/Daemon/CrashWatcher.cpp | 47 | ||||
-rw-r--r-- | src/Daemon/CrashWatcher.h | 8 | ||||
-rw-r--r-- | src/Daemon/Daemon.cpp | 117 | ||||
-rw-r--r-- | src/Daemon/Makefile.am | 2 | ||||
-rw-r--r-- | src/Daemon/MiddleWare.cpp | 226 | ||||
-rw-r--r-- | src/Daemon/MiddleWare.h | 49 | ||||
-rw-r--r-- | src/Daemon/PluginManager.cpp | 5 | ||||
-rw-r--r-- | src/Daemon/Settings.cpp | 54 | ||||
-rwxr-xr-x | src/Daemon/abrt-debuginfo-install | 249 | ||||
-rw-r--r-- | src/Daemon/abrt.conf | 15 | ||||
-rw-r--r-- | src/Gui/CCMainWindow.py | 2 | ||||
-rw-r--r-- | src/Gui/CCReporterDialog.py | 57 | ||||
-rw-r--r-- | src/Gui/report.glade | 78 | ||||
-rw-r--r-- | src/Hooks/CCpp.cpp | 4 |
19 files changed, 584 insertions, 400 deletions
diff --git a/src/Applet/Applet.cpp b/src/Applet/Applet.cpp index 327e24f5..2eed556a 100644 --- a/src/Applet/Applet.cpp +++ b/src/Applet/Applet.cpp @@ -49,13 +49,12 @@ static void Crash(DBusMessage* signal) dbus_message_iter_init(signal, &in_iter); const char* progname; r = load_val(&in_iter, progname); - if (r != ABRT_DBUS_MORE_FIELDS) + /* Optional 2nd param: uid */ + const char* uid_str = NULL; + if (r == ABRT_DBUS_MORE_FIELDS) { - error_msg("dbus signal %s: parameter type mismatch", __func__); - return; + r = load_val(&in_iter, uid_str); } - const char* uid_str; - r = load_val(&in_iter, uid_str); if (r != ABRT_DBUS_LAST_FIELD) { error_msg("dbus signal %s: parameter type mismatch", __func__); @@ -66,13 +65,17 @@ static void Crash(DBusMessage* signal) // return; // uid_t uid_num = atol(uid_str); - char* endptr; - int64_t uid_num = strtoll(uid_str,&endptr, 10); - - if ((uid_num != getuid()) && (uid_num != -1)) + if (uid_str != NULL) { - return; + char *end; + errno = 0; + unsigned long uid_num = strtoul(uid_str, &end, 10); + if (errno || *end != '\0' || uid_num != getuid()) + { + return; + } } + const char* message = _("A crash in package %s has been detected"); //applet->AddEvent(uid, progname); applet->SetIconTooltip(message, progname); 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 2483942d..ed7e3858 100644 --- a/src/Daemon/CommLayerServerDBus.cpp +++ b/src/Daemon/CommLayerServerDBus.cpp @@ -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); @@ -273,12 +281,12 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) report_status_t argout1; try { - argout1 = Report(argin1, user_conf_data, 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); @@ -307,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, 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 7afe4b6e..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; @@ -157,7 +157,7 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan } else { - warn_client("Received unknown message type."); + error_msg("Received unknown message type"); } } diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp index ad3f37ad..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,7 +161,7 @@ static void* create_report(void* arg) } catch (CABRTException& e) { - warn_client(e.what()); + error_msg("%s", e.what()); } catch (...) {} set_client_name(NULL); @@ -208,12 +206,12 @@ int CreateReportThread(const char* pUUID, const char* pUID, int force, const cha 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) { @@ -221,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 af4f9dc5..3ceab47c 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -19,6 +19,7 @@ #include <syslog.h> #include <pthread.h> +#include <resolv.h> /* res_init */ #include <string> #include <limits.h> #include <sys/inotify.h> @@ -175,8 +176,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) @@ -184,8 +186,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) @@ -199,7 +202,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; } @@ -225,7 +229,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(); @@ -234,7 +238,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()); } } } @@ -368,29 +372,29 @@ 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]); + VERB1 log("Saving %s into database", itt->c_str()); + RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str()); break; case MW_IN_DB: - VERB1 log("Already saved in database (%s)", itt->c_str()); + VERB1 log("%s is already saved in database", itt->c_str()); break; case MW_REPORTED: case MW_OCCURED: + VERB1 log("Already saved crash %s, deleting", itt->c_str()); + DeleteDebugDumpDir(itt->c_str()); + break; case MW_BLACKLISTED: case MW_CORRUPTED: case MW_PACKAGE_ERROR: case MW_GPG_ERROR: case MW_FILE_ERROR: default: -//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); + log("Corrupted or bad crash %s (res:%d), deleting", itt->c_str(), (int)res); + DeleteDebugDumpDir(itt->c_str()); break; } } @@ -400,7 +404,7 @@ static void FindNewDumps(const char* pPath) { throw e; } - error_msg("%s", e.what().c_str()); + error_msg("%s", e.what()); } } } @@ -514,47 +518,33 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin ) { 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 */ - if(crashinfo[CD_MWANALYZER][CD_CONTENT] == "Kerneloops") - { - // When Kerneloops comes it will be sent uid with -1 - // Applet will detected and show normal user - g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT], to_string("-1")); - } - else - { - 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 */ - if(crashinfo[CD_MWANALYZER][CD_CONTENT] == "Kerneloops") { - // When Kerneloops comes it will be sent uid with -1 - // Applet will detected and show normal user - g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT], to_string("-1")); + 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); } - else - { - g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT], crashinfo[CD_UID][CD_CONTENT]); - } - //DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name); break; case MW_BLACKLISTED: case MW_CORRUPTED: @@ -563,14 +553,14 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin 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) { free(buf); @@ -594,6 +584,8 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin 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) { @@ -618,6 +610,33 @@ static void run_main_loop(GMainLoop* loop) 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); @@ -795,7 +814,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 @@ -852,7 +871,7 @@ int main(int argc, char** argv) } catch (CABRTException& e) { - error_msg("Error: %s", e.what().c_str()); + error_msg("Error: %s", e.what()); } catch (std::exception& e) { diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am index 4365a0c9..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 diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp index e30a0048..0bc358e1 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; @@ -98,7 +99,8 @@ static void DebugDumpToCrashReport(const std::string& pDebugDumpDir, map_crash_r fileName, CD_BIN, CD_ISNOTEDITABLE, - pDebugDumpDir + "/" + fileName); + concat_path_file(pDebugDumpDir, fileName.c_str()) + ); } else { @@ -137,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); @@ -150,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); @@ -164,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; } @@ -202,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)) { @@ -215,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); @@ -234,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; } @@ -253,24 +255,22 @@ 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; @@ -278,24 +278,23 @@ void RunActionsAndReporters(const std::string& pDebugDumpDir) { 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, plugin_settings, (*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()); } } } @@ -315,11 +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") + 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 || @@ -343,7 +342,7 @@ static bool CheckReport(const map_crash_report_t& pCrashReport) report_status_t Report(const map_crash_report_t& pCrashReport, map_map_string_t& pSettings, - const std::string& pUID) + const char *pUID) { report_status_t ret; @@ -361,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()); } } @@ -434,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()); } } } @@ -448,20 +446,19 @@ 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); database->Connect(); - row = database->GetUUIDData(pUUID, pUID); + database_row_t row = database->GetUUIDData(pUUID, pUID); database->Delete(pUUID, pUID); database->DisConnect(); @@ -476,8 +473,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(); @@ -511,19 +508,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())) @@ -543,7 +540,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; @@ -552,19 +549,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; @@ -575,13 +572,28 @@ static mw_result_t SavePackageDescriptionToDebugDump(const std::string& pExecuta return MW_OK; } +bool analyzer_has_InformAllUsers(const char *analyzer_name) +{ + CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(analyzer_name); + if (!analyzer) + { + VERB1 log("Strange, asked for analyzer %s but it doesn't exist?", analyzer_name); + 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()); +} + /** * Execute 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. */ -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()) @@ -595,13 +607,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()); } } } @@ -618,20 +629,18 @@ 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; CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase); - database_row_t row; database->Connect(); database->Insert(pUUID, pUID, pDebugDumpDir, pTime); - row = database->GetUUIDData(pUUID, pUID); + database_row_t row = database->GetUUIDData(pUUID, pUID); database->DisConnect(); - res = GetCrashInfo(pUUID, pUID, pCrashInfo); + mw_result_t res = GetCrashInfo(pUUID, pUID, pCrashInfo); if (row.m_sReported == "1") { log("Crash is already reported"); @@ -645,33 +654,23 @@ 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; database->Connect(); - row = database->GetUUIDData(pUUID, pUID); + database_row_t row = database->GetUUIDData(pUUID, pUID); database->DisConnect(); return row.m_sDebugDumpDir; } -mw_result_t SaveDebugDump(const std::string& 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; std::string UID; std::string time; std::string analyzer; std::string executable; - mw_result_t res; - try { CDebugDump dd; @@ -683,7 +682,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; @@ -691,41 +690,41 @@ 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); + mw_result_t res = SavePackageDescriptionToDebugDump(executable.c_str(), pDebugDumpDir); if (res != MW_OK) { return res; } - lUUID = GetLocalUUID(analyzer, pDebugDumpDir); - - return SaveDebugDumpToDatabase(lUUID, UID, time, pDebugDumpDir, pCrashInfo); + std::string lUUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir); + const char *uid_str = analyzer_has_InformAllUsers(analyzer.c_str()) + ? "-1" + : UID.c_str(); + return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashInfo); } -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); - database_row_t row; database->Connect(); - row = database->GetUUIDData(pUUID, pUID); + database_row_t row = database->GetUUIDData(pUUID, pUID); database->DisConnect(); 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); @@ -733,13 +732,14 @@ mw_result_t GetCrashInfo(const std::string& pUUID, } catch (CABRTException& e) { - warn_client("GetCrashInfo(): " + e.what()); + error_msg("%s", e.what()); if (e.type() == EXCEP_DD_LOAD) { 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); @@ -755,7 +755,7 @@ mw_result_t GetCrashInfo(const std::string& pUUID, 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; @@ -773,15 +773,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 c78d4d95..ac042def 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 @@ -94,7 +94,7 @@ void RunActionsAndReporters(const std::string& pDebugDumpDir); */ report_status_t Report(const map_crash_report_t& pCrashReport, map_map_string_t& pSettings, - const std::string& pUID); + const char *pUID); /** * Get debugdump direcotory. If debugdump is not found * in database it will return empty string. @@ -102,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 @@ -117,14 +117,8 @@ 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); -/** - * 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); +std::string DeleteCrashInfo(const char *pUUID, + const char *pUID); /** * Saves debugdump into database. If saving is successful, * it fills crash info. @@ -132,7 +126,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, @@ -142,8 +136,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 @@ -151,7 +145,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. @@ -159,17 +153,18 @@ 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); +bool analyzer_has_InformAllUsers(const char *analyzer_name); #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..cefd35a4 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) @@ -132,17 +132,17 @@ static void ParseCommon() map_string_t::const_iterator end = s_mapSectionCommon.end(); if (it != end) { - g_settings_bOpenGPGCheck = it->second == "yes"; + g_settings_bOpenGPGCheck = string_to_bool(it->second.c_str()); } 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 6070b74d..dc8e595d 100755 --- a/src/Daemon/abrt-debuginfo-install +++ b/src/Daemon/abrt-debuginfo-install @@ -80,22 +80,39 @@ 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 +print_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` + done +} + +print_missing_debuginfos() { + 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 + fi + test -f "/$file" && continue + echo -n "/$file " + done +} + +cleanup_and_report_missing() { +# Which debuginfo files are still missing, including those we just unpacked? + missing_build_ids=`print_missing_build_ids` $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" + $debug || -rf "$tempdir" fi for missing in $missing_build_ids; do @@ -105,6 +122,98 @@ cleanup_and_report_missing() { test x"$missing_build_ids" != x"" && echo "`count_words $missing_build_ids` debuginfos can't be found" } +# $1: iteration (1,2...) +print_package_names() { + # We'll run something like: + # yum --enablerepo='*debuginfo*' --quiet provides \ + # /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \ + # /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ... + local yumopts="" + if test x"$1" = x"1"; then + yumopts="-C" + echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list from cache" >&2 + else + echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list" >&2 + fi + local cmd="yum $yumopts --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files 2>&1" + echo "$cmd" >"yum_provides.$1.OUT" + local yum_provides_OUT=`$cmd` + local err=$? + printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >>"yum_provides.$1.OUT" + test $err = 0 || exit 2 + + # The output is pretty machine-unfriendly: + # glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc + # Repo : rawhide-debuginfo + # Matched from: + # Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug + # + # 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus + # Repo : updates-debuginfo + # Matched from: + # Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug + # Need to massage it a lot. + # There can be duplicates (one package may provide many debuginfos). + printf "%s\n" "$yum_provides_OUT" \ + | grep -- -debuginfo- \ + | sed 's/^[0-9]*://' \ + | sed -e 's/ .*//' -e 's/:.*//' \ + | sort | uniq | xargs +} + +download_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) + # In this case, $f is the literal "*.rpm" string + test -f "$f" || exit 2 + echo "Unpacking: $f" + echo "Processing: $f" >>unpack.OUT + rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1 + done + + # Copy debuginfo files to cachedir + if test x"$cachedir" != x"" && test -d "$cachedir"; then + for build_id in $build_ids; do + build_id1=${build_id:0:2} + build_id2=${build_id:2} + + file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + + 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 Copying2 "$file" to "$cachedir/$file" >&2 + cp --remove-destination "$file" "$cachedir/$file" + continue + fi + done + fi +} + # eu-unstrip output example: # 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe] @@ -138,113 +247,39 @@ build_ids=`printf "%s\n" "$eu_unstrip_OUT" \ done | sort | uniq | xargs` $debug && echo "build_ids:$build_ids" -# Which debuginfo files are missing? -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 - fi - test -f "/$file" && continue - echo -n "/$file " -done` -$debug && echo "missing_debuginfo_files:$missing_debuginfo_files" - -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 \ -# /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \ -# /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ... -echo "Determining list of packages for `count_words $missing_debuginfo_files` missing debuginfos" -yum_provides_OUT=`yum --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files 2>&1` -err=$? -printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >yum_provides.OUT -test $err = 0 || exit 2 +# We try to not run yum without -C unless absolutely necessary. +# Therefore we loop. yum is run by print_package_names function, +# on first iteration it is run with -C, on second - without, +# which usually causes yum to download updated filelists, +# which in turn takes several minutes and annoys users. +iter=0 +while true; do + : $((iter++)) + test $iter -gt 2 && break -# The output is pretty machine-unfriendly: -# glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc -# Repo : rawhide-debuginfo -# Matched from: -# Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug -# -# 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus -# Repo : updates-debuginfo -# Matched from: -# Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug -# Need to massage it a lot. -# There can be duplicates (one package may provide many debuginfos). -packages=`printf "%s\n" "$yum_provides_OUT" \ -| grep -- -debuginfo- \ -| sed 's/^[0-9]*://' \ -| sed -e 's/ .*//' -e 's/:.*//' \ -| sort | uniq | xargs` -$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). -if test x"$packages" = x""; then - cleanup_and_report_missing - exit 1 -fi - -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 + # Analyze $build_ids and check which debuginfos are present + missing_debuginfo_files=`print_missing_debuginfos` + $debug && echo "missing_debuginfo_files:$missing_debuginfo_files" -for f in *.rpm; do - # Happens if no .rpm's were downloaded (yumdownloader problem) - # In this case, $f is the literal "*.rpm" string - test -f "$f" || exit 2 - echo "Unpacking: $f" - echo "Processing: $f" >>unpack.OUT - rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1 -done + if test x"$missing_debuginfo_files" = x""; then + break + fi -# 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} + # Map $missing_debuginfo_files to package names. + # yum is run here. + packages=`print_package_names $iter` + $debug && echo "packages ($iter):$packages" - file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" + # yum may return "" here if it found no packages (say, if coredump + # is from a new, unreleased package fresh from koji). + if test x"$packages" = x""; then + continue + fi - 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 Copying2 "$file" to "$cachedir/$file" >&2 - cp --remove-destination "$file" "$cachedir/$file" - continue - fi - done -fi -$debug && echo "missing_build_ids:$missing_build_ids" + num_packages=`count_words $packages` + echo "Downloading $num_packages packages" + download_packages +done cleanup_and_report_missing diff --git a/src/Daemon/abrt.conf b/src/Daemon/abrt.conf index a02cef44..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 +# Blacklisted packages BlackList = nspluginwrapper -# enabled plugins -# there has to be exactly one database plugin +# 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/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py index d3a3abd0..31ebb410 100644 --- a/src/Gui/CCMainWindow.py +++ b/src/Gui/CCMainWindow.py @@ -88,7 +88,7 @@ class MainWindow(): columns[0] = gtk.TreeViewColumn(_("Package")) columns[1] = gtk.TreeViewColumn(_("Application")) columns[2] = gtk.TreeViewColumn(_("Date")) - columns[3] = gtk.TreeViewColumn(_("Crash Rate")) + columns[3] = gtk.TreeViewColumn(_("Crash count")) if os.getuid() == 0: column = gtk.TreeViewColumn(_("User")) columns.append(column) diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py index 9207a3e5..61e65526 100644 --- a/src/Gui/CCReporterDialog.py +++ b/src/Gui/CCReporterDialog.py @@ -43,6 +43,10 @@ class ReporterDialog(): self.tvComment = self.wTree.get_widget("tvComment") self.tvComment.connect("focus-in-event", self.on_comment_focus_cb) self.comment_changed = False + + # "how to reproduce" textview + self.tevHowToReproduce = self.wTree.get_widget("tevHowToReproduce") + self.how_to_changed = False self.tvReport = self.wTree.get_widget("tvReport") @@ -76,6 +80,8 @@ class ReporterDialog(): # connect the signals self.tvReport.connect_after("size-allocate", self.on_window_resize) self.wTree.get_widget("bSend").connect("clicked", self.on_send_clicked) + # start with the warning hidden, so it's not visible when there is no rating + self.wTree.get_widget("ebErrors").hide() self.hydrate() # this callback is called when user press Cancel or Report button in Report dialog @@ -180,6 +186,50 @@ class ReporterDialog(): self.tvComment.set_buffer(buff) continue + if item == "How to reproduce": + buff = gtk.TextBuffer() + how_to_reproduce = _("") + try: + if self.report[item][CONTENT]: + how_to_reproduce = self.report[item][CONTENT] + self.how_to_changed = True + except Exception, e: + pass + + buff.set_text(how_to_reproduce) + + self.tevHowToReproduce.set_buffer(buff) + continue + # if an backtrace has rating use it + if item == "rating": + try: + package = self.report["package"][CONTENT] + # if we don't have package for some reason + except: + package = None + ebErrors = self.wTree.get_widget("ebErrors") + lErrors = self.wTree.get_widget("lErrors") + bSend = self.wTree.get_widget("bSend") + # not usable report + if int(self.report[item][CONTENT]) < 3: + ebErrors.show() + ebErrors.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) + if package: + lErrors.set_markup( + "<span color=\"white\">%s</span>" % _("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command:<span color=\"blue\"> debuginfo-install %s </span>\nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) + else: + lErrors.set_markup("<span color=\"white\">%s</span>" % _("The bactrace is unusable, you can't report this!")) + bSend.set_sensitive(False) + # probably usable 3 + elif int(self.report[item][CONTENT]) < 4: + ebErrors.show() + ebErrors.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("yellow")) + lErrors.set_markup("<span color=\"black\">%s</span>" % _("The bactrace is incomplete, please make sure you provide good steps to reproduce.")) + bSend.set_sensitive(True) + else: + ebErrors.hide() + bSend.set_sensitive(True) + if self.report[item][TYPE] != 's': # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 if self.report[item][EDITABLE] == 'y': @@ -200,11 +250,18 @@ class ReporterDialog(): self.report[rowe["item"]][CONTENT] = rowe["content"] else: del self.report[rowe["item"]] + # handle comment if self.comment_changed: buff = self.tvComment.get_buffer() self.report["Comment"] = ['t', 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] else: del self.report["Comment"] + # handle how to reproduce + if self.how_to_changed: + buff = self.tevHowToReproduce.get_buffer() + self.report["How to reproduce"] = ['t', 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] + else: + del self.report["How to reproduce"] def on_send_clicked(self, button): #def on_apply_clicked(self, button, treeview): diff --git a/src/Gui/report.glade b/src/Gui/report.glade index 9b582b22..ce21acb1 100644 --- a/src/Gui/report.glade +++ b/src/Gui/report.glade @@ -13,10 +13,12 @@ <child internal-child="vbox"> <widget class="GtkVBox" id="dialog-vbox4"> <property name="visible">True</property> + <property name="orientation">vertical</property> <property name="spacing">2</property> <child> <widget class="GtkVBox" id="vbox5"> <property name="visible">True</property> + <property name="orientation">vertical</property> <child> <widget class="GtkLabel" id="label10"> <property name="visible">True</property> @@ -44,14 +46,78 @@ <property name="position">1</property> </packing> </child> + <child> + <widget class="GtkEventBox" id="ebErrors"> + <property name="visible">True</property> + <child> + <widget class="GtkLabel" id="lErrors"> + <property name="visible">True</property> + <property name="label" translatable="yes"> </property> + <property name="use_markup">True</property> + </widget> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> </widget> <packing> <property name="position">0</property> </packing> </child> <child> + <widget class="GtkVBox" id="vbox2"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <widget class="GtkEventBox" id="eventbox2"> + <property name="visible">True</property> + <child> + <widget class="GtkLabel" id="lHowToReproduce"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="ypad">2</property> + <property name="label" translatable="yes">How to reproduce (in a few simple steps)</property> + </widget> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">never</property> + <property name="vscrollbar_policy">automatic</property> + <child> + <widget class="GtkTextView" id="tevHowToReproduce"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="wrap_mode">word</property> + </widget> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> + <child> <widget class="GtkVBox" id="vbox1"> <property name="visible">True</property> + <property name="orientation">vertical</property> <child> <widget class="GtkEventBox" id="eventbox1"> <property name="visible">True</property> @@ -91,7 +157,7 @@ </widget> <packing> <property name="expand">False</property> - <property name="position">2</property> + <property name="position">3</property> </packing> </child> <child internal-child="action_area"> @@ -100,7 +166,7 @@ <property name="layout_style">end</property> <child> <widget class="GtkButton" id="bCancel"> - <property name="label" translatable="yes">gtk-cancel</property> + <property name="label">gtk-cancel</property> <property name="response_id">-6</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -108,12 +174,14 @@ <property name="use_stock">True</property> </widget> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> <widget class="GtkButton" id="bRefresh"> - <property name="label" translatable="yes">gtk-refresh</property> + <property name="label">gtk-refresh</property> <property name="response_id">-50</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -121,6 +189,8 @@ <property name="use_stock">True</property> </widget> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> @@ -133,6 +203,8 @@ <property name="receives_default">True</property> </widget> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child> diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index 1c152e6c..0f95d05b 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -188,7 +188,7 @@ int main(int argc, char** argv) 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_str); + dd.SaveText(FILENAME_REASON, ssprintf("Process was terminated by signal %s", signal_str).c_str()); int len = strlen(path); snprintf(path + len, sizeof(path) - len, "/"FILENAME_COREDUMP); @@ -221,7 +221,7 @@ int main(int argc, char** argv) } catch (CABRTException& e) { - error_msg_and_die("%s", e.what().c_str()); + error_msg_and_die("%s", e.what()); } catch (std::exception& e) { |