diff options
author | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-01-21 21:20:33 +0100 |
---|---|---|
committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-01-21 21:20:33 +0100 |
commit | ce57d1299f6dadecb36c597e35c00de79d00c5f4 (patch) | |
tree | 0a900704b79558b4f1683debc9b36fd62b2f2c5b /lib/Plugins | |
parent | f750288769b23497ad5b57b1c50f683402c509f6 (diff) | |
parent | 4b54f9866f0dbdc859e300b0169b6ef504ee6c12 (diff) | |
download | abrt-ce57d1299f6dadecb36c597e35c00de79d00c5f4.tar.gz abrt-ce57d1299f6dadecb36c597e35c00de79d00c5f4.tar.xz abrt-ce57d1299f6dadecb36c597e35c00de79d00c5f4.zip |
Merge branch 'master' into rhel6
Conflicts:
src/Daemon/abrt.conf
Diffstat (limited to 'lib/Plugins')
28 files changed, 408 insertions, 319 deletions
diff --git a/lib/Plugins/Bugzilla.conf b/lib/Plugins/Bugzilla.conf index 6e98c9d5..14fc92c1 100644 --- a/lib/Plugins/Bugzilla.conf +++ b/lib/Plugins/Bugzilla.conf @@ -1,3 +1,4 @@ +Enabled = 1 # Bugzilla URL BugzillaURL = https://bugzilla.redhat.com/ # yes means that ssl certificates will not be checked diff --git a/lib/Plugins/Bugzilla.cpp b/lib/Plugins/Bugzilla.cpp index f963eb9c..0197a7bf 100644 --- a/lib/Plugins/Bugzilla.cpp +++ b/lib/Plugins/Bugzilla.cpp @@ -11,7 +11,9 @@ # include <config.h> #endif -#define XML_RPC_SUFFIX "/xmlrpc.cgi" +#define XML_RPC_SUFFIX "/xmlrpc.cgi" +#define NEW_BUG -1 +#define MISSING_MEMBER -2 /* * TODO: npajkovs: better deallocation of xmlrpc value @@ -32,8 +34,8 @@ struct ctx: public abrt_xmlrpc_conn { int32_t check_uuid_in_bugzilla(const char* component, const char* UUID); bool check_cc_and_reporter(uint32_t bug_id, const char* login); void add_plus_one_cc(uint32_t bug_id, const char* login); - uint32_t new_bug(const map_crash_report_t& pCrashReport); - void add_attachments(const char* bug_id_str, const map_crash_report_t& pCrashReport); + uint32_t new_bug(const map_crash_data_t& pCrashData); + void add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData); }; void ctx::login(const char* login, const char* passwd) @@ -123,6 +125,12 @@ bool ctx::check_cc_and_reporter(uint32_t bug_id, const char* login) return true; } } + else + { + VERB3 log("Missing member 'reporter'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bugs'")); + } xmlrpc_value* cc_member = NULL; xmlrpc_struct_find_value(&env, result, "cc", &cc_member); @@ -169,6 +177,12 @@ bool ctx::check_cc_and_reporter(uint32_t bug_id, const char* login) } xmlrpc_DECREF(cc_member); } + else + { + VERB3 log("Missing member 'bugs'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'cc'")); + } xmlrpc_DECREF(result); return false; @@ -235,7 +249,7 @@ int32_t ctx::check_uuid_in_bugzilla(const char* component, const char* UUID) { xmlrpc_DECREF(result); xmlrpc_DECREF(bugs_member); - return -1; + return NEW_BUG; } xmlrpc_value* item = NULL; @@ -270,30 +284,42 @@ int32_t ctx::check_uuid_in_bugzilla(const char* component, const char* UUID) xmlrpc_DECREF(result); return bug_id; } + else + { + VERB3 log("Missing member 'bug_id'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bug_id'")); + } xmlrpc_DECREF(item); xmlrpc_DECREF(bugs_member); } + else + { + VERB3 log("Missing member 'bugs'"); + xmlrpc_DECREF(result); + throw CABRTException(EXCEP_PLUGIN, _("Missing member 'bugs'")); + } xmlrpc_DECREF(result); - return -1; + return MISSING_MEMBER; } -uint32_t ctx::new_bug(const map_crash_report_t& pCrashReport) +uint32_t ctx::new_bug(const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); - std::string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - std::string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - std::string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT]; - std::string arch = pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]; - std::string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const std::string& package = get_crash_data_item_content(pCrashData, FILENAME_PACKAGE); + const std::string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const std::string& release = get_crash_data_item_content(pCrashData, FILENAME_RELEASE); + const std::string& arch = get_crash_data_item_content(pCrashData, FILENAME_ARCHITECTURE); + const std::string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); std::string summary = "[abrt] crash in " + package; std::string status_whiteboard = "abrt_hash:" + uuid; std::string description = "abrt "VERSION" detected a crash.\n\n"; - description += make_description_bz(pCrashReport); + description += make_description_bz(pCrashData); std::string product; std::string version; @@ -346,28 +372,29 @@ uint32_t ctx::new_bug(const map_crash_report_t& pCrashReport) return bug_id; } -void ctx::add_attachments(const char* bug_id_str, const map_crash_report_t& pCrashReport) +void ctx::add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); xmlrpc_value* result = NULL; - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { - const std::string &filename = it->first; + const std::string &itemname = it->first; const std::string &type = it->second[CD_TYPE]; const std::string &content = it->second[CD_CONTENT]; - if (type == CD_TXT && content.length() > CD_TEXT_ATT_SIZE) - { + if (type == CD_TXT + && (content.length() > CD_TEXT_ATT_SIZE || itemname == FILENAME_BACKTRACE) + ) { char *encoded64 = encode_base64(content.c_str(), content.length()); // fails only when you write query. when it's done it never fails. xmlrpc_value* param = xmlrpc_build_value(&env, "(s{s:s,s:s,s:s,s:s})", bug_id_str, - "description", ("File: " + filename).c_str(), - "filename", filename.c_str(), + "description", ("File: " + itemname).c_str(), + "filename", itemname.c_str(), "contenttype", "text/plain", "data", encoded64 ); @@ -404,7 +431,7 @@ CReporterBugzilla::CReporterBugzilla() : CReporterBugzilla::~CReporterBugzilla() {} -std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, +std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -433,8 +460,8 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, NoSSLVerify = m_bNoSSLVerify; } - std::string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - std::string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const std::string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const std::string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); try { ctx bz_server(BugzillaXMLRPC.c_str(), NoSSLVerify); @@ -442,12 +469,13 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, update_client(_("Checking for duplicates...")); bug_id = bz_server.check_uuid_in_bugzilla(component.c_str(), uuid.c_str()); - update_client(_("Logging into bugzilla...")); if ((Login == "") && (Password == "")) { VERB3 log("Empty login and password"); throw CABRTException(EXCEP_PLUGIN, _("Empty login and password. Please check Bugzilla.conf")); } + + update_client(_("Logging into bugzilla...")); bz_server.login(Login.c_str(), Password.c_str()); if (bug_id > 0) @@ -458,12 +486,14 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, bz_server.add_plus_one_cc(bug_id, Login.c_str()); } bz_server.logout(); - return BugzillaURL + "/show_bug.cgi?id=" + to_string(bug_id); + BugzillaURL += "/show_bug.cgi?id="; + BugzillaURL += to_string(bug_id); + return BugzillaURL; } update_client(_("Creating new bug...")); - bug_id = bz_server.new_bug(pCrashReport); - bz_server.add_attachments(to_string(bug_id).c_str(), pCrashReport); + bug_id = bz_server.new_bug(pCrashData); + bz_server.add_attachments(to_string(bug_id).c_str(), pCrashData); update_client(_("Logging out...")); bz_server.logout(); @@ -475,12 +505,16 @@ std::string CReporterBugzilla::Report(const map_crash_report_t& pCrashReport, if (bug_id > 0) { - return BugzillaURL + "/show_bug.cgi?id=" + to_string(bug_id); + BugzillaURL += "/show_bug.cgi?id="; + BugzillaURL += to_string(bug_id); + return BugzillaURL; } - return BugzillaURL + "/show_bug.cgi?id="; + BugzillaURL += "/show_bug.cgi?id="; + return BugzillaURL; } +//todo: make static map_plugin_settings_t CReporterBugzilla::parse_settings(const map_plugin_settings_t& pSettings) { map_plugin_settings_t plugin_settings; diff --git a/lib/Plugins/Bugzilla.h b/lib/Plugins/Bugzilla.h index ee6bc6a5..571d0c60 100644 --- a/lib/Plugins/Bugzilla.h +++ b/lib/Plugins/Bugzilla.h @@ -20,7 +20,7 @@ class CReporterBugzilla : public CReporter CReporterBugzilla(); virtual ~CReporterBugzilla(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index ab29fbbe..5838bc45 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -40,10 +40,6 @@ using namespace std; #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" #define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u %c" -#define FILENAME_COREDUMP "coredump" -#define FILENAME_BACKTRACE "backtrace" -#define FILENAME_MEMORYMAP "memorymap" - #define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di" CAnalyzerCCpp::CAnalyzerCCpp() : @@ -233,7 +229,7 @@ static int rate_backtrace(const char *backtrace) } } - /* Bogus "backtrace" with zero frames? */ + /* Bogus 'backtrace' with zero frames? */ if (best_possible_rating == 0) return 0; @@ -421,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..858d1346 100644 --- a/lib/Plugins/Catcut.conf +++ b/lib/Plugins/Catcut.conf @@ -1,4 +1,5 @@ -Enabled=1 +Enabled = 0 + # 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/Catcut.cpp b/lib/Plugins/Catcut.cpp index b69038fb..3580a3b4 100644 --- a/lib/Plugins/Catcut.cpp +++ b/lib/Plugins/Catcut.cpp @@ -215,13 +215,13 @@ struct ctx: public abrt_xmlrpc_conn { ctx(const char* url, bool no_ssl_verify): abrt_xmlrpc_conn(url, no_ssl_verify) {} string login(const char* login, const char* passwd); - string new_bug(const char *auth_cookie, const map_crash_report_t& pCrashReport); + string new_bug(const char *auth_cookie, const map_crash_data_t& pCrashData); string request_upload(const char* auth_cookie, const char* pTicketName, const char* fileName, const char* description); void add_attachments(const char* xmlrpc_URL, const char* auth_cookie, const char* pTicketName, - const map_crash_report_t& pCrashReport, + const map_crash_data_t& pCrashData, int retryCount, int retryDelaySeconds); }; @@ -263,21 +263,21 @@ ctx::login(const char* login, const char* passwd) } string -ctx::new_bug(const char *auth_cookie, const map_crash_report_t& pCrashReport) +ctx::new_bug(const char *auth_cookie, const map_crash_data_t& pCrashData) { xmlrpc_env env; xmlrpc_env_init(&env); - string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; - string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; - string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT]; - string arch = pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]; - string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + const string& package = get_crash_data_item_content(pCrashData, FILENAME_PACKAGE); + const string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT); + const string& release = get_crash_data_item_content(pCrashData, FILENAME_RELEASE); + const string& arch = get_crash_data_item_content(pCrashData, FILENAME_ARCHITECTURE); + const string& uuid = get_crash_data_item_content(pCrashData, CD_DUPHASH); string summary = "[abrt] crash in " + package; string status_whiteboard = "abrt_hash:" + uuid; - string description = make_description_catcut(pCrashReport); + string description = make_description_catcut(pCrashData); string product; string version; @@ -382,13 +382,13 @@ void ctx::add_attachments(const char* xmlrpc_URL, const char* auth_cookie, const char* pTicketName, - const map_crash_report_t& pCrashReport, + const map_crash_data_t& pCrashData, int retryCount, int retryDelaySeconds) { - map_crash_report_t::const_iterator it = pCrashReport.begin(); - for (; it != pCrashReport.end(); it++) + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { if (it->second[CD_TYPE] == CD_TXT && it->second[CD_TYPE].size() > CD_TEXT_ATT_SIZE) { @@ -446,7 +446,7 @@ CReporterCatcut::CReporterCatcut() : CReporterCatcut::~CReporterCatcut() {} -string CReporterCatcut::Report(const map_crash_report_t& pCrashReport, +string CReporterCatcut::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -459,14 +459,14 @@ string CReporterCatcut::Report(const map_crash_report_t& pCrashReport, string message; if (auth_cookie != "") { - string ticket_name = catcut_server.new_bug(auth_cookie.c_str(), pCrashReport); + string ticket_name = catcut_server.new_bug(auth_cookie.c_str(), pCrashData); if (ticket_name != "") { catcut_server.add_attachments( m_sCatcutURL.c_str(), auth_cookie.c_str(), ticket_name.c_str(), - pCrashReport, + pCrashData, m_nRetryCount, m_nRetryDelay ); diff --git a/lib/Plugins/Catcut.h b/lib/Plugins/Catcut.h index 00f486c0..65c70444 100644 --- a/lib/Plugins/Catcut.h +++ b/lib/Plugins/Catcut.h @@ -20,7 +20,7 @@ class CReporterCatcut : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *Args); }; 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 b08ecd51..4d317c8d 100644 --- a/lib/Plugins/FileTransfer.cpp +++ b/lib/Plugins/FileTransfer.cpp @@ -22,15 +22,6 @@ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif -#include <iostream> -#include <sstream> -#include <fstream> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <zip.h> #include <libtar.h> #include <bzlib.h> @@ -66,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 */ @@ -89,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) @@ -101,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 *)) { @@ -128,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; @@ -150,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; @@ -162,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); } @@ -295,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); @@ -325,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) @@ -367,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 d9807556..98d892b7 100644 --- a/lib/Plugins/Firefox.cpp +++ b/lib/Plugins/Firefox.cpp @@ -36,10 +36,6 @@ #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" #define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u" -#define FILENAME_COREDUMP "coredump" -#define FILENAME_BACKTRACE "backtrace" -#define FILENAME_MEMORYMAP "memorymap" - #define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di" CAnalyzerFirefox::CAnalyzerFirefox() : @@ -227,7 +223,7 @@ static int rate_backtrace(const char *backtrace) } } - /* Bogus "backtrace" with zero frames? */ + /* Bogus 'backtrace' with zero frames? */ if (best_possible_rating == 0) return 0; @@ -627,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 != ""? */ @@ -716,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/Kerneloops.cpp b/lib/Plugins/Kerneloops.cpp index 2e28cf4a..bcb7a723 100644 --- a/lib/Plugins/Kerneloops.cpp +++ b/lib/Plugins/Kerneloops.cpp @@ -30,8 +30,6 @@ #include "ABRTException.h" #include "CommLayerInner.h" -#define FILENAME_KERNELOOPS "kerneloops" - std::string CAnalyzerKerneloops::GetLocalUUID(const char *pDebugDumpDir) { log(_("Getting local universal unique identification")); diff --git a/lib/Plugins/KerneloopsReporter.cpp b/lib/Plugins/KerneloopsReporter.cpp index 5cb525bc..18932aea 100644 --- a/lib/Plugins/KerneloopsReporter.cpp +++ b/lib/Plugins/KerneloopsReporter.cpp @@ -30,8 +30,6 @@ #include "CommLayerInner.h" #include "ABRTException.h" -#define FILENAME_KERNELOOPS "kerneloops" - /* helpers */ static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) { @@ -93,7 +91,7 @@ CKerneloopsReporter::CKerneloopsReporter() : m_sSubmitURL("http://submit.kerneloops.org/submitoops.php") {} -std::string CKerneloopsReporter::Report(const map_crash_report_t& pCrashReport, +std::string CKerneloopsReporter::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -101,8 +99,8 @@ std::string CKerneloopsReporter::Report(const map_crash_report_t& pCrashReport, update_client(_("Creating and submitting a report...")); - map_crash_report_t::const_iterator it = pCrashReport.find(FILENAME_KERNELOOPS); - if (it != pCrashReport.end()) { + map_crash_data_t::const_iterator it = pCrashData.find(FILENAME_KERNELOOPS); + if (it != pCrashData.end()) { ret = http_post_to_kerneloops_site( m_sSubmitURL.c_str(), it->second[CD_CONTENT].c_str() diff --git a/lib/Plugins/KerneloopsReporter.h b/lib/Plugins/KerneloopsReporter.h index 10e5e644..91326526 100644 --- a/lib/Plugins/KerneloopsReporter.h +++ b/lib/Plugins/KerneloopsReporter.h @@ -43,7 +43,7 @@ class CKerneloopsReporter : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; diff --git a/lib/Plugins/KerneloopsScanner.cpp b/lib/Plugins/KerneloopsScanner.cpp index 1bb45aba..42ffd409 100644 --- a/lib/Plugins/KerneloopsScanner.cpp +++ b/lib/Plugins/KerneloopsScanner.cpp @@ -34,10 +34,6 @@ #include "KerneloopsSysLog.h" #include "KerneloopsScanner.h" -#include <limits.h> - -#define FILENAME_KERNELOOPS "kerneloops" - // TODO: https://fedorahosted.org/abrt/ticket/78 CKerneloopsScanner::CKerneloopsScanner() @@ -54,8 +50,7 @@ void CKerneloopsScanner::Run(const char *pActionDir, const char *pArgs) { const char *syslog_file = "/var/log/messages"; map_plugin_settings_t::const_iterator it = m_pSettings.find("SysLogFile"); - if (it != m_pSettings.end()) - { + if (it != m_pSettings.end()) { syslog_file = it->second.c_str(); } @@ -205,4 +200,4 @@ void save_oops_to_debug_dump(CKerneloopsScanner *This) This->SaveOopsToDebugDump(); } -} +} /* extern "C" */ 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/Logger.cpp b/lib/Plugins/Logger.cpp index d6cc124e..f428aec5 100644 --- a/lib/Plugins/Logger.cpp +++ b/lib/Plugins/Logger.cpp @@ -59,12 +59,12 @@ void CLogger::SetSettings(const map_plugin_settings_t& pSettings) // return m_pSettings; //} -std::string CLogger::Report(const map_crash_report_t& pCrashReport, +std::string CLogger::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { - std::string description = make_description_logger(pCrashReport); + std::string description = make_description_logger(pCrashData); description += "\n\n\n"; FILE *fOut; diff --git a/lib/Plugins/Logger.h b/lib/Plugins/Logger.h index c7d76798..02429b2c 100644 --- a/lib/Plugins/Logger.h +++ b/lib/Plugins/Logger.h @@ -1,6 +1,6 @@ /* Logger.h - header file for Logger reporter plugin - - it simple writes report to specific file + - it simply writes report to specific file Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) Copyright (C) 2009 RedHat inc. @@ -37,7 +37,7 @@ class CLogger : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; 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/Mailx.cpp b/lib/Plugins/Mailx.cpp index 2f8448f5..2ee96455 100644 --- a/lib/Plugins/Mailx.cpp +++ b/lib/Plugins/Mailx.cpp @@ -65,7 +65,7 @@ static char** append_str_to_vector(char **vec, unsigned &size, const char *str) return vec; } -std::string CMailx::Report(const map_crash_report_t& pCrashReport, +std::string CMailx::Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs) { @@ -74,13 +74,13 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, args = append_str_to_vector(args, arg_size, MAILX_COMMAND); //TODO: move email body generation to make_descr.cpp - std::string binaryFiles, commonFiles, additionalFiles, UUIDFile; - map_crash_report_t::const_iterator it; - for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + std::string binaryFiles, commonFiles, additionalFiles, DUPHASHFile; + map_crash_data_t::const_iterator it; + for (it = pCrashData.begin(); it != pCrashData.end(); it++) { if (it->second[CD_TYPE] == CD_TXT) { - if (it->first != CD_UUID + if (it->first != CD_DUPHASH && it->first != FILENAME_ARCHITECTURE && it->first != FILENAME_KERNEL && it->first != FILENAME_PACKAGE @@ -90,12 +90,12 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, additionalFiles += it->second[CD_CONTENT]; additionalFiles += "\n\n"; } - else if (it->first == CD_UUID) + else if (it->first == CD_DUPHASH) { - UUIDFile += it->first; - UUIDFile += "\n-----\n"; - UUIDFile += it->second[CD_CONTENT]; - UUIDFile += "\n\n"; + DUPHASHFile += it->first; + DUPHASHFile += "\n-----\n"; + DUPHASHFile += it->second[CD_CONTENT]; + DUPHASHFile += "\n\n"; } else { @@ -117,9 +117,9 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, } } - std::string emailBody = "Duplicity check\n"; + std::string emailBody = "Duplicate check\n"; emailBody += "=====\n\n"; - emailBody += UUIDFile; + emailBody += DUPHASHFile; emailBody += "\nCommon information\n"; emailBody += "=====\n\n"; emailBody += commonFiles; @@ -135,7 +135,7 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, args = append_str_to_vector(args, arg_size, m_sEmailTo.c_str()); update_client(_("Sending an email...")); - const char *uid_str = pCrashReport.find(CD_MWUID)->second[CD_CONTENT].c_str(); + const char *uid_str = get_crash_data_item_content(pCrashData, FILENAME_UID).c_str(); exec_and_feed_input(xatoi_u(uid_str), emailBody.c_str(), args); while (*args) diff --git a/lib/Plugins/Mailx.h b/lib/Plugins/Mailx.h index 1ddb5ff0..619e349c 100644 --- a/lib/Plugins/Mailx.h +++ b/lib/Plugins/Mailx.h @@ -41,7 +41,7 @@ class CMailx : public CReporter virtual void SetSettings(const map_plugin_settings_t& pSettings); //ok to delete? // virtual const map_plugin_settings_t& GetSettings(); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; 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/Python.cpp b/lib/Plugins/Python.cpp index 23d6f5c0..ad954681 100644 --- a/lib/Plugins/Python.cpp +++ b/lib/Plugins/Python.cpp @@ -1,15 +1,14 @@ +#include "abrtlib.h" #include "Python.h" #include "DebugDump.h" #include "ABRTException.h" -#define FILENAME_BACKTRACE "backtrace" - static std::string CreateHash(const char *pDebugDumpDir) { - std::string uuid; CDebugDump dd; dd.Open(pDebugDumpDir); - dd.LoadText("uuid", uuid); + std::string uuid; + dd.LoadText(FILENAME_UUID, uuid); return uuid; } diff --git a/lib/Plugins/RunApp.cpp b/lib/Plugins/RunApp.cpp index e2147e26..77f5d3c8 100644 --- a/lib/Plugins/RunApp.cpp +++ b/lib/Plugins/RunApp.cpp @@ -19,7 +19,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - +#include "abrtlib.h" #include "RunApp.h" #include "DebugDump.h" #include "ABRTException.h" 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 7483768d..c85a329b 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,11 +87,11 @@ 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); } } -void CTicketUploader::SendFile(const char *pURL, const char *pFilename) +void CTicketUploader::SendFile(const char *pURL, const char *pFilename, int retry_count, int retry_delay) { if (pURL[0] == '\0') { @@ -110,7 +103,7 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) const char *base = (strrchr(pFilename, '/') ? : pFilename-1) + 1; string wholeURL = concat_path_file(pURL, base); - int count = m_nRetryCount; + int count = retry_count; int result; while (1) { @@ -140,7 +133,7 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) if (result == 0 || --count <= 0) break; /* retry the upload if not succesful, wait a bit before next try */ - sleep(m_nRetryDelay); + sleep(retry_delay); } if (count <= 0 && result != 0) @@ -150,78 +143,101 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) } -string CTicketUploader::Report(const map_crash_report_t& pCrashReport, +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...")); - + string customer_name; + string ticket_name; + string upload_url; + bool do_encrypt; + bool do_upload; + int retry_count; + int retry_delay; + + /* if parse_settings fails it returns an empty map so we need to use defaults */ + map_plugin_settings_t settings = parse_settings(pSettings); // Get ticket name, customer name, and do_encrypt from config settings - string customer_name = m_sCustomer; - string ticket_name = m_sTicket; - string upload_url = m_sURL; - bool do_encrypt = m_bEncrypt; - bool do_upload = m_bUpload; - - bool have_ticket_name = false; - if (ticket_name == "") + if (!settings.empty()) { - ticket_name = "TicketUploader-newticket"; + customer_name = settings["Customer"]; + ticket_name = settings["Ticket"]; + upload_url = settings["URL"]; + do_encrypt = string_to_bool(settings["Encrypt"].c_str()); + do_upload = string_to_bool(settings["Upload"].c_str()); + retry_count = xatoi_u(settings["RetryCount"].c_str()); + retry_delay = xatoi_u(settings["RetryDelay"].c_str()); } else { - have_ticket_name = true; + customer_name = m_sCustomer; + ticket_name = m_sTicket; + upload_url = m_sURL; + do_encrypt = m_bEncrypt; + do_upload = m_bUpload; + retry_count = m_nRetryCount; + retry_delay = m_nRetryDelay; } + update_client(_("Creating an TicketUploader report...")); - // Format the time to add to the file name - const int timebufmax = 256; - char timebuf[timebufmax]; - time_t curtime = time(NULL); - if (!strftime(timebuf, timebufmax, "-%G%m%d%k%M%S", gmtime(&curtime))) + bool have_ticket_name = (ticket_name != ""); + if (!have_ticket_name) { - Error("Can't format time"); + ticket_name = "TicketUploader-newticket"; } - // Create a tmp work directory, and within that the directory - // that will be the root of the tarball + // Format the time to add to the file name + char timebuf[256]; + time_t curtime = time(NULL); + strftime(timebuf, sizeof(timebuf), "-%Y%m%d%H%M%S", gmtime(&curtime)); + + // 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 - map_crash_report_t::const_iterator it; - for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + // 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 +247,11 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, // 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 @@ -280,7 +282,7 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, if (do_upload) { // FIXME: SendFile isn't working sometime (scp) - SendFile(upload_url.c_str(), outfile_name.c_str()); + SendFile(upload_url.c_str(), outfile_name.c_str(), retry_count, retry_delay); } else { @@ -328,21 +330,19 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, } 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 +352,28 @@ string CTicketUploader::Report(const map_crash_report_t& pCrashReport, 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 +385,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; } @@ -401,13 +426,81 @@ const map_plugin_settings_t& CTicketUploader::GetSettings() m_pSettings["Ticket"] = m_sTicket; m_pSettings["URL"] = m_sURL; m_pSettings["Encrypt"] = m_bEncrypt ? "yes" : "no"; - m_pSettings["Upload"] = m_bEncrypt ? "yes" : "no"; + m_pSettings["Upload"] = m_bUpload ? "yes" : "no"; m_pSettings["RetryCount"] = to_string(m_nRetryCount); m_pSettings["RetryDelay"] = to_string(m_nRetryDelay); return m_pSettings; } +//todo: make static +map_plugin_settings_t CTicketUploader::parse_settings(const map_plugin_settings_t& pSettings) +{ + map_plugin_settings_t plugin_settings; + + map_plugin_settings_t::const_iterator end = pSettings.end(); + map_plugin_settings_t::const_iterator it; + + it = pSettings.find("Customer"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Customer"] = it->second; + + it = pSettings.find("Ticket"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Ticket"] = it->second; + + it = pSettings.find("URL"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["URL"] = it->second; + + it = pSettings.find("Encrypt"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Encrypt"] = it->second; + + it = pSettings.find("Upload"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["Upload"] = it->second; + + it = pSettings.find("RetryCount"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["RetryCount"] = it->second; + + it = pSettings.find("RetryDelay"); + if (it == end) + { + plugin_settings.clear(); + return plugin_settings; + } + plugin_settings["RetryDelay"] = it->second; + + VERB1 log("User settings ok, using them instead of defaults"); + return plugin_settings; +} + PLUGIN_INFO(REPORTER, CTicketUploader, "TicketUploader", diff --git a/lib/Plugins/TicketUploader.h b/lib/Plugins/TicketUploader.h index 1bc8f6ba..a719d0bd 100644 --- a/lib/Plugins/TicketUploader.h +++ b/lib/Plugins/TicketUploader.h @@ -27,7 +27,6 @@ #include "Plugin.h" #include "Reporter.h" -//#include "CrashTypes.h" class CTicketUploader : public CReporter { @@ -40,7 +39,8 @@ class CTicketUploader : public CReporter int m_nRetryCount; int m_nRetryDelay; - void SendFile(const char *pURL, const char *pFilename); + void SendFile(const char *pURL, const char *pFilename, int retry_count, int retry_delay); + map_plugin_settings_t parse_settings(const map_plugin_settings_t& pSettings); public: CTicketUploader(); @@ -48,7 +48,7 @@ class CTicketUploader : public CReporter virtual const map_plugin_settings_t& GetSettings(); virtual void SetSettings(const map_plugin_settings_t& pSettings); - virtual std::string Report(const map_crash_report_t& pCrashReport, + virtual std::string Report(const map_crash_data_t& pCrashData, const map_plugin_settings_t& pSettings, const char *pArgs); }; 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 |