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/TicketUploader.cpp | |
| 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/TicketUploader.cpp')
| -rw-r--r-- | lib/Plugins/TicketUploader.cpp | 255 |
1 files changed, 174 insertions, 81 deletions
diff --git a/lib/Plugins/TicketUploader.cpp b/lib/Plugins/TicketUploader.cpp index 7483768..c85a329 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", |
