summaryrefslogtreecommitdiffstats
path: root/src/daemon
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2010-11-10 17:01:31 +0100
committerJiri Moskovcak <jmoskovc@redhat.com>2010-11-10 18:27:05 +0100
commit3fce116492052267e5e1a634e5404b1b518f7ef3 (patch)
tree3160a2d429987573004fb8166d40542b76a7315b /src/daemon
parent9d2cb4518c3a8a72ccc714ddbc131aaa84506092 (diff)
downloadabrt-3fce116492052267e5e1a634e5404b1b518f7ef3.tar.gz
abrt-3fce116492052267e5e1a634e5404b1b518f7ef3.tar.xz
abrt-3fce116492052267e5e1a634e5404b1b518f7ef3.zip
move files from lib/plugins to src/plugins
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/Daemon.cpp5
-rw-r--r--src/daemon/Makefile.am193
-rw-r--r--src/daemon/abrt-action-analyze-c.c238
-rw-r--r--src/daemon/abrt-action-analyze-oops.c176
-rw-r--r--src/daemon/abrt-action-analyze-python.c119
-rw-r--r--src/daemon/abrt-action-bugzilla.cpp908
-rw-r--r--src/daemon/abrt-action-generate-backtrace.c386
-rwxr-xr-xsrc/daemon/abrt-action-install-debuginfo418
-rw-r--r--src/daemon/abrt-action-kerneloops.cpp197
-rw-r--r--src/daemon/abrt-action-print.cpp106
-rw-r--r--src/daemon/abrt-action-rhtsupport.cpp338
-rw-r--r--src/daemon/abrt_rh_support.c519
-rw-r--r--src/daemon/abrt_rh_support.h55
13 files changed, 16 insertions, 3642 deletions
diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp
index a30b2d97..72bb54bf 100644
--- a/src/daemon/Daemon.cpp
+++ b/src/daemon/Daemon.cpp
@@ -843,6 +843,11 @@ int main(int argc, char** argv)
if (!getenv("PATH"))
putenv((char*)"PATH=/usr/sbin:/usr/bin:/sbin:/bin");
+ /* need to add LIBEXEC_DIR to PATH, because otherwise abrt-action-*
+ * is not found by exec()
+ */
+ putenv(xasprintf("PATH=%s:%s", LIBEXEC_DIR, getenv("PATH")));
+
putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
msg_prefix = "abrtd"; /* for log(), error_msg() and such */
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index a939798c..072f7f17 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -1,21 +1,13 @@
bin_SCRIPTS = \
- abrt-action-install-debuginfo \
abrt-handle-upload
-
-sbin_PROGRAMS = abrtd \
- abrt-server \
- abrt-action-analyze-c \
- abrt-action-analyze-python \
- abrt-action-analyze-oops \
- abrt-action-generate-backtrace \
+libexec_PROGRAMS = \
abrt-action-save-package-data
bin_PROGRAMS = \
- abrt-handle-crashdump \
- abrt-action-bugzilla \
- abrt-action-rhtsupport \
- abrt-action-kerneloops \
- abrt-action-print
+ abrt-handle-crashdump
+
+sbin_PROGRAMS = abrtd \
+ abrt-server
abrtd_SOURCES = \
PluginManager.h PluginManager.cpp \
@@ -35,6 +27,7 @@ abrtd_CPPFLAGS = \
-DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \
-DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
-DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
+ -DLIBEXEC_DIR=\"$(LIBEXEC_DIR)\" \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
$(ENABLE_SOCKET_OR_DBUS) \
@@ -63,45 +56,9 @@ abrt_server_CPPFLAGS = \
abrt_server_LDADD = \
../../lib/utils/libABRTUtils.la
-abrt_action_analyze_c_SOURCES = \
- abrt-action-analyze-c.c
-abrt_action_analyze_c_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_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_analyze_oops_SOURCES = \
- abrt-action-analyze-oops.c
-abrt_action_analyze_oops_CPPFLAGS = \
+abrt_handle_crashdump_SOURCES = \
+ abrt-handle-crashdump.c
+abrt_handle_crashdump_CPPFLAGS = \
-I$(srcdir)/../../inc \
-I$(srcdir)/../../lib/utils \
-DBIN_DIR=\"$(bindir)\" \
@@ -114,28 +71,9 @@ abrt_action_analyze_oops_CPPFLAGS = \
-DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
-D_GNU_SOURCE \
-Wall -Werror
-abrt_action_analyze_oops_LDADD = \
+abrt_handle_crashdump_LDADD = \
../../lib/utils/libABRTUtils.la
-abrt_action_generate_backtrace_SOURCES = \
- abrt-action-generate-backtrace.c
-abrt_action_generate_backtrace_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_generate_backtrace_LDADD = \
- ../../lib/utils/libABRTUtils.la \
- ../btparser/libbtparser.la
-
abrt_action_save_package_data_SOURCES = \
rpm.h rpm.c \
Settings.h Settings.cpp \
@@ -160,115 +98,6 @@ abrt_action_save_package_data_LDADD = \
../../lib/utils/libABRTdUtils.la \
../../lib/utils/libABRTUtils.la
-abrt_handle_crashdump_SOURCES = \
- abrt-handle-crashdump.c
-abrt_handle_crashdump_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_handle_crashdump_LDADD = \
- ../../lib/utils/libABRTUtils.la
-
-abrt_action_bugzilla_SOURCES = \
- abrt-action-bugzilla.cpp
-abrt_action_bugzilla_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_bugzilla_LDADD = \
- $(GLIB_LIBS) \
- ../../lib/utils/libABRT_web_utils.la \
- ../../lib/utils/libABRTdUtils.la \
- ../../lib/utils/libABRTUtils.la
-
-abrt_action_rhtsupport_SOURCES = \
- abrt_rh_support.h abrt_rh_support.c \
- 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) \
- $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \
- -D_GNU_SOURCE \
- -Wall -Werror
-abrt_action_rhtsupport_LDFLAGS = -ltar
-abrt_action_rhtsupport_LDADD = \
- $(GLIB_LIBS) \
- $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \
- ../../lib/utils/libABRT_web_utils.la \
- ../../lib/utils/libABRTdUtils.la \
- ../../lib/utils/libABRTUtils.la
-
-abrt_action_kerneloops_SOURCES = \
- abrt-action-kerneloops.cpp
-abrt_action_kerneloops_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
-# libABRTdUtils is used only because of LoadPluginSettings:
-abrt_action_kerneloops_LDADD = \
- ../../lib/utils/libABRT_web_utils.la \
- ../../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
-# libABRTdUtils is used only because of make_description_logger:
-abrt_action_print_LDADD = \
- ../../lib/utils/libABRTdUtils.la \
- ../../lib/utils/libABRTUtils.la
-
dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/
dist_dbusabrtconf_DATA = dbus-abrt.conf
@@ -286,7 +115,7 @@ dist_comredhatabrtservice_DATA = com.redhat.abrt.service
man_MANS = abrtd.8 abrt.conf.5
-EXTRA_DIST = $(man_MANS) abrt-action-install-debuginfo abrt-handle-upload
+EXTRA_DIST = $(man_MANS) abrt-handle-upload
if HAVE_SYSTEMD
dist_systemdsystemunit_DATA = \
diff --git a/src/daemon/abrt-action-analyze-c.c b/src/daemon/abrt-action-analyze-c.c
deleted file mode 100644
index 60e08372..00000000
--- a/src/daemon/abrt-action-analyze-c.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- Copyright (C) 2009 Zdenek Prikryl (zprikryl@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"
-
-#define PROGNAME "abrt-action-analyze-c"
-
-static void create_hash(char hash_str[SHA1_RESULT_LEN*2 + 1], const char *pInput)
-{
- unsigned len;
- unsigned char hash2[SHA1_RESULT_LEN];
- sha1_ctx_t sha1ctx;
-
- sha1_begin(&sha1ctx);
- sha1_hash(pInput, strlen(pInput), &sha1ctx);
- sha1_end(hash2, &sha1ctx);
- len = SHA1_RESULT_LEN;
-
- char *d = hash_str;
- unsigned char *s = hash2;
- while (len)
- {
- *d++ = "0123456789abcdef"[*s >> 4];
- *d++ = "0123456789abcdef"[*s & 0xf];
- s++;
- len--;
- }
- *d = '\0';
- //log("hash2:%s str:'%s'", hash_str, pInput);
-}
-
-static char *run_unstrip_n(const char *dump_dir_name, unsigned timeout_sec)
-{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return NULL;
- char *uid_str = dd_load_text(dd, CD_UID);
- dd_close(dd);
- unsigned uid = xatoi_u(uid_str);
- free(uid_str);
-
- int flags = EXECFLG_INPUT_NUL | EXECFLG_OUTPUT | EXECFLG_SETGUID | EXECFLG_SETSID | EXECFLG_QUIET;
- VERB1 flags &= ~EXECFLG_QUIET;
- int pipeout[2];
- char* args[4];
- args[0] = (char*)"eu-unstrip";
- args[1] = xasprintf("--core=%s/"FILENAME_COREDUMP, dump_dir_name);
- args[2] = (char*)"-n";
- args[3] = NULL;
- pid_t child = fork_execv_on_steroids(flags, args, pipeout, /*unsetenv_vec:*/ NULL, /*dir:*/ NULL, uid);
- free(args[1]);
-
- /* Bugs in unstrip or corrupted coredumps can cause it to enter infinite loop.
- * Therefore we have a (largish) timeout, after which we kill the child.
- */
- int t = time(NULL); /* int is enough, no need to use time_t */
- int endtime = t + timeout_sec;
- struct strbuf *buf_out = strbuf_new();
- while (1)
- {
- int timeout = endtime - t;
- if (timeout < 0)
- {
- kill(child, SIGKILL);
- strbuf_append_strf(buf_out, "\nTimeout exceeded: %u seconds, killing %s\n", timeout_sec, args[0]);
- break;
- }
-
- /* We don't check poll result - checking read result is enough */
- struct pollfd pfd;
- pfd.fd = pipeout[0];
- pfd.events = POLLIN;
- poll(&pfd, 1, timeout * 1000);
-
- char buff[1024];
- int r = read(pipeout[0], buff, sizeof(buff) - 1);
- if (r <= 0)
- break;
- buff[r] = '\0';
- strbuf_append_str(buf_out, buff);
- t = time(NULL);
- }
- close(pipeout[0]);
-
- /* Prevent having zombie child process */
- int status;
- waitpid(child, &status, 0);
-
- if (status != 0)
- {
- /* unstrip didnt exit with exitcode 0 */
- strbuf_free(buf_out);
- return NULL;
- }
-
- return strbuf_free_nobuf(buf_out);
-}
-
-static void trim_unstrip_output(char *result, const char *unstrip_n_output)
-{
- // lines look like this:
- // 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe]
- // 0x400000+0x209000 ab3c8286aac6c043fd1bb1cc2a0b88ec29517d3e@0x40024c /bin/sleep /usr/lib/debug/bin/sleep.debug [exe]
- // 0x7fff313ff000+0x1000 389c7475e3d5401c55953a425a2042ef62c4c7df@0x7fff313ff2f8 . - linux-vdso.so.1
- // ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // we drop everything except the marked part ^
-
- char *dst = result;
- const char *line = unstrip_n_output;
- while (*line)
- {
- const char *eol = strchrnul(line, '\n');
- const char *plus = (char*)memchr(line, '+', eol - line);
- if (plus)
- {
- while (++plus < eol && *plus != '@')
- {
- if (!isspace(*plus))
- {
- *dst++ = *plus;
- }
- }
- }
- if (*eol != '\n') break;
- line = eol + 1;
- }
- *dst = '\0';
-}
-
-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 of coredumps"
- );
- 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));
-
- msg_prefix = PROGNAME;
-//Maybe we will want this... later
-// if (opts & OPT_s)
-// {
-// openlog(msg_prefix, 0, LOG_DAEMON);
-// logmode = LOGMODE_SYSLOG;
-// }
-
- /* Run unstrip -n and trim its output, leaving only sizes and build ids */
-
- char *unstrip_n_output = run_unstrip_n(dump_dir_name, /*timeout_sec:*/ 30);
- if (!unstrip_n_output)
- return 1; /* bad dump_dir_name, can't run unstrip, etc... */
- /* modifies unstrip_n_output in-place: */
- trim_unstrip_output(unstrip_n_output, unstrip_n_output);
-
- /* Hash package + executable + unstrip_n_output and save it as UUID */
-
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return 1;
-
- char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
- char *package = dd_load_text(dd, FILENAME_PACKAGE);
- /* Package variable has "firefox-3.5.6-1.fc11[.1]" format */
- /* Remove distro suffix and maybe least significant version number */
- char *p = package;
- while (*p)
- {
- if (*p == '.' && (p[1] < '0' || p[1] > '9'))
- {
- /* We found "XXXX.nondigitXXXX", trim this part */
- *p = '\0';
- break;
- }
- p++;
- }
- char *first_dot = strchr(package, '.');
- if (first_dot)
- {
- char *last_dot = strrchr(first_dot, '.');
- if (last_dot != first_dot)
- {
- /* There are more than one dot: "1.2.3"
- * Strip last part, we don't want to distinquish crashes
- * in packages which differ only by minor release number.
- */
- *last_dot = '\0';
- }
- }
-
- char *string_to_hash = xasprintf("%s%s%s", package, executable, unstrip_n_output);
- /*free(package);*/
- /*free(executable);*/
- /*free(unstrip_n_output);*/
-
- char hash_str[SHA1_RESULT_LEN*2 + 1];
- create_hash(hash_str, string_to_hash);
- /*free(hash_str);*/
-
- dd_save_text(dd, CD_UUID, hash_str);
- dd_close(dd);
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-analyze-oops.c b/src/daemon/abrt-action-analyze-oops.c
deleted file mode 100644
index 354ec6fd..00000000
--- a/src/daemon/abrt-action-analyze-oops.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- 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-oops"
-
-static unsigned hash_oops_str(const char *oops_ptr)
-{
- unsigned char old_c;
- unsigned char c = 0;
- unsigned hash = 0;
-
- /* Special-case: if the first line is of form:
- * WARNING: at net/wireless/core.c:614 wdev_cleanup_work+0xe9/0x120 [cfg80211]() (Not tainted)
- * then hash only "file:line func+ofs/len" part.
- */
- if (strncmp(oops_ptr, "WARNING: at ", sizeof("WARNING: at ")-1) == 0)
- {
- const char *p = oops_ptr + sizeof("WARNING: at ")-1;
- p = strchr(p, ' '); /* skip filename:NNN */
- if (p)
- {
- p = strchrnul(p + 1, ' '); /* skip function_name+0xNN/0xNNN */
- oops_ptr += sizeof("WARNING: at ")-1;
- while (oops_ptr < p)
- {
- c = *oops_ptr++;
- hash = ((hash << 5) ^ (hash >> 27)) ^ c;
- }
- return hash;
- }
- }
-
- while (1)
- {
- old_c = c;
- c = *oops_ptr++;
- if (!c)
- break;
- if (c == '\n')
- {
- // Exclude some lines which have process name - in some oops classes
- // process name is irrelevant and changes with every oops.
- // Lines we filter out:
- // Pid: 8003, comm: Xorg Not tainted (2.6.27.9-159.fc10.i686 #1)
- // Process Xorg (pid: 8003, ti=f0a0c000 task=f2380000 task.ti=f0a0c000)
- if (strncmp(oops_ptr, "Pid: ", 5) == 0
- || strncmp(oops_ptr, "Process ", 8) == 0
- ) {
- while (*oops_ptr && *oops_ptr != '\n')
- oops_ptr++;
- continue;
- }
- }
- if (!isalnum(old_c))
- {
- if (c >= '0' && c <= '9')
- {
- // Convert all (possibly hex) numbers to just one '0'
- if (c == '0' && *oops_ptr == 'x') // "0xSOMETHING"
- oops_ptr++;
- while (isxdigit(*oops_ptr))
- oops_ptr++;
- c = '0';
- }
- else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
- {
- // This *may be* a hex number without 0x prefix: "f0a0c000"
- // Check that it indeed is, and replace with '0'
- const char *oops_ptr2 = oops_ptr;
- while (isxdigit(*oops_ptr2))
- oops_ptr2++;
- // Does it end in a letter which is not a hex digit?
- // (Example: "abcw" is not a hex number, "abc " is)
- if (!isalpha(*oops_ptr2))
- {
- // It's "abc " case. Skip the "abc" string
- oops_ptr = oops_ptr2;
- c = '0';
- }
- // else: hash the string as-is
- }
- }
- // TODO: Drop call trace tail - in interrupt-driven oopses,
- // everything before interrupt is irrelevant.
- // Example of call trace part of oops:
- // Call Trace:
- // [<f88e11c7>] ? radeon_cp_resume+0x7d/0xbc [radeon]
- // [<f88745f8>] ? drm_ioctl+0x1b0/0x225 [drm]
- // [<f88e114a>] ? radeon_cp_resume+0x0/0xbc [radeon]
- // [<c049b1c0>] ? vfs_ioctl+0x50/0x69
- // [<c049b414>] ? do_vfs_ioctl+0x23b/0x247
- // [<c0460a56>] ? audit_syscall_entry+0xf9/0x123
- // [<c049b460>] ? sys_ioctl+0x40/0x5c
- // [<c0403c76>] ? syscall_call+0x7/0xb
-
- /* An algorithm proposed by Donald E. Knuth in The Art Of Computer
- * Programming Volume 3, under the topic of sorting and search
- * chapter 6.4.
- */
- hash = ((hash << 5) ^ (hash >> 27)) ^ c;
- }
- return hash;
-}
-
-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 oops 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));
-
- msg_prefix = PROGNAME;
-//Maybe we will want this... later
-// 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 *oops = dd_load_text(dd, FILENAME_BACKTRACE);
- unsigned hash = hash_oops_str(oops);
- /* free(oops); */
-
- hash &= 0x7FFFFFFF;
- char hash_str[sizeof(int)*3 + 2];
- sprintf(hash_str, "%u", hash);
- dd_save_text(dd, CD_UUID, hash_str);
- dd_save_text(dd, FILENAME_DUPHASH, hash_str);
-
- dd_close(dd);
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-analyze-python.c b/src/daemon/abrt-action-analyze-python.c
deleted file mode 100644
index bb5722ec..00000000
--- a/src/daemon/abrt-action-analyze-python.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- 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));
-
- msg_prefix = PROGNAME;
-//Maybe we will want this... later
-// 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 --git a/src/daemon/abrt-action-bugzilla.cpp b/src/daemon/abrt-action-bugzilla.cpp
deleted file mode 100644
index a3c2f0b0..00000000
--- a/src/daemon/abrt-action-bugzilla.cpp
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
- 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 "abrt_xmlrpc.h"
-#include "crash_types.h"
-#include "abrt_exception.h"
-
-#include "plugin.h" /* make_description_bz */
-
-#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
- * npajkovs: figure out how to deal with cloning bugs
- * npajkovs: check if attachment was uploaded successul an if not try it again(max 3 times)
- * and if it still fails. retrun successful, but mention that attaching failed
- * npajkovs: add option to set comment privat
- */
-
-struct bug_info {
- const char* bug_status;
- const char* bug_resolution;
- const char* bug_reporter;
- const char* bug_product;
- xmlrpc_int32 bug_dup_id;
- std::vector<char*> bug_cc;
-};
-
-static void bug_info_init(struct bug_info* bz)
-{
- bz->bug_status = NULL;
- bz->bug_resolution = NULL;
- bz->bug_reporter = NULL;
- bz->bug_product = NULL;
- bz->bug_dup_id = -1;
-}
-
-static void bug_info_destroy(struct bug_info* bz)
-{
- free((void*)bz->bug_status);
- free((void*)bz->bug_resolution);
- free((void*)bz->bug_reporter);
- free((void*)bz->bug_product);
-
- if (!bz->bug_cc.empty())
- {
- for (unsigned ii = 0; ii < bz->bug_cc.size(); ii++)
- free(bz->bug_cc[ii]);
-
- bz->bug_cc.clear();
- }
-}
-
-static int am_i_in_cc(const struct bug_info* bz, const char* login)
-{
- if (bz->bug_cc.empty())
- return -1;
-
- int size = bz->bug_cc.size();
- for (int ii = 0; ii < size; ii++)
- {
- if (strcmp(login, bz->bug_cc[ii]) == 0)
- return 0;
- }
- return -1;
-}
-
-/*
- * Static namespace for xmlrpc stuff.
- * Used mainly to ensure we always destroy xmlrpc client and server_info.
- */
-
-namespace {
-
-struct ctx: public abrt_xmlrpc_conn {
- xmlrpc_env env;
-
- ctx(const char* url, bool ssl_verify): abrt_xmlrpc_conn(url, ssl_verify)
- { xmlrpc_env_init(&env); }
- ~ctx() { xmlrpc_env_clean(&env); }
-
- void login(const char* login, const char* passwd);
- void logout();
-
- const char* get_bug_status(xmlrpc_value* result_xml);
- const char* get_bug_resolution(xmlrpc_value* result_xml);
- const char* get_bug_reporter(xmlrpc_value* result_xml);
- const char* get_bug_product(xmlrpc_value* relult_xml);
-
- xmlrpc_value* call_quicksearch_duphash(const char* component, const char* release, const char* duphash);
- xmlrpc_value* get_cc_member(xmlrpc_value* result_xml);
- xmlrpc_value* get_member(const char* member, xmlrpc_value* result_xml);
-
- int get_array_size(xmlrpc_value* result_xml);
- xmlrpc_int32 get_bug_id(xmlrpc_value* result_xml);
- xmlrpc_int32 get_bug_dup_id(xmlrpc_value* result_xml);
- void get_bug_cc(xmlrpc_value* result_xml, struct bug_info* bz);
- int add_plus_one_cc(xmlrpc_int32 bug_id, const char* login);
- xmlrpc_int32 new_bug(const map_crash_data_t& pCrashData, int depend_on_bugno);
- int add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData);
- int get_bug_info(struct bug_info* bz, xmlrpc_int32 bug_id);
- int add_comment(xmlrpc_int32 bug_id, const char* comment, bool is_private);
-
- xmlrpc_value* call(const char* method, const char* format, ...);
-};
-
-xmlrpc_value* ctx::call(const char* method, const char* format, ...)
-{
- va_list args;
- xmlrpc_value* param = NULL;
- xmlrpc_value* result = NULL;
- const char* suffix;
-
- va_start(args, format);
- xmlrpc_build_value_va(&env, format, args, &param, &suffix);
- va_end(args);
-
- if (!env.fault_occurred)
- {
- if (*suffix != '\0')
- {
- xmlrpc_env_set_fault_formatted(
- &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument "
- "specifier: '%s'. There must be exactly one arument.",
- suffix);
-
- xmlrpc_DECREF(param);
- return NULL;
- }
-
- xmlrpc_client_call2(&env, m_pClient, m_pServer_info, method, param, &result);
- xmlrpc_DECREF(param);
- if (env.fault_occurred)
- return NULL;
- }
-
-
- return result;
-}
-
-xmlrpc_value* ctx::get_member(const char* member, xmlrpc_value* result_xml)
-{
- xmlrpc_value* cc_member = NULL;
- xmlrpc_struct_find_value(&env, result_xml, member, &cc_member);
- if (env.fault_occurred)
- return NULL;
-
- return cc_member;
-}
-
-int ctx::get_array_size(xmlrpc_value* result_xml)
-{
- int size = xmlrpc_array_size(&env, result_xml);
- if (env.fault_occurred)
- return -1;
-
- return size;
-}
-
-xmlrpc_int32 ctx::get_bug_dup_id(xmlrpc_value* result_xml)
-{
- xmlrpc_value* dup_id = get_member("dup_id", result_xml);
- if (!dup_id)
- return -1;
-
- xmlrpc_int32 dup_id_int = -1;
- xmlrpc_read_int(&env, dup_id, &dup_id_int);
- xmlrpc_DECREF(dup_id);
- if (env.fault_occurred)
- return -1;
-
- VERB3 log("got dup_id: %i", dup_id_int);
- return dup_id_int;
-}
-
-const char* ctx::get_bug_product(xmlrpc_value* result_xml)
-{
- xmlrpc_value* product_member = get_member("product", result_xml);
- if (!product_member) //should never happend. Each bug has to set up product
- return NULL;
-
- const char* product = NULL;
- xmlrpc_read_string(&env, product_member, &product);
- xmlrpc_DECREF(product_member);
- if (env.fault_occurred)
- return NULL;
-
- if (*product != '\0')
- {
- VERB3 log("got bug product: %s", product);
- return product;
- }
-
- free((void*)product);
- return NULL;
-}
-
-const char* ctx::get_bug_reporter(xmlrpc_value* result_xml)
-{
- xmlrpc_value* reporter_member = get_member("reporter", result_xml);
- if (!reporter_member)
- return NULL;
-
- const char* reporter = NULL;
- xmlrpc_read_string(&env, reporter_member, &reporter);
- xmlrpc_DECREF(reporter_member);
- if (env.fault_occurred)
- return NULL;
-
- if (*reporter != '\0')
- {
- VERB3 log("got bug reporter: %s", reporter);
- return reporter;
- }
- free((void*)reporter);
- return NULL;
-}
-
-const char* ctx::get_bug_resolution(xmlrpc_value* result_xml)
-{
- xmlrpc_value* bug_resolution = get_member("resolution", result_xml);
- if (!bug_resolution)
- return NULL;
-
- const char* resolution_str = NULL;
- xmlrpc_read_string(&env, bug_resolution, &resolution_str);
- xmlrpc_DECREF(bug_resolution);
- if (env.fault_occurred)
- return NULL;
-
- if (*resolution_str != '\0')
- {
- VERB3 log("got resolution: %s", resolution_str);
- return resolution_str;
- }
- free((void*)resolution_str);
- return NULL;
-}
-
-const char* ctx::get_bug_status(xmlrpc_value* result_xml)
-{
- xmlrpc_value* bug_status = get_member("bug_status", result_xml);
- if (!bug_status)
- return NULL;
-
- const char* status_str = NULL;
- xmlrpc_read_string(&env, bug_status, &status_str);
- xmlrpc_DECREF(bug_status);
- if (env.fault_occurred)
- return NULL;
-
- if (*status_str != '\0')
- {
- VERB3 log("got bug_status: %s", status_str);
- return status_str;
- }
- free((void*)status_str);
- return NULL;
-}
-
-void ctx::get_bug_cc(xmlrpc_value* result_xml, struct bug_info* bz)
-{
- xmlrpc_value* cc_member = get_member("cc", result_xml);
- if (!cc_member)
- return;
-
- int array_size = xmlrpc_array_size(&env, cc_member);
- if (array_size == -1)
- return;
-
- VERB3 log("count members on cc %i", array_size);
-
- for (int i = 0; i < array_size; i++)
- {
- xmlrpc_value* item = NULL;
- xmlrpc_array_read_item(&env, cc_member, i, &item);
- if (env.fault_occurred)
- return;
-
- if (item)
- {
- const char* cc = NULL;
- xmlrpc_read_string(&env, item, &cc);
- xmlrpc_DECREF(item);
- if (env.fault_occurred)
- {
- xmlrpc_DECREF(cc_member);
- return;
- }
-
- if (*cc != '\0')
- {
- bz->bug_cc.push_back((char*)cc);
- VERB3 log("member on cc is %s", cc);
- continue;
- }
- free((char*)cc);
- }
- }
- xmlrpc_DECREF(cc_member);
- return;
-}
-
-xmlrpc_value* ctx::call_quicksearch_duphash(const char* component, const char* release, const char* duphash)
-{
- char *query = NULL;
- if (!release)
- query = xasprintf("ALL component:\"%s\" whiteboard:\"%s\"", component, duphash);
- else
- {
- char *product = NULL;
- char *version = NULL;
- parse_release(release, &product, &version);
- query = xasprintf("ALL component:\"%s\" whiteboard:\"%s\" product:\"%s\"",
- component, duphash, product
- );
- free(product);
- free(version);
- }
-
- VERB3 log("quicksearch for `%s'", query);
- xmlrpc_value *ret = call("Bug.search", "({s:s})", "quicksearch", query);
- free(query);
- return ret;
-}
-
-xmlrpc_int32 ctx::get_bug_id(xmlrpc_value* result_xml)
-{
- xmlrpc_value* item = NULL;
- xmlrpc_array_read_item(&env, result_xml, 0, &item);
- if (env.fault_occurred)
- return -1;
-
- xmlrpc_value* bug = get_member("bug_id", item);
- xmlrpc_DECREF(item);
- if (!bug)
- return -1;
-
- xmlrpc_int32 bug_id = -1;
- xmlrpc_read_int(&env, bug, &bug_id);
- xmlrpc_DECREF(bug);
- if (env.fault_occurred)
- return -1;
-
- VERB3 log("got bug_id %d", (int)bug_id);
- return bug_id;
-}
-
-int ctx::add_plus_one_cc(xmlrpc_int32 bug_id, const char* login)
-{
- xmlrpc_value* result = call("Bug.update", "({s:i,s:{s:(s)}})", "ids", (int)bug_id, "updates", "add_cc", login);
- if (result)
- xmlrpc_DECREF(result);
- return result ? 0 : -1;
-}
-
-int ctx::add_comment(xmlrpc_int32 bug_id, const char* comment, bool is_private)
-{
- xmlrpc_value* result = call("Bug.add_comment", "({s:i,s:s,s:b})", "id", (int)bug_id,
- "comment", comment,
- "private", is_private);
- if (result)
- xmlrpc_DECREF(result);
- return result ? 0 : -1;
-}
-
-xmlrpc_int32 ctx::new_bug(const map_crash_data_t& pCrashData, int depend_on_bugno)
-{
- 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, 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 != NULL && strlen(function) < 30)
- strbuf_append_strf(buf_summary, ": %s", function);
-
- if (reason != NULL)
- strbuf_append_strf(buf_summary, ": %s", reason);
-
- char *status_whiteboard = xasprintf("abrt_hash:%s", duphash);
-
- 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, &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,
- "version", version,
- "summary", summary,
- "description", full_dsc,
- "status_whiteboard", status_whiteboard,
- "platform", arch,
- "dependson", depend_on_bugno
- );
- }
- else
- {
- result = call("Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
- "product", product,
- "component", component,
- "version", version,
- "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;
-
- xmlrpc_value* id = get_member("id", result);
- xmlrpc_DECREF(result);
- if (!id)
- return -1;
-
- xmlrpc_int32 bug_id = -1;
- xmlrpc_read_int(&env, id, &bug_id);
- xmlrpc_DECREF(id);
- if (env.fault_occurred)
- return -1;
-
- log(_("New bug id: %i"), (int)bug_id);
-
- return bug_id;
-}
-
-int ctx::add_attachments(const char* bug_id_str, const map_crash_data_t& pCrashData)
-{
- map_crash_data_t::const_iterator it = pCrashData.begin();
- for (; it != pCrashData.end(); it++)
- {
- 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)
- && (strlen(content) > CD_TEXT_ATT_SIZE || (strcmp(itemname, FILENAME_BACKTRACE) == 0))
- ) {
- 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", filename,
- "filename", itemname,
- "contenttype", "text/plain",
- "data", encoded64
- );
- free(encoded64);
- free(filename);
- if (!result)
- return -1;
-
- xmlrpc_DECREF(result);
- }
- }
- return 0;
-}
-
-int ctx::get_bug_info(struct bug_info* bz, xmlrpc_int32 bug_id)
-{
- xmlrpc_value* result = call("bugzilla.getBug", "(s)", to_string(bug_id).c_str());
- if (!result)
- return -1;
-
- bz->bug_product = get_bug_product(result);
- if (bz->bug_product == NULL)
- return -1;
-
- bz->bug_status = get_bug_status(result);
- if (bz->bug_status == NULL)
- return -1;
-
- bz->bug_reporter = get_bug_reporter(result);
- if (bz->bug_reporter == NULL)
- return -1;
-
- // mandatory when bug status is CLOSED
- if (strcmp(bz->bug_status, "CLOSED") == 0)
- {
- bz->bug_resolution = get_bug_resolution(result);
- if ((env.fault_occurred) && (bz->bug_resolution == NULL))
- return -1;
- }
-
- // mandatory when bug status is CLOSED and resolution is DUPLICATE
- if ((strcmp(bz->bug_status, "CLOSED") == 0)
- && (strcmp(bz->bug_resolution, "DUPLICATE") == 0)
- ) {
- bz->bug_dup_id = get_bug_dup_id(result);
- if (env.fault_occurred)
- return -1;
- }
-
- get_bug_cc(result, bz);
- if (env.fault_occurred)
- return -1;
-
- xmlrpc_DECREF(result);
- return 0;
-}
-
-void ctx::login(const char* login, const char* passwd)
-{
- xmlrpc_value* result = call("User.login", "({s:s,s:s})", "login", login, "password", passwd);
-
- if (!result)
- {
- 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);
-}
-
-void ctx::logout()
-{
- xmlrpc_value* result = call("User.logout", "(s)", "");
- if (result)
- xmlrpc_DECREF(result);
-
- throw_if_xml_fault_occurred(&env);
-}
-
-} /* namespace */
-
-
-static void report_to_bugzilla(
- const char *dump_dir_name,
- /*const*/ map_plugin_settings_t& settings)
-{
- 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);
-
- const char *env;
- const char *login;
- const char *password;
- const char *bugzilla_xmlrpc;
- const char *bugzilla_url;
- bool ssl_verify;
-
- env = getenv("Bugzilla_Login");
- login = env ? env : settings["Login"].c_str();
- env = getenv("Bugzilla_Password");
- password = env ? env : settings["Password"].c_str();
- if (!login[0] || !password[0])
- {
- VERB3 log("Empty login and password");
- throw CABRTException(EXCEP_PLUGIN, _("Empty login or password, please check %s"), PLUGINS_CONF_DIR"/Bugzilla.conf");
- }
-
- env = getenv("Bugzilla_BugzillaURL");
- bugzilla_url = env ? env : settings["BugzillaURL"].c_str();
- if (!bugzilla_url[0])
- bugzilla_url = "https://bugzilla.redhat.com";
- bugzilla_xmlrpc = xasprintf("%s"XML_RPC_SUFFIX, bugzilla_url);
-
- env = getenv("Bugzilla_SSLVerify");
- ssl_verify = string_to_bool(env ? env : settings["SSLVerify"].c_str());
-
- const char *component = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_COMPONENT);
- const char *duphash = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_DUPHASH);
- const char *release = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_RELEASE);
-
- ctx bz_server(bugzilla_xmlrpc, ssl_verify);
-
- log(_("Logging into bugzilla..."));
- bz_server.login(login, password);
-
- log(_("Checking for duplicates..."));
-
- char *product = NULL;
- char *version = NULL;
- parse_release(release, &product, &version);
-
- xmlrpc_value *result;
- if (strcmp(product, "Fedora") == 0)
- result = bz_server.call_quicksearch_duphash(component, product, duphash);
- else
- result = bz_server.call_quicksearch_duphash(component, NULL, duphash);
-
- if (!result)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- xmlrpc_value *all_bugs = bz_server.get_member("bugs", result);
- xmlrpc_DECREF(result);
-
- if (!all_bugs)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- throw CABRTException(EXCEP_PLUGIN, _("Missing mandatory member 'bugs'"));
- }
-
- xmlrpc_int32 bug_id = -1;
- int all_bugs_size = bz_server.get_array_size(all_bugs);
- struct bug_info bz;
- int depend_on_bugno = -1;
- if (all_bugs_size > 0)
- {
- bug_id = bz_server.get_bug_id(all_bugs);
- xmlrpc_DECREF(all_bugs);
- if (bug_id == -1)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- bug_info_init(&bz);
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
- throw CABRTException(EXCEP_PLUGIN, _("get_bug_info() failed. Could not collect all mandatory information"));
- }
-
- if (strcmp(bz.bug_product, product) != 0)
- {
- depend_on_bugno = bug_id;
- bug_info_destroy(&bz);
- result = bz_server.call_quicksearch_duphash(component, release, duphash);
- if (!result)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- all_bugs = bz_server.get_member("bugs", result);
- xmlrpc_DECREF(result);
-
- if (!all_bugs)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- throw CABRTException(EXCEP_PLUGIN, _("Missing mandatory member 'bugs'"));
- }
-
- all_bugs_size = bz_server.get_array_size(all_bugs);
- if (all_bugs_size > 0)
- {
- bug_id = bz_server.get_bug_id(all_bugs);
- xmlrpc_DECREF(all_bugs);
- if (bug_id == -1)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- bug_info_init(&bz);
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
- throw CABRTException(EXCEP_PLUGIN, _("get_bug_info() failed. Could not collect all mandatory information"));
- }
- }
- else
- xmlrpc_DECREF(all_bugs);
- }
- }
- free(product);
- free(version);
-
- if (all_bugs_size < 0)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
- else if (all_bugs_size == 0) // Create new bug
- {
- log(_("Creating a new bug..."));
- bug_id = bz_server.new_bug(pCrashData, depend_on_bugno);
- if (bug_id < 0)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- throw CABRTException(EXCEP_PLUGIN, _("Bugzilla entry creation failed"));
- }
-
- log("Adding attachments to bug %d...", bug_id);
- int ret = bz_server.add_attachments(to_string(bug_id).c_str(), pCrashData);
- if (ret == -1)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
-
- log(_("Logging out..."));
- bz_server.logout();
-
- log("Status: NEW %s/show_bug.cgi?id=%u",
- bugzilla_url,
- (int)bug_id
- );
- return;
- }
-
- if (all_bugs_size > 1)
- {
- // 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);
- }
-
- // decision based on state
- log(_("Bug is already reported: %i"), bug_id);
-
- xmlrpc_int32 original_bug_id = bug_id;
- if ((strcmp(bz.bug_status, "CLOSED") == 0) && (strcmp(bz.bug_resolution, "DUPLICATE") == 0))
- {
- for (int ii = 0; ii <= MAX_HOPS; ii++)
- {
- if (ii == MAX_HOPS)
- {
- VERB3 log("Bugzilla could not find a parent of bug %d", (int)original_bug_id);
- bug_info_destroy(&bz);
- throw CABRTException(EXCEP_PLUGIN, _("Bugzilla couldn't find parent of bug %d"), (int)original_bug_id);
- }
-
- log("Bug %d is a duplicate, using parent bug %d", bug_id, (int)bz.bug_dup_id);
- bug_id = bz.bug_dup_id;
- bug_info_destroy(&bz);
- bug_info_init(&bz);
-
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- if (bz_server.env.fault_occurred)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
- throw CABRTException(EXCEP_PLUGIN, _("get_bug_info() failed. Could not collect all mandatory information"));
- }
-
- // found a bug which is not CLOSED as DUPLICATE
- if (bz.bug_dup_id == -1)
- break;
- }
- }
-
- if (strcmp(bz.bug_status, "CLOSED") != 0)
- {
- int status = 0;
- if ((strcmp(bz.bug_reporter, login) != 0) && (am_i_in_cc(&bz, login)))
- {
- log(_("Add %s to CC list"), login);
- status = bz_server.add_plus_one_cc(bug_id, login);
- }
-
- if (status == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
- }
-
- 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");
-
- char *full_dsc = xasprintf("Package: %s\n"
- "Architecture: %s\n"
- "OS Release: %s\n"
- "%s", package, arch, release, dsc
- );
-
- log(_("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, full_dsc, is_priv) == -1)
- {
- free(full_dsc);
- bug_info_destroy(&bz);
- throw_xml_fault(&bz_server.env);
- }
- free(full_dsc);
- }
- }
-
- log(_("Logging out..."));
- bz_server.logout();
-
- log("Status: %s%s%s %s/show_bug.cgi?id=%u",
- bz.bug_status,
- bz.bug_resolution ? " " : "",
- bz.bug_resolution ? bz.bug_resolution : "",
- bugzilla_url,
- (int)bug_id
- );
-
- bug_info_destroy(&bz);
-}
-
-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: abrt-action-bugzilla -c CONFFILE -d DIR [-vs]"
- "\n"
- "\nReport a crash to Bugzilla"
- "\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("abrt-action-bugzilla[%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_bugzilla(dump_dir_name, settings);
- }
- catch (CABRTException& e)
- {
- error_msg_and_die("%s", e.what());
- }
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-generate-backtrace.c b/src/daemon/abrt-action-generate-backtrace.c
deleted file mode 100644
index 8f1642d7..00000000
--- a/src/daemon/abrt-action-generate-backtrace.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "../btparser/backtrace.h"
-#include "../btparser/frame.h"
-#include "../btparser/location.h"
-#include "parse_options.h"
-
-
-#define PROGNAME "abrt-action-generate-backtrace"
-
-#define DEBUGINFO_CACHE_DIR LOCALSTATEDIR"/cache/abrt-di"
-
-static const char *dump_dir_name = ".";
-static const char *debuginfo_dirs;
-static int exec_timeout_sec = 60;
-
-
-static void create_hash(char hash_str[SHA1_RESULT_LEN*2 + 1], const char *pInput)
-{
- unsigned len;
- unsigned char hash2[SHA1_RESULT_LEN];
- sha1_ctx_t sha1ctx;
-
- sha1_begin(&sha1ctx);
- sha1_hash(pInput, strlen(pInput), &sha1ctx);
- sha1_end(hash2, &sha1ctx);
- len = SHA1_RESULT_LEN;
-
- char *d = hash_str;
- unsigned char *s = hash2;
- while (len)
- {
- *d++ = "0123456789abcdef"[*s >> 4];
- *d++ = "0123456789abcdef"[*s & 0xf];
- s++;
- len--;
- }
- *d = '\0';
- //log("hash2:%s str:'%s'", hash_str, pInput);
-}
-
-/**
- *
- * @param[out] status See `man 2 wait` for status information.
- * @return Malloc'ed string
- */
-static char* exec_vp(char **args, uid_t uid, int redirect_stderr, int *status)
-{
- /* Nuke everything which may make setlocale() switch to non-POSIX locale:
- * we need to avoid having gdb output in some obscure language.
- */
- static const char *const unsetenv_vec[] = {
- "LANG",
- "LC_ALL",
- "LC_COLLATE",
- "LC_CTYPE",
- "LC_MESSAGES",
- "LC_MONETARY",
- "LC_NUMERIC",
- "LC_TIME",
- NULL
- };
-
- int flags = EXECFLG_INPUT_NUL | EXECFLG_OUTPUT | EXECFLG_SETGUID | EXECFLG_SETSID | EXECFLG_QUIET;
- if (redirect_stderr)
- flags |= EXECFLG_ERR2OUT;
- VERB1 flags &= ~EXECFLG_QUIET;
-
- int pipeout[2];
- pid_t child = fork_execv_on_steroids(flags, args, pipeout, (char**)unsetenv_vec, /*dir:*/ NULL, uid);
-
- /* We use this function to run gdb and unstrip. Bugs in gdb or corrupted
- * coredumps were observed to cause gdb to enter infinite loop.
- * Therefore we have a (largish) timeout, after which we kill the child.
- */
- int t = time(NULL); /* int is enough, no need to use time_t */
- int endtime = t + exec_timeout_sec;
-
- struct strbuf *buf_out = strbuf_new();
-
- while (1)
- {
- int timeout = endtime - t;
- if (timeout < 0)
- {
- kill(child, SIGKILL);
- strbuf_append_strf(buf_out, "\nTimeout exceeded: %u seconds, killing %s\n", exec_timeout_sec, args[0]);
- break;
- }
-
- /* We don't check poll result - checking read result is enough */
- struct pollfd pfd;
- pfd.fd = pipeout[0];
- pfd.events = POLLIN;
- poll(&pfd, 1, timeout * 1000);
-
- char buff[1024];
- int r = read(pipeout[0], buff, sizeof(buff) - 1);
- if (r <= 0)
- break;
- buff[r] = '\0';
- strbuf_append_str(buf_out, buff);
- t = time(NULL);
- }
- close(pipeout[0]);
-
- /* Prevent having zombie child process, and maybe collect status
- * (note that status == NULL is ok too) */
- waitpid(child, status, 0);
-
- return strbuf_free_nobuf(buf_out);
-}
-
-static char *get_backtrace(struct dump_dir *dd)
-{
- char *uid_str = dd_load_text(dd, CD_UID);
- uid_t uid = xatoi_u(uid_str);
- free(uid_str);
- char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
- dd_close(dd);
-
- // Workaround for
- // http://sourceware.org/bugzilla/show_bug.cgi?id=9622
- unsetenv("TERM");
- // This is not necessary
- //putenv((char*)"TERM=dumb");
-
- char *args[21];
- args[0] = (char*)"gdb";
- args[1] = (char*)"-batch";
-
- // when/if gdb supports "set debug-file-directory DIR1:DIR2":
- // (https://bugzilla.redhat.com/show_bug.cgi?id=528668):
- args[2] = (char*)"-ex";
- struct strbuf *set_debug_file_directory = strbuf_new();
- strbuf_append_str(set_debug_file_directory, "set debug-file-directory /usr/lib/debug");
- const char *p = debuginfo_dirs;
- while (1)
- {
- while (*p == ':')
- p++;
- if (*p == '\0')
- break;
- const char *colon_or_nul = strchrnul(p, ':');
- strbuf_append_strf(set_debug_file_directory, ":%.*s/usr/lib/debug", (int)(colon_or_nul - p), p);
- p = colon_or_nul;
- }
- args[3] = strbuf_free_nobuf(set_debug_file_directory);
-
- /* "file BINARY_FILE" is needed, without it gdb cannot properly
- * unwind the stack. Currently the unwind information is located
- * in .eh_frame which is stored only in binary, not in coredump
- * or debuginfo.
- *
- * Fedora GDB does not strictly need it, it will find the binary
- * by its build-id. But for binaries either without build-id
- * (= built on non-Fedora GCC) or which do not have
- * their debuginfo rpm installed gdb would not find BINARY_FILE
- * so it is still makes sense to supply "file BINARY_FILE".
- *
- * Unfortunately, "file BINARY_FILE" doesn't work well if BINARY_FILE
- * was deleted (as often happens during system updates):
- * gdb uses specified BINARY_FILE
- * even if it is completely unrelated to the coredump.
- * See https://bugzilla.redhat.com/show_bug.cgi?id=525721
- *
- * TODO: check mtimes on COREFILE and BINARY_FILE and not supply
- * BINARY_FILE if it is newer (to at least avoid gdb complaining).
- */
- args[4] = (char*)"-ex";
- args[5] = xasprintf("file %s", executable);
- free(executable);
-
- args[6] = (char*)"-ex";
- args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, dump_dir_name);
-
- args[8] = (char*)"-ex";
- /*args[9] = ... see below */
- args[10] = (char*)"-ex";
- args[11] = (char*)"info sharedlib";
- /* glibc's abort() stores its message in __abort_msg variable */
- args[12] = (char*)"-ex";
- args[13] = (char*)"print (char*)__abort_msg";
- args[14] = (char*)"-ex";
- args[15] = (char*)"print (char*)__glib_assert_msg";
- args[16] = (char*)"-ex";
- args[17] = (char*)"info registers";
- args[18] = (char*)"-ex";
- args[19] = (char*)"disassemble";
- args[20] = NULL;
-
- /* Get the backtrace, but try to cap its size */
- /* Limit bt depth. With no limit, gdb sometimes OOMs the machine */
- unsigned bt_depth = 2048;
- const char *thread_apply_all = "thread apply all";
- const char *full = " full";
- char *bt = NULL;
- while (1)
- {
- args[9] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full);
- bt = exec_vp(args, uid, /*redirect_stderr:*/ 1, NULL);
- free(args[9]);
- if ((bt && strnlen(bt, 256*1024) < 256*1024) || bt_depth <= 32)
- {
- break;
- }
-
- free(bt);
- bt_depth /= 2;
- if (bt_depth <= 64 && thread_apply_all[0] != '\0')
- {
- /* This program likely has gazillion threads, dont try to bt them all */
- bt_depth = 256;
- thread_apply_all = "";
- }
- if (bt_depth <= 64 && full[0] != '\0')
- {
- /* Looks like there are gigantic local structures or arrays, disable "full" bt */
- bt_depth = 256;
- full = "";
- }
- }
-
- free(args[3]);
- free(args[5]);
- free(args[7]);
- return bt;
-}
-
-static char *i_opt;
-static const char abrt_action_generage_backtrace_usage[] = PROGNAME" [options] -d DIR";
-enum {
- OPT_v = 1 << 0,
- OPT_d = 1 << 1,
- OPT_i = 1 << 2,
- OPT_t = 1 << 3,
- OPT_s = 1 << 4,
-};
-/* Keep enum above and order of options below in sync! */
-static struct options abrt_action_generate_backtrace_options[] = {
- OPT__VERBOSE(&g_verbose),
- OPT_STRING( 'd', NULL, &dump_dir_name, "DIR", "Crash dump directory"),
- OPT_STRING( 'i', NULL, &i_opt, "dir1[:dir2]...", "Additional debuginfo directories"),
- OPT_INTEGER('t', NULL, &exec_timeout_sec, "Kill gdb if it runs for more than N seconds"),
- OPT_BOOL( 's', NULL, NULL, "Log to syslog"),
- OPT_END()
-};
-
-int main(int argc, char **argv)
-{
- char *env_verbose = getenv("ABRT_VERBOSE");
- if (env_verbose)
- g_verbose = atoi(env_verbose);
-
- unsigned opts = parse_opts(argc, argv, abrt_action_generate_backtrace_options,
- abrt_action_generage_backtrace_usage);
-
- debuginfo_dirs = DEBUGINFO_CACHE_DIR;
- if (i_opt)
- {
- debuginfo_dirs = xasprintf("%s:%s", DEBUGINFO_CACHE_DIR, i_opt);
- }
-
- putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
- msg_prefix = PROGNAME;
-
- 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 *package = dd_load_text(dd, FILENAME_PACKAGE);
- char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
-
- /* Create and store backtrace */
- /* NB: get_backtrace() closes dd */
- char *backtrace_str = get_backtrace(dd);
- if (!backtrace_str)
- {
- backtrace_str = xstrdup("");
- VERB3 log("get_backtrace() returns NULL, broken core/gdb?");
- }
-
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return 1;
-
- dd_save_text(dd, FILENAME_BACKTRACE, backtrace_str);
-
- /* Compute and store backtrace hash. */
- struct btp_location location;
- btp_location_init(&location);
- char *backtrace_str_ptr = backtrace_str;
- struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, &location);
- if (!backtrace)
- {
- VERB1 log(_("Backtrace parsing failed for %s"), dump_dir_name);
- VERB1 log("%d:%d: %s", location.line, location.column, location.message);
- /* If the parser failed compute the UUID from the executable
- and package only. This is not supposed to happen often.
- Do not store the rating, as we do not know how good the
- backtrace is. */
- struct strbuf *emptybt = strbuf_new();
- strbuf_prepend_str(emptybt, executable);
- strbuf_prepend_str(emptybt, package);
- char hash_str[SHA1_RESULT_LEN*2 + 1];
- create_hash(hash_str, emptybt->buf);
- dd_save_text(dd, FILENAME_DUPHASH, hash_str);
-
- strbuf_free(emptybt);
- free(backtrace_str);
- free(package);
- free(executable);
- dd_close(dd);
- return 2;
- }
- free(backtrace_str);
-
- /* Compute duplication hash. */
- char *str_hash_core = btp_backtrace_get_duplication_hash(backtrace);
- struct strbuf *str_hash = strbuf_new();
- strbuf_append_str(str_hash, package);
- strbuf_append_str(str_hash, executable);
- strbuf_append_str(str_hash, str_hash_core);
- char hash_str[SHA1_RESULT_LEN*2 + 1];
- create_hash(hash_str, str_hash->buf);
- dd_save_text(dd, FILENAME_DUPHASH, hash_str);
- strbuf_free(str_hash);
- free(str_hash_core);
-
- /* Compute the backtrace rating. */
- float quality = btp_backtrace_quality_complex(backtrace);
- const char *rating;
- if (quality < 0.6f)
- rating = "0";
- else if (quality < 0.7f)
- rating = "1";
- else if (quality < 0.8f)
- rating = "2";
- else if (quality < 0.9f)
- rating = "3";
- else
- rating = "4";
- dd_save_text(dd, FILENAME_RATING, rating);
-
- /* Get the function name from the crash frame. */
- struct btp_frame *crash_frame = btp_backtrace_get_crash_frame(backtrace);
- if (crash_frame)
- {
- if (crash_frame->function_name &&
- 0 != strcmp(crash_frame->function_name, "??"))
- {
- dd_save_text(dd, FILENAME_CRASH_FUNCTION, crash_frame->function_name);
- }
- btp_frame_free(crash_frame);
- }
- btp_backtrace_free(backtrace);
- dd_close(dd);
-
- free(executable);
- free(package);
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-install-debuginfo b/src/daemon/abrt-action-install-debuginfo
deleted file mode 100755
index c1b8fdb9..00000000
--- a/src/daemon/abrt-action-install-debuginfo
+++ /dev/null
@@ -1,418 +0,0 @@
-#!/bin/sh
-# Called by abrtd before producing a backtrace.
-# The task of this script is to install debuginfos.
-#
-# Just using [pk-]debuginfo-install does not work well.
-# - they can't install more than one version of debuginfo
-# for a package
-# - their output is unsuitable for scripting
-# - debuginfo-install aborts if yum lock is busy
-# - pk-debuginfo-install was observed to hang
-#
-# Usage: abrt-action-install-debuginfo CORE TEMPDIR [CACHEDIR[:DEBUGINFODIR1:DEBUGINFODIR2...]]
-# If CACHEDIR is specified, debuginfos should be installed there.
-# If not, debuginfos should be installed into TEMPDIR.
-#
-# Currently, we are called with CACHEDIR set to "/var/cache/abrt-di",
-# but in the future it may be omitted or set to something else.
-# Script must be ready for those cases too. Consider, for example,
-# corner cases of "" and "/".
-#
-# Output goes to GUI as debuginfo install log. The script should be careful
-# to give useful, but not overly cluttered info to stdout.
-# Additionally, abrt daemon handles "MISSING:xxxx" messages specially:
-# it is used to inform about missing debuginfos.
-#
-# Exitcodes:
-# 0 - all debuginfos are installed
-# 1 - not all debuginfos are installed
-# 2+ - serious problem
-#
-# Algorithm:
-# - Create TEMPDIR
-# - Extract build-ids from coredump
-# - For every build-id, check /usr/lib/debug/.build-id/XX/XXXX.debug
-# and CACHEDIR/usr/lib/debug/.build-id/XX/XXXX.debug
-# - If they all exist, exit 0
-# - Using "yum provides /usr/lib/debug/.build-id/XX/XXXX.debug",
-# figure out which debuginfo packages are needed
-# - Download them using "yumdownloader PACKAGE..."
-# - Unpack them with rpm2cpio | cpio to TEMPDIR
-# - If CACHEDIR is specified, copy usr/lib/debug/.build-id/XX/XXXX.debug
-# to CACHEDIR/usr/lib/debug/.build-id/XX/XXXX.debug and delete TEMPDIR
-# - Report which XX/XXXX.debug are still missing.
-#
-# For better debuggability, eu_unstrip.OUT, yum_provides.OUT etc files
-# are saved in TEMPDIR, and TEMPDIR is not deleted if we exit with exitcode 2
-# ("serious problem").
-
-
-debug=false
-# Useful if you need to see saved rpms, command outputs etc
-keep_tmp=false
-
-
-# Handle options
-if test x"$1" = x"--"; then
- shift
-else
- if test x"$1" = x"-v"; then
- debug=true
- shift
- fi
- if test $# -lt 2 || test x"$1" = x"--help"; then
- echo "Usage:"
- echo
- echo "abrt-action-install-debuginfo [-v] CORE TEMPDIR [CACHEDIR[:DEBUGINFODIR...]]"
- echo
- echo "TEMPDIR must be a name of a new temporary directory. It must not exist."
- echo "If CACHEDIR is specified, debuginfos are installed in CACHEDIR,"
- echo "and TEMPDIR is deleted on exit."
- echo "Otherwise, debuginfos are installed into TEMPDIR, which is not deleted."
- echo
- echo "Options:"
- echo " -v Verbose (for debugging)"
- echo
- exit
- fi
-fi
-
-
-# Parse params
-core="$1"
-tempdir="$2"
-debuginfodirs="${3//:/ }"
-cachedir="${3%%:*}"
-
-
-# stderr may be used for status messages too
-exec 2>&1
-
-
-error_msg_and_die() {
- echo "$*"
- exit 2
-}
-
-count_words() {
- echo $#
-}
-
-print_missing_build_ids() {
- local build_id
- local build_id1
- local build_id2
- local file
- local d
- for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
- test -f "/$file" && continue
- # On 2nd pass, we may already have some debuginfos in tempdir
- test -f "$tempdir/$file" && continue
- # Check cachedir if we have one
- for d in $debuginfodirs; do
- test -f "$d/$file" && continue 2
- done
- echo -n "$build_id "
- done
-}
-
-# Note: it is run in `backticks`, use >&2 for error messages
-print_missing_debuginfos() {
- local build_id
- local build_id1
- local build_id2
- local file
- local d
- for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
- test -f "/$file" && continue
- # On 2nd pass, we may already have some debuginfos in tempdir
- test -f "$tempdir/$file" && continue
- # Check cachedir if we have one
- if test x"$cachedir" != x""; then
- for d in $debuginfodirs; do
- test -f "$d/$file" && continue 2
- done
- fi
- echo -n "/$file "
- done
-}
-
-cleanup_and_report_missing() {
-# Which debuginfo files are still missing, including those we just unpacked?
- missing_build_ids=`print_missing_build_ids`
- $debug && echo "missing_build_ids:$missing_build_ids" >&2
-
- # If cachedir is specified, tempdir is just a staging area. Delete it
- if test x"$cachedir" != x""; then
- $keep_tmp && echo "NOT removing $tempdir (keep_tmp debugging is on)" >&2
- $keep_tmp || { $debug && echo "Removing $tempdir" >&2; rm -rf "$tempdir"; }
- fi
-
- for missing in $missing_build_ids; do
- echo "MISSING:$missing" >&2
- done
-
- test x"$missing_build_ids" != x"" && echo "`count_words $missing_build_ids` debuginfos can't be found" >&2
-}
-
-# $1: iteration (1,2...)
-# Note: it is run in `backticks`, use >&2 for error messages
-print_package_names() {
- # We'll run something like:
- # yum --enablerepo=*debuginfo* --quiet provides \
- # /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \
- # /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ...
- local yumopts=""
- if test x"$1" = x"1"; then
- yumopts="-C"
- echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list from cache" >&2
- else
- echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list from repositories" >&2
- fi
- # --showduplicates: do not just show the latest package
- # (tried to use -R2 to abort on stuck yum lock but -R is not about that)
- local cmd="yum $yumopts $yum_repo_opts --showduplicates --quiet provides $missing_debuginfo_files"
- echo "$cmd" >"yum_provides.$1.OUT"
- $debug && echo "Running: $cmd" >&2
- # eval is needed to strip away ''s in $yum_repo_opts; cant remove them and just use
- # unquoted $cmd, that would perform globbing on '*'
- local yum_provides_OUT="`eval $cmd 2>&1`"
- local err=$?
- printf "%s\nyum exitcode:%s\n" "$yum_provides_OUT" $err >>"yum_provides.$1.OUT"
- test $err = 0 || error_msg_and_die "yum provides... exited with $err:
-`head yum_provides.$1.OUT`" >&2
-
- # The output is pretty machine-unfriendly:
- # glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc
- # Repo : rawhide-debuginfo
- # Matched from:
- # Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug
- #
- # 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus
- # Repo : updates-debuginfo
- # Matched from:
- # Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug
- # Need to massage it a lot.
- # There can be duplicates (one package may provide many debuginfos).
- printf "%s\n" "$yum_provides_OUT" \
- | grep -- -debuginfo- \
- | sed 's/^[0-9]*://' \
- | sed -e 's/ .*//' -e 's/:.*//' \
- | sort | uniq | xargs
-}
-
-abort_if_low_on_disk_space() {
- local mb
- # free_blocks * block_size / (1024*1024), careful to not overflow:
- mb=$((`stat -f -c "%a / 8192 * %S / 128" "$tempdir"`))
- if test $mb -lt $1; then
- $debug && echo "Removing $tempdir" >&2
- rm -rf "$tempdir"
- error_msg_and_die "Less than $1 Mb of free space in $tempdir: $mb Mb"
- fi
- if test x"$cachedir" != x"" && test -d "$cachedir"; then
- mb=$((`stat -f -c "%a / 8192 * %S / 128" "$cachedir"`))
- if test $mb -lt $1; then
- $debug && echo "Removing $tempdir" >&2
- rm -rf "$tempdir"
- error_msg_and_die "Less than $1 Mb of free space in $cachedir: $mb Mb"
- fi
- fi
-}
-
-download_packages() {
- local pkg
- local err
- local file
- local build_id
- local build_id1
- local build_id2
- local d
-
- ## Download with one command (too silent):
- ## Redirecting, since progress bar stuff only messes up our output
- ##yumdownloader --enablerepo=*debuginfo* --quiet $packages >yumdownloader.OUT 2>&1
- ##err=$?
- ##echo "exitcode:$err" >>yumdownloader.OUT
- ##test $err = 0 || error_msg_and_die ...
- >yumdownloader.OUT
- i=1
- for pkg in $packages; do
- echo "Download $i/$num_packages: $pkg"
- echo "Download $i/$num_packages: $pkg" >>yumdownloader.OUT
- cmd="yumdownloader $yum_repo_opts --quiet $pkg"
- $debug && echo "Running: $cmd" >&2
- # eval is needed to strip away ''s in $yum_repo_opts
- eval $cmd >>yumdownloader.OUT 2>&1 &
- # using EXIT handler and this, make sure we kill yumdownloader if we exit:
- CHILD_PID=$!
- wait
- err=$?
- CHILD_PID=""
- echo "exitcode:$err" >>yumdownloader.OUT
- echo >>yumdownloader.OUT
- test $err = 0 || echo "Download of $pkg failed!"
- abort_if_low_on_disk_space 256
-
- # Process and delete the *.rpm file just downloaded
- # We do it right after download: some users have smallish disks...
- for file in *.rpm; do
- # Happens if no .rpm's were downloaded (yumdownloader problem)
- # In this case, $f is the literal "*.rpm" string
- test -f "$file" || { echo "No rpm file downloaded"; continue; }
- echo "Unpacking: $file"
- echo "Processing: $file" >>unpack.OUT
- rpm2cpio <"$file" >"unpacked.cpio" 2>>unpack.OUT || error_msg_and_die "Can't convert '$file' to cpio"
- $keep_tmp || rm "$file"
- abort_if_low_on_disk_space 256
- cpio -id <"unpacked.cpio" >>unpack.OUT 2>&1 || error_msg_and_die "Can't unpack '$file' cpio archive"
- rm "unpacked.cpio"
- abort_if_low_on_disk_space 256
- # Copy debuginfo files to cachedir
- if test x"$cachedir" != x"" && test -d "$cachedir"; then
- # For every needed debuginfo, check whether we have it
- for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
- # Do not copy it if it can be found in any of $debuginfodirs
- test -f "/$file" && continue
- if test x"$cachedir" != x""; then
- for d in $debuginfodirs; do
- test -f "$d/$file" && continue 2
- done
- fi
- if test -f "$file"; then
- # File is one of those we just installed, cache it
- mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1"
- # Note: this does not preserve symlinks. This is intentional
- $debug && echo Copying "$file" to "$cachedir/$file" >&2
- echo "Caching debuginfo: $file"
- cp --remove-destination "$file" "$cachedir/$file" || error_msg_and_die "Can't copy $file (disk full?)"
- continue
- fi
- done
- fi
- # Delete remaining files unpacked from .cpio
- # which we didn't need after all
- rm -r etc bin sbin usr var opt 2>/dev/null
- done
- : $((i++))
- done
-}
-
-
-# Sanity checking
-test -f "$core" || error_msg_and_die "not a file: '$core'"
-# cachedir is optional
-test x"$cachedir" = x"" || test -d "$cachedir" || error_msg_and_die "bad cachedir '$cachedir'"
-# tempdir must not exist
-test -e "$tempdir" && error_msg_and_die "tempdir exists: '$tempdir'"
-
-# Intentionally not using -p: we want to abort if tempdir exists
-mkdir -- "$tempdir" || exit 2
-cd "$tempdir" || exit 2
-
-
-abort_if_low_on_disk_space 1024
-
-
-# A hook to stop yumdownloader, in case we are terminated by kill -TERM etc.
-CHILD_PID=""
-trap 'test x"$CHILD_PID" != x"" && kill -- "$CHILD_PID"' EXIT
-
-
-$debug && echo "Downloading rpms to $tempdir"
-
-
-echo "Getting list of build IDs"
-# Observed errors:
-# eu-unstrip: /var/spool/abrt/ccpp-1256301004-2754/coredump: Callback returned failure
-eu_unstrip_OUT=`eu-unstrip "--core=$core" -n 2>eu_unstrip.ERR`
-err=$?
-printf "%s\neu-unstrip exitcode:%s\n" "$eu_unstrip_OUT" $err >eu_unstrip.OUT
-test $err = 0 || error_msg_and_die "eu-unstrip exited with $err:
-`cat eu_unstrip.ERR`
-`head eu_unstrip.OUT`"
-
-# eu-unstrip output example:
-# 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe]
-# or
-# 0x400000+0x20d000 233aa1a57e9ffda65f53efdaf5e5058657a39993@0x40024c /usr/libexec/im-settings-daemon /usr/lib/debug/usr/libexec/im-settings-daemon.debug [exe]
-# 0x7fff5cdff000+0x1000 0d3eb4326fd7489fcf9b598269f1edc420e2c560@0x7fff5cdff2f8 . - linux-vdso.so.1
-# 0x3d15600000+0x208000 20196628d1bc062279622615cc9955554e5bb227@0x3d156001a0 /usr/lib64/libnotify.so.1.1.3 /usr/lib/debug/usr/lib64/libnotify.so.1.1.3.debug libnotify.so.1
-# 0x7fd8ae931000+0x62d000 dd49f44f958b5a11a1635523b2f09cb2e45c1734@0x7fd8ae9311a0 /usr/lib64/libgtk-x11-2.0.so.0.1600.6 /usr/lib/debug/usr/lib64/libgtk-x11-2.0.so.0.1600.6.debug
-#
-# Get space-separated list of all build-ids
-# There can be duplicates (observed in real world)
-build_ids=`printf "%s\n" "$eu_unstrip_OUT" \
-| while read junk1 build_id binary_file di_file lib_name junk2; do
- build_id=${build_id%%@*}
-
- # This filters out linux-vdso.so, among others
- test x"$lib_name" != x"[exe]" && test x"${binary_file:0:1}" != x"/" && continue
- # Sanitize build_id: must be longer than 2 chars
- test ${#build_id} -le 2 && continue
- # Sanitize build_id: must have only hex digits
- test x"${build_id//[0-9a-f]/}" != x"" && continue
-
- echo "$build_id"
-done | sort | uniq | xargs`
-$debug && echo "build_ids:$build_ids"
-
-
-# Prepare list of repos to use.
-# When we look for debuginfo we need only -debuginfo* repos, we can disable the rest
-# and thus make it faster.
-yum_repo_opts="'--disablerepo=*'"
-#// Disabled. Too often, debuginfo repos have names which do not conform to "foo-debuginfo" scheme,
-#// and users get bad backtraces.
-#// # (Without -C, yum for some reason wants to talk to repos! If one is down, it becomes S..L..O..W)
-#// for enabled_repo in `LANG=C yum -C repolist all | grep 'enabled:' | cut -f1 -d' ' | grep -v -- '-debuginfo'`; do
-#// yum_repo_opts="$yum_repo_opts '--enablerepo=${enabled_repo}-debuginfo*'"
-#// done
-yum_repo_opts="$yum_repo_opts '--enablerepo=*-debug*'"
-
-
-# We try to not run yum without -C unless absolutely necessary.
-# Therefore we loop. yum is run by print_package_names function,
-# on first iteration it is run with -C, on second - without,
-# which usually causes yum to download updated filelists,
-# which in turn takes several minutes and annoys users.
-iter=0
-while test $((++iter)) -le 2; do
- # Analyze $build_ids and check which debuginfos are present
- missing_debuginfo_files=`print_missing_debuginfos`
- # Did print_missing_debuginfos fail?
- test $? = 0 || exit 2
- $debug && echo "missing_debuginfo_files:$missing_debuginfo_files"
-
- test x"$missing_debuginfo_files" = x"" && break
-
- # Map $missing_debuginfo_files to package names.
- # yum is run here.
- packages=`print_package_names $iter`
- # Did print_package_names fail?
- test $? = 0 || exit 2
- $debug && echo "packages ($iter):$packages"
-
- # yum may return "" here if it found no packages (say, if coredump
- # is from a new, unreleased package fresh from koji).
- test x"$packages" = x"" && continue
-
- num_packages=`count_words $packages`
- echo "Downloading $num_packages packages"
- download_packages
-done
-
-cleanup_and_report_missing
-
-test x"$missing_build_ids" != x"" && exit 1
-echo "All needed debuginfos are present"
-exit 0
diff --git a/src/daemon/abrt-action-kerneloops.cpp b/src/daemon/abrt-action-kerneloops.cpp
deleted file mode 100644
index 4c820081..00000000
--- a/src/daemon/abrt-action-kerneloops.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- 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.
-
- Authors:
- Anton Arapov <anton@redhat.com>
- Arjan van de Ven <arjan@linux.intel.com>
- */
-
-#include <curl/curl.h>
-#include "abrtlib.h"
-#include "crash_types.h"
-#include "abrt_exception.h"
-
-#include "plugin.h" /* LoadPluginSettings */
-
-#define PROGNAME "abrt-action-kerneloops"
-
-/* helpers */
-static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
-{
- size *= nmemb;
-/*
- char *c, *c1, *c2;
-
- log("received: '%*.*s'\n", (int)size, (int)size, (char*)ptr);
- c = (char*)xzalloc(size + 1);
- memcpy(c, ptr, size);
- c1 = strstr(c, "201 ");
- if (c1)
- {
- c1 += 4;
- c2 = strchr(c1, '\n');
- if (c2)
- *c2 = 0;
- }
- free(c);
-*/
-
- return size;
-}
-
-/* Send oops data to kerneloops.org-style site, using HTTP POST */
-/* Returns 0 on success */
-static CURLcode http_post_to_kerneloops_site(const char *url, const char *oopsdata)
-{
- CURLcode ret;
- CURL *handle;
- struct curl_httppost *post = NULL;
- struct curl_httppost *last = NULL;
-
- handle = curl_easy_init();
- if (!handle)
- error_msg_and_die("Can't create curl handle");
-
- curl_easy_setopt(handle, CURLOPT_URL, url);
-
- curl_formadd(&post, &last,
- CURLFORM_COPYNAME, "oopsdata",
- CURLFORM_COPYCONTENTS, oopsdata,
- CURLFORM_END);
- curl_formadd(&post, &last,
- CURLFORM_COPYNAME, "pass_on_allowed",
- CURLFORM_COPYCONTENTS, "yes",
- CURLFORM_END);
-
- curl_easy_setopt(handle, CURLOPT_HTTPPOST, post);
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefunction);
-
- ret = curl_easy_perform(handle);
-
- curl_formfree(post);
- curl_easy_cleanup(handle);
-
- return ret;
-}
-
-static void report_to_kerneloops(
- const char *dump_dir_name,
- const map_plugin_settings_t& settings)
-{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- exit(1); /* error msg is already logged */
-
- map_crash_data_t pCrashData;
- load_crash_data_from_debug_dump(dd, pCrashData);
- dd_close(dd);
-
- const char *backtrace = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_BACKTRACE);
- if (!backtrace)
- error_msg_and_die("Error sending kernel oops due to missing backtrace");
-
- map_plugin_settings_t::const_iterator end = settings.end();
- map_plugin_settings_t::const_iterator it;
-
- const char *env = getenv("KerneloopsReporter_SubmitURL");
- it = settings.find("SubmitURL");
- const char *submitURL = (env ? env : it == end ? "" : it->second.c_str());
- if (!submitURL[0])
- submitURL = "http://submit.kerneloops.org/submitoops.php";
-
- log(_("Submitting oops report to %s"), submitURL);
-
- CURLcode ret = http_post_to_kerneloops_site(submitURL, backtrace);
- if (ret != CURLE_OK)
- error_msg_and_die("Kernel oops has not been sent due to %s", curl_easy_strerror(ret));
-
- /* Server replies with:
- * 200 thank you for submitting the kernel oops information
- * RemoteIP: 34192fd15e34bf60fac6a5f01bba04ddbd3f0558
- * - no URL or bug ID apparently...
- */
- log("Kernel oops report was uploaded");
-}
-
-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 kernel oops to kerneloops.org (or similar) site"
- "\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;
- }
-
- try
- {
- report_to_kerneloops(dump_dir_name, settings);
- }
- catch (CABRTException& e)
- {
- error_msg_and_die("%s", e.what());
- }
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-print.cpp b/src/daemon/abrt-action-print.cpp
deleted file mode 100644
index a4db373a..00000000
--- a/src/daemon/abrt-action-print.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- Write crash dump to stdout in text form.
-
- Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 const char *dump_dir_name = ".";
-static const char *output_file = NULL;
-static const char *open_mode = "w";
-
-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] [-o FILE] -d DIR\n"
- "\n"
- "Print information about the crash to standard output");
- enum {
- OPT_v = 1 << 0,
- OPT_d = 1 << 1,
- OPT_o = 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_STRING('o', NULL, &output_file , "FILE", _("Output file")),
- OPT_END()
- };
-
- /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage);
-
- putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
- //msg_prefix = PROGNAME;
-
- char *env = getenv("Logger_LogPath");
- VERB3 log("output_file:'%s' Logger_LogPath env:'%s'", output_file, env);
- if (env)
- output_file = env;
-
- env = getenv("Logger_AppendLogs");
- VERB3 log("Logger_AppendLogs env:'%s'", env);
- if (env && string_to_bool(env))
- open_mode = "a";
-
- if (output_file)
- {
- if (!freopen(output_file, open_mode, stdout))
- {
- perror_msg_and_die("Can't open '%s'", output_file);
- }
- }
-
- try
- {
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return 1; /* error message is already logged */
-
- 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);
- }
- catch (CABRTException& e)
- {
- log("%s", e.what());
- return 1;
- }
-
- if (output_file)
- {
- const char *format = (open_mode[0] == 'a' ? _("The report was appended to %s") : _("The report was stored to %s"));
- log(format, output_file);
- }
-
- return 0;
-}
diff --git a/src/daemon/abrt-action-rhtsupport.cpp b/src/daemon/abrt-action-rhtsupport.cpp
deleted file mode 100644
index d1854541..00000000
--- a/src/daemon/abrt-action-rhtsupport.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- 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 <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& settings)
-{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- exit(1); /* error msg is already logged by dd_opendir */
-
- 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;
-
- char* env;
- map_plugin_settings_t::const_iterator end = settings.end();
- map_plugin_settings_t::const_iterator it;
-
- env = getenv("RHTSupport_URL");
- it = settings.find("URL");
- char *url = xstrdup(env ? env : it == end ? "https://api.access.redhat.com/rs" : it->second.c_str());
-
- env = getenv("RHTSupport_Login");
- it = settings.find("Login");
- char *login = xstrdup(env ? env : it == end ? "" : it->second.c_str());
-
- env = getenv("RHTSupport_Password");
- it = settings.find("Password");
- char *password = xstrdup(env ? env : it == end ? "" : it->second.c_str());
-
- env = getenv("RHTSupport_SSLVerify");
- it = settings.find("SSLVerify");
- bool ssl_verify = string_to_bool(env ? env : it == end ? "1" : 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
- );
- /* 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 */
- error_msg_and_die("%s", result);
- }
- /* No error */
- log("%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)
- error_msg_and_die("%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)
- {
- error_msg_and_die("%s", e.what());
- }
-
- return 0;
-}
diff --git a/src/daemon/abrt_rh_support.c b/src/daemon/abrt_rh_support.c
deleted file mode 100644
index 04e2c8ef..00000000
--- a/src/daemon/abrt_rh_support.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- 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 <libxml/encoding.h>
-#include <libxml/xmlwriter.h>
-#include <curl/curl.h>
-#include "abrtlib.h"
-#include "abrt_curl.h"
-#include "abrt_rh_support.h"
-
-struct reportfile {
- xmlTextWriterPtr writer;
- xmlBufferPtr buf;
-};
-
-static void __attribute__((__noreturn__))
-die_xml_oom(void)
-{
- error_msg_and_die("can't create XML attribute (out of memory?)");
-}
-
-static xmlBufferPtr
-xxmlBufferCreate(void)
-{
- xmlBufferPtr r = xmlBufferCreate();
- if (!r)
- die_xml_oom();
- return r;
-}
-
-static xmlTextWriterPtr
-xxmlNewTextWriterMemory(xmlBufferPtr buf /*, int compression*/)
-{
- xmlTextWriterPtr r = xmlNewTextWriterMemory(buf, /*compression:*/ 0);
- if (!r)
- die_xml_oom();
- return r;
-}
-
-static void
-xxmlTextWriterStartDocument(xmlTextWriterPtr writer,
- const char * version,
- const char * encoding,
- const char * standalone)
-{
- if (xmlTextWriterStartDocument(writer, version, encoding, standalone) < 0)
- die_xml_oom();
-}
-
-static void
-xxmlTextWriterEndDocument(xmlTextWriterPtr writer)
-{
- if (xmlTextWriterEndDocument(writer) < 0)
- die_xml_oom();
-}
-
-static void
-xxmlTextWriterStartElement(xmlTextWriterPtr writer, const char *name)
-{
- // these bright guys REDEFINED CHAR (!) to unsigned char...
- if (xmlTextWriterStartElement(writer, (unsigned char*)name) < 0)
- die_xml_oom();
-}
-
-static void
-xxmlTextWriterEndElement(xmlTextWriterPtr writer)
-{
- if (xmlTextWriterEndElement(writer) < 0)
- die_xml_oom();
-}
-
-static void
-xxmlTextWriterWriteElement(xmlTextWriterPtr writer, const char *name, const char *content)
-{
- if (xmlTextWriterWriteElement(writer, (unsigned char*)name, (unsigned char*)content) < 0)
- die_xml_oom();
-}
-
-static void
-xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content)
-{
- if (xmlTextWriterWriteAttribute(writer, (unsigned char*)name, (unsigned char*)content) < 0)
- die_xml_oom();
-}
-
-#if 0 //unused
-static void
-xxmlTextWriterWriteString(xmlTextWriterPtr writer, const char *content)
-{
- if (xmlTextWriterWriteString(writer, (unsigned char*)content) < 0)
- die_xml_oom();
-}
-#endif
-
-//
-// End the reportfile, and prepare it for delivery.
-// No more bindings can be added after this.
-//
-static void
-close_writer(reportfile_t* file)
-{
- if (!file->writer)
- return;
-
- // close off the end of the xml file
- xxmlTextWriterEndDocument(file->writer);
- xmlFreeTextWriter(file->writer);
- file->writer = NULL;
-}
-
-//
-// This allocates a reportfile_t structure and initializes it.
-//
-reportfile_t*
-new_reportfile(void)
-{
- // create a new reportfile_t
- reportfile_t* file = (reportfile_t*)xmalloc(sizeof(*file));
-
- // set up a libxml 'buffer' and 'writer' to that buffer
- file->buf = xxmlBufferCreate();
- file->writer = xxmlNewTextWriterMemory(file->buf);
-
- // start a new xml document:
- // <report xmlns="http://www.redhat.com/gss/strata">...
- xxmlTextWriterStartDocument(file->writer, /*version:*/ NULL, /*encoding:*/ NULL, /*standalone:*/ NULL);
- xxmlTextWriterStartElement(file->writer, "report");
- xxmlTextWriterWriteAttribute(file->writer, "xmlns", "http://www.redhat.com/gss/strata");
-
- return file;
-}
-
-static void
-internal_reportfile_start_binding(reportfile_t* file, const char* name, int isbinary, const char* filename)
-{
- // <binding name=NAME [fileName=FILENAME] type=text/binary...
- xxmlTextWriterStartElement(file->writer, "binding");
- xxmlTextWriterWriteAttribute(file->writer, "name", name);
- if (filename)
- xxmlTextWriterWriteAttribute(file->writer, "fileName", filename);
- if (isbinary)
- xxmlTextWriterWriteAttribute(file->writer, "type", "binary");
- else
- xxmlTextWriterWriteAttribute(file->writer, "type", "text");
-}
-
-//
-// Add a new text binding
-//
-void
-reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value)
-{
- // <binding name=NAME type=text value=VALUE>
- internal_reportfile_start_binding(file, name, /*isbinary:*/ 0, /*filename:*/ NULL);
- xxmlTextWriterWriteAttribute(file->writer, "value", value);
- xxmlTextWriterEndElement(file->writer);
-}
-
-//
-// Add a new binding to a report whose value is represented as a file.
-//
-void
-reportfile_add_binding_from_namedfile(reportfile_t* file,
- const char* on_disk_filename, /* unused so far */
- const char* binding_name,
- const char* recorded_filename,
- int isbinary)
-{
- // <binding name=NAME fileName=FILENAME type=text/binary...
- internal_reportfile_start_binding(file, binding_name, isbinary, recorded_filename);
- // ... href=content/NAME>
- char *href_name = concat_path_file("content", binding_name);
- xxmlTextWriterWriteAttribute(file->writer, "href", href_name);
- free(href_name);
-}
-
-//
-// Return the contents of the reportfile as a string.
-//
-const char*
-reportfile_as_string(reportfile_t* file)
-{
- close_writer(file);
- // unsigned char -> char
- return (char*)file->buf->content;
-}
-
-void
-reportfile_free(reportfile_t* file)
-{
- if (!file)
- return;
- close_writer(file);
- xmlBufferFree(file->buf);
- free(file);
-}
-
-
-//
-// post_signature()
-//
-char*
-post_signature(const char* baseURL, bool ssl_verify, const char* signature)
-{
- char *URL = concat_path_file(baseURL, "/signatures");
-
- abrt_post_state_t *state = new_abrt_post_state(0
- + ABRT_POST_WANT_HEADERS
- + ABRT_POST_WANT_BODY
- + ABRT_POST_WANT_ERROR_MSG
- + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0)
- );
- int http_resp_code = abrt_post_string(state, URL, "application/xml", signature);
- free(URL);
-
- char *retval;
- const char *strata_msg;
- switch (http_resp_code)
- {
- case 200:
- case 201:
- if (state->body)
- {
- retval = state->body;
- state->body = NULL;
- break;
- }
- strata_msg = find_header_in_abrt_post_state(state, "Strata-Message:");
- if (strata_msg && strcmp(strata_msg, "CREATED") != 0) {
- retval = xstrdup(strata_msg);
- break;
- }
- retval = xstrdup("Signature submitted successfully");
- break;
-
- default:
- strata_msg = find_header_in_abrt_post_state(state, "Strata-Message:");
- if (strata_msg)
- {
- retval = xasprintf("Error (HTTP response %d): %s",
- http_resp_code,
- strata_msg);
- break;
- }
- if (state->curl_error_msg)
- {
- if (http_resp_code >= 0)
- retval = xasprintf("Error (HTTP response %d): %s", http_resp_code, state->curl_error_msg);
- else
- retval = xasprintf("Error in HTTP transaction: %s", state->curl_error_msg);
- break;
- }
- retval = xasprintf("Error (HTTP response %d), body:\n%s", http_resp_code, state->body);
- break;
- }
-
- free_abrt_post_state(state);
- return retval;
-}
-
-
-//
-// send_report_to_new_case()
-//
-
-static char*
-make_case_data(const char* summary, const char* description,
- const char* product, const char* version,
- const char* component)
-{
- char* retval;
- xmlTextWriterPtr writer;
- xmlBufferPtr buf;
-
- buf = xxmlBufferCreate();
- writer = xxmlNewTextWriterMemory(buf);
-
- xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes");
- xxmlTextWriterStartElement(writer, "case");
- xxmlTextWriterWriteAttribute(writer, "xmlns",
- "http://www.redhat.com/gss/strata");
-
- xxmlTextWriterWriteElement(writer, "summary", summary);
- xxmlTextWriterWriteElement(writer, "description", description);
- if (product) {
- xxmlTextWriterWriteElement(writer, "product", product);
- }
- if (version) {
- xxmlTextWriterWriteElement(writer, "version", version);
- }
- if (component) {
- xxmlTextWriterWriteElement(writer, "component", component);
- }
-
- xxmlTextWriterEndDocument(writer);
- retval = xstrdup((const char*)buf->content);
- xmlFreeTextWriter(writer);
- xmlBufferFree(buf);
- return retval;
-}
-
-#if 0 //unused
-static char*
-make_response(const char* title, const char* body,
- const char* actualURL, const char* displayURL)
-{
- char* retval;
- xmlTextWriterPtr writer;
- xmlBufferPtr buf;
-
- buf = xxmlBufferCreate();
- writer = xxmlNewTextWriterMemory(buf);
-
- xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes");
- xxmlTextWriterStartElement(writer, "response");
- if (title) {
- xxmlTextWriterWriteElement(writer, "title", title);
- }
- if (body) {
- xxmlTextWriterWriteElement(writer, "body", body);
- }
- if (actualURL || displayURL) {
- xxmlTextWriterStartElement(writer, "URL");
- if (actualURL) {
- xxmlTextWriterWriteAttribute(writer, "href", actualURL);
- }
- if (displayURL) {
- xxmlTextWriterWriteString(writer, displayURL);
- }
- }
-
- xxmlTextWriterEndDocument(writer);
- retval = xstrdup((const char*)buf->content);
- xmlFreeTextWriter(writer);
- xmlBufferFree(buf);
- return retval;
-}
-//Example:
-//<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-//<response><title>Case Created and Report Attached</title><body></body><URL href="http://support-services-devel.gss.redhat.com:8080/Strata/cases/00005129/attachments/ccbf3e65-b941-3db7-a016-6a3831691a32">New Case URL</URL></response>
-#endif
-
-char*
-send_report_to_new_case(const char* baseURL,
- const char* username,
- const char* password,
- bool ssl_verify,
- const char* summary,
- const char* description,
- const char* component,
- const char* report_file_name)
-{
- char *case_url = concat_path_file(baseURL, "/cases");
-
- char *case_data = make_case_data(summary, description,
- "Red Hat Enterprise Linux", "6.0",
- component);
-
- int redirect_count = 0;
- char *errmsg;
- char *allocated = NULL;
- char* retval = NULL;
- abrt_post_state_t *case_state;
-
- redirect_case:
- case_state = new_abrt_post_state(0
- + ABRT_POST_WANT_HEADERS
- + ABRT_POST_WANT_BODY
- + ABRT_POST_WANT_ERROR_MSG
- + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0)
- );
- case_state->username = username;
- case_state->password = password;
- abrt_post_string(case_state, case_url, "application/xml", case_data);
-
- char *case_location = find_header_in_abrt_post_state(case_state, "Location:");
- switch (case_state->http_resp_code)
- {
- case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */
- case 302: /* "302 Found" (just in case) */
- case 305: /* "305 Use Proxy" */
- if (++redirect_count < 10 && case_location)
- {
- free(case_url);
- case_url = xstrdup(case_location);
- free_abrt_post_state(case_state);
- goto redirect_case;
- }
- goto bad_resp_code;
-
- case 404:
- /* Not strictly necessary, but makes this typical error less cryptic:
- * instead of returning html-encoded body, we show short concise message,
- * and show offending URL (typos in which is a typical cause) */
- retval = xasprintf("error in case creation, "
- "HTTP code: 404 (Not found), URL:'%s'", case_url);
- break;
-
- default:
- bad_resp_code:
- errmsg = case_state->curl_error_msg;
- if (errmsg)
- retval = xasprintf("error in case creation: %s", errmsg);
- else
- {
- errmsg = find_header_in_abrt_post_state(case_state, "Strata-Message:");
- if ((!errmsg || !errmsg[0]) && case_state->body && case_state->body[0])
- errmsg = case_state->body;
- if (errmsg)
- retval = xasprintf("error in case creation, HTTP code: %d, server says: '%s'",
- case_state->http_resp_code, errmsg);
- else
- retval = xasprintf("error in case creation, HTTP code: %d",
- case_state->http_resp_code);
- }
- break;
-
- case 200:
- case 201: {
- if (!case_location) {
- /* Case Creation returned valid code, but no location */
- retval = xasprintf("error in case creation: no Location URL, HTTP code: %d",
- case_state->http_resp_code);
- break;
- }
-
- char *atch_url = concat_path_file(case_location, "/attachments");
- abrt_post_state_t *atch_state;
- redirect_attach:
- atch_state = new_abrt_post_state(0
- + ABRT_POST_WANT_HEADERS
- + ABRT_POST_WANT_BODY
- + ABRT_POST_WANT_ERROR_MSG
- + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0)
- );
- atch_state->username = username;
- atch_state->password = password;
- abrt_post_file_as_form(atch_state, atch_url, "application/binary", report_file_name);
-
- char *atch_location = find_header_in_abrt_post_state(atch_state, "Location:");
- switch (atch_state->http_resp_code)
- {
- case 305: /* "305 Use Proxy" */
- if (++redirect_count < 10 && atch_location)
- {
- free(atch_url);
- atch_url = xstrdup(atch_location);
- free_abrt_post_state(atch_state);
- goto redirect_attach;
- }
- /* fall through */
-
- default:
- /* Case Creation Succeeded, attachement FAILED */
- errmsg = find_header_in_abrt_post_state(atch_state, "Strata-Message:");
- if (!errmsg || !errmsg[0])
- errmsg = atch_state->curl_error_msg;
- if (atch_state->body && atch_state->body[0])
- {
- if (errmsg && errmsg[0]
- && strcmp(errmsg, atch_state->body) != 0
- ) /* both strata/curl error and body are present (and aren't the same) */
- allocated = errmsg = xasprintf("%s. %s",
- atch_state->body,
- errmsg);
- else /* only body exists */
- errmsg = atch_state->body;
- }
- /* Note: to prevent URL misparsing, make sure to delimit
- * case_location only using spaces */
- retval = xasprintf("Case created: %s but report attachment failed (HTTP code %d)%s%s",
- case_location,
- atch_state->http_resp_code,
- errmsg ? ": " : "",
- errmsg ? errmsg : ""
- );
- break;
-
- case 200:
- case 201:
- // unused
- //char *body = atch_state->body;
- //if (case_state->body && case_state->body[0])
- //{
- // body = case_state->body;
- // if (atch_state->body && atch_state->body[0])
- // allocated = body = xasprintf("%s\n%s",
- // case_state->body,
- // atch_state->body);
- //}
- retval = xasprintf("Case created: %s", /*body,*/ case_location);
- } /* switch (attach HTTP code) */
-
- free_abrt_post_state(atch_state);
- free(atch_url);
- } /* case 200/201 */
-
- } /* switch (case HTTP code) */
-
- free_abrt_post_state(case_state);
- free(allocated);
- free(case_url);
- return retval;
-}
diff --git a/src/daemon/abrt_rh_support.h b/src/daemon/abrt_rh_support.h
deleted file mode 100644
index db6e9cd7..00000000
--- a/src/daemon/abrt_rh_support.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- 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.
-*/
-#ifndef ABRT_RH_SUPPORT_H_
-#define ABRT_RH_SUPPORT_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct reportfile reportfile_t;
-
-reportfile_t *new_reportfile(void);
-void reportfile_free(reportfile_t* file);
-
-void reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value);
-void reportfile_add_binding_from_namedfile(reportfile_t* file,
- const char* on_disk_filename, /* unused so far */
- const char* binding_name,
- const char* recorded_filename,
- int isbinary);
-
-const char* reportfile_as_string(reportfile_t* file);
-
-char* post_signature(const char* baseURL, bool ssl_verify, const char* signature);
-char*
-send_report_to_new_case(const char* baseURL,
- const char* username,
- const char* password,
- bool ssl_verify,
- const char* summary,
- const char* description,
- const char* component,
- const char* report_file_name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif