summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-11-03 19:44:39 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2010-11-03 19:44:39 +0100
commit76eea28e05500146cd79633f6935a8368bee6ff1 (patch)
tree3db1e31607269383145d95e2d536f9c77e7a89b4
parenta8f39ad24b77926929fe6780dfeba44ac0558a92 (diff)
downloadabrt-76eea28e05500146cd79633f6935a8368bee6ff1.tar.gz
abrt-76eea28e05500146cd79633f6935a8368bee6ff1.tar.xz
abrt-76eea28e05500146cd79633f6935a8368bee6ff1.zip
extend list_possible_events() to be able to return list _for a specified dir_
Example: post-create analyze reanalyze report report_Bugzilla report_Logger post-create reanalyze report_Bugzilla report_Logger Note that "analyze" and "report" steps arent't listed for TEST_DIR because there is not a single matching rule for them. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r--inc/abrtlib.h2
-rw-r--r--lib/utils/run_event.c98
-rw-r--r--src/daemon/abrt-handle-crashdump.c11
3 files changed, 73 insertions, 38 deletions
diff --git a/inc/abrtlib.h b/inc/abrtlib.h
index d9b74975..94e7ca32 100644
--- a/inc/abrtlib.h
+++ b/inc/abrtlib.h
@@ -224,7 +224,7 @@ static inline struct run_event_state *new_run_event_state()
static inline void free_run_event_state(struct run_event_state *state)
{ free(state); }
int run_event(struct run_event_state *state, const char *dump_dir_name, const char *event);
-char *list_possible_events(const char *pfx);
+char *list_possible_events(const char *dump_dir_name, const char *pfx);
#ifdef __cplusplus
}
diff --git a/lib/utils/run_event.c b/lib/utils/run_event.c
index 4ad2e270..020799a9 100644
--- a/lib/utils/run_event.c
+++ b/lib/utils/run_event.c
@@ -38,7 +38,7 @@ int run_event(struct run_event_state *state,
char *full_name = realpath(dump_dir_name, NULL);
setenv("DUMP_DIR", (full_name ? full_name : dump_dir_name), 1);
free(full_name);
- /*setenv("EVENT", event, 1); - is this useful for children to know? */
+ setenv("EVENT", event, 1);
/* Read, match, and execute lines from abrt_event.conf */
int retval = 0;
@@ -55,14 +55,17 @@ int run_event(struct run_event_state *state,
while (1) /* word loop */
{
+ char *end_word = skip_non_whitespace(p);
+ char *next_word = skip_whitespace(end_word);
+ *end_word = '\0';
+
/* If there is no '=' in this word... */
- char *next_word = skip_whitespace(skip_non_whitespace(p));
- char *needed_val = strchr(p, '=');
- if (!needed_val || needed_val >= next_word)
+ char *line_val = strchr(p, '=');
+ if (!line_val)
break; /* ...we found the start of a command */
- /* Current word has VAR=VAL form. needed_val => VAL */
- *needed_val++ = '\0';
+ /* Current word has VAR=VAL form. line_val => VAL */
+ *line_val++ = '\0';
const char *real_val;
char *malloced_val = NULL;
@@ -83,12 +86,9 @@ int run_event(struct run_event_state *state,
}
/* Does VAL match? */
- unsigned len = strlen(real_val);
- bool match = (strncmp(real_val, needed_val, len) == 0
- && (needed_val[len] == ' ' || needed_val[len] == '\t'));
- if (!match)
+ if (strcmp(real_val, line_val) != 0)
{
- VERB3 log("var '%s': '%s'!='%s', skipping line", p, real_val, needed_val);
+ VERB3 log("var '%s': '%s'!='%s', skipping line", p, real_val, line_val);
free(malloced_val);
goto next_line; /* no */
}
@@ -135,6 +135,7 @@ int run_event(struct run_event_state *state,
free(buf);
}
fclose(fp); /* Got EOF, close. This also closes pipefds[0] */
+
/* Wait for child to actually exit, collect status */
int status;
waitpid(pid, &status, 0);
@@ -167,7 +168,7 @@ int run_event(struct run_event_state *state,
return retval;
}
-char *list_possible_events(const char *pfx)
+char *list_possible_events(const char *dump_dir_name, const char *pfx)
{
FILE *conffile = fopen(CONF_DIR"/abrt_event.conf", "r");
if (!conffile)
@@ -176,6 +177,7 @@ char *list_possible_events(const char *pfx)
return NULL;
}
+ struct dump_dir *dd = NULL;
unsigned pfx_len = strlen(pfx);
struct strbuf *result = strbuf_new();
char *line;
@@ -190,42 +192,72 @@ char *list_possible_events(const char *pfx)
while (1) /* word loop */
{
+ char *end_word = skip_non_whitespace(p);
+ char *next_word = skip_whitespace(end_word);
+ *end_word = '\0';
+
/* If there is no '=' in this word... */
- char *end_of_word = skip_non_whitespace(p);
- char *next_word = skip_whitespace(end_of_word);
- char *val = strchr(p, '=');
- if (!val || val >= next_word)
+ char *line_val = strchr(p, '=');
+ if (!line_val)
break; /* ...we found the start of a command */
- /* Current word has VAR=VAL form */
- *val++ = '\0';
+ /* Current word has VAR=VAL form. line_val => VAL */
+ *line_val++ = '\0';
+
+ /* Is it EVENT? */
if (strcmp(p, "EVENT") == 0)
{
- /* EVENT=VAL */
- *end_of_word = '\0';
- if (strncmp(pfx, val, pfx_len) == 0)
+ if (strncmp(line_val, pfx, pfx_len) != 0)
+ goto next_line; /* prefix doesn't match */
+ /* (Ab)use line to save matching "\nEVENT_VAL\n" */
+ sprintf(line, "\n%s\n", line_val);
+ }
+ else
+ {
+ /* Get this name from dump dir */
+ if (!dd)
+ {
+ /* Without dir name to match, we assume match */
+ if (!dump_dir_name)
+ goto matched;
+ dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
+ if (!dd)
+ goto stop; /* error (note: dd_opendir logged error msg) */
+ }
+ char *real_val = dd_load_text(dd, p);
+ /* Does VAL match? */
+ if (strcmp(real_val, line_val) != 0)
{
- /* VAL starts with pfx */
- unsigned val_len_p2 = sprintf(line, "\n%s\n", val); /* line = "\nVAL\n" */
-
- /* Do we already have VAL in the result? */
- if (!strstr(result->buf, line)
- && strncmp(result->buf, line + 1, val_len_p2 - 1) != 0
- ) {
- /* No, add VAL\n */
- strbuf_append_str(result, line + 1);
- }
+ VERB3 log("var '%s': '%s'!='%s', skipping line", p, real_val, line_val);
+ free(real_val);
+ goto next_line; /* no */
}
- /* We don't check for more EVENT=foo words on the line */
- break;
+ free(real_val);
}
+ /* Go to next word */
p = next_word;
} /* end of word loop */
+ matched:
+ dd_close(dd);
+ dd = NULL;
+
+ if (line[0] == '\n' /* do we *have* saved matched "\nEVENT_VAL\n"? */
+ /* and does result->buf NOT yet have VAL? */
+ && strncmp(result->buf, line + 1, strlen(line + 1)) != 0
+ && !strstr(result->buf, line)
+ ) {
+ /* Add "EVENT_VAL\n" */
+ strbuf_append_str(result, line + 1);
+ }
+
next_line:
free(line);
} /* end of line loop */
+
+ stop:
+ free(line);
fclose(conffile);
return strbuf_free_nobuf(result);
diff --git a/src/daemon/abrt-handle-crashdump.c b/src/daemon/abrt-handle-crashdump.c
index 196731de..031b5d22 100644
--- a/src/daemon/abrt-handle-crashdump.c
+++ b/src/daemon/abrt-handle-crashdump.c
@@ -21,7 +21,7 @@
#define PROGNAME "abrt-handle-crashdump"
-static const char *dump_dir_name = ".";
+static const char *dump_dir_name = NULL;
//static const char *conf_filename = CONF_DIR"/abrt_event.conf";
static const char *event;
static const char *pfx = "";
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
const char *program_usage = _(
PROGNAME" [-vs]" /*" [-c CONFFILE]"*/ " -d DIR -e EVENT\n"
- " or: "PROGNAME" [-vs]" /*" [-c CONFFILE]"*/ " -l[PFX]\n"
+ " or: "PROGNAME" [-vs]" /*" [-c CONFFILE]"*/ " [-d DIR] -l[PFX]\n"
"\n"
"Handle crash dump according to rules in abrt_event.conf");
enum {
@@ -74,7 +74,10 @@ int main(int argc, char **argv)
if (opts & OPT_l)
{
- char *events = list_possible_events(pfx);
+ /* Note that dump_dir_name may be NULL here, it means "show all
+ * possible events regardless of dir"
+ */
+ char *events = list_possible_events(dump_dir_name, pfx);
if (!events)
return 1; /* error msg is already logged */
fputs(events, stdout);
@@ -85,7 +88,7 @@ int main(int argc, char **argv)
/* -e EVENT: run event */
struct run_event_state *run_state = new_run_event_state();
run_state->logging_callback = do_log;
- int r = run_event(run_state, dump_dir_name, event);
+ int r = run_event(run_state, dump_dir_name ? dump_dir_name : ".", event);
free_run_event_state(run_state);
return r;