summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abrt.spec1
-rw-r--r--lib/plugins/Makefile.am2
-rw-r--r--lib/plugins/RHTSupport.cpp353
-rw-r--r--lib/plugins/RHTSupport.h7
-rw-r--r--src/daemon/Makefile.am24
-rw-r--r--src/daemon/abrt-action-rhtsupport.cpp312
6 files changed, 421 insertions, 278 deletions
diff --git a/abrt.spec b/abrt.spec
index 3b3ca631..44f2a28c 100644
--- a/abrt.spec
+++ b/abrt.spec
@@ -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("&amp;")-2;
- if (*s == '<')
- count += sizeof("&lt;")-2;
- if (*s == '>')
- count += sizeof("&gt;")-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, "&amp;");
- else if (*s == '<')
- d = stpcpy(d, "&lt;");
- else if (*s == '>')
- d = stpcpy(d, "&gt;");
- 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;
+}