summaryrefslogtreecommitdiff
path: root/minecctl
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-07-09 22:58:22 +0200
committerDavid Härdeman <david@hardeman.nu>2020-07-09 22:58:22 +0200
commit3dc8d84af1753b41fe37b3b3954731379dc579aa (patch)
treeb9f5ba58a13457c2a4323a6ca2dede014c066457 /minecctl
parent984f586e3ef70b9db759ce48da4f06f0a6680c6f (diff)
Implement new command for minecctl
Diffstat (limited to 'minecctl')
-rw-r--r--minecctl/minecctl-commands.h5
-rw-r--r--minecctl/minecctl.c14
-rw-r--r--minecctl/misc-commands.c140
-rw-r--r--minecctl/misc-commands.h2
4 files changed, 137 insertions, 24 deletions
diff --git a/minecctl/minecctl-commands.h b/minecctl/minecctl-commands.h
index 16cf511..f50bc6c 100644
--- a/minecctl/minecctl-commands.h
+++ b/minecctl/minecctl-commands.h
@@ -5,6 +5,7 @@
enum commands {
CMD_INVALID = 0,
CMD_INIT,
+ CMD_NEW,
CMD_LIST,
CMD_LINT,
CMD_INFO,
@@ -25,6 +26,10 @@ static struct command_list {
.cmd = CMD_INIT,
},
{
+ .name = "new",
+ .cmd = CMD_NEW,
+ },
+ {
.name = "list",
.cmd = CMD_LIST,
},
diff --git a/minecctl/minecctl.c b/minecctl/minecctl.c
index b374f18..3b1da80 100644
--- a/minecctl/minecctl.c
+++ b/minecctl/minecctl.c
@@ -157,6 +157,7 @@ _noreturn_ static void usage(bool no_error)
"\n"
"Valid commands:\n"
" init perform initial setup\n"
+ " new SERVER create a new server\n"
" list list known servers\n"
" lint check validity of server configuration files\n"
" info [SERVER] show information about a running SERVER (or all known servers)\n"
@@ -178,7 +179,7 @@ _noreturn_ static void usage(bool no_error)
" -m, --mc-address=ADDR connect to Minecraft server at ADDR\n"
" (only relevant for some commands, can also\n"
" use environment variable MC_ADDRESS)\n"
- " -c, --cfgdir=DIR look for server configuration files in DIR\n"
+ " -c, --cfgdir=DIR look for configuration files in DIR\n"
" -f, --force stop server even if it has players\n"
" -v, --verbose enable extra logging\n"
" -d, --debug enable debugging information\n"
@@ -324,6 +325,17 @@ static void parse_command(struct cfg *cfg, char *const *argv)
}
cfg->cmd = do_init;
break;
+ case CMD_NEW:
+ if (!*argv) {
+ error("Missing arguments");
+ usage(false);
+ } else if (*(argv + 1)) {
+ error("Too many arguments");
+ usage(false);
+ }
+ cfg->commands = strv_copy(argv);
+ cfg->cmd = do_new;
+ break;
case CMD_LIST:
if (*argv) {
error("Too many arguments");
diff --git a/minecctl/misc-commands.c b/minecctl/misc-commands.c
index 5a6fe3a..34cbedf 100644
--- a/minecctl/misc-commands.c
+++ b/minecctl/misc-commands.c
@@ -149,26 +149,17 @@ out:
return rv;
}
-static bool create_config_tree(int xfd)
+static bool create_server_cfg(int sfd, int cfd, const char *name,
+ const char *filename)
{
- int mfd = -1, sfd = -1, efd = -1, cfd = -1;
+ int efd = -1;
bool rv = false;
- mfd = open_subdir(xfd, "minecproxy", true);
- if (mfd < 0)
- goto out;
-
- sfd = open_subdir(mfd, "servers", true);
- if (sfd < 0)
- goto out;
-
- if (!write_cfg_file(sfd, "README.TXT", ___examples_README_TXT,
- ___examples_README_TXT_len))
- goto out;
-
- efd = open_subdir(sfd, "example", true);
- if (efd < 0)
+ efd = open_subdir(sfd, name, true);
+ if (efd < 0) {
+ error("Failed to create configuration directory \"%s\"", name);
goto out;
+ }
if (!write_cfg_file(efd, "eula.txt", ___examples_eula_txt,
___examples_eula_txt_len))
@@ -182,19 +173,48 @@ static bool create_config_tree(int xfd)
if (!create_link(efd, "server.jar", "../server.jar"))
goto out;
- cfd = open_subdir(mfd, "config", true);
- if (cfd < 0)
- goto out;
-
- if (!write_cfg_file(cfd, "example.mcserver",
+ if (!write_cfg_file(cfd, filename,
___examples_example_mcserver,
___examples_example_mcserver_len))
goto out;
+ rv = true;
+
+out:
+ if (efd >= 0)
+ close(efd);
+
+ return rv;
+}
+
+static bool create_config_tree(int xfd)
+{
+ int mfd = -1, sfd = -1, cfd = -1;
+ bool rv = false;
+
+ mfd = open_subdir(xfd, "minecproxy", true);
+ if (mfd < 0)
+ goto out;
+
+ sfd = open_subdir(mfd, "servers", true);
+ if (sfd < 0)
+ goto out;
+
+ if (!write_cfg_file(sfd, "README.TXT", ___examples_README_TXT,
+ ___examples_README_TXT_len))
+ goto out;
+
+ cfd = open_subdir(mfd, "config", true);
+ if (cfd < 0)
+ goto out;
+
if (!write_cfg_file(cfd, "minecproxy.conf", ___examples_minecproxy_conf,
___examples_minecproxy_conf_len))
goto out;
+ if (!create_server_cfg(sfd, cfd, "example", "example.mcserver"))
+ goto out;
+
info("Created configuration in $XDG_CONFIG_HOME/minecproxy");
rv = true;
@@ -203,8 +223,6 @@ out:
close(mfd);
if (sfd >= 0)
close(sfd);
- if (efd >= 0)
- close(efd);
if (cfd >= 0)
close(cfd);
return rv;
@@ -251,6 +269,82 @@ out:
return rv;
}
+static bool valid_name(const char *name)
+{
+ const char *f = name;
+
+ if (empty_str(name)) {
+ error("Empty server name given");
+ return false;
+ }
+
+ while (*f != '\0') {
+ if ((*f >= 'a' && *f <= 'z') ||
+ (*f >= 'A' && *f <= 'Z') ||
+ (*f >= '0' && *f <= '9') ||
+ (*f == ':') || (*f == '-') ||
+ (*f == '_') || (*f == '.') ||
+ (*f == '\\')) {
+ f++;
+ continue;
+ }
+ error("Server name \"%s\" contains invalid characters", name);
+ return false;
+ }
+
+ if ((f - name) > (256 - STRLEN("minecserver@"))) {
+ error("Server name \"%s\" is too long", name);
+ return false;
+ }
+
+ return true;
+}
+
+bool do_new(struct cfg *cfg)
+{
+ const char *name = cfg->commands[0];
+ struct server *server;
+ int sfd = -1;
+ bool rv = false;
+
+ if (!valid_name(name))
+ return false;
+
+ char filename[strlen(name) + STRLEN(".mcserver") + 1];
+ sprintf(filename, "%s.mcserver", name);
+
+ server_load_all_known(cfg);
+
+ if (!cfg->dir)
+ goto out;
+
+ list_for_each_entry(server, &cfg->servers, list) {
+ if (streq(server->name, name)) {
+ error("Server \"%s\" already exists", name);
+ goto out;
+ }
+ }
+
+ sfd = open_subdir(dirfd(cfg->dir), "../servers", false);
+ if (sfd < 0) {
+ error("Failed to open configuration directory \"servers\"");
+ goto out;
+ }
+
+ if (!create_server_cfg(sfd, dirfd(cfg->dir), name, filename))
+ goto out;
+
+ info("Created server configuration %s", name);
+
+ rv = true;
+
+out:
+ if (sfd >= 0)
+ close(sfd);
+
+ return rv;
+}
+
bool do_list(struct cfg *cfg)
{
struct server *server;
diff --git a/minecctl/misc-commands.h b/minecctl/misc-commands.h
index 95d0ba0..d8f62ca 100644
--- a/minecctl/misc-commands.h
+++ b/minecctl/misc-commands.h
@@ -4,6 +4,8 @@
bool do_init(struct cfg *cfg);
+bool do_new(struct cfg *cfg);
+
bool do_list(struct cfg *cfg);
bool do_lint(struct cfg *cfg);