From f06ff46151c38b2259c5ee4ae83d38c6f6fc0c8c Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Sun, 12 Jul 2020 02:30:31 +0200 Subject: Teach minecctl to create proper mcserver files, auto-generate systemd service names as necessary --- shared/config-parser.c | 71 ++++++++++++++++++++++++++++++++------------------ shared/config-parser.h | 1 + shared/utils.c | 34 ++++++++++++++++++++++++ shared/utils.h | 2 ++ 4 files changed, 83 insertions(+), 25 deletions(-) (limited to 'shared') diff --git a/shared/config-parser.c b/shared/config-parser.c index 8ea6557..4dc446c 100644 --- a/shared/config-parser.c +++ b/shared/config-parser.c @@ -529,29 +529,17 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async, case SCFG_KEY_SYSTEMD_SERVICE: if (scfg->systemd_service) ERROR("systemd service defined multiple times"); - else { - const char *suffix; - char *tmp; - - suffix = strrchr(value.str, '.'); - if (!suffix || !streq(suffix, ".service")) { - tmp = zmalloc(strlen(value.str) + - STRLEN(".service") + 1); - if (tmp) - sprintf(tmp, "%s.service", - value.str); - } else - tmp = xstrdup(value.str); - - if (!tmp) - ERROR("malloc/strdup failure"); - - scfg->systemd_service = tmp; - scfg->systemd_obj = - systemd_object_path(scfg->systemd_service); - if (!scfg->systemd_obj) - ERROR("failed to create object_path"); - } + + const char *suffix = strrchr(value.str, '.'); + if (!suffix || !streq(suffix, ".service")) + scfg->systemd_service = xsprintf(NULL, + "%s.service", + value.str); + else + scfg->systemd_service = xstrdup(value.str); + + if (!scfg->systemd_service) + ERROR("malloc/strdup failure"); break; @@ -563,6 +551,22 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async, } } + if (!scfg->systemd_service && + (scfg->stop_method == SERVER_STOP_METHOD_SYSTEMD || + scfg->start_method == SERVER_START_METHOD_SYSTEMD)) { + scfg->systemd_service = xsprintf(NULL, + "minecserver@%s.service", + scfg->name); + if (!scfg->systemd_service) + ERROR("failed to create systemd_service string"); + } + + if (scfg->systemd_service && !scfg->systemd_obj) { + scfg->systemd_obj = systemd_object_path(scfg->systemd_service); + if (!scfg->systemd_obj) + ERROR("failed to create object_path"); + } + return true; } @@ -605,14 +609,31 @@ bool scfg_init(struct server_config *scfg, const char *filename) assert_return(scfg, false); if (filename) { + const char *suffix; + + suffix = strrchr(filename, '.'); + if (!suffix || suffix == filename) { + error("invalid filename: %s", filename); + return false; + } + + scfg->name = xstrndup(filename, suffix - filename); + if (!scfg->name) { + error("xstrndup: %m"); + return false; + } + scfg->filename = xstrdup(filename); - if (!scfg->filename) { error("strdup: %m"); + xfree(scfg->name); + scfg->name = NULL; return false; } - } else + } else { + scfg->name = NULL; scfg->filename = NULL; + } scfg->type = SERVER_TYPE_UNDEFINED; scfg->pretty_name = NULL; diff --git a/shared/config-parser.h b/shared/config-parser.h index da5250d..ad7e4b2 100644 --- a/shared/config-parser.h +++ b/shared/config-parser.h @@ -35,6 +35,7 @@ enum server_announce { }; struct server_config { + char *name; char *filename; enum server_type type; char *pretty_name; diff --git a/shared/utils.c b/shared/utils.c index 9bf8cd8..99fcaa3 100644 --- a/shared/utils.c +++ b/shared/utils.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "utils.h" @@ -218,3 +219,36 @@ int strtou16_strict(const char *str, uint16_t *result) *result = val; return 0; } + +char *xsprintf(size_t *rlen, const char *fmt, ...) +{ + va_list ap; + int len; + char *str; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (len < 0) + return NULL; + + len++; + str = zmalloc(len); + if (!str) + return NULL; + + va_start(ap, fmt); + len = vsnprintf(str, len, fmt, ap); + va_end(ap); + + if (len < 0) { + xfree(str); + return NULL; + } + + if (rlen) + *rlen = len; + + return str; +} diff --git a/shared/utils.h b/shared/utils.h index bf1b63a..1291d21 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -89,6 +89,8 @@ void saddr_set_addrstr(struct saddr *saddr); int strtou16_strict(const char *str, uint16_t *result); +char *xsprintf(size_t *rlen, const char *fmt, ...) _printf_(2, 3); + static inline bool empty_str(const char *str) { if (!str || str[0] == '\0') -- cgit v1.2.3