summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/abrt-retrace-client.c161
1 files changed, 76 insertions, 85 deletions
diff --git a/src/plugins/abrt-retrace-client.c b/src/plugins/abrt-retrace-client.c
index 5b012274..20e008a5 100644
--- a/src/plugins/abrt-retrace-client.c
+++ b/src/plugins/abrt-retrace-client.c
@@ -29,8 +29,8 @@
static const char *dump_dir_name = NULL;
static const char *coredump = NULL;
static const char *url = "retrace01.fedoraproject.org";
-static const char *task_id = NULL;
-static const char *task_password = NULL;
+static bool ssl_allow_insecure = false;
+static bool http_show_headers = false;
/* Add an entry name to the args array if the entry name exists in a
* dump directory. The entry is added to argindex offset to the array,
@@ -51,7 +51,7 @@ static void args_add_if_exists(const char *args[],
/* Create an archive with files required for retrace server and return
* a file descriptor. Returns -1 if it fails.
*/
-static int create_archive(const char *dump_dir_name, bool unlink_temp)
+static int create_archive(bool unlink_temp)
{
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
@@ -145,7 +145,6 @@ static SECStatus ssl_bad_cert_handler(void *arg, PRFileDesc *sock)
char *target_host = SSL_RevealURL(sock);
if (!target_host)
target_host = xstrdup("(unknown)");
- bool allow_insecure = (bool)arg;
switch (err)
{
case SEC_ERROR_CA_CERT_INVALID:
@@ -170,7 +169,7 @@ static SECStatus ssl_bad_cert_handler(void *arg, PRFileDesc *sock)
break;
}
PR_Free(target_host);
- return allow_insecure ? SECSuccess : SECFailure;
+ return ssl_allow_insecure ? SECSuccess : SECFailure;
}
static SECStatus ssl_handshake_callback(PRFileDesc *sock, void *arg)
@@ -202,10 +201,8 @@ static char *ssl_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
return NULL;
}
-static void ssl_connect(const char *host,
- PRFileDesc **tcp_sock,
- PRFileDesc **ssl_sock,
- bool allow_insecure)
+static void ssl_connect(PRFileDesc **tcp_sock,
+ PRFileDesc **ssl_sock)
{
const char *configdir = ssl_get_configdir();
if (configdir)
@@ -244,7 +241,7 @@ static void ssl_connect(const char *host,
error_msg_and_die("Failed to enable client handshake to SSL socket.");
if (SECSuccess != SSL_OptionSet(*ssl_sock, SSL_ENABLE_TLS, PR_TRUE))
error_msg_and_die("Failed to enable client handshake to SSL socket.");
- sec_status = SSL_SetURL(*ssl_sock, host);
+ sec_status = SSL_SetURL(*ssl_sock, url);
if (SECSuccess != sec_status)
{
PR_Close(*ssl_sock);
@@ -252,7 +249,7 @@ static void ssl_connect(const char *host,
}
char buffer[PR_NETDB_BUF_SIZE];
PRHostEnt host_entry;
- pr_status = PR_GetHostByName(host, buffer, sizeof(buffer), &host_entry);
+ pr_status = PR_GetHostByName(url, buffer, sizeof(buffer), &host_entry);
if (PR_SUCCESS != pr_status)
{
char *error = xmalloc(PR_GetErrorTextLength());
@@ -281,7 +278,7 @@ static void ssl_connect(const char *host,
}
if (SECSuccess != SSL_BadCertHook(*ssl_sock,
(SSLBadCertHandler)ssl_bad_cert_handler,
- (void*)allow_insecure))
+ NULL))
{
PR_Close(*ssl_sock);
error_msg_and_die("Failed to set certificate hook.");
@@ -403,22 +400,18 @@ static char *tcp_read_response(PRFileDesc *tcp_sock)
return strbuf_free_nobuf(strbuf);
}
-static int create(const char *dump_dir,
- const char *coredump,
- bool ssl_allow_insecure,
- bool delete_temp_archive,
- bool http_show_headers,
+static int create(bool delete_temp_archive,
char **task_id,
char **task_password)
{
- int tempfd = create_archive(dump_dir_name, delete_temp_archive);
+ int tempfd = create_archive(delete_temp_archive);
if (-1 == tempfd)
return 1;
/* Get the file size. */
struct stat tempfd_buf;
fstat(tempfd, &tempfd_buf);
PRFileDesc *tcp_sock, *ssl_sock;
- ssl_connect(url, &tcp_sock, &ssl_sock, ssl_allow_insecure);
+ ssl_connect(&tcp_sock, &ssl_sock);
/* Upload the archive. */
struct strbuf *http_request = strbuf_new();
strbuf_append_strf(http_request,
@@ -486,29 +479,24 @@ static int create(const char *dump_dir,
return result;
}
-static int run_create(const char *dump_dir,
- const char *coredump,
- bool ssl_allow_insecure,
- bool delete_temp_archive,
- bool http_show_headers)
+static int run_create(bool delete_temp_archive)
{
char *task_id, *task_password;
- int result = create(dump_dir, coredump, ssl_allow_insecure, delete_temp_archive,
- http_show_headers, &task_id, &task_password);
+ int result = create(delete_temp_archive, &task_id, &task_password);
+ if (0 != result)
+ return result;
printf("Task Id: %s\nTask Password: %s\n", task_id, task_password);
free(task_id);
free(task_password);
- return result;
+ return 0;
}
static void status(const char *task_id,
const char *task_password,
- bool ssl_allow_insecure,
- bool http_show_headers,
char **task_status)
{
PRFileDesc *tcp_sock, *ssl_sock;
- ssl_connect(url, &tcp_sock, &ssl_sock, ssl_allow_insecure);
+ ssl_connect(&tcp_sock, &ssl_sock);
struct strbuf *http_request = strbuf_new();
strbuf_append_strf(http_request,
"GET /%s HTTP/1.1\r\n"
@@ -542,26 +530,19 @@ static void status(const char *task_id,
ssl_disconnect(ssl_sock);
}
-static void run_status(const char *task_id,
- const char *task_password,
- bool ssl_allow_insecure,
- bool http_show_headers)
+static void run_status(const char *task_id, const char *task_password)
{
char *task_status;
- status(task_id, task_password, ssl_allow_insecure,
- http_show_headers, &task_status);
+ status(task_id, task_password, &task_status);
printf("Task Status: %s\n", task_status);
free(task_status);
}
-static int run_backtrace(const char *task_id,
- const char *task_password,
- bool ssl_allow_insecure,
- bool http_show_headers)
+static void backtrace(const char *task_id, const char *task_password,
+ char **backtrace)
{
PRFileDesc *tcp_sock, *ssl_sock;
- ssl_connect(url, &tcp_sock, &ssl_sock,
- ssl_allow_insecure);
+ ssl_connect(&tcp_sock, &ssl_sock);
struct strbuf *http_request = strbuf_new();
strbuf_append_strf(http_request,
"GET /%s/backtrace HTTP/1.1\r\n"
@@ -591,25 +572,34 @@ static int run_backtrace(const char *task_id,
char *headers_end = strstr(http_response, "\r\n\r\n");
if (!headers_end)
error_msg_and_die("Invalid response from server: missing HTTP message body.");
- for (char *c = headers_end + 4; *c; ++c)
+ int length = strlen(http_response) + (headers_end - http_response) + strlen("\r\n\r\n");
+ /* Slightly more space than needed might be allocated, because
+ * '\r' characters are not copied to the backtrace. */
+ *backtrace = xmalloc(length);
+ char *b = *backtrace;
+ for (char *c = headers_end + strlen("\r\n\r\n"); *c; ++c)
{
if (*c == '\r')
continue;
- putc(*c, stdout);
+ *b = *c;
+ ++b;
}
free(http_response);
ssl_disconnect(ssl_sock);
- return 0;
}
-static int run_log(const char *task_id,
- const char *task_password,
- bool ssl_allow_insecure,
- bool http_show_headers)
+static void run_backtrace(const char *task_id, const char *task_password)
+{
+ char *backtrace_text;
+ backtrace(task_id, task_password, &backtrace_text);
+ printf("%s", backtrace_text);
+ free(backtrace_text);
+}
+
+static void run_log(const char *task_id, const char *task_password)
{
PRFileDesc *tcp_sock, *ssl_sock;
- ssl_connect(url, &tcp_sock, &ssl_sock,
- ssl_allow_insecure);
+ ssl_connect(&tcp_sock, &ssl_sock);
struct strbuf *http_request = strbuf_new();
strbuf_append_strf(http_request,
"GET /%s/log HTTP/1.1\r\n"
@@ -647,59 +637,63 @@ static int run_log(const char *task_id,
}
free(http_response);
ssl_disconnect(ssl_sock);
- return 0;
}
-
-static int run_batch(const char *dump_dir,
- const char *coredump,
- bool ssl_allow_insecure,
- bool delete_temp_archive,
- bool http_show_headers)
+static int run_batch(bool delete_temp_archive)
{
char *task_id, *task_password;
- int retcode = create(dump_dir, coredump, ssl_allow_insecure,
- delete_temp_archive, http_show_headers,
- &task_id, &task_password);
+ int retcode = create(delete_temp_archive, &task_id, &task_password);
if (0 != retcode)
return retcode;
char *task_status = xstrdup("");
while (0 != strncmp(task_status, "FINISHED", strlen("finished")))
{
free(task_status);
- status(task_id, task_password, ssl_allow_insecure,
- http_show_headers, &task_status);
+ status(task_id, task_password, &task_status);
puts(task_status);
}
if (0 == strcmp(task_status, "FINISHED_SUCCESS"))
{
- retcode = run_backtrace(task_id, task_password,
- ssl_allow_insecure, http_show_headers);
+ char *backtrace_text;
+ backtrace(task_id, task_password, &backtrace_text);
+ if (dump_dir_name)
+ {
+ char *backtrace_path = xasprintf("%s/backtrace", dump_dir_name);
+ int backtrace_fd = xopen3(backtrace_path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
+ xwrite(backtrace_fd, backtrace_text, strlen(backtrace_text));
+ close(backtrace_fd);
+ free(backtrace_path);
+ }
+ else
+ printf("%s", backtrace_text);
+ free(backtrace_text);
}
else
- {
- retcode = run_log(task_id, task_password, ssl_allow_insecure,
- http_show_headers);
- }
+ run_log(task_id, task_password);
free(task_status);
free(task_id);
free(task_password);
- return retcode;
+ return 0;
}
int main(int argc, char **argv)
{
+ const char *task_id = NULL;
+ const char *task_password = NULL;
+
enum {
OPT_verbose = 1 << 0,
OPT_syslog = 1 << 1,
OPT_insecure = 1 << 2,
OPT_url = 1 << 3,
OPT_headers = 1 << 4,
- OPT_dir = 1 << 5,
- OPT_core = 1 << 6,
- OPT_no_unlink = 1 << 7,
- OPT_task = 1 << 8,
- OPT_password = 1 << 9
+ OPT_group_1 = 1 << 5,
+ OPT_dir = 1 << 6,
+ OPT_core = 1 << 7,
+ OPT_no_unlink = 1 << 8,
+ OPT_group_2 = 1 << 9,
+ OPT_task = 1 << 10,
+ OPT_password = 1 << 11
};
/* Keep enum above and order of options below in sync! */
@@ -745,19 +739,19 @@ int main(int argc, char **argv)
operation = argv[optind];
else
show_usage_and_die(usage, options);
+ ssl_allow_insecure = opts & OPT_insecure;
+ http_show_headers = opts & OPT_headers;
if (0 == strcasecmp(operation, "create"))
{
if (!dump_dir_name && !coredump)
error_msg_and_die("Either dump directory or coredump is needed.");
- return run_create(dump_dir_name, coredump, opts & OPT_insecure,
- opts & OPT_no_unlink, opts & OPT_headers);
+ return run_create(0 == (opts & OPT_no_unlink));
}
else if (0 == strcasecmp(operation, "batch"))
{
if (!dump_dir_name && !coredump)
error_msg_and_die("Either dump directory or coredump is needed.");
- return run_batch(dump_dir_name, coredump, opts & OPT_insecure,
- opts & OPT_no_unlink, opts & OPT_headers);
+ return run_batch(0 == (opts & OPT_no_unlink));
}
else if (0 == strcasecmp(operation, "status"))
{
@@ -765,8 +759,7 @@ int main(int argc, char **argv)
error_msg_and_die("Task id is needed.");
if (!task_password)
error_msg_and_die("Task password is needed.");
- run_status(task_id, task_password, opts & OPT_insecure,
- opts & OPT_headers);
+ run_status(task_id, task_password);
}
else if (0 == strcasecmp(operation, "backtrace"))
{
@@ -774,8 +767,7 @@ int main(int argc, char **argv)
error_msg_and_die("Task id is needed.");
if (!task_password)
error_msg_and_die("Task password is needed.");
- return run_backtrace(task_id, task_password, opts & OPT_insecure,
- opts & OPT_headers);
+ run_backtrace(task_id, task_password);
}
else if (0 == strcasecmp(operation, "log"))
{
@@ -783,8 +775,7 @@ int main(int argc, char **argv)
error_msg_and_die("Task id is needed.");
if (!task_password)
error_msg_and_die("Task password is needed.");
- return run_log(task_id, task_password, opts & OPT_insecure,
- opts & OPT_headers);
+ run_log(task_id, task_password);
}
else
error_msg_and_die("Unknown operation: %s", operation);