summaryrefslogtreecommitdiff
path: root/minecctl/server.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2020-07-09 20:36:15 +0200
committerDavid Härdeman <david@hardeman.nu>2020-07-09 20:36:15 +0200
commitdd6321c0acf7b0570811200a205cc4104bee49c7 (patch)
tree52da75427a0c1d237806fbebba23025afd79d28d /minecctl/server.c
parent4ae60696aed938347cc1cf2a5d8f5a2b86292132 (diff)
Implement a basic init command in minecctl to create an initial example config
Diffstat (limited to 'minecctl/server.c')
-rw-r--r--minecctl/server.c117
1 files changed, 77 insertions, 40 deletions
diff --git a/minecctl/server.c b/minecctl/server.c
index 599be1f..91e7842 100644
--- a/minecctl/server.c
+++ b/minecctl/server.c
@@ -8,16 +8,81 @@
#include "minecctl.h"
#include "server.h"
#include "misc.h"
+#include "config.h"
#define INVALID(msg) do { *error = (msg); return false; } while(0)
+static DIR *open_cfg_dir(const char *cmdline_path)
+{
+ int dfd, mfd;
+ DIR *dir;
+
+ if (cmdline_path) {
+ dir = opendir(cmdline_path);
+ if (!dir)
+ error("opendir(%s): %m", cmdline_path);
+ return dir;
+ }
+
+ /* First, attempt per-user config dir... */
+ dfd = open_xdg_cfg_dir(false);
+ if (dfd >= 0) {
+ mfd = openat(dfd, "minecproxy/config",
+ O_CLOEXEC | O_DIRECTORY | O_RDONLY);
+ close(dfd);
+ if (mfd >= 0) {
+ dir = fdopendir(mfd);
+ if (!dir)
+ error("fdopendir: %m");
+ return dir;
+ }
+ }
+
+ /* ...and fallback on the system dir */
+ dir = opendir(DEFAULT_CFG_DIR);
+ if (!dir)
+ error("Failed to open configuration directory: %m");
+ return dir;
+}
+
+void server_load_all_known(struct cfg *cfg)
+{
+ struct dirent *dent;
+
+ if (cfg->server_list_loaded)
+ return;
+
+ cfg->server_list_loaded = true;
+ cfg->dir = open_cfg_dir(cfg->dir_path);
+ if (!cfg->dir) {
+ error("Failed to open config directory");
+ return;
+ }
+
+ while ((dent = readdir(cfg->dir))) {
+ struct server *server;
+ char *suffix;
+
+ if (!config_valid_server_filename(dent, NULL))
+ continue;
+
+ server = server_new(dent->d_name);
+
+ suffix = strrchr(dent->d_name, '.');
+ assert_die(suffix, "Error parsing filename");
+ *suffix = '\0';
+ server->name = xstrdup(dent->d_name);
+
+ list_add(&server->list, &cfg->servers);
+ }
+}
+
bool server_read_config(struct cfg *cfg, struct server *server,
unsigned *lineno, const char **error)
{
char buf[4096];
size_t off = 0;
ssize_t r;
- int dfd;
int fd;
if (!error)
@@ -35,19 +100,16 @@ bool server_read_config(struct cfg *cfg, struct server *server,
if (server->file_read)
return true;
+ if (!cfg->dir)
+ INVALID("Configuration directory not opened");
+
*lineno = 0;
server->file_read = true;
- dfd = open(cfg->cfgdir, O_DIRECTORY | O_PATH | O_CLOEXEC);
- if (dfd < 0)
- INVALID("failed to open configuration directory");
-
- fd = openat(dfd, server->scfg.filename, O_RDONLY | O_CLOEXEC);
+ fd = openat(dirfd(cfg->dir), server->scfg.filename, O_RDONLY | O_CLOEXEC);
if (fd < 0)
INVALID("failed to open configuration file");
- close(dfd);
-
while (true) {
r = read(fd, buf + off, sizeof(buf) - off - 1);
if (r < 0)
@@ -85,6 +147,8 @@ bool server_read_all_configs(struct cfg *cfg, bool print_results)
const char *error;
bool rv = true;
+ server_load_all_known(cfg);
+
/* server->scfg.filename check excludes servers created from cmdline */
list_for_each_entry(server, &cfg->servers, list) {
if (!server->scfg.filename)
@@ -111,6 +175,8 @@ bool server_read_all_configs(struct cfg *cfg, bool print_results)
ansi_normal);
}
}
+
+ return rv;
}
struct server *server_get_default(struct cfg *cfg)
@@ -124,7 +190,7 @@ struct server *server_get_default(struct cfg *cfg)
die("No servers defined");
if (!server_read_config(cfg, server, &lineno, &error)) {
- error("server_read_config error: %s", error);
+ error("%s: server_read_config error - %s", server->name, error);
return NULL;
}
@@ -137,6 +203,8 @@ bool server_set_default(struct cfg *cfg, const char *name)
assert_die(cfg, "invalid arguments");
+ server_load_all_known(cfg);
+
list_for_each_entry(server, &cfg->servers, list) {
if (streq(name, server->name)) {
list_rotate_to_front(&server->list, &cfg->servers);
@@ -148,37 +216,6 @@ bool server_set_default(struct cfg *cfg, const char *name)
return false;
}
-void server_load_all_known(struct cfg *cfg)
-{
- struct dirent *dent;
- DIR *dir;
-
- dir = opendir(cfg->cfgdir);
- if (!dir) {
- info("Can't open config directory %s: %m", cfg->cfgdir);
- return;
- }
-
- while ((dent = readdir(dir))) {
- struct server *server;
- char *suffix;
-
- if (!config_valid_server_filename(dent, NULL))
- continue;
-
- server = server_new(dent->d_name);
-
- suffix = strrchr(dent->d_name, '.');
- assert_die(suffix, "Error parsing filename");
- *suffix = '\0';
- server->name = xstrdup(dent->d_name);
-
- list_add(&server->list, &cfg->servers);
- }
-
- closedir(dir);
-}
-
void server_free_all(struct cfg *cfg)
{
struct server *server, *tmp;