summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--src/plugins/Makefile.am25
-rw-r--r--src/plugins/abrt-retrace-client.c243
3 files changed, 267 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index f1b08889..6aa95607 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
AC_INIT([abrt], [1.2.0], [crash-catcher@fedorahosted.org])
AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([-Wall -Werror foreign silent-rules])
+AM_INIT_AUTOMAKE([-Wall foreign silent-rules])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
AC_ARG_ENABLE(debug,
@@ -17,7 +17,7 @@ AC_SYS_LARGEFILE
CXXFLAGS="$CXXFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
-D_FILE_OFFSET_BITS=64 -fno-strict-aliasing "
CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
- -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing -std=gnu99 -Wall"
+ -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing -std=gnu99"
dnl ****** INTERNATIONALIZATION **********************
GETTEXT_PACKAGE=abrt
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index a7790e71..c7d8c1f7 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -74,7 +74,8 @@ libexec_PROGRAMS = \
abrt-action-kerneloops \
abrt-action-upload \
abrt-action-mailx \
- abrt-action-print
+ abrt-action-print \
+ abrt-retrace-client
abrt_action_analyze_c_SOURCES = \
abrt-action-analyze-c.c
@@ -186,8 +187,7 @@ abrt_action_rhtsupport_CPPFLAGS = \
-DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
$(GLIB_CFLAGS) \
$(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \
- -D_GNU_SOURCE \
- -Wall -Werror
+ -D_GNU_SOURCE
abrt_action_rhtsupport_LDFLAGS = -ltar
abrt_action_rhtsupport_LDADD = \
$(GLIB_LIBS) \
@@ -279,4 +279,23 @@ abrt_action_print_CPPFLAGS = \
abrt_action_print_LDADD = \
../lib/libabrt.la
+abrt_retrace_client_SOURCES = \
+ abrt-retrace-client.c
+abrt_retrace_client_CPPFLAGS = \
+ -I$(srcdir)/../include \
+ -I$(srcdir)/../lib \
+ -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_retrace_client_LDADD = \
+ ../lib/libabrt.la \
+ ../btparser/libbtparser.la
+
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
diff --git a/src/plugins/abrt-retrace-client.c b/src/plugins/abrt-retrace-client.c
new file mode 100644
index 00000000..834c22d3
--- /dev/null
+++ b/src/plugins/abrt-retrace-client.c
@@ -0,0 +1,243 @@
+/*
+ Copyright (C) 2010 Red Hat, 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.
+
+http://www.mail-archive.com/dev-tech-crypto@lists.mozilla.org/msg01921.html
+*/
+#include "abrtlib.h"
+#include "parse_options.h"
+#include <nspr.h>
+#include <nss.h>
+#include <pk11pub.h>
+#include <ssl.h>
+#include <sslproto.h>
+
+static const char *dump_dir_name = ".";
+static const char abrt_retrace_client_usage[] = "abrt-retrace-client [options] -d DIR";
+
+enum {
+ OPT_v = 1 << 0,
+ OPT_d = 1 << 1,
+ OPT_s = 1 << 2,
+};
+
+/* Keep enum above and order of options below in sync! */
+static struct options abrt_retrace_client_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()
+};
+
+void add_if_exists(struct dump_dir *dd,
+ const char *name,
+ const char *args[],
+ int *argindex)
+{
+ if (dd_exist(dd, name))
+ {
+ args[*argindex] = name;
+ *argindex += 1;
+ }
+}
+
+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_retrace_client_options,
+ abrt_retrace_client_usage);
+
+ 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;
+
+ const char *args[10];
+ args[0] = "tar";
+ args[1] = "cJvO";
+ int argindex = 2;
+ args[argindex++] = xasprintf("--directory=%s", dump_dir_name);
+ args[argindex++] = FILENAME_COREDUMP;
+ add_if_exists(dd, FILENAME_ANALYZER, args, &argindex);
+ add_if_exists(dd, FILENAME_ARCHITECTURE, args, &argindex);
+ add_if_exists(dd, FILENAME_EXECUTABLE, args, &argindex);
+ add_if_exists(dd, FILENAME_PACKAGE, args, &argindex);
+ add_if_exists(dd, FILENAME_RELEASE, args, &argindex);
+ args[argindex] = NULL;
+
+ int tempfd = mkstemp("/tmp/abrt-retrace-client-archive.tar.xz.XXXXXX");
+ if (tempfd == -1)
+ perror_msg_and_die("Cannot open temporary file");
+
+ int flags = EXECFLG_INPUT_NUL | EXECFLG_OUTPUT;
+ int pipeout[2];
+ pid_t child = fork_execv_on_steroids(flags, (char**)args,
+ pipeout, NULL, NULL, 0);
+
+ while (1)
+ {
+ struct pollfd pfd;
+ pfd.fd = pipeout[0];
+ pfd.events = POLLIN;
+ poll(&pfd, 1, 1000);
+
+ char buf[32768];
+ int r = read(pipeout[0], buf, sizeof(buf));
+ if (r <= 0)
+ {
+ if (r == -1)
+ {
+ if (EINTR == errno || EAGAIN == errno || EWOULDBLOCK == errno)
+ continue;
+ perror_msg_and_die("Failed to read from a pipe");
+ }
+ break;
+ }
+
+ int w = 0;
+ while (r)
+ {
+ w += write(tempfd, buf + w, r);
+ if (w == -1)
+ {
+ if (EINTR == errno)
+ continue;
+
+ perror_msg_and_die("Failed to write to a temp file");
+ }
+ if (w < r)
+ {
+ r -= w;
+ continue;
+ }
+ }
+ }
+
+ close(pipeout[0]);
+ close(tempfd);
+
+ /* Prevent having zombie child process, and maybe collect status
+ * (note that status == NULL is ok too) */
+ int status;
+ waitpid(child, &status, 0);
+ free((void*)args[2]);
+
+ dd_close(dd);
+
+
+ /* Upload the archive. */
+#define HOST "coding.debuntu.org"
+#define PAGE "/"
+#define PORT 443
+#define USERAGENT "HTMLGET 1.0"
+
+ NSS_Init("path");
+ PRFileDesc *tcp_sock = PR_NewTCPSocket();
+ if (!sock)
+ error_msg_and_die("Failed to create a TCP socket");
+
+ PRSocketOptionData sock_option;
+ sock_option.option = PR_SockOpt_Nonblocking;
+ sock_option.value.non_blocking = PR_FALSE;
+
+ PRStatus pr_status = PR_SetSocketOption(tcp_sock, &sock_option);
+ if (PR_SUCCESS != pr_status)
+ {
+ PR_Close(tcp_sock);
+ error_msg_and_die("Failed to set socket blocking mode.");
+ }
+
+ PRFileDesc *ssl_sock = SSL_ImportFD(NULL, tcp_sock);
+ if (!ssl_sock)
+ {
+ PR_Close(tcp_sock);
+ error_msg_and_die("Failed to wrap TCP socket by SSL");
+ }
+
+ SECStatus sec_status = SSL_OptionSet(ssl_sock, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
+ if (SECSuccess != sec_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to enable client handshake to SSL socket.");
+ }
+
+ sec_status = SSL_OptionSet(ssl_sock, SSL_ENABLE_FDX, PR_TRUE);
+ if (SECSuccess != sec_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to set full duplex to SSL socket.");
+ }
+
+ sec_status = SSL_SetURL(ssl_sock, HOST);
+ if (SECSuccess != sec_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to set URL to SSL socket.");
+ }
+
+ char buffer[256];
+ PRHostEnt host_entry;
+ pr_status = PR_GetHostByName(HOST, buffer, sizeof(buffer), &host_entry);
+ if (PR_SUCCESS != pr_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to get host by name.");
+ }
+
+ PRNetAddr addr;
+ PRInt32 rv = PR_EnumerateHostEnt(0, &host_entry, PORT, &addr);
+ if (rv < 0)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to enumerate host ent.");
+ }
+
+ pr_status = PR_Connect(ssl_sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+ if (PR_SUCCESS != pr_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to connect SSL address");
+ }
+
+ sec_status = SSL_ResetHandshake(ssl_sock, PR_FALSE);
+ if (SECSuccess != sec_status)
+ {
+ PR_Close(ssl_sock);
+ error_msg_and_die("Failed to reset handshake.");
+ }
+
+ pr_status = PR_Close(ssl_sock);
+ if (PR_SUCCESS != pr_status)
+ error_msg("Failed to close SSL socket.");
+
+ SSL_ClearSessionCache();
+
+ sec_status = NSS_Shutdown();
+ if (SECSuccess != sec_status)
+ error_msg("Failed to shutdown NSS.");
+
+ PR_Cleanup();
+
+ return 0;
+}