summaryrefslogtreecommitdiff
path: root/minecctl/misc-commands.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-07-12 02:30:31 +0200
committerDavid Härdeman <david@hardeman.nu>2020-07-12 02:30:31 +0200
commitf06ff46151c38b2259c5ee4ae83d38c6f6fc0c8c (patch)
tree44f6d00604a153300eb3be9dcec96d17030727b8 /minecctl/misc-commands.c
parentd198326ef6ec3031afbe7ee47b727cc52fc1198a (diff)
Teach minecctl to create proper mcserver files, auto-generate systemd service names as necessary
Diffstat (limited to 'minecctl/misc-commands.c')
-rw-r--r--minecctl/misc-commands.c118
1 files changed, 70 insertions, 48 deletions
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");