- add log_error macro

- rename "flag_connection_alive" variable back to "global_connection_alive"
- return exit code from run_terminal_mode()
- rcon_command(): add error messages
This commit is contained in:
Tiiffi
2024-12-02 08:55:18 +02:00
parent f270a485b5
commit 7162bc6fe6

View File

@ -59,6 +59,8 @@
#define MAX_PACKET_SIZE 4106 // id (4) + cmd (4) + DATA_BUFFSIZE #define MAX_PACKET_SIZE 4106 // id (4) + cmd (4) + DATA_BUFFSIZE
#define MIN_PACKET_SIZE 10 // id (4) + cmd (4) + two empty strings (2) #define MIN_PACKET_SIZE 10 // id (4) + cmd (4) + two empty strings (2)
#define log_error(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__);
// rcon packet structure // rcon packet structure
typedef struct { typedef struct {
int32_t size; int32_t size;
@ -103,8 +105,8 @@ int rcon_command(int sock, char *command);
static int flag_raw_output = 0; static int flag_raw_output = 0;
static int flag_silent_mode = 0; static int flag_silent_mode = 0;
static int flag_disable_colors = 0; static int flag_disable_colors = 0;
static int flag_connection_alive = 1;
static int flag_wait_seconds = 0; static int flag_wait_seconds = 0;
static int global_connection_alive = 1;
static int global_rsock; static int global_rsock;
#ifdef _WIN32 #ifdef _WIN32
@ -125,7 +127,7 @@ void sighandler(int sig)
if (sig == SIGINT) if (sig == SIGINT)
putchar('\n'); putchar('\n');
flag_connection_alive = 0; global_connection_alive = 0;
#ifndef _WIN32 #ifndef _WIN32
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
#endif #endif
@ -139,17 +141,17 @@ unsigned int mcrcon_parse_seconds(char *str)
long result = strtol(str, &end, 10); long result = strtol(str, &end, 10);
if (errno != 0) { if (errno != 0) {
fprintf(stderr, "-w invalid value.\nerror %d: %s\n", errno, strerror(errno)); log_error("-w invalid value.\nerror %d: %s\n", errno, strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (end == str) { if (end == str) {
fprintf(stderr, "-w invalid value (not a number?)\n"); log_error("-w invalid value (not a number?)\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (result <= 0 || result > MAX_WAIT_TIME) { if (result <= 0 || result > MAX_WAIT_TIME) {
fprintf(stderr, "-w value out of range.\nAcceptable value is 1 - %d (seconds).\n", MAX_WAIT_TIME); log_error("-w value out of range.\nAcceptable value is 1 - %d (seconds).\n", MAX_WAIT_TIME);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -233,11 +235,11 @@ int main(int argc, char *argv[])
// auth & commands // auth & commands
if (rcon_auth(global_rsock, pass)) { if (rcon_auth(global_rsock, pass)) {
if (terminal_mode) run_terminal_mode(global_rsock); if (terminal_mode) exit_code = run_terminal_mode(global_rsock);
else exit_code = run_commands(argc, argv); else exit_code = run_commands(argc, argv);
} }
else { // auth failed else { // auth failed
fprintf(stderr, "Authentication failed!\n"); log_error("Authentication failed!\n");
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
} }
@ -292,7 +294,7 @@ void net_init_WSA(void)
int err = WSAStartup(version, &wsadata); int err = WSAStartup(version, &wsadata);
if (err != 0) { if (err != 0) {
fprintf(stderr, "WSAStartup failed. Error: %d.\n", err); log_error("WSAStartup failed. Error: %d.\n", err);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -329,11 +331,11 @@ int net_connect(const char *host, const char *port)
int ret = getaddrinfo(host, port, &hints, &server_info); int ret = getaddrinfo(host, port, &hints, &server_info);
if (ret != 0) { if (ret != 0) {
fprintf(stderr, "Name resolution failed.\n"); log_error("Name resolution failed.\n");
#ifdef _WIN32 #ifdef _WIN32
fprintf(stderr, "Error %d: %s", ret, gai_strerror(ret)); log_error("Error %d: %s", ret, gai_strerror(ret));
#else #else
fprintf(stderr, "Error %d: %s\n", ret, gai_strerror(ret)); log_error("Error %d: %s\n", ret, gai_strerror(ret));
#endif #endif
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -357,9 +359,9 @@ int net_connect(const char *host, const char *port)
if (p == NULL) { if (p == NULL) {
/* TODO (Tiiffi): Check why windows does not report errors */ /* TODO (Tiiffi): Check why windows does not report errors */
fprintf(stderr, "Connection failed.\n"); log_error("Connection failed.\n");
#ifndef _WIN32 #ifndef _WIN32
fprintf(stderr, "Error %d: %s\n", errno, strerror(errno)); log_error("Error %d: %s\n", errno, strerror(errno));
#endif #endif
freeaddrinfo(server_info); freeaddrinfo(server_info);
@ -398,20 +400,20 @@ rc_packet *net_recv_packet(int sd)
ssize_t ret = recv(sd, (char *) &psize, sizeof(psize), 0); ssize_t ret = recv(sd, (char *) &psize, sizeof(psize), 0);
if (ret == 0) { if (ret == 0) {
fprintf(stderr, "Connection lost.\n"); log_error("Connection lost.\n");
flag_connection_alive = 0; global_connection_alive = 0;
return NULL; return NULL;
} }
if (ret != sizeof(psize)) { if (ret != sizeof(psize)) {
fprintf(stderr, "Error: recv() failed.\n"); log_error("Error: recv() failed.\n");
flag_connection_alive = 0; global_connection_alive = 0;
return NULL; return NULL;
} }
if (psize < MIN_PACKET_SIZE || psize > MAX_PACKET_SIZE) { if (psize < MIN_PACKET_SIZE || psize > MAX_PACKET_SIZE) {
fprintf(stderr, "Error: Invalid packet size (%d).\n", psize); log_error("Error: Invalid packet size (%d).\n", psize);
flag_connection_alive = 0; global_connection_alive = 0;
return NULL; return NULL;
} }
@ -422,8 +424,8 @@ rc_packet *net_recv_packet(int sd)
while (received < psize) { while (received < psize) {
ret = recv(sd, p + sizeof(int32_t) + received, psize - received, 0); ret = recv(sd, p + sizeof(int32_t) + received, psize - received, 0);
if (ret == 0) { if (ret == 0) {
fprintf(stderr, "Connection lost.\n"); log_error("Connection lost.\n");
flag_connection_alive = 0; global_connection_alive = 0;
return NULL; return NULL;
} }
@ -541,7 +543,7 @@ rc_packet *packet_build(int id, int cmd, char *s)
int len = strlen(s); int len = strlen(s);
if (len > MAX_COMMAND_LENGTH) { if (len > MAX_COMMAND_LENGTH) {
fprintf(stderr, "Warning: Command string too long (%d). Maximum allowed: %d.\n", len, MAX_COMMAND_LENGTH); log_error("Warning: Command string too long (%d). Maximum allowed: %d.\n", len, MAX_COMMAND_LENGTH);
return NULL; return NULL;
} }
@ -585,18 +587,26 @@ receive:
int rcon_command(int sock, char *command) int rcon_command(int sock, char *command)
{ {
rc_packet *packet = packet_build(RCON_PID, RCON_EXEC_COMMAND, command); rc_packet *packet = packet_build(RCON_PID, RCON_EXEC_COMMAND, command);
if (packet == NULL) if (packet == NULL) {
log_error("Error: packet build() failed!\n");
return 0; return 0;
}
if (!net_send_packet(sock, packet)) if (!net_send_packet(sock, packet)) {
log_error("Error: net_send_packet() failed!\n");
return 0; return 0;
}
packet = net_recv_packet(sock); packet = net_recv_packet(sock);
if (packet == NULL) if (packet == NULL) {
log_error("Error: net_recv_packet() failed!\n");
return 0; return 0;
}
if (packet->id != RCON_PID) if (packet->id != RCON_PID) {
log_error("Error: invalid packet id!\n");
return 0; return 0;
}
if (!flag_silent_mode) { if (!flag_silent_mode) {
if (packet->size > 10) if (packet->size > 10)
@ -614,12 +624,14 @@ int run_commands(int argc, char *argv[])
if (!rcon_command(global_rsock, argv[i])) if (!rcon_command(global_rsock, argv[i]))
return EXIT_FAILURE; return EXIT_FAILURE;
if (++i >= argc) i++;
if (i >= argc)
return EXIT_SUCCESS; return EXIT_SUCCESS;
if (flag_wait_seconds > 0) { if (flag_wait_seconds > 0) {
#ifdef _WIN32 #ifdef _WIN32
Sleep(global_wait_seconds * 1000); Sleep(flag_wait_seconds * 1000);
#else #else
sleep(flag_wait_seconds); sleep(flag_wait_seconds);
#endif #endif
@ -627,25 +639,26 @@ int run_commands(int argc, char *argv[])
} }
} }
// interactive terminal mode // terminal mode
int run_terminal_mode(int sock) int run_terminal_mode(int sock)
{ {
int ret = 0;
char command[MAX_COMMAND_LENGTH] = {0}; char command[MAX_COMMAND_LENGTH] = {0};
puts("Logged in.\nType 'Q' or press Ctrl-D / Ctrl-C to disconnect."); puts("Logged in.\nType 'Q' or press Ctrl-D / Ctrl-C to disconnect.");
while (flag_connection_alive) { while (global_connection_alive) {
putchar('>'); putchar('>');
int len = get_line(command, MAX_COMMAND_LENGTH); int len = get_line(command, MAX_COMMAND_LENGTH);
if (len < 1) continue; if (len < 1) continue;
if (strcasecmp(command, "Q") == 0) if (strcasecmp(command, "Q") == 0) break;
break;
if (len > 0 && flag_connection_alive) if (len > 0 && global_connection_alive) {
ret += rcon_command(sock, command); if (!rcon_command(sock, command)) {
return EXIT_FAILURE;
}
}
/* Special case for "stop" command to prevent server-side bug. /* Special case for "stop" command to prevent server-side bug.
* https://bugs.mojang.com/browse/MC-154617 * https://bugs.mojang.com/browse/MC-154617
@ -657,11 +670,9 @@ int run_terminal_mode(int sock)
if (strcasecmp(command, "stop") == 0) { if (strcasecmp(command, "stop") == 0) {
break; break;
} }
//command[0] = len = 0;
} }
return ret; return EXIT_SUCCESS;
} }
// gets line from stdin and deals with rubbish left in the input buffer // gets line from stdin and deals with rubbish left in the input buffer
@ -670,7 +681,7 @@ int get_line(char *buffer, int bsize)
char *ret = fgets(buffer, bsize, stdin); char *ret = fgets(buffer, bsize, stdin);
if (ret == NULL) { if (ret == NULL) {
if (ferror(stdin)) { if (ferror(stdin)) {
fprintf(stderr, "Error %d: %s\n", errno, strerror(errno)); log_error("Error %d: %s\n", errno, strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
putchar('\n'); putchar('\n');