diff options
| author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-11-02 12:38:30 +0100 |
|---|---|---|
| committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-11-02 12:38:30 +0100 |
| commit | 3c8781e79c38961c47fc0683a4eaf665b835153c (patch) | |
| tree | 234611d66be82ace3fe7276dd162d07593294bcd /lib/utils | |
| parent | 8864e7d8ab05b59372f55ec8d637296aefa1515e (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.c | 13 | ||||
| -rw-r--r-- | lib/utils/parse_options.h | 12 | ||||
| -rw-r--r-- | lib/utils/run_event.c | 66 |
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); +} |
