From fc028b3417349fd60a2ddd1aff1127a417df512b Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Thu, 2 Jul 2015 15:04:06 +0200
Subject: [PATCH] lib: get possible events for problem_data_t
Certainly useful when we have no file system access to dump directories
and we only get a problem data via a D-Bus service.
Related: #1224984
Signed-off-by: Jakub Filak <jfilak@redhat.com>
---
src/include/run_event.h | 8 +++++++
src/lib/glib_support.c | 2 +-
src/lib/run_event.c | 56 +++++++++++++++++++++++++++++++++++--------------
3 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/src/include/run_event.h b/src/include/run_event.h
index 7579e8f..bc43d4f 100644
--- a/src/include/run_event.h
+++ b/src/include/run_event.h
@@ -186,6 +186,9 @@ int run_event_on_problem_data(struct run_event_state *state, problem_data_t *dat
*/
char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx);
+/* Like list_possible_events but accepts problem_data_t */
+char *list_possible_events_problem_data(problem_data_t *pd, const char *dump_dir_name, const char *pfx);
+
/*
* Returns a list of possible events for given problem directory
*
@@ -195,6 +198,11 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
GList *list_possible_events_glist(const char *problem_dir_name,
const char *pfx);
+/* Like list_possible_events_glist but accepts problem_data_t */
+GList *list_possible_events_problem_data_glist(problem_data_t *pd,
+ const char *problem_dir_name,
+ const char *pfx);
+
/* Command line run event callback implemenetation */
/*
diff --git a/src/lib/glib_support.c b/src/lib/glib_support.c
index 02c2dfd..2751b0c 100644
--- a/src/lib/glib_support.c
+++ b/src/lib/glib_support.c
@@ -92,7 +92,7 @@ GList *parse_list(const char* list)
char *tmp_list = xstrdup(list);
- GList *l = parse_delimited_list(list, LIST_DELIMITER);
+ GList *l = parse_delimited_list(tmp_list, LIST_DELIMITER);
free(tmp_list);
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
index a56cf88..252c6bc 100644
--- a/src/lib/run_event.c
+++ b/src/lib/run_event.c
@@ -298,11 +298,17 @@ static int regcmp_lines(char *val, const char *regex)
static char* pop_next_command(GList **pp_rule_list,
char **pp_event_name, /* reports EVENT value thru this, if not NULL on entry */
struct dump_dir **pp_dd, /* use *pp_dd for access to dump dir, if non-NULL */
+ problem_data_t *pd, /* use *pp for access to problem data, if non-NULL */
const char *dump_dir_name,
const char *pfx,
unsigned pfx_len
)
{
+ /* It is an error to pass both, but we can recover from it and use only
+ * problem_data_t in that case */
+ if (pp_dd != NULL && pd != NULL)
+ error_msg("BUG: both dump dir and problem data passed to %s()", __func__);
+
char *command = NULL;
struct dump_dir *dd = pp_dd ? *pp_dd : NULL;
@@ -331,7 +337,7 @@ static char* pop_next_command(GList **pp_rule_list,
else
{
/* Read from dump dir and compare */
- if (!dd)
+ if (!dd && pd == NULL)
{
/* Without dir to match, we assume match for all conditions */
if (!dump_dir_name)
@@ -349,10 +355,15 @@ static char* pop_next_command(GList **pp_rule_list,
/* Is it "VAR!=VAL"? */
int inverted = (eq_sign > cond_str && eq_sign[-1] == '!');
char *var_name = xstrndup(cond_str, eq_sign - cond_str - (regex|inverted));
- char *real_val = dd_load_text_ext(dd, var_name, DD_FAIL_QUIETLY_ENOENT);
+ char *real_val = NULL;
+ char *free_me = NULL;
+ if (pd == NULL)
+ free_me = real_val = dd_load_text_ext(dd, var_name, DD_FAIL_QUIETLY_ENOENT);
+ else
+ real_val = problem_data_get_content_or_NULL(pd, var_name);
free(var_name);
int vals_differ = regex ? regcmp_lines(real_val, eq_sign + 1) : strcmp(real_val, eq_sign + 1);
- free(real_val);
+ free(free_me);
if (inverted)
vals_differ = !vals_differ;
@@ -422,6 +433,7 @@ int spawn_next_command(struct run_event_state *state,
char *cmd = pop_next_command(&state->rule_list,
NULL, /* don't return event_name */
NULL, /* NULL dd: we match by... */
+ NULL, /* no problem data */
dump_dir_name, /* ...dirname */
event, strlen(event)+1 /* for this event name exactly (not prefix) */
);
@@ -648,7 +660,8 @@ int run_event_on_problem_data(struct run_event_state *state, problem_data_t *dat
return r;
}
-char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx)
+
+static char *_list_possible_events(struct dump_dir **dd, problem_data_t *pd, const char *dump_dir_name, const char *pfx)
{
struct strbuf *result = strbuf_new();
@@ -661,7 +674,8 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
char *event_name = NULL;
char *cmd = pop_next_command(&rule_list,
&event_name, /* return event_name */
- (dd ? &dd : NULL), /* match this dd... */
+ dd, /* match this dd... */
+ pd, /* no problem data */
dump_dir_name, /* ...or if NULL, this dirname */
pfx, pfx_len /* for events with this prefix */
);
@@ -695,24 +709,34 @@ char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const
return strbuf_free_nobuf(result);
}
+char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx)
+{
+ return _list_possible_events((dd ? &dd : NULL), NULL, dump_dir_name, pfx);
+}
+
+char *list_possible_events_problem_data(problem_data_t *pd, const char *dump_dir_name, const char *pfx)
+{
+ return _list_possible_events(NULL, pd, dump_dir_name, pfx);
+}
+
GList *list_possible_events_glist(const char *problem_dir_name,
const char *pfx)
{
struct dump_dir *dd = dd_opendir(problem_dir_name, DD_OPEN_READONLY);
- GList *l = NULL;
char *events = list_possible_events(dd, problem_dir_name, pfx);
- char *start = events;
- char *end = strchr(events, '\n');
+ GList *l = parse_delimited_list(events, "\n");
+ dd_close(dd);
+ free(events);
- while(end)
- {
- *end = '\0';
- l = g_list_append(l, xstrdup(start));
- start = end + 1;
- end = strchr(start, '\n');
- }
+ return l;
+}
- dd_close(dd);
+GList *list_possible_events_problem_data_glist(problem_data_t *pd,
+ const char *problem_dir_name,
+ const char *pfx)
+{
+ char *events = list_possible_events_problem_data(pd, problem_dir_name, pfx);
+ GList *l = parse_delimited_list(events, "\n");
free(events);
return l;
--
2.4.3