--- configure.ac | 9 + libreport.spec.in | 102 +++++++ src/Makefile.am | 2 +- src/lib/Makefile.am | 28 ++ src/lib/abrt_curl.c | 435 ++++++++++++++++++++++++++++++ src/lib/abrt_curl.h | 103 +++++++ src/lib/abrt_xmlrpc.c | 137 ++++++++++ src/lib/abrt_xmlrpc.h | 51 ++++ src/plugins/Bugzilla.conf | 12 + src/plugins/Kerneloops.conf | 3 + src/plugins/Makefile.am | 208 +++++++++++++++ src/plugins/Upload.conf | 9 + src/plugins/abrt_rh_support.c | 460 ++++++++++++++++++++++++++++++++ src/plugins/abrt_rh_support.h | 55 ++++ src/plugins/mailx_events.conf | 1 + src/plugins/print_events.conf | 2 + src/plugins/report_Bugzilla.conf | 4 + src/plugins/report_Bugzilla.xml.in | 36 +++ src/plugins/report_Kerneloops.xml.in | 20 ++ src/plugins/report_Logger.conf | 2 + src/plugins/report_Mailx.xml.in | 35 +++ src/plugins/report_RHTSupport.xml.in | 35 +++ src/plugins/reporter-bugzilla.c | 291 ++++++++++++++++++++ src/plugins/reporter-bugzilla.txt | 67 +++++ src/plugins/reporter-kerneloops.c | 166 ++++++++++++ src/plugins/reporter-kerneloops.txt | 68 +++++ src/plugins/reporter-mailx.c | 162 +++++++++++ src/plugins/reporter-mailx.txt | 91 +++++++ src/plugins/reporter-print.c | 95 +++++++ src/plugins/reporter-print.txt | 63 +++++ src/plugins/reporter-rhtsupport.c | 342 ++++++++++++++++++++++++ src/plugins/reporter-upload.c | 287 ++++++++++++++++++++ src/plugins/reporter-upload.txt | 67 +++++ src/plugins/rhbz.c | 488 ++++++++++++++++++++++++++++++++++ src/plugins/rhbz.h | 103 +++++++ src/plugins/rhtsupport_events.conf | 1 + 36 files changed, 4039 insertions(+), 1 deletions(-) create mode 100644 src/lib/abrt_curl.c create mode 100644 src/lib/abrt_curl.h create mode 100644 src/lib/abrt_xmlrpc.c create mode 100644 src/lib/abrt_xmlrpc.h create mode 100644 src/plugins/Bugzilla.conf create mode 100644 src/plugins/Kerneloops.conf create mode 100644 src/plugins/Makefile.am create mode 100644 src/plugins/Upload.conf create mode 100644 src/plugins/abrt_rh_support.c create mode 100644 src/plugins/abrt_rh_support.h create mode 100644 src/plugins/mailx_events.conf create mode 100644 src/plugins/print_events.conf create mode 100644 src/plugins/report_Bugzilla.conf create mode 100644 src/plugins/report_Bugzilla.xml.in create mode 100644 src/plugins/report_Kerneloops.xml.in create mode 100644 src/plugins/report_Logger.conf create mode 100644 src/plugins/report_Mailx.xml.in create mode 100644 src/plugins/report_RHTSupport.xml.in create mode 100644 src/plugins/reporter-bugzilla.c create mode 100644 src/plugins/reporter-bugzilla.txt create mode 100644 src/plugins/reporter-kerneloops.c create mode 100644 src/plugins/reporter-kerneloops.txt create mode 100644 src/plugins/reporter-mailx.c create mode 100644 src/plugins/reporter-mailx.txt create mode 100644 src/plugins/reporter-print.c create mode 100644 src/plugins/reporter-print.txt create mode 100644 src/plugins/reporter-rhtsupport.c create mode 100644 src/plugins/reporter-upload.c create mode 100644 src/plugins/reporter-upload.txt create mode 100644 src/plugins/rhbz.c create mode 100644 src/plugins/rhbz.h create mode 100644 src/plugins/rhtsupport_events.conf
diff --git a/configure.ac b/configure.ac index f2569ca..61f16ae 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,9 @@ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) PKG_CHECK_MODULES([NSS], [nss]) +PKG_CHECK_MODULES([XMLRPC], [xmlrpc]) +PKG_CHECK_MODULES([XMLRPC_CLIENT], [xmlrpc_client]) +PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([GNOME_KEYRING], [gnome-keyring-1]) # 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: @@ -72,9 +75,13 @@ PKG_CHECK_MODULES([NEWT], [libnewt])
PKG_PROG_PKG_CONFIG
+AC_CHECK_HEADER([libtar.h], [], + [AC_MSG_ERROR([libtar.h is needed to build libreport])]) + CONF_DIR='${sysconfdir}/${PACKAGE_NAME}' VAR_RUN='${localstatedir}/run' PLUGINS_CONF_DIR='${sysconfdir}/${PACKAGE_NAME}/plugins' +REPORT_PLUGINS_CONF_DIR='${sysconfdir}/libreport/plugins' EVENTS_DIR='${sysconfdir}/${PACKAGE_NAME}/events' EVENTS_CONF_DIR='${sysconfdir}/${PACKAGE_NAME}/events.d' PLUGINS_LIB_DIR='${libdir}/${PACKAGE_NAME}' @@ -90,6 +97,7 @@ AC_ARG_WITH(debugdumpsdir, AC_SUBST(CONF_DIR) AC_SUBST(VAR_RUN) AC_SUBST(PLUGINS_CONF_DIR) +AC_SUBST(REPORT_PLUGINS_CONF_DIR) AC_SUBST(EVENTS_CONF_DIR) AC_SUBST(EVENTS_DIR) AC_SUBST(PLUGINS_LIB_DIR) @@ -117,6 +125,7 @@ AC_CONFIG_FILES([ src/gui-wizard-gtk/Makefile src/cli/Makefile src/report-newt/Makefile + src/plugins/Makefile po/Makefile.in ])
diff --git a/libreport.spec.in b/libreport.spec.in index c5bb390..40c119a 100644 --- a/libreport.spec.in +++ b/libreport.spec.in @@ -98,6 +98,63 @@ Requires: libreport-gtk = %{version}-%{release} %description gtk-devel Development libraries and headers for libreport-gtk
+%package plugin-kerneloops +Summary: %{name}'s kerneloops reporter plugin +Group: System Environment/Libraries +Requires: curl +Requires: %{name} = %{version}-%{release} + +%description plugin-kerneloops +This package contains plugin which sends kernel crash information to specified +server, usually to kerneloops.org. + +%package plugin-logger +Summary: %{name}'s logger reporter plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Obsoletes: abrt-plugin-logger < 2.0.4 + +%description plugin-logger +The simple reporter plugin which writes a report to a specified file. + +%package plugin-mailx +Summary: %{name}'s mailx reporter plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Requires: mailx +Obsoletes: abrt-plugin-mailx < 2.0.4 + +%description plugin-mailx +The simple reporter plugin which sends a report via mailx to a specified +email address. + +%package plugin-bugzilla +Summary: %{name}'s bugzilla plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Obsoletes: abrt-plugin-bugzilla < 2.0.4 + +%description plugin-bugzilla +Plugin to report bugs into the bugzilla. + +%package plugin-rhtsupport +Summary: %{name}'s RHTSupport plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Obsoletes: abrt-plugin-rhtsupport < 2.0.4 + +%description plugin-rhtsupport +Plugin to report bugs into RH support system. + +%package plugin-reportuploader +Summary: %{name}'s reportuploader plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Obsoletes: abrt-plugin-reportuploader < 2.0.4 + +%description plugin-reportuploader +Plugin to report bugs into anonymous FTP site associated with ticketing system. + %prep %setup -q
@@ -154,6 +211,8 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %config(noreplace) %{_sysconfdir}/%{name}/report_event.conf %{_libdir}/libreport.so.* %{_libdir}/libabrt_dbus.so.* +%{_libdir}/libabrt_web.so.* +%exclude %{_libdir}/libabrt_web.so
%files devel %defattr(-,root,root,-) @@ -196,6 +255,49 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_includedir}/libreport/internal_libreport_gtk.h %{_libdir}/pkgconfig/libreport-gtk.pc
+%files plugin-kerneloops +%defattr(-,root,root,-) +%config(noreplace) %{_sysconfdir}/libreport/plugins/Kerneloops.conf +%{_sysconfdir}/libreport/events/report_Kerneloops.xml +%{_mandir}/man*/reporter-kerneloops.* +%{_bindir}/reporter-kerneloops + +%files plugin-logger +%defattr(-,root,root,-) +%{_sysconfdir}/libreport/events/report_Logger.conf +%config(noreplace) %{_sysconfdir}/libreport/events.d/print_events.conf +%{_bindir}/reporter-print +%{_mandir}/man*/reporter-print.* + +%files plugin-mailx +%defattr(-,root,root,-) +%{_sysconfdir}/libreport/events/report_Mailx.xml +%config(noreplace) %{_sysconfdir}/libreport/events.d/mailx_events.conf +%{_mandir}/man*/reporter-mailx.* +%{_bindir}/reporter-mailx + +%files plugin-bugzilla +%defattr(-,root,root,-) +%config(noreplace) %{_sysconfdir}/libreport/plugins/Bugzilla.conf +%{_sysconfdir}/libreport/events/report_Bugzilla.xml +%config(noreplace) %{_sysconfdir}/libreport/events/report_Bugzilla.conf +# FIXME: remove with the old gui +%{_mandir}/man1/reporter-bugzilla.1.gz +%{_bindir}/reporter-bugzilla + +%files plugin-rhtsupport +%defattr(-,root,root,-) +%{_sysconfdir}/libreport/events/report_RHTSupport.xml +%config(noreplace) %{_sysconfdir}/libreport/events.d/rhtsupport_events.conf +# {_mandir}/man7/abrt-RHTSupport.7.gz +%{_bindir}/reporter-rhtsupport + +%files plugin-reportuploader +%defattr(-,root,root,-) +%config(noreplace) %{_sysconfdir}/libreport/plugins/Upload.conf +%{_mandir}/man*/reporter-upload.* +%{_bindir}/reporter-upload + %changelog * Wed Jun 01 2011 Jiri Moskovcak jmoskovc@redhat.com 2.0.2-1 - initial packaging diff --git a/src/Makefile.am b/src/Makefile.am index cba73c0..24dfeb2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1 +1 @@ -SUBDIRS = include lib report-python gtk-helpers gui-wizard-gtk cli report-newt +SUBDIRS = include lib plugins report-python gtk-helpers gui-wizard-gtk cli report-newt diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index ea86dc3..7b870d9 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,6 +1,7 @@ # libreport - the stuff shared among most of abrt (like xmalloc, logging) lib_LTLIBRARIES = \ libreport.la \ + libabrt_web.la \ libabrt_dbus.la
# Not used just yet: @@ -90,6 +91,33 @@ libabrt_dbus_la_LIBADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS)
+libabrt_web_la_SOURCES = \ + abrt_curl.h abrt_curl.c \ + abrt_xmlrpc.h abrt_xmlrpc.c +libabrt_web_la_CPPFLAGS = \ + -Wall -Wwrite-strings -Werror \ + -I$(srcdir)/../include \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DVAR_RUN="$(VAR_RUN)" \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(PLUGINS_CONF_DIR)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DEVENTS_DIR="$(EVENTS_DIR)" \ + $(GLIB_CFLAGS) \ + $(CURL_CFLAGS) \ + $(LIBXML_CFLAGS) \ + $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE +libabrt_web_la_LDFLAGS = \ + -version-info 0:1:0 +libabrt_web_la_LIBADD = \ + $(GLIB_LIBS) \ + $(CURL_LIBS) \ + $(LIBXML_LIBS) \ + $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) + $(DESTDIR)/$(DEBUG_DUMPS_DIR): $(mkdir_p) '$@' # no need to chmod it here diff --git a/src/lib/abrt_curl.c b/src/lib/abrt_curl.c new file mode 100644 index 0000000..9831862 --- /dev/null +++ b/src/lib/abrt_curl.c @@ -0,0 +1,435 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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" +#include "abrt_curl.h" + +/* + * Utility functions + */ +CURL* xcurl_easy_init() +{ + CURL* curl = curl_easy_init(); + if (!curl) + { + error_msg_and_die("Can't create curl handle"); + } + return curl; +} + +static char* +check_curl_error(CURLcode err, const char* msg) +{ + if (err) + return xasprintf("%s: %s", msg, curl_easy_strerror(err)); + return NULL; +} + +static void +die_if_curl_error(CURLcode err) +{ + if (err) { + char *msg = check_curl_error(err, "curl"); + error_msg_and_die("%s", msg); + } +} + +static void +xcurl_easy_setopt_ptr(CURL *handle, CURLoption option, const void *parameter) +{ + CURLcode err = curl_easy_setopt(handle, option, parameter); + if (err) { + char *msg = check_curl_error(err, "curl"); + error_msg_and_die("%s", msg); + } +} +static inline void +xcurl_easy_setopt_long(CURL *handle, CURLoption option, long parameter) +{ + xcurl_easy_setopt_ptr(handle, option, (void*)parameter); +} + +/* + * post_state utility functions + */ + +abrt_post_state_t *new_abrt_post_state(int flags) +{ + abrt_post_state_t *state = (abrt_post_state_t *)xzalloc(sizeof(*state)); + state->flags = flags; + return state; +} + +void free_abrt_post_state(abrt_post_state_t *state) +{ + char **headers = state->headers; + if (headers) + { + while (*headers) + free(*headers++); + free(state->headers); + } + free(state->curl_error_msg); + free(state->body); + free(state); +} + +char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str) +{ + char **headers = state->headers; + if (headers) + { + unsigned len = strlen(str); + while (*headers) + { + if (strncmp(*headers, str, len) == 0) + return skip_whitespace(*headers + len); + headers++; + } + } + return NULL; +} + +/* + * abrt_post: perform HTTP POST transaction + */ + +/* "save headers" callback */ +static size_t +save_headers(void *buffer_pv, size_t count, size_t nmemb, void *ptr) +{ + abrt_post_state_t* state = (abrt_post_state_t*)ptr; + size_t size = count * nmemb; + + char *h = xstrndup((char*)buffer_pv, size); + strchrnul(h, '\r')[0] = '\0'; + strchrnul(h, '\n')[0] = '\0'; + + unsigned cnt = state->header_cnt; + + /* Check for the case when curl follows a redirect: + * header 0: 'HTTP/1.1 301 Moved Permanently' + * header 1: 'Connection: close' + * header 2: 'Location: NEW_URL' + * header 3: '' + * header 0: 'HTTP/1.1 200 OK' <-- we need to forget all hdrs and start anew + */ + if (cnt != 0 + && strncmp(h, "HTTP/", 5) == 0 + && state->headers[cnt-1][0] == '\0' /* prev header is an empty string */ + ) { + char **headers = state->headers; + if (headers) + { + while (*headers) + free(*headers++); + } + cnt = 0; + } + + VERB3 log("save_headers: header %d: '%s'", cnt, h); + state->headers = (char**)xrealloc(state->headers, (cnt+2) * sizeof(state->headers[0])); + state->headers[cnt] = h; + state->header_cnt = ++cnt; + state->headers[cnt] = NULL; + + return size; +} + +/* "read local data from a file" callback */ +static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata) +{ + static time_t last_t; // hack + + FILE *fp = (FILE*)userdata; + time_t t = time(NULL); + + // Report current file position every 16 seconds + if (!(t & 0xf) && last_t != t) + { + last_t = t; + off_t cur_pos = ftello(fp); + fseeko(fp, 0, SEEK_END); + off_t sz = ftello(fp); + fseeko(fp, cur_pos, SEEK_SET); + log(_("Uploaded: %llu of %llu kbytes"), + (unsigned long long)cur_pos / 1024, + (unsigned long long)sz / 1024); + } + + return fread(ptr, size, nmemb, fp); +} + +static int curl_debug(CURL *handle, curl_infotype it, char *buf, size_t bufsize, void *unused) +{ + if (logmode == 0) + return 0; + + switch (it) { + case CURLINFO_TEXT: /* The data is informational text. */ + log("curl: %.*s", (int) bufsize, buf); + break; + case CURLINFO_HEADER_IN: /* The data is header (or header-like) data received from the peer. */ + log("curl rcvd header: '%.*s'", (int) bufsize, buf); + break; + case CURLINFO_HEADER_OUT: /* The data is header (or header-like) data sent to the peer. */ + log("curl sent header: '%.*s'", (int) bufsize, buf); + break; + case CURLINFO_DATA_IN: /* The data is protocol data received from the peer. */ + if (g_verbose >= 3) + log("curl rcvd data: '%.*s'", (int) bufsize, buf); + else + log("curl rcvd data %u bytes", (int) bufsize); + break; + case CURLINFO_DATA_OUT: /* The data is protocol data sent to the peer. */ + if (g_verbose >= 3) + log("curl sent data: '%.*s'", (int) bufsize, buf); + else + log("curl sent data %u bytes", (int) bufsize); + break; + default: + break; + } + + return 0; +} + +int +abrt_post(abrt_post_state_t *state, + const char *url, + const char *content_type, + const char **additional_headers, + const char *data, + off_t data_size) +{ + CURLcode curl_err; + long response_code; + abrt_post_state_t localstate; + + VERB3 log("abrt_post('%s','%s')", url, data); + + if (!state) + { + memset(&localstate, 0, sizeof(localstate)); + state = &localstate; + } + + state->http_resp_code = response_code = -1; + + CURL *handle = xcurl_easy_init(); + + // Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in. + // This may be more helpful than just return code from curl_easy_perform. + // curl will need it until curl_easy_cleanup. + state->errmsg[0] = '\0'; + xcurl_easy_setopt_ptr(handle, CURLOPT_ERRORBUFFER, state->errmsg); + // Shut off the built-in progress meter completely + xcurl_easy_setopt_long(handle, CURLOPT_NOPROGRESS, 1); + + if (g_verbose >= 2) { + // "Display a lot of verbose information about its operations. + // Very useful for libcurl and/or protocol debugging and understanding. + // The verbose information will be sent to stderr, or the stream set + // with CURLOPT_STDERR" + xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1); + xcurl_easy_setopt_ptr(handle, CURLOPT_DEBUGFUNCTION, curl_debug); + } + + // TODO: do we need to check for CURLE_URL_MALFORMAT error *here*, + // not in curl_easy_perform? + xcurl_easy_setopt_ptr(handle, CURLOPT_URL, url); + + // Auth if configured + if (state->username) { + // bitmask of allowed auth methods + xcurl_easy_setopt_long(handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + xcurl_easy_setopt_ptr(handle, CURLOPT_USERNAME, state->username); + xcurl_easy_setopt_ptr(handle, CURLOPT_PASSWORD, (state->password ? state->password : "")); + } + + // Do a regular HTTP post. This also makes curl use + // a "Content-Type: application/x-www-form-urlencoded" header. + // (This is by far the most commonly used POST method). + xcurl_easy_setopt_long(handle, CURLOPT_POST, 1); + // Supply POST data... + struct curl_httppost* post = NULL; + struct curl_httppost* last = NULL; + FILE* data_file = NULL; + if (data_size == ABRT_POST_DATA_FROMFILE) { + // ...from a file + data_file = fopen(data, "r"); + if (!data_file) +//FIXME: + perror_msg_and_die("Can't open '%s'", data); + xcurl_easy_setopt_ptr(handle, CURLOPT_READDATA, data_file); + // Want to use custom read function + xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const void*)fread_with_reporting); + } else if (data_size == ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) { + // ...from a file, in multipart/formdata format + const char *basename = strrchr(data, '/'); + if (basename) basename++; + else basename = data; +#if 0 + // Simple way, without custom reader function + CURLFORMcode curlform_err = curl_formadd(&post, &last, + CURLFORM_PTRNAME, "file", // element name + CURLFORM_FILE, data, // filename to read from + CURLFORM_CONTENTTYPE, content_type, + CURLFORM_FILENAME, basename, // filename to put in the form + CURLFORM_END); +#else + data_file = fopen(data, "r"); + if (!data_file) +//FIXME: + perror_msg_and_die("Can't open '%s'", data); + // Want to use custom read function + xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const void*)fread_with_reporting); + // Need to know file size + fseeko(data_file, 0, SEEK_END); + off_t sz = ftello(data_file); + fseeko(data_file, 0, SEEK_SET); + // Create formdata + CURLFORMcode curlform_err = curl_formadd(&post, &last, + CURLFORM_PTRNAME, "file", // element name + // use CURLOPT_READFUNCTION for reading, pass data_file as its last param: + CURLFORM_STREAM, data_file, + CURLFORM_CONTENTSLENGTH, (long)sz, // a must if we use CURLFORM_STREAM option + CURLFORM_CONTENTTYPE, content_type, + CURLFORM_FILENAME, basename, // filename to put in the form + CURLFORM_END); +#endif + if (curlform_err != 0) +//FIXME: + error_msg_and_die("out of memory or read error (curl_formadd error code: %d)", (int)curlform_err); + xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post); + } else { + // .. from a blob in memory + xcurl_easy_setopt_ptr(handle, CURLOPT_POSTFIELDS, data); + // note1: if data_size == ABRT_POST_DATA_STRING == -1, curl will use strlen(data) + xcurl_easy_setopt_long(handle, CURLOPT_POSTFIELDSIZE, data_size); + // note2: CURLOPT_POSTFIELDSIZE_LARGE can't be used: xcurl_easy_setopt_long() + // truncates data_size on 32-bit arch. Need xcurl_easy_setopt_long_long()? + // Also, I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1. + } + + struct curl_slist *httpheader_list = NULL; + + // Override "Content-Type:" + if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) + { + char *content_type_header = xasprintf("Content-Type: %s", content_type); + // Note: curl_slist_append() copies content_type_header + httpheader_list = curl_slist_append(httpheader_list, content_type_header); + if (!httpheader_list) + error_msg_and_die("out of memory"); + free(content_type_header); + } + + for (; additional_headers && *additional_headers; additional_headers++) + { + httpheader_list = curl_slist_append(httpheader_list, *additional_headers); + if (!httpheader_list) + error_msg_and_die("out of memory"); + } + + // Add User-Agent: ABRT/N.M + httpheader_list = curl_slist_append(httpheader_list, "User-Agent: ABRT/"VERSION); + if (!httpheader_list) + error_msg_and_die("out of memory"); + + if (httpheader_list) + xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPHEADER, httpheader_list); + +// Disabled: was observed to also handle "305 Use proxy" redirect, +// apparently with POST->GET remapping - which server didn't like at all. +// Attempted to suppress remapping on 305 using CURLOPT_POSTREDIR of -1, +// but it still did not work. +#if 0 + // Please handle 301/302 redirects for me + xcurl_easy_setopt_long(handle, CURLOPT_FOLLOWLOCATION, 1); + xcurl_easy_setopt_long(handle, CURLOPT_MAXREDIRS, 10); + // Bitmask to control how libcurl acts on redirects after POSTs. + // Bit 0 set (value CURL_REDIR_POST_301) makes libcurl + // not convert POST requests into GET requests when following + // a 301 redirection. Bit 1 (value CURL_REDIR_POST_302) makes libcurl + // maintain the request method after a 302 redirect. + // CURL_REDIR_POST_ALL is a convenience define that sets both bits. + // The non-RFC behaviour is ubiquitous in web browsers, so the library + // does the conversion by default to maintain consistency. + // However, a server may require a POST to remain a POST. + xcurl_easy_setopt_long(handle, CURLOPT_POSTREDIR, -1L /*CURL_REDIR_POST_ALL*/ ); +#endif + + // Prepare for saving information + if (state->flags & ABRT_POST_WANT_HEADERS) + { + xcurl_easy_setopt_ptr(handle, CURLOPT_HEADERFUNCTION, (void*)save_headers); + xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEHEADER, state); + } + FILE* body_stream = NULL; + if (state->flags & ABRT_POST_WANT_BODY) + { + body_stream = open_memstream(&state->body, &state->body_size); + if (!body_stream) + error_msg_and_die("out of memory"); + xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEDATA, body_stream); + } + if (!(state->flags & ABRT_POST_WANT_SSL_VERIFY)) + { + xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYPEER, 0); + xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYHOST, 0); + } + + // This is the place where everything happens. + // Here errors are not limited to "out of memory", can't just die. + curl_err = curl_easy_perform(handle); + if (curl_err) + { + VERB2 log("curl_easy_perform: error %d", (int)curl_err); + if (state->flags & ABRT_POST_WANT_ERROR_MSG) + { + state->curl_error_msg = check_curl_error(curl_err, "curl_easy_perform"); + VERB3 log("curl_easy_perform: error_msg: %s", state->curl_error_msg); + } + goto ret; + } + + // curl-7.20.1 doesn't do it, we get NULL body in the log message below + // unless we fflush the body memstream ourself + if (body_stream) + fflush(body_stream); + + // Headers/body are already saved (if requested), extract more info + curl_err = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code); + die_if_curl_error(curl_err); + state->http_resp_code = response_code; + VERB3 log("after curl_easy_perform: http code %ld body:'%s'", response_code, state->body); + + ret: + curl_easy_cleanup(handle); + if (httpheader_list) + curl_slist_free_all(httpheader_list); + if (body_stream) + fclose(body_stream); + if (data_file) + fclose(data_file); + if (post) + curl_formfree(post); + + return response_code; +} diff --git a/src/lib/abrt_curl.h b/src/lib/abrt_curl.h new file mode 100644 index 0000000..ad2afc1 --- /dev/null +++ b/src/lib/abrt_curl.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 ABRT_CURL_H_ +#define ABRT_CURL_H_ + +#include <curl/curl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +CURL* xcurl_easy_init(); + +typedef struct abrt_post_state { + /* Supplied by caller: */ + int flags; + const char *username; + const char *password; + /* Results of POST transaction: */ + int http_resp_code; + unsigned header_cnt; + char **headers; + char *curl_error_msg; + char *body; + size_t body_size; + char errmsg[CURL_ERROR_SIZE]; +} abrt_post_state_t; + +abrt_post_state_t *new_abrt_post_state(int flags); +void free_abrt_post_state(abrt_post_state_t *state); +char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str); + +enum { + ABRT_POST_WANT_HEADERS = (1 << 0), + ABRT_POST_WANT_ERROR_MSG = (1 << 1), + ABRT_POST_WANT_BODY = (1 << 2), + ABRT_POST_WANT_SSL_VERIFY = (1 << 3), +}; +enum { + /* Must be -1! CURLOPT_POSTFIELDSIZE interprets -1 as "use strlen" */ + ABRT_POST_DATA_STRING = -1, + ABRT_POST_DATA_FROMFILE = -2, + ABRT_POST_DATA_FROMFILE_AS_FORM_DATA = -3, +}; +int +abrt_post(abrt_post_state_t *state, + const char *url, + const char *content_type, + const char **additional_headers, + const char *data, + off_t data_size); +static inline int +abrt_post_string(abrt_post_state_t *state, + const char *url, + const char *content_type, + const char **additional_headers, + const char *str) +{ + return abrt_post(state, url, content_type, additional_headers, + str, ABRT_POST_DATA_STRING); +} +static inline int +abrt_post_file(abrt_post_state_t *state, + const char *url, + const char *content_type, + const char **additional_headers, + const char *filename) +{ + return abrt_post(state, url, content_type, additional_headers, + filename, ABRT_POST_DATA_FROMFILE); +} +static inline int +abrt_post_file_as_form(abrt_post_state_t *state, + const char *url, + const char *content_type, + const char **additional_headers, + const char *filename) +{ + return abrt_post(state, url, content_type, additional_headers, + filename, ABRT_POST_DATA_FROMFILE_AS_FORM_DATA); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c new file mode 100644 index 0000000..0bdb4bd --- /dev/null +++ b/src/lib/abrt_xmlrpc.c @@ -0,0 +1,137 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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" +#include "abrt_xmlrpc.h" + +void abrt_xmlrpc_die(xmlrpc_env *env) +{ + error_msg_and_die("fatal: XML-RPC(%d): %s", env->fault_code, env->fault_string); +} + +void abrt_xmlrpc_error(xmlrpc_env *env) +{ + error_msg("error: XML-RPC (%d): %s", env->fault_code, env->fault_string); +} + +struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + struct abrt_xmlrpc *ax = xzalloc(sizeof(struct abrt_xmlrpc)); + + /* This should be done at program startup, once. We do it in main */ + /* xmlrpc_client_setup_global_const(&env); */ + + /* URL - bugzilla.redhat.com/show_bug.cgi?id=666893 Unable to make sense of + * XML-RPC response from server + * + * By default, XML data from the network may be no larger than 512K. + * XMLRPC_XML_SIZE_LIMIT_DEFAULT is #defined to (512*1024) in xmlrpc-c/base.h + * + * Users reported trouble with 733402 byte long responses, hope raising the + * limit to 2*512k is enough + */ + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 2 * XMLRPC_XML_SIZE_LIMIT_DEFAULT); + + struct xmlrpc_curl_xportparms curl_parms; + memset(&curl_parms, 0, sizeof(curl_parms)); + /* curlParms.network_interface = NULL; - done by memset */ + curl_parms.no_ssl_verifypeer = !ssl_verify; + curl_parms.no_ssl_verifyhost = !ssl_verify; +#ifdef VERSION + curl_parms.user_agent = PACKAGE_NAME"/"VERSION; +#else + curl_parms.user_agent = "abrt"; +#endif + + struct xmlrpc_clientparms client_parms; + memset(&client_parms, 0, sizeof(client_parms)); + client_parms.transport = "curl"; + client_parms.transportparmsP = &curl_parms; + client_parms.transportparm_size = XMLRPC_CXPSIZE(user_agent); + + xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, + PACKAGE_NAME, VERSION, + &client_parms, XMLRPC_CPSIZE(transportparm_size), + &ax->ax_client); + + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + ax->ax_server_info = xmlrpc_server_info_new(&env, url); + if (env.fault_occurred) + { + xmlrpc_client_destroy(ax->ax_client); + abrt_xmlrpc_die(&env); + } + + return ax; +} + +void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax) +{ + if (!ax) + return; + + if (ax->ax_server_info) + xmlrpc_server_info_free(ax->ax_server_info); + + if (ax->ax_client) + xmlrpc_client_destroy(ax->ax_client); + + free(ax); +} + +/* die or return expected results */ +xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, + const char* method, const char* format, ...) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value* param = NULL; + const char* suffix; + va_list args; + + va_start(args, format); + xmlrpc_build_value_va(&env, format, args, ¶m, &suffix); + va_end(args); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + xmlrpc_value* result = NULL; + if (*suffix != '\0') + { + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " + "specifier: '%s'. There must be exactly one argument.", + suffix); + } + else + { + xmlrpc_client_call2(&env, ax->ax_client, ax->ax_server_info, method, + param, &result); + } + xmlrpc_DECREF(param); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + return result; +} diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h new file mode 100644 index 0000000..5c94360 --- /dev/null +++ b/src/lib/abrt_xmlrpc.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 ABRT_XMLRPC_H_ +#define ABRT_XMLRPC_H_ 1 + +/* include/stdint.h: typedef int int32_t; + * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; + */ + +#include <xmlrpc-c/base.h> +#include <xmlrpc-c/client.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct abrt_xmlrpc { + xmlrpc_client *ax_client; + xmlrpc_server_info *ax_server_info; +}; + +struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify); +void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax); +void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn)); +void abrt_xmlrpc_error(xmlrpc_env *env); + +/* die or return expected results */ +xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, + const char *method, const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/plugins/Bugzilla.conf b/src/plugins/Bugzilla.conf new file mode 100644 index 0000000..76e0d1d --- /dev/null +++ b/src/plugins/Bugzilla.conf @@ -0,0 +1,12 @@ +# Description: Reports bugs to bugzilla + +Enabled = yes + +# Bugzilla URL +BugzillaURL = https://bugzilla.redhat.com/ +# yes means that ssl certificates will be checked +SSLVerify = yes +# your login has to exist, if you don have any, please create one +Login = +# your password +Password = diff --git a/src/plugins/Kerneloops.conf b/src/plugins/Kerneloops.conf new file mode 100644 index 0000000..a0b86e8 --- /dev/null +++ b/src/plugins/Kerneloops.conf @@ -0,0 +1,3 @@ +Enabled = yes + +SubmitURL = http://submit.kerneloops.org/submitoops.php diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am new file mode 100644 index 0000000..e078d62 --- /dev/null +++ b/src/plugins/Makefile.am @@ -0,0 +1,208 @@ +-include ../../config.mak + +pluginslibdir = $(PLUGINS_LIB_DIR) + +bin_PROGRAMS = \ + reporter-bugzilla \ + reporter-rhtsupport \ + reporter-kerneloops \ + reporter-upload \ + reporter-mailx \ + reporter-print + +pluginsconfdir = $(PLUGINS_CONF_DIR) + +reportpluginsconfdir = $(REPORT_PLUGINS_CONF_DIR) + +dist_reportpluginsconf_DATA = \ + Kerneloops.conf \ + Bugzilla.conf \ + Upload.conf + +eventsdir = $(EVENTS_DIR) + +dist_events_DATA = \ + report_Bugzilla.xml \ + report_Bugzilla.conf \ + report_Logger.conf \ + report_Mailx.xml \ + report_RHTSupport.xml \ + report_Kerneloops.xml + +@INTLTOOL_XML_RULE@ + +eventsconfdir = $(EVENTS_CONF_DIR) + +dist_eventsconf_DATA = \ + mailx_events.conf \ + print_events.conf \ + rhtsupport_events.conf + +MAN_TXT = \ + reporter-print.txt \ + reporter-mailx.txt \ + reporter-bugzilla.txt \ + reporter-kerneloops.txt \ + reporter-upload.txt + +# Manual pages are generated from .txt via Docbook +man1_MANS = ${MAN_TXT:%.txt=%.1} + +%.1 %.5 %.7: %.xml + $(XMLTO_SILENT) xmlto man $< 2>&1 | sed '/Note/d' + +%.xml: %.txt ../../asciidoc.conf + $(ASCIIDOC_SILENT) asciidoc --backend=docbook --doctype=manpage --conf-file ../../asciidoc.conf -aabrt_version=$(PACKAGE_VERSION) -o $@ $< + + +CLEANFILES = $(man1_MANS) + +EXTRA_DIST = \ + $(man_MANS) \ + $(MAN_TXT) \ + $(man1_MANS) \ + report_Bugzilla.xml.in \ + report_Bugzilla.conf \ + report_Logger.conf \ + report_Mailx.xml.in \ + report_RHTSupport.xml.in \ + report_Kerneloops.xml.in + +$(DESTDIR)/$(DEBUG_INFO_DIR): + $(mkdir_p) '$@' + +reporter_bugzilla_SOURCES = \ + reporter-bugzilla.c rhbz.c rhbz.h +reporter_bugzilla_CPPFLAGS = \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings +reporter_bugzilla_LDADD = \ + $(GLIB_LIBS) \ + ../lib/libabrt_web.la \ + ../lib/libreport.la + +reporter_rhtsupport_SOURCES = \ + abrt_rh_support.h abrt_rh_support.c \ + reporter-rhtsupport.c +reporter_rhtsupport_CPPFLAGS = \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings -Werror +reporter_rhtsupport_LDFLAGS = -ltar +reporter_rhtsupport_LDADD = \ + $(GLIB_LIBS) \ + $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \ + ../lib/libabrt_web.la \ + ../lib/libreport.la + +reporter_upload_SOURCES = \ + reporter-upload.c +reporter_upload_CPPFLAGS = \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(CURL_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings -Werror +reporter_upload_LDFLAGS = -ltar +reporter_upload_LDADD = \ + $(GLIB_LIBS) \ + $(CURL_LIBS) \ + ../lib/libreport.la + +reporter_kerneloops_SOURCES = \ + reporter-kerneloops.c +reporter_kerneloops_CPPFLAGS = \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings -Werror +reporter_kerneloops_LDADD = \ + ../lib/libabrt_web.la \ + ../lib/libreport.la + +reporter_mailx_SOURCES = \ + reporter-mailx.c +reporter_mailx_CPPFLAGS = \ + -I$(srcdir)/../libreport/src/include/ -I$(srcdir)/../include \ + -I$(srcdir)/../libreport/src/lib \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings -Werror +reporter_mailx_LDADD = \ + ../lib/libreport.la + +reporter_print_SOURCES = \ + reporter-print.c +reporter_print_CPPFLAGS = \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR="$(bindir)" \ + -DVAR_RUN="$(VAR_RUN)" \ + -DCONF_DIR="$(CONF_DIR)" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ + -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ + -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ + -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ + $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Wwrite-strings -Werror +reporter_print_LDADD = \ + ../lib/libreport.la + +DEFS = -DLOCALEDIR="$(localedir)" @DEFS@ diff --git a/src/plugins/Upload.conf b/src/plugins/Upload.conf new file mode 100644 index 0000000..803b0ac --- /dev/null +++ b/src/plugins/Upload.conf @@ -0,0 +1,9 @@ +# Description: Packs problem data into .tar.gz file and uploads it via FTP/SCP/etc + +# URL to upload the files to. +# supported: ftp, ftps, http, https, scp, sftp, tftp, file +# for example: ftp://user:password@server.name/directory +# or: scp://user:password@server.name:port/directory etc. +# for testing: file:///tmp/test_directory +# If empty, the prepared archive is stored in /var/run/abrt/ +URL = diff --git a/src/plugins/abrt_rh_support.c b/src/plugins/abrt_rh_support.c new file mode 100644 index 0000000..8f92af7 --- /dev/null +++ b/src/plugins/abrt_rh_support.c @@ -0,0 +1,460 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 <libxml/encoding.h> +#include <libxml/xmlwriter.h> +#include <curl/curl.h> +#include "internal_libreport.h" +#include "abrt_curl.h" +#include "abrt_rh_support.h" + +struct reportfile { + xmlTextWriterPtr writer; + xmlBufferPtr buf; +}; + +static void __attribute__((__noreturn__)) +die_xml_oom(void) +{ + error_msg_and_die("Can't create XML attribute (out of memory?)"); +} + +static xmlBufferPtr +xxmlBufferCreate(void) +{ + xmlBufferPtr r = xmlBufferCreate(); + if (!r) + die_xml_oom(); + return r; +} + +static xmlTextWriterPtr +xxmlNewTextWriterMemory(xmlBufferPtr buf /*, int compression*/) +{ + xmlTextWriterPtr r = xmlNewTextWriterMemory(buf, /*compression:*/ 0); + if (!r) + die_xml_oom(); + return r; +} + +static void +xxmlTextWriterStartDocument(xmlTextWriterPtr writer, + const char * version, + const char * encoding, + const char * standalone) +{ + if (xmlTextWriterStartDocument(writer, version, encoding, standalone) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterEndDocument(xmlTextWriterPtr writer) +{ + if (xmlTextWriterEndDocument(writer) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterStartElement(xmlTextWriterPtr writer, const char *name) +{ + // these bright guys REDEFINED CHAR (!) to unsigned char... + if (xmlTextWriterStartElement(writer, (unsigned char*)name) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterEndElement(xmlTextWriterPtr writer) +{ + if (xmlTextWriterEndElement(writer) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterWriteElement(xmlTextWriterPtr writer, const char *name, const char *content) +{ + if (xmlTextWriterWriteElement(writer, (unsigned char*)name, (unsigned char*)content) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content) +{ + if (xmlTextWriterWriteAttribute(writer, (unsigned char*)name, (unsigned char*)content) < 0) + die_xml_oom(); +} + +#if 0 //unused +static void +xxmlTextWriterWriteString(xmlTextWriterPtr writer, const char *content) +{ + if (xmlTextWriterWriteString(writer, (unsigned char*)content) < 0) + die_xml_oom(); +} +#endif + +// +// End the reportfile, and prepare it for delivery. +// No more bindings can be added after this. +// +static void +close_writer(reportfile_t* file) +{ + if (!file->writer) + return; + + // close off the end of the xml file + xxmlTextWriterEndDocument(file->writer); + xmlFreeTextWriter(file->writer); + file->writer = NULL; +} + +// +// This allocates a reportfile_t structure and initializes it. +// +reportfile_t* +new_reportfile(void) +{ + // create a new reportfile_t + reportfile_t* file = (reportfile_t*)xmalloc(sizeof(*file)); + + // set up a libxml 'buffer' and 'writer' to that buffer + file->buf = xxmlBufferCreate(); + file->writer = xxmlNewTextWriterMemory(file->buf); + + // start a new xml document: + // <report xmlns="http://www.redhat.com/gss/strata">... + xxmlTextWriterStartDocument(file->writer, /*version:*/ NULL, /*encoding:*/ NULL, /*standalone:*/ NULL); + xxmlTextWriterStartElement(file->writer, "report"); + xxmlTextWriterWriteAttribute(file->writer, "xmlns", "http://www.redhat.com/gss/strata"); + + return file; +} + +static void +internal_reportfile_start_binding(reportfile_t* file, const char* name, int isbinary, const char* filename) +{ + // <binding name=NAME [fileName=FILENAME] type=text/binary... + xxmlTextWriterStartElement(file->writer, "binding"); + xxmlTextWriterWriteAttribute(file->writer, "name", name); + if (filename) + xxmlTextWriterWriteAttribute(file->writer, "fileName", filename); + if (isbinary) + xxmlTextWriterWriteAttribute(file->writer, "type", "binary"); + else + xxmlTextWriterWriteAttribute(file->writer, "type", "text"); +} + +// +// Add a new text binding +// +void +reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value) +{ + // <binding name=NAME type=text value=VALUE> + internal_reportfile_start_binding(file, name, /*isbinary:*/ 0, /*filename:*/ NULL); + xxmlTextWriterWriteAttribute(file->writer, "value", value); + xxmlTextWriterEndElement(file->writer); +} + +// +// Add a new binding to a report whose value is represented as a file. +// +void +reportfile_add_binding_from_namedfile(reportfile_t* file, + const char* on_disk_filename, /* unused so far */ + const char* binding_name, + const char* recorded_filename, + int isbinary) +{ + // <binding name=NAME fileName=FILENAME type=text/binary... + internal_reportfile_start_binding(file, binding_name, isbinary, recorded_filename); + // ... href=content/NAME> + char *href_name = concat_path_file("content", binding_name); + xxmlTextWriterWriteAttribute(file->writer, "href", href_name); + free(href_name); +} + +// +// Return the contents of the reportfile as a string. +// +const char* +reportfile_as_string(reportfile_t* file) +{ + close_writer(file); + // unsigned char -> char + return (char*)file->buf->content; +} + +void +reportfile_free(reportfile_t* file) +{ + if (!file) + return; + close_writer(file); + xmlBufferFree(file->buf); + free(file); +} + + +// +// send_report_to_new_case() +// + +static char* +make_case_data(const char* summary, const char* description, + const char* product, const char* version, + const char* component) +{ + char* retval; + xmlTextWriterPtr writer; + xmlBufferPtr buf; + + buf = xxmlBufferCreate(); + writer = xxmlNewTextWriterMemory(buf); + + xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); + xxmlTextWriterStartElement(writer, "case"); + xxmlTextWriterWriteAttribute(writer, "xmlns", + "http://www.redhat.com/gss/strata"); + + xxmlTextWriterWriteElement(writer, "summary", summary); + xxmlTextWriterWriteElement(writer, "description", description); + if (product) { + xxmlTextWriterWriteElement(writer, "product", product); + } + if (version) { + xxmlTextWriterWriteElement(writer, "version", version); + } + if (component) { + xxmlTextWriterWriteElement(writer, "component", component); + } + + xxmlTextWriterEndDocument(writer); + retval = xstrdup((const char*)buf->content); + xmlFreeTextWriter(writer); + xmlBufferFree(buf); + return retval; +} + +#if 0 //unused +static char* +make_response(const char* title, const char* body, + const char* actualURL, const char* displayURL) +{ + char* retval; + xmlTextWriterPtr writer; + xmlBufferPtr buf; + + buf = xxmlBufferCreate(); + writer = xxmlNewTextWriterMemory(buf); + + xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); + xxmlTextWriterStartElement(writer, "response"); + if (title) { + xxmlTextWriterWriteElement(writer, "title", title); + } + if (body) { + xxmlTextWriterWriteElement(writer, "body", body); + } + if (actualURL || displayURL) { + xxmlTextWriterStartElement(writer, "URL"); + if (actualURL) { + xxmlTextWriterWriteAttribute(writer, "href", actualURL); + } + if (displayURL) { + xxmlTextWriterWriteString(writer, displayURL); + } + } + + xxmlTextWriterEndDocument(writer); + retval = xstrdup((const char*)buf->content); + xmlFreeTextWriter(writer); + xmlBufferFree(buf); + return retval; +} +//Example: +//<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +//<response><title>Case Created and Report Attached</title><body></body><URL href="http://support-services-devel.gss.redhat.com:8080/Strata/cases/00005129/attachments/ccbf3e65-b941-3db7-a016-6a3831691a32">New Case URL</URL></response> +#endif + +char* +send_report_to_new_case(const char* baseURL, + const char* username, + const char* password, + bool ssl_verify, + const char* summary, + const char* description, + const char* component, + const char* report_file_name) +{ + char *case_url = concat_path_file(baseURL, "/cases"); + + char *case_data = make_case_data(summary, description, + "Red Hat Enterprise Linux", "6.0", + component); + + int redirect_count = 0; + char *errmsg; + char *allocated = NULL; + char* retval = NULL; + abrt_post_state_t *case_state; + + redirect_case: + case_state = new_abrt_post_state(0 + + ABRT_POST_WANT_HEADERS + + ABRT_POST_WANT_BODY + + ABRT_POST_WANT_ERROR_MSG + + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0) + ); + case_state->username = username; + case_state->password = password; + + static const char *headers[] = { + "Accept: text/plain", + NULL + }; + + abrt_post_string(case_state, case_url, "application/xml", headers, case_data); + + char *case_location = find_header_in_abrt_post_state(case_state, "Location:"); + switch (case_state->http_resp_code) + { + case 404: + /* Not strictly necessary (default branch would deal with it too), + * but makes this typical error less cryptic: + * instead of returning html-encoded body, we show short concise message, + * and show offending URL (typos in which is a typical cause) */ + retval = xasprintf("error in case creation, " + "HTTP code: 404 (Not found), URL:'%s'", case_url); + break; + + case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */ + case 302: /* "302 Found" (just in case) */ + case 305: /* "305 Use Proxy" */ + if (++redirect_count < 10 && case_location) + { + free(case_url); + case_url = xstrdup(case_location); + free_abrt_post_state(case_state); + goto redirect_case; + } + /* fall through */ + + default: + errmsg = case_state->curl_error_msg; + if (errmsg && errmsg[0]) + retval = xasprintf("error in case creation: %s", errmsg); + else + { + errmsg = case_state->body; + if (errmsg && errmsg[0]) + retval = xasprintf("error in case creation, HTTP code: %d, server says: '%s'", + case_state->http_resp_code, errmsg); + else + retval = xasprintf("error in case creation, HTTP code: %d", + case_state->http_resp_code); + } + break; + + case 200: + case 201: { + if (!case_location) { + /* Case Creation returned valid code, but no location */ + retval = xasprintf("error in case creation: no Location URL, HTTP code: %d", + case_state->http_resp_code); + break; + } + + char *atch_url = concat_path_file(case_location, "/attachments"); + abrt_post_state_t *atch_state; + redirect_attach: + atch_state = new_abrt_post_state(0 + + ABRT_POST_WANT_HEADERS + + ABRT_POST_WANT_BODY + + ABRT_POST_WANT_ERROR_MSG + + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0) + ); + atch_state->username = username; + atch_state->password = password; + + abrt_post_file_as_form(atch_state, atch_url, "application/binary", headers, + report_file_name); + + char *atch_location = find_header_in_abrt_post_state(atch_state, "Location:"); + switch (atch_state->http_resp_code) + { + case 305: /* "305 Use Proxy" */ + if (++redirect_count < 10 && atch_location) + { + free(atch_url); + atch_url = xstrdup(atch_location); + free_abrt_post_state(atch_state); + goto redirect_attach; + } + /* fall through */ + + default: + /* Case Creation Succeeded, attachement FAILED */ + errmsg = atch_state->curl_error_msg; + if (atch_state->body && atch_state->body[0]) + { + if (errmsg && errmsg[0] + && strcmp(errmsg, atch_state->body) != 0 + ) /* both strata/curl error and body are present (and aren't the same) */ + allocated = errmsg = xasprintf("%s. %s", + atch_state->body, + errmsg); + else /* only body exists */ + errmsg = atch_state->body; + } + /* Note: to prevent URL misparsing, make sure to delimit + * case_location only using spaces */ + retval = xasprintf("Case created: %s but report attachment failed (HTTP code %d)%s%s", + case_location, + atch_state->http_resp_code, + errmsg ? ": " : "", + errmsg ? errmsg : "" + ); + break; + + case 200: + case 201: + // unused + //char *body = atch_state->body; + //if (case_state->body && case_state->body[0]) + //{ + // body = case_state->body; + // if (atch_state->body && atch_state->body[0]) + // allocated = body = xasprintf("%s\n%s", + // case_state->body, + // atch_state->body); + //} + retval = xasprintf("Case created: %s", /*body,*/ case_location); + } /* switch (attach HTTP code) */ + + free_abrt_post_state(atch_state); + free(atch_url); + } /* case 200/201 */ + + } /* switch (case HTTP code) */ + + free_abrt_post_state(case_state); + free(allocated); + free(case_url); + return retval; +} diff --git a/src/plugins/abrt_rh_support.h b/src/plugins/abrt_rh_support.h new file mode 100644 index 0000000..db6e9cd --- /dev/null +++ b/src/plugins/abrt_rh_support.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 ABRT_RH_SUPPORT_H_ +#define ABRT_RH_SUPPORT_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct reportfile reportfile_t; + +reportfile_t *new_reportfile(void); +void reportfile_free(reportfile_t* file); + +void reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value); +void reportfile_add_binding_from_namedfile(reportfile_t* file, + const char* on_disk_filename, /* unused so far */ + const char* binding_name, + const char* recorded_filename, + int isbinary); + +const char* reportfile_as_string(reportfile_t* file); + +char* post_signature(const char* baseURL, bool ssl_verify, const char* signature); +char* +send_report_to_new_case(const char* baseURL, + const char* username, + const char* password, + bool ssl_verify, + const char* summary, + const char* description, + const char* component, + const char* report_file_name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/plugins/mailx_events.conf b/src/plugins/mailx_events.conf new file mode 100644 index 0000000..9b71e83 --- /dev/null +++ b/src/plugins/mailx_events.conf @@ -0,0 +1 @@ +EVENT=report_Mailx reporter-mailx diff --git a/src/plugins/print_events.conf b/src/plugins/print_events.conf new file mode 100644 index 0000000..7b94aba --- /dev/null +++ b/src/plugins/print_events.conf @@ -0,0 +1,2 @@ +EVENT=report_Logger + reporter-print -o "${Log_File:-/tmp/abrt.log}" -a "${Append:-no}" -r diff --git a/src/plugins/report_Bugzilla.conf b/src/plugins/report_Bugzilla.conf new file mode 100644 index 0000000..f1a77f5 --- /dev/null +++ b/src/plugins/report_Bugzilla.conf @@ -0,0 +1,4 @@ +Bugzilla_BugzillaURL = https://bugzilla.redhat.com +Bugzilla_Login = +Bugzilla_Password = +Bugzilla_SSLVerify = yes diff --git a/src/plugins/report_Bugzilla.xml.in b/src/plugins/report_Bugzilla.xml.in new file mode 100644 index 0000000..00ef4a4 --- /dev/null +++ b/src/plugins/report_Bugzilla.xml.in @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <_name>Bugzilla</_name> + <_description>Report to Bugzilla bug tracker</_description> + + <requires-items>component,duphash,os_release</requires-items> + <exclude-items-by-default>coredump,count,event_log,reported_to</exclude-items-by-default> + <exclude-items-always></exclude-items-always> + <exclude-binary-items>yes</exclude-binary-items> + <include-items-by-default></include-items-by-default> + + <options> + <option type="text" name="Bugzilla_BugzillaURL"> + <_label>Bugzilla URL</_label> + <allow-empty>no</allow-empty> + <_description>Address of Bugzilla server</_description> + <default-value>https://bugzilla.redhat.com</default-value> + <_note-html>You can create bugzilla.redhat.com account <a href="https://bugzilla.redhat.com/createaccount.cgi%22%3Ehere%3C/a%3E;</_note-html> + </option> + <option type="text" name="Bugzilla_Login"> + <_label>User name</_label> + <allow-empty>no</allow-empty> + <_description>Bugzilla account user name</_description> + </option> + <option type="password" name="Bugzilla_Password"> + <_label>Password</_label> + <allow-empty>no</allow-empty> + <_description>Bugzilla account password</_description> + </option> + <option type="bool" name="Bugzilla_SSLVerify"> + <_label>Verify SSL</_label> + <_description>Check SSL key validity</_description> + <default-value>yes</default-value> + </option> + </options> +</event> diff --git a/src/plugins/report_Kerneloops.xml.in b/src/plugins/report_Kerneloops.xml.in new file mode 100644 index 0000000..a4da6b6 --- /dev/null +++ b/src/plugins/report_Kerneloops.xml.in @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <_name>Kerneloops.org</_name> + <_description>Send kernel problems to oops tracker</_description> + + <requires-items>backtrace</requires-items> + <exclude-items-by-default></exclude-items-by-default> + <exclude-items-always>*</exclude-items-always> + <exclude-binary-items>yes</exclude-binary-items> + <include-items-by-default></include-items-by-default> + + <options> + <option type="text" name="KerneloopsReporter_SubmitURL"> + <_label>Kerneloops URL</_label> + <allow-empty>no</allow-empty> + <_description>Oops server url</_description> + <default-value>http://submit.kerneloops.org/submitoops.php</default-value> + </option> + </options> +</event> diff --git a/src/plugins/report_Logger.conf b/src/plugins/report_Logger.conf new file mode 100644 index 0000000..d885ce5 --- /dev/null +++ b/src/plugins/report_Logger.conf @@ -0,0 +1,2 @@ +Log_File=/tmp/abrt.log +Append=yes diff --git a/src/plugins/report_Mailx.xml.in b/src/plugins/report_Mailx.xml.in new file mode 100644 index 0000000..2476a3d --- /dev/null +++ b/src/plugins/report_Mailx.xml.in @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <_name>Mailx</_name> + <_description>Send via email</_description> + + <requires-items></requires-items> + <exclude-items-by-default>coredump</exclude-items-by-default> + <exclude-items-always></exclude-items-always> + <exclude-binary-items>no</exclude-binary-items> + <include-items-by-default></include-items-by-default> + + <options> + <option type="text" name="Mailx_Subject"> + <_label>Subject</_label> + <allow-empty>no</allow-empty> + <_description>Message subject</_description> + <default-value>[abrt] detected a crash</default-value> + </option> + <option type="text" name="Mailx_EmailFrom"> + <_label>Sender</_label> + <allow-empty>no</allow-empty> + <_description>Sender's email</_description> + </option> + <option type="text" name="Mailx_EmailTo"> + <_label>Recipient</_label> + <allow-empty>no</allow-empty> + <_description>Recipient's email</_description> + </option> + <option type="bool" name="Mailx_SendBinaryData"> + <_label>Send Binary Data</_label> + <_description>Send binary files like coredump</_description> + <default-value>no</default-value> + </option> + </options> +</event> diff --git a/src/plugins/report_RHTSupport.xml.in b/src/plugins/report_RHTSupport.xml.in new file mode 100644 index 0000000..834528a --- /dev/null +++ b/src/plugins/report_RHTSupport.xml.in @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <_name>Red Hat Customer Support</_name> + <_description>Report to Red Hat support</_description> + + <requires-items>package</requires-items> + <exclude-items-by-default>event_log,reported_to</exclude-items-by-default> + <exclude-items-always></exclude-items-always> + <exclude-binary-items>no</exclude-binary-items> + <include-items-by-default></include-items-by-default> + + <options> + <option type="text" name="RHTSupport_URL"> + <_label>RH Portal URL</_label> + <allow-empty>no</allow-empty> + <_description>Address of the Red Hat support portal</_description> + <default-value>https://api.access.redhat.com/rs</default-value> + </option> + <option type="text" name="RHTSupport_Login"> + <_label>Username</_label> + <_description>Red Hat customer user name</_description> + <allow-empty>no</allow-empty> + </option> + <option type="password" name="RHTSupport_Password"> + <_label>Password</_label> + <_description>Red Hat customer password</_description> + <allow-empty>no</allow-empty> + </option> + <option type="bool" name="RHTSupport_SSLVerify"> + <_label>Verify SSL</_label> + <_description>Check SSL key validity</_description> + <default-value>yes</default-value> + </option> + </options> +</event> diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c new file mode 100644 index 0000000..99b03e7 --- /dev/null +++ b/src/plugins/reporter-bugzilla.c @@ -0,0 +1,291 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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" +#include "abrt_xmlrpc.h" +#include "rhbz.h" + +#define XML_RPC_SUFFIX "/xmlrpc.cgi" + +static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings) +{ + problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); + if (!problem_data) + xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ + + const char *env; + const char *login; + const char *password; + const char *bugzilla_xmlrpc; + const char *bugzilla_url; + bool ssl_verify; + + env = getenv("Bugzilla_Login"); + login = env ? env : get_map_string_item_or_empty(settings, "Login"); + env = getenv("Bugzilla_Password"); + password = env ? env : get_map_string_item_or_empty(settings, "Password"); + if (!login[0] || !password[0]) + error_msg_and_die(_("Empty login or password, please check your configuration")); + + env = getenv("Bugzilla_BugzillaURL"); + bugzilla_url = env ? env : get_map_string_item_or_empty(settings, "BugzillaURL"); + if (!bugzilla_url[0]) + bugzilla_url = "https://bugzilla.redhat.com"; + bugzilla_xmlrpc = xasprintf("%s"XML_RPC_SUFFIX, bugzilla_url); + + env = getenv("Bugzilla_SSLVerify"); + ssl_verify = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SSLVerify")); + + const char *component = get_problem_item_content_or_NULL(problem_data, FILENAME_COMPONENT); + const char *duphash = get_problem_item_content_or_NULL(problem_data, FILENAME_DUPHASH); +//COMPAT, remove after 2.1 release + if (!duphash) duphash = get_problem_item_content_or_NULL(problem_data, "global_uuid"); + if (!duphash) + error_msg_and_die(_("Essential file '%s' is missing, can't continue.."), + FILENAME_DUPHASH); + + if (!*duphash) + error_msg_and_die(_("Essential file '%s' is empty, can't continue.."), + FILENAME_DUPHASH); + + 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"); + + struct abrt_xmlrpc *client = abrt_xmlrpc_new_client(bugzilla_xmlrpc, ssl_verify); + + log(_("Logging into Bugzilla at %s"), bugzilla_url); + rhbz_login(client, login, password); + + log(_("Checking for duplicates")); + char *product = NULL; + char *version = NULL; + parse_release_for_bz(release, &product, &version); + free(version); + + xmlrpc_value *result; + if (strcmp(product, "Fedora") == 0) + result = rhbz_search_duphash(client, component, product, duphash); + else + result = rhbz_search_duphash(client, component, NULL, duphash); + + xmlrpc_value *all_bugs = rhbz_get_member("bugs", result); + xmlrpc_DECREF(result); + + if (!all_bugs) + error_msg_and_die(_("Missing mandatory member 'bugs'")); + + 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; + struct bug_info *bz = NULL; + if (all_bugs_size > 0) + { + bug_id = rhbz_bug_id(all_bugs); + xmlrpc_DECREF(all_bugs); + bz = rhbz_bug_info(client, bug_id); + + if (strcmp(bz->bi_product, product) != 0) + { + /* found something, but its a different product */ + free_bug_info(bz); + + xmlrpc_value *result = rhbz_search_duphash(client, component, + product, duphash); + xmlrpc_value *all_bugs = rhbz_get_member("bugs", result); + xmlrpc_DECREF(result); + + all_bugs_size = rhbz_array_size(all_bugs); + if (all_bugs_size > 0) + { + bug_id = rhbz_bug_id(all_bugs); + bz = rhbz_bug_info(client, bug_id); + } + xmlrpc_DECREF(all_bugs); + } + } + free(product); + + if (all_bugs_size == 0) // Create new bug + { + log(_("Creating a new bug")); + bug_id = rhbz_new_bug(client, problem_data, bug_id); + + 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, RHBZ_NOMAIL_NOTIFY); + + bz = new_bug_info(); + bz->bi_status = xstrdup("NEW"); + bz->bi_id = bug_id; + goto log_out; + } + + // decision based on state + log(_("Bug is already reported: %i"), bz->bi_id); + if ((strcmp(bz->bi_status, "CLOSED") == 0) + && (strcmp(bz->bi_resolution, "DUPLICATE") == 0) + ) { + struct bug_info *origin; + origin = rhbz_find_origin_bug_closed_duplicate(client, bz); + if (origin) + { + free_bug_info(bz); + bz = origin; + } + } + + if (strcmp(bz->bi_status, "CLOSED") != 0) + { + 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); + rhbz_mail_to_cc(client, bz->bi_id, login, RHBZ_NOMAIL_NOTIFY); + } + + const char *comment = get_problem_item_content_or_NULL(problem_data, FILENAME_COMMENT); + if (comment && comment[0]) + { + 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); +//COMPAT, remove in abrt-2.1 release + if (!release)release= get_problem_item_content_or_NULL(problem_data, "release"); + const char *arch = get_problem_item_content_or_NULL(problem_data, FILENAME_ARCHITECTURE); + char *full_dsc = xasprintf("Package: %s\n" + "Architecture: %s\n" + "OS Release: %s\n" + "\n" + "Comment\n" + "-----\n" + "%s\n", + package, arch, release, comment + ); + log(_("Adding new comment to bug %d"), bz->bi_id); + /* unused code, enable it when gui/cli will be ready + int is_priv = is_private && string_to_bool(is_private); + const char *is_private = get_problem_item_content_or_NULL(problem_data, + "is_private"); + */ + rhbz_add_comment(client, bz->bi_id, full_dsc, 0); + free(full_dsc); + } + } + + log_out: + log(_("Logging out")); + rhbz_logout(client); + + log("Status: %s%s%s %s/show_bug.cgi?id=%u", + bz->bi_status, + bz->bi_resolution ? " " : "", + bz->bi_resolution ? bz->bi_resolution : "", + bugzilla_url, + bz->bi_id); + + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (dd) + { + 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); + free_bug_info(bz); + abrt_xmlrpc_free_client(client); +} + +int main(int argc, char **argv) +{ + abrt_init(argv); + + map_string_h *settings = new_map_string(); + const char *dump_dir_name = "."; + GList *conf_file = NULL; + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] [-c CONFFILE] -d DIR\n" + "\n" + "Reports problem to Bugzilla.\n" + "\n" + "The tool reads DIR. Then it logs in to Bugzilla and tries to find a bug\n" + "with the same abrt_hash:HEXSTRING in 'Whiteboard'.\n" + "\n" + "If such bug is not found, then a new bug is created. Elements of DIR\n" + "are stored in the bug as part of bug description or as attachments,\n" + "depending on their type and size.\n" + "\n" + "Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE,\n" + "the tool follows the chain of duplicates until it finds a non-DUPLICATE bug.\n" + "The tool adds a new comment to found bug.\n" + "\n" + "The URL to new or modified bug is printed to stdout and recorded in\n" + "'reported_to' element.\n" + "\n" + "CONFFILE lines should have 'PARAM = VALUE' format.\n" + "Recognized string parameters: BugzillaURL, Login, Password.\n" + "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" + "Parameters can be overridden via $Bugzilla_PARAM environment variables." + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_c = 1 << 2, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file (may be given many times)")), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + while (conf_file) + { + char *fn = (char *)conf_file->data; + VERB1 log("Loading settings from '%s'", fn); + load_conf_file(fn, settings, /*skip key w/o values:*/ true); + VERB3 log("Loaded '%s'", fn); + conf_file = g_list_remove(conf_file, fn); + } + + VERB1 log("Initializing XML-RPC library"); + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_client_setup_global_const(&env); + if (env.fault_occurred) + error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code); + xmlrpc_env_clean(&env); + + report_to_bugzilla(dump_dir_name, settings); + + free_map_string(settings); + return 0; +} diff --git a/src/plugins/reporter-bugzilla.txt b/src/plugins/reporter-bugzilla.txt new file mode 100644 index 0000000..12cc645 --- /dev/null +++ b/src/plugins/reporter-bugzilla.txt @@ -0,0 +1,67 @@ +reporter-buzilla(1) +==================== + +NAME +---- +reporter-bugzilla - Reports problem to Bugzilla. + +SYNOPSIS +-------- +'reporter-bugzilla' [-v] [-c CONFFILE] -d DIR + +DESCRIPTION +----------- +The tool reads problem dump directory DIR. Then it logs in to Bugzilla +and tries to find a bug with the same abrt_hash:HEXSTRING in 'Whiteboard'. + +If such bug is not found, then a new bug is created. Elements of DIR +are stored in the bug as part of bug description or as attachments, +depending on their type and size. + +Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE, +the tool follows the chain of duplicates until it finds a non-DUPLICATE bug. +The tool adds a new comment to found bug. + +The URL to new or modified bug is printed to stdout and recorded in +'reported_to' element in DIR. + +Configuration file +~~~~~~~~~~~~~~~~~~ +Configuration file lines should have 'PARAM = VALUE' format. The parameters are: + +'Login':: + Login to Bugzilla account. + +'Password':: + Password to Bugzilla account. + +'BugzillaURL':: + Bugzilla http(s) address. (default: https://bugzilla.redht.com) + +'SSLVerify':: + Use yes/true/on/1 to verify Bugzilla ssl certificate. (default: yes) + +Parameters can be overridden via $Bugzilla_PARAM environment variables. + +Integration with ABRT events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'reporter-bugzilla' can be used as an ABRT reporter. Example +fragment for /etc/abrt/abrt_events.conf: + +------------ +# Report Python crashes +EVENT=report_Bugzilla analyzer=Python + reporter-bugzilla -d . -c /etc/abrt/plugins/Bugzilla.conf +------------ + +OPTIONS +------- +-d DIR:: + Path to dump directory. + +-c CONFFILE:: + Path to configration file. + +SEE ALSO +-------- +abrt_event.conf diff --git a/src/plugins/reporter-kerneloops.c b/src/plugins/reporter-kerneloops.c new file mode 100644 index 0000000..e03df36 --- /dev/null +++ b/src/plugins/reporter-kerneloops.c @@ -0,0 +1,166 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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. + + Authors: + Anton Arapov anton@redhat.com + Arjan van de Ven arjan@linux.intel.com + */ +#include <curl/curl.h> +#include "internal_libreport.h" + +/* helpers */ +static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) +{ + size *= nmemb; +/* + char *c, *c1, *c2; + + log("received: '%*.*s'", (int)size, (int)size, (char*)ptr); + c = (char*)xzalloc(size + 1); + memcpy(c, ptr, size); + c1 = strstr(c, "201 "); + if (c1) + { + c1 += 4; + c2 = strchr(c1, '\n'); + if (c2) + *c2 = 0; + } + free(c); +*/ + + return size; +} + +/* Send oops data to kerneloops.org-style site, using HTTP POST */ +/* Returns 0 on success */ +static CURLcode http_post_to_kerneloops_site(const char *url, const char *oopsdata) +{ + CURLcode ret; + CURL *handle; + struct curl_httppost *post = NULL; + struct curl_httppost *last = NULL; + + handle = curl_easy_init(); + if (!handle) + error_msg_and_die("Can't create curl handle"); + + curl_easy_setopt(handle, CURLOPT_URL, url); + + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "oopsdata", + CURLFORM_COPYCONTENTS, oopsdata, + CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "pass_on_allowed", + CURLFORM_COPYCONTENTS, "yes", + CURLFORM_END); + + curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefunction); + + ret = curl_easy_perform(handle); + + curl_formfree(post); + curl_easy_cleanup(handle); + + return ret; +} + +static void report_to_kerneloops( + const char *dump_dir_name, + map_string_h *settings) +{ + problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); + if (!problem_data) + xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ + + const char *backtrace = get_problem_item_content_or_NULL(problem_data, FILENAME_BACKTRACE); + if (!backtrace) + error_msg_and_die("Error sending kernel oops due to missing backtrace"); + + const char *env = getenv("KerneloopsReporter_SubmitURL"); + const char *submitURL = (env ? env : get_map_string_item_or_empty(settings, "SubmitURL")); + if (!submitURL[0]) + submitURL = "http://submit.kerneloops.org/submitoops.php"; + + log(_("Submitting oops report to %s"), submitURL); + + CURLcode ret = http_post_to_kerneloops_site(submitURL, backtrace); + if (ret != CURLE_OK) + error_msg_and_die("Kernel oops has not been sent due to %s", curl_easy_strerror(ret)); + + free_problem_data(problem_data); + + /* Server replies with: + * 200 thank you for submitting the kernel oops information + * RemoteIP: 34192fd15e34bf60fac6a5f01bba04ddbd3f0558 + * - no URL or bug ID apparently... + */ + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (dd) + { + char *msg = xasprintf("kerneloops: URL=%s", submitURL); + add_reported_to(dd, msg); + free(msg); + dd_close(dd); + } + + log("Kernel oops report was uploaded"); +} + +int main(int argc, char **argv) +{ + abrt_init(argv); + + map_string_h *settings = new_map_string(); + const char *dump_dir_name = "."; + GList *conf_file = NULL; + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] [-c CONFFILE]... -d DIR\n" + "\n" + "Reports kernel oops to kerneloops.org (or similar) site" + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_c = 1 << 2, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file")), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + while (conf_file) + { + char *fn = (char *)conf_file->data; + VERB1 log("Loading settings from '%s'", fn); + load_conf_file(fn, settings, /*skip key w/o values:*/ true); + VERB3 log("Loaded '%s'", fn); + conf_file = g_list_remove(conf_file, fn); + } + + report_to_kerneloops(dump_dir_name, settings); + + free_map_string(settings); + return 0; +} diff --git a/src/plugins/reporter-kerneloops.txt b/src/plugins/reporter-kerneloops.txt new file mode 100644 index 0000000..8701dfb --- /dev/null +++ b/src/plugins/reporter-kerneloops.txt @@ -0,0 +1,68 @@ +reporter-kerneloops(1) +====================== + +NAME +---- +reporter-kerneloops - Reports kernel oops to kerneloops.org (or similar) +site. + +SYNOPSIS +-------- +'reporter-kerneloops' [-v] [-c CONFFILE]... [ -d DIR ] + +DESCRIPTION +----------- +The tool is used to report the crash to the Kerneloops tracker. + +Configuration file +~~~~~~~~~~~~~~~~~~ +Configuration file contains entries in a format "Option = Value". + +The options are: + +'SubmitURL':: + The URL of the kerneloops tracker, the default is + "http://submit.kerneloops.org/submitoops.php". + +Integration with ABRT events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'reporter-kerneloops' can be used as a reporter, to allow users to report +problems to the Kerneloops tracker. This usage is pre-configured in +/etc/abrt/events.d/koops_events.conf: + +------------ +EVENT=report_Kerneloops analyzer=Kerneloops reporter-kerneloops +------------ + +It can be also used automatically and immediately without user interaction. +When this is desired, modify the event configuration file to run the tool on +the 'post-create' event: + +------------ +EVENT=post-create analyzer=Kerneloops reporter-kerneloops +------------ + +OPTIONS +------- +-v:: + Be more verbose. Can be given multiple times. + +-d DIR:: + Path to dump directory. + +-c CONFFILE:: + Path to configration file. When used in ABRT event system, the file + contains site-wide configuration. Users can change the values via + environment variables. + +ENVIRONMENT VARIABLES +--------------------- +Environment variables take precedence over values provided in +the configuration file. + +'KerneloopsReporter_SubmitURL':: + The URL of the kerneloops tracker. + +AUTHORS +------- +* ABRT team diff --git a/src/plugins/reporter-mailx.c b/src/plugins/reporter-mailx.c new file mode 100644 index 0000000..99ac586 --- /dev/null +++ b/src/plugins/reporter-mailx.c @@ -0,0 +1,162 @@ +/* + Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) + Copyright (C) 2009 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" + +static void exec_and_feed_input(const char* text, char **args) +{ + int pipein[2]; + + pid_t child = fork_execv_on_steroids( + EXECFLG_INPUT | EXECFLG_QUIET, + args, + pipein, + /*env_vec:*/ NULL, + /*dir:*/ NULL, + /*uid (ignored):*/ 0 + ); + + full_write_str(pipein[1], text); + close(pipein[1]); + + int status; + waitpid(child, &status, 0); /* wait for command completion */ + if (status != 0) + error_msg_and_die("Error running '%s'", args[0]); +} + +static char** append_str_to_vector(char **vec, unsigned *size_p, const char *str) +{ + //log("old vec: %p", vec); + unsigned size = *size_p; + vec = (char**) xrealloc(vec, (size+2) * sizeof(vec[0])); + vec[size] = xstrdup(str); + //log("new vec: %p, added [%d] %p", vec, size, vec[size]); + size++; + vec[size] = NULL; + *size_p = size; + return vec; +} + +static void create_and_send_email( + const char *dump_dir_name, + map_string_h *settings) +{ + problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); + if (!problem_data) + xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ + + char* env; + env = getenv("Mailx_Subject"); + const char *subject = (env ? env : get_map_string_item_or_NULL(settings, "Subject") ? : "[abrt] full crash report"); + env = getenv("Mailx_EmailFrom"); + const char *email_from = (env ? env : get_map_string_item_or_NULL(settings, "EmailFrom") ? : "user@localhost"); + env = getenv("Mailx_EmailTo"); + const char *email_to = (env ? env : get_map_string_item_or_NULL(settings, "EmailTo") ? : "root@localhost"); + env = getenv("Mailx_SendBinaryData"); + bool send_binary_data = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SendBinaryData")); + + char **args = NULL; + unsigned arg_size = 0; + args = append_str_to_vector(args, &arg_size, "/bin/mailx"); + + char *dsc = make_description_mailx(problem_data); + + if (send_binary_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)) + { + if (value->flags & CD_FLAG_BIN) + { + args = append_str_to_vector(args, &arg_size, "-a"); + args = append_str_to_vector(args, &arg_size, value->content); + } + } + } + + args = append_str_to_vector(args, &arg_size, "-s"); + args = append_str_to_vector(args, &arg_size, subject); + args = append_str_to_vector(args, &arg_size, "-r"); + args = append_str_to_vector(args, &arg_size, email_from); + args = append_str_to_vector(args, &arg_size, email_to); + + log(_("Sending an email...")); + exec_and_feed_input(dsc, args); + + free(dsc); + + while (*args) + free(*args++); + args -= arg_size; + free(args); + + free_problem_data(problem_data); + + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (dd) + { + char *msg = xasprintf("email: %s", email_to); + add_reported_to(dd, msg); + free(msg); + dd_close(dd); + } + log("Email was sent to: %s", email_to); +} + +int main(int argc, char **argv) +{ + abrt_init(argv); + + const char *dump_dir_name = "."; + const char *conf_file = NULL; + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] -d DIR [-c CONFFILE]\n" + "\n" + "Sends contents of a dump directory DIR via email" + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_c = 1 << 2, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_STRING('c', NULL, &conf_file , "CONFFILE", _("Config file")), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + map_string_h *settings = new_map_string(); + if (conf_file) + load_conf_file(conf_file, settings, /*skip key w/o values:*/ true); + + create_and_send_email(dump_dir_name, settings); + + free_map_string(settings); + return 0; +} diff --git a/src/plugins/reporter-mailx.txt b/src/plugins/reporter-mailx.txt new file mode 100644 index 0000000..319a3a1 --- /dev/null +++ b/src/plugins/reporter-mailx.txt @@ -0,0 +1,91 @@ +reporter-mailx(1) +================= + +NAME +---- +reporter-mailx - Sends contents of a dump directory via email. + +SYNOPSIS +-------- +'reporter-mailx' [-v] -d DIR [-c CONFFILE] + +DESCRIPTION +----------- +The tool reads a problem dump directory, composes an email message +from the directory contents, and uses mailx to send the message to +specified recipient. + +Properties of email messages can be specified in a configuration file, +and via environment variables. + +Configuration file +~~~~~~~~~~~~~~~~~~ +Configuration file contains entries in a format "Option = Value". + +The options are: + +'Subject':: + The subject of the email message. + +'EmailFrom':: + The sender of the email message. + +'EmailTo':: + The recipient of the email message. + +'SendBinaryData':: + Use yes/true/on/1 to attach all binary files from the dump + directory to the email. This can cause the emails to be very + large. + +Integration with ABRT events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'reporter-mailx' can be used as a reporter, to allow users report +problems via email when they decide to do it. This usage is +pre-configured in /etc/abrt/events.d/mailx_events.conf: + +------------ +EVENT=report_Mailx reporter-mailx +------------ + +It can also be used to notify administrator automatically when a +problem happens. When this is desired, modify the event configuration +file to run the tool on the 'post-create' event: + +------------ +EVENT=post-create reporter-mailx +------------ + +OPTIONS +------- +-d DIR:: + Path to dump directory. + +-c CONFFILE:: + Path to configration file. When used in ABRT event system, the file + contains site-wide configuration. Users can change the values via + environment variables. + +ENVIRONMENT VARIABLES +--------------------- +Environment variables take precedence over values provided in +the configuration file. + +'Mailx_Subject':: + Subject of the email message. + +'Mailx_EmailFrom':: + Sender of the email message. + +'Mailx_EmailTo':: + Recipient of the email message. If nor the environment variable + nor the corresponding option is defined, the message is send to + "root@localhost". + +'Mailx_SendBinaryData':: + Use yes/true/on/1 to attach all binary files from the dump + directory to the email. + +AUTHORS +------- +* ABRT team diff --git a/src/plugins/reporter-print.c b/src/plugins/reporter-print.c new file mode 100644 index 0000000..c688b32 --- /dev/null +++ b/src/plugins/reporter-print.c @@ -0,0 +1,95 @@ +/* + Write crash dump to stdout in text form. + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) + Copyright (C) 2009 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" + +static const char *dump_dir_name = "."; +static const char *output_file = NULL; +static const char *append = "no"; +static const char *open_mode = "w"; + +int main(int argc, char **argv) +{ + abrt_init(argv); + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] -d DIR [-o FILE] [-a yes/no] [-r]\n" + "\n" + "Prints problem information to standard output or FILE" + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_o = 1 << 2, + OPT_a = 1 << 3, + OPT_r = 1 << 4, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_STRING('o', NULL, &output_file , "FILE" , _("Output file")), + OPT_STRING('a', NULL, &append , "yes/no", _("Append to, or overwrite FILE")), + OPT_BOOL( 'r', NULL, NULL , _("Create reported_to in DIR")), + OPT_END() + }; + unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + if (output_file) + { + if (string_to_bool(append)) + open_mode = "a"; + if (!freopen(output_file, open_mode, stdout)) + perror_msg_and_die("Can't open '%s'", output_file); + } + + problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); + if (!problem_data) + xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ + + char *dsc = make_description_logger(problem_data); + fputs(dsc, stdout); + if (open_mode[0] == 'a') + fputs("\nEND:\n\n", stdout); + free(dsc); + free_problem_data(problem_data); + + if (output_file) + { + if (opts & OPT_r) + { + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (dd) + { + char *msg = xasprintf("file: %s", output_file); + add_reported_to(dd, msg); + free(msg); + dd_close(dd); + } + } + const char *format = (open_mode[0] == 'a' ? _("The report was appended to %s") : _("The report was stored to %s")); + log(format, output_file); + } + + return 0; +} diff --git a/src/plugins/reporter-print.txt b/src/plugins/reporter-print.txt new file mode 100644 index 0000000..67c800b --- /dev/null +++ b/src/plugins/reporter-print.txt @@ -0,0 +1,63 @@ +reporter-print(1) +================= + +NAME +---- +reporter-print - Prints problem information to standard output or FILE. + +SYNOPSIS +-------- +'reporter-print' [-v] [-d DIR] [-o FILE] [-a yes/no] [-r] + +DESCRIPTION +----------- +The tool reads dump directory DIR and prints its text representation +to stdout or to a specified FILE. + +Integration with ABRT events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'reporter-print' can be used as a reporter, to allow users +to report problems by writinf them to a file. Example: + +------------ +EVENT=report reporter-print -o "${Log_File:-/tmp/abrt.log}" +------------ + +OPTIONS +------- +-d DIR:: + Path to dump directory. + +-v:: + Be more verbose. Can be given multiple times. + +-o FILE:: + Output file + +-a yes/no:: + If -o FILE is specified, controls whether FILE is appended to, or overwritten. + +-r:: + Add a recor to 'reported_to' in DIR which specifies that this problem + was reported. Some tools use this to differentiate between problems + which were and weren't yet reported. + +Output format +~~~~~~~~~~~~~ +The output is designed to be machine-parseable. The elements which have only +one line are printed in the form + + NAME:<whitespace>VALUE + +Elements which have more than one line are printed in the form + + NAME: + :LINE1 + :LINE2 + :LINE3 + +Output may contain empty lines for better readability. + +AUTHORS +------- +* ABRT team diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c new file mode 100644 index 0000000..4f6d2b6 --- /dev/null +++ b/src/plugins/reporter-rhtsupport.c @@ -0,0 +1,342 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 <libtar.h> +#include "internal_libreport.h" +#include "abrt_curl.h" +#include "abrt_xmlrpc.h" +#include "abrt_rh_support.h" + +static void report_to_rhtsupport( + const char *dump_dir_name, + map_string_h *settings) +{ + problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); + if (!problem_data) + xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ + + /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ + log(_("Compressing data")); + + const char* errmsg = NULL; + TAR* tar = NULL; + pid_t child; + char* tempfile = NULL; + reportfile_t* file = NULL; + char* dsc = NULL; + char* summary = NULL; + const char* function; + const char* reason; + const char* package; + + char* env; + env = getenv("RHTSupport_URL"); + char *url = xstrdup(env ? env : (get_map_string_item_or_NULL(settings, "URL") ? : "https://api.access.redhat.com/rs")); + + env = getenv("RHTSupport_Login"); + char *login = xstrdup(env ? env : get_map_string_item_or_empty(settings, "Login")); + + env = getenv("RHTSupport_Password"); + char *password = xstrdup(env ? env : get_map_string_item_or_empty(settings, "Password")); + + env = getenv("RHTSupport_SSLVerify"); + bool ssl_verify = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SSLVerify")); + + if (!login[0] || !password[0]) + { + error_msg_and_die(_("Empty RHTS login or password")); + } + + package = get_problem_item_content_or_NULL(problem_data, FILENAME_PACKAGE); + reason = get_problem_item_content_or_NULL(problem_data, FILENAME_REASON); + function = get_problem_item_content_or_NULL(problem_data, FILENAME_CRASH_FUNCTION); + + { + struct strbuf *buf_summary = strbuf_new(); + strbuf_append_strf(buf_summary, "[abrt] %s", package); + if (function && strlen(function) < 30) + strbuf_append_strf(buf_summary, ": %s", function); + if (reason) + strbuf_append_strf(buf_summary, ": %s", reason); + summary = strbuf_free_nobuf(buf_summary); + + char *bz_dsc = make_description_bz(problem_data); + dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc); + free(bz_dsc); + } + file = new_reportfile(); + const char *dt_string = iso_date_string(NULL); + char tmpdir_name[sizeof("/tmp/rhtsupport-YYYY-MM-DD-hh:mm:ss-XXXXXX")]; + sprintf(tmpdir_name, "/tmp/rhtsupport-%s-XXXXXX", dt_string); + /* mkdtemp does mkdir(xxx, 0700), should be safe (is it?) */ + if (mkdtemp(tmpdir_name) == NULL) + { + error_msg_and_die(_("Can't create a temporary directory in /tmp")); + } + + /* Starting from here, we must perform cleanup on errors + * (delete temp dir) + */ + + tempfile = xasprintf("%s/tmp-%s-%lu.tar.gz", tmpdir_name, iso_date_string(NULL), (long)getpid()); + + int pipe_from_parent_to_child[2]; + xpipe(pipe_from_parent_to_child); + child = fork(); + if (child == 0) + { + /* child */ + close(pipe_from_parent_to_child[1]); + xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); + xmove_fd(pipe_from_parent_to_child[0], 0); + execlp("gzip", "gzip", NULL); + perror_msg_and_die("Can't execute '%s'", "gzip"); + } + close(pipe_from_parent_to_child[0]); + + if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, + /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) + { + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + + { + 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)) + { + if (strcmp(name, FILENAME_COUNT) == 0) continue; + if (strcmp(name, CD_DUMPDIR) == 0) continue; + + const char *content = value->content; + if (value->flags & CD_FLAG_TXT) + { + reportfile_add_binding_from_string(file, name, content); + } + else if (value->flags & CD_FLAG_BIN) + { + const char *basename = strrchr(content, '/'); + if (basename) + basename++; + else + basename = content; + char *xml_name = concat_path_file("content", basename); + reportfile_add_binding_from_namedfile(file, + /*on_disk_filename */ content, + /*binding_name */ name, + /*recorded_filename*/ xml_name, + /*binary */ 1); + if (tar_append_file(tar, (char*)content, xml_name) != 0) + { + errmsg = "Can't create temporary file in /tmp"; + free(xml_name); + goto ret; + } + free(xml_name); + } + } + } + + /* Write out content.xml in the tarball's root */ + { + const char *signature = reportfile_as_string(file); + unsigned len = strlen(signature); + unsigned len512 = (len + 511) & ~511; + char *block = (char*)memcpy(xzalloc(len512), signature, len); + + th_set_type(tar, S_IFREG | 0644); + th_set_mode(tar, S_IFREG | 0644); + //th_set_link(tar, char *linkname); + //th_set_device(tar, dev_t device); + //th_set_user(tar, uid_t uid); + //th_set_group(tar, gid_t gid); + th_set_mtime(tar, time(NULL)); + th_set_path(tar, (char*)"content.xml"); + th_set_size(tar, len); + th_finish(tar); /* caclulate and store th xsum etc */ + + if (th_write(tar) != 0 /* writes header block */ + /* writes content.xml, padded to 512 bytes */ + || full_write(tar_fd(tar), block, len512) != len512 + || tar_append_eof(tar) != 0 /* writes EOF blocks */ + || tar_close(tar) != 0 + ) { + free(block); + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + tar = NULL; + free(block); + } + + /* We must be sure gzip finished, and finished successfully */ + int status; + waitpid(child, &status, 0); + child = -1; + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + { + /* Hopefully, by this time child emitted more meaningful + * error message. But just in case it didn't: + */ + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + + /* Send tempfile */ + { + log(_("Creating a new case...")); + char* result = send_report_to_new_case(url, + login, + password, + ssl_verify, + summary, + dsc, + package, + tempfile + ); + /* Temporary hackish detection of errors. Ideally, + * send_report_to_new_case needs to have better error reporting. + */ + if (strncasecmp(result, "error", 5) == 0) + { + /* + * result can contain "...server says: 'multi-line <html> text'" + * Replace all '\n' with spaces: + * we want this message to be, logically, one log entry. + * IOW: one line, not many lines. + */ + char *src, *dst; + dst = src = result; + while (1) + { + unsigned char c = *src++; + if (c == '\n') + c = ' '; + *dst++ = c; + if (c == '\0') + break; + } + /* Use sanitized string as error message */ + errmsg = result; + goto ret; + } + + /* No error */ + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (dd) + { + char *msg = xasprintf("RHTSupport: %s", result); + add_reported_to(dd, msg); + free(msg); + dd_close(dd); + } + log("%s", result); + free(result); + } + + ret: + /* We must close write fd first, or else child will wait forever */ + if (tar) + tar_close(tar); + //close(pipe_from_parent_to_child[1]); - tar_close() does it itself + + /* Now wait for child to exit */ + if (child > 0) + { + // Damn, selinux does not allow SIGKILLing our own child! wtf?? + //kill(child, SIGKILL); /* just in case */ + waitpid(child, NULL, 0); + } + + unlink(tempfile); + free(tempfile); + reportfile_free(file); + rmdir(tmpdir_name); + + free(summary); + free(dsc); + + free(url); + free(login); + free(password); + free_problem_data(problem_data); + + if (errmsg) + error_msg_and_die("%s", errmsg); +} + +int main(int argc, char **argv) +{ + abrt_init(argv); + + map_string_h *settings = new_map_string(); + const char *dump_dir_name = "."; + GList *conf_file = NULL; + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] -c CONFFILE -d DIR\n" + "\n" + "Reports a problem to RHTSupport.\n" + "\n" + "CONFFILE lines should have 'PARAM = VALUE' format.\n" + "Recognized string parameters: URL, Login, Password.\n" + "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" + "Parameters can be overridden via $RHTSupport_PARAM environment variables." + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_c = 1 << 2, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file (may be given many times)")), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + while (conf_file) + { + char *fn = (char *)conf_file->data; + VERB1 log("Loading settings from '%s'", fn); + load_conf_file(fn, settings, /*skip key w/o values:*/ true); + VERB3 log("Loaded '%s'", fn); + conf_file = g_list_remove(conf_file, fn); + } + + VERB1 log("Initializing XML-RPC library"); + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_client_setup_global_const(&env); + if (env.fault_occurred) + error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code); + xmlrpc_env_clean(&env); + + report_to_rhtsupport(dump_dir_name, settings); + + free_map_string(settings); + return 0; +} diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c new file mode 100644 index 0000000..aea3891 --- /dev/null +++ b/src/plugins/reporter-upload.c @@ -0,0 +1,287 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 <libtar.h> +#include <curl/curl.h> +#include "internal_libreport.h" + +//TODO: use this for better logging +#if 0 +/* "read local data from a file" callback */ +static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata) +{ + static time_t last_t; // hack + + FILE *fp = (FILE*)userdata; + time_t t = time(NULL); + + // Report current file position every 16 seconds + if (!(t & 0xf) && last_t != t) + { + last_t = t; + off_t cur_pos = ftello(fp); + fseeko(fp, 0, SEEK_END); + off_t sz = ftello(fp); + fseeko(fp, cur_pos, SEEK_SET); + log(_("Uploaded: %llu of %llu kbytes"), + (unsigned long long)cur_pos / 1024, + (unsigned long long)sz / 1024); + } + + return fread(ptr, size, nmemb, fp); +} +#endif + +static int send_file(const char *url, const char *filename) +{ + FILE *fp = fopen(filename, "r"); + if (!fp) + { + perror_msg("Can't open '%s'", filename); + return 1; + } + + log(_("Sending %s to %s"), filename, url); + + struct stat stbuf; + fstat(fileno(fp), &stbuf); /* never fails */ + char *whole_url = concat_path_file(url, strrchr(filename, '/') ? : filename); + + CURL *curl = curl_easy_init(); + if (!curl) + { + error_msg_and_die("Can't create curl handle"); + } + /* Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in. + * This may be more helpful than just return code from curl_easy_perform. + * curl will need it until curl_easy_cleanup. */ + char curl_err_msg[CURL_ERROR_SIZE]; + curl_err_msg[0] = '\0'; + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_msg); + /* enable uploading */ + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + /* specify target */ + curl_easy_setopt(curl, CURLOPT_URL, whole_url); + /* FILE handle: passed to the default callback, it will fread() it */ + curl_easy_setopt(curl, CURLOPT_READDATA, fp); + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)stbuf.st_size); + + /* everything is done here; result 0 means success */ + CURLcode result = curl_easy_perform(curl); + free(whole_url); + fclose(fp); + if (result != 0) + error_msg("Error while uploading: '%s'", curl_easy_strerror(result)); + else + /* This ends up a "reporting status message" in abrtd */ + log(_("Successfully sent %s to %s"), filename, url); + + curl_easy_cleanup(curl); + + return result; +} + +static int create_and_upload_archive( + const char *dump_dir_name, + map_string_h *settings) +{ + int result = 0; + + pid_t child; + TAR* tar = NULL; + const char* errmsg = NULL; + char* tempfile = NULL; + + struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (!dd) + exit(1); /* error msg is already logged by dd_opendir */ + + /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ + log(_("Compressing data")); + +//TODO: +//Encrypt = yes +//ArchiveType = .tar.bz2 +//ExcludeFiles = foo,bar*,b*z + char* env; + env = getenv("Upload_URL"); + const char *url = (env ? env : get_map_string_item_or_empty(settings, "URL")); + + /* Create a child gzip which will compress the data */ + /* SELinux guys are not happy with /tmp, using /var/run/abrt */ + /* Reverted back to /tmp for ABRT2 */ + tempfile = xasprintf("/tmp/abrt-upload-%s-%lu.tar.gz", iso_date_string(NULL), (long)getpid()); + int pipe_from_parent_to_child[2]; + xpipe(pipe_from_parent_to_child); + child = vfork(); + if (child == 0) + { + /* child */ + close(pipe_from_parent_to_child[1]); + xmove_fd(pipe_from_parent_to_child[0], 0); + xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); + execlp("gzip", "gzip", NULL); + perror_msg_and_die("Can't execute '%s'", "gzip"); + } + close(pipe_from_parent_to_child[0]); + + /* If child died (say, in xopen), then parent might get SIGPIPE. + * We want to properly unlock dd, therefore we must not die on SIGPIPE: + */ + signal(SIGPIPE, SIG_IGN); + + /* Create tar writer object */ + if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, + /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) + { + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + + /* Write data to the tarball */ + { + char *exclude_from_report = getenv("EXCLUDE_FROM_REPORT"); + dd_init_next_file(dd); + char *short_name, *full_name; + while (dd_get_next_file(dd, &short_name, &full_name)) + { + if (exclude_from_report && is_in_comma_separated_list(short_name, exclude_from_report)) + goto next; + + // dd_get_next_file guarantees that it's a REG: + //struct stat stbuf; + //if (stat(full_name, &stbuf) != 0) + // || !S_ISREG(stbuf.st_mode) + //) { + // goto next; + //} + if (tar_append_file(tar, full_name, short_name) != 0) + { + errmsg = "Can't create temporary file in /tmp"; + free(short_name); + free(full_name); + goto ret; + } + next: + free(short_name); + free(full_name); + } + } + dd_close(dd); + dd = NULL; + + /* Close tar writer... */ + if (tar_append_eof(tar) != 0 || tar_close(tar) != 0) + { + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + tar = NULL; + /* ...and check that gzip child finished successfully */ + int status; + waitpid(child, &status, 0); + child = -1; + if (status != 0) + { + /* We assume the error was out-of-disk-space or out-of-quota */ + errmsg = "Can't create temporary file in /tmp"; + goto ret; + } + + /* Upload the tarball */ + if (url && url[0]) + { + result = send_file(url, tempfile); + /* cleanup code will delete tempfile */ + } + else + { + log(_("Archive is created: '%s'"), tempfile); + free(tempfile); + tempfile = NULL; + } + + ret: + dd_close(dd); + if (tar) + tar_close(tar); + /* close(pipe_from_parent_to_child[1]); - tar_close() does it itself */ + if (child > 0) + waitpid(child, NULL, 0); + if (tempfile) + { + unlink(tempfile); + free(tempfile); + } + if (errmsg) + error_msg_and_die("%s", errmsg); + + return result; +} + +int main(int argc, char **argv) +{ + abrt_init(argv); + + const char *dump_dir_name = "."; + const char *conf_file = NULL; + const char *url = NULL; + + /* Can't keep these strings/structs static: _() doesn't support that */ + const char *program_usage_string = _( + "\b [-v] -d DIR [-c CONFFILE] [-u URL]\n" + "\n" + "Uploads compressed tarball of dump directory DIR to URL.\n" + "If URL is not specified, creates tarball in /tmp and exits.\n" + "\n" + "Files with names listed in $EXCLUDE_FROM_REPORT are not included\n" + "into the tarball.\n" + "\n" + "CONFFILE lines should have 'PARAM = VALUE' format.\n" + "Recognized string parameter: URL.\n" + "Parameter can be overridden via $Upload_URL." + ); + enum { + OPT_v = 1 << 0, + OPT_d = 1 << 1, + OPT_c = 1 << 2, + OPT_u = 1 << 3, + }; + /* Keep enum above and order of options below in sync! */ + struct options program_options[] = { + OPT__VERBOSE(&g_verbose), + OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), + OPT_STRING('c', NULL, &conf_file , "CONFFILE", _("Config file")), + OPT_STRING('u', NULL, &url , "URL" , _("Base URL to upload to")), + OPT_END() + }; + /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); + + export_abrt_envvars(0); + + map_string_h *settings = new_map_string(); + if (url) + g_hash_table_replace(settings, xstrdup("URL"), xstrdup(url)); + if (conf_file) + load_conf_file(conf_file, settings, /*skip key w/o values:*/ true); + + int result = create_and_upload_archive(dump_dir_name, settings); + + free_map_string(settings); + return result; +} diff --git a/src/plugins/reporter-upload.txt b/src/plugins/reporter-upload.txt new file mode 100644 index 0000000..0a1b8f8 --- /dev/null +++ b/src/plugins/reporter-upload.txt @@ -0,0 +1,67 @@ +reporter-upload(1) +================== + +NAME +---- +reporter-upload - Uploads compressed tarball of dump directory. + +SYNOPSIS +-------- +'reporter-upload' [-c CONFFILE]... [ -d DIR ] [ -u URL ] + +DESCRIPTION +----------- +The tool is used to create a compressed tarball of the dump directory and +upload it to a URL. Supported protocols include FTP, FTPS, HTTP, HTTPS, SCP, +SFTP, TFTP and FILE. + +Configuration file +~~~~~~~~~~~~~~~~~~ +Configuration file contains entries in a format "Option = Value". + +The options are: + +'URL':: + The URL where tarball should be uploaded. + +Integration with ABRT events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'reporter-upload' can be used as a reporter, to allow users to upload +compressed tarballs of dump directiories to a configured URL. This usage can be +configured in /etc/abrt/events.d/upload_events.conf: + +------------ +EVENT=report_Upload reporter-upload +------------ + +It can be also used on the 'post-create' event to upload it automatically. + +------------ +EVENT=post-create reporter-upload +------------ + +OPTIONS +------- + +-d DIR:: + Path to dump directory. + +-c CONFFILE:: + Path to configration file. When used in ABRT event system, the file + contains site-wide configuration. Users can change the values via + environment variables. + +-u URL:: + The URL where tarball should be uploaded. + +ENVIRONMENT VARIABLES +--------------------- +Environment variables take precedence over values provided in +the configuration file. + +'Upload_URL':: + The URL where should be the tarball uploaded. + +AUTHORS +------- +* ABRT team diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c new file mode 100644 index 0000000..0a4c28e --- /dev/null +++ b/src/plugins/rhbz.c @@ -0,0 +1,488 @@ +/* + Copyright (C) 2011 ABRT team + Copyright (C) 2011 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" +#include "rhbz.h" + +#define MAX_HOPS 5 + +struct bug_info *new_bug_info() +{ + struct bug_info *bi = xzalloc(sizeof(struct bug_info)); + bi->bi_dup_id = -1; + + return bi; +} + +void free_bug_info(struct bug_info *bi) +{ + if (!bi) + return; + + free(bi->bi_status); + free(bi->bi_resolution); + free(bi->bi_reporter); + free(bi->bi_product); + + list_free_with_free(bi->bi_cc_list); + + bi->bi_status = NULL; + bi->bi_resolution = NULL; + bi->bi_reporter = NULL; + bi->bi_product = NULL; + + bi->bi_cc_list = NULL; + + free(bi); +} + +void rhbz_login(struct abrt_xmlrpc *ax, const char* login, const char* passwd) +{ + xmlrpc_value* result = abrt_xmlrpc_call(ax, "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! + xmlrpc_DECREF(result); +} + +xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, const char *component, + const char *product, const char *duphash) +{ + char *query = NULL; + if (!product) + query = xasprintf("ALL component:"%s" whiteboard:"%s"", component, duphash); + else + query = xasprintf("ALL component:"%s" whiteboard:"%s" product:"%s"", + component, duphash, product); + + VERB3 log("search for '%s'", query); + xmlrpc_value *ret = abrt_xmlrpc_call(ax, "Bug.search", "({s:s})", + "quicksearch", query); + free(query); + return ret; +} + +xmlrpc_value *rhbz_get_member(const char *member, xmlrpc_value *xml) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value *value = NULL; + /* The xmlrpc_struct_find_value functions consider "not found" to be + * a normal result. If a member of the structure with the specified key + * exists, it returns it as a handle to an xmlrpc_value. If not, it returns + * NULL in place of that handle. + */ + xmlrpc_struct_find_value(&env, xml, member, &value); + if (env.fault_occurred) + abrt_xmlrpc_error(&env); + + return value; +} + +/* The only way this can fail is if arrayP is not actually an array XML-RPC + * value. So it is usually not worth checking *envP. + * die or return size of array + */ +int rhbz_array_size(xmlrpc_value *xml) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + int size = xmlrpc_array_size(&env, xml); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + return size; +} + +/* die or return bug id; each bug must have bug id otherwise xml is corrupted */ +int rhbz_bug_id(xmlrpc_value* xml) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value *item = NULL; + xmlrpc_value *bug = NULL; + int bug_id = -1;; + + xmlrpc_array_read_item(&env, xml, 0, &item); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + bug = rhbz_get_member("bug_id", item); + xmlrpc_DECREF(item); + if (!bug) + abrt_xmlrpc_die(&env); + + xmlrpc_read_int(&env, bug, &bug_id); + xmlrpc_DECREF(bug); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + VERB3 log("found bug_id %i", bug_id); + return bug_id; +} + +/* die when mandatory value is missing (set flag RHBZ_MANDATORY_MEMB) + * or return appropriate string or NULL when fail; + */ +// TODO: npajkovs: add flag to read xmlrpc_read_array_item first +void *rhbz_bug_read_item(const char *memb, xmlrpc_value *xml, int flags) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value *member = rhbz_get_member(memb, xml); + + const char *string = NULL; + + if (!member) + goto die; + + if (IS_READ_STR(flags)) + { + xmlrpc_read_string(&env, member, &string); + xmlrpc_DECREF(member); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + if (!*string) + goto die; + + VERB3 log("found %s: '%s'", memb, string); + return (void*)string; + } + + if (IS_READ_INT(flags)) + { + int *integer = xmalloc(sizeof(int)); + xmlrpc_read_int(&env, member, integer); + xmlrpc_DECREF(member); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + VERB3 log("found %s: '%i'", memb, *integer); + return (void*)integer; + } +die: + free((void*)string); + if (IS_MANDATORY(flags)) + error_msg_and_die(_("Looks like corrupted xml response, because '%s'" + " member is missing."), memb); + + return NULL; +} + +GList *rhbz_bug_cc(xmlrpc_value* result_xml) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value* cc_member = rhbz_get_member("cc", result_xml); + if (!cc_member) + return NULL; + + int array_size = rhbz_array_size(cc_member); + + VERB3 log("count members on cc %i", array_size); + GList *cc_list = NULL; + + 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) + abrt_xmlrpc_die(&env); + + if (!item) + continue; + + const char* cc = NULL; + xmlrpc_read_string(&env, item, &cc); + xmlrpc_DECREF(item); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + if (*cc != '\0') + { + cc_list = g_list_append(cc_list, (char*)cc); + VERB3 log("member on cc is %s", cc); + continue; + } + free((char*)cc); + } + xmlrpc_DECREF(cc_member); + return cc_list; +} + +struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id) +{ + struct bug_info *bz = new_bug_info(); + xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "bugzilla.getBug", + "(i)", bug_id); + + int *ret = (int*)rhbz_bug_read_item("bug_id", xml_bug_response, + RHBZ_MANDATORY_MEMB | RHBZ_READ_INT); + bz->bi_id = *ret; + free(ret); + bz->bi_product = rhbz_bug_read_item("product", xml_bug_response, + RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); + bz->bi_reporter = rhbz_bug_read_item("reporter", xml_bug_response, + RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); + bz->bi_status = rhbz_bug_read_item("bug_status", xml_bug_response, + RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); + bz->bi_resolution = rhbz_bug_read_item("resolution", xml_bug_response, + RHBZ_READ_STR); + + if (strcmp(bz->bi_status, "CLOSED") == 0 && !bz->bi_resolution) + error_msg_and_die(_("Bug %i is CLOSED, but it has no RESOLUTION"), bz->bi_id); + + ret = (int*)rhbz_bug_read_item("dup_id", xml_bug_response, + RHBZ_READ_INT); + if (strcmp(bz->bi_status, "CLOSED") == 0 + && strcmp(bz->bi_resolution, "DUPLICATE") == 0 + && !ret) + { + error_msg_and_die(_("Bug %i is CLOSED as DUPLICATE, but it has no DUP_ID"), + bz->bi_id); + } + + bz->bi_dup_id = (ret) ? *ret: -1; + free(ret); + + bz->bi_cc_list = rhbz_bug_cc(xml_bug_response); + + xmlrpc_DECREF(xml_bug_response); + + return bz; +} + +/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ +int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, + int depend_on_bug) +{ + 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); +//COMPAT, remove after 2.1 release + if (!duphash) duphash = get_problem_item_content_or_NULL(problem_data, + "global_uuid"); + 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_short = get_problem_item_content_or_NULL(problem_data, + FILENAME_TAINTED_SHORT); + + 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_short && analyzer + && (strcmp(analyzer, "Kerneloops") == 0)) + { + strbuf_append_strf(buf_summary, ": TAINTED %s", tainted_short); + } + + 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_bug > -1) + { + result = abrt_xmlrpc_call(ax, "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_bug); + } + else + { + result = abrt_xmlrpc_call(ax, "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; + + int *r = rhbz_bug_read_item("id", result, RHBZ_MANDATORY_MEMB | RHBZ_READ_INT); + xmlrpc_DECREF(result); + int new_bug_id = *r; + free(r); + + log(_("New bug id: %i"), new_bug_id); + return new_bug_id; +} + +/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ +int rhbz_attachment(struct abrt_xmlrpc *ax, const char *filename, + const char *bug_id, const char *data, int flags) +{ + char *encoded64 = encode_base64(data, strlen(data)); + char *fn = xasprintf("File: %s", filename); + xmlrpc_value* result; + int nomail_notify = IS_NOMAIL_NOTIFY(flags); + + result= abrt_xmlrpc_call(ax, "bugzilla.addAttachment", "(s{s:s,s:s,s:s,s:s,s:i})", + bug_id, + "description", fn, + "filename", filename, + "contenttype", "text/plain", + "data", encoded64, + "nomail", nomail_notify); + + free(encoded64); + free(fn); + if (!result) + return -1; + + xmlrpc_DECREF(result); + + return 0; +} + +/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ +int rhbz_attachments(struct abrt_xmlrpc *ax, const char *bug_id, + problem_data_t *problem_data, int flags) +{ + 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)*/) + ) { + /* check if the attachment failed and try it once more */ + rhbz_attachment(ax, name, bug_id, content, flags); + } + } + + return 0; +} + +void rhbz_logout(struct abrt_xmlrpc *ax) +{ + xmlrpc_value* result = abrt_xmlrpc_call(ax, "User.logout", "(s)", ""); + if (result) + xmlrpc_DECREF(result); +} + +struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax, + struct bug_info *bi) +{ + struct bug_info *bi_tmp = new_bug_info(); + bi_tmp->bi_id = bi->bi_id; + bi_tmp->bi_dup_id = bi->bi_dup_id; + + for (int ii = 0; ii <= MAX_HOPS; ii++) + { + if (ii == MAX_HOPS) + error_msg_and_die(_("Bugzilla couldn't find parent of bug %d"), bi->bi_id); + + log("Bug %d is a duplicate, using parent bug %d", bi_tmp->bi_id, bi_tmp->bi_dup_id); + int bug_id = bi_tmp->bi_dup_id; + + free_bug_info(bi_tmp); + bi_tmp = rhbz_bug_info(ax, bug_id); + + // found a bug which is not CLOSED as DUPLICATE + if (bi_tmp->bi_dup_id == -1) + break; + } + + return bi_tmp; +} + +/* suppress mail notify by {s:i} (nomail:1) */ +void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int flags) +{ + xmlrpc_value *result; + int nomail_notify = IS_NOMAIL_NOTIFY(flags); + result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i}})", + "ids", bug_id, "updates", "add_cc", mail, + "nomail", nomail_notify); + + if (result) + xmlrpc_DECREF(result); +} + +void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment, + int flags) +{ + int private = IS_PRIVATE(flags); + int nomail_notify = IS_NOMAIL_NOTIFY(flags); + + xmlrpc_value *result; + result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i})", + "id", bug_id, "comment", comment, + "private", private, "nomail", nomail_notify); + + if (result) + xmlrpc_DECREF(result); +} diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h new file mode 100644 index 0000000..6a12c68 --- /dev/null +++ b/src/plugins/rhbz.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2011 ABRT team + Copyright (C) 2011 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 RHBZ_H +#define RHBZ_H + +/* include/stdint.h: typedef int int32_t; + * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; + */ + +#include "abrt_xmlrpc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + RHBZ_MANDATORY_MEMB = (1 << 0), + RHBZ_READ_STR = (1 << 1), + RHBZ_READ_INT = (1 << 2), + RHBZ_NOMAIL_NOTIFY = (1 << 3), + RHBZ_PRIVATE = (1 << 4), +}; + +#define IS_MANDATORY(flags) ((flags) & RHBZ_MANDATORY_MEMB) +#define IS_READ_STR(flags) ((flags) & RHBZ_READ_STR) +#define IS_READ_INT(flags) ((flags) & RHBZ_READ_INT) +#define IS_NOMAIL_NOTIFY(flags) ((flags) & RHBZ_NOMAIL_NOTIFY) +#define IS_PRIVATE(flags) ((flags) & RHBZ_PRIVATE) + +struct bug_info { + int bi_id; + int bi_dup_id; + + char *bi_status; + char *bi_resolution; + char *bi_reporter; + char *bi_product; + + GList *bi_cc_list; +}; + +struct bug_info *new_bug_info(); +void free_bug_info(struct bug_info *bz); + +void rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *passwd); + +void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int flags); + +void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment, + int flags); + +void *rhbz_bug_read_item(const char *memb, xmlrpc_value *xml, int flags); + +void rhbz_logout(struct abrt_xmlrpc *ax); + +xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, const char *component, + const char *release, const char *duphash); + +xmlrpc_value *rhbz_get_member(const char *member, xmlrpc_value *xml); + +int rhbz_array_size(xmlrpc_value *xml); + +int rhbz_bug_id(xmlrpc_value *xml); + +int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, + int depend_on_bug); + +int rhbz_attachments(struct abrt_xmlrpc *ax, const char *bug_id, + problem_data_t *problem_data, int flags); + +int rhbz_attachment(struct abrt_xmlrpc *ax, const char *filename, + const char *bug_id, const char *data, int flags); + +GList *rhbz_bug_cc(xmlrpc_value *result_xml); + +struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id); + + +struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax, + struct bug_info *bi); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/plugins/rhtsupport_events.conf b/src/plugins/rhtsupport_events.conf new file mode 100644 index 0000000..2e9b27e --- /dev/null +++ b/src/plugins/rhtsupport_events.conf @@ -0,0 +1 @@ +EVENT=report_RHTSupport reporter-rhtsupport
--- abrt.spec.in | 98 +------ configure.ac | 6 - src/daemon/abrt_event.conf | 3 - src/lib/Makefile.am | 30 +-- src/lib/abrt_curl.c | 435 ---------------------------- src/lib/abrt_curl.h | 103 ------- src/lib/abrt_xmlrpc.c | 137 --------- src/lib/abrt_xmlrpc.h | 51 ---- src/plugins/Bugzilla.conf | 12 - src/plugins/Kerneloops.conf | 3 - src/plugins/Makefile.am | 170 +----------- src/plugins/Upload.conf | 9 - src/plugins/abrt-action-bugzilla.c | 291 ------------------- src/plugins/abrt-action-bugzilla.txt | 67 ----- src/plugins/abrt-action-kerneloops.c | 166 ----------- src/plugins/abrt-action-kerneloops.txt | 68 ----- src/plugins/abrt-action-mailx.c | 162 ----------- src/plugins/abrt-action-mailx.txt | 91 ------ src/plugins/abrt-action-print.c | 95 ------ src/plugins/abrt-action-print.txt | 63 ---- src/plugins/abrt-action-rhtsupport.c | 342 ---------------------- src/plugins/abrt-action-upload.c | 287 ------------------- src/plugins/abrt-action-upload.txt | 67 ----- src/plugins/abrt_rh_support.c | 460 ------------------------------ src/plugins/abrt_rh_support.h | 55 ---- src/plugins/mailx_events.conf | 1 - src/plugins/report_Bugzilla.conf | 4 - src/plugins/report_Bugzilla.xml.in | 36 --- src/plugins/report_Kerneloops.xml.in | 20 -- src/plugins/report_Logger.conf | 2 - src/plugins/report_Mailx.xml.in | 35 --- src/plugins/report_RHTSupport.xml.in | 35 --- src/plugins/rhbz.c | 488 -------------------------------- src/plugins/rhbz.h | 103 ------- src/plugins/rhtsupport_events.conf | 1 - 35 files changed, 8 insertions(+), 3988 deletions(-) delete mode 100644 src/lib/abrt_curl.c delete mode 100644 src/lib/abrt_curl.h delete mode 100644 src/lib/abrt_xmlrpc.c delete mode 100644 src/lib/abrt_xmlrpc.h delete mode 100644 src/plugins/Bugzilla.conf delete mode 100644 src/plugins/Kerneloops.conf delete mode 100644 src/plugins/Upload.conf delete mode 100644 src/plugins/abrt-action-bugzilla.c delete mode 100644 src/plugins/abrt-action-bugzilla.txt delete mode 100644 src/plugins/abrt-action-kerneloops.c delete mode 100644 src/plugins/abrt-action-kerneloops.txt delete mode 100644 src/plugins/abrt-action-mailx.c delete mode 100644 src/plugins/abrt-action-mailx.txt delete mode 100644 src/plugins/abrt-action-print.c delete mode 100644 src/plugins/abrt-action-print.txt delete mode 100644 src/plugins/abrt-action-rhtsupport.c delete mode 100644 src/plugins/abrt-action-upload.c delete mode 100644 src/plugins/abrt-action-upload.txt delete mode 100644 src/plugins/abrt_rh_support.c delete mode 100644 src/plugins/abrt_rh_support.h delete mode 100644 src/plugins/mailx_events.conf delete mode 100644 src/plugins/report_Bugzilla.conf delete mode 100644 src/plugins/report_Bugzilla.xml.in delete mode 100644 src/plugins/report_Kerneloops.xml.in delete mode 100644 src/plugins/report_Logger.conf delete mode 100644 src/plugins/report_Mailx.xml.in delete mode 100644 src/plugins/report_RHTSupport.xml.in delete mode 100644 src/plugins/rhbz.c delete mode 100644 src/plugins/rhbz.h delete mode 100644 src/plugins/rhtsupport_events.conf
diff --git a/abrt.spec.in b/abrt.spec.in index fb2727a..0ddf5bd 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -20,16 +20,13 @@ Source2: abrt-ccpp.init Source3: abrt-oops.init BuildRequires: dbus-devel BuildRequires: gtk2-devel -BuildRequires: curl-devel BuildRequires: rpm-devel >= 4.6 BuildRequires: desktop-file-utils BuildRequires: libnotify-devel -BuildRequires: xmlrpc-c-devel #why? BuildRequires: file-devel BuildRequires: python-devel BuildRequires: gettext BuildRequires: libxml2-devel -BuildRequires: libtar-devel BuildRequires: intltool BuildRequires: libtool BuildRequires: nss-devel @@ -105,60 +102,13 @@ Summary: %{name}'s kerneloops addon Group: System Environment/Libraries Requires: curl Requires: %{name} = %{version}-%{release} +Requires: libreport-plugin-kerneloops Obsoletes: kerneloops > 0.0.1 Obsoletes: abrt-plugin-kerneloops > 0.0.1 Obsoletes: abrt-plugin-kerneloopsreporter > 0.0.1
%description addon-kerneloops -This package contains plugin for collecting kernel crash information -and reporter plugin which sends this information to specified server, -usually to kerneloops.org. - -%package plugin-logger -Summary: %{name}'s logger reporter plugin -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} - -%description plugin-logger -The simple reporter plugin which writes a report to a specified file. - -%package plugin-mailx -Summary: %{name}'s mailx reporter plugin -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} -Requires: mailx - -%description plugin-mailx -The simple reporter plugin which sends a report via mailx to a specified -email address. - -%package plugin-bugzilla -Summary: %{name}'s bugzilla plugin -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} - -%description plugin-bugzilla -Plugin to report bugs into the bugzilla. - -%package plugin-rhtsupport -Summary: %{name}'s RHTSupport plugin -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} -Obsoletes: abrt-plugin-catcut > 0.0.1 -Obsoletes: abrt-plugin-rhfastcheck > 0.0.1 -Obsoletes: abrt-plugin-rhticket > 0.0.1 - -%description plugin-rhtsupport -Plugin to report bugs into RH support system. - -%package plugin-reportuploader -Summary: %{name}'s reportuploader plugin -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} -Obsoletes: abrt-plugin-ticketuploader > 0.0.1 - -%description plugin-reportuploader -Plugin to report bugs into anonymous FTP site associated with ticketing system. +This package contains plugin for collecting kernel crash information.
%package addon-python Summary: %{name}'s addon for catching and analyzing Python exceptions @@ -179,7 +129,7 @@ Requires: %{name} = %{version}-%{release} Requires: libreport-cli Requires: abrt-addon-kerneloops Requires: abrt-addon-ccpp, abrt-addon-python -Requires: abrt-plugin-bugzilla, abrt-plugin-logger +Requires: libreport-plugin-bugzilla, libreport-plugin-logger
%description cli This package contains simple command line client for controlling abrt daemon over @@ -199,7 +149,7 @@ Requires: abrt-addon-ccpp, abrt-addon-python # Default config of addon-ccpp requires gdb Requires: gdb >= 7.0-3 Requires: abrt-gui -Requires: abrt-plugin-logger, abrt-plugin-bugzilla +Requires: libreport-plugin-logger, libreport-plugin-bugzilla #Requires: abrt-plugin-firefox Obsoletes: bug-buddy > 0.0.1 Provides: bug-buddy @@ -456,53 +406,15 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%files addon-kerneloops %defattr(-,root,root,-) -%config(noreplace) %{_sysconfdir}/libreport/plugins/Kerneloops.conf -%{_sysconfdir}/libreport/events/report_Kerneloops.xml %config(noreplace) %{_sysconfdir}/libreport/events.d/koops_events.conf %if %{with systemd} /lib/systemd/system/abrt-oops.service %else %{_initrddir}/abrt-oops %endif -%{_mandir}/man*/abrt-action-kerneloops.* %{_bindir}/abrt-dump-oops %{_bindir}/abrt-action-analyze-oops -%{_bindir}/abrt-action-kerneloops - -%files plugin-logger -%defattr(-,root,root,-) -%{_sysconfdir}/libreport/events/report_Logger.conf -%{_bindir}/abrt-action-print -%{_mandir}/man*/abrt-action-print.* - -%files plugin-mailx -%defattr(-,root,root,-) -%{_sysconfdir}/libreport/events/report_Mailx.xml -%config(noreplace) %{_sysconfdir}/libreport/events.d/mailx_events.conf -%{_mandir}/man*/abrt-action-mailx.* -%{_bindir}/abrt-action-mailx - -%files plugin-bugzilla -%defattr(-,root,root,-) -%config(noreplace) %{_sysconfdir}/libreport/plugins/Bugzilla.conf -%{_sysconfdir}/libreport/events/report_Bugzilla.xml -%config(noreplace) %{_sysconfdir}/libreport/events/report_Bugzilla.conf -# FIXME: remove with the old gui -%{_mandir}/man1/abrt-action-bugzilla.1.gz -%{_bindir}/abrt-action-bugzilla - -%files plugin-rhtsupport -%defattr(-,root,root,-) -%{_sysconfdir}/libreport/events/report_RHTSupport.xml -%config(noreplace) %{_sysconfdir}/libreport/events.d/rhtsupport_events.conf -# {_mandir}/man7/abrt-RHTSupport.7.gz -%{_bindir}/abrt-action-rhtsupport - -%files plugin-reportuploader -%defattr(-,root,root,-) -%config(noreplace) %{_sysconfdir}/libreport/plugins/Upload.conf -%{_mandir}/man*/abrt-action-upload.* -%{_bindir}/abrt-action-upload +%{_mandir}/man1/abrt-action-analyze-oops.1*
%files addon-python %defattr(-,root,root,-) diff --git a/configure.ac b/configure.ac index d53bcd1..1726093 100644 --- a/configure.ac +++ b/configure.ac @@ -61,11 +61,8 @@ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.21]) PKG_CHECK_MODULES([DBUS], [dbus-1]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) PKG_CHECK_MODULES([RPM], [rpm]) -PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([LIBNOTIFY], [libnotify]) PKG_CHECK_MODULES([NSS], [nss]) -PKG_CHECK_MODULES([XMLRPC], [xmlrpc]) -PKG_CHECK_MODULES([XMLRPC_CLIENT], [xmlrpc_client]) PKG_CHECK_MODULES([GNOME_KEYRING], [gnome-keyring-1]) PKG_CHECK_MODULES([BTPARSER], [btparser]) PKG_CHECK_MODULES([LIBREPORT], [libreport]) @@ -84,9 +81,6 @@ AC_ARG_WITH([systemdsystemunitdir], AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"])
-AC_CHECK_HEADER([libtar.h], [], - [AC_MSG_ERROR([libtar.h is needed to build abrt])]) - AC_CHECK_HEADER([sys/inotify.h], [], [AC_MSG_ERROR([sys/inotify.h is needed to build abrt])])
diff --git a/src/daemon/abrt_event.conf b/src/daemon/abrt_event.conf index bad6707..4971d28 100644 --- a/src/daemon/abrt_event.conf +++ b/src/daemon/abrt_event.conf @@ -74,6 +74,3 @@ EVENT=post-create analyzer=Python abrt-action-analyze-python EVENT=report_Bugzilla analyzer=Python test -f component || abrt-action-save-package-data abrt-action-bugzilla -c /etc/abrt/plugins/Bugzilla.conf - -EVENT=report_Logger - abrt-action-print -o "${Log_File:-/tmp/abrt.log}" -a "${Append:-no}" -r diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 163e7c3..d9465b3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -2,8 +2,7 @@ # libabrt_dbus - daemon, cli and applet use this # libabrt_web - for abrt-action-foo where foo deals with network/web/ftp/... lib_LTLIBRARIES = \ - libabrt.la \ - libabrt_web.la + libabrt.la
# Not used just yet: # time.cpp @@ -34,33 +33,6 @@ libabrt_la_LDFLAGS = \ libabrt_la_LIBADD = \ $(GLIB_LIBS)
-libabrt_web_la_SOURCES = \ - abrt_curl.h abrt_curl.c \ - abrt_xmlrpc.h abrt_xmlrpc.c -libabrt_web_la_CPPFLAGS = \ - -Wall -Wwrite-strings -Werror \ - -I$(srcdir)/../include \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DVAR_RUN="$(VAR_RUN)" \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(PLUGINS_CONF_DIR)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DEVENTS_DIR="$(EVENTS_DIR)" \ - $(GLIB_CFLAGS) \ - $(CURL_CFLAGS) \ - $(LIBXML_CFLAGS) \ - $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE -libabrt_web_la_LDFLAGS = \ - -version-info 0:1:0 -libabrt_web_la_LIBADD = \ - $(GLIB_LIBS) \ - $(CURL_LIBS) \ - $(LIBXML_LIBS) \ - $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) - $(DESTDIR)/$(DEBUG_DUMPS_DIR): $(mkdir_p) '$@' # no need to chmod it here diff --git a/src/lib/abrt_curl.c b/src/lib/abrt_curl.c deleted file mode 100644 index 34a9ada..0000000 --- a/src/lib/abrt_curl.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 "abrtlib.h" -#include "abrt_curl.h" - -/* - * Utility functions - */ -CURL* xcurl_easy_init() -{ - CURL* curl = curl_easy_init(); - if (!curl) - { - error_msg_and_die("Can't create curl handle"); - } - return curl; -} - -static char* -check_curl_error(CURLcode err, const char* msg) -{ - if (err) - return xasprintf("%s: %s", msg, curl_easy_strerror(err)); - return NULL; -} - -static void -die_if_curl_error(CURLcode err) -{ - if (err) { - char *msg = check_curl_error(err, "curl"); - error_msg_and_die("%s", msg); - } -} - -static void -xcurl_easy_setopt_ptr(CURL *handle, CURLoption option, const void *parameter) -{ - CURLcode err = curl_easy_setopt(handle, option, parameter); - if (err) { - char *msg = check_curl_error(err, "curl"); - error_msg_and_die("%s", msg); - } -} -static inline void -xcurl_easy_setopt_long(CURL *handle, CURLoption option, long parameter) -{ - xcurl_easy_setopt_ptr(handle, option, (void*)parameter); -} - -/* - * post_state utility functions - */ - -abrt_post_state_t *new_abrt_post_state(int flags) -{ - abrt_post_state_t *state = (abrt_post_state_t *)xzalloc(sizeof(*state)); - state->flags = flags; - return state; -} - -void free_abrt_post_state(abrt_post_state_t *state) -{ - char **headers = state->headers; - if (headers) - { - while (*headers) - free(*headers++); - free(state->headers); - } - free(state->curl_error_msg); - free(state->body); - free(state); -} - -char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str) -{ - char **headers = state->headers; - if (headers) - { - unsigned len = strlen(str); - while (*headers) - { - if (strncmp(*headers, str, len) == 0) - return skip_whitespace(*headers + len); - headers++; - } - } - return NULL; -} - -/* - * abrt_post: perform HTTP POST transaction - */ - -/* "save headers" callback */ -static size_t -save_headers(void *buffer_pv, size_t count, size_t nmemb, void *ptr) -{ - abrt_post_state_t* state = (abrt_post_state_t*)ptr; - size_t size = count * nmemb; - - char *h = xstrndup((char*)buffer_pv, size); - strchrnul(h, '\r')[0] = '\0'; - strchrnul(h, '\n')[0] = '\0'; - - unsigned cnt = state->header_cnt; - - /* Check for the case when curl follows a redirect: - * header 0: 'HTTP/1.1 301 Moved Permanently' - * header 1: 'Connection: close' - * header 2: 'Location: NEW_URL' - * header 3: '' - * header 0: 'HTTP/1.1 200 OK' <-- we need to forget all hdrs and start anew - */ - if (cnt != 0 - && strncmp(h, "HTTP/", 5) == 0 - && state->headers[cnt-1][0] == '\0' /* prev header is an empty string */ - ) { - char **headers = state->headers; - if (headers) - { - while (*headers) - free(*headers++); - } - cnt = 0; - } - - VERB3 log("save_headers: header %d: '%s'", cnt, h); - state->headers = (char**)xrealloc(state->headers, (cnt+2) * sizeof(state->headers[0])); - state->headers[cnt] = h; - state->header_cnt = ++cnt; - state->headers[cnt] = NULL; - - return size; -} - -/* "read local data from a file" callback */ -static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata) -{ - static time_t last_t; // hack - - FILE *fp = (FILE*)userdata; - time_t t = time(NULL); - - // Report current file position every 16 seconds - if (!(t & 0xf) && last_t != t) - { - last_t = t; - off_t cur_pos = ftello(fp); - fseeko(fp, 0, SEEK_END); - off_t sz = ftello(fp); - fseeko(fp, cur_pos, SEEK_SET); - log(_("Uploaded: %llu of %llu kbytes"), - (unsigned long long)cur_pos / 1024, - (unsigned long long)sz / 1024); - } - - return fread(ptr, size, nmemb, fp); -} - -static int curl_debug(CURL *handle, curl_infotype it, char *buf, size_t bufsize, void *unused) -{ - if (logmode == 0) - return 0; - - switch (it) { - case CURLINFO_TEXT: /* The data is informational text. */ - log("curl: %.*s", (int) bufsize, buf); - break; - case CURLINFO_HEADER_IN: /* The data is header (or header-like) data received from the peer. */ - log("curl rcvd header: '%.*s'", (int) bufsize, buf); - break; - case CURLINFO_HEADER_OUT: /* The data is header (or header-like) data sent to the peer. */ - log("curl sent header: '%.*s'", (int) bufsize, buf); - break; - case CURLINFO_DATA_IN: /* The data is protocol data received from the peer. */ - if (g_verbose >= 3) - log("curl rcvd data: '%.*s'", (int) bufsize, buf); - else - log("curl rcvd data %u bytes", (int) bufsize); - break; - case CURLINFO_DATA_OUT: /* The data is protocol data sent to the peer. */ - if (g_verbose >= 3) - log("curl sent data: '%.*s'", (int) bufsize, buf); - else - log("curl sent data %u bytes", (int) bufsize); - break; - default: - break; - } - - return 0; -} - -int -abrt_post(abrt_post_state_t *state, - const char *url, - const char *content_type, - const char **additional_headers, - const char *data, - off_t data_size) -{ - CURLcode curl_err; - long response_code; - abrt_post_state_t localstate; - - VERB3 log("abrt_post('%s','%s')", url, data); - - if (!state) - { - memset(&localstate, 0, sizeof(localstate)); - state = &localstate; - } - - state->http_resp_code = response_code = -1; - - CURL *handle = xcurl_easy_init(); - - // Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in. - // This may be more helpful than just return code from curl_easy_perform. - // curl will need it until curl_easy_cleanup. - state->errmsg[0] = '\0'; - xcurl_easy_setopt_ptr(handle, CURLOPT_ERRORBUFFER, state->errmsg); - // Shut off the built-in progress meter completely - xcurl_easy_setopt_long(handle, CURLOPT_NOPROGRESS, 1); - - if (g_verbose >= 2) { - // "Display a lot of verbose information about its operations. - // Very useful for libcurl and/or protocol debugging and understanding. - // The verbose information will be sent to stderr, or the stream set - // with CURLOPT_STDERR" - xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1); - xcurl_easy_setopt_ptr(handle, CURLOPT_DEBUGFUNCTION, curl_debug); - } - - // TODO: do we need to check for CURLE_URL_MALFORMAT error *here*, - // not in curl_easy_perform? - xcurl_easy_setopt_ptr(handle, CURLOPT_URL, url); - - // Auth if configured - if (state->username) { - // bitmask of allowed auth methods - xcurl_easy_setopt_long(handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - xcurl_easy_setopt_ptr(handle, CURLOPT_USERNAME, state->username); - xcurl_easy_setopt_ptr(handle, CURLOPT_PASSWORD, (state->password ? state->password : "")); - } - - // Do a regular HTTP post. This also makes curl use - // a "Content-Type: application/x-www-form-urlencoded" header. - // (This is by far the most commonly used POST method). - xcurl_easy_setopt_long(handle, CURLOPT_POST, 1); - // Supply POST data... - struct curl_httppost* post = NULL; - struct curl_httppost* last = NULL; - FILE* data_file = NULL; - if (data_size == ABRT_POST_DATA_FROMFILE) { - // ...from a file - data_file = fopen(data, "r"); - if (!data_file) -//FIXME: - perror_msg_and_die("Can't open '%s'", data); - xcurl_easy_setopt_ptr(handle, CURLOPT_READDATA, data_file); - // Want to use custom read function - xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const void*)fread_with_reporting); - } else if (data_size == ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) { - // ...from a file, in multipart/formdata format - const char *basename = strrchr(data, '/'); - if (basename) basename++; - else basename = data; -#if 0 - // Simple way, without custom reader function - CURLFORMcode curlform_err = curl_formadd(&post, &last, - CURLFORM_PTRNAME, "file", // element name - CURLFORM_FILE, data, // filename to read from - CURLFORM_CONTENTTYPE, content_type, - CURLFORM_FILENAME, basename, // filename to put in the form - CURLFORM_END); -#else - data_file = fopen(data, "r"); - if (!data_file) -//FIXME: - perror_msg_and_die("Can't open '%s'", data); - // Want to use custom read function - xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const void*)fread_with_reporting); - // Need to know file size - fseeko(data_file, 0, SEEK_END); - off_t sz = ftello(data_file); - fseeko(data_file, 0, SEEK_SET); - // Create formdata - CURLFORMcode curlform_err = curl_formadd(&post, &last, - CURLFORM_PTRNAME, "file", // element name - // use CURLOPT_READFUNCTION for reading, pass data_file as its last param: - CURLFORM_STREAM, data_file, - CURLFORM_CONTENTSLENGTH, (long)sz, // a must if we use CURLFORM_STREAM option - CURLFORM_CONTENTTYPE, content_type, - CURLFORM_FILENAME, basename, // filename to put in the form - CURLFORM_END); -#endif - if (curlform_err != 0) -//FIXME: - error_msg_and_die("out of memory or read error (curl_formadd error code: %d)", (int)curlform_err); - xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post); - } else { - // .. from a blob in memory - xcurl_easy_setopt_ptr(handle, CURLOPT_POSTFIELDS, data); - // note1: if data_size == ABRT_POST_DATA_STRING == -1, curl will use strlen(data) - xcurl_easy_setopt_long(handle, CURLOPT_POSTFIELDSIZE, data_size); - // note2: CURLOPT_POSTFIELDSIZE_LARGE can't be used: xcurl_easy_setopt_long() - // truncates data_size on 32-bit arch. Need xcurl_easy_setopt_long_long()? - // Also, I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1. - } - - struct curl_slist *httpheader_list = NULL; - - // Override "Content-Type:" - if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) - { - char *content_type_header = xasprintf("Content-Type: %s", content_type); - // Note: curl_slist_append() copies content_type_header - httpheader_list = curl_slist_append(httpheader_list, content_type_header); - if (!httpheader_list) - error_msg_and_die("out of memory"); - free(content_type_header); - } - - for (; additional_headers && *additional_headers; additional_headers++) - { - httpheader_list = curl_slist_append(httpheader_list, *additional_headers); - if (!httpheader_list) - error_msg_and_die("out of memory"); - } - - // Add User-Agent: ABRT/N.M - httpheader_list = curl_slist_append(httpheader_list, "User-Agent: ABRT/"VERSION); - if (!httpheader_list) - error_msg_and_die("out of memory"); - - if (httpheader_list) - xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPHEADER, httpheader_list); - -// Disabled: was observed to also handle "305 Use proxy" redirect, -// apparently with POST->GET remapping - which server didn't like at all. -// Attempted to suppress remapping on 305 using CURLOPT_POSTREDIR of -1, -// but it still did not work. -#if 0 - // Please handle 301/302 redirects for me - xcurl_easy_setopt_long(handle, CURLOPT_FOLLOWLOCATION, 1); - xcurl_easy_setopt_long(handle, CURLOPT_MAXREDIRS, 10); - // Bitmask to control how libcurl acts on redirects after POSTs. - // Bit 0 set (value CURL_REDIR_POST_301) makes libcurl - // not convert POST requests into GET requests when following - // a 301 redirection. Bit 1 (value CURL_REDIR_POST_302) makes libcurl - // maintain the request method after a 302 redirect. - // CURL_REDIR_POST_ALL is a convenience define that sets both bits. - // The non-RFC behaviour is ubiquitous in web browsers, so the library - // does the conversion by default to maintain consistency. - // However, a server may require a POST to remain a POST. - xcurl_easy_setopt_long(handle, CURLOPT_POSTREDIR, -1L /*CURL_REDIR_POST_ALL*/ ); -#endif - - // Prepare for saving information - if (state->flags & ABRT_POST_WANT_HEADERS) - { - xcurl_easy_setopt_ptr(handle, CURLOPT_HEADERFUNCTION, (void*)save_headers); - xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEHEADER, state); - } - FILE* body_stream = NULL; - if (state->flags & ABRT_POST_WANT_BODY) - { - body_stream = open_memstream(&state->body, &state->body_size); - if (!body_stream) - error_msg_and_die("out of memory"); - xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEDATA, body_stream); - } - if (!(state->flags & ABRT_POST_WANT_SSL_VERIFY)) - { - xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYPEER, 0); - xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYHOST, 0); - } - - // This is the place where everything happens. - // Here errors are not limited to "out of memory", can't just die. - curl_err = curl_easy_perform(handle); - if (curl_err) - { - VERB2 log("curl_easy_perform: error %d", (int)curl_err); - if (state->flags & ABRT_POST_WANT_ERROR_MSG) - { - state->curl_error_msg = check_curl_error(curl_err, "curl_easy_perform"); - VERB3 log("curl_easy_perform: error_msg: %s", state->curl_error_msg); - } - goto ret; - } - - // curl-7.20.1 doesn't do it, we get NULL body in the log message below - // unless we fflush the body memstream ourself - if (body_stream) - fflush(body_stream); - - // Headers/body are already saved (if requested), extract more info - curl_err = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code); - die_if_curl_error(curl_err); - state->http_resp_code = response_code; - VERB3 log("after curl_easy_perform: http code %ld body:'%s'", response_code, state->body); - - ret: - curl_easy_cleanup(handle); - if (httpheader_list) - curl_slist_free_all(httpheader_list); - if (body_stream) - fclose(body_stream); - if (data_file) - fclose(data_file); - if (post) - curl_formfree(post); - - return response_code; -} diff --git a/src/lib/abrt_curl.h b/src/lib/abrt_curl.h deleted file mode 100644 index ad2afc1..0000000 --- a/src/lib/abrt_curl.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 ABRT_CURL_H_ -#define ABRT_CURL_H_ - -#include <curl/curl.h> - -#ifdef __cplusplus -extern "C" { -#endif - -CURL* xcurl_easy_init(); - -typedef struct abrt_post_state { - /* Supplied by caller: */ - int flags; - const char *username; - const char *password; - /* Results of POST transaction: */ - int http_resp_code; - unsigned header_cnt; - char **headers; - char *curl_error_msg; - char *body; - size_t body_size; - char errmsg[CURL_ERROR_SIZE]; -} abrt_post_state_t; - -abrt_post_state_t *new_abrt_post_state(int flags); -void free_abrt_post_state(abrt_post_state_t *state); -char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str); - -enum { - ABRT_POST_WANT_HEADERS = (1 << 0), - ABRT_POST_WANT_ERROR_MSG = (1 << 1), - ABRT_POST_WANT_BODY = (1 << 2), - ABRT_POST_WANT_SSL_VERIFY = (1 << 3), -}; -enum { - /* Must be -1! CURLOPT_POSTFIELDSIZE interprets -1 as "use strlen" */ - ABRT_POST_DATA_STRING = -1, - ABRT_POST_DATA_FROMFILE = -2, - ABRT_POST_DATA_FROMFILE_AS_FORM_DATA = -3, -}; -int -abrt_post(abrt_post_state_t *state, - const char *url, - const char *content_type, - const char **additional_headers, - const char *data, - off_t data_size); -static inline int -abrt_post_string(abrt_post_state_t *state, - const char *url, - const char *content_type, - const char **additional_headers, - const char *str) -{ - return abrt_post(state, url, content_type, additional_headers, - str, ABRT_POST_DATA_STRING); -} -static inline int -abrt_post_file(abrt_post_state_t *state, - const char *url, - const char *content_type, - const char **additional_headers, - const char *filename) -{ - return abrt_post(state, url, content_type, additional_headers, - filename, ABRT_POST_DATA_FROMFILE); -} -static inline int -abrt_post_file_as_form(abrt_post_state_t *state, - const char *url, - const char *content_type, - const char **additional_headers, - const char *filename) -{ - return abrt_post(state, url, content_type, additional_headers, - filename, ABRT_POST_DATA_FROMFILE_AS_FORM_DATA); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c deleted file mode 100644 index 28d4232..0000000 --- a/src/lib/abrt_xmlrpc.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 "abrtlib.h" -#include "abrt_xmlrpc.h" - -void abrt_xmlrpc_die(xmlrpc_env *env) -{ - error_msg_and_die("fatal: XML-RPC(%d): %s", env->fault_code, env->fault_string); -} - -void abrt_xmlrpc_error(xmlrpc_env *env) -{ - error_msg("error: XML-RPC (%d): %s", env->fault_code, env->fault_string); -} - -struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - struct abrt_xmlrpc *ax = xzalloc(sizeof(struct abrt_xmlrpc)); - - /* This should be done at program startup, once. We do it in main */ - /* xmlrpc_client_setup_global_const(&env); */ - - /* URL - bugzilla.redhat.com/show_bug.cgi?id=666893 Unable to make sense of - * XML-RPC response from server - * - * By default, XML data from the network may be no larger than 512K. - * XMLRPC_XML_SIZE_LIMIT_DEFAULT is #defined to (512*1024) in xmlrpc-c/base.h - * - * Users reported trouble with 733402 byte long responses, hope raising the - * limit to 2*512k is enough - */ - xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 2 * XMLRPC_XML_SIZE_LIMIT_DEFAULT); - - struct xmlrpc_curl_xportparms curl_parms; - memset(&curl_parms, 0, sizeof(curl_parms)); - /* curlParms.network_interface = NULL; - done by memset */ - curl_parms.no_ssl_verifypeer = !ssl_verify; - curl_parms.no_ssl_verifyhost = !ssl_verify; -#ifdef VERSION - curl_parms.user_agent = PACKAGE_NAME"/"VERSION; -#else - curl_parms.user_agent = "abrt"; -#endif - - struct xmlrpc_clientparms client_parms; - memset(&client_parms, 0, sizeof(client_parms)); - client_parms.transport = "curl"; - client_parms.transportparmsP = &curl_parms; - client_parms.transportparm_size = XMLRPC_CXPSIZE(user_agent); - - xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, - PACKAGE_NAME, VERSION, - &client_parms, XMLRPC_CPSIZE(transportparm_size), - &ax->ax_client); - - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - ax->ax_server_info = xmlrpc_server_info_new(&env, url); - if (env.fault_occurred) - { - xmlrpc_client_destroy(ax->ax_client); - abrt_xmlrpc_die(&env); - } - - return ax; -} - -void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax) -{ - if (!ax) - return; - - if (ax->ax_server_info) - xmlrpc_server_info_free(ax->ax_server_info); - - if (ax->ax_client) - xmlrpc_client_destroy(ax->ax_client); - - free(ax); -} - -/* die or return expected results */ -xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, - const char* method, const char* format, ...) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_value* param = NULL; - const char* suffix; - va_list args; - - va_start(args, format); - xmlrpc_build_value_va(&env, format, args, ¶m, &suffix); - va_end(args); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - xmlrpc_value* result = NULL; - if (*suffix != '\0') - { - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one argument.", - suffix); - } - else - { - xmlrpc_client_call2(&env, ax->ax_client, ax->ax_server_info, method, - param, &result); - } - xmlrpc_DECREF(param); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - return result; -} diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h deleted file mode 100644 index 5c94360..0000000 --- a/src/lib/abrt_xmlrpc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 ABRT_XMLRPC_H_ -#define ABRT_XMLRPC_H_ 1 - -/* include/stdint.h: typedef int int32_t; - * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; - */ - -#include <xmlrpc-c/base.h> -#include <xmlrpc-c/client.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct abrt_xmlrpc { - xmlrpc_client *ax_client; - xmlrpc_server_info *ax_server_info; -}; - -struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify); -void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax); -void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn)); -void abrt_xmlrpc_error(xmlrpc_env *env); - -/* die or return expected results */ -xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, - const char *method, const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/plugins/Bugzilla.conf b/src/plugins/Bugzilla.conf deleted file mode 100644 index 76e0d1d..0000000 --- a/src/plugins/Bugzilla.conf +++ /dev/null @@ -1,12 +0,0 @@ -# Description: Reports bugs to bugzilla - -Enabled = yes - -# Bugzilla URL -BugzillaURL = https://bugzilla.redhat.com/ -# yes means that ssl certificates will be checked -SSLVerify = yes -# your login has to exist, if you don have any, please create one -Login = -# your password -Password = diff --git a/src/plugins/Kerneloops.conf b/src/plugins/Kerneloops.conf deleted file mode 100644 index a0b86e8..0000000 --- a/src/plugins/Kerneloops.conf +++ /dev/null @@ -1,3 +0,0 @@ -Enabled = yes - -SubmitURL = http://submit.kerneloops.org/submitoops.php diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 79ca7a4..2c2d5af 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -15,12 +15,6 @@ bin_PROGRAMS = \ abrt-action-trim-files \ abrt-action-generate-backtrace \ abrt-action-analyze-backtrace \ - abrt-action-bugzilla \ - abrt-action-rhtsupport \ - abrt-action-kerneloops \ - abrt-action-upload \ - abrt-action-mailx \ - abrt-action-print \ abrt-action-install-debuginfo-to-abrt-cache \ abrt-retrace-client
@@ -28,25 +22,12 @@ pluginsconfdir = $(PLUGINS_CONF_DIR)
#dist_pluginsconf_DATA = Python.conf
-reportpluginsconfdir = $(REPORT_PLUGINS_CONF_DIR) - -dist_reportpluginsconf_DATA = \ - Kerneloops.conf \ - Bugzilla.conf \ - Upload.conf - eventsdir = $(EVENTS_DIR)
dist_events_DATA = \ - report_Bugzilla.xml \ - report_Bugzilla.conf \ - report_Logger.conf \ analyze_LocalGDB.xml \ analyze_RetraceServer.xml \ - analyze_xsession_errors.xml \ - report_Mailx.xml \ - report_RHTSupport.xml \ - report_Kerneloops.xml + analyze_xsession_errors.xml
@INTLTOOL_XML_RULE@
@@ -54,25 +35,18 @@ eventsconfdir = $(EVENTS_CONF_DIR)
dist_eventsconf_DATA = \ ccpp_events.conf \ - mailx_events.conf \ koops_events.conf \ - rhtsupport_events.conf \ smart_event.conf
man_MANS = \ abrt-plugins.7
MAN_TXT = \ - abrt-action-print.txt \ abrt-action-trim-files.txt \ abrt-action-generate-backtrace.txt \ abrt-action-analyze-backtrace.txt \ abrt-action-analyze-oops.txt \ - abrt-action-mailx.txt \ - abrt-action-bugzilla.txt \ abrt-action-list-dsos.txt \ - abrt-action-kerneloops.txt \ - abrt-action-upload.txt \ abrt-retrace-client.txt
# Manual pages are generated from .txt via Docbook @@ -99,13 +73,7 @@ EXTRA_DIST = \ $(man1_MANS) \ analyze_xsession_errors.xml.in \ analyze_LocalGDB.xml.in \ - analyze_RetraceServer.xml.in \ - report_Bugzilla.xml.in \ - report_Bugzilla.conf \ - report_Logger.conf \ - report_Mailx.xml.in \ - report_RHTSupport.xml.in \ - report_Kerneloops.xml.in + analyze_RetraceServer.xml.in
$(DESTDIR)/$(DEBUG_INFO_DIR): $(mkdir_p) '$@' @@ -254,140 +222,6 @@ abrt_action_analyze_backtrace_LDADD = \ $(LIBREPORT_LIBS) \ $(BTPARSER_LIBS)
-abrt_action_bugzilla_SOURCES = \ - abrt-action-bugzilla.c rhbz.c rhbz.h -abrt_action_bugzilla_CPPFLAGS = \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -abrt_action_bugzilla_LDADD = \ - $(GLIB_LIBS) \ - ../lib/libabrt_web.la \ - $(LIBREPORT_LIBS) - -abrt_action_rhtsupport_SOURCES = \ - abrt_rh_support.h abrt_rh_support.c \ - abrt-action-rhtsupport.c -abrt_action_rhtsupport_CPPFLAGS = \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -Werror -abrt_action_rhtsupport_LDFLAGS = -ltar -abrt_action_rhtsupport_LDADD = \ - $(GLIB_LIBS) \ - $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \ - ../lib/libabrt_web.la \ - $(LIBREPORT_LIBS) - -abrt_action_upload_SOURCES = \ - abrt-action-upload.c -abrt_action_upload_CPPFLAGS = \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(CURL_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -Werror -abrt_action_upload_LDFLAGS = -ltar -abrt_action_upload_LDADD = \ - $(GLIB_LIBS) \ - $(CURL_LIBS) \ - $(LIBREPORT_LIBS) - -abrt_action_kerneloops_SOURCES = \ - abrt-action-kerneloops.c -abrt_action_kerneloops_CPPFLAGS = \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -Werror -abrt_action_kerneloops_LDADD = \ - ../lib/libabrt_web.la \ - $(LIBREPORT_LIBS) - -abrt_action_mailx_SOURCES = \ - abrt-action-mailx.c -abrt_action_mailx_CPPFLAGS = \ - -I$(srcdir)/../libreport/src/include/ -I$(srcdir)/../include \ - -I$(srcdir)/../libreport/src/lib \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -Werror -abrt_action_mailx_LDADD = \ - $(LIBREPORT_LIBS) - -abrt_action_print_SOURCES = \ - abrt-action-print.c -abrt_action_print_CPPFLAGS = \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ - -DBIN_DIR="$(bindir)" \ - -DVAR_RUN="$(VAR_RUN)" \ - -DCONF_DIR="$(CONF_DIR)" \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DDEBUG_DUMPS_DIR="$(DEBUG_DUMPS_DIR)" \ - -DDEBUG_INFO_DIR="$(DEBUG_INFO_DIR)" \ - -DPLUGINS_LIB_DIR="$(PLUGINS_LIB_DIR)" \ - -DPLUGINS_CONF_DIR="$(REPORT_PLUGINS_CONF_DIR)" \ - $(GLIB_CFLAGS) \ - $(LIBREPORT_CFLAGS) \ - -D_GNU_SOURCE \ - -Wall -Wwrite-strings -Werror -abrt_action_print_LDADD = \ - $(LIBREPORT_LIBS) - abrt_action_install_debuginfo_to_abrt_cache_SOURCES = \ abrt-action-install-debuginfo-to-abrt-cache.c abrt_action_install_debuginfo_to_abrt_cache_CPPFLAGS = \ diff --git a/src/plugins/Upload.conf b/src/plugins/Upload.conf deleted file mode 100644 index 803b0ac..0000000 --- a/src/plugins/Upload.conf +++ /dev/null @@ -1,9 +0,0 @@ -# Description: Packs problem data into .tar.gz file and uploads it via FTP/SCP/etc - -# URL to upload the files to. -# supported: ftp, ftps, http, https, scp, sftp, tftp, file -# for example: ftp://user:password@server.name/directory -# or: scp://user:password@server.name:port/directory etc. -# for testing: file:///tmp/test_directory -# If empty, the prepared archive is stored in /var/run/abrt/ -URL = diff --git a/src/plugins/abrt-action-bugzilla.c b/src/plugins/abrt-action-bugzilla.c deleted file mode 100644 index 108365b..0000000 --- a/src/plugins/abrt-action-bugzilla.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 "abrtlib.h" -#include "abrt_xmlrpc.h" -#include "rhbz.h" - -#define XML_RPC_SUFFIX "/xmlrpc.cgi" - -static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings) -{ - problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); - if (!problem_data) - xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ - - const char *env; - const char *login; - const char *password; - const char *bugzilla_xmlrpc; - const char *bugzilla_url; - bool ssl_verify; - - env = getenv("Bugzilla_Login"); - login = env ? env : get_map_string_item_or_empty(settings, "Login"); - env = getenv("Bugzilla_Password"); - password = env ? env : get_map_string_item_or_empty(settings, "Password"); - if (!login[0] || !password[0]) - error_msg_and_die(_("Empty login or password, please check your configuration")); - - env = getenv("Bugzilla_BugzillaURL"); - bugzilla_url = env ? env : get_map_string_item_or_empty(settings, "BugzillaURL"); - if (!bugzilla_url[0]) - bugzilla_url = "https://bugzilla.redhat.com"; - bugzilla_xmlrpc = xasprintf("%s"XML_RPC_SUFFIX, bugzilla_url); - - env = getenv("Bugzilla_SSLVerify"); - ssl_verify = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SSLVerify")); - - const char *component = get_problem_item_content_or_NULL(problem_data, FILENAME_COMPONENT); - const char *duphash = get_problem_item_content_or_NULL(problem_data, FILENAME_DUPHASH); -//COMPAT, remove after 2.1 release - if (!duphash) duphash = get_problem_item_content_or_NULL(problem_data, "global_uuid"); - if (!duphash) - error_msg_and_die(_("Essential file '%s' is missing, can't continue.."), - FILENAME_DUPHASH); - - if (!*duphash) - error_msg_and_die(_("Essential file '%s' is empty, can't continue.."), - FILENAME_DUPHASH); - - 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"); - - struct abrt_xmlrpc *client = abrt_xmlrpc_new_client(bugzilla_xmlrpc, ssl_verify); - - log(_("Logging into Bugzilla at %s"), bugzilla_url); - rhbz_login(client, login, password); - - log(_("Checking for duplicates")); - char *product = NULL; - char *version = NULL; - parse_release_for_bz(release, &product, &version); - free(version); - - xmlrpc_value *result; - if (strcmp(product, "Fedora") == 0) - result = rhbz_search_duphash(client, component, product, duphash); - else - result = rhbz_search_duphash(client, component, NULL, duphash); - - xmlrpc_value *all_bugs = rhbz_get_member("bugs", result); - xmlrpc_DECREF(result); - - if (!all_bugs) - error_msg_and_die(_("Missing mandatory member 'bugs'")); - - 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; - struct bug_info *bz = NULL; - if (all_bugs_size > 0) - { - bug_id = rhbz_bug_id(all_bugs); - xmlrpc_DECREF(all_bugs); - bz = rhbz_bug_info(client, bug_id); - - if (strcmp(bz->bi_product, product) != 0) - { - /* found something, but its a different product */ - free_bug_info(bz); - - xmlrpc_value *result = rhbz_search_duphash(client, component, - product, duphash); - xmlrpc_value *all_bugs = rhbz_get_member("bugs", result); - xmlrpc_DECREF(result); - - all_bugs_size = rhbz_array_size(all_bugs); - if (all_bugs_size > 0) - { - bug_id = rhbz_bug_id(all_bugs); - bz = rhbz_bug_info(client, bug_id); - } - xmlrpc_DECREF(all_bugs); - } - } - free(product); - - if (all_bugs_size == 0) // Create new bug - { - log(_("Creating a new bug")); - bug_id = rhbz_new_bug(client, problem_data, bug_id); - - 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, RHBZ_NOMAIL_NOTIFY); - - bz = new_bug_info(); - bz->bi_status = xstrdup("NEW"); - bz->bi_id = bug_id; - goto log_out; - } - - // decision based on state - log(_("Bug is already reported: %i"), bz->bi_id); - if ((strcmp(bz->bi_status, "CLOSED") == 0) - && (strcmp(bz->bi_resolution, "DUPLICATE") == 0) - ) { - struct bug_info *origin; - origin = rhbz_find_origin_bug_closed_duplicate(client, bz); - if (origin) - { - free_bug_info(bz); - bz = origin; - } - } - - if (strcmp(bz->bi_status, "CLOSED") != 0) - { - 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); - rhbz_mail_to_cc(client, bz->bi_id, login, RHBZ_NOMAIL_NOTIFY); - } - - const char *comment = get_problem_item_content_or_NULL(problem_data, FILENAME_COMMENT); - if (comment && comment[0]) - { - 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); -//COMPAT, remove in abrt-2.1 release - if (!release)release= get_problem_item_content_or_NULL(problem_data, "release"); - const char *arch = get_problem_item_content_or_NULL(problem_data, FILENAME_ARCHITECTURE); - char *full_dsc = xasprintf("Package: %s\n" - "Architecture: %s\n" - "OS Release: %s\n" - "\n" - "Comment\n" - "-----\n" - "%s\n", - package, arch, release, comment - ); - log(_("Adding new comment to bug %d"), bz->bi_id); - /* unused code, enable it when gui/cli will be ready - int is_priv = is_private && string_to_bool(is_private); - const char *is_private = get_problem_item_content_or_NULL(problem_data, - "is_private"); - */ - rhbz_add_comment(client, bz->bi_id, full_dsc, 0); - free(full_dsc); - } - } - - log_out: - log(_("Logging out")); - rhbz_logout(client); - - log("Status: %s%s%s %s/show_bug.cgi?id=%u", - bz->bi_status, - bz->bi_resolution ? " " : "", - bz->bi_resolution ? bz->bi_resolution : "", - bugzilla_url, - bz->bi_id); - - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (dd) - { - 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); - free_bug_info(bz); - abrt_xmlrpc_free_client(client); -} - -int main(int argc, char **argv) -{ - abrt_init(argv); - - map_string_h *settings = new_map_string(); - const char *dump_dir_name = "."; - GList *conf_file = NULL; - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] [-c CONFFILE] -d DIR\n" - "\n" - "Reports problem to Bugzilla.\n" - "\n" - "The tool reads DIR. Then it logs in to Bugzilla and tries to find a bug\n" - "with the same abrt_hash:HEXSTRING in 'Whiteboard'.\n" - "\n" - "If such bug is not found, then a new bug is created. Elements of DIR\n" - "are stored in the bug as part of bug description or as attachments,\n" - "depending on their type and size.\n" - "\n" - "Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE,\n" - "the tool follows the chain of duplicates until it finds a non-DUPLICATE bug.\n" - "The tool adds a new comment to found bug.\n" - "\n" - "The URL to new or modified bug is printed to stdout and recorded in\n" - "'reported_to' element.\n" - "\n" - "CONFFILE lines should have 'PARAM = VALUE' format.\n" - "Recognized string parameters: BugzillaURL, Login, Password.\n" - "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" - "Parameters can be overridden via $Bugzilla_PARAM environment variables." - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_c = 1 << 2, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file (may be given many times)")), - OPT_END() - }; - /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - while (conf_file) - { - char *fn = (char *)conf_file->data; - VERB1 log("Loading settings from '%s'", fn); - load_conf_file(fn, settings, /*skip key w/o values:*/ true); - VERB3 log("Loaded '%s'", fn); - conf_file = g_list_remove(conf_file, fn); - } - - VERB1 log("Initializing XML-RPC library"); - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_client_setup_global_const(&env); - if (env.fault_occurred) - error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code); - xmlrpc_env_clean(&env); - - report_to_bugzilla(dump_dir_name, settings); - - free_map_string(settings); - return 0; -} diff --git a/src/plugins/abrt-action-bugzilla.txt b/src/plugins/abrt-action-bugzilla.txt deleted file mode 100644 index 6002ccf..0000000 --- a/src/plugins/abrt-action-bugzilla.txt +++ /dev/null @@ -1,67 +0,0 @@ -abrt-action-buzilla(1) -==================== - -NAME ----- -abrt-action-bugzilla - Reports problem to Bugzilla. - -SYNOPSIS --------- -'abrt-action-bugzilla' [-v] [-c CONFFILE] -d DIR - -DESCRIPTION ------------ -The tool reads problem dump directory DIR. Then it logs in to Bugzilla -and tries to find a bug with the same abrt_hash:HEXSTRING in 'Whiteboard'. - -If such bug is not found, then a new bug is created. Elements of DIR -are stored in the bug as part of bug description or as attachments, -depending on their type and size. - -Otherwise, if such bug is found and it is marked as CLOSED DUPLICATE, -the tool follows the chain of duplicates until it finds a non-DUPLICATE bug. -The tool adds a new comment to found bug. - -The URL to new or modified bug is printed to stdout and recorded in -'reported_to' element in DIR. - -Configuration file -~~~~~~~~~~~~~~~~~~ -Configuration file lines should have 'PARAM = VALUE' format. The parameters are: - -'Login':: - Login to Bugzilla account. - -'Password':: - Password to Bugzilla account. - -'BugzillaURL':: - Bugzilla http(s) address. (default: https://bugzilla.redht.com) - -'SSLVerify':: - Use yes/true/on/1 to verify Bugzilla ssl certificate. (default: yes) - -Parameters can be overridden via $Bugzilla_PARAM environment variables. - -Integration with ABRT events -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-bugzilla' can be used as an ABRT reporter. Example -fragment for /etc/abrt/abrt_events.conf: - ------------- -# Report Python crashes -EVENT=report_Bugzilla analyzer=Python - abrt-action-bugzilla -d . -c /etc/abrt/plugins/Bugzilla.conf ------------- - -OPTIONS -------- --d DIR:: - Path to dump directory. - --c CONFFILE:: - Path to configration file. - -SEE ALSO --------- -abrt_event.conf diff --git a/src/plugins/abrt-action-kerneloops.c b/src/plugins/abrt-action-kerneloops.c deleted file mode 100644 index 79186f8..0000000 --- a/src/plugins/abrt-action-kerneloops.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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. - - Authors: - Anton Arapov anton@redhat.com - Arjan van de Ven arjan@linux.intel.com - */ -#include <curl/curl.h> -#include "abrtlib.h" - -/* helpers */ -static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) -{ - size *= nmemb; -/* - char *c, *c1, *c2; - - log("received: '%*.*s'", (int)size, (int)size, (char*)ptr); - c = (char*)xzalloc(size + 1); - memcpy(c, ptr, size); - c1 = strstr(c, "201 "); - if (c1) - { - c1 += 4; - c2 = strchr(c1, '\n'); - if (c2) - *c2 = 0; - } - free(c); -*/ - - return size; -} - -/* Send oops data to kerneloops.org-style site, using HTTP POST */ -/* Returns 0 on success */ -static CURLcode http_post_to_kerneloops_site(const char *url, const char *oopsdata) -{ - CURLcode ret; - CURL *handle; - struct curl_httppost *post = NULL; - struct curl_httppost *last = NULL; - - handle = curl_easy_init(); - if (!handle) - error_msg_and_die("Can't create curl handle"); - - curl_easy_setopt(handle, CURLOPT_URL, url); - - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "oopsdata", - CURLFORM_COPYCONTENTS, oopsdata, - CURLFORM_END); - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "pass_on_allowed", - CURLFORM_COPYCONTENTS, "yes", - CURLFORM_END); - - curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); - curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefunction); - - ret = curl_easy_perform(handle); - - curl_formfree(post); - curl_easy_cleanup(handle); - - return ret; -} - -static void report_to_kerneloops( - const char *dump_dir_name, - map_string_h *settings) -{ - problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); - if (!problem_data) - xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ - - const char *backtrace = get_problem_item_content_or_NULL(problem_data, FILENAME_BACKTRACE); - if (!backtrace) - error_msg_and_die("Error sending kernel oops due to missing backtrace"); - - const char *env = getenv("KerneloopsReporter_SubmitURL"); - const char *submitURL = (env ? env : get_map_string_item_or_empty(settings, "SubmitURL")); - if (!submitURL[0]) - submitURL = "http://submit.kerneloops.org/submitoops.php"; - - log(_("Submitting oops report to %s"), submitURL); - - CURLcode ret = http_post_to_kerneloops_site(submitURL, backtrace); - if (ret != CURLE_OK) - error_msg_and_die("Kernel oops has not been sent due to %s", curl_easy_strerror(ret)); - - free_problem_data(problem_data); - - /* Server replies with: - * 200 thank you for submitting the kernel oops information - * RemoteIP: 34192fd15e34bf60fac6a5f01bba04ddbd3f0558 - * - no URL or bug ID apparently... - */ - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (dd) - { - char *msg = xasprintf("kerneloops: URL=%s", submitURL); - add_reported_to(dd, msg); - free(msg); - dd_close(dd); - } - - log("Kernel oops report was uploaded"); -} - -int main(int argc, char **argv) -{ - abrt_init(argv); - - map_string_h *settings = new_map_string(); - const char *dump_dir_name = "."; - GList *conf_file = NULL; - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] [-c CONFFILE]... -d DIR\n" - "\n" - "Reports kernel oops to kerneloops.org (or similar) site" - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_c = 1 << 2, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file")), - OPT_END() - }; - /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - while (conf_file) - { - char *fn = (char *)conf_file->data; - VERB1 log("Loading settings from '%s'", fn); - load_conf_file(fn, settings, /*skip key w/o values:*/ true); - VERB3 log("Loaded '%s'", fn); - conf_file = g_list_remove(conf_file, fn); - } - - report_to_kerneloops(dump_dir_name, settings); - - free_map_string(settings); - return 0; -} diff --git a/src/plugins/abrt-action-kerneloops.txt b/src/plugins/abrt-action-kerneloops.txt deleted file mode 100644 index 0a49a4b..0000000 --- a/src/plugins/abrt-action-kerneloops.txt +++ /dev/null @@ -1,68 +0,0 @@ -abrt-action-kerneloops(1) -========================= - -NAME ----- -abrt-action-kerneloops - Reports kernel oops to kerneloops.org (or similar) -site. - -SYNOPSIS --------- -'abrt-action-kerneloops' [-v] [-c CONFFILE]... [ -d DIR ] - -DESCRIPTION ------------ -The tool is used to report the crash to the Kerneloops tracker. - -Configuration file -~~~~~~~~~~~~~~~~~~ -Configuration file contains entries in a format "Option = Value". - -The options are: - -'SubmitURL':: - The URL of the kerneloops tracker, the default is - "http://submit.kerneloops.org/submitoops.php". - -Integration with ABRT events -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-kerneloops' can be used as a reporter, to allow users to report -problems to the Kerneloops tracker. This usage is pre-configured in -/etc/abrt/events.d/koops_events.conf: - ------------- -EVENT=report_Kerneloops analyzer=Kerneloops abrt-action-kerneloops ------------- - -It can be also used automatically and immediately without user interaction. -When this is desired, modify the event configuration file to run the tool on -the 'post-create' event: - ------------- -EVENT=post-create analyzer=Kerneloops abrt-action-kerneloops ------------- - -OPTIONS -------- --v:: - Be more verbose. Can be given multiple times. - --d DIR:: - Path to dump directory. - --c CONFFILE:: - Path to configration file. When used in ABRT event system, the file - contains site-wide configuration. Users can change the values via - environment variables. - -ENVIRONMENT VARIABLES ---------------------- -Environment variables take precedence over values provided in -the configuration file. - -'KerneloopsReporter_SubmitURL':: - The URL of the kerneloops tracker. - -AUTHORS -------- -* ABRT team diff --git a/src/plugins/abrt-action-mailx.c b/src/plugins/abrt-action-mailx.c deleted file mode 100644 index 21014e5..0000000 --- a/src/plugins/abrt-action-mailx.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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 "abrtlib.h" - -static void exec_and_feed_input(const char* text, char **args) -{ - int pipein[2]; - - pid_t child = fork_execv_on_steroids( - EXECFLG_INPUT | EXECFLG_QUIET, - args, - pipein, - /*env_vec:*/ NULL, - /*dir:*/ NULL, - /*uid (ignored):*/ 0 - ); - - full_write_str(pipein[1], text); - close(pipein[1]); - - int status; - waitpid(child, &status, 0); /* wait for command completion */ - if (status != 0) - error_msg_and_die("Error running '%s'", args[0]); -} - -static char** append_str_to_vector(char **vec, unsigned *size_p, const char *str) -{ - //log("old vec: %p", vec); - unsigned size = *size_p; - vec = (char**) xrealloc(vec, (size+2) * sizeof(vec[0])); - vec[size] = xstrdup(str); - //log("new vec: %p, added [%d] %p", vec, size, vec[size]); - size++; - vec[size] = NULL; - *size_p = size; - return vec; -} - -static void create_and_send_email( - const char *dump_dir_name, - map_string_h *settings) -{ - problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); - if (!problem_data) - xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ - - char* env; - env = getenv("Mailx_Subject"); - const char *subject = (env ? env : get_map_string_item_or_NULL(settings, "Subject") ? : "[abrt] full crash report"); - env = getenv("Mailx_EmailFrom"); - const char *email_from = (env ? env : get_map_string_item_or_NULL(settings, "EmailFrom") ? : "user@localhost"); - env = getenv("Mailx_EmailTo"); - const char *email_to = (env ? env : get_map_string_item_or_NULL(settings, "EmailTo") ? : "root@localhost"); - env = getenv("Mailx_SendBinaryData"); - bool send_binary_data = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SendBinaryData")); - - char **args = NULL; - unsigned arg_size = 0; - args = append_str_to_vector(args, &arg_size, "/bin/mailx"); - - char *dsc = make_description_mailx(problem_data); - - if (send_binary_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)) - { - if (value->flags & CD_FLAG_BIN) - { - args = append_str_to_vector(args, &arg_size, "-a"); - args = append_str_to_vector(args, &arg_size, value->content); - } - } - } - - args = append_str_to_vector(args, &arg_size, "-s"); - args = append_str_to_vector(args, &arg_size, subject); - args = append_str_to_vector(args, &arg_size, "-r"); - args = append_str_to_vector(args, &arg_size, email_from); - args = append_str_to_vector(args, &arg_size, email_to); - - log(_("Sending an email...")); - exec_and_feed_input(dsc, args); - - free(dsc); - - while (*args) - free(*args++); - args -= arg_size; - free(args); - - free_problem_data(problem_data); - - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (dd) - { - char *msg = xasprintf("email: %s", email_to); - add_reported_to(dd, msg); - free(msg); - dd_close(dd); - } - log("Email was sent to: %s", email_to); -} - -int main(int argc, char **argv) -{ - abrt_init(argv); - - const char *dump_dir_name = "."; - const char *conf_file = NULL; - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] -d DIR [-c CONFFILE]\n" - "\n" - "Sends contents of a dump directory DIR via email" - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_c = 1 << 2, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_STRING('c', NULL, &conf_file , "CONFFILE", _("Config file")), - OPT_END() - }; - /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - map_string_h *settings = new_map_string(); - if (conf_file) - load_conf_file(conf_file, settings, /*skip key w/o values:*/ true); - - create_and_send_email(dump_dir_name, settings); - - free_map_string(settings); - return 0; -} diff --git a/src/plugins/abrt-action-mailx.txt b/src/plugins/abrt-action-mailx.txt deleted file mode 100644 index a12c2bf..0000000 --- a/src/plugins/abrt-action-mailx.txt +++ /dev/null @@ -1,91 +0,0 @@ -abrt-action-mailx(1) -==================== - -NAME ----- -abrt-action-mailx - Sends contents of a dump directory via email. - -SYNOPSIS --------- -'abrt-action-mailx' [-v] -d DIR [-c CONFFILE] - -DESCRIPTION ------------ -The tool reads a problem dump directory, composes an email message -from the directory contents, and uses mailx to send the message to -specified recipient. - -Properties of email messages can be specified in a configuration file, -and via environment variables. - -Configuration file -~~~~~~~~~~~~~~~~~~ -Configuration file contains entries in a format "Option = Value". - -The options are: - -'Subject':: - The subject of the email message. - -'EmailFrom':: - The sender of the email message. - -'EmailTo':: - The recipient of the email message. - -'SendBinaryData':: - Use yes/true/on/1 to attach all binary files from the dump - directory to the email. This can cause the emails to be very - large. - -Integration with ABRT events -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-mailx' can be used as a reporter, to allow users report -problems via email when they decide to do it. This usage is -pre-configured in /etc/abrt/events.d/mailx_events.conf: - ------------- -EVENT=report_Mailx abrt-action-mailx ------------- - -It can also be used to notify administrator automatically when a -problem happens. When this is desired, modify the event configuration -file to run the tool on the 'post-create' event: - ------------- -EVENT=post-create abrt-action-mailx ------------- - -OPTIONS -------- --d DIR:: - Path to dump directory. - --c CONFFILE:: - Path to configration file. When used in ABRT event system, the file - contains site-wide configuration. Users can change the values via - environment variables. - -ENVIRONMENT VARIABLES ---------------------- -Environment variables take precedence over values provided in -the configuration file. - -'Mailx_Subject':: - Subject of the email message. - -'Mailx_EmailFrom':: - Sender of the email message. - -'Mailx_EmailTo':: - Recipient of the email message. If nor the environment variable - nor the corresponding option is defined, the message is send to - "root@localhost". - -'Mailx_SendBinaryData':: - Use yes/true/on/1 to attach all binary files from the dump - directory to the email. - -AUTHORS -------- -* ABRT team diff --git a/src/plugins/abrt-action-print.c b/src/plugins/abrt-action-print.c deleted file mode 100644 index 9bad3d2..0000000 --- a/src/plugins/abrt-action-print.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - Write crash dump to stdout in text form. - - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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 "abrtlib.h" - -static const char *dump_dir_name = "."; -static const char *output_file = NULL; -static const char *append = "no"; -static const char *open_mode = "w"; - -int main(int argc, char **argv) -{ - abrt_init(argv); - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] -d DIR [-o FILE] [-a yes/no] [-r]\n" - "\n" - "Prints problem information to standard output or FILE" - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_o = 1 << 2, - OPT_a = 1 << 3, - OPT_r = 1 << 4, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_STRING('o', NULL, &output_file , "FILE" , _("Output file")), - OPT_STRING('a', NULL, &append , "yes/no", _("Append to, or overwrite FILE")), - OPT_BOOL( 'r', NULL, NULL , _("Create reported_to in DIR")), - OPT_END() - }; - unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - if (output_file) - { - if (string_to_bool(append)) - open_mode = "a"; - if (!freopen(output_file, open_mode, stdout)) - perror_msg_and_die("Can't open '%s'", output_file); - } - - problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); - if (!problem_data) - xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ - - char *dsc = make_description_logger(problem_data); - fputs(dsc, stdout); - if (open_mode[0] == 'a') - fputs("\nEND:\n\n", stdout); - free(dsc); - free_problem_data(problem_data); - - if (output_file) - { - if (opts & OPT_r) - { - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (dd) - { - char *msg = xasprintf("file: %s", output_file); - add_reported_to(dd, msg); - free(msg); - dd_close(dd); - } - } - const char *format = (open_mode[0] == 'a' ? _("The report was appended to %s") : _("The report was stored to %s")); - log(format, output_file); - } - - return 0; -} diff --git a/src/plugins/abrt-action-print.txt b/src/plugins/abrt-action-print.txt deleted file mode 100644 index 200ea67..0000000 --- a/src/plugins/abrt-action-print.txt +++ /dev/null @@ -1,63 +0,0 @@ -abrt-action-print(1) -==================== - -NAME ----- -abrt-action-print - Prints problem information to standard output or FILE. - -SYNOPSIS --------- -'abrt-action-print' [-v] [-d DIR] [-o FILE] [-a yes/no] [-r] - -DESCRIPTION ------------ -The tool reads dump directory DIR and prints its text representation -to stdout or to a specified FILE. - -Integration with ABRT events -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-print' can be used as a reporter, to allow users -to report problems by writinf them to a file. Example: - ------------- -EVENT=report abrt-action-print -o "${Log_File:-/tmp/abrt.log}" ------------- - -OPTIONS -------- --d DIR:: - Path to dump directory. - --v:: - Be more verbose. Can be given multiple times. - --o FILE:: - Output file - --a yes/no:: - If -o FILE is specified, controls whether FILE is appended to, or overwritten. - --r:: - Add a recor to 'reported_to' in DIR which specifies that this problem - was reported. Some tools use this to differentiate between problems - which were and weren't yet reported. - -Output format -~~~~~~~~~~~~~ -The output is designed to be machine-parseable. The elements which have only -one line are printed in the form - - NAME:<whitespace>VALUE - -Elements which have more than one line are printed in the form - - NAME: - :LINE1 - :LINE2 - :LINE3 - -Output may contain empty lines for better readability. - -AUTHORS -------- -* ABRT team diff --git a/src/plugins/abrt-action-rhtsupport.c b/src/plugins/abrt-action-rhtsupport.c deleted file mode 100644 index 312ab92..0000000 --- a/src/plugins/abrt-action-rhtsupport.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 <libtar.h> -#include "abrtlib.h" -#include "abrt_curl.h" -#include "abrt_xmlrpc.h" -#include "abrt_rh_support.h" - -static void report_to_rhtsupport( - const char *dump_dir_name, - map_string_h *settings) -{ - problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); - if (!problem_data) - xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ - - /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ - log(_("Compressing data")); - - const char* errmsg = NULL; - TAR* tar = NULL; - pid_t child; - char* tempfile = NULL; - reportfile_t* file = NULL; - char* dsc = NULL; - char* summary = NULL; - const char* function; - const char* reason; - const char* package; - - char* env; - env = getenv("RHTSupport_URL"); - char *url = xstrdup(env ? env : (get_map_string_item_or_NULL(settings, "URL") ? : "https://api.access.redhat.com/rs")); - - env = getenv("RHTSupport_Login"); - char *login = xstrdup(env ? env : get_map_string_item_or_empty(settings, "Login")); - - env = getenv("RHTSupport_Password"); - char *password = xstrdup(env ? env : get_map_string_item_or_empty(settings, "Password")); - - env = getenv("RHTSupport_SSLVerify"); - bool ssl_verify = string_to_bool(env ? env : get_map_string_item_or_empty(settings, "SSLVerify")); - - if (!login[0] || !password[0]) - { - error_msg_and_die(_("Empty RHTS login or password")); - } - - package = get_problem_item_content_or_NULL(problem_data, FILENAME_PACKAGE); - reason = get_problem_item_content_or_NULL(problem_data, FILENAME_REASON); - function = get_problem_item_content_or_NULL(problem_data, FILENAME_CRASH_FUNCTION); - - { - struct strbuf *buf_summary = strbuf_new(); - strbuf_append_strf(buf_summary, "[abrt] %s", package); - if (function && strlen(function) < 30) - strbuf_append_strf(buf_summary, ": %s", function); - if (reason) - strbuf_append_strf(buf_summary, ": %s", reason); - summary = strbuf_free_nobuf(buf_summary); - - char *bz_dsc = make_description_bz(problem_data); - dsc = xasprintf("abrt version: "VERSION"\n%s", bz_dsc); - free(bz_dsc); - } - file = new_reportfile(); - const char *dt_string = iso_date_string(NULL); - char tmpdir_name[sizeof("/tmp/rhtsupport-YYYY-MM-DD-hh:mm:ss-XXXXXX")]; - sprintf(tmpdir_name, "/tmp/rhtsupport-%s-XXXXXX", dt_string); - /* mkdtemp does mkdir(xxx, 0700), should be safe (is it?) */ - if (mkdtemp(tmpdir_name) == NULL) - { - error_msg_and_die(_("Can't create a temporary directory in /tmp")); - } - - /* Starting from here, we must perform cleanup on errors - * (delete temp dir) - */ - - tempfile = xasprintf("%s/tmp-%s-%lu.tar.gz", tmpdir_name, iso_date_string(NULL), (long)getpid()); - - int pipe_from_parent_to_child[2]; - xpipe(pipe_from_parent_to_child); - child = fork(); - if (child == 0) - { - /* child */ - close(pipe_from_parent_to_child[1]); - xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); - xmove_fd(pipe_from_parent_to_child[0], 0); - execlp("gzip", "gzip", NULL); - perror_msg_and_die("Can't execute '%s'", "gzip"); - } - close(pipe_from_parent_to_child[0]); - - if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, - /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) - { - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - - { - 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)) - { - if (strcmp(name, FILENAME_COUNT) == 0) continue; - if (strcmp(name, CD_DUMPDIR) == 0) continue; - - const char *content = value->content; - if (value->flags & CD_FLAG_TXT) - { - reportfile_add_binding_from_string(file, name, content); - } - else if (value->flags & CD_FLAG_BIN) - { - const char *basename = strrchr(content, '/'); - if (basename) - basename++; - else - basename = content; - char *xml_name = concat_path_file("content", basename); - reportfile_add_binding_from_namedfile(file, - /*on_disk_filename */ content, - /*binding_name */ name, - /*recorded_filename*/ xml_name, - /*binary */ 1); - if (tar_append_file(tar, (char*)content, xml_name) != 0) - { - errmsg = "Can't create temporary file in /tmp"; - free(xml_name); - goto ret; - } - free(xml_name); - } - } - } - - /* Write out content.xml in the tarball's root */ - { - const char *signature = reportfile_as_string(file); - unsigned len = strlen(signature); - unsigned len512 = (len + 511) & ~511; - char *block = (char*)memcpy(xzalloc(len512), signature, len); - - th_set_type(tar, S_IFREG | 0644); - th_set_mode(tar, S_IFREG | 0644); - //th_set_link(tar, char *linkname); - //th_set_device(tar, dev_t device); - //th_set_user(tar, uid_t uid); - //th_set_group(tar, gid_t gid); - th_set_mtime(tar, time(NULL)); - th_set_path(tar, (char*)"content.xml"); - th_set_size(tar, len); - th_finish(tar); /* caclulate and store th xsum etc */ - - if (th_write(tar) != 0 /* writes header block */ - /* writes content.xml, padded to 512 bytes */ - || full_write(tar_fd(tar), block, len512) != len512 - || tar_append_eof(tar) != 0 /* writes EOF blocks */ - || tar_close(tar) != 0 - ) { - free(block); - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - tar = NULL; - free(block); - } - - /* We must be sure gzip finished, and finished successfully */ - int status; - waitpid(child, &status, 0); - child = -1; - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - { - /* Hopefully, by this time child emitted more meaningful - * error message. But just in case it didn't: - */ - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - - /* Send tempfile */ - { - log(_("Creating a new case...")); - char* result = send_report_to_new_case(url, - login, - password, - ssl_verify, - summary, - dsc, - package, - tempfile - ); - /* Temporary hackish detection of errors. Ideally, - * send_report_to_new_case needs to have better error reporting. - */ - if (strncasecmp(result, "error", 5) == 0) - { - /* - * result can contain "...server says: 'multi-line <html> text'" - * Replace all '\n' with spaces: - * we want this message to be, logically, one log entry. - * IOW: one line, not many lines. - */ - char *src, *dst; - dst = src = result; - while (1) - { - unsigned char c = *src++; - if (c == '\n') - c = ' '; - *dst++ = c; - if (c == '\0') - break; - } - /* Use sanitized string as error message */ - errmsg = result; - goto ret; - } - - /* No error */ - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (dd) - { - char *msg = xasprintf("RHTSupport: %s", result); - add_reported_to(dd, msg); - free(msg); - dd_close(dd); - } - log("%s", result); - free(result); - } - - ret: - /* We must close write fd first, or else child will wait forever */ - if (tar) - tar_close(tar); - //close(pipe_from_parent_to_child[1]); - tar_close() does it itself - - /* Now wait for child to exit */ - if (child > 0) - { - // Damn, selinux does not allow SIGKILLing our own child! wtf?? - //kill(child, SIGKILL); /* just in case */ - waitpid(child, NULL, 0); - } - - unlink(tempfile); - free(tempfile); - reportfile_free(file); - rmdir(tmpdir_name); - - free(summary); - free(dsc); - - free(url); - free(login); - free(password); - free_problem_data(problem_data); - - if (errmsg) - error_msg_and_die("%s", errmsg); -} - -int main(int argc, char **argv) -{ - abrt_init(argv); - - map_string_h *settings = new_map_string(); - const char *dump_dir_name = "."; - GList *conf_file = NULL; - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] -c CONFFILE -d DIR\n" - "\n" - "Reports a problem to RHTSupport.\n" - "\n" - "CONFFILE lines should have 'PARAM = VALUE' format.\n" - "Recognized string parameters: URL, Login, Password.\n" - "Recognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify.\n" - "Parameters can be overridden via $RHTSupport_PARAM environment variables." - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_c = 1 << 2, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_LIST( 'c', NULL, &conf_file , "FILE", _("Configuration file (may be given many times)")), - OPT_END() - }; - /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - while (conf_file) - { - char *fn = (char *)conf_file->data; - VERB1 log("Loading settings from '%s'", fn); - load_conf_file(fn, settings, /*skip key w/o values:*/ true); - VERB3 log("Loaded '%s'", fn); - conf_file = g_list_remove(conf_file, fn); - } - - VERB1 log("Initializing XML-RPC library"); - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_client_setup_global_const(&env); - if (env.fault_occurred) - error_msg_and_die("XML-RPC Fault: %s(%d)", env.fault_string, env.fault_code); - xmlrpc_env_clean(&env); - - report_to_rhtsupport(dump_dir_name, settings); - - free_map_string(settings); - return 0; -} diff --git a/src/plugins/abrt-action-upload.c b/src/plugins/abrt-action-upload.c deleted file mode 100644 index 5d482a1..0000000 --- a/src/plugins/abrt-action-upload.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 <libtar.h> -#include <curl/curl.h> -#include "abrtlib.h" - -//TODO: use this for better logging -#if 0 -/* "read local data from a file" callback */ -static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata) -{ - static time_t last_t; // hack - - FILE *fp = (FILE*)userdata; - time_t t = time(NULL); - - // Report current file position every 16 seconds - if (!(t & 0xf) && last_t != t) - { - last_t = t; - off_t cur_pos = ftello(fp); - fseeko(fp, 0, SEEK_END); - off_t sz = ftello(fp); - fseeko(fp, cur_pos, SEEK_SET); - log(_("Uploaded: %llu of %llu kbytes"), - (unsigned long long)cur_pos / 1024, - (unsigned long long)sz / 1024); - } - - return fread(ptr, size, nmemb, fp); -} -#endif - -static int send_file(const char *url, const char *filename) -{ - FILE *fp = fopen(filename, "r"); - if (!fp) - { - perror_msg("Can't open '%s'", filename); - return 1; - } - - log(_("Sending %s to %s"), filename, url); - - struct stat stbuf; - fstat(fileno(fp), &stbuf); /* never fails */ - char *whole_url = concat_path_file(url, strrchr(filename, '/') ? : filename); - - CURL *curl = curl_easy_init(); - if (!curl) - { - error_msg_and_die("Can't create curl handle"); - } - /* Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in. - * This may be more helpful than just return code from curl_easy_perform. - * curl will need it until curl_easy_cleanup. */ - char curl_err_msg[CURL_ERROR_SIZE]; - curl_err_msg[0] = '\0'; - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_msg); - /* enable uploading */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - /* specify target */ - curl_easy_setopt(curl, CURLOPT_URL, whole_url); - /* FILE handle: passed to the default callback, it will fread() it */ - curl_easy_setopt(curl, CURLOPT_READDATA, fp); - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)stbuf.st_size); - - /* everything is done here; result 0 means success */ - CURLcode result = curl_easy_perform(curl); - free(whole_url); - fclose(fp); - if (result != 0) - error_msg("Error while uploading: '%s'", curl_easy_strerror(result)); - else - /* This ends up a "reporting status message" in abrtd */ - log(_("Successfully sent %s to %s"), filename, url); - - curl_easy_cleanup(curl); - - return result; -} - -static int create_and_upload_archive( - const char *dump_dir_name, - map_string_h *settings) -{ - int result = 0; - - pid_t child; - TAR* tar = NULL; - const char* errmsg = NULL; - char* tempfile = NULL; - - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (!dd) - exit(1); /* error msg is already logged by dd_opendir */ - - /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */ - log(_("Compressing data")); - -//TODO: -//Encrypt = yes -//ArchiveType = .tar.bz2 -//ExcludeFiles = foo,bar*,b*z - char* env; - env = getenv("Upload_URL"); - const char *url = (env ? env : get_map_string_item_or_empty(settings, "URL")); - - /* Create a child gzip which will compress the data */ - /* SELinux guys are not happy with /tmp, using /var/run/abrt */ - /* Reverted back to /tmp for ABRT2 */ - tempfile = xasprintf("/tmp/abrt-upload-%s-%lu.tar.gz", iso_date_string(NULL), (long)getpid()); - int pipe_from_parent_to_child[2]; - xpipe(pipe_from_parent_to_child); - child = vfork(); - if (child == 0) - { - /* child */ - close(pipe_from_parent_to_child[1]); - xmove_fd(pipe_from_parent_to_child[0], 0); - xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1); - execlp("gzip", "gzip", NULL); - perror_msg_and_die("Can't execute '%s'", "gzip"); - } - close(pipe_from_parent_to_child[0]); - - /* If child died (say, in xopen), then parent might get SIGPIPE. - * We want to properly unlock dd, therefore we must not die on SIGPIPE: - */ - signal(SIGPIPE, SIG_IGN); - - /* Create tar writer object */ - if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile, - /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0) - { - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - - /* Write data to the tarball */ - { - char *exclude_from_report = getenv("EXCLUDE_FROM_REPORT"); - dd_init_next_file(dd); - char *short_name, *full_name; - while (dd_get_next_file(dd, &short_name, &full_name)) - { - if (exclude_from_report && is_in_comma_separated_list(short_name, exclude_from_report)) - goto next; - - // dd_get_next_file guarantees that it's a REG: - //struct stat stbuf; - //if (stat(full_name, &stbuf) != 0) - // || !S_ISREG(stbuf.st_mode) - //) { - // goto next; - //} - if (tar_append_file(tar, full_name, short_name) != 0) - { - errmsg = "Can't create temporary file in /tmp"; - free(short_name); - free(full_name); - goto ret; - } - next: - free(short_name); - free(full_name); - } - } - dd_close(dd); - dd = NULL; - - /* Close tar writer... */ - if (tar_append_eof(tar) != 0 || tar_close(tar) != 0) - { - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - tar = NULL; - /* ...and check that gzip child finished successfully */ - int status; - waitpid(child, &status, 0); - child = -1; - if (status != 0) - { - /* We assume the error was out-of-disk-space or out-of-quota */ - errmsg = "Can't create temporary file in /tmp"; - goto ret; - } - - /* Upload the tarball */ - if (url && url[0]) - { - result = send_file(url, tempfile); - /* cleanup code will delete tempfile */ - } - else - { - log(_("Archive is created: '%s'"), tempfile); - free(tempfile); - tempfile = NULL; - } - - ret: - dd_close(dd); - if (tar) - tar_close(tar); - /* close(pipe_from_parent_to_child[1]); - tar_close() does it itself */ - if (child > 0) - waitpid(child, NULL, 0); - if (tempfile) - { - unlink(tempfile); - free(tempfile); - } - if (errmsg) - error_msg_and_die("%s", errmsg); - - return result; -} - -int main(int argc, char **argv) -{ - abrt_init(argv); - - const char *dump_dir_name = "."; - const char *conf_file = NULL; - const char *url = NULL; - - /* Can't keep these strings/structs static: _() doesn't support that */ - const char *program_usage_string = _( - "\b [-v] -d DIR [-c CONFFILE] [-u URL]\n" - "\n" - "Uploads compressed tarball of dump directory DIR to URL.\n" - "If URL is not specified, creates tarball in /tmp and exits.\n" - "\n" - "Files with names listed in $EXCLUDE_FROM_REPORT are not included\n" - "into the tarball.\n" - "\n" - "CONFFILE lines should have 'PARAM = VALUE' format.\n" - "Recognized string parameter: URL.\n" - "Parameter can be overridden via $Upload_URL." - ); - enum { - OPT_v = 1 << 0, - OPT_d = 1 << 1, - OPT_c = 1 << 2, - OPT_u = 1 << 3, - }; - /* Keep enum above and order of options below in sync! */ - struct options program_options[] = { - OPT__VERBOSE(&g_verbose), - OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Dump directory")), - OPT_STRING('c', NULL, &conf_file , "CONFFILE", _("Config file")), - OPT_STRING('u', NULL, &url , "URL" , _("Base URL to upload to")), - OPT_END() - }; - /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); - - export_abrt_envvars(0); - - map_string_h *settings = new_map_string(); - if (url) - g_hash_table_replace(settings, xstrdup("URL"), xstrdup(url)); - if (conf_file) - load_conf_file(conf_file, settings, /*skip key w/o values:*/ true); - - int result = create_and_upload_archive(dump_dir_name, settings); - - free_map_string(settings); - return result; -} diff --git a/src/plugins/abrt-action-upload.txt b/src/plugins/abrt-action-upload.txt deleted file mode 100644 index 6c20bb2..0000000 --- a/src/plugins/abrt-action-upload.txt +++ /dev/null @@ -1,67 +0,0 @@ -abrt-action-upload(1) -===================== - -NAME ----- -abrt-action-upload - Uploads compressed tarball of dump directory. - -SYNOPSIS --------- -'abrt-action-upload' [-c CONFFILE]... [ -d DIR ] [ -u URL ] - -DESCRIPTION ------------ -The tool is used to create a compressed tarball of the dump directory and -upload it to a URL. Supported protocols include FTP, FTPS, HTTP, HTTPS, SCP, -SFTP, TFTP and FILE. - -Configuration file -~~~~~~~~~~~~~~~~~~ -Configuration file contains entries in a format "Option = Value". - -The options are: - -'URL':: - The URL where tarball should be uploaded. - -Integration with ABRT events -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'abrt-action-upload' can be used as a reporter, to allow users to upload -compressed tarballs of dump directiories to a configured URL. This usage can be -configured in /etc/abrt/events.d/upload_events.conf: - ------------- -EVENT=report_Upload abrt-action-upload ------------- - -It can be also used on the 'post-create' event to upload it automatically. - ------------- -EVENT=post-create abrt-action-upload ------------- - -OPTIONS -------- - --d DIR:: - Path to dump directory. - --c CONFFILE:: - Path to configration file. When used in ABRT event system, the file - contains site-wide configuration. Users can change the values via - environment variables. - --u URL:: - The URL where tarball should be uploaded. - -ENVIRONMENT VARIABLES ---------------------- -Environment variables take precedence over values provided in -the configuration file. - -'Upload_URL':: - The URL where should be the tarball uploaded. - -AUTHORS -------- -* ABRT team diff --git a/src/plugins/abrt_rh_support.c b/src/plugins/abrt_rh_support.c deleted file mode 100644 index 3700850..0000000 --- a/src/plugins/abrt_rh_support.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 <libxml/encoding.h> -#include <libxml/xmlwriter.h> -#include <curl/curl.h> -#include "abrtlib.h" -#include "abrt_curl.h" -#include "abrt_rh_support.h" - -struct reportfile { - xmlTextWriterPtr writer; - xmlBufferPtr buf; -}; - -static void __attribute__((__noreturn__)) -die_xml_oom(void) -{ - error_msg_and_die("Can't create XML attribute (out of memory?)"); -} - -static xmlBufferPtr -xxmlBufferCreate(void) -{ - xmlBufferPtr r = xmlBufferCreate(); - if (!r) - die_xml_oom(); - return r; -} - -static xmlTextWriterPtr -xxmlNewTextWriterMemory(xmlBufferPtr buf /*, int compression*/) -{ - xmlTextWriterPtr r = xmlNewTextWriterMemory(buf, /*compression:*/ 0); - if (!r) - die_xml_oom(); - return r; -} - -static void -xxmlTextWriterStartDocument(xmlTextWriterPtr writer, - const char * version, - const char * encoding, - const char * standalone) -{ - if (xmlTextWriterStartDocument(writer, version, encoding, standalone) < 0) - die_xml_oom(); -} - -static void -xxmlTextWriterEndDocument(xmlTextWriterPtr writer) -{ - if (xmlTextWriterEndDocument(writer) < 0) - die_xml_oom(); -} - -static void -xxmlTextWriterStartElement(xmlTextWriterPtr writer, const char *name) -{ - // these bright guys REDEFINED CHAR (!) to unsigned char... - if (xmlTextWriterStartElement(writer, (unsigned char*)name) < 0) - die_xml_oom(); -} - -static void -xxmlTextWriterEndElement(xmlTextWriterPtr writer) -{ - if (xmlTextWriterEndElement(writer) < 0) - die_xml_oom(); -} - -static void -xxmlTextWriterWriteElement(xmlTextWriterPtr writer, const char *name, const char *content) -{ - if (xmlTextWriterWriteElement(writer, (unsigned char*)name, (unsigned char*)content) < 0) - die_xml_oom(); -} - -static void -xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content) -{ - if (xmlTextWriterWriteAttribute(writer, (unsigned char*)name, (unsigned char*)content) < 0) - die_xml_oom(); -} - -#if 0 //unused -static void -xxmlTextWriterWriteString(xmlTextWriterPtr writer, const char *content) -{ - if (xmlTextWriterWriteString(writer, (unsigned char*)content) < 0) - die_xml_oom(); -} -#endif - -// -// End the reportfile, and prepare it for delivery. -// No more bindings can be added after this. -// -static void -close_writer(reportfile_t* file) -{ - if (!file->writer) - return; - - // close off the end of the xml file - xxmlTextWriterEndDocument(file->writer); - xmlFreeTextWriter(file->writer); - file->writer = NULL; -} - -// -// This allocates a reportfile_t structure and initializes it. -// -reportfile_t* -new_reportfile(void) -{ - // create a new reportfile_t - reportfile_t* file = (reportfile_t*)xmalloc(sizeof(*file)); - - // set up a libxml 'buffer' and 'writer' to that buffer - file->buf = xxmlBufferCreate(); - file->writer = xxmlNewTextWriterMemory(file->buf); - - // start a new xml document: - // <report xmlns="http://www.redhat.com/gss/strata">... - xxmlTextWriterStartDocument(file->writer, /*version:*/ NULL, /*encoding:*/ NULL, /*standalone:*/ NULL); - xxmlTextWriterStartElement(file->writer, "report"); - xxmlTextWriterWriteAttribute(file->writer, "xmlns", "http://www.redhat.com/gss/strata"); - - return file; -} - -static void -internal_reportfile_start_binding(reportfile_t* file, const char* name, int isbinary, const char* filename) -{ - // <binding name=NAME [fileName=FILENAME] type=text/binary... - xxmlTextWriterStartElement(file->writer, "binding"); - xxmlTextWriterWriteAttribute(file->writer, "name", name); - if (filename) - xxmlTextWriterWriteAttribute(file->writer, "fileName", filename); - if (isbinary) - xxmlTextWriterWriteAttribute(file->writer, "type", "binary"); - else - xxmlTextWriterWriteAttribute(file->writer, "type", "text"); -} - -// -// Add a new text binding -// -void -reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value) -{ - // <binding name=NAME type=text value=VALUE> - internal_reportfile_start_binding(file, name, /*isbinary:*/ 0, /*filename:*/ NULL); - xxmlTextWriterWriteAttribute(file->writer, "value", value); - xxmlTextWriterEndElement(file->writer); -} - -// -// Add a new binding to a report whose value is represented as a file. -// -void -reportfile_add_binding_from_namedfile(reportfile_t* file, - const char* on_disk_filename, /* unused so far */ - const char* binding_name, - const char* recorded_filename, - int isbinary) -{ - // <binding name=NAME fileName=FILENAME type=text/binary... - internal_reportfile_start_binding(file, binding_name, isbinary, recorded_filename); - // ... href=content/NAME> - char *href_name = concat_path_file("content", binding_name); - xxmlTextWriterWriteAttribute(file->writer, "href", href_name); - free(href_name); -} - -// -// Return the contents of the reportfile as a string. -// -const char* -reportfile_as_string(reportfile_t* file) -{ - close_writer(file); - // unsigned char -> char - return (char*)file->buf->content; -} - -void -reportfile_free(reportfile_t* file) -{ - if (!file) - return; - close_writer(file); - xmlBufferFree(file->buf); - free(file); -} - - -// -// send_report_to_new_case() -// - -static char* -make_case_data(const char* summary, const char* description, - const char* product, const char* version, - const char* component) -{ - char* retval; - xmlTextWriterPtr writer; - xmlBufferPtr buf; - - buf = xxmlBufferCreate(); - writer = xxmlNewTextWriterMemory(buf); - - xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); - xxmlTextWriterStartElement(writer, "case"); - xxmlTextWriterWriteAttribute(writer, "xmlns", - "http://www.redhat.com/gss/strata"); - - xxmlTextWriterWriteElement(writer, "summary", summary); - xxmlTextWriterWriteElement(writer, "description", description); - if (product) { - xxmlTextWriterWriteElement(writer, "product", product); - } - if (version) { - xxmlTextWriterWriteElement(writer, "version", version); - } - if (component) { - xxmlTextWriterWriteElement(writer, "component", component); - } - - xxmlTextWriterEndDocument(writer); - retval = xstrdup((const char*)buf->content); - xmlFreeTextWriter(writer); - xmlBufferFree(buf); - return retval; -} - -#if 0 //unused -static char* -make_response(const char* title, const char* body, - const char* actualURL, const char* displayURL) -{ - char* retval; - xmlTextWriterPtr writer; - xmlBufferPtr buf; - - buf = xxmlBufferCreate(); - writer = xxmlNewTextWriterMemory(buf); - - xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); - xxmlTextWriterStartElement(writer, "response"); - if (title) { - xxmlTextWriterWriteElement(writer, "title", title); - } - if (body) { - xxmlTextWriterWriteElement(writer, "body", body); - } - if (actualURL || displayURL) { - xxmlTextWriterStartElement(writer, "URL"); - if (actualURL) { - xxmlTextWriterWriteAttribute(writer, "href", actualURL); - } - if (displayURL) { - xxmlTextWriterWriteString(writer, displayURL); - } - } - - xxmlTextWriterEndDocument(writer); - retval = xstrdup((const char*)buf->content); - xmlFreeTextWriter(writer); - xmlBufferFree(buf); - return retval; -} -//Example: -//<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -//<response><title>Case Created and Report Attached</title><body></body><URL href="http://support-services-devel.gss.redhat.com:8080/Strata/cases/00005129/attachments/ccbf3e65-b941-3db7-a016-6a3831691a32">New Case URL</URL></response> -#endif - -char* -send_report_to_new_case(const char* baseURL, - const char* username, - const char* password, - bool ssl_verify, - const char* summary, - const char* description, - const char* component, - const char* report_file_name) -{ - char *case_url = concat_path_file(baseURL, "/cases"); - - char *case_data = make_case_data(summary, description, - "Red Hat Enterprise Linux", "6.0", - component); - - int redirect_count = 0; - char *errmsg; - char *allocated = NULL; - char* retval = NULL; - abrt_post_state_t *case_state; - - redirect_case: - case_state = new_abrt_post_state(0 - + ABRT_POST_WANT_HEADERS - + ABRT_POST_WANT_BODY - + ABRT_POST_WANT_ERROR_MSG - + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0) - ); - case_state->username = username; - case_state->password = password; - - static const char *headers[] = { - "Accept: text/plain", - NULL - }; - - abrt_post_string(case_state, case_url, "application/xml", headers, case_data); - - char *case_location = find_header_in_abrt_post_state(case_state, "Location:"); - switch (case_state->http_resp_code) - { - case 404: - /* Not strictly necessary (default branch would deal with it too), - * but makes this typical error less cryptic: - * instead of returning html-encoded body, we show short concise message, - * and show offending URL (typos in which is a typical cause) */ - retval = xasprintf("error in case creation, " - "HTTP code: 404 (Not found), URL:'%s'", case_url); - break; - - case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */ - case 302: /* "302 Found" (just in case) */ - case 305: /* "305 Use Proxy" */ - if (++redirect_count < 10 && case_location) - { - free(case_url); - case_url = xstrdup(case_location); - free_abrt_post_state(case_state); - goto redirect_case; - } - /* fall through */ - - default: - errmsg = case_state->curl_error_msg; - if (errmsg && errmsg[0]) - retval = xasprintf("error in case creation: %s", errmsg); - else - { - errmsg = case_state->body; - if (errmsg && errmsg[0]) - retval = xasprintf("error in case creation, HTTP code: %d, server says: '%s'", - case_state->http_resp_code, errmsg); - else - retval = xasprintf("error in case creation, HTTP code: %d", - case_state->http_resp_code); - } - break; - - case 200: - case 201: { - if (!case_location) { - /* Case Creation returned valid code, but no location */ - retval = xasprintf("error in case creation: no Location URL, HTTP code: %d", - case_state->http_resp_code); - break; - } - - char *atch_url = concat_path_file(case_location, "/attachments"); - abrt_post_state_t *atch_state; - redirect_attach: - atch_state = new_abrt_post_state(0 - + ABRT_POST_WANT_HEADERS - + ABRT_POST_WANT_BODY - + ABRT_POST_WANT_ERROR_MSG - + (ssl_verify ? ABRT_POST_WANT_SSL_VERIFY : 0) - ); - atch_state->username = username; - atch_state->password = password; - - abrt_post_file_as_form(atch_state, atch_url, "application/binary", headers, - report_file_name); - - char *atch_location = find_header_in_abrt_post_state(atch_state, "Location:"); - switch (atch_state->http_resp_code) - { - case 305: /* "305 Use Proxy" */ - if (++redirect_count < 10 && atch_location) - { - free(atch_url); - atch_url = xstrdup(atch_location); - free_abrt_post_state(atch_state); - goto redirect_attach; - } - /* fall through */ - - default: - /* Case Creation Succeeded, attachement FAILED */ - errmsg = atch_state->curl_error_msg; - if (atch_state->body && atch_state->body[0]) - { - if (errmsg && errmsg[0] - && strcmp(errmsg, atch_state->body) != 0 - ) /* both strata/curl error and body are present (and aren't the same) */ - allocated = errmsg = xasprintf("%s. %s", - atch_state->body, - errmsg); - else /* only body exists */ - errmsg = atch_state->body; - } - /* Note: to prevent URL misparsing, make sure to delimit - * case_location only using spaces */ - retval = xasprintf("Case created: %s but report attachment failed (HTTP code %d)%s%s", - case_location, - atch_state->http_resp_code, - errmsg ? ": " : "", - errmsg ? errmsg : "" - ); - break; - - case 200: - case 201: - // unused - //char *body = atch_state->body; - //if (case_state->body && case_state->body[0]) - //{ - // body = case_state->body; - // if (atch_state->body && atch_state->body[0]) - // allocated = body = xasprintf("%s\n%s", - // case_state->body, - // atch_state->body); - //} - retval = xasprintf("Case created: %s", /*body,*/ case_location); - } /* switch (attach HTTP code) */ - - free_abrt_post_state(atch_state); - free(atch_url); - } /* case 200/201 */ - - } /* switch (case HTTP code) */ - - free_abrt_post_state(case_state); - free(allocated); - free(case_url); - return retval; -} diff --git a/src/plugins/abrt_rh_support.h b/src/plugins/abrt_rh_support.h deleted file mode 100644 index db6e9cd..0000000 --- a/src/plugins/abrt_rh_support.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 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 ABRT_RH_SUPPORT_H_ -#define ABRT_RH_SUPPORT_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct reportfile reportfile_t; - -reportfile_t *new_reportfile(void); -void reportfile_free(reportfile_t* file); - -void reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value); -void reportfile_add_binding_from_namedfile(reportfile_t* file, - const char* on_disk_filename, /* unused so far */ - const char* binding_name, - const char* recorded_filename, - int isbinary); - -const char* reportfile_as_string(reportfile_t* file); - -char* post_signature(const char* baseURL, bool ssl_verify, const char* signature); -char* -send_report_to_new_case(const char* baseURL, - const char* username, - const char* password, - bool ssl_verify, - const char* summary, - const char* description, - const char* component, - const char* report_file_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/plugins/mailx_events.conf b/src/plugins/mailx_events.conf deleted file mode 100644 index 41b976d..0000000 --- a/src/plugins/mailx_events.conf +++ /dev/null @@ -1 +0,0 @@ -EVENT=report_Mailx abrt-action-mailx diff --git a/src/plugins/report_Bugzilla.conf b/src/plugins/report_Bugzilla.conf deleted file mode 100644 index f1a77f5..0000000 --- a/src/plugins/report_Bugzilla.conf +++ /dev/null @@ -1,4 +0,0 @@ -Bugzilla_BugzillaURL = https://bugzilla.redhat.com -Bugzilla_Login = -Bugzilla_Password = -Bugzilla_SSLVerify = yes diff --git a/src/plugins/report_Bugzilla.xml.in b/src/plugins/report_Bugzilla.xml.in deleted file mode 100644 index 00ef4a4..0000000 --- a/src/plugins/report_Bugzilla.xml.in +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <_name>Bugzilla</_name> - <_description>Report to Bugzilla bug tracker</_description> - - <requires-items>component,duphash,os_release</requires-items> - <exclude-items-by-default>coredump,count,event_log,reported_to</exclude-items-by-default> - <exclude-items-always></exclude-items-always> - <exclude-binary-items>yes</exclude-binary-items> - <include-items-by-default></include-items-by-default> - - <options> - <option type="text" name="Bugzilla_BugzillaURL"> - <_label>Bugzilla URL</_label> - <allow-empty>no</allow-empty> - <_description>Address of Bugzilla server</_description> - <default-value>https://bugzilla.redhat.com</default-value> - <_note-html>You can create bugzilla.redhat.com account <a href="https://bugzilla.redhat.com/createaccount.cgi%22%3Ehere%3C/a%3E;</_note-html> - </option> - <option type="text" name="Bugzilla_Login"> - <_label>User name</_label> - <allow-empty>no</allow-empty> - <_description>Bugzilla account user name</_description> - </option> - <option type="password" name="Bugzilla_Password"> - <_label>Password</_label> - <allow-empty>no</allow-empty> - <_description>Bugzilla account password</_description> - </option> - <option type="bool" name="Bugzilla_SSLVerify"> - <_label>Verify SSL</_label> - <_description>Check SSL key validity</_description> - <default-value>yes</default-value> - </option> - </options> -</event> diff --git a/src/plugins/report_Kerneloops.xml.in b/src/plugins/report_Kerneloops.xml.in deleted file mode 100644 index a4da6b6..0000000 --- a/src/plugins/report_Kerneloops.xml.in +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <_name>Kerneloops.org</_name> - <_description>Send kernel problems to oops tracker</_description> - - <requires-items>backtrace</requires-items> - <exclude-items-by-default></exclude-items-by-default> - <exclude-items-always>*</exclude-items-always> - <exclude-binary-items>yes</exclude-binary-items> - <include-items-by-default></include-items-by-default> - - <options> - <option type="text" name="KerneloopsReporter_SubmitURL"> - <_label>Kerneloops URL</_label> - <allow-empty>no</allow-empty> - <_description>Oops server url</_description> - <default-value>http://submit.kerneloops.org/submitoops.php</default-value> - </option> - </options> -</event> diff --git a/src/plugins/report_Logger.conf b/src/plugins/report_Logger.conf deleted file mode 100644 index d885ce5..0000000 --- a/src/plugins/report_Logger.conf +++ /dev/null @@ -1,2 +0,0 @@ -Log_File=/tmp/abrt.log -Append=yes diff --git a/src/plugins/report_Mailx.xml.in b/src/plugins/report_Mailx.xml.in deleted file mode 100644 index 2476a3d..0000000 --- a/src/plugins/report_Mailx.xml.in +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <_name>Mailx</_name> - <_description>Send via email</_description> - - <requires-items></requires-items> - <exclude-items-by-default>coredump</exclude-items-by-default> - <exclude-items-always></exclude-items-always> - <exclude-binary-items>no</exclude-binary-items> - <include-items-by-default></include-items-by-default> - - <options> - <option type="text" name="Mailx_Subject"> - <_label>Subject</_label> - <allow-empty>no</allow-empty> - <_description>Message subject</_description> - <default-value>[abrt] detected a crash</default-value> - </option> - <option type="text" name="Mailx_EmailFrom"> - <_label>Sender</_label> - <allow-empty>no</allow-empty> - <_description>Sender's email</_description> - </option> - <option type="text" name="Mailx_EmailTo"> - <_label>Recipient</_label> - <allow-empty>no</allow-empty> - <_description>Recipient's email</_description> - </option> - <option type="bool" name="Mailx_SendBinaryData"> - <_label>Send Binary Data</_label> - <_description>Send binary files like coredump</_description> - <default-value>no</default-value> - </option> - </options> -</event> diff --git a/src/plugins/report_RHTSupport.xml.in b/src/plugins/report_RHTSupport.xml.in deleted file mode 100644 index 834528a..0000000 --- a/src/plugins/report_RHTSupport.xml.in +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <_name>Red Hat Customer Support</_name> - <_description>Report to Red Hat support</_description> - - <requires-items>package</requires-items> - <exclude-items-by-default>event_log,reported_to</exclude-items-by-default> - <exclude-items-always></exclude-items-always> - <exclude-binary-items>no</exclude-binary-items> - <include-items-by-default></include-items-by-default> - - <options> - <option type="text" name="RHTSupport_URL"> - <_label>RH Portal URL</_label> - <allow-empty>no</allow-empty> - <_description>Address of the Red Hat support portal</_description> - <default-value>https://api.access.redhat.com/rs</default-value> - </option> - <option type="text" name="RHTSupport_Login"> - <_label>Username</_label> - <_description>Red Hat customer user name</_description> - <allow-empty>no</allow-empty> - </option> - <option type="password" name="RHTSupport_Password"> - <_label>Password</_label> - <_description>Red Hat customer password</_description> - <allow-empty>no</allow-empty> - </option> - <option type="bool" name="RHTSupport_SSLVerify"> - <_label>Verify SSL</_label> - <_description>Check SSL key validity</_description> - <default-value>yes</default-value> - </option> - </options> -</event> diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c deleted file mode 100644 index cd3a07a..0000000 --- a/src/plugins/rhbz.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" -#include "rhbz.h" - -#define MAX_HOPS 5 - -struct bug_info *new_bug_info() -{ - struct bug_info *bi = xzalloc(sizeof(struct bug_info)); - bi->bi_dup_id = -1; - - return bi; -} - -void free_bug_info(struct bug_info *bi) -{ - if (!bi) - return; - - free(bi->bi_status); - free(bi->bi_resolution); - free(bi->bi_reporter); - free(bi->bi_product); - - list_free_with_free(bi->bi_cc_list); - - bi->bi_status = NULL; - bi->bi_resolution = NULL; - bi->bi_reporter = NULL; - bi->bi_product = NULL; - - bi->bi_cc_list = NULL; - - free(bi); -} - -void rhbz_login(struct abrt_xmlrpc *ax, const char* login, const char* passwd) -{ - xmlrpc_value* result = abrt_xmlrpc_call(ax, "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! - xmlrpc_DECREF(result); -} - -xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, const char *component, - const char *product, const char *duphash) -{ - char *query = NULL; - if (!product) - query = xasprintf("ALL component:"%s" whiteboard:"%s"", component, duphash); - else - query = xasprintf("ALL component:"%s" whiteboard:"%s" product:"%s"", - component, duphash, product); - - VERB3 log("search for '%s'", query); - xmlrpc_value *ret = abrt_xmlrpc_call(ax, "Bug.search", "({s:s})", - "quicksearch", query); - free(query); - return ret; -} - -xmlrpc_value *rhbz_get_member(const char *member, xmlrpc_value *xml) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_value *value = NULL; - /* The xmlrpc_struct_find_value functions consider "not found" to be - * a normal result. If a member of the structure with the specified key - * exists, it returns it as a handle to an xmlrpc_value. If not, it returns - * NULL in place of that handle. - */ - xmlrpc_struct_find_value(&env, xml, member, &value); - if (env.fault_occurred) - abrt_xmlrpc_error(&env); - - return value; -} - -/* The only way this can fail is if arrayP is not actually an array XML-RPC - * value. So it is usually not worth checking *envP. - * die or return size of array - */ -int rhbz_array_size(xmlrpc_value *xml) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - int size = xmlrpc_array_size(&env, xml); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - return size; -} - -/* die or return bug id; each bug must have bug id otherwise xml is corrupted */ -int rhbz_bug_id(xmlrpc_value* xml) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_value *item = NULL; - xmlrpc_value *bug = NULL; - int bug_id = -1;; - - xmlrpc_array_read_item(&env, xml, 0, &item); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - bug = rhbz_get_member("bug_id", item); - xmlrpc_DECREF(item); - if (!bug) - abrt_xmlrpc_die(&env); - - xmlrpc_read_int(&env, bug, &bug_id); - xmlrpc_DECREF(bug); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - VERB3 log("found bug_id %i", bug_id); - return bug_id; -} - -/* die when mandatory value is missing (set flag RHBZ_MANDATORY_MEMB) - * or return appropriate string or NULL when fail; - */ -// TODO: npajkovs: add flag to read xmlrpc_read_array_item first -void *rhbz_bug_read_item(const char *memb, xmlrpc_value *xml, int flags) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_value *member = rhbz_get_member(memb, xml); - - const char *string = NULL; - - if (!member) - goto die; - - if (IS_READ_STR(flags)) - { - xmlrpc_read_string(&env, member, &string); - xmlrpc_DECREF(member); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - if (!*string) - goto die; - - VERB3 log("found %s: '%s'", memb, string); - return (void*)string; - } - - if (IS_READ_INT(flags)) - { - int *integer = xmalloc(sizeof(int)); - xmlrpc_read_int(&env, member, integer); - xmlrpc_DECREF(member); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - VERB3 log("found %s: '%i'", memb, *integer); - return (void*)integer; - } -die: - free((void*)string); - if (IS_MANDATORY(flags)) - error_msg_and_die(_("Looks like corrupted xml response, because '%s'" - " member is missing."), memb); - - return NULL; -} - -GList *rhbz_bug_cc(xmlrpc_value* result_xml) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_value* cc_member = rhbz_get_member("cc", result_xml); - if (!cc_member) - return NULL; - - int array_size = rhbz_array_size(cc_member); - - VERB3 log("count members on cc %i", array_size); - GList *cc_list = NULL; - - 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) - abrt_xmlrpc_die(&env); - - if (!item) - continue; - - const char* cc = NULL; - xmlrpc_read_string(&env, item, &cc); - xmlrpc_DECREF(item); - if (env.fault_occurred) - abrt_xmlrpc_die(&env); - - if (*cc != '\0') - { - cc_list = g_list_append(cc_list, (char*)cc); - VERB3 log("member on cc is %s", cc); - continue; - } - free((char*)cc); - } - xmlrpc_DECREF(cc_member); - return cc_list; -} - -struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id) -{ - struct bug_info *bz = new_bug_info(); - xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "bugzilla.getBug", - "(i)", bug_id); - - int *ret = (int*)rhbz_bug_read_item("bug_id", xml_bug_response, - RHBZ_MANDATORY_MEMB | RHBZ_READ_INT); - bz->bi_id = *ret; - free(ret); - bz->bi_product = rhbz_bug_read_item("product", xml_bug_response, - RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); - bz->bi_reporter = rhbz_bug_read_item("reporter", xml_bug_response, - RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); - bz->bi_status = rhbz_bug_read_item("bug_status", xml_bug_response, - RHBZ_MANDATORY_MEMB | RHBZ_READ_STR); - bz->bi_resolution = rhbz_bug_read_item("resolution", xml_bug_response, - RHBZ_READ_STR); - - if (strcmp(bz->bi_status, "CLOSED") == 0 && !bz->bi_resolution) - error_msg_and_die(_("Bug %i is CLOSED, but it has no RESOLUTION"), bz->bi_id); - - ret = (int*)rhbz_bug_read_item("dup_id", xml_bug_response, - RHBZ_READ_INT); - if (strcmp(bz->bi_status, "CLOSED") == 0 - && strcmp(bz->bi_resolution, "DUPLICATE") == 0 - && !ret) - { - error_msg_and_die(_("Bug %i is CLOSED as DUPLICATE, but it has no DUP_ID"), - bz->bi_id); - } - - bz->bi_dup_id = (ret) ? *ret: -1; - free(ret); - - bz->bi_cc_list = rhbz_bug_cc(xml_bug_response); - - xmlrpc_DECREF(xml_bug_response); - - return bz; -} - -/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ -int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, - int depend_on_bug) -{ - 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); -//COMPAT, remove after 2.1 release - if (!duphash) duphash = get_problem_item_content_or_NULL(problem_data, - "global_uuid"); - 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_short = get_problem_item_content_or_NULL(problem_data, - FILENAME_TAINTED_SHORT); - - 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_short && analyzer - && (strcmp(analyzer, "Kerneloops") == 0)) - { - strbuf_append_strf(buf_summary, ": TAINTED %s", tainted_short); - } - - 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_bug > -1) - { - result = abrt_xmlrpc_call(ax, "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_bug); - } - else - { - result = abrt_xmlrpc_call(ax, "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; - - int *r = rhbz_bug_read_item("id", result, RHBZ_MANDATORY_MEMB | RHBZ_READ_INT); - xmlrpc_DECREF(result); - int new_bug_id = *r; - free(r); - - log(_("New bug id: %i"), new_bug_id); - return new_bug_id; -} - -/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ -int rhbz_attachment(struct abrt_xmlrpc *ax, const char *filename, - const char *bug_id, const char *data, int flags) -{ - char *encoded64 = encode_base64(data, strlen(data)); - char *fn = xasprintf("File: %s", filename); - xmlrpc_value* result; - int nomail_notify = IS_NOMAIL_NOTIFY(flags); - - result= abrt_xmlrpc_call(ax, "bugzilla.addAttachment", "(s{s:s,s:s,s:s,s:s,s:i})", - bug_id, - "description", fn, - "filename", filename, - "contenttype", "text/plain", - "data", encoded64, - "nomail", nomail_notify); - - free(encoded64); - free(fn); - if (!result) - return -1; - - xmlrpc_DECREF(result); - - return 0; -} - -/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */ -int rhbz_attachments(struct abrt_xmlrpc *ax, const char *bug_id, - problem_data_t *problem_data, int flags) -{ - 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)*/) - ) { - /* check if the attachment failed and try it once more */ - rhbz_attachment(ax, name, bug_id, content, flags); - } - } - - return 0; -} - -void rhbz_logout(struct abrt_xmlrpc *ax) -{ - xmlrpc_value* result = abrt_xmlrpc_call(ax, "User.logout", "(s)", ""); - if (result) - xmlrpc_DECREF(result); -} - -struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax, - struct bug_info *bi) -{ - struct bug_info *bi_tmp = new_bug_info(); - bi_tmp->bi_id = bi->bi_id; - bi_tmp->bi_dup_id = bi->bi_dup_id; - - for (int ii = 0; ii <= MAX_HOPS; ii++) - { - if (ii == MAX_HOPS) - error_msg_and_die(_("Bugzilla couldn't find parent of bug %d"), bi->bi_id); - - log("Bug %d is a duplicate, using parent bug %d", bi_tmp->bi_id, bi_tmp->bi_dup_id); - int bug_id = bi_tmp->bi_dup_id; - - free_bug_info(bi_tmp); - bi_tmp = rhbz_bug_info(ax, bug_id); - - // found a bug which is not CLOSED as DUPLICATE - if (bi_tmp->bi_dup_id == -1) - break; - } - - return bi_tmp; -} - -/* suppress mail notify by {s:i} (nomail:1) */ -void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int flags) -{ - xmlrpc_value *result; - int nomail_notify = IS_NOMAIL_NOTIFY(flags); - result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i}})", - "ids", bug_id, "updates", "add_cc", mail, - "nomail", nomail_notify); - - if (result) - xmlrpc_DECREF(result); -} - -void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment, - int flags) -{ - int private = IS_PRIVATE(flags); - int nomail_notify = IS_NOMAIL_NOTIFY(flags); - - xmlrpc_value *result; - result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i})", - "id", bug_id, "comment", comment, - "private", private, "nomail", nomail_notify); - - if (result) - xmlrpc_DECREF(result); -} diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h deleted file mode 100644 index 6a12c68..0000000 --- a/src/plugins/rhbz.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 RHBZ_H -#define RHBZ_H - -/* include/stdint.h: typedef int int32_t; - * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; - */ - -#include "abrt_xmlrpc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - RHBZ_MANDATORY_MEMB = (1 << 0), - RHBZ_READ_STR = (1 << 1), - RHBZ_READ_INT = (1 << 2), - RHBZ_NOMAIL_NOTIFY = (1 << 3), - RHBZ_PRIVATE = (1 << 4), -}; - -#define IS_MANDATORY(flags) ((flags) & RHBZ_MANDATORY_MEMB) -#define IS_READ_STR(flags) ((flags) & RHBZ_READ_STR) -#define IS_READ_INT(flags) ((flags) & RHBZ_READ_INT) -#define IS_NOMAIL_NOTIFY(flags) ((flags) & RHBZ_NOMAIL_NOTIFY) -#define IS_PRIVATE(flags) ((flags) & RHBZ_PRIVATE) - -struct bug_info { - int bi_id; - int bi_dup_id; - - char *bi_status; - char *bi_resolution; - char *bi_reporter; - char *bi_product; - - GList *bi_cc_list; -}; - -struct bug_info *new_bug_info(); -void free_bug_info(struct bug_info *bz); - -void rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *passwd); - -void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int flags); - -void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment, - int flags); - -void *rhbz_bug_read_item(const char *memb, xmlrpc_value *xml, int flags); - -void rhbz_logout(struct abrt_xmlrpc *ax); - -xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, const char *component, - const char *release, const char *duphash); - -xmlrpc_value *rhbz_get_member(const char *member, xmlrpc_value *xml); - -int rhbz_array_size(xmlrpc_value *xml); - -int rhbz_bug_id(xmlrpc_value *xml); - -int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data, - int depend_on_bug); - -int rhbz_attachments(struct abrt_xmlrpc *ax, const char *bug_id, - problem_data_t *problem_data, int flags); - -int rhbz_attachment(struct abrt_xmlrpc *ax, const char *filename, - const char *bug_id, const char *data, int flags); - -GList *rhbz_bug_cc(xmlrpc_value *result_xml); - -struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id); - - -struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax, - struct bug_info *bi); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/plugins/rhtsupport_events.conf b/src/plugins/rhtsupport_events.conf deleted file mode 100644 index 853a699..0000000 --- a/src/plugins/rhtsupport_events.conf +++ /dev/null @@ -1 +0,0 @@ -EVENT=report_RHTSupport abrt-action-rhtsupport
On Fri, 2011-07-01 at 15:06 +0200, Miroslav Lichvar wrote:
abrt.spec.in | 98 +------ configure.ac | 6 - src/daemon/abrt_event.conf | 3 - src/lib/Makefile.am | 30 +-- src/lib/abrt_curl.c | 435 ---------------------------- src/lib/abrt_curl.h | 103 ------- src/lib/abrt_xmlrpc.c | 137 --------- src/lib/abrt_xmlrpc.h | 51 ---- src/plugins/Bugzilla.conf | 12 - src/plugins/Kerneloops.conf | 3 - src/plugins/Makefile.am | 170 +----------- src/plugins/Upload.conf | 9 - src/plugins/abrt-action-bugzilla.c | 291 ------------------- src/plugins/abrt-action-bugzilla.txt | 67 ----- src/plugins/abrt-action-kerneloops.c | 166 ----------- src/plugins/abrt-action-kerneloops.txt | 68 ----- src/plugins/abrt-action-mailx.c | 162 ----------- src/plugins/abrt-action-mailx.txt | 91 ------ src/plugins/abrt-action-print.c | 95 ------ src/plugins/abrt-action-print.txt | 63 ---- src/plugins/abrt-action-rhtsupport.c | 342 ---------------------- src/plugins/abrt-action-upload.c | 287 ------------------- src/plugins/abrt-action-upload.txt | 67 ----- src/plugins/abrt_rh_support.c | 460 ------------------------------ src/plugins/abrt_rh_support.h | 55 ---- src/plugins/mailx_events.conf | 1 - src/plugins/report_Bugzilla.conf | 4 - src/plugins/report_Bugzilla.xml.in | 36 --- src/plugins/report_Kerneloops.xml.in | 20 -- src/plugins/report_Logger.conf | 2 - src/plugins/report_Mailx.xml.in | 35 --- src/plugins/report_RHTSupport.xml.in | 35 --- src/plugins/rhbz.c | 488 -------------------------------- src/plugins/rhbz.h | 103 ------- src/plugins/rhtsupport_events.conf | 1 - 35 files changed, 8 insertions(+), 3988 deletions(-) delete mode 100644 src/lib/abrt_curl.c delete mode 100644 src/lib/abrt_curl.h delete mode 100644 src/lib/abrt_xmlrpc.c delete mode 100644 src/lib/abrt_xmlrpc.h delete mode 100644 src/plugins/Bugzilla.conf delete mode 100644 src/plugins/Kerneloops.conf delete mode 100644 src/plugins/Upload.conf delete mode 100644 src/plugins/abrt-action-bugzilla.c delete mode 100644 src/plugins/abrt-action-bugzilla.txt delete mode 100644 src/plugins/abrt-action-kerneloops.c delete mode 100644 src/plugins/abrt-action-kerneloops.txt delete mode 100644 src/plugins/abrt-action-mailx.c delete mode 100644 src/plugins/abrt-action-mailx.txt delete mode 100644 src/plugins/abrt-action-print.c delete mode 100644 src/plugins/abrt-action-print.txt delete mode 100644 src/plugins/abrt-action-rhtsupport.c delete mode 100644 src/plugins/abrt-action-upload.c delete mode 100644 src/plugins/abrt-action-upload.txt delete mode 100644 src/plugins/abrt_rh_support.c delete mode 100644 src/plugins/abrt_rh_support.h delete mode 100644 src/plugins/mailx_events.conf delete mode 100644 src/plugins/report_Bugzilla.conf delete mode 100644 src/plugins/report_Bugzilla.xml.in delete mode 100644 src/plugins/report_Kerneloops.xml.in delete mode 100644 src/plugins/report_Logger.conf delete mode 100644 src/plugins/report_Mailx.xml.in delete mode 100644 src/plugins/report_RHTSupport.xml.in delete mode 100644 src/plugins/rhbz.c delete mode 100644 src/plugins/rhbz.h delete mode 100644 src/plugins/rhtsupport_events.conf
Looks straightforward, I guess you should push these changes to abrt and libreport git.
On Mon, Jul 11, 2011 at 01:45:46PM +0200, Denys Vlasenko wrote:
Looks straightforward, I guess you should push these changes to abrt and libreport git.
Done. I had to manually merge the changes included since I posted the patch, please check I didn't miss anything.
Thanks,
crash-catcher@lists.fedorahosted.org