diff options
author | David Härdeman <david@hardeman.nu> | 2020-06-16 23:22:18 +0200 |
---|---|---|
committer | David Härdeman <david@hardeman.nu> | 2020-06-16 23:22:18 +0200 |
commit | 66377f809ef1c84672e12b1896f1a39e1957dc96 (patch) | |
tree | 492462a89ad9ad69de233d814584ade7ce04befe /main.c | |
parent | e74dad8526cc72ced4554f9af16464a00b230eec (diff) |
Flesh out main config parsing
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 101 |
1 files changed, 97 insertions, 4 deletions
@@ -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 { |