summaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server.c')
-rw-r--r--server.c134
1 files changed, 113 insertions, 21 deletions
diff --git a/server.c b/server.c
index 7ec0804..ee93a24 100644
--- a/server.c
+++ b/server.c
@@ -18,6 +18,7 @@
#include "utils.h"
#include "idle.h"
#include "rcon.h"
+#include "systemd.h"
struct server_local {
struct sockaddr_in46 addr;
@@ -67,6 +68,8 @@ server_free(struct uring_task *task)
free(scfg->pretty_name);
free(scfg->start_exec);
free(scfg->stop_exec);
+ free(scfg->systemd_service);
+ free(scfg->systemd_obj);
free(scfg->name);
free(scfg);
}
@@ -323,6 +326,9 @@ server_start(struct cfg *cfg, struct server *scfg)
case SERVER_START_METHOD_EXEC:
return server_exec(cfg, scfg, scfg->start_exec);
+ case SERVER_START_METHOD_SYSTEMD:
+ return systemd_service_start(cfg, scfg);
+
case SERVER_START_METHOD_UNDEFINED:
default:
break;
@@ -342,6 +348,9 @@ server_stop(struct cfg *cfg, struct server *scfg)
case SERVER_STOP_METHOD_EXEC:
return server_exec(cfg, scfg, scfg->stop_exec);
+ case SERVER_STOP_METHOD_SYSTEMD:
+ return systemd_service_stop(cfg, scfg);
+
case SERVER_STOP_METHOD_RCON:
rcon_init(cfg, scfg);
return true;
@@ -360,65 +369,112 @@ server_commit(struct cfg *cfg, struct server *scfg)
struct server_local *local;
uint16_t port;
- if (!scfg || !scfg->name)
+ if (!scfg || !scfg->name) {
+ fprintf(stderr, "%s: called with invalid parameters\n", __func__);
return false;
+ }
- if (!list_empty(&scfg->proxys))
+ if (!list_empty(&scfg->proxys)) {
+ fprintf(stderr, "%s(%s): proxys not empty?\n", __func__, scfg->name);
return false;
+ }
/* FIXME: running? */
if (scfg->stop_method == SERVER_STOP_METHOD_RCON &&
- (list_empty(&scfg->rcons) || !scfg->rcon_password))
+ (list_empty(&scfg->rcons) || !scfg->rcon_password)) {
+ fprintf(stderr, "%s(%s): rcon stop method but missing rcon password\n", __func__, scfg->name);
+ return false;
+ }
+
+ if ((scfg->start_method == SERVER_START_METHOD_SYSTEMD ||
+ scfg->stop_method == SERVER_STOP_METHOD_SYSTEMD) &&
+ !scfg->systemd_service) {
+ fprintf(stderr, "%s(%s): systemd start/stop method but missing systemd service\n", __func__, scfg->name);
+ return false;
+ }
+
+ if (scfg->systemd_service && !scfg->systemd_obj) {
+ scfg->systemd_obj = systemd_service_object_path(cfg,
+ scfg->systemd_service);
+ if (!scfg->systemd_obj) {
+ fprintf(stderr, "%s(%s): failed to create systemd object path (%s)\n", __func__, scfg->name, scfg->systemd_service);
+ return false;
+ }
+ }
+
+ if (scfg->idle_timeout > 0 &&
+ scfg->stop_method == SERVER_STOP_METHOD_UNDEFINED) {
+ fprintf(stderr, "%s(%s): idle_timeout set but missing stop method\n", __func__, scfg->name);
return false;
+ }
switch (scfg->type) {
case SERVER_TYPE_ANNOUNCE:
- if (scfg->announce_port < 1)
+ if (scfg->announce_port < 1) {
+ fprintf(stderr, "%s(%s): missing announce port\n", __func__, scfg->name);
return false;
- if (scfg->idle_timeout > 0 &&
- scfg->stop_method == SERVER_STOP_METHOD_UNDEFINED)
- return false;
- if (scfg->start_method != SERVER_START_METHOD_UNDEFINED)
+ }
+
+ if (scfg->start_method != SERVER_START_METHOD_UNDEFINED) {
+ fprintf(stderr, "%s(%s): can't set start_method for announce server\n", __func__, scfg->name);
return false;
- if (!list_empty(&scfg->locals))
+ }
+
+ if (!list_empty(&scfg->locals)) {
+ fprintf(stderr, "%s(%s): can't set local addresses for announce server\n", __func__, scfg->name);
return false;
- if (!list_empty(&scfg->remotes))
+ }
+
+ if (!list_empty(&scfg->remotes)) {
+ fprintf(stderr, "%s(%s): can't set remote addresses for announce server\n", __func__, scfg->name);
return false;
+ }
+
break;
case SERVER_TYPE_PROXY:
- if (scfg->announce_port >= 1)
+ if (scfg->announce_port >= 1) {
+ fprintf(stderr, "%s(%s): can't set announce port for proxy server\n", __func__, scfg->name);
return false;
- if (scfg->idle_timeout > 0 &&
- scfg->stop_method == SERVER_STOP_METHOD_UNDEFINED)
- return false;
- if (list_empty(&scfg->locals))
+ }
+
+ if (list_empty(&scfg->locals)) {
+ fprintf(stderr, "%s(%s): missing local addresses for proxy server\n", __func__, scfg->name);
return false;
- if (list_empty(&scfg->remotes))
+ }
+
+ if (list_empty(&scfg->remotes)) {
+ fprintf(stderr, "%s(%s): missing remote addresses for proxy server\n", __func__, scfg->name);
return false;
+ }
list_for_each_entry(local, &scfg->locals, list) {
port = sockaddr_port(&local->addr);
- if (port == 0)
+ if (port == 0) {
+ fprintf(stderr, "%s(%s): invalid local port\n", __func__, scfg->name);
return false;
+ }
if (scfg->announce_port < 1)
scfg->announce_port = port;
if (scfg->announce_port != port) {
- fprintf(stderr, "Multiple announce ports!?\n");
+ fprintf(stderr, "%s(%s): multiple local ports\n", __func__, scfg->name);
return false;
}
}
- if (scfg->announce_port < 1)
+ if (scfg->announce_port < 1) {
+ fprintf(stderr, "%s(%s): can't determine which port to announce\n", __func__, scfg->name);
return false;
+ }
break;
default:
+ fprintf(stderr, "%s(%s): can't determine server type\n", __func__, scfg->name);
return false;
}
@@ -426,12 +482,16 @@ server_commit(struct cfg *cfg, struct server *scfg)
char *suffix;
suffix = strrchr(scfg->name, '.');
- if (!suffix || suffix == scfg->name)
+ if (!suffix || suffix == scfg->name) {
+ fprintf(stderr, "%s(%s): invalid server name\n", __func__, scfg->name);
return false;
+ }
scfg->pretty_name = strndup(scfg->name, suffix - scfg->name);
- if (!scfg->pretty_name)
+ if (!scfg->pretty_name) {
+ fprintf(stderr, "%s(%s): failed to create display name\n", __func__, scfg->name);
return false;
+ }
}
/* FIXME: config, dont reread config if server running, make sure fd is available before this is called */
@@ -443,6 +503,11 @@ server_commit(struct cfg *cfg, struct server *scfg)
idle_init(cfg, scfg);
+ if (scfg->systemd_service) {
+ fprintf(stderr, "Checking if systemd service is running\n");
+ systemd_service_running(cfg, scfg);
+ }
+
return true;
}
@@ -497,6 +562,33 @@ server_set_rcon_password(struct cfg *cfg, struct server *scfg,
}
bool
+server_set_systemd_service(struct cfg *cfg, struct server *scfg,
+ const char *service)
+{
+ const char *suffix;
+ char *tmp;
+
+ if (!cfg || !scfg || empty_str(service) || scfg->systemd_service)
+ return false;
+
+ suffix = strrchr(service, '.');
+ if (!suffix || strcmp(suffix, ".service")) {
+ tmp = malloc(strlen(service) + strlen(".service") + 1);
+ if (tmp)
+ sprintf(tmp, "%s.service", service);
+ } else
+ tmp = strdup(service);
+
+ if (!tmp) {
+ perror("malloc/strdup");
+ return false;
+ }
+
+ scfg->systemd_service = tmp;
+ return true;
+}
+
+bool
server_set_stop_method(struct cfg *cfg, struct server *scfg,
enum server_stop_method stop_method)
{