summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-07-07 22:32:11 +0200
committerDavid Härdeman <david@hardeman.nu>2020-07-07 22:32:11 +0200
commit4ae60696aed938347cc1cf2a5d8f5a2b86292132 (patch)
treeb83ad5727b56f010c0e90bb3f80b4ff95bf04082
parente685df91251ca111e42306e6f36835e55f052c0c (diff)
Improve handling of info and status commands
-rw-r--r--minecctl/mc-commands.c6
-rw-r--r--minecctl/minecctl.c25
-rw-r--r--minecctl/minecctl.h1
-rw-r--r--minecctl/misc-commands.c92
-rw-r--r--minecctl/rcon-commands.c53
-rw-r--r--minecctl/server.c36
-rw-r--r--minecctl/server.h2
7 files changed, 134 insertions, 81 deletions
diff --git a/minecctl/mc-commands.c b/minecctl/mc-commands.c
index c65f166..fb87430 100644
--- a/minecctl/mc-commands.c
+++ b/minecctl/mc-commands.c
@@ -8,8 +8,8 @@
#include "misc.h"
#include "shared/mc-protocol.h"
-bool do_mc_pcount(struct cfg *cfg, struct server *server, unsigned *online,
- unsigned *max, const char **error)
+bool do_mc_pcount(_unused_ struct cfg *cfg, struct server *server,
+ unsigned *online, unsigned *max, const char **error)
{
struct saddr *saddr;
char buf[4096];
@@ -18,7 +18,7 @@ bool do_mc_pcount(struct cfg *cfg, struct server *server, unsigned *online,
bool rv = false;
int fd;
- fd = connect_any(&server->scfg.remotes, &saddr, &error);
+ fd = connect_any(&server->scfg.remotes, &saddr, error);
if (fd < 0)
return false;
diff --git a/minecctl/minecctl.c b/minecctl/minecctl.c
index 925092e..56e386e 100644
--- a/minecctl/minecctl.c
+++ b/minecctl/minecctl.c
@@ -265,21 +265,22 @@ error:
}
static inline void get_optional_server_arg(struct cfg *cfg, char *const **argv,
- bool more)
+ bool server_mandatory, bool more)
{
- if (!cfg->rcon_addrstr) {
- if (!**argv) {
+ if (!cfg->rcon_addrstr && !cfg->mc_addrstr) {
+ if (server_mandatory && !**argv) {
error("Missing arguments");
usage(false);
}
- if (!server_set_default(cfg, **argv)) {
+ if (**argv && !server_set_default(cfg, **argv)) {
error("\"%s\" is not a known server or command",
**argv);
usage(false);
}
- (*argv)++;
+ if (**argv)
+ (*argv)++;
}
if (!more && **argv) {
@@ -336,29 +337,29 @@ static void parse_command(struct cfg *cfg, char *const *argv)
cfg->cmd = do_stop_all;
break;
case CMD_INFO:
- get_optional_server_arg(cfg, &argv, false);
+ get_optional_server_arg(cfg, &argv, false, false);
cfg->cmd = do_info;
break;
case CMD_STATUS:
- get_optional_server_arg(cfg, &argv, false);
+ get_optional_server_arg(cfg, &argv, false, false);
cfg->cmd = do_status;
break;
case CMD_STOP:
- get_optional_server_arg(cfg, &argv, false);
+ get_optional_server_arg(cfg, &argv, true, false);
cfg->cmd = do_stop;
break;
case CMD_PCOUNT:
- get_optional_server_arg(cfg, &argv, false);
+ get_optional_server_arg(cfg, &argv, true, false);
cfg->cmd = do_pcount;
break;
case CMD_CONSOLE:
- get_optional_server_arg(cfg, &argv, false);
+ get_optional_server_arg(cfg, &argv, true, false);
cfg->cmd = do_console;
break;
case CMD_COMMAND:
_fallthrough_;
case CMD_COMMANDS:
- get_optional_server_arg(cfg, &argv, true);
+ get_optional_server_arg(cfg, &argv, true, true);
if (!*argv) {
error("Missing arguments");
@@ -373,7 +374,7 @@ static void parse_command(struct cfg *cfg, char *const *argv)
break;
case CMD_INVALID:
/* shorthand notation */
- get_optional_server_arg(cfg, &argv, true);
+ get_optional_server_arg(cfg, &argv, true, true);
if (!*argv) {
/* !CMD = console */
diff --git a/minecctl/minecctl.h b/minecctl/minecctl.h
index 14243c6..16199a3 100644
--- a/minecctl/minecctl.h
+++ b/minecctl/minecctl.h
@@ -9,6 +9,7 @@ struct cfg {
char *mc_addrstr;
char **commands;
bool force_stop;
+ bool default_set;
bool (*cmd)(struct cfg *cfg);
struct list_head servers;
};
diff --git a/minecctl/misc-commands.c b/minecctl/misc-commands.c
index c7c09d0..e23de37 100644
--- a/minecctl/misc-commands.c
+++ b/minecctl/misc-commands.c
@@ -58,40 +58,11 @@ static bool saddr_match(struct list_head *la, struct list_head *lb)
bool do_lint(struct cfg *cfg)
{
- struct server *server;
- unsigned lineno;
- const char *error;
- bool rv = true;
struct server *a, *b;
unsigned ia, ib;
+ bool rv = true;
- /* server->scfg.filename check excludes servers created from cmdline */
- list_for_each_entry(server, &cfg->servers, list) {
- if (!server->scfg.filename)
- continue;
-
- if (!server_read_config(cfg, server, &lineno, &error)) {
- if (lineno != 0)
- info("• %s: %sfail%s - line %u: %s",
- server->name, ansi_red, ansi_normal,
- lineno, error);
- else
- info("• %s: %sfail%s - %s",
- server->name, ansi_red, ansi_normal,
- error);
- rv = false;
- } else if (!scfg_validate(&server->scfg, &error)) {
- info("• %s: %sfail%s - %s",
- server->name, ansi_red, ansi_normal,
- error);
- rv = false;
- } else {
- info("• %s: %sok%s", server->name, ansi_green,
- ansi_normal);
- }
- }
-
- info("");
+ rv = server_read_all_configs(cfg, true);
dump_config(cfg);
@@ -155,44 +126,65 @@ bool do_pcount(struct cfg *cfg)
return true;
}
-bool do_status(struct cfg *cfg)
+static bool do_one_status(struct cfg *cfg, struct server *server)
{
- struct server *server;
- const char *error;
unsigned online, max;
-
- /* FIXME: Do all servers when default not given */
- server = server_get_default(cfg);
- if (!server) {
- error("failed to get default server");
- return false;
- }
+ const char *error;
+ bool rv = true;
info("• %s", server->name);
if (list_empty(&server->scfg.rcons))
info(" rcon : not configured");
- else if (!do_rcon_pcount(cfg, server, &online, &max, &error))
+ else if (do_rcon_pcount(cfg, server, &online, &max, &error))
+ info(" rcon : %sok%s", ansi_green, ansi_normal);
+ else {
info(" rcon : %sfail%s (%s)",
ansi_red, ansi_normal, error);
- else
- info(" rcon : %sok%s", ansi_green, ansi_normal);
+ rv = false;
+ }
if (list_empty(&server->scfg.remotes))
info(" mc : not configured");
- else if (!do_mc_pcount(cfg, server, &online, &max, &error))
+ else if (do_mc_pcount(cfg, server, &online, &max, &error))
+ info(" mc : %sok%s", ansi_green, ansi_normal);
+ else {
info(" mc : %sfail%s (%s)",
ansi_red, ansi_normal, error);
- else
- info(" mc : %sok%s", ansi_green, ansi_normal);
+ rv = false;
+ }
if (!server->scfg.systemd_service || !server->scfg.systemd_obj)
info(" systemd service : not configured");
- else if (!systemd_service_running(&server->scfg, &error))
+ else if (systemd_service_running(&server->scfg, &error))
+ info(" systemd service : %sactive%s", ansi_green, ansi_normal);
+ else {
info(" systemd service : %sfail%s (%s)",
ansi_red, ansi_normal, error);
- else
- info(" systemd service : %sactive%s", ansi_green, ansi_normal);
+ rv = false;
+ }
+
+ return rv;
+}
+
+bool do_status(struct cfg *cfg)
+{
+ struct server *server;
+
+ if (cfg->default_set) {
+ server = server_get_default(cfg);
+ if (!server) {
+ error("failed to get default server");
+ return false;
+ }
+
+ do_one_status(cfg, server);
+ } else {
+ server_read_all_configs(cfg, false);
+ list_for_each_entry(server, &cfg->servers, list)
+ do_one_status(cfg, server);
+ }
+
systemd_delete();
return true;
diff --git a/minecctl/rcon-commands.c b/minecctl/rcon-commands.c
index 0c4fd7e..bab0004 100644
--- a/minecctl/rcon-commands.c
+++ b/minecctl/rcon-commands.c
@@ -226,7 +226,7 @@ static bool get_one_status(int fd, char *buf, size_t len, const char *cmd,
return false;
}
-bool do_info(struct cfg *cfg)
+static bool do_one_info(struct cfg *cfg, struct server *server)
{
char buf[4096];
char tbuf[4096];
@@ -235,64 +235,85 @@ bool do_info(struct cfg *cfg)
unsigned epacks, apacks;
unsigned bannedplayers, bannedips;
int fd;
- struct server *server;
- server = server_get_default(cfg);
fd = rcon_login(cfg, server);
if (fd < 0)
return false;
+ info("• %s", server->name);
if (get_one_status(fd, buf, sizeof(buf), "seed", 1, "Seed : [ %[^]]]",
&reply, tbuf))
- info("Seed: %s", tbuf);
+ info(" Seed: %s", tbuf);
if (get_one_status(fd, buf, sizeof(buf), "difficulty", 1,
"The difficulty is %s", &reply, tbuf))
- info("Difficulty: %s", tbuf);
+ info(" Difficulty: %s", tbuf);
if (get_one_status(fd, buf, sizeof(buf), "list", 2,
"There are %u of a max %u players online", &reply,
&cplayers, &maxplayers))
- info("Players: %u/%u", cplayers, maxplayers);
+ info(" Players: %u/%u", cplayers, maxplayers);
if (get_one_status(fd, buf, sizeof(buf), "time query day", 1,
"The time is %u", &reply, &gtime))
- info("In-game days: %u", gtime);
+ info(" In-game days: %u", gtime);
if (get_one_status(fd, buf, sizeof(buf), "time query gametime", 1,
"The time is %u", &reply, &gtime))
- info("World age: %ud:%02uh:%02um", mctime_days(gtime),
+ info(" World age: %ud:%02uh:%02um", mctime_days(gtime),
mctime_hh(gtime), mctime_mm(gtime));
if (get_one_status(fd, buf, sizeof(buf), "time query daytime", 1,
"The time is %u", &reply, &gtime))
- info("Current in-game time: %02uh:%02um",
+ info(" Current in-game time: %02uh:%02um",
mctime_hh(gtime + MCTIME_OFFSET),
mctime_mm(gtime + MCTIME_OFFSET));
if (get_one_status(fd, buf, sizeof(buf), "datapack list enabled", 2,
"There are %u data packs enabled: %[^\n]", &reply,
&epacks, tbuf))
- info("Enabled data packs (%u): %s", epacks, tbuf);
+ info(" Enabled data packs (%u): %s", epacks, tbuf);
if (get_one_status(fd, buf, sizeof(buf), "datapack list available", 2,
"There are %u data packs available : %[^\n]", &reply,
&apacks, tbuf))
- info("Available data packs (%u): %s", apacks, tbuf);
+ info(" Available data packs (%u): %s", apacks, tbuf);
else if (streq(reply, "There are no more data packs available"))
- info("Available data packs: none");
+ info(" Available data packs: none");
if (get_one_status(fd, buf, sizeof(buf), "banlist players", 1,
"There are %u bans", &reply, &bannedplayers))
- info("Banned players: %u", bannedplayers);
+ info(" Banned players: %u", bannedplayers);
else if (streq(reply, "There are no bans"))
- info("Banned players: 0");
+ info(" Banned players: 0");
if (get_one_status(fd, buf, sizeof(buf), "banlist ips", 1,
"There are %u bans", &reply, &bannedips))
- info("Banned IPs: %u", bannedips);
+ info(" Banned IPs: %u", bannedips);
else if (streq(reply, "There are no bans"))
- info("Banned IPs: 0");
+ info(" Banned IPs: 0");
+
+ close(fd);
+ return true;
+}
+
+bool do_info(struct cfg *cfg)
+{
+ struct server *server;
+
+ if (cfg->default_set) {
+ server = server_get_default(cfg);
+ if (!server) {
+ error("failed to get default server");
+ return false;
+ }
+
+ do_one_info(cfg, server);
+ } else {
+ server_read_all_configs(cfg, false);
+ list_for_each_entry(server, &cfg->servers, list)
+ do_one_info(cfg, server);
+ }
return true;
}
diff --git a/minecctl/server.c b/minecctl/server.c
index 979c15f..599be1f 100644
--- a/minecctl/server.c
+++ b/minecctl/server.c
@@ -78,6 +78,41 @@ bool server_read_config(struct cfg *cfg, struct server *server,
return true;
}
+bool server_read_all_configs(struct cfg *cfg, bool print_results)
+{
+ struct server *server;
+ unsigned lineno;
+ const char *error;
+ bool rv = true;
+
+ /* server->scfg.filename check excludes servers created from cmdline */
+ list_for_each_entry(server, &cfg->servers, list) {
+ if (!server->scfg.filename)
+ continue;
+
+ 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,
+ lineno, error);
+ else if (print_results)
+ info("• %s: %sfail%s - %s",
+ server->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,
+ error);
+ rv = false;
+ } else if (print_results) {
+ info("• %s: %sok%s", server->name, ansi_green,
+ ansi_normal);
+ }
+ }
+}
+
struct server *server_get_default(struct cfg *cfg)
{
struct server *server;
@@ -105,6 +140,7 @@ bool server_set_default(struct cfg *cfg, const char *name)
list_for_each_entry(server, &cfg->servers, list) {
if (streq(name, server->name)) {
list_rotate_to_front(&server->list, &cfg->servers);
+ cfg->default_set = true;
return true;
}
}
diff --git a/minecctl/server.h b/minecctl/server.h
index ace1943..556187d 100644
--- a/minecctl/server.h
+++ b/minecctl/server.h
@@ -16,6 +16,8 @@ struct server {
bool server_read_config(struct cfg *cfg, struct server *server,
unsigned *lineno, const char **error);
+bool server_read_all_configs(struct cfg *cfg, bool print_results);
+
struct server *server_get_default(struct cfg *cfg);
bool server_set_default(struct cfg *cfg, const char *name);