summaryrefslogtreecommitdiffstats
path: root/src/plugins/abrt-action-bugzilla.cpp
diff options
context:
space:
mode:
authorNikola Pajkovsky <npajkovs@redhat.com>2011-05-09 11:11:25 +0200
committerNikola Pajkovsky <npajkovs@redhat.com>2011-05-12 15:10:25 +0200
commit1de58ce7be0e869490b02f197800d80d7020af75 (patch)
tree8d2063bb30e78b596d26225bf8347e412abcee90 /src/plugins/abrt-action-bugzilla.cpp
parent5f05e82e179275da7b0c29fbba4ab42e32035a9d (diff)
downloadabrt-1de58ce7be0e869490b02f197800d80d7020af75.tar.gz
abrt-1de58ce7be0e869490b02f197800d80d7020af75.tar.xz
abrt-1de58ce7be0e869490b02f197800d80d7020af75.zip
xmlrpc and bugzilla in a new C coat
Bugzilla is splitted into two parts. One of them is core of bugzilla and second one is small module called librhbz. I did it, because I want to add a new functionality into bugzilla and I don't want to squash it into one big module. Librhbz is not a part of our libreport, because almost every function dies when feels badly (print error msg and then die). Server sends error or abrt sends corrupted xml or server sends corrupted xml. Signed-off-by: Nikola Pajkovsky <npajkovs@redhat.com>
Diffstat (limited to 'src/plugins/abrt-action-bugzilla.cpp')
-rw-r--r--src/plugins/abrt-action-bugzilla.cpp768
1 files changed, 75 insertions, 693 deletions
diff --git a/src/plugins/abrt-action-bugzilla.cpp b/src/plugins/abrt-action-bugzilla.cpp
index e8a605f1..91bc26f8 100644
--- a/src/plugins/abrt-action-bugzilla.cpp
+++ b/src/plugins/abrt-action-bugzilla.cpp
@@ -17,350 +17,12 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "abrtlib.h"
-#include "abrt_xmlrpc.h"
#include "abrt_problem_data.h"
#include "parse_options.h"
+#include "abrt_xmlrpc.h"
+#include "rhbz.h"
#define XML_RPC_SUFFIX "/xmlrpc.cgi"
-#define MAX_HOPS 5
-
-/*
- * TODO: npajkovs: better deallocation of xmlrpc value
- * npajkovs: better gathering function which collects all information from bugzilla
- * npajkovs: figure out how to deal with cloning bugs
- * npajkovs: check if attachment was uploaded successul an if not try it again(max 3 times)
- * and if it still fails. retrun successful, but mention that attaching failed
- * npajkovs: add option to set comment privat
- */
-
-struct bug_info {
- const char* bug_status;
- const char* bug_resolution;
- const char* bug_reporter;
- const char* bug_product;
- xmlrpc_int32 bug_dup_id;
- GList* bug_cc;
-};
-
-/* xzalloc */
-static void bug_info_init(struct bug_info* bz)
-{
- bz->bug_status = NULL;
- bz->bug_resolution = NULL;
- bz->bug_reporter = NULL;
- bz->bug_product = NULL;
- bz->bug_dup_id = -1;
- bz->bug_cc = NULL;
-}
-
-static void bug_info_destroy(struct bug_info* bz)
-{
- free((void*)bz->bug_status);
- free((void*)bz->bug_resolution);
- free((void*)bz->bug_reporter);
- free((void*)bz->bug_product);
-
- list_free_with_free(bz->bug_cc);
-}
-
-/*
- * Static namespace for xmlrpc stuff.
- * Used mainly to ensure we always destroy xmlrpc client and server_info.
- */
-
-namespace {
-
-struct ctx: public abrt_xmlrpc_conn {
- xmlrpc_env env;
-
- ctx(const char* url, bool ssl_verify): abrt_xmlrpc_conn(url, ssl_verify)
- { xmlrpc_env_init(&env); }
- ~ctx() { xmlrpc_env_clean(&env); }
-
- void login(const char* login, const char* passwd);
- void logout();
-
- const char* get_bug_status(xmlrpc_value* result_xml);
- const char* get_bug_resolution(xmlrpc_value* result_xml);
- const char* get_bug_reporter(xmlrpc_value* result_xml);
- const char* get_bug_product(xmlrpc_value* relult_xml);
-
- xmlrpc_value* call_quicksearch_duphash(const char* component, const char* release, const char* duphash);
- xmlrpc_value* get_cc_member(xmlrpc_value* result_xml);
- xmlrpc_value* get_member(const char* member, xmlrpc_value* result_xml);
-
- int get_array_size(xmlrpc_value* result_xml);
- xmlrpc_int32 get_bug_id(xmlrpc_value* result_xml);
- xmlrpc_int32 get_bug_dup_id(xmlrpc_value* result_xml);
- 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(problem_data_t *problem_data, int depend_on_bugno);
- int add_attachments(const char* bug_id_str, problem_data_t *problem_data);
- 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);
-
- xmlrpc_value* call(const char* method, const char* format, ...);
-};
-
-xmlrpc_value* ctx::call(const char* method, const char* format, ...)
-{
- xmlrpc_value* result = NULL;
-
- if (!env.fault_occurred)
- {
- xmlrpc_value* param = NULL;
- va_list args;
- const char* suffix;
-
- va_start(args, format);
- xmlrpc_build_value_va(&env, format, args, &param, &suffix);
- va_end(args);
-
- if (*suffix != '\0')
- {
- xmlrpc_env_set_fault_formatted(
- &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument "
- "specifier: '%s'. There must be exactly one arument.",
- suffix);
- }
- else
- {
- xmlrpc_client_call2(&env, m_pClient, m_pServer_info, method, param, &result);
- }
- xmlrpc_DECREF(param);
- if (env.fault_occurred)
- return NULL;
- }
-
- return result;
-}
-
-xmlrpc_value* ctx::get_member(const char* member, xmlrpc_value* result_xml)
-{
- xmlrpc_value* cc_member = NULL;
- xmlrpc_struct_find_value(&env, result_xml, member, &cc_member);
- if (env.fault_occurred)
- return NULL;
-
- return cc_member;
-}
-
-int ctx::get_array_size(xmlrpc_value* result_xml)
-{
- int size = xmlrpc_array_size(&env, result_xml);
- if (env.fault_occurred)
- return -1;
-
- return size;
-}
-
-xmlrpc_int32 ctx::get_bug_dup_id(xmlrpc_value* result_xml)
-{
- xmlrpc_value* dup_id = get_member("dup_id", result_xml);
- if (!dup_id)
- return -1;
-
- xmlrpc_int32 dup_id_int = -1;
- xmlrpc_read_int(&env, dup_id, &dup_id_int);
- xmlrpc_DECREF(dup_id);
- if (env.fault_occurred)
- return -1;
-
- VERB3 log("got dup_id: %i", dup_id_int);
- return dup_id_int;
-}
-
-const char* ctx::get_bug_product(xmlrpc_value* result_xml)
-{
- xmlrpc_value* product_member = get_member("product", result_xml);
- if (!product_member) //should never happend. Each bug has to set up product
- return NULL;
-
- const char* product = NULL;
- xmlrpc_read_string(&env, product_member, &product);
- xmlrpc_DECREF(product_member);
- if (env.fault_occurred)
- return NULL;
-
- if (*product != '\0')
- {
- VERB3 log("got bug product: %s", product);
- return product;
- }
-
- free((void*)product);
- return NULL;
-}
-
-const char* ctx::get_bug_reporter(xmlrpc_value* result_xml)
-{
- xmlrpc_value* reporter_member = get_member("reporter", result_xml);
- if (!reporter_member)
- return NULL;
-
- const char* reporter = NULL;
- xmlrpc_read_string(&env, reporter_member, &reporter);
- xmlrpc_DECREF(reporter_member);
- if (env.fault_occurred)
- return NULL;
-
- if (*reporter != '\0')
- {
- VERB3 log("got bug reporter: %s", reporter);
- return reporter;
- }
- free((void*)reporter);
- return NULL;
-}
-
-const char* ctx::get_bug_resolution(xmlrpc_value* result_xml)
-{
- xmlrpc_value* bug_resolution = get_member("resolution", result_xml);
- if (!bug_resolution)
- return NULL;
-
- const char* resolution_str = NULL;
- xmlrpc_read_string(&env, bug_resolution, &resolution_str);
- xmlrpc_DECREF(bug_resolution);
- if (env.fault_occurred)
- return NULL;
-
- if (*resolution_str != '\0')
- {
- VERB3 log("got resolution: %s", resolution_str);
- return resolution_str;
- }
- free((void*)resolution_str);
- return NULL;
-}
-
-const char* ctx::get_bug_status(xmlrpc_value* result_xml)
-{
- xmlrpc_value* bug_status = get_member("bug_status", result_xml);
- if (!bug_status)
- return NULL;
-
- const char* status_str = NULL;
- xmlrpc_read_string(&env, bug_status, &status_str);
- xmlrpc_DECREF(bug_status);
- if (env.fault_occurred)
- return NULL;
-
- if (*status_str != '\0')
- {
- VERB3 log("got bug_status: %s", status_str);
- return status_str;
- }
- free((void*)status_str);
- return NULL;
-}
-
-void ctx::get_bug_cc(xmlrpc_value* result_xml, struct bug_info* bz)
-{
- xmlrpc_value* cc_member = get_member("cc", result_xml);
- if (!cc_member)
- return;
-
- int array_size = xmlrpc_array_size(&env, cc_member);
- if (array_size == -1)
- return;
-
- VERB3 log("count members on cc %i", array_size);
-
- for (int i = 0; i < array_size; i++)
- {
- xmlrpc_value* item = NULL;
- xmlrpc_array_read_item(&env, cc_member, i, &item);
- if (env.fault_occurred)
- return;
-
- if (item)
- {
- const char* cc = NULL;
- xmlrpc_read_string(&env, item, &cc);
- xmlrpc_DECREF(item);
- if (env.fault_occurred)
- {
- xmlrpc_DECREF(cc_member);
- return;
- }
-
- if (*cc != '\0')
- {
- bz->bug_cc = g_list_append(bz->bug_cc, (char*)cc);
- VERB3 log("member on cc is %s", cc);
- continue;
- }
- free((char*)cc);
- }
- }
- xmlrpc_DECREF(cc_member);
- return;
-}
-
-xmlrpc_value* ctx::call_quicksearch_duphash(const char* component,
- const char* release, const char* duphash)
-{
- char *query = NULL;
- if (!release)
- query = xasprintf("ALL component:\"%s\" whiteboard:\"%s\"", component, duphash);
- else
- {
- char *product = NULL;
- char *version = NULL;
- parse_release_for_bz(release, &product, &version);
- query = xasprintf("ALL component:\"%s\" whiteboard:\"%s\" product:\"%s\"",
- component, duphash, product
- );
- free(product);
- free(version);
- }
-
- VERB3 log("quicksearch for `%s'", query);
- xmlrpc_value *ret = call("Bug.search", "({s:s})", "quicksearch", query);
- free(query);
- return ret;
-}
-
-xmlrpc_int32 ctx::get_bug_id(xmlrpc_value* result_xml)
-{
- xmlrpc_value* item = NULL;
- xmlrpc_array_read_item(&env, result_xml, 0, &item);
- if (env.fault_occurred)
- return -1;
-
- xmlrpc_value* bug = get_member("bug_id", item);
- xmlrpc_DECREF(item);
- if (!bug)
- return -1;
-
- xmlrpc_int32 bug_id = -1;
- xmlrpc_read_int(&env, bug, &bug_id);
- xmlrpc_DECREF(bug);
- if (env.fault_occurred)
- return -1;
-
- VERB3 log("got bug_id %d", (int)bug_id);
- return bug_id;
-}
-
-int ctx::add_plus_one_cc(xmlrpc_int32 bug_id, const char* login)
-{
- xmlrpc_value* result = call("Bug.update", "({s:i,s:{s:(s)}})", "ids", (int)bug_id, "updates", "add_cc", login);
- if (result)
- xmlrpc_DECREF(result);
- return result ? 0 : -1;
-}
-
-int ctx::add_comment(xmlrpc_int32 bug_id, const char* comment, bool is_private)
-{
- xmlrpc_value* result = call("Bug.add_comment", "({s:i,s:s,s:b})", "id", (int)bug_id,
- "comment", comment,
- "private", is_private);
- if (result)
- xmlrpc_DECREF(result);
- return result ? 0 : -1;
-}
/* From RHEL6 kernel/panic.c:
* { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
@@ -415,6 +77,7 @@ static const char * const taint_warnings[] = {
NULL,
};
+/* TODO: npajkovs: fix tainted string */
static const char *tainted_string(unsigned tainted)
{
unsigned idx = 0;
@@ -424,207 +87,7 @@ static const char *tainted_string(unsigned tainted)
return taint_warnings[idx];
}
-xmlrpc_int32 ctx::new_bug(problem_data_t *problem_data, int depend_on_bugno)
-{
- const char *package = get_problem_item_content_or_NULL(problem_data, FILENAME_PACKAGE);
- const char *component = get_problem_item_content_or_NULL(problem_data, FILENAME_COMPONENT);
- const char *release = get_problem_item_content_or_NULL(problem_data, FILENAME_OS_RELEASE);
- if (!release) /* Old dump dir format compat. Remove in abrt-2.1 */
- release = get_problem_item_content_or_NULL(problem_data, "release");
- const char *arch = get_problem_item_content_or_NULL(problem_data, FILENAME_ARCHITECTURE);
- const char *duphash = get_problem_item_content_or_NULL(problem_data, FILENAME_DUPHASH);
- const char *reason = get_problem_item_content_or_NULL(problem_data, FILENAME_REASON);
- const char *function = get_problem_item_content_or_NULL(problem_data, FILENAME_CRASH_FUNCTION);
- const char *analyzer = get_problem_item_content_or_NULL(problem_data, FILENAME_ANALYZER);
- const char *tainted_str = get_problem_item_content_or_NULL(problem_data, FILENAME_TAINTED);
-
- struct strbuf *buf_summary = strbuf_new();
- strbuf_append_strf(buf_summary, "[abrt] %s", package);
-
- if (function != NULL && strlen(function) < 30)
- strbuf_append_strf(buf_summary, ": %s", function);
-
- if (reason != NULL)
- strbuf_append_strf(buf_summary, ": %s", reason);
-
- if (tainted_str && analyzer
- && (strcmp(analyzer, "Kerneloops") == 0)
- ) {
- unsigned long tainted = xatoi_positive(tainted_str);
- const char *tainted_warning = tainted_string(tainted);
- if (tainted_warning)
- strbuf_append_strf(buf_summary, ": TAINTED %s", tainted_warning);
- }
-
- char *status_whiteboard = xasprintf("abrt_hash:%s", duphash);
-
- char *bz_dsc = make_description_bz(problem_data);
- char *full_dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc);
- free(bz_dsc);
-
- char *product = NULL;
- char *version = NULL;
- parse_release_for_bz(release, &product, &version);
-
- xmlrpc_value* result = NULL;
- char *summary = strbuf_free_nobuf(buf_summary);
- if (depend_on_bugno > -1)
- {
- result = call("Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:i})",
- "product", product,
- "component", component,
- "version", version,
- "summary", summary,
- "description", full_dsc,
- "status_whiteboard", status_whiteboard,
- "platform", arch,
- "dependson", depend_on_bugno
- );
- }
- else
- {
- result = call("Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
- "product", product,
- "component", component,
- "version", version,
- "summary", summary,
- "description", full_dsc,
- "status_whiteboard", status_whiteboard,
- "platform", arch
- );
- }
- free(status_whiteboard);
- free(product);
- free(version);
- free(summary);
- free(full_dsc);
-
- if (!result)
- return -1;
-
- xmlrpc_value* id = get_member("id", result);
- xmlrpc_DECREF(result);
- if (!id)
- return -1;
-
- xmlrpc_int32 bug_id = -1;
- xmlrpc_read_int(&env, id, &bug_id);
- xmlrpc_DECREF(id);
- if (env.fault_occurred)
- return -1;
-
- log(_("New bug id: %i"), (int)bug_id);
-
- return bug_id;
-}
-
-int ctx::add_attachments(const char* bug_id_str, problem_data_t *problem_data)
-{
- GHashTableIter iter;
- char *name;
- struct problem_item *value;
- g_hash_table_iter_init(&iter, problem_data);
- while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value))
- {
- const char *content = value->content;
-
- // We were special-casing FILENAME_BACKTRACE here, but Karel says
- // he can retrieve it in inlined form from comments too.
- 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;
-
- xmlrpc_DECREF(result);
- }
- }
- return 0;
-}
-
-int ctx::get_bug_info(struct bug_info* bz, xmlrpc_int32 bug_id)
-{
- char bug_id_str[sizeof(long)*3 + 2];
- sprintf(bug_id_str, "%lu", (long)bug_id);
- xmlrpc_value* result = call("bugzilla.getBug", "(s)", bug_id_str);
- if (!result)
- return -1;
-
- bz->bug_product = get_bug_product(result);
- if (bz->bug_product == NULL)
- return -1;
-
- bz->bug_status = get_bug_status(result);
- if (bz->bug_status == NULL)
- return -1;
-
- bz->bug_reporter = get_bug_reporter(result);
- if (bz->bug_reporter == NULL)
- return -1;
-
- // mandatory when bug status is CLOSED
- if (strcmp(bz->bug_status, "CLOSED") == 0)
- {
- bz->bug_resolution = get_bug_resolution(result);
- if ((env.fault_occurred) && (bz->bug_resolution == NULL))
- return -1;
- }
-
- // mandatory when bug status is CLOSED and resolution is DUPLICATE
- if ((strcmp(bz->bug_status, "CLOSED") == 0)
- && (strcmp(bz->bug_resolution, "DUPLICATE") == 0)
- ) {
- bz->bug_dup_id = get_bug_dup_id(result);
- if (env.fault_occurred)
- return -1;
- }
-
- get_bug_cc(result, bz);
- if (env.fault_occurred)
- return -1;
-
- xmlrpc_DECREF(result);
- return 0;
-}
-
-void ctx::login(const char* login, const char* passwd)
-{
- xmlrpc_value* result = call("User.login", "({s:s,s:s})", "login", login, "password", passwd);
-//TODO: with URL like http://bugzilla.redhat.com (that is, with http: instead of https:)
-//we are getting this error:
-//Logging into Bugzilla at http://bugzilla.redhat.com
-//Can't login. Server said: HTTP response code is 301, not 200
-//But this is a 301 redirect! We _can_ follow it if we configure curl to understand that!
- if (!result)
- error_msg_and_die("Can't login. Server said: %s", env.fault_string);
- xmlrpc_DECREF(result);
-}
-
-void ctx::logout()
-{
- xmlrpc_value* result = call("User.logout", "(s)", "");
- if (result)
- xmlrpc_DECREF(result);
-
- throw_if_xml_fault_occurred(&env);
-}
-
-} /* namespace */
-
-
-static void report_to_bugzilla(
- const char *dump_dir_name,
- map_string_h *settings)
+static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings)
{
struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
@@ -669,13 +132,12 @@ static void report_to_bugzilla(
if (!release) /* Old dump dir format compat. Remove in abrt-2.1 */
release = get_problem_item_content_or_NULL(problem_data, "release");
- ctx bz_server(bugzilla_xmlrpc, ssl_verify);
+ struct abrt_xmlrpc *client = abrt_xmlrpc_new_client(bugzilla_xmlrpc, ssl_verify);
log(_("Logging into Bugzilla at %s"), bugzilla_url);
- bz_server.login(login, password);
+ rhbz_login(client, login, password);
log(_("Checking for duplicates"));
-
char *product = NULL;
char *version = NULL;
parse_release_for_bz(release, &product, &version);
@@ -683,225 +145,145 @@ static void report_to_bugzilla(
xmlrpc_value *result;
if (strcmp(product, "Fedora") == 0)
- result = bz_server.call_quicksearch_duphash(component, product, duphash);
+ result = rhbz_search_duphash(client, component, product, duphash);
else
- result = bz_server.call_quicksearch_duphash(component, NULL, duphash);
+ result = rhbz_search_duphash(client, component, NULL, duphash);
- if (!result)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- xmlrpc_value *all_bugs = bz_server.get_member("bugs", result);
+ xmlrpc_value *all_bugs = rhbz_get_member("bugs", result);
xmlrpc_DECREF(result);
if (!all_bugs)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
error_msg_and_die(_("Missing mandatory member 'bugs'"));
- }
- xmlrpc_int32 bug_id = -1;
- int all_bugs_size = bz_server.get_array_size(all_bugs);
- struct bug_info bz;
- int depend_on_bugno = -1;
+ int all_bugs_size = rhbz_array_size(all_bugs);
+ // When someone clones bug it has same duphash, so we can find more than 1.
+ // Need to be checked if component is same.
+ VERB3 log("Bugzilla has %i reports with same duphash '%s'",
+ all_bugs_size, duphash);
+
+ int bug_id = -1, dependent_bug = -1;
+ struct bug_info *bz = NULL;
if (all_bugs_size > 0)
{
- bug_id = bz_server.get_bug_id(all_bugs);
+ bug_id = rhbz_bug_id(all_bugs);
xmlrpc_DECREF(all_bugs);
- if (bug_id == -1)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- bug_info_init(&bz);
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
- error_msg_and_die(_("get_bug_info() failed. Could not collect all mandatory information"));
- }
+ bz = rhbz_bug_info(client, bug_id);
- if (strcmp(bz.bug_product, product) != 0)
+ if (strcmp(bz->bi_product, product) != 0)
{
- depend_on_bugno = bug_id;
- bug_info_destroy(&bz);
- result = bz_server.call_quicksearch_duphash(component, release, duphash);
- if (!result)
- throw_if_xml_fault_occurred(&bz_server.env);
+ dependent_bug = bug_id;
+ /* found something, but its a different product */
+ free_bug_info(bz);
- all_bugs = bz_server.get_member("bugs", result);
+ xmlrpc_value *result = rhbz_search_duphash(client, component,
+ product, duphash);
+ xmlrpc_value *all_bugs = rhbz_get_member("bugs", result);
xmlrpc_DECREF(result);
- if (!all_bugs)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- error_msg_and_die(_("Missing mandatory member 'bugs'"));
- }
-
- all_bugs_size = bz_server.get_array_size(all_bugs);
+ all_bugs_size = rhbz_array_size(all_bugs);
if (all_bugs_size > 0)
{
- bug_id = bz_server.get_bug_id(all_bugs);
- xmlrpc_DECREF(all_bugs);
- if (bug_id == -1)
- throw_if_xml_fault_occurred(&bz_server.env);
-
- bug_info_init(&bz);
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
- error_msg_and_die(_("get_bug_info() failed. Could not collect all mandatory information"));
- }
+ bug_id = rhbz_bug_id(all_bugs);
+ bz = rhbz_bug_info(client, bug_id);
}
- else
- xmlrpc_DECREF(all_bugs);
+ xmlrpc_DECREF(all_bugs);
}
+
}
free(product);
- if (all_bugs_size < 0)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
- else if (all_bugs_size == 0) // Create new bug
+ if (all_bugs_size == 0) // Create new bug
{
log(_("Creating a new bug"));
- bug_id = bz_server.new_bug(problem_data, depend_on_bugno);
- if (bug_id < 0)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- error_msg_and_die(_("Bugzilla entry creation failed"));
- }
+ bug_id = rhbz_new_bug(client, problem_data, bug_id);
- 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, problem_data);
- if (ret == -1)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
+ log("Adding attachments to bug %i", bug_id);
+ char bug_id_str[sizeof(int)*3 + 2];
+ sprintf(bug_id_str, "%i", bug_id);
+
+ rhbz_attachments(client, bug_id_str, problem_data);
log(_("Logging out"));
- bz_server.logout();
+ rhbz_logout(client);
- log("Status: NEW %s/show_bug.cgi?id=%u",
- bugzilla_url,
- (int)bug_id
- );
+ log("Status: NEW %s/show_bug.cgi?id=%u", bugzilla_url, bug_id);
+ abrt_xmlrpc_free_client(client);
return;
}
- if (all_bugs_size > 1)
- {
- // When someone clones bug it has same duphash, so we can find more than 1.
- // Need to be checked if component is same.
- VERB3 log("Bugzilla has %u reports with same duphash '%s'", all_bugs_size, duphash);
- }
-
// decision based on state
- log(_("Bug is already reported: %i"), bug_id);
-
- xmlrpc_int32 original_bug_id = bug_id;
- if ((strcmp(bz.bug_status, "CLOSED") == 0) && (strcmp(bz.bug_resolution, "DUPLICATE") == 0))
+ log(_("Bug is already reported: %i"), bz->bi_id);
+ if ((strcmp(bz->bi_status, "CLOSED") == 0)
+ && (strcmp(bz->bi_resolution, "DUPLICATE") == 0))
{
- for (int ii = 0; ii <= MAX_HOPS; ii++)
+ struct bug_info *origin;
+ origin = rhbz_find_origin_bug_closed_duplicate(client, bz);
+ if (origin)
{
- if (ii == MAX_HOPS)
- {
- VERB3 log("Bugzilla could not find a parent of bug %d", (int)original_bug_id);
- bug_info_destroy(&bz);
- error_msg_and_die(_("Bugzilla couldn't find parent of bug %d"), (int)original_bug_id);
- }
-
- log("Bug %d is a duplicate, using parent bug %d", bug_id, (int)bz.bug_dup_id);
- bug_id = bz.bug_dup_id;
- bug_info_destroy(&bz);
- bug_info_init(&bz);
-
- if (bz_server.get_bug_info(&bz, bug_id) == -1)
- {
- bug_info_destroy(&bz);
- if (bz_server.env.fault_occurred)
- {
- throw_if_xml_fault_occurred(&bz_server.env);
- }
- error_msg_and_die(_("get_bug_info() failed. Could not collect all mandatory information"));
- }
-
- // found a bug which is not CLOSED as DUPLICATE
- if (bz.bug_dup_id == -1)
- break;
+ free_bug_info(bz);
+ bz = origin;
}
}
- if (strcmp(bz.bug_status, "CLOSED") != 0)
+ if (strcmp(bz->bi_status, "CLOSED") != 0)
{
- int status = 0;
- if ((strcmp(bz.bug_reporter, login) != 0)
- && (g_list_find(bz.bug_cc, login)))
+ if ((strcmp(bz->bi_reporter, login) != 0)
+ && (!g_list_find_custom(bz->bi_cc_list, login, (GCompareFunc)g_strcmp0)))
{
log(_("Add %s to CC list"), login);
- status = bz_server.add_plus_one_cc(bug_id, login);
- }
-
- if (status == -1)
- {
- bug_info_destroy(&bz);
- throw_if_xml_fault_occurred(&bz_server.env);
+ rhbz_mail_to_cc(client, bz->bi_id, login);
}
char *dsc = make_description_comment(problem_data);
if (dsc)
{
- const char* package = get_problem_item_content_or_NULL(problem_data, FILENAME_PACKAGE);
- const char* release = get_problem_item_content_or_NULL(problem_data, FILENAME_OS_RELEASE);
+ const char *package = get_problem_item_content_or_NULL(problem_data,
+ FILENAME_PACKAGE);
+ const char *release = get_problem_item_content_or_NULL(problem_data,
+ FILENAME_OS_RELEASE);
if (!release) /* Old dump dir format compat. Remove in abrt-2.1 */
release = get_problem_item_content_or_NULL(problem_data, "release");
- const char* arch = get_problem_item_content_or_NULL(problem_data, FILENAME_ARCHITECTURE);
- const char* is_private = get_problem_item_content_or_NULL(problem_data, "is_private");
+ const char *arch = get_problem_item_content_or_NULL(problem_data,
+ FILENAME_ARCHITECTURE);
+ const char *is_private = get_problem_item_content_or_NULL(problem_data,
+ "is_private");
char *full_dsc = xasprintf("Package: %s\n"
- "Architecture: %s\n"
- "OS Release: %s\n"
- "%s", package, arch, release, dsc
- );
-
- log(_("Adding new comment to bug %d"), (int)bug_id);
+ "Architecture: %s\n"
+ "OS Release: %s\n"
+ "%s", package, arch, release, dsc);
+ log(_("Adding new comment to bug %d"), bz->bi_id);
free(dsc);
- bool is_priv = is_private && string_to_bool(is_private);
- if (bz_server.add_comment(bug_id, full_dsc, is_priv) == -1)
- {
- free(full_dsc);
- bug_info_destroy(&bz);
- throw_xml_fault(&bz_server.env);
- }
+ int is_priv = is_private && string_to_bool(is_private);
+ rhbz_add_comment(client, bz->bi_id, full_dsc, is_priv);
free(full_dsc);
}
}
log(_("Logging out"));
- bz_server.logout();
+ rhbz_logout(client);
log("Status: %s%s%s %s/show_bug.cgi?id=%u",
- bz.bug_status,
- bz.bug_resolution ? " " : "",
- bz.bug_resolution ? bz.bug_resolution : "",
+ bz->bi_status,
+ bz->bi_resolution ? " " : "",
+ bz->bi_resolution ? bz->bi_resolution : "",
bugzilla_url,
- (int)bug_id
- );
+ bz->bi_id);
dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
- char *msg = xasprintf("Bugzilla: URL=%s/show_bug.cgi?id=%u", bugzilla_url, (int)bug_id);
+ char *msg = xasprintf("Bugzilla: URL=%s/show_bug.cgi?id=%u", bugzilla_url, bz->bi_id);
add_reported_to(dd, msg);
free(msg);
dd_close(dd);
}
free_problem_data(problem_data);
- bug_info_destroy(&bz);
+ free_bug_info(bz);
+ abrt_xmlrpc_free_client(client);
}
int main(int argc, char **argv)