summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-06-01 17:57:31 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2011-06-01 17:57:31 +0200
commit2fa751f6d98995e73db4d0edd0d22b9560281644 (patch)
treecc5ed9575493d38d19db783324d329d2e43fe94d
parentf4e4a76f3ca70f0bad636e324c43d3da993df854 (diff)
downloadabrt-2fa751f6d98995e73db4d0edd0d22b9560281644.zip
abrt-2fa751f6d98995e73db4d0edd0d22b9560281644.tar.gz
abrt-2fa751f6d98995e73db4d0edd0d22b9560281644.tar.xz
wizard: hook selection checkboxes to reporters.
Checkboxes are controlled by the following elements in .xml: <requires-items> ITEM1,ITEM2 </requires-items> <exclude-items-by-default> ITEM1,ITEM2 </exclude-items-by-default> <exclude-items-always> ITEM1,ITEM2 </exclude-items-always> <exclude-binary-items> yes / no </exclude-binary-items> <include-items-by-default> ITEM1,ITEM2 </include-items-by-default> exclude-items-by-default and exclude-items-always can be "*" meaning "all". include-items-by-default specifies which items are included (checked) is exclude-items-by-default is "*". Else, all are checked by default. the set of iters NOT included is passed in $EXCLUDE_FROM_REPORT variable. bugzilla, kerneloops, mailx, print and rhtsupport are made aware of this variable. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r--src/gtk-helpers/event_config_dialog.c4
-rw-r--r--src/gtk-helpers/libreport-gtk.h3
-rw-r--r--src/gui-wizard-gtk/main.c29
-rw-r--r--src/gui-wizard-gtk/wizard.c177
-rw-r--r--src/include/report/event_config.h13
-rw-r--r--src/include/report/problem_data.h9
-rw-r--r--src/lib/event_config.c13
-rw-r--r--src/lib/event_xml_parser.c45
-rw-r--r--src/lib/problem_data.c79
-rw-r--r--src/lib/report.c2
-rw-r--r--src/lib/run_event.c2
-rw-r--r--src/plugins/abrt-action-bugzilla.c17
-rw-r--r--src/plugins/abrt-action-kerneloops.c11
-rw-r--r--src/plugins/abrt-action-mailx.c11
-rw-r--r--src/plugins/abrt-action-print.c11
-rw-r--r--src/plugins/abrt-action-rhtsupport.c11
-rw-r--r--src/plugins/analyze_LocalGDB.xml.in2
-rw-r--r--src/plugins/analyze_RetraceServer.xml.in2
-rw-r--r--src/plugins/analyze_xsession_errors.xml.in2
-rw-r--r--src/plugins/report_Bugzilla.xml.in7
20 files changed, 366 insertions, 84 deletions
diff --git a/src/gtk-helpers/event_config_dialog.c b/src/gtk-helpers/event_config_dialog.c
index 5010e31..769dbf6 100644
--- a/src/gtk-helpers/event_config_dialog.c
+++ b/src/gtk-helpers/event_config_dialog.c
@@ -420,7 +420,7 @@ void show_events_list_dialog(GtkWindow *parent)
gtk_widget_show_all(event_list_window);
}
-void show_event_opt_error_dialog(const char *event_name)
+static void show_event_opt_error_dialog(const char *event_name)
{
event_config_t *ec = get_event_config(event_name);
char *message = xasprintf(_("Wrong settings detected for %s, "
@@ -445,6 +445,8 @@ void show_event_opt_error_dialog(const char *event_name)
gtk_widget_destroy(wrong_settings);
}
+//TODO: move this code to its only callsite?
+// (in which case, move show_event_opt_error_dialog and g_parent_window too)
void g_validate_event(const char* event_name)
{
GHashTable *errors = validate_event(event_name);
diff --git a/src/gtk-helpers/libreport-gtk.h b/src/gtk-helpers/libreport-gtk.h
index 9395c55..ff19ab7 100644
--- a/src/gtk-helpers/libreport-gtk.h
+++ b/src/gtk-helpers/libreport-gtk.h
@@ -19,10 +19,11 @@
#include "report.h"
-void show_events_list_dialog(GtkWindow *parent);
void make_label_autowrap_on_resize(GtkLabel *label);
void fix_all_wrapped_labels(GtkWidget *widget);
+void show_events_list_dialog(GtkWindow *parent);
+
void abrt_keyring_save_settings(const char *event_name);
void load_event_config_data_from_keyring();
void g_validate_event(const char* event_name);
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c
index cd100ac..de47f82 100644
--- a/src/gui-wizard-gtk/main.c
+++ b/src/gui-wizard-gtk/main.c
@@ -35,7 +35,6 @@ problem_data_t *g_cd;
void reload_problem_data_from_dump_dir(void)
{
- free_problem_data(g_cd);
free(g_analyze_events);
free(g_report_events);
@@ -43,13 +42,37 @@ void reload_problem_data_from_dump_dir(void)
if (!dd)
xfunc_die(); /* dd_opendir already logged error msg */
- g_cd = create_problem_data_from_dump_dir(dd);
- add_to_problem_data_ext(g_cd, CD_DUMPDIR, g_dump_dir_name, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE);
+ problem_data_t *new_cd = create_problem_data_from_dump_dir(dd);
+ add_to_problem_data_ext(new_cd, CD_DUMPDIR, g_dump_dir_name, (CD_FLAG_TXT | CD_FLAG_ISNOTEDITABLE));
g_analyze_events = list_possible_events(dd, NULL, "analyze");
g_report_events = list_possible_events(dd, NULL, "report");
dd_close(dd);
+ if (1)
+ {
+ /* Copy "selected for reporting" flags */
+ GHashTableIter iter;
+ char *name;
+ struct problem_item *new_item;
+ g_hash_table_iter_init(&iter, new_cd);
+ while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&new_item))
+ {
+ struct problem_item *old_item = g_cd ? get_problem_data_item_or_NULL(g_cd, name) : NULL;
+ if (old_item)
+ {
+ new_item->selected_by_user = old_item->selected_by_user;
+ }
+ else
+ {
+ new_item->selected_by_user = 0;
+ }
+ //log("%s: was ->selected_by_user=%d", __func__, new_item->selected_by_user);
+ }
+ free_problem_data(g_cd);
+ }
+ g_cd = new_cd;
+
/* Load /etc/abrt/events/foo.{conf,xml} stuff */
load_event_config_data();
load_event_config_data_from_keyring();
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 12e6a81..4703a99 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -39,6 +39,7 @@ typedef struct event_gui_data_t
static GtkAssistant *g_assistant;
static char *g_analyze_event_selected;
+static char *g_reporter_events_selected;
static unsigned g_black_event_count = 0;
static GtkBox *g_box_analyzers;
@@ -367,7 +368,9 @@ static struct problem_item *get_current_problem_item_or_NULL(GtkTreeView *tree_v
return NULL;
*pp_item_name = NULL;
- gtk_tree_model_get(model, &iter, DETAIL_COLUMN_NAME, pp_item_name, -1);
+ gtk_tree_model_get(model, &iter,
+ DETAIL_COLUMN_NAME, pp_item_name,
+ -1);
if (!*pp_item_name) /* paranoia, should never happen */
return NULL;
struct problem_item *item = get_problem_data_item_or_NULL(g_cd, *pp_item_name);
@@ -438,7 +441,9 @@ static void g_tv_details_checkbox_toggled(
return;
gchar *item_name = NULL;
- gtk_tree_model_get(GTK_TREE_MODEL(g_ls_details), &iter, DETAIL_COLUMN_NAME, &item_name, -1);
+ gtk_tree_model_get(GTK_TREE_MODEL(g_ls_details), &iter,
+ DETAIL_COLUMN_NAME, &item_name,
+ -1);
if (!item_name) /* paranoia, should never happen */
return;
struct problem_item *item = get_problem_data_item_or_NULL(g_cd, item_name);
@@ -446,11 +451,27 @@ static void g_tv_details_checkbox_toggled(
if (!item) /* paranoia */
return;
- item->flags ^= 0x8000000;
- //log("%s: item->flags=%x", __func__, item->flags);
- gtk_list_store_set(g_ls_details, &iter,
- DETAIL_COLUMN_CHECKBOX, !!(item->flags & 0x8000000),
+ int cur_value;
+ if (item->selected_by_user == 0)
+ cur_value = item->default_by_reporter;
+ else
+ cur_value = !!(item->selected_by_user + 1); /* map -1,1 to 0,1 */
+ //log("%s: allowed:%d reqd:%d def:%d user:%d cur:%d", __func__,
+ // item->allowed_by_reporter,
+ // item->required_by_reporter,
+ // item->default_by_reporter,
+ // item->selected_by_user,
+ // cur_value
+ //);
+ if (item->allowed_by_reporter && !item->required_by_reporter)
+ {
+ cur_value = !cur_value;
+ item->selected_by_user = cur_value * 2 - 1; /* map 0,1 to -1,1 */
+ //log("%s: now ->selected_by_user=%d", __func__, item->selected_by_user);
+ gtk_list_store_set(g_ls_details, &iter,
+ DETAIL_COLUMN_CHECKBOX, cur_value,
-1);
+ }
}
@@ -498,9 +519,9 @@ static void report_tb_was_toggled(GtkButton *button_unused, gpointer user_data_u
);
/* Update "list of reporters" label */
- char *str = strbuf_free_nobuf(reporters_string);
- gtk_label_set_text(g_lbl_reporters, str);
- free(str);
+ free(g_reporter_events_selected);
+ g_reporter_events_selected = strbuf_free_nobuf(reporters_string);
+ gtk_label_set_text(g_lbl_reporters, g_reporter_events_selected);
}
/* event_name contains "EVENT1\nEVENT2\nEVENT3\n".
@@ -550,12 +571,12 @@ static event_gui_data_t *add_event_buttons(GtkBox *box,
if (cfg->screen_name)
event_screen_name = cfg->screen_name;
event_description = cfg->description;
- if (cfg->creates_elements)
+ if (cfg->ec_creates_items)
{
- if (get_problem_data_item_or_NULL(g_cd, cfg->creates_elements))
+ if (get_problem_data_item_or_NULL(g_cd, cfg->ec_creates_items))
{
green_choice = true;
- event_description = tmp_description = xasprintf(_("(not needed, '%s' already exists)"), cfg->creates_elements);
+ event_description = tmp_description = xasprintf(_("(not needed, '%s' already exists)"), cfg->ec_creates_items);
}
}
}
@@ -800,6 +821,42 @@ enum {
LOGSTATE_MIDLINE,
};
+static void set_excluded_envvar(void)
+{
+ struct strbuf *item_list = strbuf_new();
+ const char *fmt = "%s";
+
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(g_ls_details), &iter))
+ {
+ do {
+ gchar *item_name = NULL;
+ gboolean checked = 0;
+ gtk_tree_model_get(GTK_TREE_MODEL(g_ls_details), &iter,
+ DETAIL_COLUMN_NAME, &item_name,
+ DETAIL_COLUMN_CHECKBOX, &checked,
+ -1);
+ if (!item_name) /* paranoia, should never happen */
+ continue;
+ if (!checked)
+ {
+ strbuf_append_strf(item_list, fmt, item_name);
+ fmt = ",%s";
+ }
+ g_free(item_name);
+ } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(g_ls_details), &iter));
+ }
+ char *var = strbuf_free_nobuf(item_list);
+ //log("EXCLUDE_FROM_REPORT='%s'", var);
+ if (var)
+ {
+ xsetenv("EXCLUDE_FROM_REPORT", var);
+ free(var);
+ }
+ else
+ unsetenv("EXCLUDE_FROM_REPORT");
+}
+
static int spawn_next_command_in_evd(struct analyze_event_data *evd)
{
evd->env_list = export_event_config(evd->event_name);
@@ -1041,7 +1098,9 @@ static void start_event_run(const char *event_name,
if (!locked)
return; /* user refused to steal, or write error, etc... */
+ set_excluded_envvar();
GList *env_list = export_event_config(event_name);
+
if (spawn_next_command(state, g_dump_dir_name, event_name) < 0)
{
unexport_event_config(env_list);
@@ -1266,6 +1325,23 @@ static void log_ready_state()
}
#endif
+static bool is_in_comma_separated_list(const char *value, const char *list)
+{
+ if (!list)
+ return false;
+ unsigned len = strlen(value);
+ while (*list)
+ {
+ const char *comma = strchrnul(list, ',');
+ if ((comma - list == len) && strncmp(value, list, len) == 0)
+ return true;
+ if (!*comma)
+ break;
+ list = comma + 1;
+ }
+ return false;
+}
+
static void on_page_prepare(GtkAssistant *assistant, GtkWidget *page, gpointer user_data)
{
//int page_no = gtk_assistant_get_current_page(g_assistant);
@@ -1310,6 +1386,83 @@ static void on_page_prepare(GtkAssistant *assistant, GtkWidget *page, gpointer u
//gtk_cell_renderer_set_visible(g_tv_details_renderer_checkbox,
// (pages[PAGENO_REVIEW_DATA].page_widget == page)
//);
+
+ if (pages[PAGENO_REVIEW_DATA].page_widget == page)
+ {
+ /* Based on selected reporter, update item checkboxes */
+ event_config_t *cfg = get_event_config(g_reporter_events_selected ? g_reporter_events_selected : "");
+ //log("%s: event:'%s', cfg:'%p'", __func__, g_reporter_events_selected, cfg);
+ if (cfg)
+ {
+ /* Default settings are... */
+ int allowed_by_reporter = 1;
+ if (cfg->ec_exclude_items_always && strcmp(cfg->ec_exclude_items_always, "*") == 0)
+ allowed_by_reporter = 0;
+ int default_by_reporter = allowed_by_reporter;
+ if (cfg->ec_exclude_items_by_default && strcmp(cfg->ec_exclude_items_by_default, "*") == 0)
+ default_by_reporter = 0;
+
+ GHashTableIter iter;
+ char *name;
+ struct problem_item *item;
+ g_hash_table_iter_init(&iter, g_cd);
+ while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&item))
+ {
+ /* Decide whether item is allowed, required, and what's the default */
+ item->allowed_by_reporter = allowed_by_reporter;
+ if (is_in_comma_separated_list(name, cfg->ec_exclude_items_always))
+ item->allowed_by_reporter = 0;
+ if ((item->flags & CD_FLAG_BIN) && cfg->ec_exclude_binary_items)
+ item->allowed_by_reporter = 0;
+
+ item->default_by_reporter = item->allowed_by_reporter ? default_by_reporter : 0;
+ if (is_in_comma_separated_list(name, cfg->ec_exclude_items_by_default))
+ item->default_by_reporter = 0;
+ if (is_in_comma_separated_list(name, cfg->ec_include_items_by_default))
+ item->allowed_by_reporter = item->default_by_reporter = 1;
+
+ item->required_by_reporter = 0;
+ if (is_in_comma_separated_list(name, cfg->ec_requires_items))
+ item->default_by_reporter = item->allowed_by_reporter = item->required_by_reporter = 1;
+
+ int cur_value;
+ if (item->selected_by_user == 0)
+ cur_value = item->default_by_reporter;
+ else
+ cur_value = !!(item->selected_by_user + 1); /* map -1,1 to 0,1 */
+
+ //log("%s: '%s' allowed:%d reqd:%d def:%d user:%d", __func__, name,
+ // item->allowed_by_reporter,
+ // item->required_by_reporter,
+ // item->default_by_reporter,
+ // item->selected_by_user
+ //);
+
+ /* Find corresponding line and update checkbox */
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(g_ls_details), &iter))
+ {
+ do {
+ gchar *item_name = NULL;
+ gtk_tree_model_get(GTK_TREE_MODEL(g_ls_details), &iter,
+ DETAIL_COLUMN_NAME, &item_name,
+ -1);
+ if (!item_name) /* paranoia, should never happen */
+ continue;
+ int differ = strcmp(name, item_name);
+ g_free(item_name);
+ if (differ)
+ continue;
+ gtk_list_store_set(g_ls_details, &iter,
+ DETAIL_COLUMN_CHECKBOX, cur_value,
+ -1);
+ //log("%s: changed gtk_list_store_set to %d", __func__, (item->allowed_by_reporter && item->selected_by_user >= 0));
+ break;
+ } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(g_ls_details), &iter));
+ }
+ }
+ }
+ }
}
if (pages[PAGENO_EDIT_COMMENT].page_widget == page)
diff --git a/src/include/report/event_config.h b/src/include/report/event_config.h
index 2e2783d..8ab9477 100644
--- a/src/include/report/event_config.h
+++ b/src/include/report/event_config.h
@@ -66,12 +66,17 @@ void free_event_option(event_option_t *p);
//structure to hold the option data
typedef struct
{
- char *screen_name; //ui friendly name of the event: "Bugzilla" "RedHat Support Upload"
- //char *title; //window title - not used right now, maybe the "name" is enough?
- //char *action; //action description to show in gui like: Upload report to the Red Hat bugzilla"
+ char *screen_name; //ui friendly name of the event: "Bugzilla" "RedHat Support Upload"
char *description; // "Report to..."/"Save to file". Should be one sentence, not long
char *long_descr; // Long(er) explanation, if needed
- char *creates_elements;
+
+ char *ec_creates_items;
+ char *ec_requires_items;
+ char *ec_exclude_items_by_default;
+ char *ec_include_items_by_default;
+ char *ec_exclude_items_always;
+ bool ec_exclude_binary_items;
+
GList *options;
} event_config_t;
diff --git a/src/include/report/problem_data.h b/src/include/report/problem_data.h
index f717807..31ef7d2 100644
--- a/src/include/report/problem_data.h
+++ b/src/include/report/problem_data.h
@@ -40,6 +40,11 @@ enum {
struct problem_item {
char *content;
unsigned flags;
+ /* Used by UI for presenting "item allowed/not allowed" checkboxes: */
+ int selected_by_user; /* 0 "don't know", -1 "no", 1 "yes" */
+ int allowed_by_reporter; /* 0 "no", 1 "yes" */
+ int default_by_reporter; /* 0 "no", 1 "yes" */
+ int required_by_reporter; /* 0 "no", 1 "yes" */
};
typedef struct problem_item problem_item;
@@ -80,8 +85,10 @@ const char *get_problem_item_content_or_die(problem_data_t *problem_data, const
/* Conversions between in-memory and on-disk formats */
-void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd);
+void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd, char **excluding);
problem_data_t *create_problem_data_from_dump_dir(struct dump_dir *dd);
+/* Helper for typical operation in reporters: */
+problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name);
struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name);
diff --git a/src/lib/event_config.c b/src/lib/event_config.c
index 9f48af5..38da44e 100644
--- a/src/lib/event_config.c
+++ b/src/lib/event_config.c
@@ -46,19 +46,22 @@ void free_event_option(event_option_t *p)
void free_event_config(event_config_t *p)
{
- GList *opt;
-
if (!p)
return;
+
free(p->screen_name);
- //free(p->title);
- //free(p->action);
free(p->description);
free(p->long_descr);
- free(p->creates_elements);
+ free(p->ec_creates_items);
+ free(p->ec_requires_items);
+ free(p->ec_exclude_items_by_default);
+ free(p->ec_include_items_by_default);
+ free(p->ec_exclude_items_always);
+ GList *opt;
for (opt = p->options; opt; opt = opt->next)
free_event_option(opt->data);
g_list_free(p->options);
+
free(p);
}
diff --git a/src/lib/event_xml_parser.c b/src/lib/event_xml_parser.c
index 5bf5f41..b2037cd 100644
--- a/src/lib/event_xml_parser.c
+++ b/src/lib/event_xml_parser.c
@@ -25,12 +25,19 @@
#define LONG_DESCR_ELEMENT "long-description"
#define ALLOW_EMPTY_ELEMENT "allow-empty"
#define NOTE_HTML_ELEMENT "note-html"
-#define CREATES_ELEMENT "creates-elements"
+#define CREATES_ELEMENT "creates-items"
#define OPTION_ELEMENT "option"
//#define ACTION_ELEMENT "action"
#define NAME_ELEMENT "name"
#define DEFAULT_VALUE_ELEMENT "default-value"
+#define REQUIRES_ELEMENT "requires-items"
+#define EXCL_BY_DEFAULT_ELEMENT "exclude-items-by-default"
+#define INCL_BY_DEFAULT_ELEMENT "include-items-by-default"
+#define EXCL_ALWAYS_ELEMENT "exclude-items-always"
+#define EXCL_BINARY_ELEMENT "exclude-binary-items"
+
+
struct my_parse_data
{
event_config_t *event_config;
@@ -305,9 +312,9 @@ static void text(GMarkupParseContext *context,
*/
if (strcmp(inner_element, CREATES_ELEMENT) == 0)
{
- VERB2 log("creates_elements:'%s'", text_copy);
- free(ui->creates_elements);
- ui->creates_elements = text_copy;
+ VERB2 log("ec_creates_items:'%s'", text_copy);
+ free(ui->ec_creates_items);
+ ui->ec_creates_items = text_copy;
return;
}
if (strcmp(inner_element, NAME_ELEMENT) == 0)
@@ -363,6 +370,36 @@ static void text(GMarkupParseContext *context,
}
return;
}
+ if (strcmp(inner_element, REQUIRES_ELEMENT) == 0)
+ {
+ free(ui->ec_requires_items);
+ ui->ec_requires_items = text_copy;
+ return;
+ }
+ if (strcmp(inner_element, EXCL_BY_DEFAULT_ELEMENT) == 0)
+ {
+ free(ui->ec_exclude_items_by_default);
+ ui->ec_exclude_items_by_default = text_copy;
+ return;
+ }
+ if (strcmp(inner_element, INCL_BY_DEFAULT_ELEMENT) == 0)
+ {
+ free(ui->ec_include_items_by_default);
+ ui->ec_include_items_by_default = text_copy;
+ return;
+ }
+ if (strcmp(inner_element, EXCL_ALWAYS_ELEMENT) == 0)
+ {
+ free(ui->ec_exclude_items_always);
+ ui->ec_exclude_items_always = text_copy;
+ return;
+ }
+ if (strcmp(inner_element, EXCL_BINARY_ELEMENT) == 0)
+ {
+ ui->ec_exclude_binary_items = string_to_bool(text_copy);
+ free(text_copy);
+ return;
+ }
}
free(text_copy);
}
diff --git a/src/lib/problem_data.c b/src/lib/problem_data.c
index 87821af..7ef1f68 100644
--- a/src/lib/problem_data.c
+++ b/src/lib/problem_data.c
@@ -265,7 +265,7 @@ static char* is_text_file(const char *name, ssize_t *sz)
return NULL; /* it's binary */
}
-void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd)
+void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd, char **excluding)
{
char *short_name;
char *full_name;
@@ -273,6 +273,12 @@ void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_d
dd_init_next_file(dd);
while (dd_get_next_file(dd, &short_name, &full_name))
{
+ if (excluding && is_in_string_list(short_name, excluding))
+ {
+ //log("Excluded:'%s'", short_name);
+ goto next;
+ }
+
ssize_t sz = 4*1024;
char *text = NULL;
bool editable = is_editable_file(short_name);
@@ -287,20 +293,15 @@ void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_d
full_name,
CD_FLAG_BIN + CD_FLAG_ISNOTEDITABLE
);
- free(short_name);
- free(full_name);
- continue;
+ goto next;
}
}
char *content;
if (sz < 4*1024) /* did is_text_file read entire file? */
{
+ /* yes */
content = text;
- /* Strip '\n' from one-line elements: */
- char *nl = strchr(content, '\n');
- if (nl && nl[1] == '\0')
- *nl = '\0';
}
else
{
@@ -308,6 +309,10 @@ void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_d
free(text);
content = dd_load_text(dd, short_name);
}
+ /* Strip '\n' from one-line elements: */
+ char *nl = strchr(content, '\n');
+ if (nl && nl[1] == '\0')
+ *nl = '\0';
int flags = 0;
@@ -335,16 +340,70 @@ void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_d
content,
flags
);
+ free(content);
+ next:
free(short_name);
free(full_name);
- free(content);
}
}
problem_data_t *create_problem_data_from_dump_dir(struct dump_dir *dd)
{
problem_data_t *problem_data = new_problem_data();
- load_problem_data_from_dump_dir(problem_data, dd);
+ load_problem_data_from_dump_dir(problem_data, dd, NULL);
+ return problem_data;
+}
+
+/*
+ * Returns NULL-terminated char *vector[]. Result itself must be freed,
+ * but do no free list elements. IOW: do free(result), but never free(result[i])!
+ * If comma_separated_list is NULL or "", returns NULL.
+ */
+static char **build_exclude_vector(const char *comma_separated_list)
+{
+ char **exclude_items = NULL;
+ if (comma_separated_list && comma_separated_list[0])
+ {
+ /* even w/o commas, we'll need two elements:
+ * exclude_items[0] = "name"
+ * exclude_items[1] = NULL
+ */
+ unsigned cnt = 2;
+
+ const char *cp = comma_separated_list;
+ while (*cp)
+ if (*cp++ == ',')
+ cnt++;
+
+ /* We place the string directly after the char *vector[cnt]: */
+ exclude_items = xzalloc(cnt * sizeof(exclude_items[0]) + (cp - comma_separated_list) + 1);
+ char *p = strcpy((char*)&exclude_items[cnt], comma_separated_list);
+
+ char **pp = exclude_items;
+ *pp++ = p;
+ while (*p)
+ {
+ if (*p++ == ',')
+ {
+ p[-1] = '\0';
+ *pp++ = p;
+ }
+ }
+ }
+
+ return exclude_items;
+}
+
+problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name)
+{
+ char **exclude_items = build_exclude_vector(getenv("EXCLUDE_FROM_REPORT"));
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ if (!dd)
+ return NULL; /* dd_opendir already emitted error msg */
+ problem_data_t *problem_data = new_problem_data();
+ load_problem_data_from_dump_dir(problem_data, dd, exclude_items);
+ dd_close(dd);
+ free(exclude_items);
return problem_data;
}
diff --git a/src/lib/report.c b/src/lib/report.c
index 07299e4..137f7b1 100644
--- a/src/lib/report.c
+++ b/src/lib/report.c
@@ -114,7 +114,7 @@ int report_problem_in_memory(problem_data_t *pd, int flags)
if (dd)
{
if (flags & LIBREPORT_RELOAD_DATA)
- load_problem_data_from_dump_dir(pd, dd);
+ load_problem_data_from_dump_dir(pd, dd, NULL);
dd_delete(dd);
}
}
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
index 856f326..0d29128 100644
--- a/src/lib/run_event.c
+++ b/src/lib/run_event.c
@@ -500,7 +500,7 @@ int run_event_on_problem_data(struct run_event_state *state, problem_data_t *dat
free(dir_name);
if (dd)
{
- load_problem_data_from_dump_dir(data, dd);
+ load_problem_data_from_dump_dir(data, dd, NULL);
dd_delete(dd);
}
diff --git a/src/plugins/abrt-action-bugzilla.c b/src/plugins/abrt-action-bugzilla.c
index 9290112..956e11e 100644
--- a/src/plugins/abrt-action-bugzilla.c
+++ b/src/plugins/abrt-action-bugzilla.c
@@ -22,15 +22,13 @@
#include "abrt_xmlrpc.h"
#include "rhbz.h"
-#define XML_RPC_SUFFIX "/xmlrpc.cgi"
+#define XML_RPC_SUFFIX "/xmlrpc.cgi"
static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings)
{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- xfunc_die(); /* dd_opendir already emitted error msg */
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
+ problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
+ if (!problem_data)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
const char *env;
const char *login;
@@ -100,7 +98,7 @@ static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings
VERB3 log("Bugzilla has %i reports with same duphash '%s'",
all_bugs_size, duphash);
- int bug_id = -1, dependent_bug = -1;
+ int bug_id = -1;
struct bug_info *bz = NULL;
if (all_bugs_size > 0)
{
@@ -110,7 +108,6 @@ static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings
if (strcmp(bz->bi_product, product) != 0)
{
- dependent_bug = bug_id;
/* found something, but its a different product */
free_bug_info(bz);
@@ -209,7 +206,7 @@ static void report_to_bugzilla(const char *dump_dir_name, map_string_h *settings
bugzilla_url,
bz->bi_id);
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
char *msg = xasprintf("Bugzilla: URL=%s/show_bug.cgi?id=%u", bugzilla_url, bz->bi_id);
@@ -233,7 +230,7 @@ int main(int argc, char **argv)
/* Can't keep these strings/structs static: _() doesn't support that */
const char *program_usage_string = _(
- "\b [-v] -c CONFFILE -d DIR\n"
+ "\b [-v] [-c CONFFILE] -d DIR\n"
"\n"
"Reports problem to Bugzilla.\n"
"\n"
diff --git a/src/plugins/abrt-action-kerneloops.c b/src/plugins/abrt-action-kerneloops.c
index 99b2fea..b8f4337 100644
--- a/src/plugins/abrt-action-kerneloops.c
+++ b/src/plugins/abrt-action-kerneloops.c
@@ -84,12 +84,9 @@ static void report_to_kerneloops(
const char *dump_dir_name,
map_string_h *settings)
{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- exit(1); /* error msg is already logged */
-
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
+ problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
+ if (!problem_data)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
const char *backtrace = get_problem_item_content_or_NULL(problem_data, FILENAME_BACKTRACE);
if (!backtrace)
@@ -113,7 +110,7 @@ static void report_to_kerneloops(
* RemoteIP: 34192fd15e34bf60fac6a5f01bba04ddbd3f0558
* - no URL or bug ID apparently...
*/
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
char *msg = xasprintf("kerneloops: URL=%s", submitURL);
diff --git a/src/plugins/abrt-action-mailx.c b/src/plugins/abrt-action-mailx.c
index 2118085..d513fbb 100644
--- a/src/plugins/abrt-action-mailx.c
+++ b/src/plugins/abrt-action-mailx.c
@@ -59,12 +59,9 @@ static void create_and_send_email(
const char *dump_dir_name,
map_string_h *settings)
{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- exit(1); /* error msg is already logged by dd_opendir */
-
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
+ problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
+ if (!problem_data)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
char* env;
env = getenv("Mailx_Subject");
@@ -116,7 +113,7 @@ static void create_and_send_email(
free_problem_data(problem_data);
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
char *msg = xasprintf("email: %s", email_to);
diff --git a/src/plugins/abrt-action-print.c b/src/plugins/abrt-action-print.c
index d433fa5..0de1fbe 100644
--- a/src/plugins/abrt-action-print.c
+++ b/src/plugins/abrt-action-print.c
@@ -64,12 +64,9 @@ int main(int argc, char **argv)
perror_msg_and_die("Can't open '%s'", output_file);
}
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- return 1; /* error message is already logged */
-
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
+ problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
+ if (!problem_data)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
char *dsc = make_description_logger(problem_data);
fputs(dsc, stdout);
@@ -82,7 +79,7 @@ int main(int argc, char **argv)
{
if (opts & OPT_r)
{
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
char *msg = xasprintf("file: %s", output_file);
diff --git a/src/plugins/abrt-action-rhtsupport.c b/src/plugins/abrt-action-rhtsupport.c
index 989fd75..59d02ed 100644
--- a/src/plugins/abrt-action-rhtsupport.c
+++ b/src/plugins/abrt-action-rhtsupport.c
@@ -28,12 +28,9 @@ static void report_to_rhtsupport(
const char *dump_dir_name,
map_string_h *settings)
{
- struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
- if (!dd)
- exit(1); /* error msg is already logged by dd_opendir */
-
- problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
+ problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
+ if (!problem_data)
+ xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
/* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */
log(_("Compressing data"));
@@ -245,7 +242,7 @@ static void report_to_rhtsupport(
}
/* No error */
- dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (dd)
{
char *msg = xasprintf("RHTSupport: %s", result);
diff --git a/src/plugins/analyze_LocalGDB.xml.in b/src/plugins/analyze_LocalGDB.xml.in
index 4f7ccce..b2975f7 100644
--- a/src/plugins/analyze_LocalGDB.xml.in
+++ b/src/plugins/analyze_LocalGDB.xml.in
@@ -5,5 +5,5 @@
<_long-description>Needs to downloads debuginfo packages, which might take significant time, and take up disk space.
However, unlike RetraceServer, doesn't send coredump to remote machines.
</_long-description>
- <creates-elements>backtrace</creates-elements>
+ <creates-items>backtrace</creates-items>
</event>
diff --git a/src/plugins/analyze_RetraceServer.xml.in b/src/plugins/analyze_RetraceServer.xml.in
index d2072db..139e114 100644
--- a/src/plugins/analyze_RetraceServer.xml.in
+++ b/src/plugins/analyze_RetraceServer.xml.in
@@ -6,7 +6,7 @@
Pros: no need for debuginfo downloads. Retrace server's database of debuginfos is more complete. Retrace server may generate better backtraces.
Cons: coredump you upload contains all the data from the crashed program, including your private data, if any.
</_long-description>
- <creates-elements>backtrace</creates-elements>
+ <creates-items>backtrace</creates-items>
<options>
<option type="text" name="RETRACE_SERVER_URL">
<_label>Retrace server URL</_label>
diff --git a/src/plugins/analyze_xsession_errors.xml.in b/src/plugins/analyze_xsession_errors.xml.in
index 9f7a46b..1e3d738 100644
--- a/src/plugins/analyze_xsession_errors.xml.in
+++ b/src/plugins/analyze_xsession_errors.xml.in
@@ -6,5 +6,5 @@
Scans through ~/.xsession-errors file and saves those lines which contain executable's name.
The result is saved as 'xsession_errors' element.
</_long-description>
- <creates-elements>xsession_errors</creates-elements>
+ <creates-items>xsession_errors</creates-items>
</event>
diff --git a/src/plugins/report_Bugzilla.xml.in b/src/plugins/report_Bugzilla.xml.in
index 8a53f61..d12521d 100644
--- a/src/plugins/report_Bugzilla.xml.in
+++ b/src/plugins/report_Bugzilla.xml.in
@@ -2,6 +2,13 @@
<event>
<_name>Bugzilla</_name>
<_description>Report to Bugzilla bug tracker</_description>
+
+ <requires-items></requires-items>
+ <exclude-items-by-default></exclude-items-by-default>
+ <exclude-items-always></exclude-items-always>
+ <exclude-binary-items>yes</exclude-binary-items>
+ <include-items-by-default></include-items-by-default>
+
<options>
<option type="text" name="Bugzilla_BugzillaURL">
<_label>Bugzilla URL</_label>