summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-07-07 18:41:38 +0200
committerDavid Härdeman <david@hardeman.nu>2020-07-07 18:41:38 +0200
commit90e27b4356f2a6ab98e812c4096b0b76f94a8fb3 (patch)
tree7c900e498c426611c90ef8b2ba80d141456d9552
parent0e2db6328946180c47bc09a486fe38ca0364e2af (diff)
Flesh out the ping implementation
-rw-r--r--minecctl/mc-commands.c31
-rw-r--r--minecctl/mc-commands.h3
-rw-r--r--minecctl/misc-commands.c63
-rw-r--r--minecctl/misc-commands.h2
-rw-r--r--minecctl/rcon-commands.c20
-rw-r--r--minecctl/rcon-commands.h5
-rw-r--r--minecproxy/main.c4
-rw-r--r--minecproxy/main.h2
-rw-r--r--minecproxy/meson.build3
-rw-r--r--minecproxy/server.c12
-rw-r--r--minecproxy/systemd.h13
-rw-r--r--shared/meson.build4
-rw-r--r--shared/systemd.c (renamed from minecproxy/systemd.c)89
-rw-r--r--shared/systemd.h13
14 files changed, 156 insertions, 108 deletions
diff --git a/minecctl/mc-commands.c b/minecctl/mc-commands.c
index 7d44451..c65f166 100644
--- a/minecctl/mc-commands.c
+++ b/minecctl/mc-commands.c
@@ -8,32 +8,23 @@
#include "misc.h"
#include "shared/mc-protocol.h"
-bool do_mc_pcount(struct cfg *cfg, unsigned *online, unsigned *max)
+bool do_mc_pcount(struct cfg *cfg, struct server *server, unsigned *online,
+ unsigned *max, const char **error)
{
- struct server *server;
struct saddr *saddr;
- const char *error;
char buf[4096];
size_t plen, off;
ssize_t r;
bool rv = false;
int fd;
- server = server_get_default(cfg);
- if (!server) {
- error("failed to get default server");
- return false;
- }
-
fd = connect_any(&server->scfg.remotes, &saddr, &error);
- if (fd < 0) {
- error("%s: unable to connect - %s", server->name, error);
+ if (fd < 0)
return false;
- }
if (!mc_protocol_create_status_request(buf, sizeof(buf), &plen,
saddr)) {
- error("Failed to create req");
+ *error = "failed to create request";
goto out;
}
@@ -42,7 +33,7 @@ bool do_mc_pcount(struct cfg *cfg, unsigned *online, unsigned *max)
while (off < plen) {
r = write(fd, buf + off, plen - off);
if (r <= 0) {
- error("write failed: %zi (%m)", r);
+ *error = "write failed";
goto out;
}
off += r;
@@ -52,23 +43,23 @@ bool do_mc_pcount(struct cfg *cfg, unsigned *online, unsigned *max)
while (off < sizeof(buf)) {
r = read(fd, buf + off, sizeof(buf) - off);
if (r <= 0) {
- error("Read failed %zi: %m", r);
+ *error = "read failed";
goto out;
}
off += r;
- if (mc_is_handshake_complete(buf, off)) {
- rv = true;
+ if (mc_is_handshake_complete(buf, off))
break;
- }
}
if (!mc_protocol_parse_status_reply(buf, off, online, max)) {
- error("Failed to get player count");
- return false;
+ *error = "failed to get player count";
+ goto out;
}
+ rv = true;
+
out:
close(fd);
return rv;
diff --git a/minecctl/mc-commands.h b/minecctl/mc-commands.h
index c6e2e6f..493a976 100644
--- a/minecctl/mc-commands.h
+++ b/minecctl/mc-commands.h
@@ -2,6 +2,7 @@
#ifndef foomccommandshfoo
#define foomccomanndshfoo
-bool do_mc_pcount(struct cfg *cfg, unsigned *online, unsigned *max);
+bool do_mc_pcount(struct cfg *cfg, struct server *server, unsigned *online,
+ unsigned *max, const char **error);
#endif
diff --git a/minecctl/misc-commands.c b/minecctl/misc-commands.c
index f89afb6..1870e07 100644
--- a/minecctl/misc-commands.c
+++ b/minecctl/misc-commands.c
@@ -5,6 +5,7 @@
#include "misc-commands.h"
#include "rcon-commands.h"
#include "mc-commands.h"
+#include "shared/systemd.h"
bool do_list(struct cfg *cfg)
{
@@ -135,13 +136,65 @@ bool do_lint(struct cfg *cfg)
bool do_pcount(struct cfg *cfg)
{
- unsigned x, y;
+ unsigned online, max;
+ struct server *server;
+ const char *error;
+
+ server = server_get_default(cfg);
+ if (!server) {
+ error("failed to get default server");
+ return false;
+ }
- if (do_rcon_pcount(cfg, &y, &x))
- error("Rcon says %u/%u", y, x);
+ if (do_rcon_pcount(cfg, server, &online, &max, &error))
+ info("Rcon says %u/%u", online, max);
- if (do_mc_pcount(cfg, &y, &x))
- error("MC says %u/%u", y, x);
+ if (do_mc_pcount(cfg, server, &online, &max, &error))
+ info("MC says %u/%u", online, max);
return true;
}
+
+bool do_ping(struct cfg *cfg)
+{
+ 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;
+ }
+
+ info("• %s", server->name);
+
+ if (list_empty(&server->scfg.rcons))
+ info(" rcon : not configured");
+ else if (!do_rcon_pcount(cfg, server, &online, &max, &error))
+ info(" rcon : %sfail%s (%s)",
+ ansi_red, ansi_normal, error);
+ else
+ info(" rcon : %sok%s", ansi_green, ansi_normal);
+
+ if (list_empty(&server->scfg.remotes))
+ info(" mc : not configured");
+ else if (!do_mc_pcount(cfg, server, &online, &max, &error))
+ info(" mc : %sfail%s (%s)",
+ ansi_red, ansi_normal, error);
+ else
+ info(" mc : %sok%s", ansi_green, ansi_normal);
+
+ if (!server->scfg.systemd_service || !server->scfg.systemd_obj)
+ info(" systemd service : not configured");
+ else if (!systemd_service_running(&server->scfg, &error))
+ info(" systemd service : %sfail%s (%s)",
+ ansi_red, ansi_normal, error);
+ else
+ info(" systemd service : %sactive%s", ansi_green, ansi_normal);
+ systemd_delete();
+
+ return true;
+}
+
diff --git a/minecctl/misc-commands.h b/minecctl/misc-commands.h
index 8ea4127..ac2fd54 100644
--- a/minecctl/misc-commands.h
+++ b/minecctl/misc-commands.h
@@ -8,4 +8,6 @@ bool do_lint(struct cfg *cfg);
bool do_pcount(struct cfg *cfg);
+bool do_ping(struct cfg *cfg);
+
#endif
diff --git a/minecctl/rcon-commands.c b/minecctl/rcon-commands.c
index f18f082..61a682c 100644
--- a/minecctl/rcon-commands.c
+++ b/minecctl/rcon-commands.c
@@ -12,8 +12,8 @@
#include "shared/utils.h"
#include "shared/rcon-protocol.h"
#include "minecctl.h"
-#include "rcon-commands.h"
#include "server.h"
+#include "rcon-commands.h"
#include "misc.h"
static void send_packet(int sfd, const char *buf, size_t len)
@@ -93,6 +93,7 @@ static void send_msg(int sfd, char *buf, size_t len, enum rcon_packet_type type,
rcon_packet_id++;
}
+/* FIXME: return error message */
static int rcon_login(struct cfg *cfg, struct server *server)
{
const char *error;
@@ -296,12 +297,6 @@ bool do_status(struct cfg *cfg)
return true;
}
-bool do_ping(_unused_ struct cfg *cfg)
-{
- die("Not implemented");
- return false;
-}
-
static bool get_player_count(int fd, unsigned *current, unsigned *max)
{
char buf[4096];
@@ -382,18 +377,21 @@ bool do_stop_all(struct cfg *cfg)
return rv;
}
-bool do_rcon_pcount(struct cfg *cfg, unsigned *online, unsigned *max)
+bool do_rcon_pcount(struct cfg *cfg, struct server *server, unsigned *online,
+ unsigned *max, const char **error)
{
- struct server *server;
bool rv;
int fd;
- server = server_get_default(cfg);
fd = rcon_login(cfg, server);
- if (fd < 0)
+ if (fd < 0) {
+ *error = "failed to login";
return false;
+ }
rv = get_player_count(fd, online, max);
+ if (!rv)
+ *error = "failed to get player count";
close(fd);
diff --git a/minecctl/rcon-commands.h b/minecctl/rcon-commands.h
index b2720b4..84d5529 100644
--- a/minecctl/rcon-commands.h
+++ b/minecctl/rcon-commands.h
@@ -4,13 +4,12 @@
bool do_status(struct cfg *cfg);
-bool do_ping(struct cfg *cfg);
-
bool do_stop(struct cfg *cfg);
bool do_stop_all(struct cfg *cfg);
-bool do_rcon_pcount(struct cfg *cfg, unsigned *online, unsigned *max);
+bool do_rcon_pcount(struct cfg *cfg, struct server *server, unsigned *online,
+ unsigned *max, const char **error);
bool do_console(struct cfg *cfg);
diff --git a/minecproxy/main.c b/minecproxy/main.c
index 238b612..c51b01c 100644
--- a/minecproxy/main.c
+++ b/minecproxy/main.c
@@ -24,7 +24,7 @@
#include "server.h"
#include "server-config.h"
#include "announce.h"
-#include "systemd.h"
+#include "shared/systemd.h"
#include "igmp.h"
#include "idle.h"
#include "ptimer.h"
@@ -177,7 +177,7 @@ static void cfg_free(struct uring_task *task)
assert_return(task && xcfg == cfg);
debug(DBG_SIG, "called");
- systemd_delete(cfg);
+ systemd_delete();
xfree(cfg->igmp_iface);
cfg->igmp_iface = NULL;
exiting = true;
diff --git a/minecproxy/main.h b/minecproxy/main.h
index 12b16df..2c7be83 100644
--- a/minecproxy/main.h
+++ b/minecproxy/main.h
@@ -99,8 +99,6 @@ struct cfg {
struct ptimer *ptimer;
struct igmp *igmp;
struct idle *idle;
- struct sd_bus *sd_bus;
- bool sd_bus_failed;
struct uring_task task;
struct list_head servers;
};
diff --git a/minecproxy/meson.build b/minecproxy/meson.build
index 959b975..155840c 100644
--- a/minecproxy/meson.build
+++ b/minecproxy/meson.build
@@ -11,17 +11,14 @@ minecproxy_sources = [
'idle.c',
'ptimer.c',
'igmp.c',
- 'systemd.c',
'misc.c',
]
dep_liburing = dependency('liburing')
-dep_libsystemd = dependency('libsystemd')
dep_libcapng = dependency('libcap-ng')
minecproxy_deps = [
dep_liburing,
- dep_libsystemd,
dep_libcapng,
dep_config_h,
dep_libshared,
diff --git a/minecproxy/server.c b/minecproxy/server.c
index d24c0ad..b1e9b05 100644
--- a/minecproxy/server.c
+++ b/minecproxy/server.c
@@ -18,9 +18,9 @@
#include "server-config.h"
#include "server-proxy.h"
#include "server-rcon.h"
-#include "shared/config-parser.h"
#include "idle.h"
-#include "systemd.h"
+#include "shared/config-parser.h"
+#include "shared/systemd.h"
void server_refdump(struct server *server)
{
@@ -218,13 +218,15 @@ static bool server_exec(struct server *server, const char *cmd)
static bool server_check_running(struct server *server)
{
+ const char *error;
+
assert_return(server, false);
/* FIXME: other methods, rcon? */
if (server->scfg.systemd_service) {
verbose("%s: checking if systemd service is running",
server->name);
- if (systemd_service_running(server)) {
+ if (systemd_service_running(&server->scfg, &error)) {
server->state = SERVER_STATE_RUNNING;
return true;
} else {
@@ -252,7 +254,7 @@ bool server_start(struct server *server)
server->name,
server->scfg.systemd_service);
- if (systemd_service_start(server)) {
+ if (systemd_service_start(&server->scfg)) {
server->state = SERVER_STATE_RUNNING;
return true;
} else
@@ -281,7 +283,7 @@ bool server_stop(struct server *server)
verbose("Stopping server %s via systemd (%s)",
server->name,
server->scfg.systemd_service);
- if (systemd_service_stop(server)) {
+ if (systemd_service_stop(&server->scfg)) {
server->state = SERVER_STATE_STOPPED;
return true;
} else
diff --git a/minecproxy/systemd.h b/minecproxy/systemd.h
deleted file mode 100644
index f3f96e4..0000000
--- a/minecproxy/systemd.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef foosystemdhfoo
-#define foosystemdhfoo
-
-void systemd_delete();
-
-bool systemd_service_running(struct server *server);
-
-bool systemd_service_stop(struct server *server);
-
-bool systemd_service_start(struct server *server);
-
-#endif
diff --git a/shared/meson.build b/shared/meson.build
index 021fe11..a937e92 100644
--- a/shared/meson.build
+++ b/shared/meson.build
@@ -3,10 +3,14 @@ srcs_libshared = [
'rcon-protocol.c',
'mc-protocol.c',
'config-parser.c',
+ 'systemd.c',
'utils.c',
]
+dep_libsystemd = dependency('libsystemd')
+
deps_libshared = [
+ dep_libsystemd,
dep_config_h,
]
diff --git a/minecproxy/systemd.c b/shared/systemd.c
index 94d5b8b..c45c7c5 100644
--- a/minecproxy/systemd.c
+++ b/shared/systemd.c
@@ -4,37 +4,41 @@
#include <systemd/sd-bus.h>
#include <errno.h>
-#include "main.h"
-#include "server.h"
+#include "utils.h"
+#include "config-parser.h"
#include "systemd.h"
#include "config.h"
+static sd_bus *bus = NULL;
+static bool bus_failed = false;
+
void systemd_delete()
{
- assert_return_silent(cfg->sd_bus);
+ assert_return_silent(bus);
- sd_bus_unref(cfg->sd_bus);
- cfg->sd_bus = NULL;
+ sd_bus_unref(bus);
+ bus = NULL;
+ bus_failed = false;
}
static sd_bus *get_bus()
{
int r;
- if (cfg->sd_bus_failed)
+ if (bus_failed)
return NULL;
- if (!cfg->sd_bus) {
- r = sd_bus_open_user(&cfg->sd_bus);
+ if (!bus) {
+ r = sd_bus_open_user(&bus);
if (r < 0) {
error("failed to connect to user system bus: %s",
strerror(-r));
- cfg->sd_bus_failed = true;
+ bus_failed = true;
return NULL;
}
}
- return cfg->sd_bus;
+ return bus;
}
/*
@@ -48,48 +52,48 @@ static sd_bus *get_bus()
* "org.freedesktop.systemd1.Unit"
* "ActiveState"
*/
-bool systemd_service_running(struct server *server)
+bool systemd_service_running(struct server_config *scfg, const char **error)
{
sd_bus *bus = get_bus();
- sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_error sderror = SD_BUS_ERROR_NULL;
char *status = NULL;
bool running = false;
int r;
- assert_return(server && bus && server->scfg.systemd_service &&
- server->scfg.systemd_obj,
- false);
+ assert_return(bus && error && scfg && scfg->systemd_service &&
+ scfg->systemd_obj, false);
again:
r = sd_bus_get_property_string(bus, SYSTEMD_DBUS_SERVICE,
- server->scfg.systemd_obj,
+ scfg->systemd_obj,
SYSTEMD_DBUS_INTERFACE, "ActiveState",
- &error, &status);
+ &sderror, &status);
if (r < 0) {
- if (sd_bus_error_get_errno(&error) == EINTR)
+ if (sd_bus_error_get_errno(&sderror) == EINTR)
goto again;
- error("failed to get status for service %s (%s): %s",
- server->scfg.systemd_service, server->scfg.systemd_obj,
- error.message);
- goto out;
- }
+ debug(DBG_SYSD, "failed to get status for server %s (%s): %s",
+ scfg->systemd_service, scfg->systemd_obj, sderror.message);
+ *error = "failed to get service status";
- if (streq(status, "active")) {
+ } else if (streq(status, "active")) {
running = true;
debug(DBG_SYSD, "systemd service %s (%s) is active",
- server->scfg.systemd_service, server->scfg.systemd_obj);
- } else
- debug(DBG_SYSD, "systemd service %s (%s) is not active",
- server->scfg.systemd_service, server->scfg.systemd_obj);
+ scfg->systemd_service, scfg->systemd_obj);
+
+ } else {
+ debug(DBG_SYSD, "systemd service %s (%s) is not active (%s)",
+ scfg->systemd_service, scfg->systemd_obj, status);
+ *error = "service not active";
+ }
-out:
free(status);
- sd_bus_error_free(&error);
+ sd_bus_error_free(&sderror);
return running;
}
-static bool systemd_service_action(struct server *server, const char *action)
+static bool systemd_service_action(struct server_config *scfg,
+ const char *action)
{
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *m = NULL;
@@ -98,12 +102,11 @@ static bool systemd_service_action(struct server *server, const char *action)
bool performed = false;
int r;
- assert_return(server && bus && server->scfg.systemd_service &&
- server->scfg.systemd_obj && action,
- false);
+ assert_return(bus && scfg && scfg->systemd_service &&
+ scfg->systemd_obj && action, false);
again:
- r = sd_bus_call_method(bus, SYSTEMD_DBUS_SERVICE, server->scfg.systemd_obj,
+ r = sd_bus_call_method(bus, SYSTEMD_DBUS_SERVICE, scfg->systemd_obj,
SYSTEMD_DBUS_INTERFACE, action, &error, &m, "s",
"fail");
if (r < 0) {
@@ -111,7 +114,7 @@ again:
goto again;
error("failed to perform action %s on systemd service %s: %s",
- action, server->scfg.systemd_service, error.message);
+ action, scfg->systemd_service, error.message);
goto out;
}
@@ -122,7 +125,7 @@ again:
}
verbose("action %s queued for service %s", action,
- server->scfg.systemd_service);
+ scfg->systemd_service);
performed = true;
out:
@@ -140,11 +143,11 @@ out:
* --object-path /org/freedesktop/systemd1/unit/mc_40world1_2eservice
* --method org.freedesktop.systemd1.Unit.Stop "fail"
*/
-bool systemd_service_stop(struct server *server)
+bool systemd_service_stop(struct server_config *scfg)
{
- assert_return(server, false);
+ assert_return(scfg, false);
- return systemd_service_action(server, "Stop");
+ return systemd_service_action(scfg, "Stop");
}
/*
@@ -156,9 +159,9 @@ bool systemd_service_stop(struct server *server)
* --object-path /org/freedesktop/systemd1/unit/mc_40world1_2eservice
* --method org.freedesktop.systemd1.Unit.Start "fail"
*/
-bool systemd_service_start(struct server *server)
+bool systemd_service_start(struct server_config *scfg)
{
- assert_return(server, false);
+ assert_return(scfg, false);
- return systemd_service_action(server, "Start");
+ return systemd_service_action(scfg, "Start");
}
diff --git a/shared/systemd.h b/shared/systemd.h
new file mode 100644
index 0000000..0da1eca
--- /dev/null
+++ b/shared/systemd.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef foosharedsystemdhfoo
+#define foosharedsystemdhfoo
+
+void systemd_delete();
+
+bool systemd_service_running(struct server_config *scfg, const char **error);
+
+bool systemd_service_stop(struct server_config *scfg);
+
+bool systemd_service_start(struct server_config *scfg);
+
+#endif