From 6586ea650597ae0563c4234a7658499ce1e0117b Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Sun, 12 Jul 2020 14:04:40 +0200 Subject: Teach minecproxy to use same dirs as minecctl, step 1 --- minecproxy/main.c | 96 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 44 deletions(-) (limited to 'minecproxy/main.c') diff --git a/minecproxy/main.c b/minecproxy/main.c index 0406976..48bb1fa 100644 --- a/minecproxy/main.c +++ b/minecproxy/main.c @@ -179,6 +179,8 @@ static void cfg_free(struct uring_task *task) debug(DBG_SIG, "called"); systemd_delete(); xfree(cfg->igmp_iface); + xfree(cfg->data_real_path); + xfree(cfg->cfg_real_path); cfg->igmp_iface = NULL; exiting = true; /* The cfg struct is free:d in main() */ @@ -258,54 +260,45 @@ struct cfg_key_value_map mcfg_key_map[] = { static void cfg_read() { - FILE *cfgfile; - const char *path; char buf[4096]; - char *pos = buf; - size_t rd = 0; + char *pos; + size_t off; size_t r; unsigned lineno; + _cleanup_close_ int fd = -1; + _cleanup_fclose_ FILE *cfgfile = NULL; assert_return(cfg); - if (cfg->cfg_file) - path = cfg->cfg_file; - else - path = DEFAULT_MAIN_CFG_FILE; - - cfgfile = fopen(path, "re"); - if (!cfgfile) { - /* ENOENT is only an error with an explicitly set path */ - if (errno == ENOENT && !cfg->cfg_file) - return; - else if (errno == ENOENT) - die("main config file (%s) missing", path); - else - die("fopen(%s): %m", path); - } + fd = openat(dirfd(cfg->cfg_dir), DEFAULT_MAIN_CFG_FILE, + O_RDONLY | O_CLOEXEC | O_NOCTTY); + if (fd < 0) + return; + + cfgfile = fdopen(fd, "re"); + if (!cfgfile) + return; - debug(DBG_CFG, "opened main config file (%s)", path); + fd = -1; + debug(DBG_CFG, "opened main config file %s/%s", cfg->cfg_real_path, + DEFAULT_MAIN_CFG_FILE); - while (rd < sizeof(buf)) { - r = fread(pos, 1, sizeof(buf) - rd - 1, cfgfile); + for (off = 0; off < sizeof(buf); off += r) { + r = fread(buf + off, 1, sizeof(buf) - off, cfgfile); if (r == 0) break; - rd += r; - pos += r; } - if (rd == 0) - die("main config file (%s) zero size", path); + if (off >= sizeof(buf) - 1) + die("main config file %s/%s too large", cfg->cfg_real_path, + DEFAULT_MAIN_CFG_FILE); - if (rd >= sizeof(buf)) - die("main config file (%s) too large", path); - - fclose(cfgfile); - *pos = '\0'; + buf[off] = '\0'; pos = buf; if (!config_parse_header("mcproxy", &pos, &lineno)) - die("main config file (%s) missing/invalid header", path); + die("main config file %s/%s missing/invalid header", + cfg->cfg_real_path, DEFAULT_MAIN_CFG_FILE); while (true) { int key; @@ -313,13 +306,15 @@ static void cfg_read() struct cfg_value value; const char *error; - if (!config_parse_line(path, &pos, mcfg_key_map, &key, &keyname, + if (!config_parse_line(DEFAULT_MAIN_CFG_FILE, &pos, + mcfg_key_map, &key, &keyname, &value, false, &lineno, &error)) break; if (key == MCFG_KEY_INVALID) - die("main config file (%s) invalid: line %u: %s", path, - lineno, error); + die("main config file %s/%s invalid: line %u: %s", + cfg->cfg_real_path, DEFAULT_MAIN_CFG_FILE, lineno, + error); debug(DBG_CFG, "main cfg: key %s", keyname); @@ -369,7 +364,7 @@ static void cfg_read() case MCFG_KEY_INVALID: default: - die("main config file (%s) invalid", path); + die("main config file invalid"); } } } @@ -436,8 +431,8 @@ _noreturn_ static void usage(bool invalid) info("Usage: %s [OPTIONS]\n" "\n" "Valid options:\n" - " -c, --cfgdir=DIR\tlook for server configuration files in DIR\n" - " -C, --cfgfile=PATH\tuse PATH as the main configuration file\n" + " -c, --cfgdir=DIR\tuse DIR for configuration files\n" + " -C, --datadir=DIR\tuse DIR for server data\n" " -u, --user=USER\trun as USER\n" " -D, --daemonize\trun in daemon mode (disables stderr output)\n" " -l, --logfile=FILE\tlog to FILE instead of stderr\n" @@ -465,7 +460,12 @@ static void cfg_init(int argc, char **argv) uring_task_init(&cfg->task, "main", NULL, cfg_free); INIT_LIST_HEAD(&cfg->servers); - cfg->cfg_dir = DEFAULT_CFG_DIR; + cfg->cfg_path = NULL; + cfg->cfg_real_path = NULL; + cfg->cfg_dir = NULL; + cfg->data_path = NULL; + cfg->data_real_path = NULL; + cfg->data_dir = NULL; cfg->announce_interval = DEFAULT_ANNOUNCE_INTERVAL; cfg->proxy_connection_interval = DEFAULT_PROXY_CONN_INTERVAL; cfg->proxy_connection_attempts = DEFAULT_PROXY_CONN_ATTEMPTS; @@ -482,7 +482,7 @@ static void cfg_init(int argc, char **argv) /* clang-format off */ static struct option long_options[] = { { "cfgdir", required_argument, 0, 'c' }, - { "cfgfile", required_argument, 0, 'C' }, + { "datadir", required_argument, 0, 'C' }, { "user", required_argument, 0, 'u' }, { "daemonize", no_argument, 0, 'D' }, { "logfile", required_argument, 0, 'l' }, @@ -500,11 +500,11 @@ static void cfg_init(int argc, char **argv) switch (c) { case 'c': - cfg->cfg_dir = optarg; + cfg->cfg_path = optarg; break; case 'C': - cfg->cfg_file = optarg; + cfg->data_path = optarg; break; case 'v': @@ -618,8 +618,16 @@ static void cfg_apply() * Do this after caps have been dropped to make sure we're not * accessing a directory we should have permissions to. */ - if (chdir(cfg->cfg_dir)) - die("chdir(%s): %m", cfg->cfg_dir); + cfg->cfg_dir = open_cfg_dir(cfg->cfg_path, &cfg->cfg_real_path); + if (!cfg->cfg_dir) + die("Unable to open configuration directory"); + + cfg->data_dir = open_data_dir(cfg->data_path, &cfg->data_real_path); + if (!cfg->data_dir) + die("Unable to open server directory"); + + if (fchdir(dirfd(cfg->data_dir))) + die("Unable to chdir to server directory: %m"); if (debug_enabled(DBG_VERBOSE)) { char *wd; -- cgit v1.2.3