summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Plugins/CCpp.cpp4
-rw-r--r--lib/Plugins/Catcut.conf4
-rw-r--r--lib/Plugins/FileTransfer.conf3
-rw-r--r--lib/Plugins/FileTransfer.cpp171
-rw-r--r--lib/Plugins/Firefox.cpp8
-rw-r--r--lib/Plugins/Kerneloops.conf3
-rw-r--r--lib/Plugins/Logger.conf2
-rw-r--r--lib/Plugins/Mailx.conf7
-rw-r--r--lib/Plugins/Python.conf2
-rw-r--r--lib/Plugins/TicketUploader.conf6
-rw-r--r--lib/Plugins/TicketUploader.cpp137
-rw-r--r--lib/Plugins/abrt-FileTransfer.745
-rw-r--r--lib/Utils/spawn.cpp2
-rw-r--r--src/Daemon/Settings.cpp5
-rw-r--r--src/Daemon/abrt.conf7
-rw-r--r--src/Hooks/hooklib.cpp4
16 files changed, 198 insertions, 212 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp
index 28e6bac3..5838bc45 100644
--- a/lib/Plugins/CCpp.cpp
+++ b/lib/Plugins/CCpp.cpp
@@ -417,9 +417,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir,
char buff[1024];
while (fgets(buff, sizeof(buff), pipeout_fp))
{
- int last = strlen(buff) - 1;
- if (last >= 0 && buff[last] == '\n')
- buff[last] = '\0';
+ strchrnul(buff, '\n')[0] = '\0';
if (strncmp(buff, "MISSING:", 8) == 0)
{
diff --git a/lib/Plugins/Catcut.conf b/lib/Plugins/Catcut.conf
index a0249fd1..6cafc2bd 100644
--- a/lib/Plugins/Catcut.conf
+++ b/lib/Plugins/Catcut.conf
@@ -1,4 +1,5 @@
-Enabled=1
+Enabled = 1
+
# Catcut URL
CatcutURL = http://127.0.0.1:8080/catcut/xmlrpc
# yes means that ssl certificates will not be checked
@@ -7,4 +8,3 @@ NoSSLVerify = no
Login = gavin
# your password
Password = junk
-Enabled = yes \ No newline at end of file
diff --git a/lib/Plugins/FileTransfer.conf b/lib/Plugins/FileTransfer.conf
index c92eaeec..1ceccece 100644
--- a/lib/Plugins/FileTransfer.conf
+++ b/lib/Plugins/FileTransfer.conf
@@ -1,3 +1,5 @@
+Enabled = yes
+
# Configuration of the file transfer reporter plugin
# it takes one parameter:
# store - just save information about crash
@@ -17,4 +19,3 @@ RetryCount = 3
#how long we wait between we retry the upload (in seconds)
RetryDelay = 20
-Enabled = yes \ No newline at end of file
diff --git a/lib/Plugins/FileTransfer.cpp b/lib/Plugins/FileTransfer.cpp
index e28fbbee..4d317c8d 100644
--- a/lib/Plugins/FileTransfer.cpp
+++ b/lib/Plugins/FileTransfer.cpp
@@ -22,9 +22,6 @@
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
-#include <iostream>
-#include <sstream>
-#include <fstream>
#include <zip.h>
#include <libtar.h>
#include <bzlib.h>
@@ -60,22 +57,21 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename)
update_client(_("Sending archive %s to %s"), pFilename, pURL);
- string wholeURL = concat_path_file(pURL, pFilename);
+ string wholeURL = concat_path_file(pURL, strrchr(pFilename, '/') ? : pFilename);
int count = m_nRetryCount;
while (1)
{
- FILE *f;
- struct stat buf;
- CURL *curl;
-
- f = fopen(pFilename, "r");
+ FILE *f = fopen(pFilename, "r");
if (!f)
{
throw CABRTException(EXCEP_PLUGIN, "Can't open archive file '%s'", pFilename);
}
+
+ struct stat buf;
fstat(fileno(f), &buf); /* never fails */
- curl = xcurl_easy_init();
+
+ CURL *curl = xcurl_easy_init();
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
@@ -83,8 +79,10 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename)
/* FILE handle: passed to the default callback, it will fread() it */
curl_easy_setopt(curl, CURLOPT_READDATA, f);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)buf.st_size);
+
/* everything is done here; result 0 means success */
int result = curl_easy_perform(curl);
+
curl_easy_cleanup(curl);
fclose(f);
if (result == 0 || --count <= 0)
@@ -95,11 +93,9 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename)
}
/*
-walks through the directory and applies a function with one
-parameter "something" to each filename,
-now used in create_zip, but can be useful for some future
-archivers as well
-*/
+ * Walks through the directory and applies a function with one
+ * parameter "something" to each filename.
+ */
static void traverse_directory(const char *directory, void *something,
void (*func)(void *, const char *))
{
@@ -122,20 +118,26 @@ static void traverse_directory(const char *directory, void *something,
closedir(dp);
}
-static void add_to_zip(void * z, const char * filename)
+static void add_to_zip(void *z, const char *filename)
{
struct zip_source *s;
- s = zip_source_file( (struct zip *)z, filename, 0, 0);
- zip_add( (struct zip *)z, filename, s);
+ s = zip_source_file((struct zip *)z, filename, /*start:*/ 0, /*len:*/ 0);
+ if (s)
+ {
+ if (zip_add((struct zip *)z, filename, s) == -1)
+ {
+ zip_source_free(s);
+ }
+ /* else: don't call zip_source_free(s), successful zip_add consumes it */
+ }
}
-
-static void create_zip(const char * archive_name, const char * directory)
+static void create_zip(const char *archive_name, const char *directory)
{
- struct zip * z;
+ struct zip *z;
- z = zip_open(archive_name, ZIP_CREATE, NULL);
+ z = zip_open(archive_name, ZIP_CREATE, /*errorp:*/ NULL);
if (z == NULL)
{
return;
@@ -144,7 +146,7 @@ static void create_zip(const char * archive_name, const char * directory)
zip_close(z);
}
-static void create_tar(const char * archive_name, const char * directory)
+static void create_tar(const char *archive_name, const char *directory)
{
TAR *tar;
@@ -156,89 +158,86 @@ static void create_tar(const char * archive_name, const char * directory)
tar_close(tar);
}
-static void create_targz(const char * archive_name, const char * directory)
+static void create_targz(const char *archive_name, const char *directory)
{
- char * name_without_gz;
- char buf[BUFSIZ];
- FILE * f;
- ssize_t bytesRead;
- gzFile gz;
-
- name_without_gz = xstrdup(archive_name);
+ char *name_without_gz = xstrdup(archive_name);
strrchr(name_without_gz, '.')[0] = '\0';
+
create_tar(name_without_gz, directory);
- f = fopen(name_without_gz, "r");
- if (f == NULL)
+ int fd = open(name_without_gz, O_RDONLY);
+ if (fd < 0)
{
-//TODO: we leak uncompressed tar file on disk??
+ remove(name_without_gz);
free(name_without_gz);
return;
}
- gz = gzopen(archive_name, "w");
+
+ gzFile gz = gzopen(archive_name, "w");
if (gz == NULL)
{
- fclose(f);
+ close(fd);
+ remove(name_without_gz);
free(name_without_gz);
return;
}
- while ((bytesRead = fread(buf, 1, BUFSIZ, f)) > 0)
+ char buf[BUFSIZ];
+ ssize_t bytesRead;
+ while ((bytesRead = full_read(fd, buf, BUFSIZ)) > 0)
{
- gzwrite(gz, buf, bytesRead);
+ gzwrite(gz, buf, bytesRead); // TODO: check that return value == bytesRead
}
+
gzclose(gz);
- fclose(f);
+ close(fd);
remove(name_without_gz);
free(name_without_gz);
}
static void create_tarbz2(const char * archive_name, const char * directory)
{
- char * name_without_bz2;
- char buf[BUFSIZ];
- FILE * f;
- ssize_t bytesRead;
- int tarFD;
- int bzError;
- BZFILE * bz;
-#define BLOCK_MULTIPLIER 7
-
- name_without_bz2 = xstrdup(archive_name);
+ char *name_without_bz2 = xstrdup(archive_name);
strrchr(name_without_bz2, '.')[0] = '\0';
+
create_tar(name_without_bz2, directory);
- tarFD = open(name_without_bz2, O_RDONLY);
+ int tarFD = open(name_without_bz2, O_RDONLY);
if (tarFD == -1)
{
+ remove(name_without_bz2);
free(name_without_bz2);
return;
}
- f = fopen(archive_name, "w");
+ FILE *f = fopen(archive_name, "w");
if (f == NULL)
{
-//TODO: we leak uncompressed tar file on disk??
close(tarFD);
+ remove(name_without_bz2);
free(name_without_bz2);
return;
}
- bz = BZ2_bzWriteOpen(&bzError, f, BLOCK_MULTIPLIER, 0, 0);
+ int bzError;
+ BZFILE *bz = BZ2_bzWriteOpen(&bzError, f, /*BLOCK_MULTIPLIER:*/ 7, 0, 0);
if (bz == NULL)
{
- close(tarFD);
fclose(f);
+ close(tarFD);
+ remove(name_without_bz2);
free(name_without_bz2);
return;
}
+ char buf[BUFSIZ];
+ ssize_t bytesRead;
while ((bytesRead = read(tarFD, buf, BUFSIZ)) > 0)
{
BZ2_bzWrite(&bzError, bz, buf, bytesRead);
}
- BZ2_bzWriteClose(&bzError, bz, 0, NULL, NULL);
- close(tarFD);
+ BZ2_bzWriteClose(&bzError, bz, 0, NULL, NULL);
fclose(f);
+ close(tarFD);
remove(name_without_bz2);
free(name_without_bz2);
}
@@ -289,23 +288,31 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs)
{
update_client(_("File Transfer: Creating a report..."));
+ if (strcmp(pArgs, "store") == 0)
+ {
+ /* Remember pActiveDir for later sending */
+ FILE *dirlist = fopen(FILETRANSFER_DIRLIST, "a");
+ fprintf(dirlist, "%s\n", pActionDir);
+ fclose(dirlist);
+ VERB3 log("Remembered '%s' for future file transfer", pActionDir);
+ return;
+ }
+
char hostname[HBLEN];
gethostname(hostname, HBLEN-1);
hostname[HBLEN-1] = '\0';
- fstream dirlist;
- if (strcmp(pArgs, "store") == 0)
+ char tmpdir_name[] = "/tmp/abrtuploadXXXXXX";
+ /* mkdtemp does mkdir(xxx, 0700), should be safe (is it?) */
+ if (mkdtemp(tmpdir_name) == NULL)
{
- /* store pActiveDir for later sending */
- dirlist.open(FILETRANSFER_DIRLIST, fstream::out | fstream::app);
- dirlist << pActionDir << endl;
- dirlist.close();
+ throw CABRTException(EXCEP_PLUGIN, "Can't mkdir a temporary directory in /tmp");
}
- else if (strcmp(pArgs, "one") == 0)
+
+ if (strcmp(pArgs, "one") == 0)
{
- /* just send one archive */
-//TODO: where are we creating it??!! In cwd, which may well be / ??!!!
- string archivename = ssprintf("%s-%s%s", hostname, DirBase(pActionDir).c_str(), m_sArchiveType.c_str());
+ /* Just send one archive */
+ string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname, DirBase(pActionDir).c_str(), m_sArchiveType.c_str());
try
{
CreateArchive(archivename.c_str(), pActionDir);
@@ -319,35 +326,43 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs)
}
else
{
- dirlist.open(FILETRANSFER_DIRLIST, fstream::in);
- if (dirlist.fail())
+ /* Tar up and send all remebered directories */
+ FILE *dirlist = fopen(FILETRANSFER_DIRLIST, "r");
+ if (!dirlist)
{
- /* this means there are no reports to send (no crashes, hurray)
- which is perfectly OK */
- return;
+ /* not an error */
+ VERB3 log("No saved crashes to transfer");
+ goto del_tmp_dir;
}
- string dirname;
- while (getline(dirlist, dirname), dirlist.good())
+ char dirname[PATH_MAX];
+ while (fgets(dirname, sizeof(dirname), dirlist) != NULL)
{
- string archivename = ssprintf("%s-%s%s", hostname, DirBase(dirname.c_str()).c_str(), m_sArchiveType.c_str());
+ strchrnul(dirname, '\n')[0] = '\0';
+ string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname, DirBase(dirname).c_str(), m_sArchiveType.c_str());
try
{
- CreateArchive(archivename.c_str(), dirname.c_str());
+ VERB3 log("Creating archive '%s' of dir '%s'", archivename.c_str(), dirname);
+ CreateArchive(archivename.c_str(), dirname);
+ VERB3 log("Sending archive to '%s'", m_sURL.c_str());
SendFile(m_sURL.c_str(), archivename.c_str());
}
catch (CABRTException& e)
{
error_msg(_("Can't create and send an archive %s"), e.what());
}
+ VERB3 log("Deleting archive '%s'", archivename.c_str());
unlink(archivename.c_str());
}
- dirlist.close();
+ fclose(dirlist);
/* all the files we're able to send should be sent now,
starting over with clean table */
unlink(FILETRANSFER_DIRLIST);
}
+
+ del_tmp_dir:
+ rmdir(tmpdir_name);
}
void CFileTransfer::SetSettings(const map_plugin_settings_t& pSettings)
@@ -361,10 +376,6 @@ void CFileTransfer::SetSettings(const map_plugin_settings_t& pSettings)
{
m_sURL = it->second;
}
- else
- {
- error_msg(_("FileTransfer: URL not specified"));
- }
it = pSettings.find("RetryCount");
if (it != end)
diff --git a/lib/Plugins/Firefox.cpp b/lib/Plugins/Firefox.cpp
index e8b12f56..98d892b7 100644
--- a/lib/Plugins/Firefox.cpp
+++ b/lib/Plugins/Firefox.cpp
@@ -623,9 +623,7 @@ Another application is holding the yum lock, cannot continue
std::string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1));
while (fgets(buff, sizeof(buff), pipeout_fp))
{
- int last = strlen(buff) - 1;
- if (last >= 0 && buff[last] == '\n')
- buff[last] = '\0';
+ strchrnul(buff, '\n')[0] = '\0';
log("%s", buff);
update_client("%s", buff); /* maybe only if buff != ""? */
@@ -712,9 +710,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
char buff[1024];
while (fgets(buff, sizeof(buff), pipeout_fp))
{
- int last = strlen(buff) - 1;
- if (last >= 0 && buff[last] == '\n')
- buff[last] = '\0';
+ strchrnul(buff, '\n')[0] = '\0';
if (strncmp(buff, "MISSING:", 8) == 0)
{
diff --git a/lib/Plugins/Kerneloops.conf b/lib/Plugins/Kerneloops.conf
index 1db2436f..4d6bd469 100644
--- a/lib/Plugins/Kerneloops.conf
+++ b/lib/Plugins/Kerneloops.conf
@@ -1,3 +1,5 @@
+Enabled = yes
+
# Do we want kernel oopses to be visible to any user?
# Set to "yes" for compatibility with kerneloops.org tool.
InformAllUsers = yes
@@ -15,4 +17,3 @@ SysLogFile = /var/log/messages
# KerneloopsReporter configuration
##################################
SubmitURL = http://submit.kerneloops.org/submitoops.php
-Enabled = yes \ No newline at end of file
diff --git a/lib/Plugins/Logger.conf b/lib/Plugins/Logger.conf
index 8809963c..f96c5b80 100644
--- a/lib/Plugins/Logger.conf
+++ b/lib/Plugins/Logger.conf
@@ -1,6 +1,6 @@
# Configuration for Logger plugin
+Enabled = yes
LogPath = /var/log/abrt.log
AppendLogs = yes
-Enabled = yes
diff --git a/lib/Plugins/Mailx.conf b/lib/Plugins/Mailx.conf
index de19709f..ccd14292 100644
--- a/lib/Plugins/Mailx.conf
+++ b/lib/Plugins/Mailx.conf
@@ -1,8 +1,8 @@
# Configuration to Email reporter plugin
-# it takes one parameter: subject in "", if it isn't specified, then a default
-# subject is taken
+Enabled = yes
-# Subject of an emain
+# In abrt.conf, plugin takes one parameter: subject (in "" if you need to embed spaces).
+# If it isn't specified, then a default subject is taken from this file
Subject = "[abrt] crash report"
# Your Email
@@ -13,4 +13,3 @@ EmailTo = root@localhost
# Warning! enabling this may cause sending a lot of MB via email
SendBinaryData = no
-Enabled = yes \ No newline at end of file
diff --git a/lib/Plugins/Python.conf b/lib/Plugins/Python.conf
index 75d22298..3201c6da 100644
--- a/lib/Plugins/Python.conf
+++ b/lib/Plugins/Python.conf
@@ -1 +1 @@
-Enabled = yes \ No newline at end of file
+Enabled = yes
diff --git a/lib/Plugins/TicketUploader.conf b/lib/Plugins/TicketUploader.conf
index ad5f6d28..b6e9c5f3 100644
--- a/lib/Plugins/TicketUploader.conf
+++ b/lib/Plugins/TicketUploader.conf
@@ -1,5 +1,3 @@
-
-
# Customer = "Example Inc."
# Ticket = IT12345
# Encrypt = yes
@@ -16,7 +14,3 @@
#how long we wait between we retry the upload (in seconds)
#RetryDelay = 20
-
-
-
-
diff --git a/lib/Plugins/TicketUploader.cpp b/lib/Plugins/TicketUploader.cpp
index b273ae8b..77d20919 100644
--- a/lib/Plugins/TicketUploader.cpp
+++ b/lib/Plugins/TicketUploader.cpp
@@ -18,8 +18,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string>
-#include <fstream>
-#include <sstream>
#include "abrtlib.h"
#include "abrt_xmlrpc.h" /* for xcurl_easy_init */
#include "TicketUploader.h"
@@ -41,18 +39,12 @@ CTicketUploader::~CTicketUploader()
{}
-static void Error(const char *msg)
-{
- update_client("%s", msg);
- throw CABRTException(EXCEP_PLUGIN, msg);
-}
-
static void RunCommand(const char *cmd)
{
int retcode = system(cmd);
if (retcode)
{
- Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode);
}
}
@@ -61,20 +53,21 @@ static string ReadCommand(const char *cmd)
FILE* fp = popen(cmd, "r");
if (!fp)
{
- Error(ssprintf("error running '%s'", cmd).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "Error running '%s'", cmd);
}
string result;
char buff[1024];
while (fgets(buff, sizeof(buff), fp) != NULL)
{
+ strchrnul(buff, '\n')[0] = '\0';
result += buff;
}
int retcode = pclose(fp);
if (retcode)
{
- Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode);
}
return result;
@@ -85,7 +78,7 @@ static void WriteCommand(const char *cmd, const char *input)
FILE* fp = popen(cmd, "w");
if (!fp)
{
- Error(ssprintf("error running '%s'", cmd).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "error running '%s'", cmd);
}
/* Hoping it's not too big to get us forever blocked... */
@@ -94,7 +87,7 @@ static void WriteCommand(const char *cmd, const char *input)
int retcode = pclose(fp);
if (retcode)
{
- Error(ssprintf("'%s' exited with %d", cmd, retcode).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "'%s' exited with %d", cmd, retcode);
}
}
@@ -150,11 +143,23 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename)
}
+static void write_str_to_file(const char *str, const char *path, const char *fname)
+{
+ string ofile_name = concat_path_file(path, fname);
+ FILE *ofile = fopen(ofile_name.c_str(), "w");
+ if (!ofile)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "Can't open '%s'", ofile_name.c_str());
+ }
+ fprintf(ofile, "%s\n", str);
+ fclose(ofile);
+}
+
string CTicketUploader::Report(const map_crash_data_t& pCrashData,
const map_plugin_settings_t& pSettings,
const char *pArgs)
{
- update_client(_("Creating an TicketUploader report..."));
+ update_client(_("Creating a TicketUploader report..."));
// Get ticket name, customer name, and do_encrypt from config settings
string customer_name = m_sCustomer;
@@ -163,65 +168,52 @@ string CTicketUploader::Report(const map_crash_data_t& pCrashData,
bool do_encrypt = m_bEncrypt;
bool do_upload = m_bUpload;
- bool have_ticket_name = false;
- if (ticket_name == "")
+ bool have_ticket_name = (ticket_name != "");
+ if (!have_ticket_name)
{
ticket_name = "TicketUploader-newticket";
}
- else
- {
- have_ticket_name = true;
- }
// Format the time to add to the file name
- const int timebufmax = 256;
- char timebuf[timebufmax];
+ char timebuf[256];
time_t curtime = time(NULL);
- if (!strftime(timebuf, timebufmax, "-%G%m%d%k%M%S", gmtime(&curtime)))
- {
- Error("Can't format time");
- }
+ strftime(timebuf, sizeof(timebuf), "-%Y%m%d%H%M%S", gmtime(&curtime));
- // Create a tmp work directory, and within that the directory
- // that will be the root of the tarball
+ // Create a tmp work directory, and within that
+ // create the "<ticketname>-yyyymmddhhmmss" directory
+ // which will be the root of the tarball
string file_name = ticket_name + timebuf;
- char tmpdir_name[] = "/tmp/rhuploadXXXXXX";
+ char tmpdir_name[] = "/tmp/abrtuploadXXXXXX";
if (mkdtemp(tmpdir_name) == NULL)
{
- Error("Can't mkdir a temporary directory in /tmp");
+ throw CABRTException(EXCEP_PLUGIN, "Can't mkdir a temporary directory in /tmp");
}
string tmptar_name = concat_path_file(tmpdir_name, file_name.c_str());
- if (mkdir(tmptar_name.c_str(), S_IRWXU))
+ if (mkdir(tmptar_name.c_str(), 0700))
{
- Error(ssprintf("Can't mkdir '%s'", tmptar_name.c_str()).c_str());
+ throw CABRTException(EXCEP_PLUGIN, "Can't mkdir '%s'", tmptar_name.c_str());
}
- // Copy each entry into the tarball root,
- // files are simply copied, strings are written to a file
+ // Copy each entry into the tarball root.
+ // Files are simply copied, strings are written to a file
map_crash_data_t::const_iterator it;
for (it = pCrashData.begin(); it != pCrashData.end(); it++)
{
+ const char *content = it->second[CD_CONTENT].c_str();
if (it->second[CD_TYPE] == CD_TXT)
{
- string ofile_name = concat_path_file(tmptar_name.c_str(), it->first.c_str());
- ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary);
- if (!ofile)
- {
- Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str());
- }
- ofile << it->second[CD_CONTENT] << endl;
- ofile.close();
+ write_str_to_file(content, tmptar_name.c_str(), it->first.c_str());
}
else if (it->second[CD_TYPE] == CD_BIN)
{
string ofile_name = concat_path_file(tmptar_name.c_str(), it->first.c_str());
- if (copy_file(it->second[CD_CONTENT].c_str(), ofile_name.c_str(), 0644) < 0)
+ if (copy_file(content, ofile_name.c_str(), 0644) < 0)
{
throw CABRTException(EXCEP_PLUGIN,
"Can't copy '%s' to '%s'",
- it->second[CD_CONTENT].c_str(),
+ content,
ofile_name.c_str()
);
}
@@ -231,25 +223,11 @@ string CTicketUploader::Report(const map_crash_data_t& pCrashData,
// add ticket_name and customer name to tarball
if (have_ticket_name)
{
- string ofile_name = tmptar_name + "/TICKET";
- ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary);
- if (!ofile)
- {
- Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str());
- }
- ofile << ticket_name << endl;
- ofile.close();
+ write_str_to_file(ticket_name.c_str(), tmptar_name.c_str(), "TICKET");
}
if (customer_name != "")
{
- string ofile_name = tmptar_name + "/CUSTOMER";
- ofstream ofile(ofile_name.c_str(), fstream::trunc|fstream::binary);
- if (!ofile)
- {
- Error(ssprintf("Can't open '%s'", ofile_name.c_str()).c_str());
- }
- ofile << customer_name << endl;
- ofile.close();
+ write_str_to_file(customer_name.c_str(), tmptar_name.c_str(), "CUSTOMER");
}
// Create the compressed tarball
@@ -328,21 +306,19 @@ string CTicketUploader::Report(const map_crash_data_t& pCrashData,
}
msg += "END:\n";
- /* warn the client: */
+ // warn the client (why _warn_? it's not an error, maybe update_client?):
error_msg("%s", msg.c_str());
string ret;
if (do_upload)
{
- string xx = _("report sent to ") + upload_url + '/' + outfile_basename;
- update_client("%s", xx.c_str());
- ret = xx;
+ ret = _("report sent to ") + upload_url + '/' + outfile_basename;
+ update_client("%s", ret.c_str());
}
else
{
- string xx = _("report copied to /tmp/") + outfile_basename;
- update_client("%s", xx.c_str());
- ret = xx;
+ ret = _("report copied to /tmp/") + outfile_basename;
+ update_client("%s", ret.c_str());
}
// delete the temporary directory
@@ -352,6 +328,28 @@ string CTicketUploader::Report(const map_crash_data_t& pCrashData,
return ret;
}
+static bool is_string_safe(const char *str)
+{
+ const char *p = str;
+ while (*p)
+ {
+ unsigned char c = *p;
+ if ((c < '0' || c > '9')
+ && c != '_'
+ && c != '-'
+ ) {
+ c |= 0x20; // tolower
+ if (c < 'a' || c > 'z')
+ {
+ return false;
+ }
+ }
+ // only 0-9, -, _, A-Z, a-z reach this point
+ p++;
+ }
+ return true;
+}
+
void CTicketUploader::SetSettings(const map_plugin_settings_t& pSettings)
{
m_pSettings = pSettings;
@@ -363,8 +361,11 @@ void CTicketUploader::SetSettings(const map_plugin_settings_t& pSettings)
{
m_sCustomer = it->second;
}
+ // We use m_sTicket as part of filename,
+ // and we use resulting filename in system("cd %s; ...", filename) etc,
+ // so we are very paraniod about allowed chars
it = pSettings.find("Ticket");
- if (it != end)
+ if (it != end && is_string_safe(it->second.c_str()))
{
m_sTicket = it->second;
}
diff --git a/lib/Plugins/abrt-FileTransfer.7 b/lib/Plugins/abrt-FileTransfer.7
index 132bfcde..a721dd81 100644
--- a/lib/Plugins/abrt-FileTransfer.7
+++ b/lib/Plugins/abrt-FileTransfer.7
@@ -18,24 +18,17 @@ The plugin is invoked in the \fIabrt.conf\fP file, usually in the
\fIActionsAndReporters\fP option and/or the \fI[cron]\fP section.
There are two modes of invocation:
.P
-* If you use the parameter
-\fI"store"\fP, the plugin stores a record of the occurrence of
-the crash in its internal list.
+* Specify \fIFileTransfer(one)\fP in ActionsAndReporters directive.
+Immediately after crash is detected, the plugin transfers crash data
+to the server specified in the \fIFileTransfer.conf\fP configuration file.
.P
-* If you use the parameter
-\fI"one"\fP, the plugin will transfer this specific crash,
-on which it was invoked, without storing it in the internal
-list.
-.P
-* If you use some other parameter, or no parameter at all, the
-plugin will iterate through the internal list and will send
-every recorded crash to the server specified in the \fIFileTransfer.conf\fP
-configuration file. After that, the internal list is cleared.
-.P
-On a production machine, you probably do not want the daemon to send crash
-data at times that the machine is busy working. This second mode allows you
-to send crash reports at a quieter time (at night, perhaps) that you
-schedule in the \fI[cron]\fP section of \fIabrt.conf\fP.
+* Specify \fIFileTransfer(store)\fP in ActionsAndReporters directive
+and add \fIHH:MM = FileTransfer\fP line in [cron] section.
+At the time of the crash,
+the plugin stores a record of it in its internal list.
+When specified time is reached, the plugin iterates through
+its internal list and sends every recorded crash to the specified URL.
+After that, the internal list is cleared.
.SH CONFIGURATION
The \fIFileTransfer.conf\fP configuration file contains
several entries in the format "Option = Value". The options are:
@@ -48,24 +41,16 @@ URL = ftp://user:passwd@server.com/path
.SS ArchiveType
The type of the archive in which to pack the crash data.
Currently, \fI.tar\fP, \fI.tar.gz\fP, \fI.tar.bz2\fP and \fI.zip\fP
-are supported.
-The plugin uses archive creation libraries for this.
-The default is
-.br
-ArchiveType = .tar.gz
+are supported. The default is \fI.tar.gz\fP
.SS RetryCount
This specifies how many times the plugin will try to resend
the file if the transfer was not succesful. The plugin
-waits a while before it retries the transfer: see \fIRetryDelay\fP
-The default is
-.br
-RetryCount = 3
+waits a while before it retries the transfer: see \fIRetryDelay\fP.
+The default is 3
.SS RetryDelay
If the transfer was not succesful, the plugin will
wait some time before sending the file again. This configuration
-option specifies the time in seconds. The default is
-.br
-RetryDelay = 20
+option specifies the time in seconds. The default is 20.
.SH EXAMPLES
.P
Typical configuration in \fIabrt.conf\fP. The crash is stored
@@ -74,7 +59,7 @@ is transferred to a central server.
.P
[common]
.br
-ActionsAndReporters = FileTransfer("store")
+ActionsAndReporters = FileTransfer(store)
.br
[cron]
.br
diff --git a/lib/Utils/spawn.cpp b/lib/Utils/spawn.cpp
index 43c4b4a9..54d08a4a 100644
--- a/lib/Utils/spawn.cpp
+++ b/lib/Utils/spawn.cpp
@@ -115,7 +115,7 @@ char *run_in_shell_and_save_output(int flags,
flags |= EXECFLG_OUTPUT;
flags &= ~EXECFLG_INPUT;
- const char *argv[] = { "/bin/sh", "sh", "-c", cmd, NULL };
+ const char *argv[] = { "/bin/sh", "-c", cmd, NULL };
int pipeout[2];
pid_t child = fork_execv_on_steroids(flags, (char **)argv, pipeout,
/*unsetenv_vec:*/ NULL, dir, /*uid (unused):*/ 0);
diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp
index 73736f13..6cf32a68 100644
--- a/src/Daemon/Settings.cpp
+++ b/src/Daemon/Settings.cpp
@@ -77,7 +77,7 @@ static set_string_t ParseList(const char* pList)
return set;
}
-/* (What format do we parse here?) */
+/* Format: name, name(param),name("param with spaces \"and quotes\"") */
static vector_pair_string_string_t ParseListWithArgs(const char *pValue)
{
VERB3 log(" ParseListWithArgs(%s)", pValue);
@@ -92,7 +92,6 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue)
{
if (is_quote && pValue[ii] == '\\' && pValue[ii+1])
{
- item += pValue[ii];
ii++;
item += pValue[ii];
continue;
@@ -100,7 +99,7 @@ static vector_pair_string_string_t ParseListWithArgs(const char *pValue)
if (pValue[ii] == '"')
{
is_quote = !is_quote;
- item += pValue[ii];
+ /*item += pValue[ii]; - wrong! name("param") must be == name(param) */
continue;
}
if (is_quote)
diff --git a/src/Daemon/abrt.conf b/src/Daemon/abrt.conf
index acf8566f..406289fe 100644
--- a/src/Daemon/abrt.conf
+++ b/src/Daemon/abrt.conf
@@ -13,11 +13,13 @@ BlackList = nspluginwrapper
Database = SQLite3
# Max size for crash storage [MiB]
MaxCrashReportsSize = 1000
-# Vector of actions and reporters which are activated immediately after a crash occurs
+# Vector of actions and reporters which are activated immediately after a crash occurs,
+# comma separated.
#ActionsAndReporters = Mailx("[abrt] new crash was detected")
+#ActionsAndReporters = FileTransfer("store")
ActionsAndReporters = RunApp("test x\"`cat component`\" = x\"xorg-x11-server-Xorg\" && cp /var/log/Xorg.0.log .")
-# What actions or reporters to run on specified crash type
+# What actions or reporters to run on each crash type
[ AnalyzerActionsAndReporters ]
Kerneloops = KerneloopsReporter
CCpp = Bugzilla, Logger
@@ -29,3 +31,4 @@ Python = Bugzilla, Logger
# h:m - at h:m an action plugin is activated
# s - every s seconds is an action plugin activated
120 = KerneloopsScanner
+#02:00 = FileTransfer
diff --git a/src/Hooks/hooklib.cpp b/src/Hooks/hooklib.cpp
index 41b9627f..06bde974 100644
--- a/src/Hooks/hooklib.cpp
+++ b/src/Hooks/hooklib.cpp
@@ -47,9 +47,7 @@ void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSi
break;
}
- unsigned len = strlen(line);
- if (len > 0 && line[len-1] == '\n')
- line[--len] = '\0';
+ strchrnul(line, '\n')[0] = '\0';
const char *p = skip_whitespace(line);
#undef DIRECTIVE
#define DIRECTIVE "MaxCrashReportsSize"