diff --git a/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch b/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch new file mode 100644 index 0000000..fedb796 --- /dev/null +++ b/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch @@ -0,0 +1,136 @@ +From 128490bb35079d77c0fa04f2e254bd6a0acc382a Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Thu, 24 Nov 2016 07:54:21 +0100 +Subject: [PATCH] reportclient: honor ABRT_VERBOSE + +libreport's verbosity can be configured via ABRT_VERBOSE environment +variable and reportclient must be aware of that. + +Related to #1257159 + +Signed-off-by: Jakub Filak +--- + src/client-python/__init__.py | 9 ++++++++ + tests/Makefile.am | 1 + + tests/client_python.at | 53 +++++++++++++++++++++++++++++++++++++++++++ + tests/testsuite.at | 1 + + 4 files changed, 64 insertions(+) + create mode 100644 tests/client_python.at + +diff --git a/src/client-python/__init__.py b/src/client-python/__init__.py +index 8966f22..f10f710 100644 +--- a/src/client-python/__init__.py ++++ b/src/client-python/__init__.py +@@ -31,6 +31,7 @@ from report import EXIT_STOP_EVENT_RUN as RETURN_STOP_EVENT_RUN + + + GETTEXT_PROGNAME = "libreport" ++import os + import locale + import gettext + +@@ -52,10 +53,18 @@ def init_gettext(): + init_gettext() + + verbose = 0 ++ABRT_VERBOSE = os.getenv("ABRT_VERBOSE") ++if ABRT_VERBOSE: ++ try: ++ verbose = int(ABRT_VERBOSE) ++ except: ++ pass ++ + + def set_verbosity(verbosity): + global verbose + verbose = verbosity ++ os.environ["ABRT_VERBOSE"] = str(verbose) + + def log(fmt, *args): + sys.stderr.write("%s\n" % (fmt % args)) +diff --git a/tests/Makefile.am b/tests/Makefile.am +index b45f2d9..52dfce4 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -40,6 +40,7 @@ TESTSUITE_AT = \ + libreport_types.at \ + xml_definition.at \ + report_python.at \ ++ client_python.at \ + xfuncs.at \ + string_list.at \ + ureport.at \ +diff --git a/tests/client_python.at b/tests/client_python.at +new file mode 100644 +index 0000000..656b1b2 +--- /dev/null ++++ b/tests/client_python.at +@@ -0,0 +1,53 @@ ++# -*- Autotest -*- ++ ++AT_BANNER([client_python]) ++ ++## --------- ## ++## verbosity ## ++## --------- ## ++ ++AT_PYTESTFUN([verbosity], [[ ++import sys ++import os ++import unittest ++ ++sys.path.insert(0, "../../../src/client-python") ++sys.path.insert(0, "../../../src/client-python/.libs") ++ ++ ++class TestReportClientVerbose(unittest.TestCase): ++ def setUp(self): ++ try: ++ del os.environ["ABRT_VERBOSE"] ++ except: ++ pass ++ os.unsetenv("ABRT_VERBOSE") ++ self.clientpython = __import__("client-python", globals(), locals(), [], -1) ++ reload(self.clientpython) ++ sys.modules["clientpython"] = self.clientpython ++ ++ def tearDown(self): ++ del sys.modules["clientpython"] ++ ++ def test_default(self): ++ self.assertEquals(self.clientpython.verbose, 0) ++ ++ def test_assign(self): ++ self.clientpython.set_verbosity(1) ++ self.assertEquals(self.clientpython.verbose, 1) ++ self.assertEquals(os.environ["ABRT_VERBOSE"], "1") ++ ++ def test_load_from_environ(self): ++ os.environ["ABRT_VERBOSE"] = "2" ++ reload(self.clientpython) ++ self.assertEquals(self.clientpython.verbose, 2) ++ ++ def test_recover_from_invalid_environ(self): ++ os.environ["ABRT_VERBOSE"] = "foo" ++ reload(self.clientpython) ++ self.assertEquals(self.clientpython.verbose, 0) ++ ++ ++if __name__ == "__main__": ++ unittest.main() ++]]) +diff --git a/tests/testsuite.at b/tests/testsuite.at +index ccb37d1..8ded735 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -15,6 +15,7 @@ m4_include([make_description.at]) + m4_include([libreport_types.at]) + m4_include([xml_definition.at]) + m4_include([report_python.at]) ++m4_include([client_python.at]) + m4_include([string_list.at]) + m4_include([ureport.at]) + m4_include([problem_report.at]) +-- +1.8.3.1 + diff --git a/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch b/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch new file mode 100644 index 0000000..cf2e243 --- /dev/null +++ b/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch @@ -0,0 +1,303 @@ +From 8ee8cf6d0467241d2886a095be25c2885d3a8666 Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Wed, 23 Nov 2016 16:22:51 +0100 +Subject: [PATCH] tree-wide: introduce 'stop_on_not_reportable' option + +Make it possible to ignore existence of not-reportable file and continue +in reporting. + +The new configuration option is not yet persistent and can be configured +via an environment variable. + +Related to #1257159 +Related to abrt/abrt#1166 + +Signed-off-by: Jakub Filak +--- + src/cli/cli-report.c | 3 +- + src/gui-wizard-gtk/wizard.c | 21 ++++++++---- + src/include/global_configuration.h | 28 ++++++++++++++++ + src/include/internal_libreport.h | 1 + + src/include/report.h | 3 ++ + src/lib/global_configuration.c | 22 +++++++++++++ + src/lib/report.c | 6 ++++ + src/report-newt/report-newt.c | 4 ++- + src/report-python/reportmodule.c | 1 + + tests/global_config.at | 67 ++++++++++++++++++++++++++++++++++++++ + 10 files changed, 148 insertions(+), 8 deletions(-) + +diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c +index 68baa8b..adb58a7 100644 +--- a/src/cli/cli-report.c ++++ b/src/cli/cli-report.c +@@ -525,7 +525,8 @@ static int is_not_reportable(problem_data_t *problem_data) + if (not_reportable) + { + printf("%s\n", not_reportable); +- return 1; ++ if (get_global_stop_on_not_reportable()) ++ return 1; + } + return 0; + } +diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c +index 31861a1..35c6fc3 100644 +--- a/src/gui-wizard-gtk/wizard.c ++++ b/src/gui-wizard-gtk/wizard.c +@@ -2039,7 +2039,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g + dd_sanitize_mode_and_owner(dd); + } + +- if (retval == 0 && !g_expert_mode) ++ if (retval == 0 && !g_expert_mode && get_global_stop_on_not_reportable()) + { + /* Check whether NOT_REPORTABLE element appeared. If it did, we'll stop + * even if exit code is "success". +@@ -3103,16 +3103,25 @@ static gint select_next_page_no(gint current_page_no, gpointer data) + + if (problem_data_get_content_or_NULL(g_cd, FILENAME_NOT_REPORTABLE)) + { +- free(event); + + char *msg = xasprintf(_("This problem should not be reported " + "(it is likely a known problem). %s"), + problem_data_get_content_or_NULL(g_cd, FILENAME_NOT_REPORTABLE) + ); +- cancel_processing(g_lbl_event_log, msg, TERMINATE_NOFLAGS); +- free(msg); +- current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1; +- goto again; ++ ++ if (get_global_stop_on_not_reportable()) ++ { ++ free(event); ++ cancel_processing(g_lbl_event_log, msg, TERMINATE_NOFLAGS); ++ free(msg); ++ current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1; ++ goto again; ++ } ++ else ++ { ++ log(msg); ++ free(msg); ++ } + } + + /* must set g_event_selected otherwise if the event was not +diff --git a/src/include/global_configuration.h b/src/include/global_configuration.h +index bc5513d..0eb18c6 100644 +--- a/src/include/global_configuration.h ++++ b/src/include/global_configuration.h +@@ -53,6 +53,34 @@ bool get_global_create_private_ticket(void); + #define set_global_create_private_ticket libreport_set_global_create_private_ticket + void set_global_create_private_ticket(bool enabled, int flags); + ++/** ++ * Returns logical true if the reporting process shall not start or contine if ++ * the not-reportable files exists. ++ * ++ * The option can be enabled by ABRT_STOP_ON_NOT_REPORTABLE environment ++ * variable. ++ * ++ * @return true if the process shall stop; otherwise the function returns ++ * false. ++ */ ++#define get_global_stop_on_not_reportable libreport_get_global_stop_on_not_reportable ++bool get_global_stop_on_not_reportable(void); ++ ++/** ++ * Configures the stop on not reportable global option ++ * ++ * The function changes the configuration only for the current process by ++ * default. ++ * ++ * The option can be enabled by ABRT_STOP_ON_NOT_REPORTABLE environment ++ * variable. ++ * ++ * @param enabled The option's value ++ * @param flags For future needs (enable persistent configuration) ++ */ ++#define set_global_stop_on_not_reportable libreport_set_global_stop_on_not_reportable ++void set_global_stop_on_not_reportable(bool enabled, int flags); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h +index cf5730c..23cdfa0 100644 +--- a/src/include/internal_libreport.h ++++ b/src/include/internal_libreport.h +@@ -87,6 +87,7 @@ int vdprintf(int d, const char *format, va_list ap); + + /* consts used across whole libreport */ + #define CREATE_PRIVATE_TICKET "ABRT_CREATE_PRIVATE_TICKET" ++#define STOP_ON_NOT_REPORTABLE "ABRT_STOP_ON_NOT_REPORTABLE" + + /* Pull in entire public libreport API */ + #include "dump_dir.h" +diff --git a/src/include/report.h b/src/include/report.h +index d31eb0a..03f3dc6 100644 +--- a/src/include/report.h ++++ b/src/include/report.h +@@ -35,6 +35,9 @@ enum { + LIBREPORT_DEL_DIR = (1 << 6), /* delete directory after reporting (passes --delete to child) */ + LIBREPORT_RUN_CLI = (1 << 7), /* run 'cli' instead of 'gui' */ + LIBREPORT_RUN_NEWT = (1 << 8), /* run 'report-newt' */ ++ LIBREPORT_IGNORE_NOT_REPORTABLE = (1 << 9), /* do not terminate the ++ reporting process if the ++ not-repotrable file exits. */ + }; + + int report_problem_in_dir(const char *dirname, int flags); +diff --git a/src/lib/global_configuration.c b/src/lib/global_configuration.c +index ef921e9..46b9a63 100644 +--- a/src/lib/global_configuration.c ++++ b/src/lib/global_configuration.c +@@ -163,3 +163,25 @@ void set_global_create_private_ticket(bool enabled, int flags/*unused - persiste + else + safe_unsetenv(CREATE_PRIVATE_TICKET); + } ++ ++bool get_global_stop_on_not_reportable(void) ++{ ++ assert_global_configuration_initialized(); ++ ++ char *env_create_private = getenv(STOP_ON_NOT_REPORTABLE); ++ ++ if (env_create_private == NULL) ++ return true; ++ ++ return string_to_bool(env_create_private); ++} ++ ++void set_global_stop_on_not_reportable(bool enabled, int flags/*unused - persistent*/) ++{ ++ assert_global_configuration_initialized(); ++ ++ if (enabled) ++ xsetenv(STOP_ON_NOT_REPORTABLE, "1"); ++ else ++ xsetenv(STOP_ON_NOT_REPORTABLE, "0"); ++} +diff --git a/src/lib/report.c b/src/lib/report.c +index 7a655fd..3380a52 100644 +--- a/src/lib/report.c ++++ b/src/lib/report.c +@@ -26,6 +26,12 @@ int report_problem_in_dir(const char *dirname, int flags) + if (prgname) + prgname = xasprintf("LIBREPORT_PRGNAME=%s", prgname); + ++ if (flags & LIBREPORT_IGNORE_NOT_REPORTABLE) ++ { ++ load_global_configuration(); ++ set_global_stop_on_not_reportable(false, 0); ++ } ++ + fflush(NULL); + + pid_t pid = fork(); +diff --git a/src/report-newt/report-newt.c b/src/report-newt/report-newt.c +index f5fca76..278cfb7 100644 +--- a/src/report-newt/report-newt.c ++++ b/src/report-newt/report-newt.c +@@ -336,7 +336,9 @@ static int report(const char *dump_dir_name) + dd_close(dd); + newtWinMessage(_("Error"), _("Ok"), (char *)"%s", t); + free(t); +- return -1; ++ ++ if (get_global_stop_on_not_reportable()) ++ return -1; + } + + dd_close(dd); +diff --git a/src/report-python/reportmodule.c b/src/report-python/reportmodule.c +index b8154ae..4491fd4 100644 +--- a/src/report-python/reportmodule.c ++++ b/src/report-python/reportmodule.c +@@ -98,6 +98,7 @@ init_pyreport(void) + PyModule_AddObject(m, "LIBREPORT_DEL_DIR" , Py_BuildValue("i", LIBREPORT_DEL_DIR )); + PyModule_AddObject(m, "LIBREPORT_RUN_CLI" , Py_BuildValue("i", LIBREPORT_RUN_CLI )); + PyModule_AddObject(m, "LIBREPORT_RUN_NEWT" , Py_BuildValue("i", LIBREPORT_RUN_NEWT )); ++ PyModule_AddObject(m, "LIBREPORT_IGNORE_NOT_REPORTABLE", Py_BuildValue("i", LIBREPORT_IGNORE_NOT_REPORTABLE)); + PyModule_AddObject(m, "EXIT_CANCEL_BY_USER", Py_BuildValue("i", EXIT_CANCEL_BY_USER)); + PyModule_AddObject(m, "EXIT_STOP_EVENT_RUN", Py_BuildValue("i", EXIT_STOP_EVENT_RUN)); + } +diff --git a/tests/global_config.at b/tests/global_config.at +index 05a0ffa..1067128 100644 +--- a/tests/global_config.at ++++ b/tests/global_config.at +@@ -169,3 +169,70 @@ TS_MAIN + } + TS_RETURN_MAIN + ]]) ++ ++ ++## ---------------------- ## ++## stop_on_not_reportable ## ++## ---------------------- ## ++ ++AT_TESTFUN([stop_on_not_reportable], [[ ++#include "testsuite.h" ++ ++TS_MAIN ++{ ++ char cwd_buf[PATH_MAX + 1]; ++ static const char *dirs[] = { ++ NULL, ++ NULL, ++ }; ++ dirs[0] = getcwd(cwd_buf, sizeof(cwd_buf)); ++ ++ static int dir_flags[] = { ++ CONF_DIR_FLAG_NONE, ++ -1, ++ }; ++ ++ unlink("libreport.conf"); ++ FILE *lrf = fopen("libreport.conf", "wx"); ++ assert(lrf != NULL); ++ fclose(lrf); ++ ++ assert(load_global_configuration_from_dirs(dirs, dir_flags)); ++ ++ TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "True by default"); ++ ++ set_global_stop_on_not_reportable(true, 0); ++ ++ TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Still true"); ++ ++ set_global_stop_on_not_reportable(false, 0); ++ ++ TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Configuration accepted"); ++ TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "0", "Correct ENVIRONMENT value"); ++ ++ set_global_stop_on_not_reportable(true, 0); ++ ++ TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Configuration sanity"); ++ TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "1", "Correct ENVIRONMENT value"); ++ ++ set_global_stop_on_not_reportable(false, 0); ++ ++ TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Reverted back to False"); ++ TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "0", "Correct ENVIRONMENT value"); ++ ++ xsetenv(STOP_ON_NOT_REPORTABLE, "1"); ++ ++ TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Loaded from environment"); ++ ++ unsetenv(STOP_ON_NOT_REPORTABLE); ++ ++ TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Reflects environment"); ++ ++ xsetenv(STOP_ON_NOT_REPORTABLE, "0"); ++ ++ TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Zero is false"); ++ ++ free_global_configuration(); ++} ++TS_RETURN_MAIN ++]]) +-- +1.8.3.1 + diff --git a/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch b/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch new file mode 100644 index 0000000..244f62e --- /dev/null +++ b/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch @@ -0,0 +1,33 @@ +From 696fcadc7d494fc14ad5ac23f19b7da6a7f98c3b Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Mon, 5 Sep 2016 10:42:11 +0200 +Subject: [PATCH] rhtsupport: fix a double free of config at exit + +Introduced in commit 028b35b where I forgot on the code added in commit +5ff7f36. + +Related: rhbz#1373094 +--- + src/plugins/reporter-rhtsupport.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c +index 63a24a5..14b3864 100644 +--- a/src/plugins/reporter-rhtsupport.c ++++ b/src/plugins/reporter-rhtsupport.c +@@ -811,12 +811,7 @@ int main(int argc, char **argv) + /* Check for hints and show them if we have something */ + log(_("Checking for hints")); + if (check_for_hints(base_api_url, &login, &password, ssl_verify, tempfile)) +- { +- ureport_server_config_destroy(&urconf); +- free_map_string(ursettings); +- free(bthash); + goto ret; +- } + } + + log(_("Creating a new case")); +-- +1.8.3.1 + diff --git a/SOURCES/0216-reportclient-fix-verbosity-test.patch b/SOURCES/0216-reportclient-fix-verbosity-test.patch new file mode 100644 index 0000000..3f6fb62 --- /dev/null +++ b/SOURCES/0216-reportclient-fix-verbosity-test.patch @@ -0,0 +1,33 @@ +From 10fb97f11e27c4ac2144005f0ac28b8beff14733 Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Wed, 8 Feb 2017 14:50:49 +0100 +Subject: [PATCH] reportclient: fix verbosity test + +Imported missing report module. + +Related #1257159 + +Signed-off-by: Matej Habrnal +--- + tests/client_python.at | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/client_python.at b/tests/client_python.at +index 656b1b2..9f1c1c1 100644 +--- a/tests/client_python.at ++++ b/tests/client_python.at +@@ -13,7 +13,11 @@ import unittest + + sys.path.insert(0, "../../../src/client-python") + sys.path.insert(0, "../../../src/client-python/.libs") ++sys.path.insert(0, "../../../src/report-python") ++sys.path.insert(0, "../../../src/report-python/.libs") + ++report = __import__("report-python", globals(), locals(), [], -1) ++sys.modules["report"] = report + + class TestReportClientVerbose(unittest.TestCase): + def setUp(self): +-- +1.8.3.1 + diff --git a/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch b/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch new file mode 100644 index 0000000..231a615 --- /dev/null +++ b/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch @@ -0,0 +1,39 @@ +From 79d5c0352a09fc1bfe8cc491b33a745ac33b7855 Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Tue, 21 Feb 2017 12:08:13 +0100 +Subject: [PATCH] report-newt: free allocated variables, don't close dd twice + +Uncovered by coverity. + +Related #1257159 + +Signed-off-by: Matej Habrnal +--- + src/report-newt/report-newt.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/report-newt/report-newt.c b/src/report-newt/report-newt.c +index 278cfb7..2427d86 100644 +--- a/src/report-newt/report-newt.c ++++ b/src/report-newt/report-newt.c +@@ -333,12 +333,16 @@ static int report(const char *dump_dir_name) + not_reportable ? " " : "", + reason ? : _("(no description)")); + +- dd_close(dd); + newtWinMessage(_("Error"), _("Ok"), (char *)"%s", t); + free(t); ++ free(not_reportable); ++ free(reason); + + if (get_global_stop_on_not_reportable()) ++ { ++ dd_close(dd); + return -1; ++ } + } + + dd_close(dd); +-- +1.8.3.1 + diff --git a/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch b/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch deleted file mode 100644 index 5ab0a57..0000000 --- a/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch +++ /dev/null @@ -1,781 +0,0 @@ -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 deleted file mode 100644 index d0e74f9..0000000 --- a/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch +++ /dev/null @@ -1,405 +0,0 @@ -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 -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 -@@ -98,6 +98,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" { -@@ -107,6 +108,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 deleted file mode 100644 index ee9a33c..0000000 --- a/SOURCES/1003-ureport-set-url-to-public-faf-server.patch +++ /dev/null @@ -1,27 +0,0 @@ -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.itos.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 deleted file mode 100644 index f0386e8..0000000 --- a/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch +++ /dev/null @@ -1,29 +0,0 @@ -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.itos.redhat.com -+ https://retrace.fedoraproject.org/faf - -