[PATCH] abrt-gui: spawn abrt-handle-event for opening problem dirs
by Denys Vlasenko
This makes sure we exec immediately after fork and thus eliminate
threading-related problems.
Run-tested.
Stops https://bugzilla.redhat.com/show_bug.cgi?id=835112
from happening.
--
vda
diff -x '*.po' -d -urpN abrt.8/abrt.spec.in abrt.9/abrt.spec.in
--- abrt.8/abrt.spec.in 2012-06-25 08:40:35.000000000 +0200
+++ abrt.9/abrt.spec.in 2012-06-26 12:38:20.789106812 +0200
@@ -462,7 +462,7 @@ gtk-update-icon-cache %{_datadir}/icons/
%endif
%{_sbindir}/abrtd
%{_sbindir}/abrt-server
-%{_libexecdir}/abrt-handle-event
+%{_bindir}/abrt-handle-event
%{_bindir}/abrt-handle-upload
%{_bindir}/abrt-action-save-package-data
%{_bindir}/abrt-watch-log
diff -x '*.po' -d -urpN abrt.8/src/daemon/abrtd.c abrt.9/src/daemon/abrtd.c
--- abrt.8/src/daemon/abrtd.c 2012-06-08 14:49:19.000000000 +0200
+++ abrt.9/src/daemon/abrtd.c 2012-06-26 12:39:23.054114293 +0200
@@ -64,7 +64,7 @@ static int socket_client_count = 0;
static pid_t spawn_event_handler_child(const char *dump_dir_name, const char *event_name, FILE **fpp)
{
char *args[6];
- args[0] = (char *) "/usr/libexec/abrt-handle-event";
+ args[0] = (char *) "abrt-handle-event";
args[1] = (char *) "-e";
args[2] = (char *) event_name;
args[3] = (char *) "--";
diff -x '*.po' -d -urpN abrt.8/src/daemon/abrt-handle-event.c abrt.9/src/daemon/abrt-handle-event.c
--- abrt.8/src/daemon/abrt-handle-event.c 2012-06-08 14:49:19.000000000 +0200
+++ abrt.9/src/daemon/abrt-handle-event.c 2012-06-26 13:02:03.338169218 +0200
@@ -276,7 +276,6 @@ int main(int argc, char **argv)
char *event_name = NULL;
struct options program_options[] = {
OPT__VERBOSE(&g_verbose),
- OPT_GROUP(""),
OPT_STRING('e', "event" , &event_name, "EVENT", _("Run EVENT on DIR")),
OPT_END()
};
diff -x '*.po' -d -urpN abrt.8/src/daemon/Makefile.am abrt.9/src/daemon/Makefile.am
--- abrt.8/src/daemon/Makefile.am 2012-06-08 14:49:19.000000000 +0200
+++ abrt.9/src/daemon/Makefile.am 2012-06-26 12:38:04.866097539 +0200
@@ -7,14 +7,13 @@ bin_SCRIPTS = \
abrt-handle-upload
bin_PROGRAMS = \
- abrt-action-save-package-data
+ abrt-action-save-package-data \
+ abrt-handle-event
sbin_PROGRAMS = \
abrtd \
abrt-server
-libexec_PROGRAMS = abrt-handle-event
-
abrtd_SOURCES = \
abrtd.c
abrtd_CPPFLAGS = \
diff -x '*.po' -d -urpN abrt.8/src/gui-gtk/main.c abrt.9/src/gui-gtk/main.c
--- abrt.8/src/gui-gtk/main.c 2012-06-14 15:49:24.000000000 +0200
+++ abrt.9/src/gui-gtk/main.c 2012-06-26 13:02:23.858892449 +0200
@@ -643,11 +643,19 @@ static void on_row_activated_cb(GtkTreeV
{
if (!is_dbus || chown_dir_over_dbus(dirname) == 0)
{
- report_problem_in_dir(dirname,
- LIBREPORT_ANALYZE | LIBREPORT_NOWAIT | LIBREPORT_GETPID);
+ pid_t pid = fork();
+ if (pid < 0) /* error */
+ perror_msg_and_die("fork");
+ if (pid == 0) /* child */
+ {
+ execl(BIN_DIR"/abrt-handle-event", "abrt-handle-event", "-e", "report-gui", "--", (char *)dirname, NULL);
+ execlp("abrt-handle-event", "abrt-handle-event", "-e", "report-gui", "--", (char *)dirname, NULL);
+ /* Child can't use GUI error reporting, we need to clear g_custom_logger */
+ g_custom_logger = NULL;
+ perror_msg_and_die("Can't execute '%s'", "abrt-handle-event");
+ }
}
- //else
- // TODO: show a warning dialog
+ /* else: chown_dir_over_dbus already complained */
}
}
@@ -668,18 +676,11 @@ static void open_problem_data_cb(GtkMenu
perror_msg_and_die("fork");
if (pid == 0) /* child */
{
- struct run_event_state *run_state = new_run_event_state();
- int r = run_event_on_dir_name(run_state, dirname, "open-gui");
- int no_such_event = (r == 0 && run_state->children_count == 0);
- free_run_event_state(run_state);
- if (!no_such_event)
- {
- exit(r);
- }
- /* Default: launch graphical tool */
- execl(BIN_DIR"/report-gtk", "report-gtk", "--", (char *)dirname, NULL);
- execlp("report-gtk", "report-gtk", "--", (char *)dirname, NULL);
- perror_msg_and_die("Can't execute %s", "report-gtk");
+ execl(BIN_DIR"/abrt-handle-event", "abrt-handle-event", "-e", "open-gui", "--", (char *)dirname, NULL);
+ execlp("abrt-handle-event", "abrt-handle-event", "-e", "open-gui", "--", (char *)dirname, NULL);
+ /* Child can't use GUI error reporting, we need to clear g_custom_logger */
+ g_custom_logger = NULL;
+ perror_msg_and_die("Can't execute '%s'", "abrt-handle-event");
}
}
}
11 years, 10 months
[PATCH] added new problem data API for hooks
by Jiri Moskovcak
- this API should ease the process of creating the problem directory
from hooks and actually doesn't require user to know anything about
the problem directory
- it should also prevent some problems with locking as most of the time
ot works with the in memory problem representation
---
src/include/Makefile.am | 3 ++-
src/include/hooklib.h | 22 ++++++++++++++++++++++
src/include/libabrt.h | 1 +
src/lib/hooklib.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 72 insertions(+), 1 deletion(-)
create mode 100644 src/include/hooklib.h
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index f98e2d5..a4f24b9 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -3,4 +3,5 @@ libabrt_includedir = \
libabrt_include_HEADERS = \
libabrt.h \
- abrt-dbus.h
+ abrt-dbus.h \
+ hooklib.h
diff --git a/src/include/hooklib.h b/src/include/hooklib.h
new file mode 100644
index 0000000..6a8b282
--- /dev/null
+++ b/src/include/hooklib.h
@@ -0,0 +1,22 @@
+/*
+ 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.
+*/
+
+problem_data_t * problem_data_new();
+int problem_data_add_item(problem_data_t *pd, char *key, char *value);
+int problem_data_add_file(problem_data_t *pd, const char* path);
+int problem_data_finalize(problem_data_t *pd, char **problem_id);
diff --git a/src/include/libabrt.h b/src/include/libabrt.h
index 2b50fe5..fff80ef 100644
--- a/src/include/libabrt.h
+++ b/src/include/libabrt.h
@@ -10,6 +10,7 @@
#include "abrt-dbus.h"
/* libreport's internal functions we use: */
#include <libreport/internal_libreport.h>
+#include "hooklib.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c
index b00b81e..d6db340 100644
--- a/src/lib/hooklib.c
+++ b/src/lib/hooklib.c
@@ -342,3 +342,50 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
free(args[7]);
return bt;
}
+
+static const char *get_filename(const char *path)
+{
+ const char *filename = NULL;
+
+ filename = strrchr(path, '/');
+ if (filename)
+ /* +1 => strip the '/' */
+ return filename+1;
+
+ return path;
+}
+
+problem_data_t *problem_data_new()
+{
+ return new_problem_data();
+}
+
+int problem_data_add_item(problem_data_t *pd, char * key, char * value)
+{
+ add_to_problem_data_ext(pd, key, value, CD_FLAG_TXT);
+ return 0;
+}
+
+int problem_data_add_file(problem_data_t *pd, const char* path)
+{
+ add_to_problem_data_ext(pd, get_filename(path), path, CD_FLAG_FILE);
+ return 0;
+}
+
+/** Saves the problem data
+ * creates the problem_dir in the configured problems directory
+ * destroyes
+*/
+int problem_data_finalize(problem_data_t *pd, char **problem_id)
+{
+ load_abrt_conf();
+ LibreportError res = save_dump_dir_from_problem_data(pd, problem_id, g_settings_dump_location);
+ VERB2 log("problem id: '%s'", *problem_id);
+ if (res != LR_OK)
+ /* can't be sure if it's ok, when the save fails */
+ *problem_id = NULL;
+
+ free_problem_data(pd);
+ pd = NULL;
+ return res;
+}
--
1.7.10.2
11 years, 10 months
[PATCH 1/2] added dd_rename() function
by Jiri Moskovcak
---
src/include/dump_dir.h | 1 +
src/lib/dump_dir.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index f8d2931..1073949 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -70,6 +70,7 @@ void dd_save_text(struct dump_dir *dd, const char *name, const char *data);
void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size);
/* Returns 0 if directory is deleted or not found */
int dd_delete(struct dump_dir *dd);
+int dd_rename(struct dump_dir *dd, const char *new_path);
/* reported_to handling */
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index 908a2df..a61fccf 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -913,6 +913,16 @@ report_result_t *find_in_reported_to(struct dump_dir *dd, const char *prefix)
return result;
}
+int dd_rename(struct dump_dir *dd, const char *new_path)
+{
+ int res = rename(dd->dd_dirname, new_path);
+ if (res == 0)
+ {
+ free(dd->dd_dirname);
+ dd->dd_dirname = rm_trailing_slashes(new_path);
+ }
+ return res;
+}
/* Utility function */
--
1.7.10.2
11 years, 10 months
[PATCH 1/2] move dbus client API to the libabrt
by Jiri Moskovcak
- so it can be shared in the gui and applet
---
po/POTFILES.in | 1 +
src/gui-gtk/main.c | 152 +-----------------------------------------
src/include/libabrt.h | 9 +++
src/lib/Makefile.am | 5 +-
src/lib/problem_api.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 190 insertions(+), 152 deletions(-)
create mode 100644 src/lib/problem_api.c
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9ae9f23..0b8176c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ src/gui-gtk/abrt.desktop.in
src/gui-gtk/main.c
src/lib/abrt_conf.c
src/lib/hooklib.c
+src/lib/problem_api.c
src/plugins/abrt-action-analyze-backtrace.c
src/plugins/abrt-action-analyze-c.c
src/plugins/abrt-action-analyze-oops.c
diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
index 41aef3c..981b7b4 100644
--- a/src/gui-gtk/main.c
+++ b/src/gui-gtk/main.c
@@ -19,7 +19,6 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <sys/inotify.h>
-#include <gio/gio.h> /* dbus */
#if HAVE_LOCALE_H
# include <locale.h>
#endif
@@ -154,121 +153,6 @@ static void watch_this_dir(const char *dir_name)
}
}
-static GDBusProxy *get_dbus_proxy(void)
-{
- GError *error = NULL;
- GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- ABRT_DBUS_NAME,
- ABRT_DBUS_OBJECT,
- ABRT_DBUS_IFACE,
- NULL,
- &error);
- if (error)
- {
- error_msg(_("Can't connect to system DBus: %s"), error->message);
- g_error_free(error);
- /* proxy is NULL in this case */
- }
- return proxy;
-}
-
-static int chown_dir_over_dbus(const char *problem_dir_path)
-{
- GDBusProxy *proxy = get_dbus_proxy();
- if (!proxy)
- return 1;
-
- GError *error = NULL;
- g_dbus_proxy_call_sync(proxy,
- "ChownProblemDir",
- g_variant_new("(s)", problem_dir_path),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- g_object_unref(proxy);
- if (error)
- {
- error_msg(_("Can't chown '%s': %s"), problem_dir_path, error->message);
- g_error_free(error);
- return 1;
- }
- return 0;
-}
-
-static int delete_problem_dirs_over_dbus(const GList *problem_dir_paths)
-{
- GDBusProxy *proxy = get_dbus_proxy();
- if (!proxy)
- return 1;
-
- GVariant *parameters = variant_from_string_list(problem_dir_paths);
-
- GError *error = NULL;
- g_dbus_proxy_call_sync(proxy,
- "DeleteProblem",
- parameters,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
-//g_variant_unref(parameters); -- need this??? no?? why?
- g_object_unref(proxy);
- if (error)
- {
- error_msg(_("Deleting problem directory failed: %s"), error->message);
- g_error_free(error);
- return 1;
- }
- return 0;
-}
-
-static problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
-{
- GDBusProxy *proxy = get_dbus_proxy();
- if (!proxy)
- return NULL;
-
- GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
- g_variant_builder_add(builder, "s", FILENAME_TIME );
- g_variant_builder_add(builder, "s", FILENAME_REASON );
- g_variant_builder_add(builder, "s", FILENAME_NOT_REPORTABLE);
- g_variant_builder_add(builder, "s", FILENAME_COMPONENT );
- g_variant_builder_add(builder, "s", FILENAME_EXECUTABLE );
- g_variant_builder_add(builder, "s", FILENAME_REPORTED_TO );
- GVariant *params = g_variant_new("(sas)", problem_dir_path, builder);
- g_variant_builder_unref(builder);
-
- GError *error = NULL;
- GVariant *result = g_dbus_proxy_call_sync(proxy,
- "GetInfo",
- params,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- g_object_unref(proxy);
- if (error)
- {
- error_msg(_("Can't get problem data from abrt-dbus: %s"), error->message);
- g_error_free(error);
- return NULL;
- }
-
- problem_data_t *pd = new_problem_data();
- char *key, *val;
- GVariantIter *iter;
- g_variant_get(result, "(a{ss})", &iter);
- while (g_variant_iter_loop(iter, "{ss}", &key, &val))
- {
- add_to_problem_data(pd, key, val);
- }
- g_variant_unref(result);
- return pd;
-}
-
static void add_directory_to_dirlist(const char *problem_dir_path, gpointer data)
{
bool use_dbus = (bool)data;
@@ -346,43 +230,9 @@ static void add_directory_to_dirlist(const char *problem_dir_path, gpointer data
VERB1 log("added: %s", problem_dir_path);
}
-static GList *get_problems_over_dbus(void)
-{
- GDBusProxy *proxy = get_dbus_proxy();
- if (!proxy)
- return NULL;
-
- GError *error = NULL;
- GVariant *result = g_dbus_proxy_call_sync(proxy,
- g_authorize ? "GetAllProblems" : "GetProblems",
- g_variant_new("()"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- g_object_unref(proxy);
- if (error)
- {
- error_msg(_("Can't get problem list from abrt-dbus: %s"), error->message);
- g_error_free(error);
- }
-
- GList *list = NULL;
- if (result)
- {
- /* Fetch "as" from "(as)" */
- GVariant *array = g_variant_get_child_value(result, 0);
- list = string_list_from_variant(array);
- g_variant_unref(array);
- g_variant_unref(result);
- }
-
- return list;
-}
-
static void query_dbus_and_add_to_dirlist(void)
{
- GList *problem_dirs = get_problems_over_dbus();
+ GList *problem_dirs = get_problems_over_dbus(g_authorize);
if (problem_dirs)
{
diff --git a/src/include/libabrt.h b/src/include/libabrt.h
index 0af2494..e9594b5 100644
--- a/src/include/libabrt.h
+++ b/src/include/libabrt.h
@@ -6,6 +6,8 @@
#ifndef LIBABRT_H_
#define LIBABRT_H_
+#include <gio/gio.h> /* dbus */
+#include "abrt-dbus.h"
/* libreport's internal functions we use: */
#include <libreport/internal_libreport.h>
@@ -82,6 +84,13 @@ void koops_extract_oopses(GList **oops_list, char *buffer, size_t buflen);
#define koops_print_suspicious_strings abrt_koops_print_suspicious_strings
void koops_print_suspicious_strings(void);
+/* dbus client api */
+int chown_dir_over_dbus(const char *problem_dir_path);
+int delete_problem_dirs_over_dbus(const GList *problem_dir_paths);
+problem_data_t *get_problem_data_dbus(const char *problem_dir_path);
+GList *get_problems_over_dbus(bool authorize);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 0e11a29..f7019ff 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -11,7 +11,8 @@ libabrt_la_SOURCES = \
kernel.c \
abrt_glib.c \
migrate_dirs.c \
- check_recent_crash_file.c
+ check_recent_crash_file.c \
+ problem_api.c
libabrt_la_CPPFLAGS = \
-Wall -Wwrite-strings -Werror \
@@ -22,9 +23,11 @@ libabrt_la_CPPFLAGS = \
-DEVENTS_DIR=\"$(EVENTS_DIR)\" \
$(GLIB_CFLAGS) \
$(LIBREPORT_CFLAGS) \
+ $(GIO_CFLAGS) \
-D_GNU_SOURCE
libabrt_la_LDFLAGS = \
-version-info 0:1:0
libabrt_la_LIBADD = \
$(GLIB_LIBS) \
+ $(GIO_LIBS) \
$(LIBREPORT_LIBS)
diff --git a/src/lib/problem_api.c b/src/lib/problem_api.c
new file mode 100644
index 0000000..704a0f9
--- /dev/null
+++ b/src/lib/problem_api.c
@@ -0,0 +1,175 @@
+/*
+ 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 "libabrt.h"
+
+static GDBusProxy *get_dbus_proxy(void)
+{
+ static GDBusProxy *proxy;
+
+ /* we cache it, so we can't free it! */
+ if (proxy != NULL)
+ return proxy;
+
+ GError *error = NULL;
+ proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ ABRT_DBUS_NAME,
+ ABRT_DBUS_OBJECT,
+ ABRT_DBUS_IFACE,
+ NULL,
+ &error);
+ if (error)
+ {
+ error_msg(_("Can't connect to system DBus: %s"), error->message);
+ g_error_free(error);
+ /* proxy is NULL in this case */
+ }
+ return proxy;
+}
+
+int chown_dir_over_dbus(const char *problem_dir_path)
+{
+ GDBusProxy *proxy = get_dbus_proxy();
+ if (!proxy)
+ return 1;
+
+ GError *error = NULL;
+ g_dbus_proxy_call_sync(proxy,
+ "ChownProblemDir",
+ g_variant_new("(s)", problem_dir_path),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ error_msg(_("Can't chown '%s': %s"), problem_dir_path, error->message);
+ g_error_free(error);
+ return 1;
+ }
+ return 0;
+}
+
+int delete_problem_dirs_over_dbus(const GList *problem_dir_paths)
+{
+ GDBusProxy *proxy = get_dbus_proxy();
+ if (!proxy)
+ return 1;
+
+ GVariant *parameters = variant_from_string_list(problem_dir_paths);
+
+ GError *error = NULL;
+ g_dbus_proxy_call_sync(proxy,
+ "DeleteProblem",
+ parameters,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+//g_variant_unref(parameters); -- need this??? no?? why?
+
+ if (error)
+ {
+ error_msg(_("Deleting problem directory failed: %s"), error->message);
+ g_error_free(error);
+ return 1;
+ }
+ return 0;
+}
+
+problem_data_t *get_problem_data_dbus(const char *problem_dir_path)
+{
+ GDBusProxy *proxy = get_dbus_proxy();
+ if (!proxy)
+ return NULL;
+
+ GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ g_variant_builder_add(builder, "s", FILENAME_TIME );
+ g_variant_builder_add(builder, "s", FILENAME_REASON );
+ g_variant_builder_add(builder, "s", FILENAME_NOT_REPORTABLE);
+ g_variant_builder_add(builder, "s", FILENAME_COMPONENT );
+ g_variant_builder_add(builder, "s", FILENAME_EXECUTABLE );
+ g_variant_builder_add(builder, "s", FILENAME_REPORTED_TO );
+ GVariant *params = g_variant_new("(sas)", problem_dir_path, builder);
+ g_variant_builder_unref(builder);
+
+ GError *error = NULL;
+ GVariant *result = g_dbus_proxy_call_sync(proxy,
+ "GetInfo",
+ params,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ error_msg(_("Can't get problem data from abrt-dbus: %s"), error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ problem_data_t *pd = new_problem_data();
+ char *key, *val;
+ GVariantIter *iter;
+ g_variant_get(result, "(a{ss})", &iter);
+ while (g_variant_iter_loop(iter, "{ss}", &key, &val))
+ {
+ add_to_problem_data(pd, key, val);
+ }
+ g_variant_unref(result);
+ return pd;
+}
+
+GList *get_problems_over_dbus(bool authorize)
+{
+ GDBusProxy *proxy = get_dbus_proxy();
+ if (!proxy)
+ return NULL;
+
+ GError *error = NULL;
+ GVariant *result = g_dbus_proxy_call_sync(proxy,
+ authorize ? "GetAllProblems" : "GetProblems",
+ g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ error_msg(_("Can't get problem list from abrt-dbus: %s"), error->message);
+ g_error_free(error);
+ }
+
+ GList *list = NULL;
+ if (result)
+ {
+ /* Fetch "as" from "(as)" */
+ GVariant *array = g_variant_get_child_value(result, 0);
+ list = string_list_from_variant(array);
+ g_variant_unref(array);
+ g_variant_unref(result);
+ }
+
+ return list;
+}
\ No newline at end of file
--
1.7.10.2
11 years, 10 months
[PATCH 1/2] rename abrt_curl.h to libreport_curl.h
by Nikola Pajkovsky
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
libreport.spec.in | 2 +-
po/POTFILES.in | 2 +-
src/include/Makefile.am | 2 +-
src/include/abrt_curl.h | 117 ---------
src/include/libreport_curl.h | 117 +++++++++
src/lib/Makefile.am | 2 +-
src/lib/abrt_curl.c | 499 -------------------------------------
src/lib/curl.c | 499 +++++++++++++++++++++++++++++++++++++
src/lib/json.c | 2 +-
src/plugins/abrt-bodhi.c | 2 +-
src/plugins/abrt_rh_support.c | 2 +-
src/plugins/reporter-kerneloops.c | 2 +-
src/plugins/reporter-rhtsupport.c | 2 +-
src/plugins/reporter-upload.c | 2 +-
src/plugins/ureport.c | 2 +-
15 files changed, 627 insertions(+), 627 deletions(-)
delete mode 100644 src/include/abrt_curl.h
create mode 100644 src/include/libreport_curl.h
delete mode 100644 src/lib/abrt_curl.c
create mode 100644 src/lib/curl.c
diff --git a/libreport.spec.in b/libreport.spec.in
index f758d2e..599986d 100644
--- a/libreport.spec.in
+++ b/libreport.spec.in
@@ -321,7 +321,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%files web-devel
%defattr(-,root,root,-)
-%{_includedir}/libreport/abrt_curl.h
+%{_includedir}/libreport/libreport_curl.h
%{_libdir}/pkgconfig/libreport-web.pc
%files python
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9fac721..f32ba57 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,7 +11,7 @@ src/gui-wizard-gtk/wizard.c
src/gui-wizard-gtk/wizard.glade
src/lib/event_config.c
src/lib/parse_options.c
-src/lib/abrt_curl.c
+src/lib/curl.c
src/lib/client.c
src/lib/run_event.c
src/lib/problem_data.c
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index fc73545..61b49a3 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -6,7 +6,7 @@ libreport_include_HEADERS = \
problem_data.h \
report.h \
run_event.h \
- abrt_curl.h \
+ libreport_curl.h \
\
internal_libreport.h \
internal_abrt_dbus.h
diff --git a/src/include/abrt_curl.h b/src/include/abrt_curl.h
deleted file mode 100644
index ca3c5b8..0000000
--- a/src/include/abrt_curl.h
+++ /dev/null
@@ -1,117 +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();
-
-/* Set proxy according to the url and call curl_easy_perform */
-CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url);
-
-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,
- ABRT_POST_DATA_STRING_AS_FORM_DATA = -4,
-};
-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_string_as_form_data(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_AS_FORM_DATA);
-}
-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/include/libreport_curl.h b/src/include/libreport_curl.h
new file mode 100644
index 0000000..ca3c5b8
--- /dev/null
+++ b/src/include/libreport_curl.h
@@ -0,0 +1,117 @@
+/*
+ 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();
+
+/* Set proxy according to the url and call curl_easy_perform */
+CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url);
+
+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,
+ ABRT_POST_DATA_STRING_AS_FORM_DATA = -4,
+};
+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_string_as_form_data(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_AS_FORM_DATA);
+}
+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/Makefile.am b/src/lib/Makefile.am
index cd19e90..d2282db 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -91,7 +91,7 @@ libabrt_dbus_la_LIBADD = \
$(DBUS_LIBS)
libreport_web_la_SOURCES = \
- abrt_curl.c \
+ curl.c \
abrt_xmlrpc.h abrt_xmlrpc.c \
proxies.h proxies.c \
ureport.h json.c
diff --git a/src/lib/abrt_curl.c b/src/lib/abrt_curl.c
deleted file mode 100644
index 1ae773d..0000000
--- a/src/lib/abrt_curl.c
+++ /dev/null
@@ -1,499 +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 "internal_libreport.h"
-#include "abrt_curl.h"
-#include "proxies.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);
-}
-
-static void
-xcurl_easy_setopt_off_t(CURL *handle, CURLoption option, curl_off_t parameter)
-{
- /* Can't reuse xcurl_easy_setopt_ptr: paramter is too wide */
- CURLcode err = curl_easy_setopt(handle, option, parameter);
- if (err) {
- char *msg = check_curl_error(err, "curl");
- error_msg_and_die("%s", msg);
- }
-}
-
-CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url)
-{
- GList *proxy_list, *li;
- CURLcode curl_err;
-
- proxy_list = get_proxy_list(url);
-
- if (proxy_list)
- {
- /* Try with each proxy before giving up. */
- /* TODO: Should we repeat the perform call only on certain errors? */
- for (li = proxy_list, curl_err = 1; curl_err && li; li = g_list_next(li))
- {
- xcurl_easy_setopt_ptr(handle, CURLOPT_PROXY, li->data);
- VERB3 log("Proxy set to: '%s'", (const char *)li->data);
-
- curl_err = curl_easy_perform(handle);
- }
- } else
- curl_err = curl_easy_perform(handle);
-
- list_free_with_free(proxy_list);
-
- return curl_err;
-}
-
-/*
- * 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);
- // Without this, curl would send "Content-Length: -1"
- // servers don't like that: "413 Request Entity Too Large"
- fseeko(data_file, 0, SEEK_END);
- off_t sz = ftello(data_file);
- fseeko(data_file, 0, SEEK_SET);
- xcurl_easy_setopt_off_t(handle, CURLOPT_POSTFIELDSIZE_LARGE, sz);
- } 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
-//FIXME: what if file size doesn't fit in long?
- 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 if (data_size == ABRT_POST_DATA_STRING_AS_FORM_DATA) {
- CURLFORMcode curlform_err = curl_formadd(&post, &last,
- CURLFORM_PTRNAME, "file", // element name
- // curl bug - missing filename
- // http://curl.haxx.se/mail/lib-2011-07/0176.html
- // https://github.com/bagder/curl/commit/45d883d
- // fixed in curl-7.22.0~144
- // tested with curl-7.24.0-3
- // should be working on F17
- CURLFORM_BUFFER, "*buffer*", // provides filename
- CURLFORM_BUFFERPTR, data,
- CURLFORM_BUFFERLENGTH, (long)strlen(data),
-//FIXME: what if file size doesn't fit in long?
- CURLFORM_CONTENTTYPE, content_type,
- CURLFORM_END);
- if (curlform_err != 0)
- 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);
- // We don't use CURLOPT_POSTFIELDSIZE_LARGE because
- // I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1.
- // Not a big problem: memory blobs >4GB are very unlikely.
- }
-
- struct curl_slist *httpheader_list = NULL;
-
- // Override "Content-Type:"
- if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA
- && data_size != ABRT_POST_DATA_STRING_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_with_proxy(handle, url);
- 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/curl.c b/src/lib/curl.c
new file mode 100644
index 0000000..98b24f5
--- /dev/null
+++ b/src/lib/curl.c
@@ -0,0 +1,499 @@
+/*
+ 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 "libreport_curl.h"
+#include "proxies.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);
+}
+
+static void
+xcurl_easy_setopt_off_t(CURL *handle, CURLoption option, curl_off_t parameter)
+{
+ /* Can't reuse xcurl_easy_setopt_ptr: paramter is too wide */
+ CURLcode err = curl_easy_setopt(handle, option, parameter);
+ if (err) {
+ char *msg = check_curl_error(err, "curl");
+ error_msg_and_die("%s", msg);
+ }
+}
+
+CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url)
+{
+ GList *proxy_list, *li;
+ CURLcode curl_err;
+
+ proxy_list = get_proxy_list(url);
+
+ if (proxy_list)
+ {
+ /* Try with each proxy before giving up. */
+ /* TODO: Should we repeat the perform call only on certain errors? */
+ for (li = proxy_list, curl_err = 1; curl_err && li; li = g_list_next(li))
+ {
+ xcurl_easy_setopt_ptr(handle, CURLOPT_PROXY, li->data);
+ VERB3 log("Proxy set to: '%s'", (const char *)li->data);
+
+ curl_err = curl_easy_perform(handle);
+ }
+ } else
+ curl_err = curl_easy_perform(handle);
+
+ list_free_with_free(proxy_list);
+
+ return curl_err;
+}
+
+/*
+ * 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);
+ // Without this, curl would send "Content-Length: -1"
+ // servers don't like that: "413 Request Entity Too Large"
+ fseeko(data_file, 0, SEEK_END);
+ off_t sz = ftello(data_file);
+ fseeko(data_file, 0, SEEK_SET);
+ xcurl_easy_setopt_off_t(handle, CURLOPT_POSTFIELDSIZE_LARGE, sz);
+ } 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
+//FIXME: what if file size doesn't fit in long?
+ 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 if (data_size == ABRT_POST_DATA_STRING_AS_FORM_DATA) {
+ CURLFORMcode curlform_err = curl_formadd(&post, &last,
+ CURLFORM_PTRNAME, "file", // element name
+ // curl bug - missing filename
+ // http://curl.haxx.se/mail/lib-2011-07/0176.html
+ // https://github.com/bagder/curl/commit/45d883d
+ // fixed in curl-7.22.0~144
+ // tested with curl-7.24.0-3
+ // should be working on F17
+ CURLFORM_BUFFER, "*buffer*", // provides filename
+ CURLFORM_BUFFERPTR, data,
+ CURLFORM_BUFFERLENGTH, (long)strlen(data),
+//FIXME: what if file size doesn't fit in long?
+ CURLFORM_CONTENTTYPE, content_type,
+ CURLFORM_END);
+ if (curlform_err != 0)
+ 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);
+ // We don't use CURLOPT_POSTFIELDSIZE_LARGE because
+ // I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1.
+ // Not a big problem: memory blobs >4GB are very unlikely.
+ }
+
+ struct curl_slist *httpheader_list = NULL;
+
+ // Override "Content-Type:"
+ if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA
+ && data_size != ABRT_POST_DATA_STRING_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_with_proxy(handle, url);
+ 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/json.c b/src/lib/json.c
index 659eda2..651010d 100644
--- a/src/lib/json.c
+++ b/src/lib/json.c
@@ -23,7 +23,7 @@
#include "internal_libreport.h"
#include "ureport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
/* on success 1 returned, on error zero is returned and appropriate value
diff --git a/src/plugins/abrt-bodhi.c b/src/plugins/abrt-bodhi.c
index 91f0eed..632a351 100644
--- a/src/plugins/abrt-bodhi.c
+++ b/src/plugins/abrt-bodhi.c
@@ -24,7 +24,7 @@
#include <rpm/rpmpgp.h>
#include "internal_libreport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "client.h"
//699198,705037,705036
diff --git a/src/plugins/abrt_rh_support.c b/src/plugins/abrt_rh_support.c
index 8d05e84..233edfa 100644
--- a/src/plugins/abrt_rh_support.c
+++ b/src/plugins/abrt_rh_support.c
@@ -20,7 +20,7 @@
#include <libxml/xmlwriter.h>
#include <curl/curl.h>
#include "internal_libreport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "abrt_rh_support.h"
struct reportfile {
diff --git a/src/plugins/reporter-kerneloops.c b/src/plugins/reporter-kerneloops.c
index 81ab93e..843c10b 100644
--- a/src/plugins/reporter-kerneloops.c
+++ b/src/plugins/reporter-kerneloops.c
@@ -16,7 +16,7 @@
Anton Arapov <anton(a)redhat.com>
Arjan van de Ven <arjan(a)linux.intel.com>
*/
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "internal_libreport.h"
/* helpers */
diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
index 4e4cccb..215b7c1 100644
--- a/src/plugins/reporter-rhtsupport.c
+++ b/src/plugins/reporter-rhtsupport.c
@@ -19,7 +19,7 @@
#include <libtar.h>
#include "internal_libreport.h"
#include "client.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "abrt_xmlrpc.h"
#include "abrt_rh_support.h"
#include "reporter-rhtsupport.h"
diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c
index 16b588d..38de383 100644
--- a/src/plugins/reporter-upload.c
+++ b/src/plugins/reporter-upload.c
@@ -17,7 +17,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <libtar.h>
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "internal_libreport.h"
//TODO: use this for better logging
diff --git a/src/plugins/ureport.c b/src/plugins/ureport.c
index 5ffcea3..c75af63 100644
--- a/src/plugins/ureport.c
+++ b/src/plugins/ureport.c
@@ -20,7 +20,7 @@
#include <json/json.h>
#include "internal_libreport.h"
#include "ureport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
/*
* Loads uReport configuration from various sources.
--
1.7.10.2
11 years, 10 months
CERT Triage Tools 1.0 (INFO#208126) (re-send)
by Jonathan M. Foote
Hello,
I work on the Vulnerability Analysis team at CERT/CC (www.cert.org<http://www.cert.org>). We recently released an open source project that I developed, the CERT Triage Tools, and I thought it might be of interest to your team. From the CERT Triage Tools webpage (http://www.cert.org/vuls/discovery/triage.html):
'''
The CERT Triage Tools can be used to assist software vendors and analysts in identifying the impact of defects discovered through techniques such as fuzz testing and prioritizing their remediation in the software development process. The CERT Triage Tools include a GNU Debugger (GDB) extension called "exploitable" that classifies Linux application bugs by severity and a wrapper script for batch execution.
'''
The 'exploitable' GDB extension mentioned above is a Python script that can be used to determine how exploitable a crash is. I recently published a blog post with some more information on the extension and how to use it: http://www.cert.org/blogs/certcc/2012/04/cert_triage_tools_10.html
Josh Bressers and Steve Grubb, of Red Hat, have been investigating use of the tools by your organization. I have CC'd them on this message. (Josh and Steve: The first message I sent didn't post to the mailing list due to a clerical error on my part - feel free to ignore this re-send)
Regardless, I have been passively following the work your team has been doing and thought our tools might be useful to you. If you have any questions, comments, or ideas feel please feel free to drop me a line.
Thanks,
Jon Foote
11 years, 10 months
[PATCH] bugzilla: make bugs private
by Nikola Pajkovsky
to make bugs private, it must be placed in groups. Name of groups
is not possible fetch via xmlrpc query against bugzilla server.
That means, that everyone must "magically" know the name of group.
And things can go even worst. E.g. if you want to place bug in group
Red Hat Development (internal), it won't be work like that
reporter-bugzilla -g "Red Hat Development (internal)"
because it's not the name of group. Digging into
bugzilla.redhat.com/<some-bug-id> I found
<input type="hidden" name="defined_groups" value="devel">
<input type="checkbox" value="devel" name="groups" id="group_12">
<label for="group_12">Red Hat Development (internal)</label>
<input type="hidden" name="defined_groups" value="redhat">
<input type="checkbox" value="redhat" name="groups" id="group_161">
<label for="group_161">Red Hat Employee (internal)</label>
that means, corrent name for 'Red Hat Development (internal)' is 'devel',
and corrent name for 'Red Hat Employee (internal)' is 'redhat' - tough cookies.
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
doc/reporter-bugzilla.txt | 5 +++-
src/plugins/reporter-bugzilla.c | 6 +++--
src/plugins/rhbz.c | 57 ++++++++++++++++++++++++++++++++-------
src/plugins/rhbz.h | 2 +-
4 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/doc/reporter-bugzilla.txt b/doc/reporter-bugzilla.txt
index 94216ae..1d6af43 100644
--- a/doc/reporter-bugzilla.txt
+++ b/doc/reporter-bugzilla.txt
@@ -7,7 +7,7 @@ reporter-bugzilla - Reports problem to Bugzilla.
SYNOPSIS
--------
-'reporter-bugzilla' [-vbf] [-c CONFFILE] -d DIR
+'reporter-bugzilla' [-vbf] [-g|--group GROUP-NAME]... [-c CONFFILE] -d DIR
Or:
@@ -85,6 +85,9 @@ OPTIONS
-h::
--duphash::
Search in bugzilla by abrt's DUPHASH and return BUG-ID
+-g::
+--group GROUP-NAME::
+ When creating bug, add bug in given group
SEE ALSO
--------
diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c
index bb59ac7..66758a1 100644
--- a/src/plugins/reporter-bugzilla.c
+++ b/src/plugins/reporter-bugzilla.c
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
/* Can't keep these strings/structs static: _() doesn't support that */
const char *program_usage_string = _(
"\n"
- "& [-vbf] [-c CONFFILE] -d DIR\n"
+ "& [-vbf] [-g|--group GROUP-NAME]... [-c CONFFILE] -d DIR\n"
"or:\n"
"& [-v] [-c CONFFILE] [-d DIR] -t[ID] FILE...\n"
"\n"
@@ -104,6 +104,7 @@ int main(int argc, char **argv)
};
char *ticket_no = NULL, *abrt_hash = NULL;
+ GList *group = NULL;
/* Keep enum above and order of options below in sync! */
struct options program_options[] = {
OPT__VERBOSE(&g_verbose),
@@ -113,6 +114,7 @@ int main(int argc, char **argv)
OPT_BOOL( 'b', NULL, NULL, _("When creating bug, attach binary files too")),
OPT_BOOL( 'f', NULL, NULL, _("Force reporting even if this problem is already reported")),
OPT_STRING( 'h', "duphash", &abrt_hash, "DUPHASH", _("Find BUG-ID according to DUPHASH")),
+ OPT_LIST( 'g', "group", &group , "GROUP-NAME", _("Add new bug in given groups ")),
OPT_END()
};
unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
@@ -340,7 +342,7 @@ int main(int argc, char **argv)
{
/* Create new bug */
log(_("Creating a new bug"));
- int bug_id = rhbz_new_bug(client, problem_data, rhbz.b_release);
+ int bug_id = rhbz_new_bug(client, problem_data, rhbz.b_release, group);
log(_("Adding attachments to bug %i"), bug_id);
char bug_id_str[sizeof(int)*3 + 2];
diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c
index 579655b..93febbf 100644
--- a/src/plugins/rhbz.c
+++ b/src/plugins/rhbz.c
@@ -596,10 +596,13 @@ char *rhbz_get_backtrace_info(problem_data_t *problem_data, size_t max_text_size
/* suppress mail notify by {s:i} (nomail:1) (driven by flag) */
int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data,
- const char *release)
+ const char *release, GList *group)
{
func_entry();
+ if (group)
+ VERB3 log("# of groups %d", g_list_length(group));
+
const char *package = get_problem_item_content_or_NULL(problem_data,
FILENAME_PACKAGE);
const char *component = get_problem_item_content_or_NULL(problem_data,
@@ -693,14 +696,50 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data,
xmlrpc_value* result = NULL;
char *summary = strbuf_free_nobuf(buf_summary);
- 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);
+
+ if (!group)
+ {
+ 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);
+ }
+ else
+ {
+ xmlrpc_env env;
+ xmlrpc_env_init(&env);
+
+ xmlrpc_value *xmlrpc_groups = xmlrpc_array_new(&env);
+ if (env.fault_occurred)
+ abrt_xmlrpc_die(&env);
+
+ for (GList *l = group; l; l = l->next)
+ {
+ xmlrpc_value *s = xmlrpc_string_new(&env, (char *) l->data);
+ if (env.fault_occurred)
+ abrt_xmlrpc_die(&env);
+
+ xmlrpc_array_append_item(&env, xmlrpc_groups, s);
+ if (env.fault_occurred)
+ abrt_xmlrpc_die(&env);
+
+ xmlrpc_DECREF(s);
+ }
+
+ result = abrt_xmlrpc_call(ax, "Bug.create", "({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:A})",
+ "product", product,
+ "component", component,
+ "version", version,
+ "summary", summary,
+ "description", full_dsc,
+ "status_whiteboard", status_whiteboard,
+ "platform", arch,
+ "groups", xmlrpc_groups);
+ }
free(status_whiteboard);
free(product);
diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h
index b3084d3..4687aa7 100644
--- a/src/plugins/rhbz.h
+++ b/src/plugins/rhbz.h
@@ -102,7 +102,7 @@ int rhbz_array_size(xmlrpc_value *xml);
int rhbz_bug_id(xmlrpc_value *xml, size_t ver);
int rhbz_new_bug(struct abrt_xmlrpc *ax, problem_data_t *problem_data,
- const char *release);
+ const char *release, GList *group);
int rhbz_attach_files(struct abrt_xmlrpc *ax, const char *bug_id,
problem_data_t *problem_data, int flags);
--
1.7.10.2
11 years, 10 months
[PATCH] track#557 : add report-gui and report_uRerport events actions to analyzer configs
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/plugins/ccpp_event.conf | 8 ++++++++
src/plugins/koops_event.conf | 8 ++++++++
src/plugins/python_event.conf | 8 ++++++++
src/plugins/xorg_event.conf | 4 ++++
4 files changed, 28 insertions(+)
diff --git a/src/plugins/ccpp_event.conf b/src/plugins/ccpp_event.conf
index 9ac32bb..1667ff8 100644
--- a/src/plugins/ccpp_event.conf
+++ b/src/plugins/ccpp_event.conf
@@ -47,3 +47,11 @@ EVENT=report_Bugzilla analyzer=CCpp duphash!=
abrt-dedup-client
test -f component || abrt-action-save-package-data
reporter-bugzilla -b -c /etc/libreport/plugins/bugzilla.conf
+
+# Send micro report
+EVENT=report_uReport analyzer=CCpp
+ reporter-ureport
+
+# Reporting of C/Cpp problems
+EVENT=report-gui analyzer=CCpp
+ report-gtk -e report_uReport -e analyze_RetraceServer -e report_Bugzilla -- "$DUMP_DIR"
diff --git a/src/plugins/koops_event.conf b/src/plugins/koops_event.conf
index 02e956e..4d75110 100644
--- a/src/plugins/koops_event.conf
+++ b/src/plugins/koops_event.conf
@@ -17,3 +17,11 @@ EVENT=post-create analyzer=Kerneloops
EVENT=report_Bugzilla analyzer=Kerneloops
reporter-bugzilla -b
+
+# Send micro report
+EVENT=report_uReport analyzer=Kerneloops
+ reporter-ureport
+
+# Reporting of kernel oopses
+EVENT=report-gui analyzer=Kerneloops
+ report-gtk -e report_uReport -e report_Bugzilla -- "$DUMP_DIR"
diff --git a/src/plugins/python_event.conf b/src/plugins/python_event.conf
index 7f089b0..a7c72ac 100644
--- a/src/plugins/python_event.conf
+++ b/src/plugins/python_event.conf
@@ -5,3 +5,11 @@ EVENT=post-create analyzer=Python
EVENT=report_Bugzilla analyzer=Python
test -f component || abrt-action-save-package-data
reporter-bugzilla -b -c /etc/libreport/plugins/bugzilla.conf
+
+# Send micro report
+EVENT=report_uReport analyzer=Python
+ reporter-ureport
+
+# Reporting of python exceptions
+EVENT=report-gui analyzer=Python
+ report-gtk -e report_uReport -e report_Bugzilla -- "$DUMP_DIR"
diff --git a/src/plugins/xorg_event.conf b/src/plugins/xorg_event.conf
index 0785f48..b974a6b 100644
--- a/src/plugins/xorg_event.conf
+++ b/src/plugins/xorg_event.conf
@@ -30,3 +30,7 @@ EVENT=post-create analyzer=xorg
EVENT=report_Bugzilla analyzer=xorg
reporter-bugzilla -b
+
+# Reporting of xorg problems
+EVENT=report-gui analyzer=xorg
+ report-gtk -e report_Bugzilla -- "$DUMP_DIR"
--
1.7.10.2
11 years, 10 months
[PATCH] fixed hyperlink parsing rhbz#831333
by Jiri Moskovcak
---
src/gtk-helpers/hyperlinks.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/gtk-helpers/hyperlinks.c b/src/gtk-helpers/hyperlinks.c
index 72fab15..a58bb3a 100644
--- a/src/gtk-helpers/hyperlinks.c
+++ b/src/gtk-helpers/hyperlinks.c
@@ -6,9 +6,24 @@
char *tag_url(const char* line, const char* prefix)
{
static const char *const known_url_prefixes[] = {"http://", "https://", "ftp://", "file://", NULL};
+ static const char *known_url_ends = ",'\"\t\n ";
char *result = xstrdup(line);
+
+ char *find_end(const char* url_start)
+ {
+ char *url_end = strchrnul(url_start, *known_url_ends);
+ const char *curr_end = known_url_ends;
+ while(*(++curr_end) != '\0')
+ {
+ char *tmp = strchrnul(url_start, *curr_end);
+ if (tmp < url_end)
+ url_end = tmp;
+ }
+ return url_end;
+ }
+
const char *const *pfx = known_url_prefixes;
while (*pfx != NULL)
{
@@ -16,7 +31,7 @@ char *tag_url(const char* line, const char* prefix)
char *url_start;
while ((url_start = strstr(cur_pos, *pfx)) != NULL)
{
- char *url_end = strchrnul(url_start, ' '); //TODO: also '.', ',', '\t', '\n'...
+ char *url_end = find_end(url_start);
int len = url_end - url_start;
char *hyperlink = xasprintf("%s<a href=\"%.*s\">%.*s</a>",
prefix,
--
1.7.10.2
11 years, 10 months
[PATCH] track#557 : remove ureport config and move it's configuration to analyzer configs
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
libreport.spec.in | 1 -
src/lib/report_event.conf | 3 +++
src/plugins/Makefile.am | 3 +--
src/plugins/ureport_event.conf | 11 -----------
4 files changed, 4 insertions(+), 14 deletions(-)
delete mode 100644 src/plugins/ureport_event.conf
diff --git a/libreport.spec.in b/libreport.spec.in
index d1dcf1c..6fb0e05 100644
--- a/libreport.spec.in
+++ b/libreport.spec.in
@@ -358,7 +358,6 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%{_bindir}/reporter-ureport
#%{_mandir}/man1/reporter-ureport.1.gz
%{_sysconfdir}/libreport/events/report_uReport.xml
-%config(noreplace) %{_sysconfdir}/libreport/events.d/ureport_event.conf
%files plugin-bugzilla
%defattr(-,root,root,-)
diff --git a/src/lib/report_event.conf b/src/lib/report_event.conf
index 0a116ff..f5c9407 100644
--- a/src/lib/report_event.conf
+++ b/src/lib/report_event.conf
@@ -46,3 +46,6 @@ include events.d/*.conf
# For testing purposes only
#EVENT=report_Dummy analyzer=libreport echo "Hello world" >> /tmp/libreport.log
+
+EVENT=report-gui analyzer=libreport
+ report-gtk -e report_Bugzilla -- "$DUMP_DIR"
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index d4bd428..3760fb4 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -42,8 +42,7 @@ dist_eventsconf_DATA = \
print_event.conf \
bugzilla_event.conf \
rhtsupport_event.conf \
- uploader_event.conf \
- ureport_event.conf
+ uploader_event.conf
EXTRA_DIST = \
report_Bugzilla.xml.in \
diff --git a/src/plugins/ureport_event.conf b/src/plugins/ureport_event.conf
deleted file mode 100644
index 94cdbac..0000000
--- a/src/plugins/ureport_event.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-EVENT=report_uReport analyzer=CCpp reporter-ureport
-
-EVENT=report_uReport analyzer=Python reporter-ureport
-
-EVENT=report_uReport analyzer=Kerneloops reporter-ureport
-
-EVENT=report-gui analyzer=CCpp
- report-gtk -e report_uReport -e analyze_RetraceServer -e report_Bugzilla -- "$DUMP_DIR"
-
-EVENT=report-gui analyzer!=CCpp
- report-gtk -e report_uReport -e report_Bugzilla -- "$DUMP_DIR"
--
1.7.10.2
11 years, 10 months