summaryrefslogtreecommitdiffstats
path: root/src/Daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/Daemon')
-rw-r--r--src/Daemon/CrashWatcher.cpp953
-rw-r--r--src/Daemon/CrashWatcher.h146
-rw-r--r--src/Daemon/Daemon.cpp1062
-rw-r--r--src/Daemon/Makefile.am1
4 files changed, 1056 insertions, 1106 deletions
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
deleted file mode 100644
index bd45c5f9..00000000
--- a/src/Daemon/CrashWatcher.cpp
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
- Copyright (C) 2009 RedHat inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include "abrtlib.h"
-#include "CrashWatcher.h"
-#include <iostream>
-#include <climits>
-#include <cstdlib>
-#include <cstring>
-#include <csignal>
-#include <sstream>
-#include <cstring>
-#include "ABRTException.h"
-
-#define VAR_RUN_LOCK_FILE VAR_RUN"/abrt.lock"
-#define VAR_RUN_PIDFILE VAR_RUN"/abrt.pid"
-
-/* just a helper function
-template< class T >
-std::string
-to_string( T x )
-{
- std::ostringstream o;
- o << x;
- return o.str();
-}
-*/
-
-/* 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);
-
-gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer daemon)
-{
- GIOError err;
- char *buf = new char[INOTIFY_BUFF_SIZE];
- gsize len;
- gsize i = 0;
- err = g_io_channel_read(gio, buf, INOTIFY_BUFF_SIZE, &len);
- CCrashWatcher *cc = (CCrashWatcher*)daemon;
- if (err != G_IO_ERROR_NONE)
- {
- cc->Warning("Error reading inotify fd.");
- delete[] buf;
- return FALSE;
- }
- /* reconstruct each event and send message to the dbus */
- while (i < len)
- {
- const char *name = NULL;
- struct inotify_event *event;
-
- event = (struct inotify_event *) &buf[i];
- if (event->len)
- name = &buf[i] + sizeof (struct inotify_event);
- i += sizeof (struct inotify_event) + event->len;
-
- cc->Debug(std::string("Created file: ") + name);
-
- /* we want to ignore the lock files */
- if (event->mask & IN_ISDIR)
- {
- if (GetDirSize(DEBUG_DUMPS_DIR) / (1024*1024) < cc->m_pSettings->GetMaxCrashReportsSize())
- {
- //std::string sName = name;
- map_crash_info_t crashinfo;
- try
- {
- CMiddleWare::mw_result_t res;
- res = cc->m_pMW->SaveDebugDump(std::string(DEBUG_DUMPS_DIR) + "/" + name, crashinfo);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- cc->Debug("New crash, saving...");
- cc->m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
- /* send message to dbus */
- cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
- break;
- case CMiddleWare::MW_REPORTED:
- case CMiddleWare::MW_OCCURED:
- /* send message to dbus */
- cc->Debug("Already saved crash, deleting...");
- cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- break;
- case CMiddleWare::MW_BLACKLISTED:
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_PACKAGE_ERROR:
- case CMiddleWare::MW_GPG_ERROR:
- case CMiddleWare::MW_IN_DB:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- cc->Warning("Corrupted or bad crash, deleting...");
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- break;
- }
- }
- catch (CABRTException& e)
- {
- cc->Warning(e.what());
- if (e.type() == EXCEP_FATAL)
- {
- delete[] buf;
- return -1;
- }
- }
- catch (...)
- {
- delete[] buf;
- throw;
- }
- }
- else
- {
- cc->Debug(std::string("DebugDumps size has exceeded the limit, deleting the last dump: ") + name);
- cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
- }
- }
- else
- {
- cc->Debug("Some file created, ignoring...");
- }
- }
- delete[] buf;
- return TRUE;
-}
-
-void *CCrashWatcher::create_report(void *arg)
-{
- thread_data_t *thread_data = (thread_data_t *) arg;
- map_crash_info_t crashReport;
- thread_data->daemon->Debug("Creating report...");
- try
- {
- CMiddleWare::mw_result_t res;
- res = thread_data->daemon->m_pMW->CreateCrashReport(thread_data->UUID,thread_data->UID,crashReport);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- break;
- case CMiddleWare::MW_IN_DB_ERROR:
- thread_data->daemon->Warning(std::string("Did not find crash with UUID ")+thread_data->UUID+ " in database.");
- break;
- case CMiddleWare::MW_PLUGIN_ERROR:
- thread_data->daemon->Warning(std::string("Particular analyzer plugin isn't loaded or there is an error within plugin(s)."));
- break;
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- {
- std::string debugDumpDir;
- thread_data->daemon->Warning(std::string("Corrupted crash with UUID ")+thread_data->UUID+", deleting.");
- debugDumpDir = thread_data->daemon->m_pMW->DeleteCrashInfo(thread_data->UUID, thread_data->UID);
- thread_data->daemon->m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- break;
- }
- /* only one thread can write */
- pthread_mutex_lock(&(thread_data->daemon->m_pJobsMutex));
- thread_data->daemon->pending_jobs[std::string(thread_data->UID)][thread_data->thread_id] = crashReport;
- pthread_mutex_unlock(&(thread_data->daemon->m_pJobsMutex));
- thread_data->daemon->m_pCommLayer->JobDone(thread_data->dest, thread_data->thread_id);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- /* free strduped strings */
- free(thread_data->UUID);
- free(thread_data->UID);
- free(thread_data->dest);
- free(thread_data);
- throw e;
- }
- thread_data->daemon->Warning(e.what());
- }
- /* free strduped strings */
- free(thread_data->UUID);
- free(thread_data->UID);
- free(thread_data->dest);
- free(thread_data);
-
- /* Bogus value. pthreads require us to return void* */
- return NULL;
-}
-
-gboolean CCrashWatcher::cron_activation_periodic_cb(gpointer data)
-{
- cron_callback_data_t* cronPeriodicCallbackData = static_cast<cron_callback_data_t*>(data);
- cronPeriodicCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronPeriodicCallbackData->m_sPluginName);
- cronPeriodicCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronPeriodicCallbackData->m_pCrashWatcher->m_sTarget,
- cronPeriodicCallbackData->m_sPluginName,
- cronPeriodicCallbackData->m_sPluginArgs);
- return TRUE;
-}
-gboolean CCrashWatcher::cron_activation_one_cb(gpointer data)
-{
- cron_callback_data_t* cronOneCallbackData = static_cast<cron_callback_data_t*>(data);
- cronOneCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronOneCallbackData->m_sPluginName);
- cronOneCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronOneCallbackData->m_pCrashWatcher->m_sTarget,
- cronOneCallbackData->m_sPluginName,
- cronOneCallbackData->m_sPluginArgs);
- return FALSE;
-}
-gboolean CCrashWatcher::cron_activation_reshedule_cb(gpointer data)
-{
- cron_callback_data_t* cronResheduleCallbackData = static_cast<cron_callback_data_t*>(data);
- cronResheduleCallbackData->m_pCrashWatcher->Debug("Rescheduling plugin: " + cronResheduleCallbackData->m_sPluginName);
- cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(cronResheduleCallbackData->m_pCrashWatcher,
- cronResheduleCallbackData->m_sPluginName,
- cronResheduleCallbackData->m_sPluginArgs,
- cronResheduleCallbackData->m_nTimeout);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- cronPeriodicCallbackData->m_nTimeout,
- cron_activation_periodic_cb,
- static_cast<gpointer>(cronPeriodicCallbackData),
- cron_delete_callback_data_cb);
-
-
- return FALSE;
-}
-
-void CCrashWatcher::cron_delete_callback_data_cb(gpointer data)
-{
- cron_callback_data_t* cronDeleteCallbackData = static_cast<cron_callback_data_t*>(data);
- delete cronDeleteCallbackData;
-}
-
-void CCrashWatcher::SetUpMW()
-{
- m_pMW->SetOpenGPGCheck(m_pSettings->GetOpenGPGCheck());
- m_pMW->SetDatabase(m_pSettings->GetDatabase());
- CSettings::set_strings_t openGPGPublicKeys = m_pSettings->GetOpenGPGPublicKeys();
- CSettings::set_strings_t::iterator it_k;
- for (it_k = openGPGPublicKeys.begin(); it_k != openGPGPublicKeys.end(); it_k++)
- {
- m_pMW->AddOpenGPGPublicKey(*it_k);
- }
- CSettings::set_strings_t blackList = m_pSettings->GetBlackList();
- CSettings::set_strings_t::iterator it_b;
- for (it_b = blackList.begin(); it_b != blackList.end(); it_b++)
- {
- m_pMW->AddBlackListedPackage(*it_b);
- }
- CSettings::set_strings_t enabledPlugins = m_pSettings->GetEnabledPlugins();
- CSettings::set_strings_t::iterator it_p;
- for (it_p = enabledPlugins.begin(); it_p != enabledPlugins.end(); it_p++)
- {
- m_pMW->RegisterPlugin(*it_p);
- }
- CSettings::vector_pair_strings_t actionsAndReporters = m_pSettings->GetActionsAndReporters();
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = actionsAndReporters.begin(); it_ar != actionsAndReporters.end(); it_ar++)
- {
- m_pMW->AddActionOrReporter((*it_ar).first, (*it_ar).second);
- }
-
- CSettings::map_analyzer_actions_and_reporters_t analyzerActionsAndReporters = m_pSettings->GetAnalyzerActionsAndReporters();
- CSettings::map_analyzer_actions_and_reporters_t::iterator it_aar;
- for (it_aar = analyzerActionsAndReporters.begin(); it_aar != analyzerActionsAndReporters.end(); it_aar++)
- {
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_aar->second.begin(); it_ar != it_aar->second.end(); it_ar++)
- {
- m_pMW->AddAnalyzerActionOrReporter(it_aar->first, (*it_ar).first, (*it_ar).second);
- }
- }
-}
-
-void CCrashWatcher::SetUpCron()
-{
- CSettings::map_cron_t cron = m_pSettings->GetCron();
- CSettings::map_cron_t::iterator it_c;
- for (it_c = cron.begin(); it_c != cron.end(); it_c++)
- {
- std::string::size_type pos = it_c->first.find(":");
- int timeout = 0;
- int nH = -1;
- int nM = -1;
- int nS = -1;
-
- if (pos != std::string::npos)
- {
- std::string sH = "";
- std::string sM = "";
-
- sH = it_c->first.substr(0, pos);
- nH = atoi(sH.c_str());
- nH = nH > 23 ? 23 : nH;
- nH = nH < 0 ? 0 : nH;
- nM = nM > 59 ? 59 : nM;
- nM = nM < 0 ? 0 : nM;
- timeout += nH * 60 * 60;
- sM = it_c->first.substr(pos + 1);
- nM = atoi(sM.c_str());
- timeout += nM * 60;
- }
- else
- {
- std::string sS = "";
-
- sS = it_c->first;
- nS = atoi(sS.c_str());
- nS = nS <= 0 ? 1 : nS;
- timeout = nS;
- }
-
- if (nS != -1)
- {
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
- {
-
- cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(this, (*it_ar).first, (*it_ar).second, timeout);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- timeout,
- cron_activation_periodic_cb,
- static_cast<gpointer>(cronPeriodicCallbackData),
- cron_delete_callback_data_cb);
- }
- }
- else
- {
- time_t actTime = time(NULL);
- if (actTime == ((time_t)-1))
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get time.");
- }
- struct tm locTime;
- if (localtime_r(&actTime, &locTime) == NULL)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get local time.");
- }
- locTime.tm_hour = nH;
- locTime.tm_min = nM;
- locTime.tm_sec = 0;
- time_t nextTime = mktime(&locTime);
- if (nextTime == ((time_t)-1))
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot set up time.");
- }
- if (actTime > nextTime)
- {
- timeout = 24*60*60 + (nextTime - actTime);
- }
- else
- {
- timeout = nextTime - actTime;
- }
- CSettings::vector_pair_strings_t::iterator it_ar;
- for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
- {
-
- cron_callback_data_t* cronOneCallbackData = new cron_callback_data_t(this, (*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(this, (*it_ar).first, (*it_ar).second, 24 * 60 * 60);
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
- timeout,
- cron_activation_reshedule_cb,
- static_cast<gpointer>(cronResheduleCallbackData),
- cron_delete_callback_data_cb);
- }
- }
- }
-}
-
-void CCrashWatcher::Status(const std::string& pMessage, const std::string& pDest)
-{
- std::cout << "Update: " + pMessage << std::endl;
- //FIXME: send updates only to job owner
- if(m_pCommLayer != NULL)
- m_pCommLayer->Update(pDest,pMessage);
-}
-
-void CCrashWatcher::Warning(const std::string& pMessage, const std::string& pDest)
-{
- std::cerr << "Warning: " + pMessage << std::endl;
- if(m_pCommLayer != NULL)
- m_pCommLayer->Warning(pDest,pMessage);
-}
-
-void CCrashWatcher::Debug(const std::string& pMessage, const std::string& pDest)
-{
- //some logic to add logging levels?
- std::cout << "Debug: " + pMessage << std::endl;
-}
-
-static double GetDirSize(const std::string &pPath)
-{
- double size = 0;
- struct dirent *ep;
- struct stat stats;
- DIR *dp;
-
- dp = opendir(pPath.c_str());
- if (dp != NULL)
- {
- while ((ep = readdir(dp)) != NULL)
- {
- if (dot_or_dotdot(ep->d_name))
- continue;
- std::string dname = pPath + "/" + ep->d_name;
- if (lstat(dname.c_str(), &stats) == 0)
- {
- if (S_ISDIR(stats.st_mode))
- {
- size += GetDirSize(dname);
- }
- else if (S_ISREG(stats.st_mode))
- {
- size += stats.st_size;
- }
- }
- }
- closedir(dp);
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, std::string(__func__) + ": Init Failed");
- }
- return size;
-}
-
-CCrashWatcher::CCrashWatcher(const std::string& pPath)
-{
- int watch = 0;
- m_sTarget = pPath;
-
- // TODO: initialize object according parameters -w -d
- // status has to be always created.
- m_pCommLayer = NULL;
- comm_layer_inner_init(this);
-
- m_pSettings = new CSettings();
- m_pSettings->LoadSettings(std::string(CONF_DIR) + "/abrt.conf");
-
- m_pMainloop = g_main_loop_new(NULL,FALSE);
- m_pMW = new CMiddleWare(PLUGINS_CONF_DIR,PLUGINS_LIB_DIR);
- if (pthread_mutex_init(&m_pJobsMutex, NULL) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't init mutex!");
- }
- try
- {
- SetUpMW();
- SetUpCron();
- FindNewDumps(pPath);
-#ifdef ENABLE_DBUS
- m_pCommLayer = new CCommLayerServerDBus();
-#elif ENABLE_SOCKET
- m_pCommLayer = new CCommLayerServerSocket();
-#endif
-// m_pCommLayer = new CCommLayerServerDBus();
-// m_pCommLayer = new CCommLayerServerSocket();
- m_pCommLayer->Attach(this);
-
- if ((m_nFd = inotify_init()) == -1)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Init Failed");
- }
- if ((watch = inotify_add_watch(m_nFd, pPath.c_str(), IN_CREATE)) == -1)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Add watch failed:" + pPath);
- }
- m_pGio = g_io_channel_unix_new(m_nFd);
- }
- catch (...)
- {
- /* This restores /proc/sys/kernel/core_pattern, among other things */
- delete m_pMW;
- //too? delete m_pCommLayer;
- throw;
- }
-}
-
-CCrashWatcher::~CCrashWatcher()
-{
- //delete dispatcher, connection, etc..
- //m_pConn->disconnect();
-
- g_io_channel_unref(m_pGio);
- g_main_loop_unref(m_pMainloop);
-
- delete m_pCommLayer;
- delete m_pMW;
- delete m_pSettings;
- if (pthread_mutex_destroy(&m_pJobsMutex) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't destroy mutex!");
- }
- /* delete pid file */
- unlink(VAR_RUN_PIDFILE);
- /* delete lock file */
- unlink(VAR_RUN_LOCK_FILE);
-}
-
-void CCrashWatcher::FindNewDumps(const std::string& pPath)
-{
- Debug("Scanning for unsaved entries...");
- struct dirent *ep;
- struct stat stats;
- DIR *dp;
- std::vector<std::string> dirs;
- std::string dname;
- // get potential unsaved debugdumps
- dp = opendir(pPath.c_str());
- if (dp != NULL)
- {
- while ((ep = readdir(dp)))
- {
- if (dot_or_dotdot(ep->d_name))
- continue;
- dname = pPath + "/" + ep->d_name;
- if (lstat(dname.c_str(), &stats) == 0)
- {
- if (S_ISDIR(stats.st_mode))
- {
- dirs.push_back(dname);
- }
- }
- }
- (void) closedir(dp);
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::FindNewDumps(): Couldn't open the directory:" + pPath);
- }
-
- for (std::vector<std::string>::iterator itt = dirs.begin(); itt != dirs.end(); ++itt){
- map_crash_info_t crashinfo;
- try
- {
- CMiddleWare::mw_result_t res;
- res = m_pMW->SaveDebugDump(*itt, crashinfo);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- Debug("Saving into database (" + *itt + ").");
- m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
- break;
- case CMiddleWare::MW_IN_DB:
- Debug("Already saved in database (" + *itt + ").");
- break;
- case CMiddleWare::MW_REPORTED:
- case CMiddleWare::MW_OCCURED:
- case CMiddleWare::MW_BLACKLISTED:
- case CMiddleWare::MW_CORRUPTED:
- case CMiddleWare::MW_PACKAGE_ERROR:
- case CMiddleWare::MW_GPG_ERROR:
- case CMiddleWare::MW_FILE_ERROR:
- default:
- Warning("Corrupted, bad or already saved crash, deleting.");
- m_pMW->DeleteDebugDumpDir(*itt);
- break;
- }
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
- }
-}
-void CCrashWatcher::CreatePidFile()
-{
- int fd;
-
- /* JIC */
- unlink(VAR_RUN_PIDFILE);
-
- /* open the pidfile */
- fd = open(VAR_RUN_PIDFILE, O_WRONLY|O_CREAT|O_EXCL, 0644);
- if (fd >= 0)
- {
- /* write our pid to it */
- char buf[sizeof(int)*3 + 2];
- int len = sprintf(buf, "%u\n", (unsigned)getpid());
- write(fd, buf, len);
- close(fd);
- return;
- }
-
- /* something went wrong */
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreatePidFile(): can not open pid file");
-}
-
-void CCrashWatcher::Lock()
-{
- int lfp = open(VAR_RUN_LOCK_FILE, O_RDWR|O_CREAT, 0640);
- if (lfp < 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): can not open lock file");
- }
- if (lockf(lfp, F_TLOCK, 0) < 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): cannot create lock on lockfile");
- }
- /* only first instance continues */
- //sprintf(str,"%d\n",getpid());
- //write(lfp,str,strlen(str)); /* record pid to lockfile */
-}
-
-void CCrashWatcher::StartWatch()
-{
- char *buff = new char[INOTIFY_BUFF_SIZE];
- int len = 0;
- int i = 0;
- char action[FILENAME_MAX];
- struct inotify_event *pevent;
- //run forever
- while (1)
- {
- i = 0;
- len = read(m_nFd,buff,INOTIFY_BUFF_SIZE);
- while (i < len)
- {
- pevent = (struct inotify_event *)&buff[i];
- if (pevent->len)
- {
- std::strcpy(action, pevent->name);
- }
- else
- {
- std::strcpy(action, m_sTarget.c_str());
- }
-
- i += sizeof(struct inotify_event) + pevent->len;
- Debug(std::string("Created file: ") + action);
- }
- }
- delete[] buff;
-}
-
-extern uint8_t sig_caught;
-//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.
-typedef struct SignalSource
-{
- GSource src;
- CCrashWatcher* watcher;
-} SignalSource;
-static gboolean waitsignal_prepare(GSource *source, gint *timeout_)
-{
- /* We depend on the fact that in Unix, poll() is interrupted
- * by caught signals (returns EINTR). Thus we do not need to set
- * a small timeout here: infinite timeout (-1) works too */
- *timeout_ = -1;
- return sig_caught != 0;
-}
-static gboolean waitsignal_check(GSource *source)
-{
- return sig_caught != 0;
-}
-static gboolean waitsignal_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
-{
- SignalSource *ssrc = (SignalSource*) source;
- ssrc->watcher->StopRun();
- return 1;
-}
-
-/* daemon loop with glib */
-void CCrashWatcher::GStartWatch()
-{
- g_io_add_watch(m_pGio, G_IO_IN, handle_event_cb, this);
-
- 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
- SignalSource *waitsignal_src = (SignalSource*) g_source_new(&waitsignal_funcs, sizeof(*waitsignal_src));
- waitsignal_src->watcher = this;
- g_source_attach(&waitsignal_src->src, g_main_context_default());
-
- //enter the event loop
- g_main_run(m_pMainloop);
-}
-
-void CCrashWatcher::Run()
-{
- Debug("Running...");
- Lock();
- CreatePidFile();
- GStartWatch();
-}
-
-void CCrashWatcher::StopRun()
-{
- g_main_quit(m_pMainloop);
-}
-
-vector_crash_infos_t CCrashWatcher::GetCrashInfos(const std::string &pUID)
-{
- vector_crash_infos_t retval;
- Debug("Getting crash infos...");
- try
- {
- vector_pair_string_string_t UUIDsUIDs;
- UUIDsUIDs = m_pMW->GetUUIDsOfCrash(pUID);
-
- unsigned int ii;
- for (ii = 0; ii < UUIDsUIDs.size(); ii++)
- {
- CMiddleWare::mw_result_t res;
- map_crash_info_t info;
-
- res = m_pMW->GetCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second, info);
- switch (res)
- {
- case CMiddleWare::MW_OK:
- retval.push_back(info);
- break;
- case CMiddleWare::MW_ERROR:
- Warning("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- Status("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
- m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
- break;
- case CMiddleWare::MW_FILE_ERROR:
- {
- std::string debugDumpDir;
- Warning("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
- Status("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
- debugDumpDir = m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
- m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- break;
- default:
- break;
- }
- }
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- }
-
- //retval = m_pMW->GetCrashInfos(pUID);
- //Notify("Sent crash info");
- return retval;
-}
-
-uint64_t CCrashWatcher::CreateReport_t(const std::string &pUUID,const std::string &pUID, const std::string &pSender)
-{
- thread_data_t *thread_data = (thread_data_t *)xzalloc(sizeof(thread_data_t));
- if (thread_data != NULL)
- {
- thread_data->UUID = xstrdup(pUUID.c_str());
- thread_data->UID = xstrdup(pUID.c_str());
- thread_data->dest = xstrdup(pSender.c_str());
- thread_data->daemon = this;
- if (pthread_create(&(thread_data->thread_id), NULL, create_report, (void *)thread_data) != 0)
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot create thread!");
- }
- }
- else
- {
- throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot allocate memory!");
- }
- //FIXME: we don't use this value anymore, so fix the API
- return 0;
-}
-
-CMiddleWare::report_status_t CCrashWatcher::Report(map_crash_report_t pReport, const std::string& pUID)
-{
- //#define FIELD(X) crashReport.m_s##X = pReport[#X];
- //crashReport.m_sUUID = pReport["UUID"];
- //ALL_CRASH_REPORT_FIELDS;
- //#undef FIELD
- //for (dbus_map_report_info_t::iterator it = pReport.begin(); it!=pReport.end(); ++it) {
- // std::cerr << it->second << std::endl;
- //}
- CMiddleWare::report_status_t rs;
- try
- {
- rs = m_pMW->Report(pReport, pUID);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- return rs;
- }
- return rs;
-}
-
-bool CCrashWatcher::DeleteDebugDump(const std::string& pUUID, const std::string& pUID)
-{
- try
- {
- std::string debugDumpDir;
- debugDumpDir = m_pMW->DeleteCrashInfo(pUUID,pUID);
- m_pMW->DeleteDebugDumpDir(debugDumpDir);
- }
- catch (CABRTException& e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- Status(e.what());
- return false;
- }
- return true;
-}
-
-map_crash_report_t CCrashWatcher::GetJobResult(uint64_t pJobID, const std::string& pSender)
-{
- /* FIXME: once we return the result, we should remove it from map to free memory
- - use some TTL to clean the memory even if client won't get it
- - if we don't find it in the cache we should try to ask MW to get it again??
- */
- return pending_jobs[pSender][pJobID];
-}
-
-vector_map_string_string_t CCrashWatcher::GetPluginsInfo()
-{
- try
- {
- return m_pMW->GetPluginsInfo();
- }
- catch (CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
- // TODO: is it right? I added it just to disable a warning...
- // but maybe returning empty map is wrong here?
- return vector_map_string_string_t();
-}
-
-map_plugin_settings_t CCrashWatcher::GetPluginSettings(const std::string& pName, const std::string& pUID)
-{
- try
- {
- return m_pMW->GetPluginSettings(pName, pUID);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::RegisterPlugin(const std::string& pName)
-{
- try
- {
- m_pMW->RegisterPlugin(pName);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::UnRegisterPlugin(const std::string& pName)
-{
- try
- {
- m_pMW->UnRegisterPlugin(pName);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
-
-void CCrashWatcher::SetPluginSettings(const std::string& pName, const std::string& pUID, const map_plugin_settings_t& pSettings)
-{
- try
- {
- m_pMW->SetPluginSettings(pName, pUID, pSettings);
- }
- catch(CABRTException &e)
- {
- if (e.type() == EXCEP_FATAL)
- {
- throw e;
- }
- Warning(e.what());
- }
-}
diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h
deleted file mode 100644
index 23e3da16..00000000
--- a/src/Daemon/CrashWatcher.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
- Copyright (C) 2009 RedHat inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CRASHWATCHER_H_
-#define CRASHWATCHER_H_
-
-#include <string>
-#include <sys/inotify.h>
-#include <sys/inotify.h>
-#include <glib.h>
-#include <pthread.h>
-//#include "DBusManager.h"
-//#include "DBusServerProxy.h"
-#include "MiddleWare.h"
-#include "Settings.h"
-
-//FIXME remove when it gets to autoconf
-//#include "CommLayerServerDBus.h"
-//#include "CommLayerServerSocket.h"
-#ifdef ENABLE_DBUS
- #include "CommLayerServerDBus.h"
-#elif ENABLE_SOCKET
- #include "CommLayerServerSocket.h"
-#endif
-#include "CommLayerInner.h"
-
-// 1024 simultaneous actions
-#define INOTIFY_BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)
-
-class CCrashWatcher
-//: public CDBusServer_adaptor,
-// public DBus::IntrospectableAdaptor,
-// public DBus::ObjectAdaptor,
-: public CObserver
-{
- private:
- //FIXME: add some struct to be able to join all threads!
- typedef struct SCronCallbackData
- {
- CCrashWatcher* m_pCrashWatcher;
- std::string m_sPluginName;
- std::string m_sPluginArgs;
- unsigned int m_nTimeout;
-
- SCronCallbackData(CCrashWatcher* pCrashWatcher,
- const std::string& pPluginName,
- const std::string& pPluginArgs,
- const unsigned int& pTimeout) :
- m_pCrashWatcher(pCrashWatcher),
- m_sPluginName(pPluginName),
- m_sPluginArgs(pPluginArgs),
- m_nTimeout(pTimeout)
- {}
-
- } cron_callback_data_t;
-
- typedef struct SThreadData {
- pthread_t thread_id;
- char* UUID;
- char* UID;
- char *dest;
- CCrashWatcher *daemon;
- } thread_data_t;
-
- /**
- * Map to cache the results from CreateReport_t
- * <UID, <UUID, result>>
- */
- std::map <const std::string, std::map <int, map_crash_report_t > > pending_jobs;
- /**
- * mutex to protect pending_jobs from being accesed by multiple threads at the same time
- */
- pthread_mutex_t m_pJobsMutex;
-
- static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer data);
- static void *create_report(void *arg);
- static gboolean cron_activation_periodic_cb(gpointer data);
- static gboolean cron_activation_one_cb(gpointer data);
- static gboolean cron_activation_reshedule_cb(gpointer data);
- static void cron_delete_callback_data_cb(gpointer data);
-
- void StartWatch();
- void GStartWatch();
- void CreatePidFile();
- void Lock();
- void SetUpMW();
- void SetUpCron();
- /* finds dumps created when daemon wasn't running */
- // FIXME: how to catch abrt itself without this?
- void FindNewDumps(const std::string& pPath);
-
- int m_nFd;
- GIOChannel* m_pGio;
- GMainLoop *m_pMainloop;
- std::string m_sTarget;
- CMiddleWare *m_pMW;
- CCommLayerServer *m_pCommLayer;
- /*FIXME not needed */
- //DBus::Connection *m_pConn;
- CSettings *m_pSettings;
- public:
- //CCrashWatcher(const std::string& pPath,DBus::Connection &connection);
- CCrashWatcher(const std::string& pPath);
- virtual ~CCrashWatcher();
- void Run();
- void StopRun();
-
- /* methods exported on dbus */
- public:
- virtual vector_crash_infos_t GetCrashInfos(const std::string &pUID);
- /*FIXME: fix CLI and remove this stub*/
- virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pUID){map_crash_report_t retval; return retval;};
- uint64_t CreateReport_t(const std::string &pUUID,const std::string &pUID, const std::string &pSender);
- virtual CMiddleWare::report_status_t Report(map_crash_report_t pReport, const std::string &pUID);
- virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pUID);
- virtual map_crash_report_t GetJobResult(uint64_t pJobID, const std::string& pSender);
- /* plugins related */
- virtual vector_map_string_string_t GetPluginsInfo();
- virtual map_plugin_settings_t GetPluginSettings(const std::string& pName, const std::string& pUID);
- void SetPluginSettings(const std::string& pName, const std::string& pUID, const map_plugin_settings_t& pSettings);
- void RegisterPlugin(const std::string& pName);
- void UnRegisterPlugin(const std::string& pName);
-
- /* Observer methods */
- void Status(const std::string& pMessage,const std::string& pDest="0");
- void Debug(const std::string& pMessage, const std::string& pDest="0");
- void Warning(const std::string& pMessage, const std::string& pDest="0");
-};
-
-#endif /*CRASHWATCHER_H_*/
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index 8f08eb64..b40cef7f 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -18,15 +18,1065 @@
*/
#include "abrtlib.h"
-#include "CrashWatcher.h"
+#include <sys/inotify.h>
+#include <glib.h>
+#include <pthread.h>
+
#include "ABRTException.h"
#include <iostream>
-#include <cstdio>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+//#include <sstream>
+#include <string>
+
+//#include "DBusManager.h"
+//#include "DBusServerProxy.h"
+#include "MiddleWare.h"
+#include "Settings.h"
+
+//FIXME remove when it gets to autoconf
+//#include "CommLayerServerDBus.h"
+//#include "CommLayerServerSocket.h"
+#ifdef ENABLE_DBUS
+ #include "CommLayerServerDBus.h"
+#elif ENABLE_SOCKET
+ #include "CommLayerServerSocket.h"
+#endif
+#include "CommLayerInner.h"
+
+// 1024 simultaneous actions
+#define INOTIFY_BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)
+
+#define VAR_RUN_LOCK_FILE VAR_RUN"/abrt.lock"
+#define VAR_RUN_PIDFILE VAR_RUN"/abrt.pid"
+
+static uint8_t sig_caught; /* = 0 */
+
+
+/* CCrashWatcher interface */
+
+namespace { /* make it all static */
+
+class CCrashWatcher
+//: public CDBusServer_adaptor,
+// public DBus::IntrospectableAdaptor,
+// public DBus::ObjectAdaptor,
+: public CObserver
+{
+ private:
+ //FIXME: add some struct to be able to join all threads!
+ typedef struct SCronCallbackData
+ {
+ CCrashWatcher* m_pCrashWatcher;
+ std::string m_sPluginName;
+ std::string m_sPluginArgs;
+ unsigned int m_nTimeout;
+
+ SCronCallbackData(CCrashWatcher* pCrashWatcher,
+ const std::string& pPluginName,
+ const std::string& pPluginArgs,
+ const unsigned int& pTimeout) :
+ m_pCrashWatcher(pCrashWatcher),
+ m_sPluginName(pPluginName),
+ m_sPluginArgs(pPluginArgs),
+ m_nTimeout(pTimeout)
+ {}
+
+ } cron_callback_data_t;
+
+ typedef struct SThreadData {
+ pthread_t thread_id;
+ char* UUID;
+ char* UID;
+ char *dest;
+ CCrashWatcher *daemon;
+ } thread_data_t;
+
+ /**
+ * Map to cache the results from CreateReport_t
+ * <UID, <UUID, result>>
+ */
+ std::map <const std::string, std::map <int, map_crash_report_t > > pending_jobs;
+ /**
+ * mutex to protect pending_jobs from being accesed by multiple threads at the same time
+ */
+ pthread_mutex_t m_pJobsMutex;
+
+ static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer data);
+ static void *create_report(void *arg);
+ static gboolean cron_activation_periodic_cb(gpointer data);
+ static gboolean cron_activation_one_cb(gpointer data);
+ static gboolean cron_activation_reshedule_cb(gpointer data);
+ static void cron_delete_callback_data_cb(gpointer data);
+
+ void StartWatch();
+ void GStartWatch();
+ void CreatePidFile();
+ void Lock();
+ void SetUpMW();
+ void SetUpCron();
+ /* finds dumps created when daemon wasn't running */
+ // FIXME: how to catch abrt itself without this?
+ void FindNewDumps(const std::string& pPath);
+
+ int m_nFd;
+ GIOChannel* m_pGio;
+ GMainLoop *m_pMainloop;
+ std::string m_sTarget;
+ CMiddleWare *m_pMW;
+ CCommLayerServer *m_pCommLayer;
+ /*FIXME not needed */
+ //DBus::Connection *m_pConn;
+ CSettings *m_pSettings;
+ public:
+ //CCrashWatcher(const std::string& pPath,DBus::Connection &connection);
+ CCrashWatcher(const std::string& pPath);
+ virtual ~CCrashWatcher();
+ void Run();
+ void StopRun();
+
+ /* methods exported on dbus */
+ public:
+ virtual vector_crash_infos_t GetCrashInfos(const std::string &pUID);
+ /*FIXME: fix CLI and remove this stub*/
+ virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pUID){map_crash_report_t retval; return retval;};
+ uint64_t CreateReport_t(const std::string &pUUID,const std::string &pUID, const std::string &pSender);
+ virtual CMiddleWare::report_status_t Report(map_crash_report_t pReport, const std::string &pUID);
+ virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pUID);
+ virtual map_crash_report_t GetJobResult(uint64_t pJobID, const std::string& pSender);
+ /* plugins related */
+ virtual vector_map_string_string_t GetPluginsInfo();
+ virtual map_plugin_settings_t GetPluginSettings(const std::string& pName, const std::string& pUID);
+ void SetPluginSettings(const std::string& pName, const std::string& pUID, const map_plugin_settings_t& pSettings);
+ void RegisterPlugin(const std::string& pName);
+ void UnRegisterPlugin(const std::string& pName);
+
+ /* Observer methods */
+ void Status(const std::string& pMessage,const std::string& pDest="0");
+ void Debug(const std::string& pMessage, const std::string& pDest="0");
+ void Warning(const std::string& pMessage, const std::string& pDest="0");
+};
+
+} /* unnamed namespace */
+
+
+/* CCrashWatcher implementation */
+
+namespace { /* make it all static */
+
+/* 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);
+
+gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer daemon)
+{
+ GIOError err;
+ char *buf = new char[INOTIFY_BUFF_SIZE];
+ gsize len;
+ gsize i = 0;
+ err = g_io_channel_read(gio, buf, INOTIFY_BUFF_SIZE, &len);
+ CCrashWatcher *cc = (CCrashWatcher*)daemon;
+ if (err != G_IO_ERROR_NONE)
+ {
+ cc->Warning("Error reading inotify fd.");
+ delete[] buf;
+ return FALSE;
+ }
+ /* reconstruct each event and send message to the dbus */
+ while (i < len)
+ {
+ const char *name = NULL;
+ struct inotify_event *event;
+
+ event = (struct inotify_event *) &buf[i];
+ if (event->len)
+ name = &buf[i] + sizeof (struct inotify_event);
+ i += sizeof (struct inotify_event) + event->len;
+
+ cc->Debug(std::string("Created file: ") + name);
+
+ /* we want to ignore the lock files */
+ if (event->mask & IN_ISDIR)
+ {
+ if (GetDirSize(DEBUG_DUMPS_DIR) / (1024*1024) < cc->m_pSettings->GetMaxCrashReportsSize())
+ {
+ //std::string sName = name;
+ map_crash_info_t crashinfo;
+ try
+ {
+ CMiddleWare::mw_result_t res;
+ res = cc->m_pMW->SaveDebugDump(std::string(DEBUG_DUMPS_DIR) + "/" + name, crashinfo);
+ switch (res)
+ {
+ case CMiddleWare::MW_OK:
+ cc->Debug("New crash, saving...");
+ cc->m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
+ /* send message to dbus */
+ cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
+ break;
+ case CMiddleWare::MW_REPORTED:
+ case CMiddleWare::MW_OCCURED:
+ /* send message to dbus */
+ cc->Debug("Already saved crash, deleting...");
+ cc->m_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT]);
+ cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
+ break;
+ case CMiddleWare::MW_BLACKLISTED:
+ case CMiddleWare::MW_CORRUPTED:
+ case CMiddleWare::MW_PACKAGE_ERROR:
+ case CMiddleWare::MW_GPG_ERROR:
+ case CMiddleWare::MW_IN_DB:
+ case CMiddleWare::MW_FILE_ERROR:
+ default:
+ cc->Warning("Corrupted or bad crash, deleting...");
+ cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
+ break;
+ }
+ }
+ catch (CABRTException& e)
+ {
+ cc->Warning(e.what());
+ if (e.type() == EXCEP_FATAL)
+ {
+ delete[] buf;
+ return -1;
+ }
+ }
+ catch (...)
+ {
+ delete[] buf;
+ throw;
+ }
+ }
+ else
+ {
+ cc->Debug(std::string("DebugDumps size has exceeded the limit, deleting the last dump: ") + name);
+ cc->m_pMW->DeleteDebugDumpDir(std::string(DEBUG_DUMPS_DIR) + "/" + name);
+ }
+ }
+ else
+ {
+ cc->Debug("Some file created, ignoring...");
+ }
+ }
+ delete[] buf;
+ return TRUE;
+}
+
+void *CCrashWatcher::create_report(void *arg)
+{
+ thread_data_t *thread_data = (thread_data_t *) arg;
+ map_crash_info_t crashReport;
+ thread_data->daemon->Debug("Creating report...");
+ try
+ {
+ CMiddleWare::mw_result_t res;
+ res = thread_data->daemon->m_pMW->CreateCrashReport(thread_data->UUID,thread_data->UID,crashReport);
+ switch (res)
+ {
+ case CMiddleWare::MW_OK:
+ break;
+ case CMiddleWare::MW_IN_DB_ERROR:
+ thread_data->daemon->Warning(std::string("Did not find crash with UUID ")+thread_data->UUID+ " in database.");
+ break;
+ case CMiddleWare::MW_PLUGIN_ERROR:
+ thread_data->daemon->Warning(std::string("Particular analyzer plugin isn't loaded or there is an error within plugin(s)."));
+ break;
+ case CMiddleWare::MW_CORRUPTED:
+ case CMiddleWare::MW_FILE_ERROR:
+ default:
+ {
+ std::string debugDumpDir;
+ thread_data->daemon->Warning(std::string("Corrupted crash with UUID ")+thread_data->UUID+", deleting.");
+ debugDumpDir = thread_data->daemon->m_pMW->DeleteCrashInfo(thread_data->UUID, thread_data->UID);
+ thread_data->daemon->m_pMW->DeleteDebugDumpDir(debugDumpDir);
+ }
+ break;
+ }
+ /* only one thread can write */
+ pthread_mutex_lock(&(thread_data->daemon->m_pJobsMutex));
+ thread_data->daemon->pending_jobs[std::string(thread_data->UID)][thread_data->thread_id] = crashReport;
+ pthread_mutex_unlock(&(thread_data->daemon->m_pJobsMutex));
+ thread_data->daemon->m_pCommLayer->JobDone(thread_data->dest, thread_data->thread_id);
+ }
+ catch (CABRTException& e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ /* free strduped strings */
+ free(thread_data->UUID);
+ free(thread_data->UID);
+ free(thread_data->dest);
+ free(thread_data);
+ throw e;
+ }
+ thread_data->daemon->Warning(e.what());
+ }
+ /* free strduped strings */
+ free(thread_data->UUID);
+ free(thread_data->UID);
+ free(thread_data->dest);
+ free(thread_data);
+
+ /* Bogus value. pthreads require us to return void* */
+ return NULL;
+}
+
+gboolean CCrashWatcher::cron_activation_periodic_cb(gpointer data)
+{
+ cron_callback_data_t* cronPeriodicCallbackData = static_cast<cron_callback_data_t*>(data);
+ cronPeriodicCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronPeriodicCallbackData->m_sPluginName);
+ cronPeriodicCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronPeriodicCallbackData->m_pCrashWatcher->m_sTarget,
+ cronPeriodicCallbackData->m_sPluginName,
+ cronPeriodicCallbackData->m_sPluginArgs);
+ return TRUE;
+}
+gboolean CCrashWatcher::cron_activation_one_cb(gpointer data)
+{
+ cron_callback_data_t* cronOneCallbackData = static_cast<cron_callback_data_t*>(data);
+ cronOneCallbackData->m_pCrashWatcher->Debug("Activating plugin: " + cronOneCallbackData->m_sPluginName);
+ cronOneCallbackData->m_pCrashWatcher->m_pMW->RunAction(cronOneCallbackData->m_pCrashWatcher->m_sTarget,
+ cronOneCallbackData->m_sPluginName,
+ cronOneCallbackData->m_sPluginArgs);
+ return FALSE;
+}
+gboolean CCrashWatcher::cron_activation_reshedule_cb(gpointer data)
+{
+ cron_callback_data_t* cronResheduleCallbackData = static_cast<cron_callback_data_t*>(data);
+ cronResheduleCallbackData->m_pCrashWatcher->Debug("Rescheduling plugin: " + cronResheduleCallbackData->m_sPluginName);
+ cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(cronResheduleCallbackData->m_pCrashWatcher,
+ cronResheduleCallbackData->m_sPluginName,
+ cronResheduleCallbackData->m_sPluginArgs,
+ cronResheduleCallbackData->m_nTimeout);
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ cronPeriodicCallbackData->m_nTimeout,
+ cron_activation_periodic_cb,
+ static_cast<gpointer>(cronPeriodicCallbackData),
+ cron_delete_callback_data_cb);
+
+
+ return FALSE;
+}
+
+void CCrashWatcher::cron_delete_callback_data_cb(gpointer data)
+{
+ cron_callback_data_t* cronDeleteCallbackData = static_cast<cron_callback_data_t*>(data);
+ delete cronDeleteCallbackData;
+}
+
+void CCrashWatcher::SetUpMW()
+{
+ m_pMW->SetOpenGPGCheck(m_pSettings->GetOpenGPGCheck());
+ m_pMW->SetDatabase(m_pSettings->GetDatabase());
+ CSettings::set_strings_t openGPGPublicKeys = m_pSettings->GetOpenGPGPublicKeys();
+ CSettings::set_strings_t::iterator it_k;
+ for (it_k = openGPGPublicKeys.begin(); it_k != openGPGPublicKeys.end(); it_k++)
+ {
+ m_pMW->AddOpenGPGPublicKey(*it_k);
+ }
+ CSettings::set_strings_t blackList = m_pSettings->GetBlackList();
+ CSettings::set_strings_t::iterator it_b;
+ for (it_b = blackList.begin(); it_b != blackList.end(); it_b++)
+ {
+ m_pMW->AddBlackListedPackage(*it_b);
+ }
+ CSettings::set_strings_t enabledPlugins = m_pSettings->GetEnabledPlugins();
+ CSettings::set_strings_t::iterator it_p;
+ for (it_p = enabledPlugins.begin(); it_p != enabledPlugins.end(); it_p++)
+ {
+ m_pMW->RegisterPlugin(*it_p);
+ }
+ CSettings::vector_pair_strings_t actionsAndReporters = m_pSettings->GetActionsAndReporters();
+ CSettings::vector_pair_strings_t::iterator it_ar;
+ for (it_ar = actionsAndReporters.begin(); it_ar != actionsAndReporters.end(); it_ar++)
+ {
+ m_pMW->AddActionOrReporter((*it_ar).first, (*it_ar).second);
+ }
+
+ CSettings::map_analyzer_actions_and_reporters_t analyzerActionsAndReporters = m_pSettings->GetAnalyzerActionsAndReporters();
+ CSettings::map_analyzer_actions_and_reporters_t::iterator it_aar;
+ for (it_aar = analyzerActionsAndReporters.begin(); it_aar != analyzerActionsAndReporters.end(); it_aar++)
+ {
+ CSettings::vector_pair_strings_t::iterator it_ar;
+ for (it_ar = it_aar->second.begin(); it_ar != it_aar->second.end(); it_ar++)
+ {
+ m_pMW->AddAnalyzerActionOrReporter(it_aar->first, (*it_ar).first, (*it_ar).second);
+ }
+ }
+}
+
+void CCrashWatcher::SetUpCron()
+{
+ CSettings::map_cron_t cron = m_pSettings->GetCron();
+ CSettings::map_cron_t::iterator it_c;
+ for (it_c = cron.begin(); it_c != cron.end(); it_c++)
+ {
+ std::string::size_type pos = it_c->first.find(":");
+ int timeout = 0;
+ int nH = -1;
+ int nM = -1;
+ int nS = -1;
+
+ if (pos != std::string::npos)
+ {
+ std::string sH = "";
+ std::string sM = "";
+
+ sH = it_c->first.substr(0, pos);
+ nH = atoi(sH.c_str());
+ nH = nH > 23 ? 23 : nH;
+ nH = nH < 0 ? 0 : nH;
+ nM = nM > 59 ? 59 : nM;
+ nM = nM < 0 ? 0 : nM;
+ timeout += nH * 60 * 60;
+ sM = it_c->first.substr(pos + 1);
+ nM = atoi(sM.c_str());
+ timeout += nM * 60;
+ }
+ else
+ {
+ std::string sS = "";
+
+ sS = it_c->first;
+ nS = atoi(sS.c_str());
+ nS = nS <= 0 ? 1 : nS;
+ timeout = nS;
+ }
+
+ if (nS != -1)
+ {
+ CSettings::vector_pair_strings_t::iterator it_ar;
+ for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
+ {
+
+ cron_callback_data_t* cronPeriodicCallbackData = new cron_callback_data_t(this, (*it_ar).first, (*it_ar).second, timeout);
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ timeout,
+ cron_activation_periodic_cb,
+ static_cast<gpointer>(cronPeriodicCallbackData),
+ cron_delete_callback_data_cb);
+ }
+ }
+ else
+ {
+ time_t actTime = time(NULL);
+ if (actTime == ((time_t)-1))
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get time.");
+ }
+ struct tm locTime;
+ if (localtime_r(&actTime, &locTime) == NULL)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot get local time.");
+ }
+ locTime.tm_hour = nH;
+ locTime.tm_min = nM;
+ locTime.tm_sec = 0;
+ time_t nextTime = mktime(&locTime);
+ if (nextTime == ((time_t)-1))
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::SetUpCron(): Cannot set up time.");
+ }
+ if (actTime > nextTime)
+ {
+ timeout = 24*60*60 + (nextTime - actTime);
+ }
+ else
+ {
+ timeout = nextTime - actTime;
+ }
+ CSettings::vector_pair_strings_t::iterator it_ar;
+ for (it_ar = it_c->second.begin(); it_ar != it_c->second.end(); it_ar++)
+ {
+
+ cron_callback_data_t* cronOneCallbackData = new cron_callback_data_t(this, (*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(this, (*it_ar).first, (*it_ar).second, 24 * 60 * 60);
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ timeout,
+ cron_activation_reshedule_cb,
+ static_cast<gpointer>(cronResheduleCallbackData),
+ cron_delete_callback_data_cb);
+ }
+ }
+ }
+}
+
+void CCrashWatcher::Status(const std::string& pMessage, const std::string& pDest)
+{
+ std::cout << "Update: " + pMessage << std::endl;
+ //FIXME: send updates only to job owner
+ if(m_pCommLayer != NULL)
+ m_pCommLayer->Update(pDest,pMessage);
+}
+
+void CCrashWatcher::Warning(const std::string& pMessage, const std::string& pDest)
+{
+ std::cerr << "Warning: " + pMessage << std::endl;
+ if(m_pCommLayer != NULL)
+ m_pCommLayer->Warning(pDest,pMessage);
+}
+
+void CCrashWatcher::Debug(const std::string& pMessage, const std::string& pDest)
+{
+ //some logic to add logging levels?
+ std::cout << "Debug: " + pMessage << std::endl;
+}
+
+static double GetDirSize(const std::string &pPath)
+{
+ double size = 0;
+ struct dirent *ep;
+ struct stat stats;
+ DIR *dp;
+
+ dp = opendir(pPath.c_str());
+ if (dp != NULL)
+ {
+ while ((ep = readdir(dp)) != NULL)
+ {
+ if (dot_or_dotdot(ep->d_name))
+ continue;
+ std::string dname = pPath + "/" + ep->d_name;
+ if (lstat(dname.c_str(), &stats) == 0)
+ {
+ if (S_ISDIR(stats.st_mode))
+ {
+ size += GetDirSize(dname);
+ }
+ else if (S_ISREG(stats.st_mode))
+ {
+ size += stats.st_size;
+ }
+ }
+ }
+ closedir(dp);
+ }
+ else
+ {
+ throw CABRTException(EXCEP_FATAL, std::string(__func__) + ": Init Failed");
+ }
+ return size;
+}
+
+CCrashWatcher::CCrashWatcher(const std::string& pPath)
+{
+ int watch = 0;
+ m_sTarget = pPath;
+
+ // TODO: initialize object according parameters -w -d
+ // status has to be always created.
+ m_pCommLayer = NULL;
+ comm_layer_inner_init(this);
+
+ m_pSettings = new CSettings();
+ m_pSettings->LoadSettings(std::string(CONF_DIR) + "/abrt.conf");
+
+ m_pMainloop = g_main_loop_new(NULL,FALSE);
+ m_pMW = new CMiddleWare(PLUGINS_CONF_DIR,PLUGINS_LIB_DIR);
+ if (pthread_mutex_init(&m_pJobsMutex, NULL) != 0)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't init mutex!");
+ }
+ try
+ {
+ SetUpMW();
+ SetUpCron();
+ FindNewDumps(pPath);
+#ifdef ENABLE_DBUS
+ m_pCommLayer = new CCommLayerServerDBus();
+#elif ENABLE_SOCKET
+ m_pCommLayer = new CCommLayerServerSocket();
+#endif
+// m_pCommLayer = new CCommLayerServerDBus();
+// m_pCommLayer = new CCommLayerServerSocket();
+ m_pCommLayer->Attach(this);
+
+ if ((m_nFd = inotify_init()) == -1)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Init Failed");
+ }
+ if ((watch = inotify_add_watch(m_nFd, pPath.c_str(), IN_CREATE)) == -1)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Add watch failed:" + pPath);
+ }
+ m_pGio = g_io_channel_unix_new(m_nFd);
+ }
+ catch (...)
+ {
+ /* This restores /proc/sys/kernel/core_pattern, among other things */
+ delete m_pMW;
+ //too? delete m_pCommLayer;
+ throw;
+ }
+}
+
+CCrashWatcher::~CCrashWatcher()
+{
+ //delete dispatcher, connection, etc..
+ //m_pConn->disconnect();
+
+ g_io_channel_unref(m_pGio);
+ g_main_loop_unref(m_pMainloop);
+
+ delete m_pCommLayer;
+ delete m_pMW;
+ delete m_pSettings;
+ if (pthread_mutex_destroy(&m_pJobsMutex) != 0)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CCrashWatcher(): Can't destroy mutex!");
+ }
+ /* delete pid file */
+ unlink(VAR_RUN_PIDFILE);
+ /* delete lock file */
+ unlink(VAR_RUN_LOCK_FILE);
+}
+
+void CCrashWatcher::FindNewDumps(const std::string& pPath)
+{
+ Debug("Scanning for unsaved entries...");
+ struct dirent *ep;
+ struct stat stats;
+ DIR *dp;
+ std::vector<std::string> dirs;
+ std::string dname;
+ // get potential unsaved debugdumps
+ dp = opendir(pPath.c_str());
+ if (dp != NULL)
+ {
+ while ((ep = readdir(dp)))
+ {
+ if (dot_or_dotdot(ep->d_name))
+ continue;
+ dname = pPath + "/" + ep->d_name;
+ if (lstat(dname.c_str(), &stats) == 0)
+ {
+ if (S_ISDIR(stats.st_mode))
+ {
+ dirs.push_back(dname);
+ }
+ }
+ }
+ (void) closedir(dp);
+ }
+ else
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::FindNewDumps(): Couldn't open the directory:" + pPath);
+ }
+
+ for (std::vector<std::string>::iterator itt = dirs.begin(); itt != dirs.end(); ++itt){
+ map_crash_info_t crashinfo;
+ try
+ {
+ CMiddleWare::mw_result_t res;
+ res = m_pMW->SaveDebugDump(*itt, crashinfo);
+ switch (res)
+ {
+ case CMiddleWare::MW_OK:
+ Debug("Saving into database (" + *itt + ").");
+ m_pMW->RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT]);
+ break;
+ case CMiddleWare::MW_IN_DB:
+ Debug("Already saved in database (" + *itt + ").");
+ break;
+ case CMiddleWare::MW_REPORTED:
+ case CMiddleWare::MW_OCCURED:
+ case CMiddleWare::MW_BLACKLISTED:
+ case CMiddleWare::MW_CORRUPTED:
+ case CMiddleWare::MW_PACKAGE_ERROR:
+ case CMiddleWare::MW_GPG_ERROR:
+ case CMiddleWare::MW_FILE_ERROR:
+ default:
+ Warning("Corrupted, bad or already saved crash, deleting.");
+ m_pMW->DeleteDebugDumpDir(*itt);
+ break;
+ }
+ }
+ catch (CABRTException& e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+ }
+}
+
+void CCrashWatcher::CreatePidFile()
+{
+ int fd;
+
+ /* JIC */
+ unlink(VAR_RUN_PIDFILE);
+
+ /* open the pidfile */
+ fd = open(VAR_RUN_PIDFILE, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (fd >= 0)
+ {
+ /* write our pid to it */
+ char buf[sizeof(int)*3 + 2];
+ int len = sprintf(buf, "%u\n", (unsigned)getpid());
+ write(fd, buf, len);
+ close(fd);
+ return;
+ }
+
+ /* something went wrong */
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreatePidFile(): can not open pid file");
+}
+
+void CCrashWatcher::Lock()
+{
+ int lfp = open(VAR_RUN_LOCK_FILE, O_RDWR|O_CREAT, 0640);
+ if (lfp < 0)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): can not open lock file");
+ }
+ if (lockf(lfp, F_TLOCK, 0) < 0)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Lock(): cannot create lock on lockfile");
+ }
+ /* only first instance continues */
+ //sprintf(str,"%d\n",getpid());
+ //write(lfp,str,strlen(str)); /* record pid to lockfile */
+}
+
+void CCrashWatcher::StartWatch()
+{
+ char *buff = new char[INOTIFY_BUFF_SIZE];
+ int len = 0;
+ int i = 0;
+ char action[FILENAME_MAX];
+ struct inotify_event *pevent;
+ //run forever
+ while (1)
+ {
+ i = 0;
+ len = read(m_nFd,buff,INOTIFY_BUFF_SIZE);
+ while (i < len)
+ {
+ pevent = (struct inotify_event *)&buff[i];
+ if (pevent->len)
+ {
+ strcpy(action, pevent->name);
+ }
+ else
+ {
+ strcpy(action, m_sTarget.c_str());
+ }
+
+ i += sizeof(struct inotify_event) + pevent->len;
+ Debug(std::string("Created file: ") + action);
+ }
+ }
+ delete[] buff;
+}
+
+//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.
+typedef struct SignalSource
+{
+ GSource src;
+ CCrashWatcher* watcher;
+} SignalSource;
+static gboolean waitsignal_prepare(GSource *source, gint *timeout_)
+{
+ /* We depend on the fact that in Unix, poll() is interrupted
+ * by caught signals (returns EINTR). Thus we do not need to set
+ * a small timeout here: infinite timeout (-1) works too */
+ *timeout_ = -1;
+ return sig_caught != 0;
+}
+static gboolean waitsignal_check(GSource *source)
+{
+ return sig_caught != 0;
+}
+static gboolean waitsignal_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ SignalSource *ssrc = (SignalSource*) source;
+ ssrc->watcher->StopRun();
+ return 1;
+}
+
+/* daemon loop with glib */
+void CCrashWatcher::GStartWatch()
+{
+ g_io_add_watch(m_pGio, G_IO_IN, handle_event_cb, this);
+
+ 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
+ SignalSource *waitsignal_src = (SignalSource*) g_source_new(&waitsignal_funcs, sizeof(*waitsignal_src));
+ waitsignal_src->watcher = this;
+ g_source_attach(&waitsignal_src->src, g_main_context_default());
+
+ //enter the event loop
+ g_main_run(m_pMainloop);
+}
+
+void CCrashWatcher::Run()
+{
+ Debug("Running...");
+ Lock();
+ CreatePidFile();
+ GStartWatch();
+}
+
+void CCrashWatcher::StopRun()
+{
+ g_main_quit(m_pMainloop);
+}
+
+vector_crash_infos_t CCrashWatcher::GetCrashInfos(const std::string &pUID)
+{
+ vector_crash_infos_t retval;
+ Debug("Getting crash infos...");
+ try
+ {
+ vector_pair_string_string_t UUIDsUIDs;
+ UUIDsUIDs = m_pMW->GetUUIDsOfCrash(pUID);
+
+ unsigned int ii;
+ for (ii = 0; ii < UUIDsUIDs.size(); ii++)
+ {
+ CMiddleWare::mw_result_t res;
+ map_crash_info_t info;
+
+ res = m_pMW->GetCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second, info);
+ switch (res)
+ {
+ case CMiddleWare::MW_OK:
+ retval.push_back(info);
+ break;
+ case CMiddleWare::MW_ERROR:
+ Warning("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
+ Status("Can not find debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting from database");
+ m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
+ break;
+ case CMiddleWare::MW_FILE_ERROR:
+ {
+ std::string debugDumpDir;
+ Warning("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
+ Status("Can not open file in debug dump directory for UUID: " + UUIDsUIDs[ii].first + ", deleting ");
+ debugDumpDir = m_pMW->DeleteCrashInfo(UUIDsUIDs[ii].first, UUIDsUIDs[ii].second);
+ m_pMW->DeleteDebugDumpDir(debugDumpDir);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ catch (CABRTException& e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ Status(e.what());
+ }
+
+ //retval = m_pMW->GetCrashInfos(pUID);
+ //Notify("Sent crash info");
+ return retval;
+}
+
+uint64_t CCrashWatcher::CreateReport_t(const std::string &pUUID,const std::string &pUID, const std::string &pSender)
+{
+ thread_data_t *thread_data = (thread_data_t *)xzalloc(sizeof(thread_data_t));
+ if (thread_data != NULL)
+ {
+ thread_data->UUID = xstrdup(pUUID.c_str());
+ thread_data->UID = xstrdup(pUID.c_str());
+ thread_data->dest = xstrdup(pSender.c_str());
+ thread_data->daemon = this;
+ if (pthread_create(&(thread_data->thread_id), NULL, create_report, (void *)thread_data) != 0)
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot create thread!");
+ }
+ }
+ else
+ {
+ throw CABRTException(EXCEP_FATAL, "CCrashWatcher::CreateReport_t(): Cannot allocate memory!");
+ }
+ //FIXME: we don't use this value anymore, so fix the API
+ return 0;
+}
+
+CMiddleWare::report_status_t CCrashWatcher::Report(map_crash_report_t pReport, const std::string& pUID)
+{
+ //#define FIELD(X) crashReport.m_s##X = pReport[#X];
+ //crashReport.m_sUUID = pReport["UUID"];
+ //ALL_CRASH_REPORT_FIELDS;
+ //#undef FIELD
+ //for (dbus_map_report_info_t::iterator it = pReport.begin(); it!=pReport.end(); ++it) {
+ // std::cerr << it->second << std::endl;
+ //}
+ CMiddleWare::report_status_t rs;
+ try
+ {
+ rs = m_pMW->Report(pReport, pUID);
+ }
+ catch (CABRTException& e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ Status(e.what());
+ return rs;
+ }
+ return rs;
+}
+
+bool CCrashWatcher::DeleteDebugDump(const std::string& pUUID, const std::string& pUID)
+{
+ try
+ {
+ std::string debugDumpDir;
+ debugDumpDir = m_pMW->DeleteCrashInfo(pUUID,pUID);
+ m_pMW->DeleteDebugDumpDir(debugDumpDir);
+ }
+ catch (CABRTException& e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ Status(e.what());
+ return false;
+ }
+ return true;
+}
+
+map_crash_report_t CCrashWatcher::GetJobResult(uint64_t pJobID, const std::string& pSender)
+{
+ /* FIXME: once we return the result, we should remove it from map to free memory
+ - use some TTL to clean the memory even if client won't get it
+ - if we don't find it in the cache we should try to ask MW to get it again??
+ */
+ return pending_jobs[pSender][pJobID];
+}
+
+vector_map_string_string_t CCrashWatcher::GetPluginsInfo()
+{
+ try
+ {
+ return m_pMW->GetPluginsInfo();
+ }
+ catch (CABRTException &e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+ // TODO: is it right? I added it just to disable a warning...
+ // but maybe returning empty map is wrong here?
+ return vector_map_string_string_t();
+}
+
+map_plugin_settings_t CCrashWatcher::GetPluginSettings(const std::string& pName, const std::string& pUID)
+{
+ try
+ {
+ return m_pMW->GetPluginSettings(pName, pUID);
+ }
+ catch(CABRTException &e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+}
+
+void CCrashWatcher::RegisterPlugin(const std::string& pName)
+{
+ try
+ {
+ m_pMW->RegisterPlugin(pName);
+ }
+ catch(CABRTException &e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+}
+
+void CCrashWatcher::UnRegisterPlugin(const std::string& pName)
+{
+ try
+ {
+ m_pMW->UnRegisterPlugin(pName);
+ }
+ catch(CABRTException &e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+}
+
+void CCrashWatcher::SetPluginSettings(const std::string& pName, const std::string& pUID, const map_plugin_settings_t& pSettings)
+{
+ try
+ {
+ m_pMW->SetPluginSettings(pName, pUID, pSettings);
+ }
+ catch(CABRTException &e)
+ {
+ if (e.type() == EXCEP_FATAL)
+ {
+ throw e;
+ }
+ Warning(e.what());
+ }
+}
+
+} /* unnamed namespace */
+
-uint8_t sig_caught;
+/* Daemon's main() */
static void handle_fatal_signal(int signal)
{
diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am
index fdc1d604..6485f0f6 100644
--- a/src/Daemon/Makefile.am
+++ b/src/Daemon/Makefile.am
@@ -6,7 +6,6 @@ abrt_SOURCES = \
ABRTPlugin.cpp ABRTPlugin.h \
PluginManager.cpp PluginManager.h \
MiddleWare.cpp MiddleWare.h \
- CrashWatcher.cpp CrashWatcher.h \
CommLayerServer.h CommLayerServer.cpp \
CommLayerServerSocket.h CommLayerServerSocket.cpp \
CommLayerServerDBus.h CommLayerServerDBus.cpp \