From bc0a809ddb4c2b84be2897c00a7a2fcd5a0cce87 Mon Sep 17 00:00:00 2001
From: David Härdeman <david@hardeman.nu>
Date: Sun, 12 Jul 2020 21:01:59 +0200
Subject: Teach minecproxy to also read additional properties from
 server.properties

---
 minecproxy/server-config.c | 70 +++++++++++++++++++++++++++++++++++++++++-----
 minecproxy/uring.c         |  2 ++
 2 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/minecproxy/server-config.c b/minecproxy/server-config.c
index 81df970..baf47fb 100644
--- a/minecproxy/server-config.c
+++ b/minecproxy/server-config.c
@@ -29,11 +29,67 @@ void server_cfg_async_dns_update(struct server_config *scfg)
 	}
 }
 
+static void server_reading_done(struct server *server)
+{
+	if (!list_empty(&server->scfg.dnslookups)) {
+		uring_task_get(&server->task);
+		scfg_async_dns_start(&server->scfg);
+		return;
+	}
+
+	server_commit(server);
+}
+
+static void server_prop_read_cb(struct uring_task *task, int res)
+{
+	struct server *server = container_of(task, struct server, task);
+	const char *error;
+	unsigned lineno;
+
+	assert_return(task);
+	assert_task_alive(DBG_CFG, task);
+
+	if (res <= 0) {
+		error("error reading prop file for %s: %s", server->scfg.name,
+		      strerror(-res));
+		uring_task_close_fd(&server->task);
+		server_reading_done(server);
+		return;
+	}
+
+	debug(DBG_CFG, "%s: parsing cfg (%i bytes)", server->scfg.name, res);
+	uring_task_close_fd(&server->task);
+	
+	sprop_parse(&server->scfg, server->tbuf.buf, &lineno, &error);
+
+	server_reading_done(server);
+}
+
+static void server_prop_open_cb(struct uring_task *task, int res)
+{
+	struct server *server = container_of(task, struct server, task);
+
+	assert_return(task);
+	assert_task_alive(DBG_CFG, task);
+
+	if (res < 0) {
+		debug(DBG_CFG, "open prop(%s) failed: %s", server->scfg.name,
+		      strerror(-res));
+		server_reading_done(server);
+		return;
+	}
+
+	debug(DBG_CFG, "reading server prop %s (fd %i)", server->scfg.name, res);
+	uring_task_set_fd(&server->task, res);
+	uring_tbuf_read_until_eof(&server->task, server_prop_read_cb);
+}
+
 static void server_cfg_read_cb(struct uring_task *task, int res)
 {
 	struct server *server = container_of(task, struct server, task);
 	const char *error;
 	unsigned lineno;
+	_cleanup_free_ char *sprop = NULL;
 
 	assert_return(task);
 	assert_task_alive(DBG_CFG, task);
@@ -55,15 +111,15 @@ static void server_cfg_read_cb(struct uring_task *task, int res)
 		return;
 	}
 
-	/* FIXME: open/read/parse server.properties */
-
-	if (!list_empty(&server->scfg.dnslookups)) {
-		uring_task_get(&server->task);
-		scfg_async_dns_start(&server->scfg);
+	sprop = xstrcat(server->scfg.name, "/server.properties", NULL);
+	if (!sprop) {
+		error("%s: xstrcat %m", server->scfg.name);
+		server_delete(server);
 		return;
 	}
 
-	server_commit(server);
+	uring_openat(&server->task, dirfd(cfg->data_dir), sprop,
+		     server_prop_open_cb);
 }
 
 static void server_cfg_open_cb(struct uring_task *task, int res)
@@ -74,7 +130,7 @@ static void server_cfg_open_cb(struct uring_task *task, int res)
 	assert_task_alive(DBG_CFG, task);
 
 	if (res < 0) {
-		error("open(%s) failed: %s", server->scfg.name, strerror(-res));
+		error("open cfg(%s) failed: %s", server->scfg.name, strerror(-res));
 		server_delete(server);
 		return;
 	}
diff --git a/minecproxy/uring.c b/minecproxy/uring.c
index ead566d..d16abac 100644
--- a/minecproxy/uring.c
+++ b/minecproxy/uring.c
@@ -437,6 +437,8 @@ void uring_openat(struct uring_task *task, int dfd, const char *path,
 	task->cb = cb;
 	io_uring_prep_openat(sqe, dfd, path, O_RDONLY | O_CLOEXEC, 0);
 	io_uring_sqe_set_data(sqe, task);
+	/* We need to do this here since path may go away */
+	io_uring_submit(&cfg->uring->uring);
 }
 
 void uring_tbuf_recvmsg(struct uring_task *task, utask_cb_t cb)
-- 
cgit v1.2.3