diff options
-rw-r--r-- | abrt.spec | 1 | ||||
-rw-r--r-- | lib/plugins/Makefile.am | 2 | ||||
-rw-r--r-- | lib/plugins/RHTSupport.cpp | 353 | ||||
-rw-r--r-- | lib/plugins/RHTSupport.h | 7 | ||||
-rw-r--r-- | src/daemon/Makefile.am | 24 | ||||
-rw-r--r-- | src/daemon/abrt-action-rhtsupport.cpp | 312 |
6 files changed, 421 insertions, 278 deletions
@@ -355,6 +355,7 @@ fi %{_sbindir}/abrt-action-generate-backtrace %{_sbindir}/abrt-action-save-package-data %{_bindir}/abrt-action-bugzilla +%{_bindir}/abrt-action-rhtsupport %{_bindir}/abrt-action-install-debuginfo %{_bindir}/%{name}-handle-upload %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf diff --git a/lib/plugins/Makefile.am b/lib/plugins/Makefile.am index 6e8c3f9c..22a9bcd4 100644 --- a/lib/plugins/Makefile.am +++ b/lib/plugins/Makefile.am @@ -125,7 +125,7 @@ libBugzilla_la_CPPFLAGS = \ # RHTSupport libRHTSupport_la_SOURCES = RHTSupport.h RHTSupport.cpp libRHTSupport_la_LIBADD = -libRHTSupport_la_LDFLAGS = -avoid-version -ltar +libRHTSupport_la_LDFLAGS = -avoid-version libRHTSupport_la_CPPFLAGS = \ -I$(INC_PATH) -I$(UTILS_PATH) \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ diff --git a/lib/plugins/RHTSupport.cpp b/lib/plugins/RHTSupport.cpp index 016d5a91..5c9109e7 100644 --- a/lib/plugins/RHTSupport.cpp +++ b/lib/plugins/RHTSupport.cpp @@ -17,11 +17,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE 1 /* for stpcpy */ -#include <libtar.h> #include "abrtlib.h" -#include "abrt_curl.h" -#include "abrt_rh_support.h" #include "crash_types.h" #include "abrt_exception.h" #include "comm_layer_inner.h" @@ -29,296 +25,115 @@ using namespace std; - -#if 0 //unused -static char *xml_escape(const char *str) -{ - const char *s = str; - unsigned count = 1; /* for NUL */ - while (*s) - { - if (*s == '&') - count += sizeof("&")-2; - if (*s == '<') - count += sizeof("<")-2; - if (*s == '>') - count += sizeof(">")-2; - if ((unsigned char)*s > 126 || (unsigned char)*s < ' ') - count += sizeof("\\x00")-2; - count++; - s++; - } - char *result = (char*)xmalloc(count); - char *d = result; - s = str; - while (*s) - { - if (*s == '&') - d = stpcpy(d, "&"); - else if (*s == '<') - d = stpcpy(d, "<"); - else if (*s == '>') - d = stpcpy(d, ">"); - else - if ((unsigned char)*s > 126 - || ( (unsigned char)*s < ' ' - && *s != '\t' - && *s != '\n' - && *s != '\r' - ) - ) { - *d++ = '\\'; - *d++ = 'x'; - *d++ = "0123456789abcdef"[(unsigned char)*s >> 4]; - *d++ = "0123456789abcdef"[(unsigned char)*s & 0xf]; - } - else - *d++ = *s; - s++; - } - *d = '\0'; - return result; -} -#endif - - -/* - * CReporterRHticket - */ - CReporterRHticket::CReporterRHticket() { - m_login = NULL; - m_password = NULL; - m_ssl_verify = true; - m_strata_url = xstrdup("https://api.access.redhat.com/rs"); + m_pSettings["URL"] = "https://api.access.redhat.com/rs"; + m_pSettings["Login"] = ""; + m_pSettings["Password"] = ""; + m_pSettings["SSLVerify"] = "yes"; } CReporterRHticket::~CReporterRHticket() { - free(m_login); - free(m_password); - free(m_strata_url); } -string CReporterRHticket::Report(const map_crash_data_t& pCrashData, - const map_plugin_settings_t& pSettings, - const char *pArgs) +void CReporterRHticket::SetSettings(const map_plugin_settings_t& pSettings) { - /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ - update_client(_("Compressing data")); - - string retval; + /* Can't simply do this: - map_plugin_settings_t::const_iterator end = pSettings.end(); - map_plugin_settings_t::const_iterator it; - it = pSettings.find("URL"); - char *url = (it == end ? m_strata_url : xstrdup(it->second.c_str())); - - it = pSettings.find("Login"); - char *login = (it == end ? m_login : xstrdup(it->second.c_str())); - - it = pSettings.find("Password"); - char *password = (it == end ? m_password : xstrdup(it->second.c_str())); - - it = pSettings.find("SSLVerify"); - bool ssl_verify = (it == end ? m_ssl_verify : string_to_bool(it->second.c_str())); - - const char *package = get_crash_data_item_content_or_NULL(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& duphash = get_crash_data_item_content(pCrashData, FILENAME_DUPHASH); - const char *reason = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_REASON); - const char *function = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_CRASH_FUNCTION); - - struct strbuf *buf_summary = strbuf_new(); - strbuf_append_strf(buf_summary, "[abrt] %s", package); - - if (function && strlen(function) < 30) - strbuf_append_strf(buf_summary, ": %s", function); - - if (reason) - strbuf_append_strf(buf_summary, ": %s", reason); - - char *summary = strbuf_free_nobuf(buf_summary); - - char *bz_dsc = make_description_bz(pCrashData); - char *dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc); - free(bz_dsc); - - reportfile_t* file = new_reportfile(); + m_pSettings = pSettings; - /* SELinux guys are not happy with /tmp, using /var/run/abrt */ - char *tempfile = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%lu-%lu.tar.gz", (long)getpid(), (long)time(NULL)); + * - it will erase keys which aren't present in pSettings. + * Example: if Bugzilla.conf doesn't have "Login = foo", + * then there's no pSettings["Login"] and m_pSettings = pSettings + * will nuke default m_pSettings["Login"] = "", + * making GUI think that we have no "Login" key at all + * and thus never overriding it - even if it *has* an override! + */ - int pipe_from_parent_to_child[2]; - xpipe(pipe_from_parent_to_child); - pid_t child = fork(); - if (child == 0) + map_plugin_settings_t::iterator it = m_pSettings.begin(); + while (it != m_pSettings.end()) { - /* child */ - close(pipe_from_parent_to_child[1]); - xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); - xmove_fd(pipe_from_parent_to_child[0], 0); - execlp("gzip", "gzip", NULL); - perror_msg_and_die("can't execute '%s'", "gzip"); - } - close(pipe_from_parent_to_child[0]); - - TAR *tar = NULL; - if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, - /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) - { - retval = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; - goto ret; - } - - { - map_crash_data_t::const_iterator it = pCrashData.begin(); - for (; it != pCrashData.end(); it++) + map_plugin_settings_t::const_iterator override = pSettings.find(it->first); + if (override != pSettings.end()) { - if (it->first == CD_COUNT) continue; - if (it->first == CD_DUMPDIR) continue; - if (it->first == CD_INFORMALL) continue; - if (it->first == CD_REPORTED) continue; - if (it->first == CD_MESSAGE) continue; // plugin's status message (if we already reported it yesterday) - if (it->first == FILENAME_DESCRIPTION) continue; // package description - - const char *content = it->second[CD_CONTENT].c_str(); - if (it->second[CD_TYPE] == CD_TXT) - { - reportfile_add_binding_from_string(file, it->first.c_str(), content); - } - else if (it->second[CD_TYPE] == CD_BIN) - { - const char *basename = strrchr(content, '/'); - if (basename) - basename++; - else - basename = content; - char *xml_name = concat_path_file("content", basename); - reportfile_add_binding_from_namedfile(file, - /*on_disk_filename */ content, - /*binding_name */ it->first.c_str(), - /*recorded_filename*/ xml_name, - /*binary */ 1); - if (tar_append_file(tar, (char*)content, xml_name) != 0) - { - retval = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; - free(xml_name); - goto ret; - } - free(xml_name); - } - } - } - - /* Write out content.xml in the tarball's root */ - { - const char *signature = reportfile_as_string(file); - unsigned len = strlen(signature); - unsigned len512 = (len + 511) & ~511; - char *block = (char*)memcpy(xzalloc(len512), signature, len); - th_set_type(tar, S_IFREG | 0644); - th_set_mode(tar, S_IFREG | 0644); - //th_set_link(tar, char *linkname); - //th_set_device(tar, dev_t device); - //th_set_user(tar, uid_t uid); - //th_set_group(tar, gid_t gid); - //th_set_mtime(tar, time_t fmtime); - th_set_path(tar, (char*)"content.xml"); - th_set_size(tar, len); - th_finish(tar); /* caclulate and store th xsum etc */ - if (th_write(tar) != 0 - || full_write(tar_fd(tar), block, len512) != len512 - || tar_close(tar) != 0 - ) { - free(block); - retval = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; - goto ret; + VERB3 log(" rhtsupport settings[%s]='%s'", it->first.c_str(), it->second.c_str()); + it->second = override->second; } - tar = NULL; - free(block); - } - - { - update_client(_("Creating a new case...")); - char* result = send_report_to_new_case(url, - login, - password, - ssl_verify, - summary, - dsc, - package, - tempfile - ); - VERB3 log("post result:'%s'", result); - retval = result; - free(result); - } - - ret: - // Damn, selinux does not allow SIGKILLing our own child! wtf?? - //kill(child, SIGKILL); /* just in case */ - waitpid(child, NULL, 0); - if (tar) - tar_close(tar); - //close(pipe_from_parent_to_child[1]); - tar_close() does it itself - unlink(tempfile); - free(tempfile); - reportfile_free(file); - - free(summary); - free(dsc); - - if (strncasecmp(retval.c_str(), "error", 5) == 0) - { - throw CABRTException(EXCEP_PLUGIN, "%s", retval.c_str()); + it++; } - return retval; } -void CReporterRHticket::SetSettings(const map_plugin_settings_t& pSettings) +string CReporterRHticket::Report(const map_crash_data_t& crash_data, + const map_plugin_settings_t& settings, + const char *args) { - m_pSettings = pSettings; - - map_plugin_settings_t::const_iterator end = pSettings.end(); - map_plugin_settings_t::const_iterator it; - it = pSettings.find("URL"); - if (it != end) - { - free(m_strata_url); - m_strata_url = xstrdup(it->second.c_str()); - } - it = pSettings.find("Login"); - if (it != end) - { - free(m_login); - m_login = xstrdup(it->second.c_str()); - } - it = pSettings.find("Password"); - if (it != end) + /* abrt-action-bugzilla [-s] -c /etc/arbt/Bugzilla.conf -c - -d pCrashData.dir NULL */ + char *argv[9]; + char **pp = argv; + *pp++ = (char*)"abrt-action-rhtsupport"; + +//We want to consume output, so don't redirect to syslog. +// if (logmode & LOGMODE_SYSLOG) +// *pp++ = (char*)"-s"; +//TODO: the actions<->daemon interaction will be changed anyway... + + *pp++ = (char*)"-c"; + *pp++ = (char*)(PLUGINS_CONF_DIR"/RHTSupport."PLUGINS_CONF_EXTENSION); + *pp++ = (char*)"-c"; + *pp++ = (char*)"-"; + *pp++ = (char*)"-d"; + *pp++ = (char*)get_crash_data_item_content_or_NULL(crash_data, CD_DUMPDIR); + *pp = NULL; + int pipefds[2]; + pid_t pid = fork_execv_on_steroids(EXECFLG_INPUT + EXECFLG_OUTPUT + EXECFLG_ERR2OUT, + argv, + pipefds, + /* unsetenv_vec: */ NULL, + /* dir: */ NULL, + /* uid(unused): */ 0 + ); + + /* Write the configuration to stdin */ + map_plugin_settings_t::const_iterator it = settings.begin(); + while (it != settings.end()) { - free(m_password); - m_password = xstrdup(it->second.c_str()); + full_write_str(pipefds[1], it->first.c_str()); + full_write_str(pipefds[1], "="); + full_write_str(pipefds[1], it->second.c_str()); + full_write_str(pipefds[1], "\n"); + it++; } - it = pSettings.find("SSLVerify"); - if (it != end) + close(pipefds[1]); + + FILE *fp = fdopen(pipefds[0], "r"); + if (!fp) + die_out_of_memory(); + + /* Consume log from stdout */ + std::string bug_status; + char buf[512]; + while (fgets(buf, sizeof(buf), fp)) { - m_ssl_verify = string_to_bool(it->second.c_str()); + strchrnul(buf, '\n')[0] = '\0'; + if (strncmp(buf, "STATUS:", 7) == 0) + bug_status = buf + 7; + else + if (strncmp(buf, "EXCEPT:", 7) == 0) + { + fclose(fp); + waitpid(pid, NULL, 0); + throw CABRTException(EXCEP_PLUGIN, "%s", buf + 7); + } + else + update_client("%s", buf); } -} -/* Should not be deleted (why?) */ -const map_plugin_settings_t& CReporterRHticket::GetSettings() -{ - m_pSettings["URL"] = (m_strata_url)? m_strata_url: ""; - m_pSettings["Login"] = (m_login)? m_login: ""; - m_pSettings["Password"] = (m_password)? m_password: ""; - m_pSettings["SSLVerify"] = m_ssl_verify ? "yes" : "no"; + fclose(fp); /* this also closes pipefds[0] */ + /* wait for child to actually exit, and prevent leaving a zombie behind */ + waitpid(pid, NULL, 0); - return m_pSettings; + return bug_status; } PLUGIN_INFO(REPORTER, diff --git a/lib/plugins/RHTSupport.h b/lib/plugins/RHTSupport.h index 82a3e4bd..2338732f 100644 --- a/lib/plugins/RHTSupport.h +++ b/lib/plugins/RHTSupport.h @@ -24,12 +24,6 @@ class CReporterRHticket: public CReporter { - private: - bool m_ssl_verify; - char *m_strata_url; - char *m_login; - char *m_password; - public: CReporterRHticket(); virtual ~CReporterRHticket(); @@ -39,7 +33,6 @@ class CReporterRHticket: public CReporter const char *pArgs); virtual void SetSettings(const map_plugin_settings_t& pSettings); - virtual const map_plugin_settings_t& GetSettings(); }; #endif diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index f3fad098..bd839a23 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -11,7 +11,8 @@ sbin_PROGRAMS = abrtd \ abrt-action-save-package-data bin_PROGRAMS = \ - abrt-action-bugzilla + abrt-action-bugzilla \ + abrt-action-rhtsupport abrtd_SOURCES = \ PluginManager.h PluginManager.cpp \ @@ -178,6 +179,27 @@ abrt_action_bugzilla_LDADD = \ ../../lib/utils/libABRTdUtils.la \ ../../lib/utils/libABRTUtils.la +abrt_action_rhtsupport_SOURCES = \ + abrt-action-rhtsupport.cpp +abrt_action_rhtsupport_CPPFLAGS = \ + -I$(srcdir)/../../inc \ + -I$(srcdir)/../../lib/utils \ + -DBIN_DIR=\"$(bindir)\" \ + -DVAR_RUN=\"$(VAR_RUN)\" \ + -DCONF_DIR=\"$(CONF_DIR)\" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ + -DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + $(GLIB_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Werror +abrt_action_rhtsupport_LDFLAGS = -ltar +abrt_action_rhtsupport_LDADD = \ + ../../lib/utils/libABRTdUtils.la \ + ../../lib/utils/libABRTUtils.la + dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/ dist_dbusabrtconf_DATA = dbus-abrt.conf diff --git a/src/daemon/abrt-action-rhtsupport.cpp b/src/daemon/abrt-action-rhtsupport.cpp new file mode 100644 index 00000000..d3918761 --- /dev/null +++ b/src/daemon/abrt-action-rhtsupport.cpp @@ -0,0 +1,312 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#define _GNU_SOURCE 1 /* for stpcpy */ +#include <libtar.h> +#include "abrtlib.h" +#include "abrt_curl.h" +#include "abrt_xmlrpc.h" +#include "abrt_rh_support.h" +#include "crash_types.h" +#include "abrt_exception.h" + +#include "plugin.h" /* make_description_bz */ + + +#define PROGNAME "abrt-action-rhtsupport" + +static void report_to_rhtsupport( + const char *dump_dir_name, + /*const*/ map_plugin_settings_t& pSettings) +{ + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (!dd) + { + throw CABRTException(EXCEP_PLUGIN, _("Can't open '%s'"), dump_dir_name); + } + map_crash_data_t pCrashData; + load_crash_data_from_debug_dump(dd, pCrashData); + dd_close(dd); + + /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ + log(_("Compressing data")); + + const char* errmsg = NULL; + TAR* tar = NULL; + pid_t child; + char* tempfile = NULL; + reportfile_t* file = NULL; + char* dsc = NULL; + char* summary = NULL; + const char* function; + const char* reason; + const char* package; + + map_plugin_settings_t::const_iterator end = pSettings.end(); + map_plugin_settings_t::const_iterator it; + it = pSettings.find("URL"); + char *url = xstrdup(it == end ? "https://api.access.redhat.com/rs" : it->second.c_str()); + + it = pSettings.find("Login"); + char *login = xstrdup(it == end ? "" : it->second.c_str()); + + it = pSettings.find("Password"); + char *password = xstrdup(it == end ? "" : it->second.c_str()); + + it = pSettings.find("SSLVerify"); + bool ssl_verify = (it == end ? true : string_to_bool(it->second.c_str())); + + if (!login[0] || !password[0]) + { + errmsg = _("Empty login or password, please check RHTSupport.conf"); + goto ret; + } + + package = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_PACKAGE); + reason = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_REASON); + function = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_CRASH_FUNCTION); + + { + struct strbuf *buf_summary = strbuf_new(); + strbuf_append_strf(buf_summary, "[abrt] %s", package); + if (function && strlen(function) < 30) + strbuf_append_strf(buf_summary, ": %s", function); + if (reason) + strbuf_append_strf(buf_summary, ": %s", reason); + summary = strbuf_free_nobuf(buf_summary); + + char *bz_dsc = make_description_bz(pCrashData); + dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc); + free(bz_dsc); + } + + file = new_reportfile(); + + /* SELinux guys are not happy with /tmp, using /var/run/abrt */ + tempfile = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%lu-%lu.tar.gz", (long)getpid(), (long)time(NULL)); + + int pipe_from_parent_to_child[2]; + xpipe(pipe_from_parent_to_child); + child = fork(); + if (child == 0) + { + /* child */ + close(pipe_from_parent_to_child[1]); + xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); + xmove_fd(pipe_from_parent_to_child[0], 0); + execlp("gzip", "gzip", NULL); + perror_msg_and_die("can't execute '%s'", "gzip"); + } + close(pipe_from_parent_to_child[0]); + + if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, + /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) + { + errmsg = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; + goto ret; + } + + { + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) + { + if (it->first == CD_COUNT) continue; + if (it->first == CD_DUMPDIR) continue; + if (it->first == CD_INFORMALL) continue; + if (it->first == CD_REPORTED) continue; + if (it->first == CD_MESSAGE) continue; // plugin's status message (if we already reported it yesterday) + if (it->first == FILENAME_DESCRIPTION) continue; // package description + + const char *content = it->second[CD_CONTENT].c_str(); + if (it->second[CD_TYPE] == CD_TXT) + { + reportfile_add_binding_from_string(file, it->first.c_str(), content); + } + else if (it->second[CD_TYPE] == CD_BIN) + { + const char *basename = strrchr(content, '/'); + if (basename) + basename++; + else + basename = content; + char *xml_name = concat_path_file("content", basename); + reportfile_add_binding_from_namedfile(file, + /*on_disk_filename */ content, + /*binding_name */ it->first.c_str(), + /*recorded_filename*/ xml_name, + /*binary */ 1); + if (tar_append_file(tar, (char*)content, xml_name) != 0) + { + errmsg = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; + free(xml_name); + goto ret; + } + free(xml_name); + } + } + } + + /* Write out content.xml in the tarball's root */ + { + const char *signature = reportfile_as_string(file); + unsigned len = strlen(signature); + unsigned len512 = (len + 511) & ~511; + char *block = (char*)memcpy(xzalloc(len512), signature, len); + th_set_type(tar, S_IFREG | 0644); + th_set_mode(tar, S_IFREG | 0644); + //th_set_link(tar, char *linkname); + //th_set_device(tar, dev_t device); + //th_set_user(tar, uid_t uid); + //th_set_group(tar, gid_t gid); + //th_set_mtime(tar, time_t fmtime); + th_set_path(tar, (char*)"content.xml"); + th_set_size(tar, len); + th_finish(tar); /* caclulate and store th xsum etc */ + if (th_write(tar) != 0 + || full_write(tar_fd(tar), block, len512) != len512 + || tar_close(tar) != 0 + ) { + free(block); + errmsg = "can't create temporary file in "LOCALSTATEDIR"/run/abrt"; + goto ret; + } + tar = NULL; + free(block); + } + + { + log(_("Creating a new case...")); + char* result = send_report_to_new_case(url, + login, + password, + ssl_verify, + summary, + dsc, + package, + tempfile + ); + VERB3 log("post result:'%s'", result); + printf("STATUS:%s", result); + free(result); + } + + ret: + // Damn, selinux does not allow SIGKILLing our own child! wtf?? + //kill(child, SIGKILL); /* just in case */ + waitpid(child, NULL, 0); + if (tar) + tar_close(tar); + //close(pipe_from_parent_to_child[1]); - tar_close() does it itself + unlink(tempfile); + free(tempfile); + reportfile_free(file); + + free(summary); + free(dsc); + + free(url); + free(login); + free(password); + + if (errmsg) + { + throw CABRTException(EXCEP_PLUGIN, "%s", errmsg); + } +} + +int main(int argc, char **argv) +{ + char *env_verbose = getenv("ABRT_VERBOSE"); + if (env_verbose) + g_verbose = atoi(env_verbose); + + map_plugin_settings_t settings; + + const char *dump_dir_name = "."; + enum { + OPT_s = (1 << 0), + }; + int optflags = 0; + int opt; + while ((opt = getopt(argc, argv, "c:d:vs")) != -1) + { + switch (opt) + { + case 'c': + dump_dir_name = optarg; + VERB1 log("Loading settings from '%s'", optarg); + LoadPluginSettings(optarg, settings); + VERB3 log("Loaded '%s'", optarg); + break; + case 'd': + dump_dir_name = optarg; + break; + case 'v': + g_verbose++; + break; + case 's': + optflags |= OPT_s; + break; + default: + /* Careful: the string below contains tabs, dont replace with spaces */ + error_msg_and_die( + "Usage: "PROGNAME" -c CONFFILE -d DIR [-vs]" + "\n" + "\nReport a crash to RHTSupport" + "\n" + "\nOptions:" + "\n -c FILE Configuration file (may be given many times)" + "\n -d DIR Crash dump directory" + "\n -v Verbose" + "\n -s Log to syslog" + ); + } + } + + putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); + +//DONT! our stdout/stderr goes directly to daemon, don't want to have prefix there. +// msg_prefix = xasprintf(PROGNAME"[%u]", getpid()); + + if (optflags & OPT_s) + { + openlog(msg_prefix, 0, LOG_DAEMON); + logmode = LOGMODE_SYSLOG; + } + + VERB1 log("Initializing XML-RPC library"); + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_client_setup_global_const(&env); + if (env.fault_occurred) + error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code); + xmlrpc_env_clean(&env); + + try + { + report_to_rhtsupport(dump_dir_name, settings); + } + catch (CABRTException& e) + { + printf("EXCEPT:%s\n", e.what()); + return 1; + } + + return 0; +} |