use dd_{add,rm}_attachments_file() to add or remove file to attach.
Signed-off-by: Nikola Pajkovsky npajkovs@redhat.com --- src/include/report/dump_dir.h | 1 + src/lib/dump_dir.c | 37 +++++++++ src/plugins/abrt-action-bugzilla.cpp | 104 ++++++++++++++++++-------- src/plugins/abrt-action-generate-backtrace.c | 1 + 4 files changed, 111 insertions(+), 32 deletions(-)
diff --git a/src/include/report/dump_dir.h b/src/include/report/dump_dir.h index a41b700..0fd9c20 100644 --- a/src/include/report/dump_dir.h +++ b/src/include/report/dump_dir.h @@ -59,6 +59,7 @@ void dd_save_text(struct dump_dir *dd, const char *name, const char *data); void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size); void dd_delete(struct dump_dir *dd); char **dd_get_unknown_files(struct dump_dir *dd, const char **known_files); +char **dd_load_attachments_name(const struct dump_dir *dd); void dd_add_attachments_name(struct dump_dir *dd, const char *name); void dd_rm_attachments_name(struct dump_dir *dd, const char *name);
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c index 5537002..bf71dfd 100644 --- a/src/lib/dump_dir.c +++ b/src/lib/dump_dir.c @@ -610,6 +610,43 @@ void dd_rm_attachments_name(struct dump_dir *dd, const char *name) strbuf_free(list); free(attach_list); } + +/* + * read entire 'attachments' file + * return NULL if fail or char** (malloc'ed) array on success + */ +char **dd_load_attachments_name(const struct dump_dir *dd) +{ + if (!dd->locked) + error_msg_and_die("dump_dir is not opened"); /* bug */ + + char *attach_list = dd_load_text_ext(dd, "attachments", + DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); + if (!attach_list) + return NULL; + + unsigned size = 16; + unsigned idx = 0; + char **attachments = xzalloc(sizeof(char*) * size); + + char *token = strtok(attach_list, "\n"); + while (token) + { + if (idx + 1 >= size) + { + size *= 2; + attachments = xrealloc(attachments, sizeof(char*) * size); + } + + attachments[idx++] = token; + token = strtok(NULL, "\n"); + } + + attachments[idx] = NULL; + + return attachments; +} + /* Utility function */ void delete_dump_dir(const char *dd_dir) { diff --git a/src/plugins/abrt-action-bugzilla.cpp b/src/plugins/abrt-action-bugzilla.cpp index 19acc4f..28487f3 100644 --- a/src/plugins/abrt-action-bugzilla.cpp +++ b/src/plugins/abrt-action-bugzilla.cpp @@ -112,7 +112,7 @@ struct ctx: public abrt_xmlrpc_conn { 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(crash_data_t *crash_data, int depend_on_bugno); - int add_attachments(const char* bug_id_str, crash_data_t *crash_data); + int add_attachments(const char* bug_id_str, char **att_name, char **att_body); 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);
@@ -533,35 +533,29 @@ xmlrpc_int32 ctx::new_bug(crash_data_t *crash_data, int depend_on_bugno) return bug_id; }
-int ctx::add_attachments(const char* bug_id_str, crash_data_t *crash_data) +int ctx::add_attachments(const char* bug_id_str, char **att_name, char **att_body) { - GHashTableIter iter; - char *name; - struct crash_item *value; - g_hash_table_iter_init(&iter, crash_data); - while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) + for ( ; *att_name; att_name++, att_body++) { - const char *content = value->content; - - if ((value->flags & CD_FLAG_TXT) - && (strlen(content) > CD_TEXT_ATT_SIZE || (strcmp(name, FILENAME_BACKTRACE) == 0)) - ) { - char *encoded64 = encode_base64(content, strlen(content)); - char *filename = xasprintf("File: %s", name); - xmlrpc_value* result = call("bugzilla.addAttachment", "(s{s:s,s:s,s:s,s:s})", bug_id_str, - "description", filename, - "filename", name, - "contenttype", "text/plain", - "data", encoded64 - ); - free(encoded64); - free(filename); - if (!result) - return -1; + if (!att_body && !*att_body) + continue; + + char *encoded64 = encode_base64(*att_body, strlen(*att_body)); + char *filename = xasprintf("File: %s", *att_name); + xmlrpc_value* result = call("bugzilla.addAttachment", "(s{s:s,s:s,s:s,s:s})", bug_id_str, + "description", filename, + "filename", *att_name, + "contenttype", "text/plain", + "data", encoded64 + ); + free(encoded64); + free(filename); + if (!result) + return -1;
- xmlrpc_DECREF(result); - } + xmlrpc_DECREF(result); } + return 0; }
@@ -640,6 +634,32 @@ static void report_to_bugzilla( if (!dd) xfunc_die(); /* dd_opendir already emitted error msg */ crash_data_t *crash_data = load_crash_data_from_dump_dir(dd); + + char **att_name = NULL; + unsigned size = 16; + unsigned idx = 0; + char **att_body = NULL; + + att_name = dd_load_attachments_name(dd); + if (!att_name) + goto skip_attachments; + + att_body = (char **)xzalloc(sizeof(char*) * size); + for (unsigned ii = 0; att_name[ii]; ++ii) + { + if (idx + 1 >= size) + { + size *= 2; + att_body = (char **)xrealloc(att_body, sizeof(char*) * size); + } + + char *body = dd_load_text_ext(dd, *att_name, + DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); + + att_body[ii] = body; + } + +skip_attachments: dd_close(dd);
const char *env; @@ -774,13 +794,24 @@ static void report_to_bugzilla( error_msg_and_die(_("Bugzilla entry creation failed")); }
- log("Adding attachments to bug %ld...", (long)bug_id); - char bug_id_str[sizeof(long)*3 + 2]; - sprintf(bug_id_str, "%ld", (long) bug_id); - int ret = bz_server.add_attachments(bug_id_str, crash_data); - if (ret == -1) + if (att_name && *att_name + && att_body && *att_body) { - throw_if_xml_fault_occurred(&bz_server.env); + log("Adding attachments to bug %ld...", (long)bug_id); + char bug_id_str[sizeof(long)*3 + 2]; + sprintf(bug_id_str, "%ld", (long) bug_id); + int ret = bz_server.add_attachments(bug_id_str, att_name, att_body); + + for ( ; att_name; att_name++, att_body++) + { + free(*att_name); + free(*att_body); + } + + if (ret == -1) + { + throw_if_xml_fault_occurred(&bz_server.env); + } }
log(_("Logging out...")); @@ -893,6 +924,15 @@ static void report_to_bugzilla(
free_crash_data(crash_data); bug_info_destroy(&bz); + + if (att_name && *att_name + && att_body && *att_body) + for ( ; att_name; att_name++, att_body++) + { + free(*att_name); + free(*att_body); + } + }
int main(int argc, char **argv) diff --git a/src/plugins/abrt-action-generate-backtrace.c b/src/plugins/abrt-action-generate-backtrace.c index a575a19..c576735 100644 --- a/src/plugins/abrt-action-generate-backtrace.c +++ b/src/plugins/abrt-action-generate-backtrace.c @@ -308,6 +308,7 @@ int main(int argc, char **argv) return 1;
dd_save_text(dd, FILENAME_BACKTRACE, backtrace_str); + dd_add_attachments_name(dd, FILENAME_BACKTRACE);
/* Compute and store backtrace hash. */ struct btp_location location;