/* This file is part of genrc Copyryght (C) 2018 Sergey Poznyakoff License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. */ #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:::"); 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; }