From 66377f809ef1c84672e12b1896f1a39e1957dc96 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Tue, 16 Jun 2020 23:22:18 +0200 Subject: Flesh out main config parsing --- main.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 4 deletions(-) (limited to 'main.c') diff --git a/main.c b/main.c index 148b2d2..9915cf2 100644 --- a/main.c +++ b/main.c @@ -57,25 +57,118 @@ cfg_free(struct uring_task *task) debug(DBG_SIG, "called\n"); systemd_delete(cfg); + xfree(cfg->igmp_iface); + cfg->igmp_iface = NULL; + xfree(cfg->cfg_path); + cfg->cfg_path = NULL; exiting = true; /* The cfg struct is free:d in main() */ } +#define DEFAULT_MAIN_CONFIG_FILE_PATH "./mcproxy.conf" + +enum mcfg_keys { + MCFG_KEY_INVALID = 0, + MCFG_KEY_IGMP, + MCFG_KEY_IGMP_IFACE +}; + +struct cfg_key_value_map mcfg_key_map[] = { + { + .key_name = "igmp", + .key_value = MCFG_KEY_IGMP, + .value_type = CFG_VAL_TYPE_BOOL, + }, { + .key_name = "igmp_iface", + .key_value = MCFG_KEY_IGMP_IFACE, + .value_type = CFG_VAL_TYPE_STRING, + }, { + .key_name = NULL, + .key_value = MCFG_KEY_INVALID, + .value_type = CFG_VAL_TYPE_INVALID, + } +}; + static void cfg_read(struct cfg *cfg) { FILE *cfgfile; - - cfgfile = fopen("./mcproxy.conf", "re"); + const char *path; + char buf[4096]; + char *pos = buf; + size_t rd = 0; + size_t r; + + if (cfg->cfg_path) + path = cfg->cfg_path; + else + path = DEFAULT_MAIN_CONFIG_FILE_PATH; + + cfgfile = fopen(path, "re"); if (!cfgfile) { - if (errno == ENOENT) + /* ENOENT is only an error with an explicitly set path */ + if (errno == ENOENT && !cfg->cfg_path) return; + else if (errno == ENOENT) + die("main config file (%s) missing\n", path); else perrordie("fopen"); } - debug(DBG_CFG, "opened config file\n"); + debug(DBG_CFG, "opened main config file (%s)\n", path); + + while (rd < sizeof(buf)) { + r = fread(pos, 1, sizeof(buf) - rd - 1, cfgfile); + if (r == 0) + break; + rd += r; + pos += r; + } + + if (rd == 0) + die("main config file (%s) invalid\n", path); + + if (rd >= sizeof(buf)) + die("main config file (%s) too large\n", path); + fclose(cfgfile); + *pos = '\0'; + pos = buf; + + if (!config_parse_header(cfg, path, "mcproxy", &pos)) + die("main config file (%s) invalid\n", path); + + while (true) { + int key; + const char *keyname; + union cfg_value value; + + if (!config_parse_line(cfg, path, &pos, mcfg_key_map, + &key, &keyname, &value)) + break; + + if (key == MCFG_KEY_INVALID) + die("main config file (%s) invalid\n", path); + + debug(DBG_CFG, "main cfg: key %s\n", keyname); + + switch (key) { + + case MCFG_KEY_IGMP: + cfg->do_igmp = value.boolean; + break; + + case MCFG_KEY_IGMP_IFACE: + cfg->igmp_iface = xstrdup(value.str); + if (!cfg->igmp_iface) + perrordie("xstrdup"); + break; + + case MCFG_KEY_INVALID: + default: + die("main config file (%s) invalid\n", path); + } + } } const struct { -- cgit v1.2.3