[LIBREPORT PATCH v2] trac#688: do not store configuration options as Item look attributes
by Jakub Filak
- all configuration options are stored as binary data in Secret
member of Item interface
- each option is stored as c-string 'name=value\0' and a secret value
consists from concatenation of corresponding strings for all options
- lookup attributes contain only 'libreportEventConfig' key and and the
key is associated with event name
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/gtk-helpers/secrets.c | 298 +++++++++++++++++++++++++++++++---------------
1 file changed, 205 insertions(+), 93 deletions(-)
diff --git a/src/gtk-helpers/secrets.c b/src/gtk-helpers/secrets.c
index ee6a348..c9c32e1 100644
--- a/src/gtk-helpers/secrets.c
+++ b/src/gtk-helpers/secrets.c
@@ -29,6 +29,7 @@
#define SECRETS_COLLECTION_ALIAS "default"
#define SECRETS_SEARCH_ATTRIBUTE "libreportEventConfig"
+#define SECRETS_OPTION_VALUE_DELIMITER '='
/* 5s timeout*/
#define SECRETS_CALL_DEFAULT_TIMEOUT 5000
@@ -36,6 +37,7 @@
/* Well known errors for which we have workarounds */
#define NOT_IMPLEMENTED_READ_ALIAS_ERROR_MESSAGE "GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such method 'ReadAlias' in interface 'org.freedesktop.Secret.Service' at object path '/org/freedesktop/secrets' (signature 's')"
#define INVALID_PROPERTIES_ARGUMENTS "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Invalid properties argument"
+#define GNOME_KEYRING_NOT_HAVING_SECRET_ERROR_MESSAGE "GDBus.Error:org.freedesktop.DBus.Error.Failed: Couldn't get item secret"
/*
Data structure:
@@ -47,12 +49,23 @@
Collection is a set of Items identified by labels (label is a string).
Libreport uses event names as labels for items which hold event config data.
+ One item holds all configuration items for one event.
+
+ Item has a set of (name,value) pairs called lookup attributes.
+ Libreport uses 'libreportEventConfig' attribute for searching. The
+ attribute hodls an event name.
+ Item has a secret value. The value holds an arbitrary binary data.
+ Libreport uses the value to store configuration items.
+ The value consists from several c-strings where each option is
+ represented by one c-string (bytes followed by '\0').
+ Each option string is concatenation of option name, delimiter and option value.
+
+
+ For example, "report_Bugzilla" item will have the lookup attribute
+ like ("libreportEventConfig", "report_Bugzilla") and the secret value
+ like ("Bugzilla_URL=https://bugzilla.redhat.com\0Bugzilla_Login=foo\0")
- Item is a set of (name,value) pairs called attributes.
- Libreport uses attributes to store config data.
- For example, "report_Bugzilla" item will have some attributes,
- like ("Bugzilla_BugzillaURL", "https://bugzilla.redhat.com").
DBus API:
=========
@@ -246,32 +259,6 @@ static GDBusProxy *secrets_object_get_properties_proxy(struct secrets_object *ob
return obj->property_proxy;
}
-
-static bool secrets_object_set_dbus_property(struct secrets_object *obj,
- const char *property,
- GVariant *value)
-{
- GDBusProxy *properties = secrets_object_get_properties_proxy(obj);
-
- if (!properties)
- return false;
-
- /* http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfac... */
- /* org.freedesktop.DBus.Properties.Set (IN String interface_name, IN String property_name, IN Variant value); */
- GVariant *const resp = dbus_call_sync(properties,
- "Set",
- g_variant_new("(ssv)",
- obj->interface_name,
- property,
- value)
- );
-
- if (resp)
- g_variant_unref(resp);
-
- return resp;
-}
-
/*******************************************************************************/
/* struct secrets_service */
/*******************************************************************************/
@@ -472,6 +459,7 @@ static GVariant *secrets_prompt(const char *prompt_path,
.closure_marshal = NULL,
};
+ /* TODO : leak */
GDBusProxy *const prompt_proxy = get_dbus_proxy(prompt_path, SECRETS_NAME_SPACE("Prompt"));
*dismissed = false;
@@ -544,6 +532,7 @@ static GVariant *secrets_service_unlock(const gchar *const *objects,
gchar *prompt = NULL;
GVariant *result = NULL;
+ /* TODO : leak */
g_variant_get(var, "(@aoo)", &result, &prompt);
*dismissed = false;
@@ -774,6 +763,7 @@ static struct secrets_object *secrets_service_create_collection(const gchar *lab
gchar *prompt = NULL;
GVariant *collection_var = NULL;
+ /* TODO : leak */
g_variant_get(resp, "(@oo)", &collection_var, &prompt);
if (is_prompt_required(prompt))
@@ -810,7 +800,7 @@ static struct secrets_object *secrets_service_create_collection(const gchar *lab
static GVariant *create_item_call_args(const char *event_name,
GVariant *attributes,
- GDBusProxy *session,
+ GVariant *secret,
bool full_property_name)
{
/* gnome-keyring accepts properties with namespace */
@@ -842,21 +832,60 @@ static GVariant *create_item_call_args(const char *event_name,
g_variant_builder_add(prop_builder, "{sv}", lbl_name, g_variant_new_string(event_name));
g_variant_builder_add(prop_builder, "{sv}", att_name, attributes);
- GVariantBuilder *const param_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ GVariant *const prop = g_variant_builder_end(prop_builder);
+
+ return g_variant_new("(@a{sv}@(oayays)b)", prop, secret, FALSE);
+}
+
+static GVariant *create_secret_from_options(GDBusProxy *session, GList *options, bool store_passwords)
+{
GVariantBuilder *const value_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ for (GList *iter = g_list_first(options); iter; iter = g_list_next(iter))
+ {
+ event_option_t *const op = (event_option_t *)iter->data;
+ /* TODO : is it still necessary? Passwords are encrypted now. */
+ if (op->eo_type != OPTION_TYPE_PASSWORD || store_passwords)
+ {
+ const char *byte = op->eo_name;
+ while(byte[0] != '\0')
+ g_variant_builder_add(value_builder, "y", *byte++);
+
+ g_variant_builder_add(value_builder, "y", SECRETS_OPTION_VALUE_DELIMITER);
+
+ byte = op->eo_value;
+ while(byte[0] != '\0')
+ g_variant_builder_add(value_builder, "y", *byte++);
- GVariant *const secret = g_variant_new("(o@ay@ays)",
- g_dbus_proxy_get_object_path(session),
- g_variant_builder_end(param_builder),
- g_variant_builder_end(value_builder),
- "text/plain, charset=utf8");
+ g_variant_builder_add(value_builder, "y", '\0');
+ }
+ }
+
+ GVariant *const value = g_variant_builder_end(value_builder);
- return g_variant_new("(@a{sv}@(oayays)b)", g_variant_builder_end(prop_builder), secret, FALSE);
+ return g_variant_new("(oay@ays)",
+ g_dbus_proxy_get_object_path(session),
+ /* param */ NULL,
+ value,
+ "application/libreport");
+}
+
+static GVariant *create_lookup_attributes(const char *event_name)
+{
+ GVariantBuilder *const attr_builder = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY);
+ /* add extra attribute used for searching */
+ g_variant_builder_add(attr_builder, "{ss}", SECRETS_SEARCH_ATTRIBUTE, event_name);
+
+ /* An example of attributes: */
+ /* { */
+ /* "libreportEventConfig": "event_name", */
+ /* } */
+ return g_variant_builder_end(attr_builder);
}
static bool secrets_collection_create_text_item(struct secrets_object *collection,
const char *event_name,
GVariant *attributes,
+ GVariant *secret,
bool *dismissed)
{
bool succ = false;
@@ -903,8 +932,10 @@ static bool secrets_collection_create_text_item(struct secrets_object *collectio
/* prompt : A prompt object, or the special value '/' if no prompt */
/* is necessary. */
GVariant *const resp = g_dbus_proxy_call_sync(collection->proxy, "CreateItem",
- create_item_call_args(event_name, g_variant_ref(attributes),
- g_session_proxy, options[choice]),
+ create_item_call_args(event_name,
+ g_variant_ref(attributes),
+ g_variant_ref(secret),
+ options[choice]),
G_DBUS_PROXY_FLAGS_NONE, SECRETS_CALL_DEFAULT_TIMEOUT,
NULL, &error);
@@ -924,6 +955,7 @@ static bool secrets_collection_create_text_item(struct secrets_object *collectio
gchar *prompt = NULL;
gchar *item = NULL;
+ /* TODO : leak */
g_variant_get(resp, "(oo)", &item, &prompt);
/* if prompt is no required the function is successfull */
@@ -941,6 +973,7 @@ static bool secrets_collection_create_text_item(struct secrets_object *collectio
}
g_variant_unref(attributes);
+ g_variant_unref(secret);
return succ;
}
@@ -1052,68 +1085,138 @@ static bool get_default_collection(struct secrets_object **collection,
return succ;
}
-static void load_event_options_from_item(GList *options,
+static void load_event_options_from_item(GDBusProxy *session,
+ GList *options,
struct secrets_object *item)
{
- GVariant *const attributes =
- g_dbus_proxy_get_cached_property(item->proxy, "Attributes");
+ { /* for backward compatibility */
+ /* load configuration from lookup attributes but don't store configuration in lookup attributes */
+ GVariant *const attributes =
+ g_dbus_proxy_get_cached_property(item->proxy, "Attributes");
- GVariantIter *iter = NULL;
- g_variant_get(attributes, "a{ss}", &iter);
+ GVariantIter *iter = NULL;
+ g_variant_get(attributes, "a{ss}", &iter);
- gchar *name = NULL;
- gchar *value = NULL;
- while (g_variant_iter_loop(iter, "{ss}", &name, &value))
- {
- event_option_t *const option = get_event_option_from_list(name, options);
- if (option)
+ gchar *name = NULL;
+ gchar *value = NULL;
+ while (g_variant_iter_loop(iter, "{ss}", &name, &value))
{
- free(option->eo_value);
- option->eo_value = xstrdup(value);
- VERB2 log("loaded event option : '%s => %s'", name, option->eo_value);
+ event_option_t *const option = get_event_option_from_list(name, options);
+ if (option)
+ {
+ free(option->eo_value);
+ option->eo_value = xstrdup(value);
+ VERB2 log("loaded event option : '%s' => '%s'", name, option->eo_value);
+ }
}
+
+ g_variant_unref(attributes);
}
- g_variant_unref(attributes);
-}
+ { /* read configuration from the secret value */
+ GError *error = NULL;
+ GVariant *const resp = g_dbus_proxy_call_sync(item->proxy,
+ "GetSecret",
+ g_variant_new("(o)",
+ g_dbus_proxy_get_object_path(session)),
+ G_DBUS_PROXY_FLAGS_NONE,
+ SECRETS_CALL_DEFAULT_TIMEOUT,
+ /* GCancellable */ NULL,
+ &error);
-static GVariant *create_attributes_from_options(GList *options,
- const char *event_name,
- bool store_passwords)
-{
- GVariantBuilder *const attr_builder = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY);
- for (GList *iter = g_list_first(options); iter; iter = g_list_next(iter))
- { /* we store data in the search attributes */
- event_option_t *const op = (event_option_t *)iter->data;
- if (op->eo_type != OPTION_TYPE_PASSWORD || store_passwords)
- g_variant_builder_add(attr_builder, "{ss}", op->eo_name, op->eo_value);
- }
+ if (error)
+ { /* if the error is NOT the known error produced by the gnome-keyring */
+ /* when no secret value is assigned to an item */
+ /* then let you user known that the error occured */
+ if(strcmp(error->message, GNOME_KEYRING_NOT_HAVING_SECRET_ERROR_MESSAGE) != 0)
+ error_msg(_("can't get secret value: %s"), error->message);
+ else
+ {
+ VERB1 log("can't get secret value: %s", error->message);
+ }
- /* and finally, add extra attribute used for searching */
- g_variant_builder_add(attr_builder, "{ss}", SECRETS_SEARCH_ATTRIBUTE, event_name);
+ g_error_free(error);
+ return;
+ }
- /* An example of attributes: */
- /* { */
- /* "BugzillaURL": "Value1", */
- /* "BugzillaPassword": "Value2", */
- /* "libreportEventConfig": "event_name", */
- /* } */
- return g_variant_builder_end(attr_builder);
+ if (g_variant_n_children(resp) == 0)
+ {
+ VERB1 log("response from GetSecret() method doesn't contain data: '%s'", g_variant_print(resp, TRUE));
+ return;
+ }
+
+ /* All dbus responses are returned inside of an variant */
+ GVariant *const secret = g_variant_get_child_value(resp, 0);
+
+ /* DBus represents a structure as a tuple of values */
+ /* struct Secret
+ * {
+ * (o) object path
+ * (ay) byte array params
+ * (ay) byte array value
+ * (s) string content type
+ * }
+ */
+ if (g_variant_n_children(secret) != 4)
+ {
+ VERB1 log("secret value has invalid structure: '%s'", g_variant_print(secret, TRUE));
+ return;
+ }
+
+ /* get (ay) byte array value */
+ GVariant *const secret_value = g_variant_get_child_value(secret, 2);
+
+ gsize nelems;
+ gconstpointer data = g_variant_get_fixed_array(secret_value, &nelems, sizeof(guchar));
+
+ while(nelems > 0)
+ {
+ const size_t sz = strlen(data) + 1;
+ if (sz > nelems)
+ { /* check next size, if is too big then trailing 0 is probably missing */
+ VERB1 log("broken secret value, atttempts to read %zdB but only %zdB are available)", sz, nelems);
+ break;
+ }
+ nelems -= sz;
+
+ char *name = xstrdup(data);
+ char *value = strchr(name, SECRETS_OPTION_VALUE_DELIMITER);
+ if (!value)
+ {
+ VERB1 log("secret value has invalid format: missing delimiter after option name");
+ goto next_option;
+ }
+
+ *value++ = '\0';
+
+ event_option_t *const option = get_event_option_from_list(name, options);
+ if (option)
+ {
+ free(option->eo_value);
+ option->eo_value = xstrdup(value);
+ VERB2 log("loaded event option : '%s' => '%s'", name, option->eo_value);
+ }
+
+next_option:
+ free(name);
+ data += sz;
+ }
+
+ g_variant_unref(secret_value);
+ g_variant_unref(secret);
+ g_variant_unref(resp);
+ }
}
static bool find_item_by_event_name(const struct secrets_object *collection,
const char *event_name,
struct secrets_object **item)
{
- GVariantBuilder *const attrs = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY);
-
- /* For searching uses item's attribute holding an event name */
- g_variant_builder_add(attrs, "{ss}", SECRETS_SEARCH_ATTRIBUTE, event_name);
-
- return secrets_collection_search_one_item(collection, g_variant_builder_end(attrs), item);
+ return secrets_collection_search_one_item(collection, create_lookup_attributes(event_name), item);
}
-static void load_settings(struct secrets_object *collection, const char *event_name, event_config_t *ec)
+static void load_settings(GDBusProxy *session, struct secrets_object *collection,
+ const char *event_name, event_config_t *ec)
{
/* Locked property is not supported by ksecrets */
/* thus we have to perform Unlock for each call of load settings */
@@ -1128,7 +1231,7 @@ static void load_settings(struct secrets_object *collection, const char *event_n
if (succ && item)
{
VERB2 log("loading event config : '%s'", event_name);
- load_event_options_from_item(ec->options, item);
+ load_event_options_from_item(session, ec->options, item);
secrets_object_delete(item);
item = NULL;
}
@@ -1145,7 +1248,7 @@ static void load_event_config(gpointer key, gpointer value, gpointer user_data)
struct secrets_object *const collection = (struct secrets_object *)user_data;
if (is_event_config_user_storage_available())
- load_settings(collection, event_name, ec);
+ load_settings(g_session_proxy, collection, event_name, ec);
}
static bool save_options(struct secrets_object *collection,
@@ -1160,22 +1263,31 @@ static bool save_options(struct secrets_object *collection,
if (!succ)
return succ;
- GVariant *const attributes = create_attributes_from_options(options,
- event_name,
- store_passwords);
+ GVariant *const secret = create_secret_from_options(g_session_proxy, options, store_passwords);
if (item)
- { /* item exists, change Attributes */
+ { /* item exists, change a secret */
VERB2 log("updating event config : '%s'", event_name);
+ /* can't be dismissed */
*dismissed = false;
- succ = secrets_object_set_dbus_property(item, "Attributes", attributes);
+ GVariant *const args = g_variant_new("(@(oayays))", secret);
+ GVariant *const resp = dbus_call_sync(item->proxy, "SetSecret", args);
+ succ = resp;
+
+ if (succ)
+ g_variant_unref(resp);
+
secrets_object_delete(item);
- item = NULL;
}
else
- { /* create a new item with Attributes */
+ { /* create a new item */
+ GVariant *const attributes = create_lookup_attributes(event_name);
VERB2 log("creating event config : '%s'", event_name);
- succ = secrets_collection_create_text_item(collection, event_name, attributes, dismissed);
+ succ = secrets_collection_create_text_item(collection, event_name, attributes, secret, dismissed);
+
+ /* I can't figure out why I have to do the following */
+ g_variant_unref(attributes);
+ g_variant_unref(secret);
}
return succ;
--
1.7.11.4
11 years, 7 months
[LIBREPORT PATCH] build: optional build of ureport plugin
by Nikola Pajkovsky
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
configure.ac | 15 ++++++++++-----
src/lib/Makefile.am | 8 ++++++--
src/plugins/Makefile.am | 23 +++++++++++++++++------
3 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac
index d6c877a..27d9680 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,10 +43,6 @@ AC_ARG_ENABLE(debug,
[Enable debug information])],
[CFLAGS="$CFLAGS -DDEBUG -ggdb -g -O0"])
-AC_ARG_ENABLE([bodhi],
- AC_HELP_STRING([--disable-bodhi], [do not use bodhi plugin]))
-
-
dnl ****** INTERNATIONALIZATION **********************
GETTEXT_PACKAGE=libreport
AC_SUBST(GETTEXT_PACKAGE)
@@ -132,13 +128,22 @@ PKG_CHECK_MODULES([DBUS], [dbus-1])
PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
PKG_CHECK_MODULES([NSS], [nss])
PKG_CHECK_MODULES([CURL], [libcurl])
-PKG_CHECK_MODULES([JSON_C], [json])
PKG_CHECK_MODULES([BTPARSER], [btparser])
PKG_CHECK_MODULES([NEWT], [libnewt])
PKG_CHECK_MODULES([PROXY], [libproxy-1.0], [
AC_DEFINE([HAVE_PROXY], [1], [Use libproxy])
], [:])
+AC_ARG_WITH(ureport,
+AS_HELP_STRING([--with-ureport],[use uReport plugin (default is YES)]),
+LIBREPORT_PARSE_WITH([ureport]))
+if test -z "$NO_UREPORT"; then
+AM_CONDITIONAL(BUILD_UREPORT, true)
+PKG_CHECK_MODULES([JSON_C], [json])
+else
+AM_CONDITIONAL(BUILD_UREPORT, false)
+fi dnl end NO_UREPORT
+
PKG_PROG_PKG_CONFIG
AC_CHECK_HEADER([libtar.h], [],
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 50ff9ae..5345950 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -93,10 +93,14 @@ if BUILD_BUGZILLA
libreport_web_o += abrt_xmlrpc.h abrt_xmlrpc.c
endif
+if BUILD_UREPORT
+libreport_web_o += ureport.h json.c
+endif
+
libreport_web_la_SOURCES = $(libreport_web_o) \
curl.c \
- proxies.h proxies.c \
- ureport.h json.c
+ proxies.h proxies.c
+
libreport_web_la_CPPFLAGS = \
-I$(srcdir)/../include \
-DLOCALSTATEDIR='"$(localstatedir)"' \
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index edd4f1a..0d8a978 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -5,14 +5,17 @@ if BUILD_BUGZILLA
reporters_bin += reporter-bugzilla
endif
+if BUILD_UREPORT
+reporters_bin += reporter-ureport
+endif
+
bin_PROGRAMS = $(reporters_bin) \
reporter-rhtsupport \
reporter-kerneloops \
reporter-upload \
reporter-mailx \
reporter-print \
- report \
- reporter-ureport
+ report
pluginsconfdir = $(PLUGINS_CONF_DIR)
@@ -34,14 +37,17 @@ if BUILD_BUGZILLA
reporters_events += report_Bugzilla.xml report_Bugzilla.conf
endif
+if BUILD_UREPORT
+reporters_events += report_uReport.xml
+endif
+
dist_events_DATA = $(reporters_events) \
report_Logger.conf \
report_Logger.xml \
report_Mailx.xml \
report_RHTSupport.xml \
report_Kerneloops.xml \
- report_Uploader.xml \
- report_uReport.xml
+ report_Uploader.xml
@INTLTOOL_XML_RULE@
@@ -59,14 +65,17 @@ if BUILD_BUGZILLA
reporters_extra_dist += report_Bugzilla.xml.in report_Bugzilla.conf
endif
+if BUILD_UREPORT
+reporters_extra_dist += report_uReport.xml.in
+endif
+
EXTRA_DIST = $(reporters_extra_dist) \
report_Logger.conf \
report_Logger.xml.in \
report_Mailx.xml.in \
report_RHTSupport.xml.in \
report_Kerneloops.xml.in \
- report_Uploader.xml.in \
- report_uReport.xml.in
+ report_Uploader.xml.in
$(DESTDIR)/$(DEBUG_INFO_DIR):
$(mkdir_p) '$@'
@@ -214,6 +223,7 @@ report_CPPFLAGS = \
report_LDADD = \
../lib/libreport.la
+if BUILD_UREPORT
reporter_ureport_SOURCES = \
ureport.c
reporter_ureport_CPPFLAGS = \
@@ -225,5 +235,6 @@ reporter_ureport_CPPFLAGS = \
reporter_ureport_LDADD = \
../lib/libreport.la \
../lib/libreport-web.la
+endif
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
--
1.7.12
11 years, 7 months
[Automatic Bug Reporting Tool - ABRT] #753: create a query to get weekly stats about problems
by fedora-badges
#753: create a query to get weekly stats about problems
----------------------+------------------------------
Reporter: jmoskovc | Owner: crash-catcher@…
Type: defect | Status: new
Priority: major | Milestone: ABRT_Server_R2
Component: abrt | Version:
Keywords: | Blocked By:
Blocking: |
----------------------+------------------------------
A weekly stats sent to fedora-devel would provide a great info about the
overall distro/component stabilization/destabilization which devels can
use to prioritize their work:
- it should contain:
- info about most destabilized components (components with highest
problem trend)
- info about most stabilized components (components with decreased
problem trend)
- top 20 (10?) crashes (yes, it's the same as hot problems)
- top 5 (10?) long lasting issues
--
Ticket URL: <https://fedorahosted.org/abrt/ticket/753>
Automatic Bug Reporting Tool - ABRT <http://fedorahoted.org/abrt/>
Automatic bug reporting tool
11 years, 7 months
[PATCH] core-backtrace: parse C++ functions correctly
by Michal Toman
---
lib/core-backtrace.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/lib/core-backtrace.c b/lib/core-backtrace.c
index a97c3da..d026758 100644
--- a/lib/core-backtrace.c
+++ b/lib/core-backtrace.c
@@ -183,9 +183,52 @@ btp_load_core_backtrace(const char *text)
frame->address = (uint64_t)off;
/* SYMBOL */
- char *symbol = read_string(&cur);
+ /* may contain spaces! RHBZ #857475 */
+ /* if ( character is found, we do not stop on white space, but on ) */
+ /* parentheses may be nested, we need to consider the depth */
+ btp_skip_whitespace(cur);
+ char lastchar = ' ';
+ char *end;
+ int depth = 0;
+ for (end = cur; *end && *end != '\n' && (*end != lastchar || depth > 1); ++end)
+ {
+ switch (*end)
+ {
+ case '(':
+ lastchar = ')';
+ ++depth;
+ break;
+
+ case ')':
+ --depth;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (*end)
+ {
+ /* jump one character to also show ) */
+ case ')':
+ ++end;
+ break;
+
+ case ' ':
+ break;
+
+ /* error - we are on \n or \0 */
+ default:
+ btp_thread_free(thread);
+ return NULL;
+ }
+
/* btparser uses "??" to denote unknown function name */
- frame->function_name = (symbol ? symbol : btp_strdup("??"));
+ *end = '\0';
+ frame->function_name = btp_strdup(strcmp(cur, "-") ? cur : "??");
+ *end = ' ';
+ cur = end;
/* FILENAME */
aux->filename = read_string(&cur);
--
1.7.1
11 years, 7 months
[PATCH] added error callback to get notification about download failure rhbz#786640
by Jiri Moskovcak
- otherwise the information *why* the download is failing is
not propagated to the gui and users don't know what's wrong
---
src/client-python/debuginfo.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/client-python/debuginfo.py b/src/client-python/debuginfo.py
index 72bbadb..c9e81cd 100644
--- a/src/client-python/debuginfo.py
+++ b/src/client-python/debuginfo.py
@@ -131,6 +131,13 @@ class MyDownloadCallback(DownloadBaseCallback):
sys.stdout.flush()
+def downloadErrorCallback(callBackObj):
+ print _("Problem '{0!s}' occured while downloading from mirror: '{1!s}'. Trying next one").format(
+ callBackObj.exception, callBackObj.mirror)
+ # explanation of the return value can be found here:
+ # /usr/lib/python2.7/site-packages/urlgrabber/mirror.py
+ return {'fail':0}
+
class DebugInfoDownload(YumBase):
def __init__(self, cache, tmp, keep_rpms=False, noninteractive=True):
self.cachedir = cache
@@ -257,6 +264,7 @@ class DebugInfoDownload(YumBase):
# connect our progress update callback
dnlcb = MyDownloadCallback(total_pkgs)
self.repos.setProgressBar(dnlcb)
+ self.repos.setMirrorFailureCallback(downloadErrorCallback)
if verbose != 0 or len(not_found) != 0:
print _("Can't find packages for {0} debuginfo files").format(len(not_found))
--
1.7.11.4
11 years, 7 months