diff options
Diffstat (limited to 'src/pid_config.c')
-rw-r--r-- | src/pid_config.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/pid_config.c b/src/pid_config.c new file mode 100644 index 0000000..b646cc0 --- /dev/null +++ b/src/pid_config.c @@ -0,0 +1,91 @@ +#include "genrc.h" + +typedef struct grecs_node *(*GRECS_PARSER_FUNC)(const char *, int); + +struct config_pid_closure { + struct genrc_pid_closure generic; + char *filename; + char *fqrn; + GRECS_PARSER_FUNC parser; +}; + +static int +pid_config_get(GENRC_PID_CLOSURE *clos, PIDLIST *plist) +{ + struct config_pid_closure *config_clos = + (struct config_pid_closure *)clos; + struct grecs_node *tree, *node; + pid_t pid; + + grecs_parser_fun = config_clos->parser; + tree = grecs_parse(config_clos->filename); + if (!tree) + exit(1); + node = grecs_find_node(tree, config_clos->fqrn); + if (!node) + usage_error("%s: relation %s not found", + config_clos->filename, + config_clos->fqrn); + if (node->type != grecs_node_stmt) + usage_error("%s: relation %s is not a statement", + config_clos->filename, + config_clos->fqrn); + if (node->v.value->type != GRECS_TYPE_STRING) + usage_error("%s: relation %s is not a string", + config_clos->filename, + config_clos->fqrn); + + pid = file_read_pid(node->v.value->v.string); + grecs_tree_free(tree); + + if (pid == -1) + return -1; + if (pid > 0) + pidlist_add(plist, pid); + + return 0; +} + +struct langtab { + char const *lang_name; + GRECS_PARSER_FUNC lang_parser; +}; + +static struct langtab langtab[] = { + { "GRECS", grecs_grecs_parser }, + { "META1", grecs_meta1_parser }, + { "BIND", grecs_bind_parser }, + { "DHCPD", grecs_dhcpd_parser }, + { "GIT", grecs_git_parser }, + { "PATH", grecs_path_parser }, + { NULL, NULL } +}; + +static GRECS_PARSER_FUNC +find_parser(const char *lang) +{ + struct langtab *p; + for (p = langtab; p->lang_name; p++) + if (strcmp(p->lang_name, lang) == 0) + break; + return p->lang_parser; +} + +GENRC_PID_CLOSURE * +genrc_pid_config_init(int argc, char **argv) +{ + struct config_pid_closure *clos; + + if (argc != 4) + usage_error("expected format: CONFIG:<LANG>:<FILE>:<FQRN>"); + + clos = xmalloc(sizeof(*clos)); + clos->generic.pid = pid_config_get; + clos->parser = find_parser(argv[1]); + if (!clos->parser) + usage_error("%s: unsupported parser type", argv[1]); + clos->filename = xstrdup(argv[2]); + clos->fqrn = xstrdup(argv[3]); + return (GENRC_PID_CLOSURE *) clos; +} + |