Blob Blame History Raw
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