From dd6321c0acf7b0570811200a205cc4104bee49c7 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Thu, 9 Jul 2020 20:36:15 +0200 Subject: Implement a basic init command in minecctl to create an initial example config --- minecctl/server.c | 117 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 40 deletions(-) (limited to 'minecctl/server.c') 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; -- cgit v1.2.3