From a71d847b0a752375e8fa2c82c634a800bede2f9b Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Thu, 25 Jun 2020 19:14:50 +0200 Subject: Only check for password if/when required --- minecctl/minecctl.c | 115 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 48 deletions(-) (limited to 'minecctl/minecctl.c') diff --git a/minecctl/minecctl.c b/minecctl/minecctl.c index e71a1cb..ed91fdf 100644 --- a/minecctl/minecctl.c +++ b/minecctl/minecctl.c @@ -57,9 +57,19 @@ __debug(_unused_ enum debug_lvl lvl, const char *fmt, ...) { va_list ap; + if (use_colors) { + if (lvl & DBG_ERROR) + fprintf(stderr, ANSI_RED); + else if (!(lvl & (DBG_INFO | DBG_VERBOSE))) + fprintf(stderr, ANSI_GREY); + } + va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); + + if (use_colors && !(lvl & (DBG_INFO | DBG_VERBOSE))) + fprintf(stderr, ANSI_NORMAL); } _noreturn_ void @@ -133,39 +143,12 @@ dump_config() info("cmdstr : %s", cfg->cmdstr); info("server : %p", cfg->server); info("cmd : %p", cfg->cmd); + info("force stop : %s", cfg->force_stop ? "yes" : "no"); info("addrs : %sempty", list_empty(&cfg->addrs) ? "" : "not "); + info("mcaddrs : %sempty", list_empty(&cfg->mcaddrs) ? "" : "not "); info("known_servers : %sempty", list_empty(&cfg->addrs) ? "" : "not "); } -static int -connect_any(struct list_head *addrs) -{ - struct saddr *saddr; - bool connected = false; - int sfd; - - list_for_each_entry(saddr, addrs, list) { - sfd = socket(saddr->storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (sfd < 0) - die("socket: %m"); - - socket_set_low_latency(sfd, true, true, true); - - if (connect(sfd, (struct sockaddr *)&saddr->storage, saddr->addrlen) < 0) { - close(sfd); - continue; - } - - connected = true; - break; - } - - if (!connected) - die("Failed to connect to remote host"); - - return sfd; -} - static void parse_server_config(char *buf, const char *filename, struct list_head *addrs) @@ -253,7 +236,7 @@ _noreturn_ static void usage(bool invalid) { if (invalid) - info("Invalid option(s)"); + error("Invalid option(s)"); info("Usage: %s [OPTION...] COMMAND\n" "\n" @@ -262,8 +245,11 @@ usage(bool invalid) " (or use environment variable RCON_PASSWORD)\n" " -a, --address=ADDR connect to rcon at ADDR\n" " (or use environment variable RCON_ADDRESS)\n" + " -A, --mcaddress=ADDR connect to Minecraft server at ADDR\n" + " (potentially used for ping, status, pcount)\n" " -c, --cfgdir=DIR look for server configurations in DIR\n" " (default: %s)\n" + " -f, --force stop server even if it has players\n" " -v, --verbose enable extra logging\n" " -h, --help print this information\n" "\n" @@ -400,8 +386,8 @@ set_server(const char *name) usage(true); } -static char * -prompt_password() +char * +ask_password() { struct termios old, new; char *password = NULL; @@ -440,13 +426,49 @@ prompt_password() return password; } +int +connect_any(struct list_head *addrs, bool may_fail) +{ + struct saddr *saddr; + bool connected = false; + int sfd; + + if (list_empty(addrs)) + die("No address to connect to"); + + list_for_each_entry(saddr, addrs, list) { + sfd = socket(saddr->storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (sfd < 0) + die("socket: %m"); + + socket_set_low_latency(sfd, true, true, true); + + if (connect(sfd, (struct sockaddr *)&saddr->storage, saddr->addrlen) < 0) { + close(sfd); + continue; + } + + connected = true; + break; + } + + if (!connected) { + if (may_fail) + sfd = -1; + else + die("Failed to connect to remote host"); + } + + return sfd; +} + static void parse_verb(int index, int remain, char **argv) { enum command_args args; enum commands cmd; - assert_die(index >= 0 && remain >= 0 && argv && cfg, "invalid arguments"); + assert_die(index >= 0 && remain >= 0 && argv, "invalid arguments"); cmd = CMD_INVALID; @@ -609,13 +631,15 @@ parse_cmdline(int argc, char **argv) static struct option long_options[] = { { "password", required_argument, 0, 'p' }, { "address", required_argument, 0, 'a' }, + { "mcaddress", required_argument, 0, 'A' }, { "cfgdir", required_argument, 0, 'c' }, { "verbose", no_argument, 0, 'v' }, + { "force", no_argument, 0, 'f' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, ":p:a:c:vh", + c = getopt_long(argc, argv, ":p:a:A:c:fvh", long_options, &option_index); if (c == -1) @@ -628,9 +652,15 @@ parse_cmdline(int argc, char **argv) case 'a': cfg->addrstr = xstrdup(optarg); break; + case 'A': + cfg->mcaddrstr = xstrdup(optarg); + break; case 'c': cfg->cfgdir = optarg; break; + case 'f': + cfg->force_stop = true; + break; case 'v': debug_mask |= DBG_VERBOSE; break; @@ -669,8 +699,8 @@ main(int argc, char **argv) set_use_colors(); cfg = zmalloc(sizeof(*cfg)); - cfg->fd = -1; list_init(&cfg->addrs); + list_init(&cfg->mcaddrs); list_init(&cfg->known_servers); parse_cmdline(argc, argv); @@ -688,8 +718,9 @@ main(int argc, char **argv) } else if (cfg->addrstr) { struct cfg_value value; + /* FIXME: create a struct server here, fill in details like name */ if (!strtosockaddrs(cfg->addrstr, &value, false)) - die("Unable to connect"); + die("Unable to parse address: %s", cfg->addrstr); if (value.type != CFG_VAL_TYPE_ADDRS) die("Unexpected return value from strtosockaddrs"); @@ -700,18 +731,6 @@ main(int argc, char **argv) list_replace(&value.saddrs, &cfg->addrs); } - info("here %p", cfg->password); - if (!cfg->password) - cfg->password = prompt_password(); - info("here %p", cfg->password); - - dump_config(); - - if (list_empty(&cfg->addrs)) - die("Remote address not found"); - - cfg->fd = connect_any(&cfg->addrs); - cfg->cmd(cfg); xfree(cfg); -- cgit v1.2.3