diff options
| author | Jiri Moskovcak <jmoskovc@redhat.com> | 2009-05-20 11:21:42 +0200 |
|---|---|---|
| committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2009-05-20 11:21:42 +0200 |
| commit | 2a8110532889efb58370d11cf3db0a059f554b82 (patch) | |
| tree | eb40de22b9d0f5b61500f7a089a5a2903008bc59 /lib | |
| parent | 40d3a846c8fb7dcbc03cf2dfcd911baf0b64987b (diff) | |
| parent | 6e99c8f26bba17cc3b6d4f49a720997d6ff0e5d6 (diff) | |
| download | abrt-2a8110532889efb58370d11cf3db0a059f554b82.tar.gz abrt-2a8110532889efb58370d11cf3db0a059f554b82.tar.xz abrt-2a8110532889efb58370d11cf3db0a059f554b82.zip | |
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'lib')
| -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 | ||||
| -rw-r--r-- | lib/Plugins/FileTransfer.conf | 13 | ||||
| -rw-r--r-- | lib/Plugins/FileTransfer.cpp | 255 | ||||
| -rw-r--r-- | lib/Plugins/FileTransfer.h | 66 | ||||
| -rw-r--r-- | lib/Plugins/Makefile.am | 11 |
10 files changed, 622 insertions, 27 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 diff --git a/lib/Plugins/FileTransfer.conf b/lib/Plugins/FileTransfer.conf new file mode 100644 index 0000000..ffd1607 --- /dev/null +++ b/lib/Plugins/FileTransfer.conf @@ -0,0 +1,13 @@ +# Configuration of the file transfer reporter plugin + +# URL to upload the files to +# supported: ftp, ftps, http, https, scp, sftp, tftp +# for example: ftp://user:password@server.name/directory +# or: scp://user:password@server.name:port/directory etc. +URL = + +#archive type, one of .zip, .tar.gz or .tar.bz2 +ArchiveType = .tar.gz + +#how many times we try to upload the file +RetryCount = 3 diff --git a/lib/Plugins/FileTransfer.cpp b/lib/Plugins/FileTransfer.cpp new file mode 100644 index 0000000..2600caa --- /dev/null +++ b/lib/Plugins/FileTransfer.cpp @@ -0,0 +1,255 @@ +/* + FileTransfer.cpp + + Copyright (C) 2009 Daniel Novotny (dnovotny@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 "FileTransfer.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <iostream> +#include <sstream> +#include <fstream> +#include <curl/curl.h> + +#include "DebugDump.h" +#include "ABRTException.h" +#include "PluginSettings.h" +#include "CommLayerInner.h" + + +using namespace std; +#define HBLEN 255 +#define FILETRANSFER_DIRLIST DEBUG_DUMPS_DIR "/FileTransferDirlist.txt" + +/* FILETRANSFER_DIRLIST */ + +void CFileTransfer::SendFile(const std::string& pURL, + const std::string& pFilename) +{ + FILE * f; + struct stat buf; + CURL * curl; + std::string wholeURL, protocol; + int result, i, count = m_nRetryCount; + int len = pURL.length(); + + if (pURL == "") + { + comm_layer_inner_warning("FileTransfer: URL not specified"); + return; + } + protocol = ""; + i = 0; + while(pURL[i] != ':') + { + protocol += pURL[i]; + i++; + if(i == len) + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::SendFile(): malformed URL, does not contain protocol"); + } + } + + comm_layer_inner_status("Sending archive " + pFilename + " via " + protocol); + + if( pURL[len-1] == '/' ) + { + wholeURL = pURL + pFilename; + } + else + { + wholeURL = pURL + "/" + pFilename; + } + + do + { + f = fopen(pFilename.c_str(),"r"); + if(!f) + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::SendFile(): cannot open archive file "+pFilename); + } + if (stat(pFilename.c_str(), &buf) == -1) + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::SendFile(): cannot stat archive file "+pFilename); + } + curl = curl_easy_init(); + if(!curl) + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::SendFile(): Curl library error."); + } + /* enable uploading */ + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + /* specify target */ + curl_easy_setopt(curl, CURLOPT_URL, wholeURL.c_str()); + /*file handle: passed to the default callback, it will fread() it*/ + curl_easy_setopt(curl, CURLOPT_READDATA, f); + /*get file size*/ + curl_easy_setopt(curl, CURLOPT_INFILESIZE, buf.st_size); + /*everything is done here; result 0 means success*/ + result = curl_easy_perform(curl); + /*goodbye*/ + curl_easy_cleanup(curl); + fclose(f); + } + /*retry the upload if not succesful, wait a bit before next try*/ + while( result!=0 && count-- != 0 && (sleep(20),1) ); + +} + +void CFileTransfer::CreateArchive(const std::string& pArchiveName, + const std::string& pDir) +{ + std::string cmdline; + int result; + + comm_layer_inner_status("Creating an archive..."); + + /*TODO: consider library for archive creation, if there is any*/ + + if(m_sArchiveType == ".tar.gz") + { + cmdline = "tar czf " + pArchiveName + " " + pDir; + } + else if(m_sArchiveType == ".tar.bz2") + { + cmdline = "tar cjf " + pArchiveName + " " + pDir; + } + else if(m_sArchiveType == ".zip") + { + cmdline = "zip " + pArchiveName + " " + pDir + "/*"; + } + else + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::CreateArchive(): unknown/unsupported archive type "+m_sArchiveType); + } + + comm_layer_inner_debug(cmdline); + result = system(cmdline.c_str()); + + if( result != 0 ) + { + throw CABRTException(EXCEP_PLUGIN, "CFileTransfer::CreateArchive(): Error while executing the archiver command."); + } +} + +/*returns the last component of the directory path*/ +std::string CFileTransfer::DirBase(const std::string& pStr) +{ + std::string result; + int i; + + i = pStr.length() - 1; + if(pStr[i] == '/') + { + i--; + } + result=""; + for(; pStr[i] != '/'; i--) + { + result = pStr[i] + result; + } + return result; +} + +void CFileTransfer::Run(const std::string& pActiveDir, const std::string& pArgs) +{ + fstream dirlist; + + comm_layer_inner_status("File Transfer: Creating a report..."); + + if (pArgs == "store") + { + /* store pActiveDir for later sending */ + dirlist.open(FILETRANSFER_DIRLIST, fstream::out | fstream::app ); + dirlist << pActiveDir << endl; + dirlist.close(); + } + else + { + std::string dirname, archivename; + + char hostname[HBLEN]; + + gethostname(hostname,HBLEN); + + dirlist.open(FILETRANSFER_DIRLIST, fstream::in); + if(dirlist.fail()) + { + /* this means there are no reports to send (no crashes, hurray) + which is perfectly OK */ + return; + } + + while(getline(dirlist,dirname), !dirlist.eof()) + { + archivename = std::string(hostname) + "-" + + DirBase(dirname) + m_sArchiveType; + try + { + CreateArchive(archivename,dirname); + SendFile(m_sURL, archivename); + } + catch (CABRTException& e) + { + comm_layer_inner_warning("CFileTransfer::Run(): Cannot create and send an archive: " + e.what()); + comm_layer_inner_status("CFileTransfer::Run(): Cannot create and send an archive: " + e.what()); + } + unlink(archivename.c_str()); + } + + dirlist.close(); + /* all the files we're able to send should be sent now, + starting over with clean table */ + unlink(FILETRANSFER_DIRLIST); + } +} + +void CFileTransfer::LoadSettings(const std::string& pPath) +{ + map_settings_t settings; + plugin_load_settings(pPath, settings); + + if (settings.find("URL")!= settings.end()) + { + m_sURL = settings["URL"]; + } + else + { + comm_layer_inner_warning("FileTransfer: URL not specified"); + } + + if (settings.find("RetryCount")!= settings.end()) + { + m_nRetryCount = atoi(settings["RetryCount"].c_str()); + } + + if (settings.find("ArchiveType")!= settings.end()) + { + /* currently supporting .tar.gz, .tar.bz2 and .zip */ + m_sArchiveType = settings["ArchiveType"]; + if(m_sArchiveType[0] != '.') + { + m_sArchiveType = "." + m_sArchiveType; + } + } + +} diff --git a/lib/Plugins/FileTransfer.h b/lib/Plugins/FileTransfer.h new file mode 100644 index 0000000..0c3a47a --- /dev/null +++ b/lib/Plugins/FileTransfer.h @@ -0,0 +1,66 @@ +/* + FileTransfer.h - header file for the file transfer plugin + - it uploads the file via ftp or sctp + + Copyright (C) 2009 Daniel Novotny (dnovotny@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 FILETRANSFER_H_ +#define FILETRANSFER_H_ + +#include <string> +#include "Plugin.h" +#include "Action.h" + +class CFileTransfer : public CAction +{ + private: + std::string m_sURL; + std::string m_sArchiveType; + int m_nRetryCount; + + void CreateArchive(const std::string& pArchiveName, + const std::string& pDir); + + void SendFile(const std::string& pURL, + const std::string& pFilename); + std::string DirBase(const std::string &pStr); + + public: + CFileTransfer() : + m_nRetryCount(3), + m_sArchiveType(".tar.gz") + {} + virtual ~CFileTransfer() {} + + virtual void LoadSettings(const std::string& pPath); + virtual void Run(const std::string& pActiveDir, + const std::string& pArgs); +}; + + +PLUGIN_INFO(ACTION, + CFileTransfer, + "FileTransfer", + "0.0.5", + "Sends a report via FTP or SCTP", + "dnovotny@redhat.com", + "https://fedorahosted.org/crash-catcher/wiki"); + + +#endif /* FILETRANSFER_H_ */ diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am index 51436f7..67b56ee 100644 --- a/lib/Plugins/Makefile.am +++ b/lib/Plugins/Makefile.am @@ -9,10 +9,11 @@ pluginslib_LTLIBRARIES = libCCpp.la \ libKerneloops.la \ libRunApp.la \ libBugzilla.la \ - libPython.la + libPython.la \ + libFileTransfer.la pluginsconfdir=$(PLUGINS_CONF_DIR) -dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf KerneloopsScanner.conf KerneloopsReporter.conf Bugzilla.conf +dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf KerneloopsScanner.conf KerneloopsReporter.conf Bugzilla.conf FileTransfer.conf # CCpp libCCpp_la_SOURCES = CCpp.cpp CCpp.h PluginSettings.h @@ -55,7 +56,7 @@ libRunApp_la_SOURCES = RunApp.h RunApp.cpp libRunApp_la_LDFLAGS = -avoid-version # Bugzilla -libBugzilla_la_SOURCES = Bugzilla.h Bugzilla.cpp +libBugzilla_la_SOURCES = Bugzilla.h Bugzilla.cpp PluginSettings.h libBugzilla_la_LIBADD = $(XMLRPC_CPP_LIBS) $(XMLRPC_CLIENT_CPP_LIBS) $(NSS_LIBS) libBugzilla_la_LDFLAGS = -avoid-version libBugzilla_la_CPPFLAGS = $(XMLRPC_CPP_CFLAGS) $(XMLRPC_CLIENT_CPP_CFLAGS) $(NSS_CFLAGS) -I$(srcdir)/../CommLayer -I$(srcdir)/../../inc -I$(srcdir)/../MiddleWare -I$(srcdir)/../Utils @@ -66,3 +67,7 @@ libPython_la_SOURCES = Python.h Python.cpp libPython_la_LDFLAGS = -avoid-version libPython_la_CPPFLAGS = $(NSS_CFLAGS) -I$(srcdir)/../CommLayer -I$(srcdir)/../../inc -I$(srcdir)/../MiddleWare -I$(srcdir)/../Utils +libFileTransfer_la_SOURCES = FileTransfer.cpp FileTransfer.h PluginSettings.h +libFileTransfer_la_LDFLAGS = -avoid-version +libFileTransfer_la_LIBADD = $(CURL_LIBS) +libFileTransfer_la_CPPFLAGS = -I$(srcdir)/../CommLayer -I$(srcdir)/../../inc -I$(srcdir)/../MiddleWare -I$(srcdir)/../Utils $(CURL_CFLAGS) -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" |
