From f06ff46151c38b2259c5ee4ae83d38c6f6fc0c8c Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Sun, 12 Jul 2020 02:30:31 +0200 Subject: Teach minecctl to create proper mcserver files, auto-generate systemd service names as necessary --- minecctl/misc-commands.c | 118 ++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 48 deletions(-) (limited to 'minecctl/misc-commands.c') diff --git a/minecctl/misc-commands.c b/minecctl/misc-commands.c index 1133e55..34dd990 100644 --- a/minecctl/misc-commands.c +++ b/minecctl/misc-commands.c @@ -20,7 +20,6 @@ #include "misc.h" #include "examples/eula.txt.h" -#include "examples/example.mcserver.h" #include "examples/minecctl.conf.h" #include "examples/minecproxy.conf.h" #include "examples/minecproxy.service.h" @@ -142,10 +141,12 @@ static bool create_user_service(int xfd, const char *service, return true; } -static bool create_server_cfg(struct cfg *cfg, const char *name, - const char *filename, - const unsigned char *properties, - size_t properties_len) +static bool write_server_cfg(struct cfg *cfg, const char *name, + const char *filename, + const unsigned char *properties, + size_t properties_len, + const unsigned char *mcserver, + size_t mcserver_len) { _cleanup_close_ int sfd = -1; int cfd, dfd; @@ -156,17 +157,15 @@ static bool create_server_cfg(struct cfg *cfg, const char *name, cfd = dirfd(cfg->cfg_dir); dfd = dirfd(cfg->data_dir); - if (!write_cfg_file(cfd, filename, - ___examples_example_mcserver, - ___examples_example_mcserver_len)) - return false; - sfd = open_subdir(dfd, name, true); if (sfd < 0) { error("Failed to create server directory \"%s\"", name); return false; } + if (!write_cfg_file(cfd, filename, mcserver, mcserver_len)) + return false; + if (!write_cfg_file(sfd, "eula.txt", ___examples_eula_txt, ___examples_eula_txt_len)) return false; @@ -299,18 +298,37 @@ static bool generate_random_password(char *buf, size_t len) } *d = '\0'; - info("Hex = %s", buf); return true; } +static unsigned char *create_mc_server(const char *name, uint16_t local_port, + size_t *len) +{ + char *mcserver; + + /* FIXME: Add comments, commented out options */ + mcserver = xsprintf(len, + "[server]\n" + "type = proxy\n" + "name = %s\n" + "local = %" PRIu16 "\n" + "idle_timeout = 600\n" + "start_method = systemd\n" + "stop_method = systemd\n", + name, local_port); + if (!mcserver) + error("xsprintf: %m"); + + return (unsigned char *)mcserver; +} + static unsigned char *create_mc_properties(const char *name, uint16_t mc_port, uint16_t rcon_port, const char *rcon_password, size_t *len) { char hexrnd[16 + 1]; - char *properties; - int r; + char *prop; if (!rcon_password) { if (!generate_random_password(hexrnd, sizeof(hexrnd))) { @@ -319,27 +337,24 @@ static unsigned char *create_mc_properties(const char *name, uint16_t mc_port, } } - /* FIXME: server-ip= */ - r = asprintf(&properties, - "#Minecraft server properties\n" - "# This is a partial file, it will be replaced with a\n" - "# fleshed out version the first time the Minecraft\n" - "# server is executed.\n" - "motd=%s\n" - "server-port=%" PRIu16 "\n" - "enable-rcon=true\n" - "rcon.port=%" PRIu16 "\n" - "rcon.password=%s", - name, mc_port, rcon_port, - rcon_password ? rcon_password : hexrnd); - if (r < 0) { - error("asprintf failed: %m"); - return NULL; - } - - if (len) - *len = r; - return (unsigned char *)properties; + prop = xsprintf(len, + "#Minecraft server properties\n" + "# This is a partial file, it will be replaced with a\n" + "# fleshed out version the first time the Minecraft\n" + "# server is executed.\n" + "motd=%s\n" + "#maybe uncomment the next line if you use minecproxy\n" + "#server-ip=127.0.0.1\n" + "server-port=%" PRIu16 "\n" + "enable-rcon=true\n" + "rcon.port=%" PRIu16 "\n" + "rcon.password=%s\n", + name, mc_port, rcon_port, + rcon_password ? rcon_password : hexrnd); + if (!prop) + error("xsprintf: %m"); + + return (unsigned char *)prop; } static uint16_t get_port(struct list_head *list) @@ -461,10 +476,12 @@ bool do_new(struct cfg *cfg) const char *name = cfg->commands[0]; struct server *server; struct server *defserver = NULL; + uint16_t local_port = 0, mc_port = 0, rcon_port = 0; + const char *rcon_password = NULL; _cleanup_free_ unsigned char *properties = NULL; size_t properties_len; - uint16_t rcon_port = 0, mc_port = 0; - const char *rcon_password = NULL; + _cleanup_free_ unsigned char *mcserver = NULL; + size_t mcserver_len; if (!valid_name(name)) return false; @@ -494,7 +511,6 @@ bool do_new(struct cfg *cfg) } if (defserver) { - /* FIXME: check list empty and tailor error msg */ rcon_port = get_port(&defserver->scfg.rcons); mc_port = get_port(&defserver->scfg.remotes); rcon_password = defserver->scfg.rcon_password; @@ -503,8 +519,8 @@ bool do_new(struct cfg *cfg) dump_config(cfg); - if (!select_free_ports(cfg, NULL, &mc_port, &rcon_port)) { - error("Failed to find a free port"); + if (!select_free_ports(cfg, &local_port, &mc_port, &rcon_port)) { + error("Failed to find free port(s)"); return false; } @@ -513,10 +529,13 @@ bool do_new(struct cfg *cfg) if (!properties) return false; - error("Created config file (%zu):\n%s", properties_len, properties); + mcserver = create_mc_server(name, local_port, &mcserver_len); + if (!mcserver) + return false; - if (!create_server_cfg(cfg, name, filename, properties, - properties_len)) + if (!write_server_cfg(cfg, name, filename, + properties, properties_len, + mcserver, mcserver_len)) return false; info("Created server configuration %s", name); @@ -532,7 +551,7 @@ bool do_list(struct cfg *cfg) /* server->scfg.filename check excludes servers created from cmdline */ list_for_each_entry(server, &cfg->servers, list) if (server->scfg.filename) - info("• %s", server->name); + info("• %s", server->scfg.name); return true; } @@ -598,22 +617,25 @@ bool do_lint(struct cfg *cfg) a->scfg.announce_port == b->scfg.announce_port) info("%sNote:%s %s and %s appear to have the " "same announce port", ansi_red, - ansi_normal, a->name, b->name); + ansi_normal, a->scfg.name, b->scfg.name); if (saddr_match(&a->scfg.locals, &b->scfg.locals)) info("%sNote:%s %s and %s appear to share at " "least one local address/port pair", - ansi_red, ansi_normal, a->name, b->name); + ansi_red, ansi_normal, a->scfg.name, + b->scfg.name); if (saddr_match(&a->scfg.remotes, &b->scfg.remotes)) info("%sNote:%s %s and %s appear to share at " "least one remote address/port pair", - ansi_red, ansi_normal, a->name, b->name); + ansi_red, ansi_normal, a->scfg.name, + b->scfg.name); if (saddr_match(&a->scfg.rcons, &b->scfg.rcons)) info("%sNote:%s %s and %s appear to share at " "least one rcon address/port pair", - ansi_red, ansi_normal, a->name, b->name); + ansi_red, ansi_normal, a->scfg.name, + b->scfg.name); ib++; } @@ -648,7 +670,7 @@ static bool do_one_status(struct cfg *cfg, struct server *server) const char *error; bool rv = true; - info("• %s", server->name); + info("• %s", server->scfg.name); if (list_empty(&server->scfg.rcons)) info(" rcon : not configured"); -- cgit v1.2.3