diff options
Diffstat (limited to 'minecproxy')
| -rw-r--r-- | minecproxy/main.c | 96 | ||||
| -rw-r--r-- | minecproxy/main.h | 30 | ||||
| -rw-r--r-- | minecproxy/server-config.c | 13 | 
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);  }  | 
