summaryrefslogtreecommitdiffstats
path: root/lib/utils
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-11-02 12:38:30 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2010-11-02 12:38:30 +0100
commit3c8781e79c38961c47fc0683a4eaf665b835153c (patch)
tree234611d66be82ace3fe7276dd162d07593294bcd /lib/utils
parent8864e7d8ab05b59372f55ec8d637296aefa1515e (diff)
abrt-handle-crashdump: add -l[pfx] option to list possible events
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/parse_options.c13
-rw-r--r--lib/utils/parse_options.h12
-rw-r--r--lib/utils/run_event.c66
3 files changed, 84 insertions, 7 deletions
diff --git a/lib/utils/parse_options.c b/lib/utils/parse_options.c
index 7029643f..c1a2c297 100644
--- a/lib/utils/parse_options.c
+++ b/lib/utils/parse_options.c
@@ -37,7 +37,12 @@ void parse_usage_and_die(const char *usage, const struct options *opt)
pos += fprintf(stderr, "--%s", opt->long_name);
if (opt->argh)
- pos += fprintf(stderr, " %s", opt->argh);
+ {
+ const char *fmt = " %s";
+ if (opt->type == OPTION_OPTSTRING)
+ fmt = "[%s]";
+ pos += fprintf(stderr, fmt, opt->argh);
+ }
if (pos <= USAGE_OPTS_WIDTH)
pad = USAGE_OPTS_WIDTH - pos;
@@ -91,6 +96,11 @@ unsigned parse_opts(int argc, char **argv, const struct options *opt,
if (opt[ii].short_name)
strbuf_append_strf(shortopts, "%c:", opt[ii].short_name);
break;
+ case OPTION_OPTSTRING:
+ curopt->has_arg = optional_argument;
+ if (opt[ii].short_name)
+ strbuf_append_strf(shortopts, "%c::", opt[ii].short_name);
+ break;
case OPTION_GROUP:
case OPTION_END:
break;
@@ -153,6 +163,7 @@ unsigned parse_opts(int argc, char **argv, const struct options *opt,
*(int*)opt[ii].value = xatoi(optarg);
break;
case OPTION_STRING:
+ case OPTION_OPTSTRING:
if (optarg)
*(char**)opt[ii].value = (char*)optarg;
break;
diff --git a/lib/utils/parse_options.h b/lib/utils/parse_options.h
index f44f29b1..105f081c 100644
--- a/lib/utils/parse_options.h
+++ b/lib/utils/parse_options.h
@@ -12,6 +12,7 @@ enum parse_opt_type {
OPTION_GROUP,
OPTION_STRING,
OPTION_INTEGER,
+ OPTION_OPTSTRING,
OPTION_END,
};
@@ -31,11 +32,12 @@ struct options {
* a - argh argument help
* h - help
*/
-#define OPT_END() { OPTION_END }
-#define OPT_BOOL(s, l, v, h) { OPTION_BOOL, (s), (l), (v), NULL, (h) }
-#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
-#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
+#define OPT_END() { OPTION_END }
+#define OPT_BOOL(s, l, v, h) { OPTION_BOOL, (s), (l), (v), NULL, (h) }
+#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
+#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
+#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
+#define OPT_OPTSTRING(s, l, v, a, h) { OPTION_OPTSTRING, (s), (l), (v), (a), (h) }
#define OPT__VERBOSE(v) OPT_BOOL('v', "verbose", (v), "be verbose")
diff --git a/lib/utils/run_event.c b/lib/utils/run_event.c
index 9c4584a8..f8ad443e 100644
--- a/lib/utils/run_event.c
+++ b/lib/utils/run_event.c
@@ -51,7 +51,7 @@ int run_event(struct run_event_state *state,
if (*p == '\0' || *p == '#')
goto next_line; /* empty or comment line, skip */
- VERB3 log("line '%s'", p);
+ VERB3 log("%s: line '%s'", __func__, p);
while (1) /* word loop */
{
@@ -166,3 +166,67 @@ int run_event(struct run_event_state *state,
return retval;
}
+
+char *list_possible_events(const char *pfx)
+{
+ FILE *conffile = fopen(CONF_DIR"/abrt_action.conf", "r");
+ if (!conffile)
+ {
+ error_msg("Can't open '%s'", CONF_DIR"/abrt_action.conf");
+ return NULL;
+ }
+
+ unsigned pfx_len = strlen(pfx);
+ struct strbuf *result = strbuf_new();
+ char *line;
+ while ((line = xmalloc_fgetline(conffile)) != NULL)
+ {
+ /* Line has form: [VAR=VAL]... PROG [ARGS] */
+ char *p = skip_whitespace(line);
+ if (*p == '\0' || *p == '#')
+ goto next_line; /* empty or comment line, skip */
+
+ VERB3 log("%s: line '%s'", __func__, p);
+
+ while (1) /* word loop */
+ {
+ /* 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)
+ break; /* ...we found the start of a command */
+
+ /* Current word has VAR=VAL form */
+ *val++ = '\0';
+ if (strcmp(p, "EVENT") == 0)
+ {
+ /* EVENT=VAL */
+ *end_of_word = '\0';
+ if (strncmp(pfx, val, pfx_len) == 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);
+ }
+ }
+ /* We don't check for more EVENT=foo words on the line */
+ break;
+ }
+
+ p = next_word;
+ } /* end of word loop */
+
+ next_line:
+ free(line);
+ } /* end of line loop */
+ fclose(conffile);
+
+ return strbuf_free_nobuf(result);
+}