Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
.gitignore | 1 +
configure.ac | 1 +
libreport.spec.in | 15 +++
src/include/internal_libreport.h | 2 +
src/lib/Makefile.am | 6 +-
src/lib/json.c | 257 ++++++++++++++++++++++++++++++++++++++
src/plugins/Makefile.am | 16 ++-
src/plugins/ureport.c | 52 ++++++++
8 files changed, 348 insertions(+), 2 deletions(-)
create mode 100644 src/lib/json.c
create mode 100644 src/plugins/ureport.c
diff --git a/.gitignore b/.gitignore
index 88419e9..5492e17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ src/plugins/reporter-mailx
src/plugins/reporter-print
src/plugins/reporter-rhtsupport
src/plugins/reporter-upload
+src/plugins/reporter-ureport
src/plugins/report
src/plugins/abrt-bodhi
src/report-newt/report-newt
diff --git a/configure.ac b/configure.ac
index 851cc89..2d5dd25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,7 @@ PKG_CHECK_MODULES([CURL], [libcurl])
PKG_CHECK_MODULES([GNOME_KEYRING], [gnome-keyring-1])
PKG_CHECK_MODULES([JSON_C], [json])
PKG_CHECK_MODULES([RPM], [rpm])
+PKG_CHECK_MODULES([BTPARSER], [btparser])
# Just PKG_CHECK_MODULES([PYTHON], [python]) works only with python2.7+
# Below, if python is not found, we set up for python2.6 w/o checking:
diff --git a/libreport.spec.in b/libreport.spec.in
index b7d5550..fc40192 100644
--- a/libreport.spec.in
+++ b/libreport.spec.in
@@ -27,6 +27,7 @@ BuildRequires: asciidoc
BuildRequires: xmlto
BuildRequires: newt-devel
BuildRequires: libproxy-devel
+BuildRequires: btparser-devel
Requires: libreport-filesystem
# required for update from old report library, otherwise we obsolete report-gtk
# and all it's plugins, but don't provide the python bindings and the sealert
@@ -170,6 +171,15 @@ BuildRequires: rpm-devel
%description plugin-bodhi
Search for a new updates in bodhi server
+%package plugin-ureport
+Summary: %{name}'s bodhi plugin
+BuildRequires: json-c-devel
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description plugin-ureport
+Uploads micro-report to abrt server
+
%description plugin-bugzilla
Plugin to report bugs into the bugzilla.
@@ -343,6 +353,11 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%{_bindir}/abrt-bodhi
%{_mandir}/man1/abrt-bodhi.1.gz
+%files plugin-ureport
+%defattr(-,root,root,-)
+%{_bindir}/reporter-ureport
+#%{_mandir}/man1/reporter-ureport.1.gz
+
%files plugin-bugzilla
%defattr(-,root,root,-)
%config(noreplace) %{_sysconfdir}/libreport/plugins/bugzilla.conf
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
index c46a525..94482af 100644
--- a/src/include/internal_libreport.h
+++ b/src/include/internal_libreport.h
@@ -788,6 +788,8 @@ unsigned parse_opts(int argc, char **argv, const struct options *opt,
#define show_usage_and_die libreport_show_usage_and_die
void show_usage_and_die(const char *usage, const struct options *opt) NORETURN;
+#define post_ureport libreport_post_ureport
+int post_ureport(problem_data_t *pd);
#ifdef __cplusplus
}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index cffabb2..6315591 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -94,7 +94,7 @@ libabrt_dbus_la_LIBADD = \
libabrt_web_la_SOURCES = \
abrt_curl.h abrt_curl.c \
abrt_xmlrpc.h abrt_xmlrpc.c \
- proxies.h proxies.c
+ proxies.h proxies.c json.c
libabrt_web_la_CPPFLAGS = \
-Wall -Wwrite-strings -Werror \
-I$(srcdir)/../include \
@@ -109,6 +109,8 @@ libabrt_web_la_CPPFLAGS = \
$(LIBXML_CFLAGS) \
$(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \
$(LIBREPORT_CFLAGS) \
+ $(JSON_C_CFLAGS) \
+ $(BTPARSER_CFLAGS) \
-D_GNU_SOURCE
libabrt_web_la_LDFLAGS = \
-version-info 0:1:0
@@ -117,6 +119,8 @@ libabrt_web_la_LIBADD = \
$(CURL_LIBS) \
$(PROXY_LIBS) \
$(LIBXML_LIBS) \
+ $(JSON_C_LIBS) \
+ $(BTPARSER_LIBS) \
$(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS)
$(DESTDIR)/$(DEBUG_DUMPS_DIR):
diff --git a/src/lib/json.c b/src/lib/json.c
new file mode 100644
index 0000000..935eadf
--- /dev/null
+++ b/src/lib/json.c
@@ -0,0 +1,257 @@
+/*
+ Copyright (C) 2012 ABRT team
+ Copyright (C) 2012 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 <json/json.h>
+#include <btparser/thread.h>
+#include <btparser/core-backtrace.h>
+
+#include "internal_libreport.h"
+#include "abrt_curl.h"
+
+
+static const char *ureport_url = "10.34.24.254/cgi-bin/json.cgi";
+
+/* on success 1 returned, on error zero is returned and appropriate value
+ * is returned as third argument. You should never read third argument when
+ * function fails
+ *
+ * json-c library doesn't have any json_object_new_long,
+ * thus we have to use only int
+ */
+static int get_pd_int_item(problem_data_t *pd, const char *key, int *result)
+{
+ if (!pd || !key)
+ return 0;
+
+ char *pd_item = get_problem_item_content_or_NULL(pd, key);
+ if (!pd_item)
+ {
+ VERB1 log("warning: '%s' is not an item in problem directory", key);
+ return 0;
+ }
+
+ int old_errno = errno;
+ errno = 0;
+ char *e;
+ long i = strtol(pd_item, &e, 10);
+ if (errno || pd_item == e || *e != '\0' || (int) i != i)
+ return 0;
+
+ *result = i;
+
+ errno = old_errno;
+ return 1;
+}
+
+static void ureport_add_int(struct json_object *ur, const char *key, int i)
+{
+ struct json_object *jint = json_object_new_int(i);
+ if (!jint)
+ return;
+
+ json_object_object_add(ur, key, jint);
+}
+
+static void ureport_add_str(struct json_object *ur, const char *key,
+ const char *s)
+{
+ struct json_object *jstring = json_object_new_string(s);
+ if (!jstring)
+ return;
+
+ json_object_object_add(ur, key, jstring);
+}
+
+static void ureport_add_os(struct json_object *ur, problem_data_t *pd)
+{
+ struct json_object *jobject = json_object_new_object();
+
+ char *pd_item = get_problem_item_content_or_NULL(pd, FILENAME_OS_RELEASE);
+ if (!pd_item)
+ return;
+
+ char *name, *version;
+ parse_release_for_rhts(pd_item, &name, &version);
+
+ ureport_add_str(jobject, "name", name);
+ ureport_add_str(jobject, "version", version);
+
+ json_object_object_add(ur, "os", jobject);
+}
+
+static void ureport_add_type(struct json_object *ur, problem_data_t *pd)
+{
+ char *pd_item = get_problem_item_content_or_NULL(pd, "analyzer");
+ if (!pd_item)
+ return;
+
+ const char type[] = "type";
+ if (!strcmp(pd_item, "CCpp"))
+ ureport_add_str(ur, type, "USERSPACE");
+ if (!strcmp(pd_item, "Python"))
+ ureport_add_str(ur, type, "PYTHON");
+ if (!strcmp(pd_item, "Kerneloops"))
+ ureport_add_str(ur, type, "KERNELOOPS");
+}
+
+static void ureport_add_core_backtrace(struct json_object *ur, problem_data_t *pd)
+{
+ char *pd_item = get_problem_item_content_or_NULL(pd, FILENAME_CORE_BACKTRACE);
+ if (!pd_item)
+ return;
+
+ struct json_object *jarray = json_object_new_array();
+ if (!jarray)
+ return;
+
+ struct btp_thread *core_bt = btp_load_core_backtrace(pd_item);
+ if (!core_bt)
+ return;
+
+ struct btp_frame *frame;
+ unsigned frame_nr = 0;
+ for (frame = core_bt->frames; frame; frame = frame->next)
+ {
+ struct frame_aux *aux = frame->user_data;
+
+ struct json_object *item = json_object_new_object();
+ log("funcname '%s'", frame->function_name);
+ if (frame->function_name)
+ ureport_add_str(item, "funcname", frame->function_name);
+
+ log("buildid '%s'", aux->build_id);
+ if (aux->build_id)
+ ureport_add_str(item, "buildid", aux->build_id);
+
+ log("fingerprint '%s'", aux->fingerprint);
+ if (aux->fingerprint)
+ ureport_add_str(item, "funchash", aux->fingerprint);
+
+ if ((uintmax_t)frame->address)
+ ureport_add_int(item, "offset", (uintmax_t)frame->address);
+
+ ureport_add_int(item, "frame", frame_nr++);
+ ureport_add_int(item, "thread", 0);
+
+
+ json_object_array_add(jarray, item);
+ }
+
+
+ json_object_object_add(ur, FILENAME_CORE_BACKTRACE, jarray);
+}
+
+#define ureport_add_id_str(name) \
+ static inline void ureport_add_##name(struct json_object *ur, \
+ problem_data_t *pd, \
+ const char *skip_pfx) \
+ { \
+ char *pd_item = get_problem_item_content_or_NULL(pd, #name); \
+ if (!pd_item) \
+ return; \
+ \
+ const char *name = skip_pfx ? #name + strlen(skip_pfx): #name; \
+ ureport_add_str(ur, name, pd_item); \
+ }
+
+#define ureport_add_id_int(name) \
+ static inline void ureport_add_##name(struct json_object *ur, \
+ problem_data_t *pd, \
+ const char *skip_pfx) \
+ { \
+ int nr; \
+ int stat = get_pd_int_item(pd, #name, &nr); \
+ if (!stat) \
+ return; \
+ \
+ const char *name = skip_pfx ? #name + strlen(skip_pfx): #name; \
+ ureport_add_int(ur, name, nr); \
+ }
+
+ureport_add_id_str(architecture);
+ureport_add_id_str(executable);
+ureport_add_id_str(reason);
+ureport_add_id_str(user_type);
+ureport_add_id_str(pkg_name);
+ureport_add_id_str(pkg_version);
+ureport_add_id_str(pkg_release);
+ureport_add_id_str(pkg_arch);
+
+ureport_add_id_int(uptime);
+ureport_add_id_int(crash_thread);
+ureport_add_id_int(pkg_epoch);
+
+static void ureport_add_pkg(struct json_object *ur, problem_data_t *pd)
+{
+ struct json_object *jobject = json_object_new_object();
+ if (!jobject)
+ return;
+
+ ureport_add_pkg_epoch(jobject, pd, "pkg_");
+ ureport_add_pkg_name(jobject, pd, "pkg_");
+ ureport_add_pkg_version(jobject, pd, "pkg_");
+ ureport_add_pkg_release(jobject, pd, "pkg_");
+ ureport_add_pkg_arch(jobject, pd, "pkg_");
+
+ json_object_object_add(ur, "installed_package", jobject);
+
+}
+
+const char *new_json_ureport(problem_data_t *pd)
+{
+ struct json_object *ureport = json_object_new_object();
+
+ ureport_add_user_type(ureport, pd, NULL);
+ ureport_add_crash_thread(ureport, pd, NULL);
+ ureport_add_uptime(ureport, pd, NULL);
+ ureport_add_architecture(ureport, pd, NULL);
+ ureport_add_executable(ureport, pd, NULL);
+ ureport_add_reason(ureport, pd, NULL);
+
+ ureport_add_type(ureport, pd);
+
+ ureport_add_pkg(ureport, pd);
+ ureport_add_os(ureport, pd);
+
+ ureport_add_core_backtrace(ureport, pd);
+
+ return json_object_to_json_string(ureport);
+}
+
+int post_ureport(problem_data_t *pd)
+{
+ abrt_post_state_t *post_state;
+ post_state = new_abrt_post_state(ABRT_POST_WANT_BODY
+ | ABRT_POST_WANT_SSL_VERIFY
+ | ABRT_POST_WANT_ERROR_MSG);
+
+ const char *headers[] = {
+ "Accept: application/json",
+ "Connection: close",
+ "X-Task-Type: 1",
+ NULL,
+ };
+
+ const char *json_ureport = new_json_ureport(pd);
+
+ abrt_post_string(post_state, ureport_url, "text/plain",
+ headers, json_ureport);
+
+ return 0;
+}
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 6514ff6..476a59d 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -8,7 +8,8 @@ bin_PROGRAMS = \
reporter-mailx \
reporter-print \
report \
- abrt-bodhi
+ abrt-bodhi \
+ reporter-ureport
pluginsconfdir = $(PLUGINS_CONF_DIR)
@@ -218,4 +219,17 @@ abrt_bodhi_LDADD = \
../lib/libreport.la \
../lib/libabrt_web.la
+reporter_ureport_SOURCES = \
+ ureport.c
+reporter_ureport_CPPFLAGS = \
+ -I$(srcdir)/../include \
+ -I$(srcdir)/../lib \
+ $(GLIB_CFLAGS) \
+ $(LIBREPORT_CFLAGS) \
+ -D_GNU_SOURCE \
+ -Wall -Wwrite-strings -Werror
+reporter_ureport_LDADD = \
+ ../lib/libreport.la \
+ ../lib/libabrt_web.la
+
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
diff --git a/src/plugins/ureport.c b/src/plugins/ureport.c
new file mode 100644
index 0000000..a9f85fc
--- /dev/null
+++ b/src/plugins/ureport.c
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2012 ABRT Team
+ Copyright (C) 2012 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 main(int argc, char **argv)
+{
+ abrt_init(argv);
+
+ const char *dump_dir_path = ".";
+ struct options program_options[] = {
+ OPT__VERBOSE(&g_verbose),
+ OPT__DUMP_DIR(&dump_dir_path),
+ OPT_END(),
+ };
+
+ const char *program_usage_string = _(
+ "& [-v] -d DIR\n"
+ "\n"
+ "Upload micro report"
+ );
+
+ parse_opts(argc, argv, program_options, program_usage_string);
+ struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY);
+ if (!dd)
+ xfunc_die();
+
+ problem_data_t *pd = create_problem_data_from_dump_dir(dd);
+ dd_close(dd);
+ if (!pd)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
+
+ post_ureport(pd);
+
+ return 0;
+}
--
1.7.9.3