diff options
| author | Zdenek Prikryl <zprikryl@redhat.com> | 2009-05-20 11:16:33 +0200 |
|---|---|---|
| committer | Zdenek Prikryl <zprikryl@redhat.com> | 2009-05-20 11:16:33 +0200 |
| commit | 821c30ceca2885836fb2aeafaa03ab0c0f1b1809 (patch) | |
| tree | ed60a68f5ca8067cc9b7f1285c1b15dd648e7238 /lib/CommLayer | |
| parent | bc12d93a46c87ccf647f83b4eafd4378d19b9e29 (diff) | |
| download | abrt-821c30ceca2885836fb2aeafaa03ab0c0f1b1809.tar.gz abrt-821c30ceca2885836fb2aeafaa03ab0c0f1b1809.tar.xz abrt-821c30ceca2885836fb2aeafaa03ab0c0f1b1809.zip | |
initial unix socket interface
Diffstat (limited to 'lib/CommLayer')
| -rw-r--r-- | lib/CommLayer/CommLayerServer.h | 10 | ||||
| -rw-r--r-- | lib/CommLayer/CommLayerServerDBus.cpp | 12 | ||||
| -rw-r--r-- | lib/CommLayer/CommLayerServerDBus.h | 14 | ||||
| -rw-r--r-- | lib/CommLayer/CommLayerServerSocket.cpp | 230 | ||||
| -rw-r--r-- | lib/CommLayer/CommLayerServerSocket.h | 36 | ||||
| -rw-r--r-- | lib/CommLayer/Makefile.am | 2 |
6 files changed, 280 insertions, 24 deletions
diff --git a/lib/CommLayer/CommLayerServer.h b/lib/CommLayer/CommLayerServer.h index f781813..77cf7ef 100644 --- a/lib/CommLayer/CommLayerServer.h +++ b/lib/CommLayer/CommLayerServer.h @@ -34,12 +34,12 @@ class CCommLayerServer{ void Attach(CObserver *pObs); void Detach(CObserver *pObs); void Notify(const std::string& pMessage); - - virtual vector_crash_infos_t GetCrashInfos(const std::string &pDBusSender) = 0; - virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pDBusSender) = 0; + + 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 bool Report(map_crash_report_t pReport) = 0; - virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender) = 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) {} diff --git a/lib/CommLayer/CommLayerServerDBus.cpp b/lib/CommLayer/CommLayerServerDBus.cpp index b9024f6..8f4b3bf 100644 --- a/lib/CommLayer/CommLayerServerDBus.cpp +++ b/lib/CommLayer/CommLayerServerDBus.cpp @@ -31,17 +31,17 @@ CCommLayerServerDBus::~CCommLayerServerDBus() delete m_pDispatcher; } -vector_crash_infos_t CCommLayerServerDBus::GetCrashInfos(const std::string &pDBusSender) +vector_crash_infos_t CCommLayerServerDBus::GetCrashInfos(const std::string &pSender) { vector_crash_infos_t crashInfos; - unsigned long unix_uid = m_pConn->sender_unix_uid(pDBusSender.c_str()); + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); crashInfos = m_pObserver->GetCrashInfos(to_string(unix_uid)); return crashInfos; } -map_crash_report_t CCommLayerServerDBus::CreateReport(const std::string &pUUID,const std::string &pDBusSender) +map_crash_report_t CCommLayerServerDBus::CreateReport(const std::string &pUUID,const std::string &pSender) { - unsigned long unix_uid = m_pConn->sender_unix_uid(pDBusSender.c_str()); + 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; @@ -53,9 +53,9 @@ bool CCommLayerServerDBus::Report(map_crash_report_t pReport) return true; } -bool CCommLayerServerDBus::DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender) +bool CCommLayerServerDBus::DeleteDebugDump(const std::string& pUUID, const std::string& pSender) { - unsigned long unix_uid = m_pConn->sender_unix_uid(pDBusSender.c_str()); + unsigned long unix_uid = m_pConn->sender_unix_uid(pSender.c_str()); m_pObserver->DeleteDebugDump(pUUID,to_string(unix_uid)); return true; } diff --git a/lib/CommLayer/CommLayerServerDBus.h b/lib/CommLayer/CommLayerServerDBus.h index b5d3180..3efe480 100644 --- a/lib/CommLayer/CommLayerServerDBus.h +++ b/lib/CommLayer/CommLayerServerDBus.h @@ -18,14 +18,14 @@ class CCommLayerServerDBus public: CCommLayerServerDBus(); virtual ~CCommLayerServerDBus(); - - virtual vector_crash_infos_t GetCrashInfos(const std::string &pDBusSender); - virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pDBusSender); + + 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 bool Report(map_crash_report_t pReport); - virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender); + virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pSender); - void Crash(const std::string& arg1); - void AnalyzeComplete(map_crash_report_t arg1); - void Error(const std::string& arg1); + 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/lib/CommLayer/CommLayerServerSocket.cpp b/lib/CommLayer/CommLayerServerSocket.cpp index b1ae434..74ba270 100644 --- a/lib/CommLayer/CommLayerServerSocket.cpp +++ b/lib/CommLayer/CommLayerServerSocket.cpp @@ -1,14 +1,240 @@ #include "CommLayerServerSocket.h" +#include "CommLayerInner.h" +#include "ABRTException.h" +#include "SocketCrashTypes.h" +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> #include <iostream> +#include <sstream> +void CCommLayerServerSocket::Send(const std::string& pData, GIOChannel *pDestination) +{ + ssize_t ret = -1; + gsize len = 0; + int offset = 0; + GError *err = NULL; + gchar* message = new gchar[ pData.length() + 3 ]; + memcpy(message, pData.c_str(), pData.length()); + message[pData.length()] = ' '; + message[pData.length() + 1] = '\n'; + message[pData.length() + 2] = '\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] == 23 &&*/ message[message.length() - 1] == '\n') + { + receivingMessage = false; + message = message.substr(0, message.length() - 1); + } + } + + 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 klinet 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)); + //TODO: rewrite to .compare() + 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)) + { + map_crash_report_t report = string_to_crash_report(pMessage); + Report(report); + } + 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() { - std::cout << "CCommLayerServerSocket init" << std::endl; + int len; + struct sockaddr_un local; + + if ((m_nSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + throw CABRTException(EXCEP_FATAL, "CCommLayerServerSocket::CCommLayerServerSocket(): Can not create socket."); + } + + local.sun_family = AF_UNIX; + strcpy(local.sun_path, SOCKET_PATH); + unlink(local.sun_path); + 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."); + } + + 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() { - std::cout << "Cleaning up Socket" << std::endl; + 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; +} + +bool CCommLayerServerSocket::Report(map_crash_report_t pReport) +{ + m_pObserver->Report(pReport); + return true; +} + +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/lib/CommLayer/CommLayerServerSocket.h b/lib/CommLayer/CommLayerServerSocket.h index d5604f1..e816ada 100644 --- a/lib/CommLayer/CommLayerServerSocket.h +++ b/lib/CommLayer/CommLayerServerSocket.h @@ -1,10 +1,40 @@ #include "CommLayerServer.h" +#include <glib.h> -class CCommLayerServerSocket -: public CCommLayerServer +#define SOCKET_PATH "/tmp/abrt.socket" + +#define MESSAGE_DELETE_DEBUG_DUMP "(DELETE_DEBUG_DUMP)" +#define MESSAGE_GET_CRASH_INFOS "(GET_CRASH_INFOS)" +#define MESSAGE_REPORT "(REPORT)" +#define MESSAGE_CREATE_REPORT "(CREATE_REPORT)" + +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(); - ~CCommLayerServerSocket(); + virtual ~CCommLayerServerSocket(); + + virtual vector_crash_infos_t GetCrashInfos(const std::string &pDBusSender); + virtual map_crash_report_t CreateReport(const std::string &pUUID,const std::string &pDBusSender); + virtual bool Report(map_crash_report_t pReport); + virtual bool DeleteDebugDump(const std::string& pUUID, const std::string& pDBusSender); + + 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/lib/CommLayer/Makefile.am b/lib/CommLayer/Makefile.am index 1e204ff..3f10888 100644 --- a/lib/CommLayer/Makefile.am +++ b/lib/CommLayer/Makefile.am @@ -12,7 +12,7 @@ libABRTCommLayer_la_CPPFLAGS = -Wall -Werror -I$(srcdir)/../../lib/MiddleWare\ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(GLIB_CFLAGS) $(DBUSCPP_CFLAGS) \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ - -DCONF_DIR=\"$(CONF_DIR)\" + -DCONF_DIR=\"$(CONF_DIR)\" -D_GNU_SOURCE #check_PROGRAMS = test #test_SOURCES = test.cpp |
