abrt-action-rhtsupport: fix error handling
by Denys Vlasenko
Fixing my recent breakage.
Run-tested.
--
vda
diff -x '*.po' -d -urpN abrt.3/src/daemon/abrt-action-rhtsupport.cpp abrt.4/src/daemon/abrt-action-rhtsupport.cpp
--- abrt.3/src/daemon/abrt-action-rhtsupport.cpp 2010-10-20 18:35:13.000000000 +0200
+++ abrt.4/src/daemon/abrt-action-rhtsupport.cpp 2010-10-21 14:58:58.155109850 +0200
@@ -201,8 +201,35 @@ static void report_to_rhtsupport(
package,
tempfile
);
- VERB3 log("post result:'%s'", result);
- printf("STATUS:%s", result);
+ /* Temporary hackish detection of errors. Ideally,
+ * send_report_to_new_case needs to have better error reporting.
+ */
+ if (strncasecmp(result, "error", 5) == 0)
+ {
+ /*
+ * result can contain "...server says: 'multi-line <html> text'"
+ * Replace all '\n' with spaces:
+ * we want this message to be, logically, one log entry.
+ * IOW: one line, not many lines.
+ */
+ char *src, *dst;
+ dst = src = result;
+ while (1)
+ {
+ unsigned char c = *src++;
+ if (c == '\n')
+ c = ' ';
+ *dst++ = c;
+ if (c == '\0')
+ break;
+ }
+ /* Use sanitized string as error message */
+ CABRTException e(EXCEP_PLUGIN, "%s", result);
+ free(result);
+ throw e;
+ }
+ /* No error */
+ printf("STATUS:%s\n", result);
free(result);
}
13 years, 7 months
[PATCH] move logger reporting to a separate program (abrt-action-print)
by Denys Vlasenko
# abrt-action-print --help
Usage: abrt-action-print [v] -d DIR
Print information about the crash to standard output
-v, --verbose be verbose
-d DIR Crash dump directory
As you can see, it simply writes crash dump information
to stdout, not to a file.
Logger plugin spawns a child abrt-action-print -d DIR
and pipes its output to log file.
Run tested.
Please review.
--
vda
diff -x '*.po' -d -urpN abrt.7/abrt.spec abrt.8/abrt.spec
--- abrt.7/abrt.spec 2010-10-18 17:49:43.560968358 +0200
+++ abrt.8/abrt.spec 2010-10-19 15:49:53.829565690 +0200
@@ -356,6 +356,7 @@ fi
%{_sbindir}/abrt-action-save-package-data
%{_bindir}/abrt-action-bugzilla
%{_bindir}/abrt-action-rhtsupport
+%{_bindir}/abrt-action-print
%{_bindir}/abrt-action-install-debuginfo
%{_bindir}/%{name}-handle-upload
%{_bindir}/%{name}-backtrace
diff -x '*.po' -d -urpN abrt.7/lib/plugins/Logger.cpp abrt.8/lib/plugins/Logger.cpp
--- abrt.7/lib/plugins/Logger.cpp 2010-10-11 19:29:27.000000000 +0200
+++ abrt.8/lib/plugins/Logger.cpp 2010-10-19 15:59:27.182316435 +0200
@@ -1,5 +1,5 @@
/*
- Logger.cpp - it simple writes report to specific file
+ Logger.cpp - it simply writes report to a specified file
Copyright (C) 2009 Zdenek Prikryl (zprikryl(a)redhat.com)
Copyright (C) 2009 RedHat inc.
@@ -19,60 +19,107 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "abrtlib.h"
-#include "Logger.h"
#include "comm_layer_inner.h"
#include "abrt_exception.h"
+#include "Logger.h"
+
+using namespace std;
CLogger::CLogger()
{
- m_log_path = xstrdup("/var/log/abrt.log");
- m_append_logs = true;
+ m_pSettings["LogPath"] = "/var/log/abrt.log";
+ m_pSettings["AppendLogs"] = "yes";
}
CLogger::~CLogger()
{
- free(m_log_path);
}
void CLogger::SetSettings(const map_plugin_settings_t& pSettings)
{
+ /* Can't simply do this:
+
m_pSettings = pSettings;
- map_plugin_settings_t::const_iterator end = pSettings.end();
- map_plugin_settings_t::const_iterator it;
- it = pSettings.find("LogPath");
- if (it != end)
+ * - 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!
+ */
+
+ map_plugin_settings_t::iterator it = m_pSettings.begin();
+ while (it != m_pSettings.end())
{
- free(m_log_path);
- m_log_path = xstrdup(it->second.c_str());
+ map_plugin_settings_t::const_iterator override = pSettings.find(it->first);
+ if (override != pSettings.end())
+ {
+ VERB3 log(" logger settings[%s]='%s'", it->first.c_str(), it->second.c_str());
+ it->second = override->second;
+ }
+ it++;
}
- it = pSettings.find("AppendLogs");
- if (it != end)
- m_append_logs = string_to_bool(it->second.c_str());
}
-std::string CLogger::Report(const map_crash_data_t& pCrashData,
+string CLogger::Report(const map_crash_data_t& crash_data,
const map_plugin_settings_t& pSettings,
const char *pArgs)
{
- char *dsc = make_description_logger(pCrashData);
- char *full_dsc = xasprintf("%s\n\n\n", dsc);
- free(dsc);
+ const char *log_path = "/var/log/abrt.log";
+ bool append_logs = true;
+
+ map_plugin_settings_t::const_iterator end = pSettings.end();
+ map_plugin_settings_t::const_iterator it;
+ it = pSettings.find("LogPath");
+ if (it != end)
+ log_path = it->second.c_str();
+ it = pSettings.find("AppendLogs");
+ if (it != end)
+ append_logs = string_to_bool(it->second.c_str());
/* open, not fopen - want to set mode if we create the file, not just open */
- const char *fname = m_log_path;
- int fd = open(fname, m_append_logs ? O_WRONLY|O_CREAT|O_APPEND : O_WRONLY|O_CREAT|O_TRUNC, 0600);
+ int fd = open(log_path, append_logs ? O_WRONLY|O_CREAT|O_APPEND : O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (fd < 0)
- throw CABRTException(EXCEP_PLUGIN, "Can't open '%s'", fname);
+ throw CABRTException(EXCEP_PLUGIN, "Can't open '%s'", log_path);
- update_client(_("Writing report to '%s'"), fname);
- full_write_str(fd, full_dsc);
- free(full_dsc);
+ update_client(_("Writing report to '%s'"), log_path);
+ /* abrt-action-print -d DIR NULL */
+ char *argv[4];
+ char **pp = argv;
+ *pp++ = (char*)"abrt-action-print";
+ *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_OUTPUT, // + EXECFLG_ERR2OUT,
+ argv,
+ pipefds,
+ /* unsetenv_vec: */ NULL,
+ /* dir: */ NULL,
+ /* uid(unused): */ 0
+ );
+
+ /* Consume log from stdout, write it to log file */
+ FILE *fp = fdopen(pipefds[0], "r");
+ if (!fp)
+ die_out_of_memory();
+ char buf[512];
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ full_write_str(fd, buf);
+ }
+ fclose(fp); /* this also closes pipefds[0] */
+ /* wait for child to actually exit, and prevent leaving a zombie behind */
+ waitpid(pid, NULL, 0);
+
+ /* Add separating empty lines, then close log file */
+ full_write_str(fd, "\n\n\n");
close(fd);
- const char *format = m_append_logs ? _("The report was appended to %s") : _("The report was stored to %s");
- return ssprintf(format, m_log_path);
+ const char *format = append_logs ? _("The report was appended to %s") : _("The report was stored to %s");
+ return ssprintf(format, log_path);
}
PLUGIN_INFO(REPORTER,
diff -x '*.po' -d -urpN abrt.7/lib/plugins/Logger.h abrt.8/lib/plugins/Logger.h
--- abrt.7/lib/plugins/Logger.h 2010-09-23 16:48:44.000000000 +0200
+++ abrt.8/lib/plugins/Logger.h 2010-10-19 16:20:13.408315878 +0200
@@ -27,9 +27,6 @@
class CLogger : public CReporter
{
- private:
- char *m_log_path;
- bool m_append_logs;
public:
CLogger();
~CLogger();
diff -x '*.po' -d -urpN abrt.7/src/daemon/abrt-action-print.cpp abrt.8/src/daemon/abrt-action-print.cpp
--- abrt.7/src/daemon/abrt-action-print.cpp 1970-01-01 01:00:00.000000000 +0100
+++ abrt.8/src/daemon/abrt-action-print.cpp 2010-10-19 16:07:55.279315726 +0200
@@ -0,0 +1,83 @@
+/*
+ Write crash dump to stdout in text form.
+
+ Copyright (C) 2009 Zdenek Prikryl (zprikryl(a)redhat.com)
+ Copyright (C) 2009 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.
+*/
+#include "abrtlib.h"
+#include "parse_options.h"
+#include "crash_types.h"
+#include "abrt_exception.h"
+#include "plugin.h" /* make_description_logger */
+
+#define PROGNAME "abrt-action-print"
+
+static void report_to_stdout(const char *dump_dir_name)
+{
+ 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);
+
+ char *dsc = make_description_logger(pCrashData);
+ fputs(dsc, stdout);
+ free(dsc);
+}
+
+static const char *dump_dir_name = ".";
+
+int main(int argc, char **argv)
+{
+ char *env_verbose = getenv("ABRT_VERBOSE");
+ if (env_verbose)
+ g_verbose = atoi(env_verbose);
+
+ const char *program_usage = _(
+ PROGNAME" [v] -d DIR\n"
+ "\n"
+ "Print information about the crash to standard output");
+ enum {
+ OPT_v = 1 << 0,
+ OPT_d = 1 << 1,
+ };
+ /* Keep enum above and order of options below in sync! */
+ struct options program_options[] = {
+ OPT__VERBOSE(&g_verbose),
+ OPT_STRING('d', NULL, &dump_dir_name, "DIR", _("Crash dump directory")),
+ OPT_END()
+ };
+
+ /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage);
+
+ putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
+
+ try
+ {
+ report_to_stdout(dump_dir_name);
+ }
+ catch (CABRTException& e)
+ {
+ log("%s", e.what());
+ return 1;
+ }
+
+ return 0;
+}
diff -x '*.po' -d -urpN abrt.7/src/daemon/Makefile.am abrt.8/src/daemon/Makefile.am
--- abrt.7/src/daemon/Makefile.am 2010-10-18 18:18:06.370302316 +0200
+++ abrt.8/src/daemon/Makefile.am 2010-10-19 15:50:56.476565669 +0200
@@ -12,7 +12,8 @@ sbin_PROGRAMS = abrtd \
bin_PROGRAMS = \
abrt-action-bugzilla \
- abrt-action-rhtsupport
+ abrt-action-rhtsupport \
+ abrt-action-print
abrtd_SOURCES = \
PluginManager.h PluginManager.cpp \
@@ -199,6 +200,26 @@ abrt_action_rhtsupport_LDADD = \
../../lib/utils/libABRTdUtils.la \
../../lib/utils/libABRTUtils.la
+abrt_action_print_SOURCES = \
+ abrt-action-print.cpp
+abrt_action_print_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_print_LDADD = \
+ ../../lib/utils/libABRTdUtils.la \
+ ../../lib/utils/libABRTUtils.la
+
dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/
dist_dbusabrtconf_DATA = dbus-abrt.conf
13 years, 7 months
[PATCH] move rhtsupport reporting to a separate program (abrt-action-rhtsupport)
by Denys Vlasenko
The tool works similarly to abrt-action-bugzilla:
# abrt-action-rhtsupport --help
abrt-action-rhtsupport: invalid option -- '-'
Usage: abrt-action-rhtsupport -c CONFFILE -d DIR [-vs]
Report a crash to RHTSupport
Options:
-c FILE Configuration file (may be given many times)
-d DIR Crash dump directory
-v Verbose
-s Log to syslog
Please review.
--
vda
diff -x '*.po' -d -urpN abrt.6/abrt.spec abrt.7/abrt.spec
--- abrt.6/abrt.spec 2010-10-15 14:22:44.381928591 +0200
+++ abrt.7/abrt.spec 2010-10-18 17:49:43.560968358 +0200
@@ -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
%{_bindir}/%{name}-backtrace
diff -x '*.po' -d -urpN abrt.6/lib/plugins/Makefile.am abrt.7/lib/plugins/Makefile.am
--- abrt.6/lib/plugins/Makefile.am 2010-10-15 13:02:48.456929208 +0200
+++ abrt.7/lib/plugins/Makefile.am 2010-10-18 18:17:03.983967955 +0200
@@ -126,7 +126,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 -x '*.po' -d -urpN abrt.6/lib/plugins/RHTSupport.cpp abrt.7/lib/plugins/RHTSupport.cpp
--- abrt.6/lib/plugins/RHTSupport.cpp 2010-10-11 19:21:31.000000000 +0200
+++ abrt.7/lib/plugins/RHTSupport.cpp 2010-10-18 17:48:54.515218108 +0200
@@ -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,88 @@
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)
+string CReporterRHticket::Report(const map_crash_data_t& crash_data,
+ const map_plugin_settings_t& settings,
+ const char *args)
{
- /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */
- update_client(_("Compressing data"));
-
- string retval;
-
- 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);
+ /* abrt-action-bugzilla [-s] -c /etc/arbt/Bugzilla.conf -c - -d pCrashData.dir NULL */
+ char *argv[9];
+ char **pp = argv;
+ *pp++ = (char*)"abrt-action-bugzilla";
- reportfile_t* file = new_reportfile();
+//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...
- /* 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));
+ *pp++ = (char*)"-c";
+ *pp++ = (char*)(PLUGINS_CONF_DIR"/Bugzilla."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
+ );
- int pipe_from_parent_to_child[2];
- xpipe(pipe_from_parent_to_child);
- pid_t child = fork();
- if (child == 0)
+ /* Write the configuration to stdin */
+ map_plugin_settings_t::const_iterator it = settings.begin();
+ while (it != settings.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");
+ 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++;
}
- close(pipe_from_parent_to_child[0]);
+ close(pipefds[1]);
- 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;
- }
+ 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))
{
- map_crash_data_t::const_iterator it = pCrashData.begin();
- for (; it != pCrashData.end(); it++)
+ strchrnul(buf, '\n')[0] = '\0';
+ if (strncmp(buf, "STATUS:", 7) == 0)
+ bug_status = buf + 7;
+ else
+ if (strncmp(buf, "EXCEPT:", 7) == 0)
{
- 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;
+ fclose(fp);
+ waitpid(pid, NULL, 0);
+ throw CABRTException(EXCEP_PLUGIN, "%s", buf + 7);
}
- 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());
- }
- return retval;
-}
-
-void CReporterRHticket::SetSettings(const map_plugin_settings_t& pSettings)
-{
- 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)
- {
- free(m_password);
- m_password = xstrdup(it->second.c_str());
- }
- it = pSettings.find("SSLVerify");
- if (it != end)
- {
- m_ssl_verify = string_to_bool(it->second.c_str());
+ 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 -x '*.po' -d -urpN abrt.6/src/daemon/abrt-action-rhtsupport.cpp abrt.7/src/daemon/abrt-action-rhtsupport.cpp
--- abrt.6/src/daemon/abrt-action-rhtsupport.cpp 1970-01-01 01:00:00.000000000 +0100
+++ abrt.7/src/daemon/abrt-action-rhtsupport.cpp 2010-10-18 18:14:20.812967965 +0200
@@ -0,0 +1,314 @@
+/*
+ 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 "comm_layer_inner.h"
+//#include "RHTSupport.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;
+}
diff -x '*.po' -d -urpN abrt.6/src/daemon/Makefile.am abrt.7/src/daemon/Makefile.am
--- abrt.6/src/daemon/Makefile.am 2010-10-15 14:21:59.451179034 +0200
+++ abrt.7/src/daemon/Makefile.am 2010-10-18 18:18:06.370302316 +0200
@@ -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 \
@@ -177,6 +178,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
13 years, 7 months
[PATCH 1/5] get rid of std::string from bugzilla
by Nikola Pajkovsky
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
inc/plugin.h | 6 +-
lib/plugins/Bugzilla.cpp | 244 ++++++++++++++++++++++++---------------------
lib/plugins/Bugzilla.h | 12 +-
lib/plugins/Logger.cpp | 10 +-
lib/utils/make_descr.cpp | 180 +++++++++++++++++++---------------
5 files changed, 245 insertions(+), 207 deletions(-)
diff --git a/inc/plugin.h b/inc/plugin.h
index 34d5743..d7772b5 100644
--- a/inc/plugin.h
+++ b/inc/plugin.h
@@ -119,9 +119,9 @@ typedef struct SPluginInfo
};
/* helper functions */
-std::string make_description_bz(const map_crash_data_t& pCrashData);
-std::string make_description_reproduce_comment(const map_crash_data_t& pCrashData);
-std::string make_description_logger(const map_crash_data_t& pCrashData);
+char* make_description_bz(const map_crash_data_t& pCrashData);
+char* make_description_reproduce_comment(const map_crash_data_t& pCrashData);
+char* make_description_logger(const map_crash_data_t& pCrashData);
/**
* Loads settings and stores it in second parameter. On success it
diff --git a/lib/plugins/Bugzilla.cpp b/lib/plugins/Bugzilla.cpp
index f3967cd..e494f08 100644
--- a/lib/plugins/Bugzilla.cpp
+++ b/lib/plugins/Bugzilla.cpp
@@ -24,6 +24,7 @@
#include "debug_dump.h"
#include "abrt_exception.h"
#include "comm_layer_inner.h"
+#include "strbuf.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -31,6 +32,7 @@
#define XML_RPC_SUFFIX "/xmlrpc.cgi"
#define MAX_HOPS 5
+
/*
* TODO: npajkovs: better deallocation of xmlrpc value
* npajkovs: better gathering function which collects all information from bugzilla
@@ -389,46 +391,45 @@ int ctx::add_comment(xmlrpc_int32 bug_id, const char* comment, bool is_private)
xmlrpc_int32 ctx::new_bug(const map_crash_data_t& pCrashData, int depend_on_bugno)
{
- 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& duphash = get_crash_data_item_content(pCrashData, CD_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);
-
- std::string summary = "[abrt] " + package;
+ const char *package = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_PACKAGE);
+ const char *component = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_COMPONENT);
+ const char *release = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_RELEASE);
+ const char *arch = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_ARCHITECTURE);
+ const char *duphash = get_crash_data_item_content_or_NULL(pCrashData, CD_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 != NULL && strlen(function) < 30)
- {
- summary += ": ";
- summary += function;
- }
+ strbuf_append_strf(buf_summary, ": %s", function);
if (reason != NULL)
- {
- summary += ": ";
- summary += reason;
- }
- std::string status_whiteboard = "abrt_hash:" + duphash;
+ strbuf_append_strf(buf_summary, ": %s", reason);
+
+ char *status_whiteboard = xasprintf("abrt_hash:%s", duphash);
- std::string description = "abrt version: "VERSION"\n";
- description += make_description_bz(pCrashData);
+ char *bz_dsc = make_description_bz(pCrashData);
+ char *full_dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc);
+ free(bz_dsc);
char *product = NULL;
char *version = NULL;
- parse_release(release.c_str(), &product, &version);
+ parse_release(release, &product, &version);
xmlrpc_value* result = NULL;
+ char *summary = strbuf_free_nobuf(buf_summary);
if (depend_on_bugno > -1)
{
result = call("Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:i})",
"product", product,
- "component", component.c_str(),
+ "component", component,
"version", version,
- "summary", summary.c_str(),
- "description", description.c_str(),
- "status_whiteboard", status_whiteboard.c_str(),
- "platform", arch.c_str(),
+ "summary", summary,
+ "description", full_dsc,
+ "status_whiteboard", status_whiteboard,
+ "platform", arch,
"dependson", depend_on_bugno
);
}
@@ -436,17 +437,19 @@ xmlrpc_int32 ctx::new_bug(const map_crash_data_t& pCrashData, int depend_on_bugn
{
result = call("Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
"product", product,
- "component", component.c_str(),
+ "component", component,
"version", version,
- "summary", summary.c_str(),
- "description", description.c_str(),
- "status_whiteboard", status_whiteboard.c_str(),
- "platform", arch.c_str()
+ "summary", summary,
+ "description", full_dsc,
+ "status_whiteboard", status_whiteboard,
+ "platform", arch
);
-
}
+ free(status_whiteboard);
free(product);
free(version);
+ free(summary);
+ free(full_dsc);
if (!result)
return -1;
@@ -473,21 +476,23 @@ int ctx::add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashD
map_crash_data_t::const_iterator it = pCrashData.begin();
for (; it != pCrashData.end(); it++)
{
- const std::string &itemname = it->first;
- const std::string &type = it->second[CD_TYPE];
- const std::string &content = it->second[CD_CONTENT];
+ const char *itemname = it->first.c_str();
+ const char *type = it->second[CD_TYPE].c_str();
+ const char *content = it->second[CD_CONTENT].c_str();
- if (type == CD_TXT
- && (content.length() > CD_TEXT_ATT_SIZE || itemname == FILENAME_BACKTRACE)
+ if ((strcmp(type, CD_TXT) == 0)
+ && (strlen(content) > CD_TEXT_ATT_SIZE || (strcmp(itemname, FILENAME_BACKTRACE) == 0))
) {
- char *encoded64 = encode_base64(content.c_str(), content.length());
+ char *encoded64 = encode_base64(content, strlen(content));
+ char *filename = xasprintf("File: %s", itemname);
xmlrpc_value* result = call("bugzilla.addAttachment", "(s{s:s,s:s,s:s,s:s})", bug_id_str,
- "description", ("File: " + itemname).c_str(),
- "filename", itemname.c_str(),
+ "description", filename,
+ "filename", itemname,
"contenttype", "text/plain",
"data", encoded64
);
free(encoded64);
+ free(filename);
if (!result)
return -1;
@@ -558,9 +563,11 @@ void ctx::login(const char* login, const char* passwd)
if (!result)
{
- std::string errmsg = ssprintf(_("Cannot login. Check Edit->Plugins->Bugzilla and /etc/abrt/plugins/Bugzilla.conf. Server said: %s"), env.fault_string);
- error_msg("%s", errmsg.c_str()); // show error in daemon log
- throw CABRTException(EXCEP_PLUGIN, "%s", errmsg.c_str());
+ char *errmsg = xasprintf("Can't login. Check Edit->Plugins->Bugzilla and /etc/abrt/plugins/Bugzilla.conf. Server said: %s", env.fault_string);
+ error_msg("%s", errmsg); // show error in daemon log
+ CABRTException e(EXCEP_PLUGIN, errmsg);
+ free(errmsg);
+ throw e;
}
xmlrpc_DECREF(result);
}
@@ -636,59 +643,68 @@ static map_plugin_settings_t parse_settings(const map_plugin_settings_t& pSettin
return plugin_settings;
}
-CReporterBugzilla::CReporterBugzilla() :
- m_bSSLVerify(true),
- m_sBugzillaURL("https://bugzilla.redhat.com"),
- m_sBugzillaXMLRPC("https://bugzilla.redhat.com"XML_RPC_SUFFIX),
- m_bRatingRequired(true)
-{}
+CReporterBugzilla::CReporterBugzilla()
+{
+ m_ssl_verify = true;
+ m_rating_required = true;
+ m_login = NULL;
+ m_password = NULL;
+ m_bugzilla_url = xstrdup("https://bugzilla.redhat.com");
+ m_bugzilla_xmlrpc = xstrdup("https://bugzilla.redhat.com"XML_RPC_SUFFIX);
+}
CReporterBugzilla::~CReporterBugzilla()
-{}
+{
+ free(m_login);
+ free(m_password);
+ free(m_bugzilla_url);
+ free(m_bugzilla_xmlrpc);
+}
std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
const map_plugin_settings_t& pSettings,
const char *pArgs)
{
xmlrpc_int32 bug_id = -1;
- std::string Login;
- std::string Password;
- std::string BugzillaXMLRPC;
- std::string BugzillaURL;
- bool SSLVerify;
+ const char *login = NULL;
+ const char *password = NULL;
+ const char *bugzilla_xmlrpc = NULL;
+ const char *bugzilla_url = NULL;
+ bool ssl_verify;
+
map_plugin_settings_t settings = parse_settings(pSettings);
/* if parse_settings fails it returns an empty map so we need to use defaults */
if (!settings.empty())
{
- Login = settings["Login"];
- Password = settings["Password"];
- BugzillaXMLRPC = settings["BugzillaXMLRPC"];
- BugzillaURL = settings["BugzillaURL"];
- SSLVerify = string_to_bool(settings["SSLVerify"].c_str());
+ login = settings["Login"].c_str();
+ password = settings["Password"].c_str();
+ bugzilla_xmlrpc = settings["BugzillaXMLRPC"].c_str();
+ bugzilla_url = settings["BugzillaURL"].c_str();
+ ssl_verify = string_to_bool(settings["NoSSLVerify"].c_str());
}
else
{
- Login = m_sLogin;
- Password = m_sPassword;
- BugzillaXMLRPC = m_sBugzillaXMLRPC;
- BugzillaURL = m_sBugzillaURL;
- SSLVerify = m_bSSLVerify;
+ login = m_login;
+ password = m_password;
+ bugzilla_xmlrpc = m_bugzilla_xmlrpc;
+ bugzilla_url = m_bugzilla_url;
+ ssl_verify = m_ssl_verify;
}
- if ((Login == "") || (Password == ""))
+ if (!login[0] || !password[0])
{
VERB3 log("Empty login and password");
throw CABRTException(EXCEP_PLUGIN, _("Empty login or password.\nPlease check "PLUGINS_CONF_DIR"/Bugzilla.conf."));
}
- const std::string& component = get_crash_data_item_content(pCrashData, FILENAME_COMPONENT);
- const std::string& duphash = get_crash_data_item_content(pCrashData, CD_DUPHASH);
- const char *release = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_RELEASE);
+ const char *component = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_COMPONENT);
+ const char *duphash = get_crash_data_item_content_or_NULL(pCrashData, CD_DUPHASH);
+ const char *release = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_RELEASE);
- ctx bz_server(BugzillaXMLRPC.c_str(), SSLVerify);
+ ctx bz_server(bugzilla_xmlrpc, ssl_verify);
update_client(_("Logging into bugzilla..."));
- bz_server.login(Login.c_str(), Password.c_str());
+ bz_server.login(login, password);
update_client(_("Checking for duplicates..."));
@@ -698,9 +714,9 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
xmlrpc_value *result;
if (strcmp(product, "Fedora") == 0)
- result = bz_server.call_quicksearch_duphash(component.c_str(), product, duphash.c_str());
+ result = bz_server.call_quicksearch_duphash(component, product, duphash);
else
- result = bz_server.call_quicksearch_duphash(component.c_str(), NULL, duphash.c_str());
+ result = bz_server.call_quicksearch_duphash(component, NULL, duphash);
if (!result)
throw_if_xml_fault_occurred(&bz_server.env);
@@ -736,7 +752,7 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
{
depend_on_bugno = bug_id;
bug_info_destroy(&bz);
- result = bz_server.call_quicksearch_duphash(component.c_str(), release, duphash.c_str());
+ result = bz_server.call_quicksearch_duphash(component, release, duphash);
if (!result)
throw_if_xml_fault_occurred(&bz_server.env);
@@ -799,7 +815,7 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
std::string bug_status = ssprintf(
"Status: NEW\n"
"%s/show_bug.cgi?id=%u",
- BugzillaURL.c_str(),
+ bugzilla_url,
(int)bug_id
);
return bug_status;
@@ -808,7 +824,7 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
{
// When someone clones bug it has same duphash, so we can find more than 1.
// Need to be checked if component is same.
- VERB3 log("Bugzilla has %u reports with same duphash '%s'", all_bugs_size, duphash.c_str());
+ VERB3 log("Bugzilla has %u reports with same duphash '%s'", all_bugs_size, duphash);
}
// decision based on state
@@ -850,11 +866,11 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
if (strcmp(bz.bug_status, "CLOSED") != 0)
{
int status = 0;
- if ((strcmp(bz.bug_reporter, Login.c_str()) != 0) && (am_i_in_cc(&bz, Login.c_str())))
+ if ((strcmp(bz.bug_reporter, login) != 0) && (am_i_in_cc(&bz, login)))
{
- VERB2 log(_("Adding %s to CC list"), Login.c_str());
- update_client(_("Adding %s to CC list"), Login.c_str());
- status = bz_server.add_plus_one_cc(bug_id, Login.c_str());
+ VERB2 log(_("Add %s to CC list"), login);
+ update_client(_("Add %s to CC list"), login);
+ status = bz_server.add_plus_one_cc(bug_id, login);
}
if (status == -1)
@@ -863,28 +879,32 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
throw_if_xml_fault_occurred(&bz_server.env);
}
- std::string description = make_description_reproduce_comment(pCrashData);
- if (!description.empty())
+ char *dsc = make_description_reproduce_comment(pCrashData);
+ if (dsc)
{
const char* package = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_PACKAGE);
const char* release = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_RELEASE);
const char* arch = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_ARCHITECTURE);
const char* is_private = get_crash_data_item_content_or_NULL(pCrashData, "is_private");
- description = ssprintf("Package: %s\n"
+ char *full_dsc = xasprintf("Package: %s\n"
"Architecture: %s\n"
"OS Release: %s\n"
- "%s", package, arch, release, description.c_str()
+ "%s", package, arch, release, dsc
);
update_client(_("Adding new comment to bug %d"), (int)bug_id);
+ free(dsc);
+
bool is_priv = is_private && (is_private[0] == '1');
- if (bz_server.add_comment(bug_id, description.c_str(), is_priv) == -1)
+ if (bz_server.add_comment(bug_id, full_dsc, is_priv) == -1)
{
+ free(full_dsc);
bug_info_destroy(&bz);
throw_if_xml_fault_occurred(&bz_server.env);
}
+ free(full_dsc);
}
}
@@ -897,7 +917,7 @@ std::string CReporterBugzilla::Report(const map_crash_data_t& pCrashData,
bz.bug_status,
bz.bug_resolution ? " " : "",
bz.bug_resolution ? bz.bug_resolution : "",
- BugzillaURL.c_str(),
+ bugzilla_url,
(int)bug_id
);
@@ -922,52 +942,48 @@ void CReporterBugzilla::SetSettings(const map_plugin_settings_t& pSettings)
it = pSettings.find("BugzillaURL");
if (it != end)
{
- m_sBugzillaURL = it->second;
- //remove the /xmlrpc.cgi part from old settings
- //FIXME: can be removed after users are informed about new config format
- std::string::size_type pos = m_sBugzillaURL.find(XML_RPC_SUFFIX);
- if (pos != std::string::npos)
- {
- m_sBugzillaURL.erase(pos);
- }
- //remove the trailing '/'
- while (m_sBugzillaURL[m_sBugzillaURL.length() - 1] == '/')
- {
- m_sBugzillaURL.erase(m_sBugzillaURL.length() - 1);
- }
- /*
- if (*(--m_sBugzillaURL.end()) == '/')
- {
- m_sBugzillaURL.erase(--m_sBugzillaURL.end());
- }
- */
- m_sBugzillaXMLRPC = m_sBugzillaURL + XML_RPC_SUFFIX;
+ free(m_bugzilla_url);
+ free(m_bugzilla_xmlrpc);
+
+ m_bugzilla_url = xstrdup(it->second.c_str());
+
+ int cnt = strlen(m_bugzilla_url);
+ while (m_bugzilla_url[cnt--] == '/')
+ m_bugzilla_url[cnt] = '\0';
+
+ int ret = suffixcmp(m_bugzilla_url, XML_RPC_SUFFIX);
+ if (ret != 0)
+ m_bugzilla_xmlrpc = xasprintf("%s%s", m_bugzilla_url, XML_RPC_SUFFIX);
+ else
+ m_bugzilla_xmlrpc = xstrdup(m_bugzilla_url);
}
it = pSettings.find("Login");
if (it != end)
{
- m_sLogin = it->second;
+ free(m_login);
+ m_login = xstrdup(it->second.c_str());
}
it = pSettings.find("Password");
if (it != end)
{
- m_sPassword = it->second;
+ free(m_password);
+ m_password = xstrdup(it->second.c_str());
}
it = pSettings.find("SSLVerify");
if (it != end)
{
- m_bSSLVerify = string_to_bool(it->second.c_str());
+ m_ssl_verify = string_to_bool(it->second.c_str());
}
}
/* Should not be deleted (why?) */
const map_plugin_settings_t& CReporterBugzilla::GetSettings()
{
- m_pSettings["BugzillaURL"] = m_sBugzillaURL;
- m_pSettings["Login"] = m_sLogin;
- m_pSettings["Password"] = m_sPassword;
- m_pSettings["SSLVerify"] = m_bSSLVerify ? "yes" : "no";
- m_pSettings["RatingRequired"] = m_bRatingRequired ? "yes" : "no";
+ m_pSettings["BugzillaURL"] = m_bugzilla_url;
+ m_pSettings["Login"] = (m_login)? m_login: "";
+ m_pSettings["Password"] = (m_password)? m_password: "";
+ m_pSettings["SSLVerify"] = m_ssl_verify ? "yes" : "no";
+ m_pSettings["RatingRequired"] = m_rating_required ? "yes" : "no";
return m_pSettings;
}
diff --git a/lib/plugins/Bugzilla.h b/lib/plugins/Bugzilla.h
index a4c9a01..2b32a70 100644
--- a/lib/plugins/Bugzilla.h
+++ b/lib/plugins/Bugzilla.h
@@ -25,12 +25,12 @@
class CReporterBugzilla : public CReporter
{
private:
- bool m_bSSLVerify;
- std::string m_sBugzillaURL;
- std::string m_sBugzillaXMLRPC;
- std::string m_sLogin;
- std::string m_sPassword;
- bool m_bRatingRequired;
+ bool m_ssl_verify;
+ char *m_bugzilla_url;
+ char *m_bugzilla_xmlrpc;
+ char *m_login;
+ char *m_password;
+ bool m_rating_required;
public:
CReporterBugzilla();
diff --git a/lib/plugins/Logger.cpp b/lib/plugins/Logger.cpp
index ece450d..a02845f 100644
--- a/lib/plugins/Logger.cpp
+++ b/lib/plugins/Logger.cpp
@@ -60,7 +60,9 @@ 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(pCrashData);
+ char *dsc = make_description_logger(pCrashData);
+ char *full_dsc = xasprintf("%s\n\n\n", dsc);
+ free(dsc);
/* open, not fopen - want to set mode if we create the file, not just open */
const char *fname = m_sLogPath.c_str();
@@ -71,9 +73,9 @@ std::string CLogger::Report(const map_crash_data_t& pCrashData,
throw CABRTException(EXCEP_PLUGIN, "Can't open '%s'", fname);
update_client(_("Writing report to '%s'"), fname);
- description += "\n\n\n";
- const char *desc = description.c_str();
- full_write(fd, desc, strlen(desc));
+ full_write(fd, full_dsc, strlen(full_dsc));
+ free(full_dsc);
+
close(fd);
const char *format = m_bAppendLogs ? _("The report was appended to %s") : _("The report was stored to %s");
diff --git a/lib/utils/make_descr.cpp b/lib/utils/make_descr.cpp
index 46d9644..93ae292 100644
--- a/lib/utils/make_descr.cpp
+++ b/lib/utils/make_descr.cpp
@@ -19,6 +19,7 @@
#include "abrtlib.h"
#include "crash_types.h"
#include "debug_dump.h" /* FILENAME_ARCHITECTURE etc */
+#include "strbuf.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@@ -29,13 +30,15 @@
# define _(S) (S)
#endif
+
using namespace std;
-static void add_content(bool &was_multiline, string& description, const char *header, const char *content)
+// caller is responsible for freeing **dsc
+static void add_content(bool *was_multiline, char **dsc, const char *header, const char *content)
{
- /* We separate multiline contents with emply line */
- if (was_multiline)
- description += '\n';
+ struct strbuf *buf_description = strbuf_new();
+ if (*was_multiline)
+ strbuf_append_char(buf_description, '\n');
while (content[0] == '\n')
content++;
@@ -45,27 +48,27 @@ static void add_content(bool &was_multiline, string& description, const char *he
if (skip_whitespace(content)[0] == '\0')
{
/* empty, dont report at all */
+ *dsc = strbuf_free_nobuf(buf_description);
return;
}
/* one string value, like OS release */
- description += header;
- description += ": ";
- description += content;
- description += '\n';
- was_multiline = 0;
+ strbuf_append_strf(buf_description, "%s: %s\n", header, content);
+ *was_multiline = 0;
}
else
{
/* multi-string value, like backtrace */
- if (!was_multiline && description.size() != 0) /* if wasn't yet separated */
- description += '\n'; /* do it now */
- description += header;
- description += "\n-----\n";
- description += content;
+ if (!*was_multiline && (buf_description->len != 0)) /* if wasn't yet separated */
+ strbuf_append_char(buf_description, '\n');
+
+ strbuf_append_strf(buf_description, "%s\n-----\n%s", header, content);
if (content[strlen(content) - 1] != '\n')
- description += '\n';
- was_multiline = 1;
+ strbuf_append_char(buf_description, '\n');
+
+ *was_multiline = 1;
}
+
+ *dsc = strbuf_free_nobuf(buf_description);
}
/* Items we don't want to include */
@@ -85,85 +88,91 @@ static const char *const blacklisted_items[] = {
NULL
};
-string make_description_bz(const map_crash_data_t& pCrashData)
+char* make_description_bz(const map_crash_data_t& pCrashData)
{
- string description;
- string long_description;
+ struct strbuf *buf_dsc = strbuf_new();
+ struct strbuf *buf_long_dsc = strbuf_new();
map_crash_data_t::const_iterator it = pCrashData.begin();
for (; it != pCrashData.end(); it++)
{
- const string& itemname = it->first;
- const string& type = it->second[CD_TYPE];
- const string& content = it->second[CD_CONTENT];
- if (type == CD_TXT)
+ const char *itemname = it->first.c_str();
+ const char *type = it->second[CD_TYPE].c_str();
+ const char *content = it->second[CD_CONTENT].c_str();
+ if (strcmp(type, CD_TXT) == 0)
{
/* Skip items we are not interested in */
const char *const *bl = blacklisted_items;
while (*bl)
{
- if (itemname == *bl)
+ if (strcmp(itemname, *bl) == 0)
break;
bl++;
}
if (*bl)
continue; /* blacklisted */
- if (content == "1.\n2.\n3.\n")
+ if (strcmp(content, "1.\n2.\n3.\n") == 0)
continue; /* user did not change default "How to reproduce" */
- if (content.size() <= CD_TEXT_ATT_SIZE)
+ if (strlen(content) <= CD_TEXT_ATT_SIZE)
{
/* Add small (less than few kb) text items inline */
bool was_multiline = 0;
- string tmp;
- add_content(was_multiline,
- tmp,
- /* "reproduce: blah" looks ugly, fixing: */
- itemname == FILENAME_REPRODUCE ? "How to reproduce" : itemname.c_str(),
- content.c_str()
+ char *tmp = NULL;
+ add_content(&was_multiline,
+ &tmp,
+ /* "reproduce: blah" looks ugly, fixing: */
+ (strcmp(itemname, FILENAME_REPRODUCE) == 0) ? "How to reproduce" : itemname,
+ content
);
if (was_multiline)
{
/* Not one-liner */
- if (long_description.size() != 0)
- long_description += '\n';
- long_description += tmp;
+ if (buf_long_dsc->len != 0)
+ strbuf_append_char(buf_long_dsc, '\n');
+
+ strbuf_append_str(buf_long_dsc, tmp);
}
else
- {
- description += tmp;
- }
+ strbuf_append_str(buf_dsc, tmp);
+
+ free(tmp);
} else {
bool was_multiline = 0;
- add_content(was_multiline, description, "Attached file", itemname.c_str());
+ char *dsc = NULL;
+ add_content(&was_multiline, &dsc, "Attached file", itemname);
+ strbuf_append_str(buf_dsc, dsc);
+ free(dsc);
}
}
}
/* One-liners go first, then multi-line items */
- if (description.size() != 0 && long_description.size() != 0)
- {
- description += '\n';
- }
- description += long_description;
+ if (buf_dsc->len != 0 && buf_long_dsc->len != 0)
+ strbuf_append_char(buf_dsc, '\n');
+
- return description;
+ char *long_dsc = strbuf_free_nobuf(buf_long_dsc);
+ strbuf_append_str(buf_dsc, long_dsc);
+ free(long_dsc);
+
+ return strbuf_free_nobuf(buf_dsc);
}
-string make_description_logger(const map_crash_data_t& pCrashData)
+char* make_description_logger(const map_crash_data_t& pCrashData)
{
- string description;
- string long_description;
+ struct strbuf *buf_dsc = strbuf_new();
+ struct strbuf *buf_long_dsc = strbuf_new();
map_crash_data_t::const_iterator it = pCrashData.begin();
for (; it != pCrashData.end(); it++)
{
- const string &filename = it->first;
- const string &type = it->second[CD_TYPE];
- const string &content = it->second[CD_CONTENT];
- if (type == CD_TXT
- || type == CD_BIN
+ const char *filename = it->first.c_str();
+ const char *type = it->second[CD_TYPE].c_str();
+ const char *content = it->second[CD_CONTENT].c_str();
+ if ((strcmp(type, CD_TXT) == 0)
+ || (strcmp(type, CD_BIN) == 0)
) {
/* Skip items we are not interested in */
const char *const *bl = blacklisted_items;
@@ -175,62 +184,73 @@ string make_description_logger(const map_crash_data_t& pCrashData)
}
if (*bl)
continue; /* blacklisted */
- if (content == "1.\n2.\n3.\n")
+ if (strcmp(content, "1.\n2.\n3.\n") == 0)
continue; /* user did not change default "How to reproduce" */
bool was_multiline = 0;
- string tmp;
- add_content(was_multiline, tmp, filename.c_str(), content.c_str());
+ char *tmp = NULL;
+ add_content(&was_multiline, &tmp, filename, content);
if (was_multiline)
{
- if (long_description.size() != 0)
- long_description += '\n';
- long_description += tmp;
+ if (buf_long_dsc->len != 0)
+ strbuf_append_char(buf_long_dsc,'\n');
+
+ strbuf_append_str(buf_long_dsc, tmp);
}
else
- {
- description += tmp;
- }
+ strbuf_append_str(buf_dsc, tmp);
}
}
- if (description.size() != 0 && long_description.size() != 0)
- {
- description += '\n';
- }
- description += long_description;
+ if (buf_dsc->len != 0 && buf_long_dsc->len != 0)
+ strbuf_append_char(buf_dsc, '\n');
+
+ char *long_dsc = strbuf_free_nobuf(buf_long_dsc);
+ strbuf_append_str(buf_dsc, long_dsc);
+ free(long_dsc);
- return description;
+ return strbuf_free_nobuf(buf_dsc);
}
-string make_description_reproduce_comment(const map_crash_data_t& pCrashData)
+char* make_description_reproduce_comment(const map_crash_data_t& pCrashData)
{
+ char *repro = NULL;
+ char *comment = NULL;
+
map_crash_data_t::const_iterator end = pCrashData.end();
map_crash_data_t::const_iterator it;
- string howToReproduce;
it = pCrashData.find(FILENAME_REPRODUCE);
if (it != end)
{
if ((it->second[CD_CONTENT].size() > 0)
&& (it->second[CD_CONTENT] != "1.\n2.\n3.\n"))
{
- howToReproduce = "\n\nHow to reproduce\n"
- "-----\n";
- howToReproduce += it->second[CD_CONTENT];
+ repro = xasprintf("\n\nHow to reproduce\n-----\n%s", it->second[CD_CONTENT].c_str());
}
}
- string comment;
+
it = pCrashData.find(FILENAME_COMMENT);
if (it != end)
{
if (it->second[CD_CONTENT].size() > 0)
- {
- comment = "\n\nComment\n"
- "-----\n";
- comment += it->second[CD_CONTENT];
- }
+ comment = xasprintf("\n\nComment\n-----\n%s", it->second[CD_CONTENT].c_str());
}
- return howToReproduce + comment;
+
+ if (!repro && !comment)
+ return NULL;
+
+ struct strbuf *buf_dsc = strbuf_new();
+
+ if (repro)
+ strbuf_append_str(buf_dsc, repro);
+
+ if (comment)
+ strbuf_append_str(buf_dsc, comment);
+
+ free(repro);
+ free(comment);
+
+ return strbuf_free_nobuf(buf_dsc);
}
--
1.7.1
13 years, 7 months
[PATCH] move uuid/duphash generation for python to a separate program (abrt-action-analyze-python)
by Denys Vlasenko
This patch splits off uuid generation for Python
to a separate program:
# abrt-action-analyze-python --help
Usage: abrt-action-analyze-python [-vs] -d DIR
Calculates and saves UUID and DUPHASH of python crash dumps
-v, --verbose be verbose
-d DIR Crash dump directory
-s Log to syslog
Run tested.
Please review.
--
vda
diff -x '*.po' -d -urpN abrt.4/abrt.spec abrt.5/abrt.spec
--- abrt.4/abrt.spec 2010-10-14 01:14:52.949399244 +0200
+++ abrt.5/abrt.spec 2010-10-15 14:22:28.079928484 +0200
@@ -350,6 +350,7 @@ fi
%{_sbindir}/abrtd
%{_sbindir}/abrt-server
%{_sbindir}/abrt-action-analyze-c
+%{_sbindir}/abrt-action-analyze-python
%{_sbindir}/abrt-action-generate-backtrace
%{_sbindir}/abrt-action-save-package-data
%{_bindir}/abrt-action-bugzilla
diff -x '*.po' -d -urpN abrt.4/inc/crash_types.h abrt.5/inc/crash_types.h
--- abrt.4/inc/crash_types.h 2010-10-14 01:14:52.949399244 +0200
+++ abrt.5/inc/crash_types.h 2010-10-15 13:16:44.749188459 +0200
@@ -63,7 +63,7 @@
// CD_UID from _somewhere_ in order to be able to store it in DB record,
// right?)
#define CD_UID "uid"
-/* CCpp is converted to save uuid as a file (python and oops aren't yet): */
+/* CCpp and Python are converted to save uuid as a file (oops isn't yet): */
#define CD_UUID "uuid"
#define CD_INFORMALL "InformAll"
#define CD_DUMPDIR "DumpDir"
diff -x '*.po' -d -urpN abrt.4/lib/plugins/Python.cpp abrt.5/lib/plugins/Python.cpp
--- abrt.4/lib/plugins/Python.cpp 2010-10-15 14:05:53.569928832 +0200
+++ abrt.5/lib/plugins/Python.cpp 2010-10-15 13:14:37.725928898 +0200
@@ -22,66 +22,61 @@
using namespace std;
-string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir)
+static string load(const char *dirname, const char *filename)
{
- struct dump_dir *dd = dd_opendir(pDebugDumpDir, /*flags:*/ 0);
- if (!dd)
- return string("");
+ string ret;
- char *bt = dd_load_text(dd, FILENAME_BACKTRACE);
+ struct dump_dir *dd = dd_opendir(dirname, /*flags:*/ 0);
+ if (!dd)
+ return ret; /* "" */
+ char *s = dd_load_text(dd, filename);
dd_close(dd);
- const char *bt_end = strchrnul(bt, '\n');
-
- char hash_str[MD5_RESULT_LEN*2 + 1];
- unsigned char hash2[MD5_RESULT_LEN];
- md5_ctx_t md5ctx;
- md5_begin(&md5ctx);
- // Better:
- // "example.py:1:<module>:ZeroDivisionError: integer division or modulo by zero"
- //md5_hash(bt_str, bt_end - bt_str, &md5ctx);
- // For now using compat version:
+ if (!s[0])
{
- char *copy = xstrndup(bt, bt_end - bt);
- free(bt);
- char *s = copy;
- char *d = copy;
- unsigned colon_cnt = 0;
- while (*s && colon_cnt < 3)
+ free(s);
+
+ pid_t pid = fork();
+ if (pid < 0)
{
- if (*s != ':')
- *d++ = *s;
- else
- colon_cnt++;
- s++;
+ perror_msg("fork");
+ return ret; /* "" */
}
- // "example.py1<module>"
- md5_hash(copy, d - copy, &md5ctx);
-//*d = '\0'; log("str:'%s'", copy);
- free(copy);
- }
- md5_end(hash2, &md5ctx);
+ if (pid == 0) /* child */
+ {
+ char *argv[4]; /* abrt-action-analyze-python -d DIR <NULL> */
+ char **pp = argv;
+ *pp++ = (char*)"abrt-action-analyze-python";
+ *pp++ = (char*)"-d";
+ *pp++ = (char*)dirname;
+ *pp = NULL;
- // Hash is MD5_RESULT_LEN bytes long, but we use only first 4
- // (I don't know why old Python code was using only 4, I mimic that)
- unsigned len = 4;
- char *d = hash_str;
- unsigned char *s = hash2;
- while (len)
- {
- *d++ = "0123456789abcdef"[*s >> 4];
- *d++ = "0123456789abcdef"[*s & 0xf];
- s++;
- len--;
+ execvp(argv[0], argv);
+ perror_msg_and_die("Can't execute '%s'", argv[0]);
+ }
+ /* parent */
+ waitpid(pid, NULL, 0);
+
+ dd = dd_opendir(dirname, /*flags:*/ 0);
+ if (!dd)
+ return ret; /* "" */
+ s = dd_load_text(dd, filename);
+ dd_close(dd);
}
- *d = '\0';
-//log("hash2:%s str:'%.*s'", hash_str, (int)(bt_end - bt_str), bt_str);
- return hash_str;
+ ret = s;
+ free(s);
+ return ret;
}
+
+string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir)
+{
+ return load(pDebugDumpDir, CD_UUID);
+}
+
string CAnalyzerPython::GetGlobalUUID(const char *pDebugDumpDir)
{
- return GetLocalUUID(pDebugDumpDir);
+ return load(pDebugDumpDir, FILENAME_DUPHASH);
}
void CAnalyzerPython::Init()
diff -x '*.po' -d -urpN abrt.4/src/daemon/abrt-action-analyze-python.c abrt.5/src/daemon/abrt-action-analyze-python.c
--- abrt.4/src/daemon/abrt-action-analyze-python.c 1970-01-01 01:00:00.000000000 +0100
+++ abrt.5/src/daemon/abrt-action-analyze-python.c 2010-10-15 15:12:05.783179177 +0200
@@ -0,0 +1,119 @@
+/*
+ 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.
+*/
+#include "abrtlib.h"
+#include "parse_options.h"
+
+#define PROGNAME "abrt-action-analyze-python"
+
+// Hash is MD5_RESULT_LEN bytes long, but we use only first 4
+// (I don't know why old Python code was using only 4, I mimic that)
+#define HASH_STRING_HEX_DIGITS 4
+
+int main(int argc, char **argv)
+{
+ char *env_verbose = getenv("ABRT_VERBOSE");
+ if (env_verbose)
+ g_verbose = atoi(env_verbose);
+
+ /* Can't keep these strings/structs static: _() doesn't support that */
+ const char *program_usage_string = _(
+ PROGNAME" [-vs] -d DIR\n\n"
+ "Calculates and saves UUID and DUPHASH of python crash dumps"
+ );
+ const char *dump_dir_name = ".";
+ enum {
+ OPT_v = 1 << 0,
+ OPT_d = 1 << 1,
+ OPT_s = 1 << 2,
+ };
+ /* Keep enum above and order of options below in sync! */
+ struct options program_options[] = {
+ OPT__VERBOSE(&g_verbose),
+ OPT_STRING('d', NULL, &dump_dir_name, "DIR", _("Crash dump directory")),
+ OPT_BOOL( 's', NULL, NULL, _("Log to syslog" )),
+ OPT_END()
+ };
+ /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string);
+
+ putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
+
+//Maybe we will want this... later
+// msg_prefix = xasprintf(PROGNAME"[%u]", getpid());
+// if (opts & OPT_s)
+// {
+// openlog(msg_prefix, 0, LOG_DAEMON);
+// logmode = LOGMODE_SYSLOG;
+// }
+
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ if (!dd)
+ return 1;
+ char *bt = dd_load_text(dd, FILENAME_BACKTRACE);
+
+ /* Hash 1st line of backtrace and save it as UUID and DUPHASH */
+
+ const char *bt_end = strchrnul(bt, '\n');
+ unsigned char hash_bytes[MD5_RESULT_LEN];
+ md5_ctx_t md5ctx;
+ md5_begin(&md5ctx);
+ // Better:
+ // "example.py:1:<module>:ZeroDivisionError: integer division or modulo by zero"
+ //md5_hash(bt_str, bt_end - bt_str, &md5ctx);
+ //free(bt);
+ // For now using compat version:
+ {
+ char *copy = xstrndup(bt, bt_end - bt);
+ free(bt);
+ char *s = copy;
+ char *d = copy;
+ unsigned colon_cnt = 0;
+ while (*s && colon_cnt < 3)
+ {
+ if (*s != ':')
+ *d++ = *s;
+ else
+ colon_cnt++;
+ s++;
+ }
+ // copy = "example.py1<module>"
+ md5_hash(copy, d - copy, &md5ctx);
+ free(copy);
+ }
+ // end of compat version
+ md5_end(hash_bytes, &md5ctx);
+
+ char hash_str[HASH_STRING_HEX_DIGITS*2 + 1];
+ unsigned len = HASH_STRING_HEX_DIGITS;
+ char *d = hash_str;
+ unsigned char *s = hash_bytes;
+ while (len)
+ {
+ *d++ = "0123456789abcdef"[*s >> 4];
+ *d++ = "0123456789abcdef"[*s & 0xf];
+ s++;
+ len--;
+ }
+ *d = '\0';
+
+ dd_save_text(dd, CD_UUID, hash_str);
+ dd_save_text(dd, FILENAME_DUPHASH, hash_str);
+ dd_close(dd);
+
+ return 0;
+}
diff -x '*.po' -d -urpN abrt.4/src/daemon/Makefile.am abrt.5/src/daemon/Makefile.am
--- abrt.4/src/daemon/Makefile.am 2010-10-14 01:14:52.951399611 +0200
+++ abrt.5/src/daemon/Makefile.am 2010-10-15 14:20:44.410178881 +0200
@@ -5,6 +5,7 @@ bin_SCRIPTS = \
sbin_PROGRAMS = abrtd \
abrt-server \
abrt-action-analyze-c \
+ abrt-action-analyze-python \
abrt-action-generate-backtrace \
abrt-action-save-package-data
@@ -77,6 +78,24 @@ abrt_action_analyze_c_CPPFLAGS = \
abrt_action_analyze_c_LDADD = \
../../lib/utils/libABRTUtils.la
+abrt_action_analyze_python_SOURCES = \
+ abrt-action-analyze-python.c
+abrt_action_analyze_python_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)\" \
+ -D_GNU_SOURCE \
+ -Wall -Werror
+abrt_action_analyze_python_LDADD = \
+ ../../lib/utils/libABRTUtils.la
+
abrt_action_generate_backtrace_SOURCES = \
abrt-action-generate-backtrace.c
abrt_action_generate_backtrace_CPPFLAGS = \
13 years, 7 months
D�sinscription
by service-commercial@chemise-web.net
Nous confirmons votre désinscription. Pour recevoir nos communications à l'avenir merci de nous écrire directement à l'adresse service-commercial(a)chemise-web.net pour être réinscrit.
13 years, 7 months