From d21897f4ffd15730f750a130a86ffaa210c9c321 Mon Sep 17 00:00:00 2001 From: Johnny Hughes Date: Aug 07 2019 14:05:58 +0000 Subject: Add mantis patch files --- diff --git a/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch b/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch new file mode 100644 index 0000000..5ab0a57 --- /dev/null +++ b/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch @@ -0,0 +1,781 @@ +From ff32b9ee7a7e396e33f1e9aeaa5bafd26ccbb273 Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Thu, 4 Dec 2014 08:45:07 +0100 +Subject: [PATCH 1000/1015] bugzilla: port to Problem Format API + +Related to #303 + +Signed-off-by: Jakub Filak +--- + src/plugins/reporter-bugzilla.c | 691 ++++------------------------------------ + 1 file changed, 59 insertions(+), 632 deletions(-) + +diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c +index fbe7873..9ff3df3 100644 +--- a/src/plugins/reporter-bugzilla.c ++++ b/src/plugins/reporter-bugzilla.c +@@ -17,515 +17,11 @@ + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include "internal_libreport.h" ++#include "problem_report.h" + #include "client.h" + #include "abrt_xmlrpc.h" + #include "rhbz.h" + +-#include +-#include +- +-struct section_t { +- char *name; +- GList *items; +-}; +-typedef struct section_t section_t; +- +- +-/* Utility functions */ +- +-static +-GList* split_string_on_char(const char *str, char ch) +-{ +- GList *list = NULL; +- for (;;) +- { +- const char *delim = strchrnul(str, ch); +- list = g_list_prepend(list, xstrndup(str, delim - str)); +- if (*delim == '\0') +- break; +- str = delim + 1; +- } +- return g_list_reverse(list); +-} +- +-static +-int compare_item_name(const char *lookup, const char *name) +-{ +- if (lookup[0] == '-') +- lookup++; +- else if (strncmp(lookup, "%bare_", 6) == 0) +- lookup += 6; +- return strcmp(lookup, name); +-} +- +-static +-int is_item_name_in_section(const section_t *lookup, const char *name) +-{ +- if (g_list_find_custom(lookup->items, name, (GCompareFunc)compare_item_name)) +- return 0; /* "found it!" */ +- return 1; +-} +- +-static +-bool is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec) +-{ +- return g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_item_name_in_section); +-} +- +-static +-GList* load_bzrep_conf_file(const char *path) +-{ +- FILE *fp = stdin; +- if (strcmp(path, "-") != 0) +- { +- fp = fopen(path, "r"); +- if (!fp) +- return NULL; +- } +- +- GList *sections = NULL; +- +- char *line; +- while ((line = xmalloc_fgetline(fp)) != NULL) +- { +- /* Skip comments */ +- char first = *skip_whitespace(line); +- if (first == '#') +- goto free_line; +- +- /* Handle trailing backslash continuation */ +- check_continuation: ; +- unsigned len = strlen(line); +- if (len && line[len-1] == '\\') +- { +- line[len-1] = '\0'; +- char *next_line = xmalloc_fgetline(fp); +- if (next_line) +- { +- line = append_to_malloced_string(line, next_line); +- free(next_line); +- goto check_continuation; +- } +- } +- +- /* We are reusing line buffer to form temporary +- * "key\0values\0..." in its beginning +- */ +- bool summary_line = false; +- char *value = NULL; +- char *src; +- char *dst; +- for (src = dst = line; *src; src++) +- { +- char c = *src; +- /* did we reach the value list? */ +- if (!value && c == ':' && src[1] == ':') +- { +- *dst++ = '\0'; /* terminate key */ +- src += 2; +- value = dst; /* remember where value starts */ +- summary_line = (strcmp(line, "%summary") == 0); +- if (summary_line) +- { +- value = src; +- break; +- } +- continue; +- } +- /* skip whitespace in value list */ +- if (value && isspace(c)) +- continue; +- *dst++ = c; /* store next key or value char */ +- } +- +- GList *item_list = NULL; +- if (summary_line) +- { +- /* %summary is special */ +- item_list = g_list_append(NULL, xstrdup(skip_whitespace(value))); +- } +- else +- { +- *dst = '\0'; /* terminate value (or key) */ +- if (value) +- item_list = split_string_on_char(value, ','); +- } +- +- section_t *sec = xzalloc(sizeof(*sec)); +- sec->name = xstrdup(line); +- sec->items = item_list; +- sections = g_list_prepend(sections, sec); +- +- free_line: +- free(line); +- } +- +- if (fp != stdin) +- fclose(fp); +- +- return g_list_reverse(sections); +-} +- +- +-/* Summary generation */ +- +-#define MAX_OPT_DEPTH 10 +-static +-char *format_percented_string(const char *str, problem_data_t *pd) +-{ +- size_t old_pos[MAX_OPT_DEPTH] = { 0 }; +- int okay[MAX_OPT_DEPTH] = { 1 }; +- int opt_depth = 1; +- struct strbuf *result = strbuf_new(); +- +- while (*str) { +- switch (*str) { +- default: +- strbuf_append_char(result, *str); +- str++; +- break; +- case '\\': +- if (str[1]) +- str++; +- strbuf_append_char(result, *str); +- str++; +- break; +- case '[': +- if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH) +- { +- old_pos[opt_depth] = result->len; +- okay[opt_depth] = 1; +- opt_depth++; +- str += 2; +- } else { +- strbuf_append_char(result, *str); +- str++; +- } +- break; +- case ']': +- if (str[1] == ']' && opt_depth > 1) +- { +- opt_depth--; +- if (!okay[opt_depth]) +- { +- result->len = old_pos[opt_depth]; +- result->buf[result->len] = '\0'; +- } +- str += 2; +- } else { +- strbuf_append_char(result, *str); +- str++; +- } +- break; +- case '%': ; +- char *nextpercent = strchr(++str, '%'); +- if (!nextpercent) +- { +- error_msg_and_die("Unterminated %%element%%: '%s'", str - 1); +- } +- +- *nextpercent = '\0'; +- const problem_item *item = problem_data_get_item_or_NULL(pd, str); +- *nextpercent = '%'; +- +- if (item && (item->flags & CD_FLAG_TXT)) +- strbuf_append_str(result, item->content); +- else +- okay[opt_depth - 1] = 0; +- str = nextpercent + 1; +- break; +- } +- } +- +- if (opt_depth > 1) +- { +- error_msg_and_die("Unbalanced [[ ]] bracket"); +- } +- +- if (!okay[0]) +- { +- error_msg("Undefined variable outside of [[ ]] bracket"); +- } +- +- return strbuf_free_nobuf(result); +-} +- +-static +-char *create_summary_string(problem_data_t *pd, GList *comment_fmt_spec) +-{ +- GList *l = comment_fmt_spec; +- while (l) +- { +- section_t *sec = l->data; +- l = l->next; +- +- /* Find %summary" */ +- if (strcmp(sec->name, "%summary") != 0) +- continue; +- +- GList *item = sec->items; +- if (!item) +- /* not supposed to happen, there will be at least "" */ +- error_msg_and_die("BUG in %%summary parser"); +- +- const char *str = item->data; +- return format_percented_string(str, pd); +- } +- +- return format_percented_string("%reason%", pd); +-} +- +- +-/* BZ comment generation */ +- +-static +-int append_text(struct strbuf *result, const char *item_name, const char *content, bool print_item_name) +-{ +- char *eol = strchrnul(content, '\n'); +- if (eol[0] == '\0' || eol[1] == '\0') +- { +- /* one-liner */ +- int pad = 16 - (strlen(item_name) + 2); +- if (pad < 0) +- pad = 0; +- if (print_item_name) +- strbuf_append_strf(result, +- eol[0] == '\0' ? "%s: %*s%s\n" : "%s: %*s%s", +- item_name, pad, "", content +- ); +- else +- strbuf_append_strf(result, +- eol[0] == '\0' ? "%s\n" : "%s", +- content +- ); +- } +- else +- { +- /* multi-line item */ +- if (print_item_name) +- strbuf_append_strf(result, "%s:\n", item_name); +- for (;;) +- { +- eol = strchrnul(content, '\n'); +- strbuf_append_strf(result, +- /* For %bare_multiline_item, we don't want to print colons */ +- (print_item_name ? ":%.*s\n" : "%.*s\n"), +- (int)(eol - content), content +- ); +- if (eol[0] == '\0' || eol[1] == '\0') +- break; +- content = eol + 1; +- } +- } +- return 1; +-} +- +-static +-int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name) +-{ +- const problem_item *item = problem_data_get_item_or_NULL(problem_data, +- FILENAME_BACKTRACE); +- if (!item) +- return 0; /* "I did not print anything" */ +- if (!(item->flags & CD_FLAG_TXT)) +- return 0; /* "I did not print anything" */ +- +- char *truncated = NULL; +- +- if (strlen(item->content) >= max_text_size) +- { +- char *error_msg = NULL; +- const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER); +- if (!analyzer) +- return 0; +- +- /* For CCpp crashes, use the GDB-produced backtrace which should be +- * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE +- * by default for CCpp crashes. +- */ +- enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer); +- if (strcmp(analyzer, "CCpp") == 0) +- report_type = SR_REPORT_GDB; +- +- struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type, +- item->content, &error_msg); +- +- if (!backtrace) +- { +- log(_("Can't parse backtrace: %s"), error_msg); +- free(error_msg); +- return 0; +- } +- +- /* Get optimized thread stack trace for 10 top most frames */ +- truncated = sr_stacktrace_to_short_text(backtrace, 10); +- sr_stacktrace_free(backtrace); +- +- if (!truncated) +- { +- log(_("Can't generate stacktrace description (no crash thread?)")); +- return 0; +- } +- } +- +- append_text(result, +- /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE, +- /*content:*/ truncated ? truncated : item->content, +- print_item_name +- ); +- free(truncated); +- return 1; +-} +- +-static +-int append_item(struct strbuf *result, const char *item_name, problem_data_t *pd, GList *comment_fmt_spec) +-{ +- bool print_item_name = (strncmp(item_name, "%bare_", strlen("%bare_")) != 0); +- if (!print_item_name) +- item_name += strlen("%bare_"); +- +- if (item_name[0] != '%') +- { +- struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name); +- if (!item) +- return 0; /* "I did not print anything" */ +- if (!(item->flags & CD_FLAG_TXT)) +- return 0; /* "I did not print anything" */ +- +- char *formatted = problem_item_format(item); +- char *content = formatted ? formatted : item->content; +- append_text(result, item_name, content, print_item_name); +- free(formatted); +- return 1; /* "I printed something" */ +- } +- +- /* Special item name */ +- +- /* Compat with previously-existed ad-hockery: %short_backtrace */ +- if (strcmp(item_name, "%short_backtrace") == 0) +- return append_short_backtrace(result, pd, CD_TEXT_ATT_SIZE_BZ, print_item_name); +- +- /* Compat with previously-existed ad-hockery: %reporter */ +- if (strcmp(item_name, "%reporter") == 0) +- return append_text(result, "reporter", PACKAGE"-"VERSION, print_item_name); +- +- /* %oneline,%multiline,%text */ +- bool oneline = (strcmp(item_name+1, "oneline" ) == 0); +- bool multiline = (strcmp(item_name+1, "multiline") == 0); +- bool text = (strcmp(item_name+1, "text" ) == 0); +- if (!oneline && !multiline && !text) +- { +- log("Unknown or unsupported element specifier '%s'", item_name); +- return 0; /* "I did not print anything" */ +- } +- +- int printed = 0; +- +- /* Iterate over _sorted_ items */ +- GList *sorted_names = g_hash_table_get_keys(pd); +- sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp); +- +- /* %text => do as if %oneline, then repeat as if %multiline */ +- if (text) +- oneline = 1; +- +- again: ; +- GList *l = sorted_names; +- while (l) +- { +- const char *name = l->data; +- l = l->next; +- struct problem_item *item = g_hash_table_lookup(pd, name); +- if (!item) +- continue; /* paranoia, won't happen */ +- +- if (!(item->flags & CD_FLAG_TXT)) +- continue; +- +- if (is_explicit_or_forbidden(name, comment_fmt_spec)) +- continue; +- +- char *formatted = problem_item_format(item); +- char *content = formatted ? formatted : item->content; +- char *eol = strchrnul(content, '\n'); +- bool is_oneline = (eol[0] == '\0' || eol[1] == '\0'); +- if (oneline == is_oneline) +- printed |= append_text(result, name, content, print_item_name); +- free(formatted); +- } +- if (text && oneline) +- { +- /* %text, and we just did %oneline. Repeat as if %multiline */ +- oneline = 0; +- /*multiline = 1; - not checked in fact, so why bother setting? */ +- goto again; +- } +- +- g_list_free(sorted_names); /* names themselves are not freed */ +- +- return printed; +-} +- +-static +-void generate_bz_comment(struct strbuf *result, problem_data_t *pd, GList *comment_fmt_spec) +-{ +- bool last_line_is_empty = true; +- GList *l = comment_fmt_spec; +- while (l) +- { +- section_t *sec = l->data; +- l = l->next; +- +- /* Skip special sections such as "%attach" */ +- if (sec->name[0] == '%') +- continue; +- +- if (sec->items) +- { +- /* "Text: item[,item]..." */ +- struct strbuf *output = strbuf_new(); +- GList *item = sec->items; +- while (item) +- { +- const char *str = item->data; +- item = item->next; +- if (str[0] == '-') /* "-name", ignore it */ +- continue; +- append_item(output, str, pd, comment_fmt_spec); +- } +- +- if (output->len != 0) +- { +- strbuf_append_strf(result, +- sec->name[0] ? "%s:\n%s" : "%s%s", +- sec->name, +- output->buf +- ); +- last_line_is_empty = false; +- } +- strbuf_free(output); +- } +- else +- { +- /* Just "Text" (can be "") */ +- +- /* Filter out consecutive empty lines */ +- if (sec->name[0] != '\0' || !last_line_is_empty) +- strbuf_append_strf(result, "%s\n", sec->name); +- last_line_is_empty = (sec->name[0] == '\0'); +- } +- } +- +- /* Nuke any trailing empty lines */ +- while (result->len >= 1 +- && result->buf[result->len-1] == '\n' +- && (result->len == 1 || result->buf[result->len-2] == '\n') +- ) { +- result->buf[--result->len] = '\0'; +- } +-} +- +- + /* BZ attachments */ + + static +@@ -573,104 +69,6 @@ int attach_file_item(struct abrt_xmlrpc *ax, const char *bug_id, + return (r == 0); + } + +-static +-int attach_item(struct abrt_xmlrpc *ax, const char *bug_id, +- const char *item_name, problem_data_t *pd, GList *comment_fmt_spec) +-{ +- if (item_name[0] != '%') +- { +- struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name); +- if (!item) +- return 0; +- if (item->flags & CD_FLAG_TXT) +- return attach_text_item(ax, bug_id, item_name, item); +- if (item->flags & CD_FLAG_BIN) +- return attach_file_item(ax, bug_id, item_name, item); +- return 0; +- } +- +- /* Special item name */ +- +- /* %oneline,%multiline,%text,%binary */ +- bool oneline = (strcmp(item_name+1, "oneline" ) == 0); +- bool multiline = (strcmp(item_name+1, "multiline") == 0); +- bool text = (strcmp(item_name+1, "text" ) == 0); +- bool binary = (strcmp(item_name+1, "binary" ) == 0); +- if (!oneline && !multiline && !text && !binary) +- { +- log("Unknown or unsupported element specifier '%s'", item_name); +- return 0; +- } +- +- log_debug("Special item_name '%s', iterating for attach...", item_name); +- int done = 0; +- +- /* Iterate over _sorted_ items */ +- GList *sorted_names = g_hash_table_get_keys(pd); +- sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp); +- +- GList *l = sorted_names; +- while (l) +- { +- const char *name = l->data; +- l = l->next; +- struct problem_item *item = g_hash_table_lookup(pd, name); +- if (!item) +- continue; /* paranoia, won't happen */ +- +- if (is_explicit_or_forbidden(name, comment_fmt_spec)) +- continue; +- +- if ((item->flags & CD_FLAG_TXT) && !binary) +- { +- char *content = item->content; +- char *eol = strchrnul(content, '\n'); +- bool is_oneline = (eol[0] == '\0' || eol[1] == '\0'); +- if (text || oneline == is_oneline) +- done |= attach_text_item(ax, bug_id, name, item); +- } +- if ((item->flags & CD_FLAG_BIN) && binary) +- done |= attach_file_item(ax, bug_id, name, item); +- } +- +- g_list_free(sorted_names); /* names themselves are not freed */ +- +- +- log_debug("...Done iterating over '%s' for attach", item_name); +- +- return done; +-} +- +-static +-int attach_files(struct abrt_xmlrpc *ax, const char *bug_id, +- problem_data_t *pd, GList *comment_fmt_spec) +-{ +- int done = 0; +- GList *l = comment_fmt_spec; +- while (l) +- { +- section_t *sec = l->data; +- l = l->next; +- +- /* Find %attach" */ +- if (strcmp(sec->name, "%attach") != 0) +- continue; +- +- GList *item = sec->items; +- while (item) +- { +- const char *str = item->data; +- item = item->next; +- if (str[0] == '-') /* "-name", ignore it */ +- continue; +- done |= attach_item(ax, bug_id, str, pd, comment_fmt_spec); +- } +- } +- +- return done; +-} +- +- + /* Main */ + + struct bugzilla_struct { +@@ -1103,18 +501,29 @@ int main(int argc, char **argv) + + if (opts & OPT_D) + { +- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); +- struct strbuf *bzcomment_buf = strbuf_new(); +- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); +- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); +- char *summary = create_summary_string(problem_data, comment_fmt_spec); ++ problem_formatter_t *pf = problem_formatter_new(); ++ ++ if (problem_formatter_load_file(pf, fmt_file)) ++ error_msg_and_die("Invalid format file: %s", fmt_file); ++ ++ problem_report_t *pr = NULL; ++ if (problem_formatter_generate_report(pf, problem_data, &pr)) ++ error_msg_and_die("Failed to format bug report from problem data"); ++ + printf("summary: %s\n" + "\n" + "%s" +- , summary, bzcomment ++ "\n" ++ , problem_report_get_summary(pr) ++ , problem_report_get_description(pr) + ); +- free(bzcomment); +- free(summary); ++ ++ puts("attachments:"); ++ for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a)) ++ printf(" %s\n", (const char *)a->data); ++ ++ problem_report_free(pr); ++ problem_formatter_free(pf); + exit(0); + } + +@@ -1227,22 +636,29 @@ int main(int argc, char **argv) + /* Create new bug */ + log(_("Creating a new bug")); + +- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); ++ problem_formatter_t *pf = problem_formatter_new(); ++ ++ if (problem_formatter_load_file(pf, fmt_file)) ++ error_msg_and_die("Invalid format file: %s", fmt_file); ++ ++ problem_report_t *pr = NULL; ++ if (problem_formatter_generate_report(pf, problem_data, &pr)) ++ error_msg_and_die("Failed to format problem data"); + +- struct strbuf *bzcomment_buf = strbuf_new(); +- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); + if (crossver_id >= 0) +- strbuf_append_strf(bzcomment_buf, "\nPotential duplicate: bug %u\n", crossver_id); +- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); +- char *summary = create_summary_string(problem_data, comment_fmt_spec); ++ problem_report_buffer_printf( ++ problem_report_get_buffer(pr, PR_SEC_DESCRIPTION), ++ "\nPotential duplicate: bug %u\n", crossver_id); ++ ++ problem_formatter_free(pf); ++ + int new_id = rhbz_new_bug(client, + problem_data, rhbz.b_product, rhbz.b_product_version, +- summary, bzcomment, ++ problem_report_get_summary(pr), ++ problem_report_get_description(pr), + rhbz.b_create_private, + rhbz.b_private_groups + ); +- free(bzcomment); +- free(summary); + + if (new_id == -1) + { +@@ -1267,9 +683,17 @@ int main(int argc, char **argv) + char new_id_str[sizeof(int)*3 + 2]; + sprintf(new_id_str, "%i", new_id); + +- attach_files(client, new_id_str, problem_data, comment_fmt_spec); +- +-//TODO: free_comment_fmt_spec(comment_fmt_spec); ++ for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a)) ++ { ++ const char *item_name = (const char *)a->data; ++ struct problem_item *item = problem_data_get_item_or_NULL(problem_data, item_name); ++ if (!item) ++ continue; ++ else if (item->flags & CD_FLAG_TXT) ++ attach_text_item(client, new_id_str, item_name, item); ++ else if (item->flags & CD_FLAG_BIN) ++ attach_file_item(client, new_id_str, item_name, item); ++ } + + bz = new_bug_info(); + bz->bi_status = xstrdup("NEW"); +@@ -1340,18 +764,21 @@ int main(int argc, char **argv) + const char *comment = problem_data_get_content_or_NULL(problem_data, FILENAME_COMMENT); + if (comment && comment[0]) + { +- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file2); +- struct strbuf *bzcomment_buf = strbuf_new(); +- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); +- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); +-//TODO: free_comment_fmt_spec(comment_fmt_spec); ++ problem_formatter_t *pf = problem_formatter_new(); ++ if (problem_formatter_load_file(pf, fmt_file2)) ++ error_msg_and_die("Invalid duplicate format file: '%s", fmt_file2); ++ ++ problem_report_t *pr; ++ if (problem_formatter_generate_report(pf, problem_data, &pr)) ++ error_msg_and_die("Failed to format duplicate comment from problem data"); ++ ++ const char *bzcomment = problem_report_get_description(pr); + + int dup_comment = is_comment_dup(bz->bi_comments, bzcomment); + if (!dup_comment) + { + log(_("Adding new comment to bug %d"), bz->bi_id); + rhbz_add_comment(client, bz->bi_id, bzcomment, 0); +- free(bzcomment); + + const char *bt = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE); + unsigned rating = 0; +@@ -1369,10 +796,10 @@ int main(int argc, char **argv) + } + } + else +- { +- free(bzcomment); + log(_("Found the same comment in the bug history, not adding a new one")); +- } ++ ++ problem_report_free(pr); ++ problem_formatter_free(pf); + } + + log_out: +-- +1.8.3.1 + diff --git a/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch b/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch new file mode 100644 index 0000000..0a7a3c6 --- /dev/null +++ b/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch @@ -0,0 +1,405 @@ +From 8d9f7ba8a42ec1cfd39e6c249aef15e9295fe0a1 Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Tue, 13 Jan 2015 19:23:08 -0500 +Subject: [PATCH 1001/1015] lib: created a new lib file for reporters + +Moved some functions from rhbz.c to src/lib/reporters.c and src/lib/strbuf.c. + +Related to #272 + +Signed-off-by: Matej Habrnal +--- + po/POTFILES.in | 1 + + src/include/Makefile.am | 3 +- + src/include/internal_libreport.h | 5 +++ + src/include/reporters.h | 36 ++++++++++++++++++ + src/lib/Makefile.am | 3 +- + src/lib/reporters.c | 80 ++++++++++++++++++++++++++++++++++++++++ + src/lib/strbuf.c | 60 ++++++++++++++++++++++++++++++ + src/plugins/rhbz.c | 78 +-------------------------------------- + src/plugins/rhbz.h | 2 - + 9 files changed, 188 insertions(+), 80 deletions(-) + create mode 100644 src/include/reporters.h + create mode 100644 src/lib/reporters.c + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 4246e06..003e686 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -27,6 +27,7 @@ src/lib/parse_options.c + src/lib/problem_data.c + src/lib/problem_report.c + src/lib/reported_to.c ++src/lib/reporters.c + src/lib/run_event.c + src/plugins/abrt_rh_support.c + src/plugins/report_Bugzilla.xml.in.in +diff --git a/src/include/Makefile.am b/src/include/Makefile.am +index 87e5e60..4d8c6a5 100644 +--- a/src/include/Makefile.am ++++ b/src/include/Makefile.am +@@ -15,7 +15,8 @@ libreport_include_HEADERS = \ + file_obj.h \ + internal_libreport.h \ + internal_abrt_dbus.h \ +- xml_parser.h ++ xml_parser.h \ ++ reporters.h + + if BUILD_UREPORT + libreport_include_HEADERS += ureport.h +diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h +index cf5730c..a867649 100644 +--- a/src/include/internal_libreport.h ++++ b/src/include/internal_libreport.h +@@ -99,6 +99,7 @@ int vdprintf(int d, const char *format, va_list ap); + #include "workflow.h" + #include "file_obj.h" + #include "libreport_types.h" ++#include "reporters.h" + + #ifdef __cplusplus + extern "C" { +@@ -108,6 +109,10 @@ extern "C" { + int prefixcmp(const char *str, const char *prefix); + #define suffixcmp libreport_suffixcmp + int suffixcmp(const char *str, const char *suffix); ++#define trim_all_whitespace libreport_trim_all_whitespace ++char *trim_all_whitespace(const char *str); ++#define shorten_string_to_length libreport_shorten_string_to_length ++char *shorten_string_to_length(const char *str, unsigned length); + #define strtrim libreport_strtrim + char *strtrim(char *str); + #define strtrimch libreport_strtrimch +diff --git a/src/include/reporters.h b/src/include/reporters.h +new file mode 100644 +index 0000000..d415b7f +--- /dev/null ++++ b/src/include/reporters.h +@@ -0,0 +1,36 @@ ++/* ++ Copyright (C) 2014 ABRT team ++ Copyright (C) 2014 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 REPORTERS_H ++#define REPORTERS_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define is_comment_dup libreport_is_comment_dup ++int is_comment_dup(GList *comments, const char *comment); ++#define comments_find_best_bt_rating libreport_comments_find_best_bt_rating ++unsigned comments_find_best_bt_rating(GList *comments); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am +index c11a42d..d41e543 100644 +--- a/src/lib/Makefile.am ++++ b/src/lib/Makefile.am +@@ -58,7 +58,8 @@ libreport_la_SOURCES = \ + xml_parser.c \ + libreport_init.c \ + global_configuration.c \ +- uriparser.c ++ uriparser.c \ ++ reporters.c + + libreport_la_CPPFLAGS = \ + -I$(srcdir)/../include \ +diff --git a/src/lib/reporters.c b/src/lib/reporters.c +new file mode 100644 +index 0000000..e3305ca +--- /dev/null ++++ b/src/lib/reporters.c +@@ -0,0 +1,80 @@ ++/* ++ String buffer implementation ++ ++ Copyright (C) 2015 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 "internal_libreport.h" ++ ++int ++is_comment_dup(GList *comments, const char *comment) ++{ ++ char * const trim_comment = trim_all_whitespace(comment); ++ bool same_comments = false; ++ ++ for (GList *l = comments; l && !same_comments; l = l->next) ++ { ++ const char * const comment_body = (const char *) l->data; ++ char * const trim_comment_body = trim_all_whitespace(comment_body); ++ same_comments = (strcmp(trim_comment_body, trim_comment) == 0); ++ free(trim_comment_body); ++ } ++ ++ free(trim_comment); ++ return same_comments; ++} ++ ++unsigned ++comments_find_best_bt_rating(GList *comments) ++{ ++ if (comments == NULL) ++ return 0; ++ ++ unsigned best_rating = 0; ++ for (GList *l = comments; l; l = l->next) ++ { ++ char *comment_body = (char *) l->data; ++ ++ char *start_rating_line = strstr(comment_body, FILENAME_RATING": "); ++ if (!start_rating_line) ++ { ++ log_debug(_("Note does not contain rating")); ++ continue; ++ } ++ ++ start_rating_line += strlen(FILENAME_RATING": "); ++ ++ errno = 0; ++ char *e; ++ long rating = strtoul(start_rating_line, &e, 10); ++ /* ++ * Note: we intentionally check for '\n'. Any other terminator ++ * (even '\0') is not ok in this case. ++ */ ++ if (errno || e == start_rating_line || (*e != '\n' && *e != '\r') || (unsigned long)rating > UINT_MAX) ++ { ++ /* error / no digits / illegal trailing chars */ ++ continue; ++ } ++ ++ if (rating > best_rating) ++ best_rating = rating; ++ } ++ ++ return best_rating; ++} ++ +diff --git a/src/lib/strbuf.c b/src/lib/strbuf.c +index ef8bda8..f0cd1b8 100644 +--- a/src/lib/strbuf.c ++++ b/src/lib/strbuf.c +@@ -37,6 +37,66 @@ int suffixcmp(const char *str, const char *suffix) + return strcmp(str + len_minus_suflen, suffix); + } + ++char *trim_all_whitespace(const char *str) ++{ ++ char *trim = xzalloc(sizeof(char) * strlen(str) + 1); ++ int i = 0; ++ while (*str) ++ { ++ if (!isspace(*str)) ++ trim[i++] = *str; ++ str++; ++ } ++ ++ return trim; ++} ++ ++/* If str is longer than max allowed length then ++ * try to find first ' ' from the end of acceptable long str string ++ * ++ * If ' ' is found replace string after that by "..." ++ * ++ * If ' ' is NOT found in maximal allowed range, cut str string on ++ * lenght (MAX_SUMMARY_LENGTH - strlen("...")) and append "..." ++ * ++ * If MAX_LENGTH is 15 and max allowed cut is 5: ++ * ++ * 0123456789ABCDEF -> 0123456789AB... ++ * 0123456789 BCDEF -> 0123456789 ... ++ * 012345 789ABCDEF -> 012345 789AB... ++ */ ++char * ++shorten_string_to_length(const char *str, unsigned length) ++{ ++ char *dup_str = xstrdup(str); ++ if (strlen(str) > length) ++ { ++ char *max_end = dup_str + (length - strlen("...")); ++ ++ /* maximal number of characters to cut due to attempt cut dup_str ++ * string after last ' ' ++ */ ++ int max_cut = 16; ++ ++ /* start looking for ' ' one char before the last possible character */ ++ char *buf = max_end - 1; ++ while (buf[0] != ' ' && max_cut--) ++ --buf; ++ ++ if (buf[0] != ' ') ++ buf = max_end; ++ else ++ ++buf; ++ ++ buf[0] = '.'; ++ buf[1] = '.'; ++ buf[2] = '.'; ++ buf[3] = '\0'; ++ } ++ ++ return dup_str; ++} ++ + /* + * Trims whitespace characters both from left and right side of a string. + * Modifies the string in-place. Returns the trimmed string. +diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c +index a227c62..fdcfff9 100644 +--- a/src/plugins/rhbz.c ++++ b/src/plugins/rhbz.c +@@ -133,41 +133,6 @@ static GList *rhbz_comments(struct abrt_xmlrpc *ax, int bug_id) + return g_list_reverse(comments); + } + +-static char *trim_all_whitespace(const char *str) +-{ +- func_entry(); +- +- char *trim = xzalloc(sizeof(char) * strlen(str) + 1); +- int i = 0; +- while (*str) +- { +- if (!isspace(*str)) +- trim[i++] = *str; +- str++; +- } +- +- return trim; +-} +- +-int is_comment_dup(GList *comments, const char *comment) +-{ +- func_entry(); +- +- char * const trim_comment = trim_all_whitespace(comment); +- bool same_comments = false; +- +- for (GList *l = comments; l && !same_comments; l = l->next) +- { +- const char * const comment_body = (const char *) l->data; +- char * const trim_comment_body = trim_all_whitespace(comment_body); +- same_comments = (strcmp(trim_comment_body, trim_comment) == 0); +- free(trim_comment_body); +- } +- +- free(trim_comment); +- return same_comments; +-} +- + static unsigned find_best_bt_rating_in_comments(GList *comments) + { + func_entry(); +@@ -553,46 +518,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, + if (!duphash) duphash = problem_data_get_content_or_NULL(problem_data, + "global_uuid"); + +- /* If summary is longer than max allowed summary length then +- * try to find first ' ' from the end of acceptable long summary string +- * +- * If ' ' is found replace string after that by "..." +- * +- * If ' ' is NOT found in maximal allowed range, cut summary string on +- * lenght (MAX_SUMMARY_LENGTH - strlen("...")) and append "..." +- * +- * If MAX_SUMMARY_LENGTH is 15 and max allowed cut is 5: +- * +- * 0123456789ABCDEF -> 0123456789AB... +- * 0123456789 BCDEF -> 0123456789 ... +- * 012345 789ABCDEF -> 012345 789AB... +- */ +- char *summary = NULL; +- if (strlen(bzsummary) > MAX_SUMMARY_LENGTH) +- { +- summary = xstrdup(bzsummary); +- char *max_end = summary + (MAX_SUMMARY_LENGTH - strlen("...")); +- +- /* maximal number of characters to cut due to attempt cut summary +- * string after last ' ' +- */ +- int max_cut = 16; +- +- /* start looking for ' ' one char before the last possible character */ +- char *buf = max_end - 1; +- while (buf[0] != ' ' && max_cut--) +- --buf; +- +- if (buf[0] != ' ') +- buf = max_end; +- else +- ++buf; +- +- buf[0] = '.'; +- buf[1] = '.'; +- buf[2] = '.'; +- buf[3] = '\0'; +- } ++ char *summary = shorten_string_to_length(bzsummary, MAX_SUMMARY_LENGTH); + + char *status_whiteboard = xasprintf("abrt_hash:%s", duphash); + +@@ -604,7 +530,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, + abrt_xmlrpc_params_add_string(&env, params, "product", product); + abrt_xmlrpc_params_add_string(&env, params, "component", component); + abrt_xmlrpc_params_add_string(&env, params, "version", version); +- abrt_xmlrpc_params_add_string(&env, params, "summary", (summary ? summary : bzsummary)); ++ abrt_xmlrpc_params_add_string(&env, params, "summary", summary); + abrt_xmlrpc_params_add_string(&env, params, "description", bzcomment); + abrt_xmlrpc_params_add_string(&env, params, "status_whiteboard", status_whiteboard); + +diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h +index 15e7699..86632a3 100644 +--- a/src/plugins/rhbz.h ++++ b/src/plugins/rhbz.h +@@ -105,8 +105,6 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id, + int rhbz_attach_fd(struct abrt_xmlrpc *ax, const char *bug_id, + const char *att_name, int fd, int flags); + +-int is_comment_dup(GList *comments, const char *comment); +- + GList *rhbz_bug_cc(xmlrpc_value *result_xml); + + struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id); +-- +1.8.3.1 + diff --git a/SOURCES/1003-ureport-set-url-to-public-faf-server.patch b/SOURCES/1003-ureport-set-url-to-public-faf-server.patch new file mode 100644 index 0000000..4e2c361 --- /dev/null +++ b/SOURCES/1003-ureport-set-url-to-public-faf-server.patch @@ -0,0 +1,27 @@ +From 2221fee2d3b930f171fa5181439ded9a1748ff00 Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Mon, 2 Feb 2015 16:31:51 +0100 +Subject: [PATCH 1003/1015] ureport: set url to public faf server + +Set url to public faf server because the private one doesn't return URL to +known issues, bthash, possible solution etc. + +Signed-off-by: Matej Habrnal +--- + src/plugins/ureport.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/ureport.conf b/src/plugins/ureport.conf +index 2256a7f..b82b0e1 100644 +--- a/src/plugins/ureport.conf ++++ b/src/plugins/ureport.conf +@@ -1,5 +1,5 @@ + # Base URL to uReport server +-# URL = http://bug-report.redhat.com ++URL = https://retrace.fedoraproject.org/faf + + # no means that ssl certificates will not be checked + # SSLVerify = no +-- +1.8.3.1 + diff --git a/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch b/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch new file mode 100644 index 0000000..4823eeb --- /dev/null +++ b/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch @@ -0,0 +1,29 @@ +From e8bb90e42d0356cdcf91d22c9deb6635d1d3c376 Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Mon, 2 Feb 2015 21:41:36 +0100 +Subject: [PATCH 1004/1015] conf: changed URL for sending uReport + +Changed faf server url in report_uReport.xml.in. +uReports are sending to https://retrace.fedoraproject.org/faf by default. + +Signed-off-by: Matej Habrnal +--- + src/plugins/report_uReport.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/report_uReport.xml.in b/src/plugins/report_uReport.xml.in +index b997851..eca30e0 100644 +--- a/src/plugins/report_uReport.xml.in ++++ b/src/plugins/report_uReport.xml.in +@@ -12,7 +12,7 @@ + <_label>uReport Server URL + no + <_description>Address of uReport webservice +- http://bug-report.redhat.com ++ https://retrace.fedoraproject.org/faf + +