diff options
Diffstat (limited to 'minecctl')
-rw-r--r-- | minecctl/minecctl.c | 8 | ||||
-rw-r--r-- | minecctl/misc-commands.c | 118 | ||||
-rw-r--r-- | minecctl/misc.c | 2 | ||||
-rw-r--r-- | minecctl/rcon-commands.c | 26 | ||||
-rw-r--r-- | minecctl/server.c | 21 | ||||
-rw-r--r-- | minecctl/server.h | 1 |
6 files changed, 95 insertions, 81 deletions
diff --git a/minecctl/minecctl.c b/minecctl/minecctl.c index 4a6bf0f..c2d6c19 100644 --- a/minecctl/minecctl.c +++ b/minecctl/minecctl.c @@ -28,7 +28,7 @@ static void dump_server(struct server *server) info("│"); info("│ ▷ server"); info("│ ┌─────"); - info("│ │ name : %s", server->name); + info("│ │ name : %s", server->scfg.name); info("│ │ file_read : %s", server->file_read ? "yes" : "no"); info("│ │ filename : %s", server->scfg.filename); @@ -237,7 +237,7 @@ static bool create_server_from_cmdline_args(struct cfg *cfg) if (!str_to_addrs(cfg->rcon_addrstr, &server->scfg.rcons)) goto error; - server->name = cfg->rcon_addrstr; + server->scfg.name = cfg->rcon_addrstr; cfg->rcon_addrstr = NULL; } @@ -245,8 +245,8 @@ static bool create_server_from_cmdline_args(struct cfg *cfg) if (!str_to_addrs(cfg->mc_addrstr, &server->scfg.remotes)) goto error; - if (!server->name) - server->name = cfg->mc_addrstr; + if (!server->scfg.name) + server->scfg.name = cfg->mc_addrstr; else xfree(cfg->mc_addrstr); 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"); diff --git a/minecctl/misc.c b/minecctl/misc.c index 26cbc86..90189dc 100644 --- a/minecctl/misc.c +++ b/minecctl/misc.c @@ -335,7 +335,7 @@ char *__xstrndup(const char *fn, int line, const char *s, size_t n) "invalid arguments"); ptr = strndup(s, n); - if (ptr) + if (!ptr) die("strdup: %m"); return ptr; } diff --git a/minecctl/rcon-commands.c b/minecctl/rcon-commands.c index cb6ea45..cdbf868 100644 --- a/minecctl/rcon-commands.c +++ b/minecctl/rcon-commands.c @@ -96,22 +96,22 @@ static int rcon_login(struct cfg *cfg, struct server *server) assert_die(cfg && server, "invalid arguments"); if (list_empty(&server->scfg.rcons)) { - error("%s: rcon address unknown", server->name); + error("%s: rcon address unknown", server->scfg.name); goto error; } fd = connect_any(&server->scfg.rcons, &saddr, &error); if (fd < 0) { - verbose("%s: unable to connect - %s", server->name, error); + verbose("%s: unable to connect - %s", server->scfg.name, error); goto error; } else - verbose("%s: connected to %s", server->name, saddr->addrstr); + verbose("%s: connected to %s", server->scfg.name, saddr->addrstr); if (!server->scfg.rcon_password) server->scfg.rcon_password = ask_password(); if (!server->scfg.rcon_password) { - error("%s: can't login - password missing", server->name); + error("%s: can't login - password missing", server->scfg.name); goto error; } @@ -123,10 +123,10 @@ static int rcon_login(struct cfg *cfg, struct server *server) if (!rcon_protocol_verify_response(1, 1, RCON_PACKET_LOGIN, rtype, &error)) { - error("%s: invalid response - %s", server->name, error); + error("%s: invalid response - %s", server->scfg.name, error); goto error; } else - verbose("%s: login ok", server->name); + verbose("%s: login ok", server->scfg.name); return fd; @@ -230,7 +230,7 @@ static bool do_one_info(struct cfg *cfg, struct server *server) if (fd < 0) return false; - info("• %s", server->name); + info("• %s", server->scfg.name); if (get_one_status(fd, buf, sizeof(buf), "seed", 1, "Seed : [ %[^]]]", &reply, tbuf)) info(" Seed: %s", tbuf); @@ -336,7 +336,7 @@ static bool stop_one_server(struct cfg *cfg, struct server *server) fd = rcon_login(cfg, server); if (fd < 0) { info("• %s: %sfail%s - unable to login", - server->name, ansi_red, ansi_normal); + server->scfg.name, ansi_red, ansi_normal); return false; } @@ -345,17 +345,17 @@ static bool stop_one_server(struct cfg *cfg, struct server *server) if (!get_player_count(fd, ¤t, NULL)) { info("• %s: %sfail%s - unable to get player count", - server->name, ansi_red, ansi_normal); + server->scfg.name, ansi_red, ansi_normal); return false; } else if (current > 0) { info("• %s: %sfail%s - has active players " "(use -f to force)", - server->name, ansi_red, ansi_normal); + server->scfg.name, ansi_red, ansi_normal); return false; } } - info("• %s: sending stop command", server->name); + info("• %s: sending stop command", server->scfg.name); rv = send_cmd(fd, "stop"); close(fd); @@ -419,9 +419,9 @@ bool do_console(struct cfg *cfg) return false; prompt = alloca(strlen(program_invocation_short_name) + STRLEN(" (") + - strlen(server->name) + STRLEN("): ") + 1); + strlen(server->scfg.name) + STRLEN("): ") + 1); sprintf(prompt, "%s (%s): ", program_invocation_short_name, - server->name); + server->scfg.name); while (true) { char *tmp; diff --git a/minecctl/server.c b/minecctl/server.c index 8bd7b51..3acc537 100644 --- a/minecctl/server.c +++ b/minecctl/server.c @@ -71,18 +71,12 @@ void server_load_all_known(struct cfg *cfg) while ((dent = readdir(cfg->cfg_dir))) { struct server *server; - char *suffix; if (!config_valid_server_filename(dent, NULL)) continue; server = server_new(dent->d_name); - suffix = strrchr(dent->d_name, '.'); - assert_die(suffix, "Error parsing filename"); - *suffix = '\0'; - server->name = xstrdup(dent->d_name); - list_add(&server->list, &cfg->servers); } } @@ -153,7 +147,7 @@ bool server_read_config(struct cfg *cfg, struct server *server, return false; /* fill in missing parameters from server.properties */ - dfd = open_subdir(dirfd(cfg->data_dir), server->name, false); + dfd = open_subdir(dirfd(cfg->data_dir), server->scfg.name, false); if (dfd < 0) goto out; @@ -193,21 +187,21 @@ bool server_read_all_configs(struct cfg *cfg, bool print_results) if (!server_read_config(cfg, server, &lineno, &error)) { if (lineno != 0 && print_results) info("• %s: %sfail%s - line %u: %s", - server->name, ansi_red, ansi_normal, + server->scfg.name, ansi_red, ansi_normal, lineno, error); else if (print_results) info("• %s: %sfail%s - %s", - server->name, ansi_red, ansi_normal, + server->scfg.name, ansi_red, ansi_normal, error); rv = false; } else if (!scfg_validate(&server->scfg, &error) && print_results) { info("• %s: %sfail%s - %s", - server->name, ansi_red, ansi_normal, + server->scfg.name, ansi_red, ansi_normal, error); rv = false; } else if (print_results) { - info("• %s: %sok%s", server->name, ansi_green, + info("• %s: %sok%s", server->scfg.name, ansi_green, ansi_normal); } } @@ -226,7 +220,7 @@ struct server *server_get_default(struct cfg *cfg) die("No servers defined"); if (!server_read_config(cfg, server, &lineno, &error)) { - error("%s: server_read_config error - %s", server->name, error); + error("%s: server_read_config error - %s", server->scfg.name, error); return NULL; } @@ -242,7 +236,7 @@ bool server_set_default(struct cfg *cfg, const char *name) server_load_all_known(cfg); list_for_each_entry(server, &cfg->servers, list) { - if (streq(name, server->name)) { + if (streq(name, server->scfg.name)) { list_rotate_to_front(&server->list, &cfg->servers); cfg->default_set = true; return true; @@ -263,7 +257,6 @@ void server_free_all(struct cfg *cfg) void server_free(struct server *server) { scfg_delete(&server->scfg); - xfree(server->name); xfree(server); } diff --git a/minecctl/server.h b/minecctl/server.h index 4520d34..47682a5 100644 --- a/minecctl/server.h +++ b/minecctl/server.h @@ -8,7 +8,6 @@ struct server { bool file_read; - char *name; struct server_config scfg; struct list_head list; }; |