diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-19 19:08:55 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-19 19:08:55 +0200 |
| commit | cba5b047558b7f0d9643a84a6257adf1a7f41086 (patch) | |
| tree | 9d08b91308e5300f8b7cab965369f730dd61bfa8 /src | |
| parent | 14b68dc5f0b2bea106383f623e9ad037a4fdc682 (diff) | |
| download | abrt-cba5b047558b7f0d9643a84a6257adf1a7f41086.tar.gz abrt-cba5b047558b7f0d9643a84a6257adf1a7f41086.tar.xz abrt-cba5b047558b7f0d9643a84a6257adf1a7f41086.zip | |
move lib/CommLayer/CommLayerServer*.{h,cpp} to src/Daemon/, the sole user
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/Daemon/CommLayerServer.cpp | 24 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServer.h | 53 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerDBus.cpp | 147 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerDBus.h | 42 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerSocket.cpp | 248 | ||||
| -rw-r--r-- | src/Daemon/CommLayerServerSocket.h | 37 | ||||
| -rw-r--r-- | src/Daemon/Makefile.am | 3 |
7 files changed, 554 insertions, 0 deletions
diff --git a/src/Daemon/CommLayerServer.cpp b/src/Daemon/CommLayerServer.cpp new file mode 100644 index 0000000..328986e --- /dev/null +++ b/src/Daemon/CommLayerServer.cpp @@ -0,0 +1,24 @@ +#include "CommLayerServer.h" +#include <iostream> + +CCommLayerServer::CCommLayerServer() +{ +} + +CCommLayerServer::~CCommLayerServer() +{ +} + +void CCommLayerServer::Attach(CObserver *pObs) +{ + m_pObserver = pObs; +} +void CCommLayerServer::Detach(CObserver *pObs) +{ + m_pObserver = NULL; +} +void CCommLayerServer::Notify(const std::string& pMessage) +{ + if(m_pObserver) + m_pObserver->Status(pMessage); +} diff --git a/src/Daemon/CommLayerServer.h b/src/Daemon/CommLayerServer.h new file mode 100644 index 0000000..7601fa1 --- /dev/null +++ b/src/Daemon/CommLayerServer.h @@ -0,0 +1,53 @@ +#ifndef COMMLAYERSERVER_H_ +#define COMMLAYERSERVER_H_ + +#include <vector> +#include <map> +#include <string> +#include <sstream> +#include <iostream> +#include "Observer.h" +#include "CrashTypes.h" + +/* just a helper function */ +template< class T > +std::string +to_string( T x ) +{ + std::ostringstream o; + o << x; + return o.str(); +} + + +class CCommLayerServer { + protected: + /* FIXME more observers? */ + //std::vector<Observer *obs>; + CObserver *m_pObserver; + public: + //CMiddleWare *m_pMW; + //CCommLayerServer(CMiddleWare *pMW); + CCommLayerServer(); + virtual ~CCommLayerServer(); + /* observer */ + void Attach(CObserver *pObs); + void Detach(CObserver *pObs); + void Notify(const std::string& pMessage); + + virtual vector_crash_infos_t GetCrashInfos(const std::string &pSender) = 0; + virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pSender) = 0; + virtual report_status_t Report(map_crash_report_t pReport,const std::string &pSender) = 0; + virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pSender) = 0; + + public: + /* just stubs to be called when not implemented in specific comm layer */ + virtual void Crash(const std::string& arg1) {} + virtual void AnalyzeComplete(map_crash_report_t arg1) {} + virtual void Error(const std::string& arg1) {} + virtual void Update(const std::string& pDest, const std::string& pMessage) {}; + virtual void Warning(const std::string& pDest, const std::string& pMessage) {}; + virtual void JobDone(const std::string &pDest, uint64_t pJobID) {}; +}; + +#endif //COMMLAYERSERVER_H_ diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp new file mode 100644 index 0000000..90a7878 --- /dev/null +++ b/src/Daemon/CommLayerServerDBus.cpp @@ -0,0 +1,147 @@ +#include "CommLayerServerDBus.h" +#include <iostream> +#include "ABRTException.h" + +DBus::Connection *CCommLayerServerDBus::init_dbus(CCommLayerServerDBus *self) +{ + CCommLayerServerDBus *server = (CCommLayerServerDBus*) self; + server->m_pDispatcher = new DBus::Glib::BusDispatcher(); + server->m_pDispatcher->attach(NULL); + DBus::default_dispatcher = self->m_pDispatcher; + server->m_pConn = new DBus::Connection(DBus::Connection::SystemBus()); + return server->m_pConn; +} + +CCommLayerServerDBus::CCommLayerServerDBus() +: CCommLayerServer(), + DBus::ObjectAdaptor(*init_dbus(this), CC_DBUS_PATH) +{ + try + { + m_pConn->request_name(CC_DBUS_NAME); + } + catch(DBus::Error err) + { + throw CABRTException(EXCEP_FATAL, std::string(__func__) + + "\nPlease check if:\n" + + " * abrt is being run with root permissions\n" + + " * you have reloaded the dbus\n"+ + + "Original exception was:\n " + err.what()); + } + +} + +CCommLayerServerDBus::~CCommLayerServerDBus() +{ + delete m_pDispatcher; +} + +vector_crash_infos_t CCommLayerServerDBus::GetCrashInfos(const std::string &pSender) +{ + vector_crash_infos_t crashInfos; + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + crashInfos = m_pObserver->GetCrashInfos(to_string(unix_uid)); + return crashInfos; +} +//FIXME: fix CLI and remove this +/* +map_crash_report_t CCommLayerServerDBus::CreateReport(const std::string &pUUID,const std::string &pSender) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + map_crash_report_t crashReport; + crashReport = m_pObserver->CreateReport(pUUID, to_string(unix_uid)); + return crashReport; +} +*/ +uint64_t CCommLayerServerDBus::CreateReport_t(const std::string &pUUID,const std::string &pSender) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + map_crash_report_t crashReport; + uint64_t job_id = m_pObserver->CreateReport_t(pUUID, to_string(unix_uid), pSender); + return job_id; +} + +report_status_t CCommLayerServerDBus::Report(map_crash_report_t pReport,const std::string &pSender) +{ + report_status_t rs; + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + rs = m_pObserver->Report(pReport, to_string(unix_uid)); + return rs; +} + +bool CCommLayerServerDBus::DeleteDebugDump(const std::string& pUUID, const std::string& pSender) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + m_pObserver->DeleteDebugDump(pUUID,to_string(unix_uid)); + return true; +} + +map_crash_report_t CCommLayerServerDBus::GetJobResult(uint64_t pJobID, const std::string& pSender) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + map_crash_report_t crashReport; + crashReport = m_pObserver->GetJobResult(pJobID,to_string(unix_uid)); + return crashReport; +} + +void CCommLayerServerDBus::Crash(const std::string& arg) +{ + CDBusServer_adaptor::Crash(arg); +} + +void CCommLayerServerDBus::AnalyzeComplete(map_crash_report_t arg1) +{ + CDBusServer_adaptor::AnalyzeComplete(arg1); +} + +void CCommLayerServerDBus::Error(const std::string& arg1) +{ + CDBusServer_adaptor::Error(arg1); +} + +void CCommLayerServerDBus::Update(const std::string& pDest, const std::string& pMessage) +{ + CDBusServer_adaptor::Update(pDest, pMessage); +} + +void CCommLayerServerDBus::JobDone(const std::string &pDest, uint64_t pJobID) +{ + CDBusServer_adaptor::JobDone(pDest, pJobID); +} + +void CCommLayerServerDBus::Warning(const std::string& pDest, const std::string& pMessage) +{ + CDBusServer_adaptor::Warning(pMessage); +} + +vector_map_string_string_t CCommLayerServerDBus::GetPluginsInfo() +{ + //FIXME: simplify? + vector_map_string_string_t plugins_info; + plugins_info = m_pObserver->GetPluginsInfo(); + return plugins_info; +} + +map_plugin_settings_t CCommLayerServerDBus::GetPluginSettings(const std::string& pName, const std::string& pSender) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + return m_pObserver->GetPluginSettings(pName, to_string(unix_uid)); +} + + +void CCommLayerServerDBus::RegisterPlugin(const std::string& pName) +{ + return m_pObserver->RegisterPlugin(pName); +} + +void CCommLayerServerDBus::UnRegisterPlugin(const std::string& pName) +{ + return m_pObserver->UnRegisterPlugin(pName); +} + +void CCommLayerServerDBus::SetPluginSettings(const std::string& pName, const std::string& pSender, const map_plugin_settings_t& pSettings) +{ + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); + return m_pObserver->SetPluginSettings(pName, to_string(unix_uid), pSettings); +} + diff --git a/src/Daemon/CommLayerServerDBus.h b/src/Daemon/CommLayerServerDBus.h new file mode 100644 index 0000000..d241c63 --- /dev/null +++ b/src/Daemon/CommLayerServerDBus.h @@ -0,0 +1,42 @@ +#include "CommLayerServer.h" + +#include <dbus-c++/dbus.h> +#include <dbus-c++/glib-integration.h> +#include "DBusServerProxy.h" +#include <iostream> + +class CCommLayerServerDBus +: public CCommLayerServer, + public CDBusServer_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor +{ + private: + DBus::Connection *m_pConn; + DBus::Glib::BusDispatcher *m_pDispatcher; + static DBus::Connection *init_dbus(CCommLayerServerDBus *self); + public: + CCommLayerServerDBus(); + virtual ~CCommLayerServerDBus(); + + virtual vector_crash_infos_t GetCrashInfos(const std::string &pSender); + /*FIXME: fix CLI and remove this stub*/ + virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pSender){map_crash_report_t retval; return retval;}; + virtual uint64_t CreateReport_t(const std::string &pUUID,const std::string &pSender); + virtual report_status_t Report(map_crash_report_t pReport,const std::string &pSender); + virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pSender); + virtual map_crash_report_t GetJobResult(uint64_t pJobID, const std::string& pSender); + virtual vector_map_string_string_t GetPluginsInfo(); + virtual map_plugin_settings_t GetPluginSettings(const std::string& pName, const std::string& pSender); + void SetPluginSettings(const std::string& pName, const std::string& pSender, const map_plugin_settings_t& pSettings); + void RegisterPlugin(const std::string& pName); + void UnRegisterPlugin(const std::string& pName); + + virtual void Crash(const std::string& arg1); + virtual void AnalyzeComplete(map_crash_report_t arg1); + virtual void Error(const std::string& arg1); + virtual void Update(const std::string& pDest, const std::string& pMessage); + virtual void JobDone(const std::string &pDest, uint64_t pJobID); + virtual void Warning(const std::string& pDest, const std::string& pMessage); +}; + diff --git a/src/Daemon/CommLayerServerSocket.cpp b/src/Daemon/CommLayerServerSocket.cpp new file mode 100644 index 0000000..f5466d4 --- /dev/null +++ b/src/Daemon/CommLayerServerSocket.cpp @@ -0,0 +1,248 @@ +#include "CommLayerServerSocket.h" +#include "CommLayerInner.h" +#include "ABRTException.h" +#include "CrashTypesSocket.h" +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <iostream> +#include <sstream> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +void CCommLayerServerSocket::Send(const std::string& pData, GIOChannel *pDestination) +{ + ssize_t ret = -1; + gsize len = pData.length(); + int offset = 0; + GError *err = NULL; + gchar* message = new gchar[len + 3]; + memcpy(message, pData.c_str(), len); + message[len] = MESSAGE_END_MARKER; + message[len + 1] = '\n'; + message[len + 2] = '\0'; + + len = 0; + while (len != strlen(message + offset)) + { + offset += len; + ret = g_io_channel_write_chars(pDestination, message + offset, strlen(message + offset), &len, &err); + if (ret == G_IO_STATUS_ERROR) + { + comm_layer_inner_warning("Error during sending data."); + } + } + + g_io_channel_flush(pDestination, &err); + delete[] message; +} + +std::string CCommLayerServerSocket::GetSenderUID(int pSenderSocket) +{ + struct ucred creds; + socklen_t len = sizeof(creds); + if (getsockopt(pSenderSocket, SOL_SOCKET, SO_PEERCRED, &creds, &len) == -1) + { + throw CABRTException(EXCEP_ERROR, "CCommLayerServerSocket::GetSenderUID(): Error can get sender uid."); + } + std::stringstream ss; + ss << creds.uid; + return ss.str(); +} + +gboolean CCommLayerServerSocket::client_socket_cb(GIOChannel *source, GIOCondition condition, gpointer data) +{ + CCommLayerServerSocket* serverSocket = static_cast<CCommLayerServerSocket*>(data); + std::string senderUID = serverSocket->GetSenderUID(g_io_channel_unix_get_fd(source)); + gchar buff[1]; + gsize len; + GIOStatus ret; + GError *err = NULL; + bool receivingMessage = true; + std::string message = ""; + + if (condition & G_IO_HUP || + condition & G_IO_ERR || + condition & G_IO_NVAL) + { + comm_layer_inner_debug("Socket client disconnected."); + g_io_channel_unref(serverSocket->m_mapClientChannels[g_io_channel_unix_get_fd(source)]); + serverSocket->m_mapClientChannels.erase(g_io_channel_unix_get_fd(source)); + return FALSE; + } + + // TODO: rewrite this + while (receivingMessage) + { + ret = g_io_channel_read_chars(source, buff, 1, &len, &err); + if (ret == G_IO_STATUS_ERROR) + { + comm_layer_inner_warning(std::string("Error while reading data from client socket: ") + err->message); + return FALSE; + } + message += buff[0]; + + if (message.length() > 2 && + message[message.length() - 2] == MESSAGE_END_MARKER && + message[message.length() - 1] == '\n') + { + receivingMessage = false; + message = message.substr(0, message.length() - 2); + } + } + + serverSocket->ProcessMessage(message, source); + return TRUE; +} + +gboolean CCommLayerServerSocket::server_socket_cb(GIOChannel *source, GIOCondition condition, gpointer data) +{ + CCommLayerServerSocket* serverSocket = static_cast<CCommLayerServerSocket*>(data); + int socket; + struct sockaddr_un remote; + socklen_t len = sizeof(remote); + + if (condition & G_IO_HUP || + condition & G_IO_ERR || + condition & G_IO_NVAL) + { + comm_layer_inner_warning("Server socket error."); + return FALSE; + } + + if ((socket = accept(serverSocket->m_nSocket, (struct sockaddr *)&remote, &len)) == -1) + { + comm_layer_inner_warning("Server can not accept client."); + return TRUE; + } + comm_layer_inner_debug("New socket client connected."); + GIOChannel* gSocket = g_io_channel_unix_new(socket); + if (!g_io_add_watch(gSocket, + static_cast<GIOCondition>(G_IO_IN |G_IO_PRI| G_IO_ERR | G_IO_HUP | G_IO_NVAL), + static_cast<GIOFunc>(client_socket_cb), + data)) + { + comm_layer_inner_warning("Can not init g_io_channel."); + return TRUE; + } + serverSocket->m_mapClientChannels[socket] = gSocket; + return TRUE; +} + +void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChannel *pSource) +{ + std::string UID = GetSenderUID(g_io_channel_unix_get_fd(pSource)); + + if (!strncmp(pMessage.c_str(), MESSAGE_GET_CRASH_INFOS, sizeof(MESSAGE_GET_CRASH_INFOS) - 1)) + { + vector_crash_infos_t crashInfos = GetCrashInfos(UID); + std::string message = MESSAGE_GET_CRASH_INFOS + crash_infos_to_string(crashInfos); + Send(message, pSource); + } + else if (!strncmp(pMessage.c_str(), MESSAGE_REPORT, sizeof(MESSAGE_REPORT) - 1)) + { + std::string message = pMessage.substr(sizeof(MESSAGE_REPORT) - 1); + map_crash_report_t report = string_to_crash_report(message); + Report(report, UID); + } + else if (!strncmp(pMessage.c_str(), MESSAGE_CREATE_REPORT, sizeof(MESSAGE_CREATE_REPORT) - 1)) + { + std::string UUID = pMessage.substr(sizeof(MESSAGE_CREATE_REPORT) - 1); + map_crash_report_t crashReport = CreateReport(UUID, UID); + std::string message = MESSAGE_CREATE_REPORT + crash_report_to_string(crashReport); + Send(message, pSource); + } + else if (!strncmp(pMessage.c_str(), MESSAGE_DELETE_DEBUG_DUMP, sizeof(MESSAGE_DELETE_DEBUG_DUMP) - 1)) + { + std::string UUID = pMessage.substr(sizeof(MESSAGE_DELETE_DEBUG_DUMP) - 1); + DeleteDebugDump(UUID, UID); + } + else + { + comm_layer_inner_warning("Received unknown message type."); + } +} + +CCommLayerServerSocket::CCommLayerServerSocket() +: CCommLayerServer() +{ + int len; + struct sockaddr_un local; + + unlink(SOCKET_FILE); + if ((m_nSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + throw CABRTException(EXCEP_FATAL, "CCommLayerServerSocket::CCommLayerServerSocket(): Can not create socket."); + } + fcntl(m_nSocket, F_SETFD, FD_CLOEXEC); + local.sun_family = AF_UNIX; + strcpy(local.sun_path, SOCKET_FILE); + len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(m_nSocket, (struct sockaddr *)&local, len) == -1) + { + throw CABRTException(EXCEP_FATAL, "CCommLayerServerSocket::CCommLayerServerSocket(): Can not bind to the socket."); + } + if (listen(m_nSocket, 5) == -1) + { + throw CABRTException(EXCEP_FATAL, "CCommLayerServerSocket::CCommLayerServerSocket(): Can not listen on the socket."); + } + chmod(SOCKET_FILE, SOCKET_PERMISSION); + + m_pGSocket = g_io_channel_unix_new(m_nSocket); + if (!g_io_add_watch(m_pGSocket, + static_cast<GIOCondition>(G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL), + static_cast<GIOFunc>(server_socket_cb), + this)) + { + throw CABRTException(EXCEP_FATAL, "CCommLayerServerSocket::CCommLayerServerSocket(): Can not init g_io_channel."); + } +} + +CCommLayerServerSocket::~CCommLayerServerSocket() +{ + g_io_channel_unref(m_pGSocket); + close(m_nSocket); +} + +vector_crash_infos_t CCommLayerServerSocket::GetCrashInfos(const std::string &pSender) +{ + vector_crash_infos_t crashInfos; + crashInfos = m_pObserver->GetCrashInfos(pSender); + return crashInfos; +} + +map_crash_report_t CCommLayerServerSocket::CreateReport(const std::string &pUUID,const std::string &pSender) +{ + map_crash_report_t crashReport; + crashReport = m_pObserver->CreateReport(pUUID, pSender); + return crashReport; +} + +report_status_t CCommLayerServerSocket::Report(map_crash_report_t pReport, const std::string& pSender) +{ + report_status_t rs; + rs = m_pObserver->Report(pReport, pSender); + return rs; +} + +bool CCommLayerServerSocket::DeleteDebugDump(const std::string& pUUID, const std::string& pSender) +{ + m_pObserver->DeleteDebugDump(pUUID, pSender); + return true; +} + +void CCommLayerServerSocket::Crash(const std::string& arg1) +{ + //Send("(CRASH)New Crash Detected: " + arg1); +} + +void CCommLayerServerSocket::AnalyzeComplete(map_crash_report_t arg1) +{ + //Send("(ANALYZE_COMPLETE)Analyze Complete."); +} + +void CCommLayerServerSocket::Error(const std::string& arg1) +{ + //Send("(ERROR)Error: " + arg1); +} diff --git a/src/Daemon/CommLayerServerSocket.h b/src/Daemon/CommLayerServerSocket.h new file mode 100644 index 0000000..2dc9a7a --- /dev/null +++ b/src/Daemon/CommLayerServerSocket.h @@ -0,0 +1,37 @@ +#include "CommLayerServer.h" +#include "DBusCommon.h" +#include <glib.h> + +#define SOCKET_FILE VAR_RUN"/abrt.socket" +#define SOCKET_PERMISSION 0666 + +class CCommLayerServerSocket : public CCommLayerServer +{ + private: + typedef std::map<int, GIOChannel*> map_clinet_channels_t; + + int m_nSocket; + GIOChannel* m_pGSocket; + map_clinet_channels_t m_mapClientChannels; + + void Send(const std::string& pData, GIOChannel *pDestination); + + static gboolean server_socket_cb(GIOChannel *source, GIOCondition condition, gpointer data); + static gboolean client_socket_cb(GIOChannel *source, GIOCondition condition, gpointer data); + + std::string GetSenderUID(int pSenderSocket); + void ProcessMessage(const std::string& pMessage, GIOChannel *pSource); + + public: + CCommLayerServerSocket(); + virtual ~CCommLayerServerSocket(); + + virtual vector_crash_infos_t GetCrashInfos(const std::string &pSender); + virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pSender); + virtual report_status_t Report(map_crash_report_t pReport, const std::string& pSender); + virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pSender); + + virtual void Crash(const std::string& arg1); + virtual void AnalyzeComplete(map_crash_report_t arg1); + virtual void Error(const std::string& arg1); +}; diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am index c040849..780760b 100644 --- a/src/Daemon/Makefile.am +++ b/src/Daemon/Makefile.am @@ -6,6 +6,9 @@ abrt_SOURCES = \ PluginManager.cpp PluginManager.h \ MiddleWare.cpp MiddleWare.h \ CrashWatcher.cpp CrashWatcher.h \ + CommLayerServer.h CommLayerServer.cpp \ + CommLayerServerSocket.h CommLayerServerSocket.cpp \ + CommLayerServerDBus.h CommLayerServerDBus.cpp \ Daemon.cpp \ Settings.h Settings.cpp abrt_CPPFLAGS = \ |
