summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2009-05-20 11:21:42 +0200
committerJiri Moskovcak <jmoskovc@redhat.com>2009-05-20 11:21:42 +0200
commit2a8110532889efb58370d11cf3db0a059f554b82 (patch)
treeeb40de22b9d0f5b61500f7a089a5a2903008bc59 /lib
parent40d3a846c8fb7dcbc03cf2dfcd911baf0b64987b (diff)
parent6e99c8f26bba17cc3b6d4f49a720997d6ff0e5d6 (diff)
downloadabrt-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.h10
-rw-r--r--lib/CommLayer/CommLayerServerDBus.cpp12
-rw-r--r--lib/CommLayer/CommLayerServerDBus.h14
-rw-r--r--lib/CommLayer/CommLayerServerSocket.cpp230
-rw-r--r--lib/CommLayer/CommLayerServerSocket.h36
-rw-r--r--lib/CommLayer/Makefile.am2
-rw-r--r--lib/Plugins/FileTransfer.conf13
-rw-r--r--lib/Plugins/FileTransfer.cpp255
-rw-r--r--lib/Plugins/FileTransfer.h66
-rw-r--r--lib/Plugins/Makefile.am11
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)\"