summaryrefslogtreecommitdiff
path: root/minecproxy
diff options
context:
space:
mode:
Diffstat (limited to 'minecproxy')
-rw-r--r--minecproxy/main.c96
-rw-r--r--minecproxy/main.h30
-rw-r--r--minecproxy/server-config.c13
3 files changed, 61 insertions, 78 deletions
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;
diff --git a/minecproxy/main.h b/minecproxy/main.h
index 2c7be83..f7dd547 100644
--- a/minecproxy/main.h
+++ b/minecproxy/main.h
@@ -14,28 +14,6 @@ struct uring_task;
extern struct cfg *cfg;
extern bool exiting;
-/*
-enum debug_lvl {
- DBG_ERROR = (0x1 << 1),
- DBG_INFO = (0x1 << 2),
- DBG_VERBOSE = (0x1 << 3),
- DBG_CFG = (0x1 << 4),
- DBG_REF = (0x1 << 5),
- DBG_MALLOC = (0x1 << 6),
- DBG_ANN = (0x1 << 7),
- DBG_SIG = (0x1 << 8),
- DBG_UR = (0x1 << 9),
- DBG_SRV = (0x1 << 10),
- DBG_PROXY = (0x1 << 11),
- DBG_RCON = (0x1 << 12),
- DBG_IDLE = (0x1 << 13),
- DBG_IGMP = (0x1 << 14),
- DBG_SYSD = (0x1 << 15),
- DBG_DNS = (0x1 << 16),
- DBG_TIMER = (0x1 << 17),
-};
-*/
-
void dump_tree();
/* To save typing in all the function definitions below */
@@ -75,10 +53,14 @@ struct uring_task {
struct cfg {
/* Options */
+ const char *cfg_path;
+ char *cfg_real_path;
+ DIR *cfg_dir;
+ const char *data_path;
+ char *data_real_path;
+ DIR *data_dir;
uid_t uid;
gid_t gid;
- const char *cfg_dir;
- const char *cfg_file;
bool do_igmp;
char *igmp_iface;
bool splice_supported;
diff --git a/minecproxy/server-config.c b/minecproxy/server-config.c
index 959f1d0..2e7f277 100644
--- a/minecproxy/server-config.c
+++ b/minecproxy/server-config.c
@@ -215,11 +215,10 @@ void server_cfg_monitor_init()
int ifd;
int iwd;
struct server_cfg_monitor *scfgm;
- DIR *dir;
struct dirent *dent;
struct server *server;
- assert_return(!cfg->server_cfg_monitor);
+ assert_return(!cfg->server_cfg_monitor && cfg->cfg_dir);
scfgm = zmalloc(sizeof(*scfgm));
if (!scfgm)
@@ -231,7 +230,7 @@ void server_cfg_monitor_init()
/* ln = IN_CREATE, cp/vi/mv = IN_CREATE, IN_OPEN, IN_CLOSE_WRITE */
iwd = inotify_add_watch(
- ifd, ".",
+ ifd, cfg->cfg_real_path,
IN_CLOSE_WRITE | IN_DELETE | IN_CREATE | IN_DELETE_SELF |
IN_MOVE_SELF | IN_MOVED_TO | IN_MOVED_FROM |
IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_ONLYDIR);
@@ -244,11 +243,7 @@ void server_cfg_monitor_init()
cfg->server_cfg_monitor = scfgm;
uring_read(&scfgm->task, scfgm->buf, sizeof(scfgm->buf), inotify_cb);
- dir = opendir(".");
- if (!dir)
- die("opendir(%s): %m", cfg->cfg_dir);
-
- while ((dent = readdir(dir)) != NULL) {
+ while ((dent = readdir(cfg->cfg_dir)) != NULL) {
if (!config_valid_server_filename(dent, NULL))
continue;
@@ -257,6 +252,4 @@ void server_cfg_monitor_init()
uring_openat(&server->task, server->scfg.filename,
server_cfg_open_cb);
}
-
- closedir(dir);
}