3 Commits

Author SHA1 Message Date
8fdda295e2 Update mcrcon.1 2019-11-19 09:47:05 +02:00
0b1853dccc Update INSTALL.md 2019-11-19 09:17:20 +02:00
d338537e23 Update README.md 2019-11-19 09:16:11 +02:00
8 changed files with 245 additions and 208 deletions

1
.gitignore vendored
View File

@ -7,4 +7,3 @@
*.project
mcrcon
todo
*.plist

View File

@ -1,13 +1,9 @@
#### Version history:
###### 0.6.2
- Set default address to localhost
###### 0.6.1
####Version history:
######0.6.1
- Color coding fixed
* Thanks to Hagb @ Github
###### 0.6.0
######0.6.0
- Version numbering changed to more sane system (0.0.5 -> 0.6.0)
- Fixed munged output
- Support for using environment variables to set some basic options
@ -18,7 +14,7 @@
- Man page added
- Proper makefile added
###### 0.0.5
######0.0.5
- IPv6 support!
* Thanks to 'Tanja84dk' for addressing the real need of IPv6.
@ -38,20 +34,20 @@
- Client now tries to clean the incoming socket data if last package was out of spec.
###### 0.0.4
######0.0.4
- Reverted back to default getopts options error handler (opterr = 1).
Custom error handler requires rewriting.
- Some cosmetic changes in program output strings.
- Program usage(); function now waits for enter before exiting on Windows.
###### 0.0.3
######0.0.3
- Colors are now supported on Windows too!
- Terminal mode is now triggered with "-t" flag. "-i" flag still works for
backwards compatibility.
- Bug fixes (Packet size check always evaluating false and color validity
check always evaluating true).
###### 0.0.2
######0.0.2
- License changed from 'ISC License' to 'zlib/libpng License'.
- Bug fixes & code cleanups
- Interactive mode (-i flag). Client acts as interactive terminal.
@ -59,9 +55,25 @@
If connecting or authentication fails, the return value is -1.
- Colors are now enabled by default. Now '-c' flag disables the color support.
###### 0.0.1
######0.0.1
- Added experimental support for bukkit colors.
Should work with any sh compatible shell.
- Packet string data limited to max 2048 (DATA_BUFFSIZE) bytes.
No idea how Minecraft handles multiple rcon packets.
If someone knows, please mail me so I can implement it.
####TODO:
- Make the receive buffer dynamic??
- Change some of the packet size issues to fatal errors.
- Code cleanups.
- Check global variables (remove if possible).
- Add some protocol checks (proper packet id check etc..).
- Preprocessor (#ifdef / #ifndef) cleanups.
- Follow valve rcon protocol standard strictly?
- Multiple packet support if minecraft supports it?!
- Investigate if player chat messages gets sent through rcon.
If they are, the messaging system requires rewriting.
- Name resolving should be integrated to connection creation function.
- Dont try to cleanup the socket if not authenticated
- Better sockets error reporting
- Better error function (VA_ARGS support)

View File

@ -1,7 +1,7 @@
Compiling and installing
------------------------
Only dependency is C library and POSIX getopt support.
Only dependency is C library with POSIX getopt support.
Compiling with GCC or CLANG:

View File

@ -1,4 +1,4 @@
Copyright (c) 2012-2019, Tiiffi <tiiffi at gmail>
Copyright (c) 2012-2016, Tiiffi <tiiffi_at_gmail_dot_com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -17,5 +17,4 @@ freely, subject to the following restrictions:
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
distribution.

View File

@ -6,15 +6,14 @@
EXENAME = mcrcon
PREFIX ?= /usr/local
INSTALL = install
LINKER =
RM = rm -v -f
CC = cc
CFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Os -s
EXTRAFLAGS ?= -fstack-protector-strong
INSTALL = install
LINKER =
RM = rm -f
ifeq ($(OS), Windows_NT)
CC = gcc
LINKER = -lws2_32
EXENAME = mcrcon.exe
RM = cmd /C del /F
@ -22,7 +21,9 @@ endif
ifeq ($(shell uname), Darwin)
INSTALL = ginstall
CFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Os
CFLAGS ?= -std=gnu99 -Wall -Wextra -Wpedantic -Os
else
CFLAGS ?= -std=gnu99 -Wall -Wextra -Wpedantic -Os -s
endif
.PHONY: all
@ -34,13 +35,13 @@ $(EXENAME): mcrcon.c
ifneq ($(OS), Windows_NT)
.PHONY: install
install:
$(INSTALL) -vD $(EXENAME) $(DESTDIR)$(PREFIX)/bin/$(EXENAME)
$(INSTALL) -vD -m 0644 mcrcon.1 $(DESTDIR)$(PREFIX)/share/man/man1/mcrcon.1
$(INSTALL) -vD $(EXENAME) $(PREFIX)/bin/$(EXENAME)
$(INSTALL) -vD -m 0644 mcrcon.1 $(PREFIX)/share/man/man1/mcrcon.1
@echo "\nmcrcon installed. Run 'make uninstall' if you want to uninstall.\n"
.PHONY: uninstall
uninstall:
$(RM) $(DESTDIR)$(PREFIX)/bin/$(EXENAME) $(DESTDIR)$(PREFIX)/share/man/man1/mcrcon.1
rm -f $(PREFIX)/bin/$(EXENAME) $(PREFIX)/share/man/man1/mcrcon.1
@echo "\nmcrcon uninstalled.\n"
endif

View File

@ -1,25 +1,13 @@
# mcrcon
mcrcon is console based Minecraft [rcon](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol) client for remote administration and server maintenance scripts.
---
### Installing:
##### via packet manager:
See https://pkgs.org/download/mcrcon for available packages in various Linux distros.
- Gentoo Linux: https://packages.gentoo.org/packages/games-util/mcrcon
- Arch Linux: https://aur.archlinux.org/packages/mcrcon/
##### from sources:
from sources:
```sh
git clone https://github.com/Tiiffi/mcrcon.git
cd mcrcon
make
sudo make install
```
Check [INSTALL.md](INSTALL.md) for more details.
Check **INSTALL** for more details.
You can also download precompiled binaries*: https://github.com/Tiiffi/mcrcon/releases/latest
@ -34,35 +22,33 @@ Sends rcon commands to Minecraft server.
```
Option:
-H Server address (default: localhost)
-P Port (default: 25575)
-p Rcon password
-t Terminal mode
-s Silent mode
-c Disable colors
-r Output raw packets
-h Print usage
-v Version information
-w Wait for specified duration (seconds) between each command
-H Server address
-P Port (default is 25575)
-p Rcon password
-t Interactive terminal mode
-s Silent mode (do not print received packets)
-c Disable colors
-r Output raw packets (debugging and custom handling)
-v Output version information
```
Commands with arguments must be enclosed in quotes.
Server address, port and password can be set using following environment variables:
```
MCRCON_HOST
MCRCON_PORT
MCRCON_PASS
```
###### Notes:
- mcrcon will start in terminal mode if no commands are given
- Command-line options will override environment variables
- Rcon commands with spaces must be enclosed in quotes
Note that command-line options will override environment variables.
Example:
```mcrcon -H my.minecraft.server -p password "say Server is restarting!" save-all stop```
---
##### Enable rcon on server
Remember to enable rcon by adding following lines to [```server.properties```](https://minecraft.gamepedia.com/Server.properties) file.
### Enable rcon on server
Remember to enable rcon by adding following lines to ```server.properties``` file.
```
enable-rcon=true
rcon.port=25575
@ -71,20 +57,14 @@ rcon.password=your_rcon_pasword
---
##### Contact:
#### Contact:
* WWW: https://github.com/Tiiffi/mcrcon/
* MAIL: tiiffi at gmail
* MAIL: tiiffi_at_gmail_dot_com
* IRC: tiiffi @ quakenet
* BUG REPORTS: https://github.com/Tiiffi/mcrcon/issues/
---
### License
This project is licensed under the zlib License - see the [LICENSE](LICENSE) file for details.
---
<sub>Master:</sub> ![Master build](https://api.travis-ci.org/Tiiffi/mcrcon.svg?branch=master)
<sub>Develop:</sub> ![Develop build](https://api.travis-ci.org/Tiiffi/mcrcon.svg?branch=develop)

View File

@ -1,9 +1,9 @@
.\" Process this file with
.\" groff -man -Tascii mcrcon.1
.\"
.TH MCRCON 1 "October 2019" "Version 0.6.2"
.TH MCRCON 1 "December 2016" "Version 0.6.1"
.SH NAME
mcrcon \- send rcon commands to a Minecraft server
mcrcon \- sends rcon commands to a Minecraft server
.SH SYNOPSIS
.B mcrcon [
options
@ -11,34 +11,31 @@ options
commands
.B ]
.SH DESCRIPTION
mcrcon is Minecraft rcon client for remote administration and server maintenance scripts.
mcrcon is Minecraft rcon client / terminal with bukkit coloring support.
It is well suited for remote administration and server maintenance scripts.
.SH OPTIONS
.IP -h
Print usage
.IP -H
Server address (default: localhost)
Server address
.IP -P
Port (default: 25575)
Port (default is 25575)
.IP -p
Rcon password
.IP -t
Terminal mode
Interactive terminal mode
.IP -s
Silent mode
Silent mode (do not print received packets)
.IP -c
Disable colors
.IP -r
Output raw packets
.IP -h
Print usage
Output raw packets (for debugging and custom handling)
.IP -v
Output version information
.IP -w
Wait for specified duration (seconds) between each command
.PP
Commands with spaces must be enclosed in quotes.
.br
mcrcon will start in terminal mode if no commands are given.
Commands with arguments must be enclosed in quotes.
.SH ENVIRONMENTAL VARIABLES
Server address, port and password can be set with following environment variables:
Server address, port and password can be set using following environment variables:
.PP
\fBMCRCON_HOST
.br
@ -58,9 +55,9 @@ Send "weather clear" command to server using custom port 1337
\fBmcrcon\fR -H my.minecraft.server -P 1337 -p password "weather clear"
.RE
.PP
Send three commands to server ("say", "save-all" and "stop"), and wait 2 seconds between them
Send three commands to server (say, save-all and stop)
.RS
\fBmcrcon\fR -H my.minecraft.server -p password -w 2 "say Server is restarting!" save-all stop
\fBmcrcon\fR -H my.minecraft.server -p password "say Server is restarting!" save-all stop
.RE
.SH BUGS
Bugs can be reported to \fBtiiffi+mcrcon at gmail\fR or \fBhttps://github.com/Tiiffi/mcrcon/issues/\fR
Bugs can be reported to \fBtiiffi_at_gmail_dot_com\fR or \fBhttps://github.com/Tiiffi/mcrcon/issues/\fR

299
mcrcon.c
View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2019, Tiiffi <tiiffi at gmail>
* Copyright (c) 2012-2016, Tiiffi <tiiffi -> gmail_dot_com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@ -32,7 +32,7 @@
#ifdef _WIN32
// for name resolving on windows
// enable this if you get compiler whine about getaddrinfo() on windows
// enable this if you get compiler whine about getaddrinfo on windows
//#define _WIN32_WINNT 0x0501
#include <ws2tcpip.h>
@ -46,7 +46,7 @@
#include <netdb.h>
#endif
#define VERSION "0.6.2"
#define VERSION "0.6.1"
#define IN_NAME "mcrcon"
#define VER_STR IN_NAME" "VERSION" (built: "__DATE__" "__TIME__")"
@ -57,7 +57,7 @@
#define RCON_PID 0xBADC0DE
// a bit too big perhaps?
#define DATA_BUFFSIZE 4096
#define DATA_BUFFSIZE 10240
// rcon packet structure
typedef struct _rc_packet {
@ -73,45 +73,46 @@ typedef struct _rc_packet {
// ===================================
// endianness related functions
bool is_bigendian(void);
int32_t reverse_int32(int32_t n);
bool is_bigendian(void);
int32_t reverse_int32(int32_t n);
// Network related functions
#ifdef _WIN32
void net_init_WSA(void);
#endif
void net_close(int sd);
int net_connect(const char *host, const char *port);
int net_send(int sd, const uint8_t *buffer, size_t size);
int net_send_packet(int sd, rc_packet *packet);
int net_connect(const char *host, const char *port);
int net_send(int sd, const uint8_t *buffer, size_t size);
int net_send_packet(int sd, rc_packet *packet);
rc_packet* net_recv_packet(int sd);
int net_clean_incoming(int sd, int size);
int net_clean_incoming(int sd, int size);
// Misc stuff
void usage(void);
void usage(void);
#ifndef _WIN32
void print_color(int color);
void print_color(int color);
#endif
int get_line(char *buffer, int len);
int run_terminal_mode(int sock);
int run_commands(int argc, char *argv[]);
int get_line(char *buffer, int len);
int run_terminal_mode(int rsock);
int run_commands(int argc, char *argv[]);
// Rcon protocol related functions
rc_packet* packet_build(int id, int cmd, char *s1);
uint8_t *packet_build_malloc(size_t *size, int32_t id, int32_t cmd, char *string);
void packet_print(rc_packet *packet);
int rcon_auth(int sock, char *passwd);
int rcon_command(int sock, char *command);
int rcon_auth(int rsock, char *passwd);
int rcon_command(int rsock, char *command);
// =============================================
// GLOBAL VARIABLES
// =============================================
static int global_raw_output = 0;
static int global_silent_mode = 0;
static int global_print_colors = 1;
static int global_connection_alive = 1;
static int global_wait_seconds = 0;
static int global_rsock;
static int raw_output = 0;
static int silent_mode = 0;
static int print_colors = 1;
static int connection_alive = 1;
static int rsock;
#ifdef _WIN32
// console coloring on windows
@ -121,14 +122,14 @@ static int global_rsock;
// safety stuff (windows is still misbehaving)
void exit_proc(void)
{
if (global_rsock != -1)
net_close(global_rsock);
if (rsock != -1)
net_close(rsock);
}
// Check windows & linux behaviour !!!
void sighandler(/*int sig*/)
{
global_connection_alive = 0;
connection_alive = 0;
#ifndef _WIN32
exit(EXIT_SUCCESS);
#endif
@ -146,43 +147,32 @@ int main(int argc, char *argv[])
if (!port)
port = "25575";
if (!host)
host = "localhost";
if(argc < 1 && pass == NULL)
if(argc < 2 && host == NULL && pass == NULL)
usage();
// default getopt error handler enabled
opterr = 1;
while ((opt = getopt(argc, argv, "vrtcshw:H:p:P:i")) != -1)
while ((opt = getopt(argc, argv, "vrtcshH:p:P:i")) != -1)
{
switch (opt)
{
case 'H': host = optarg; break;
case 'P': port = optarg; break;
case 'p': pass = optarg; break;
case 'H': host = optarg; break;
case 'P': port = optarg; break;
case 'p': pass = optarg; break;
case 'C':
case 'c': global_print_colors = 0; break;
case 'c': print_colors = 0; break;
case 'S':
case 's': global_silent_mode = 1; break;
case 's': silent_mode = 1; break;
case 'T':
case 't':
case 'I':
case 'i': terminal_mode = 1; break;
case 'r': global_raw_output = 1; break;
case 'i': terminal_mode = 1; break;
case 'r': raw_output = 1; break;
case 'v':
puts(VER_STR"\nhttps://github.com/Tiiffi/mcrcon");
exit(EXIT_SUCCESS);
case 'W':
case 'w':
global_wait_seconds = strtol(optarg, NULL, 10);
if (errno != 0)
{
fprintf(stderr, "Error %d: %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
break;
break;
case 'h':
case '?': usage(); break;
/*
@ -195,9 +185,15 @@ int main(int argc, char *argv[])
}
}
if (host == NULL)
{
fputs("Host not defined (-H flag). Try 'mcrcon -h' or 'man mcrcon' for more information.\n\n", stdout);
return 0;
}
if (pass == NULL)
{
fputs("You must give password (-p password). Try 'mcrcon -h' or 'man mcrcon' for help.\n\n", stdout);
fputs("Password not defined (-p flag). Try 'mcrcon -h' 'man mcrcon' for more information.\n\n", stdout);
return 0;
}
@ -218,58 +214,51 @@ int main(int argc, char *argv[])
#endif
// open socket
global_rsock = net_connect(host, port);
int exit_code = EXIT_SUCCESS;
rsock = net_connect(host, port);
// auth & commands
if (rcon_auth(global_rsock, pass))
if (rcon_auth(rsock, pass))
{
if (terminal_mode)
run_terminal_mode(global_rsock);
run_terminal_mode(rsock);
else
exit_code = run_commands(argc, argv);
run_commands(argc, argv);
}
else // auth failed
{
fprintf(stdout, "Authentication failed!\n");
exit_code = EXIT_FAILURE;
}
net_close(global_rsock);
global_rsock = -1;
net_close(rsock);
rsock = -1;
return exit_code;
return EXIT_SUCCESS;
}
void usage(void)
{
fputs(
"Usage: "IN_NAME" [OPTIONS] [COMMANDS]\n\n"
"Send rcon commands to Minecraft server.\n\n"
"Options:\n"
" -H\t\tServer address (default: localhost)\n"
" -P\t\tPort (default: 25575)\n"
" -p\t\tRcon password\n"
" -t\t\tTerminal mode\n"
" -s\t\tSilent mode\n"
" -c\t\tDisable colors\n"
" -r\t\tOutput raw packets\n"
"Usage: "IN_NAME" [OPTIONS]... [COMMANDS]...\n\n"
"Sends rcon commands to Minecraft server.\n\n"
"Option:\n"
" -h\t\tPrint usage\n"
" -v\t\tVersion information\n"
" -w\t\tWait for specified duration (seconds) between each command\n\n"
"Server address, port and password can be set with following environment variables:\n"
" -H\t\tServer address\n"
" -P\t\tPort (default is 25575)\n"
" -p\t\tRcon password\n"
" -t\t\tInteractive terminal mode\n"
" -s\t\tSilent mode (do not print received packets)\n"
" -c\t\tDisable colors\n"
" -r\t\tOutput raw packets (debugging and custom handling)\n"
" -v\t\tOutput version information\n\n"
"Server address, port and password can be set using following environment variables:\n"
" MCRCON_HOST\n"
" MCRCON_PORT\n"
" MCRCON_PASS\n\n"
,stdout
);
puts("mcrcon will start in terminal mode if no commands are given.");
puts("Command-line options will override environment variables.");
puts("Rcon commands with spaces must be enclosed in quotes.\n");
puts("Rcon commands with arguments must be enclosed in quotes.\n");
puts("Example:\n\t"IN_NAME" -H my.minecraft.server -p password \"say Server is restarting!\" save-all stop\n");
puts(VER_STR"\nReport bugs to tiiffi+mcrcon at gmail or https://github.com/Tiiffi/mcrcon/issues/\n");
puts(VER_STR"\nReport bugs to tiiffi_at_gmail_dot_com or https://github.com/Tiiffi/mcrcon/issues/\n");
#ifdef _WIN32
puts("Press enter to exit.");
@ -422,14 +411,14 @@ rc_packet *net_recv_packet(int sd)
if (ret == 0)
{
fprintf(stderr, "Connection lost.\n");
global_connection_alive = 0;
connection_alive = 0;
return NULL;
}
if (ret != sizeof(int))
{
fprintf(stderr, "Error: recv() failed. Invalid packet size (%d).\n", ret);
global_connection_alive = 0;
connection_alive = 0;
return NULL;
}
@ -445,18 +434,19 @@ rc_packet *net_recv_packet(int sd)
packet.size = psize;
int received = 0;
while (received < psize)
ret = recv(sd, (char *) &packet + sizeof(int), psize, 0);
if (ret == 0)
{
ret = recv(sd, (char *) &packet + sizeof(int) + received, psize - received, 0);
if (ret == 0) /* connection closed before completing receving */
{
fprintf(stderr, "Connection lost.\n");
global_connection_alive = 0;
return NULL;
}
fprintf(stderr, "Connection lost.\n");
connection_alive = 0;
return NULL;
}
received += ret;
if(ret != psize)
{
fprintf(stderr, "Warning: recv() return value (%d) does not match expected packet size (%d).\n", ret, psize);
net_clean_incoming(sd, DATA_BUFFSIZE); /* Should be enough. Needs some checking */
return NULL;
}
return &packet;
@ -471,7 +461,7 @@ int net_clean_incoming(int sd, int size)
if(ret == 0)
{
fprintf(stderr, "Connection lost.\n");
global_connection_alive = 0;
connection_alive = 0;
}
return ret;
@ -525,7 +515,7 @@ void print_color(int color)
// this hacky mess might use some optimizing
void packet_print(rc_packet *packet)
{
if (global_raw_output == 1)
if (raw_output == 1)
{
for (int i = 0; packet->data[i] != 0; ++i) putchar(packet->data[i]);
return;
@ -544,7 +534,7 @@ void packet_print(rc_packet *packet)
#endif
// colors enabled so try to handle the bukkit colors for terminal
if (global_print_colors == 1)
if (print_colors == 1)
{
for (i = 0; (unsigned char) packet->data[i] != 0; ++i)
{
@ -595,7 +585,67 @@ rc_packet *packet_build(int id, int cmd, char *s1)
return &packet;
}
int rcon_auth(int sock, char *passwd)
// TODO(Tiiffi): String length limit?
uint8_t *packet_build_malloc(size_t *size, int32_t id, int32_t cmd, char *string)
{
size_t string_length = strlen(string);
*size = 3 * sizeof(int32_t) + string_length + 2;
uint8_t *packet = malloc(*size);
if (packet == NULL) return NULL;
int32_t *p = (int32_t *) packet;
p[0] = (int32_t) *size - sizeof(int32_t);
p[1] = id;
p[2] = cmd;
memcpy(&p[3], string, string_length);
packet[12 + string_length] = 0;
packet[13 + string_length] = 0;
return packet;
}
// rcon packet structure
#define MAX_PACKET_SIZE (size_t) 1460 // including size member
#define MIN_PACKET_SIZE (size_t) 10
#define MAX_STRING_SIZE (size_t) (MAX_PACKET_SIZE - 2 - 3 * sizeof(int32_t))
#define SIZEOF_PACKET(x) (size_t) (x.size + sizeof(int32_t))
struct rcon_packet
{
int32_t size;
int32_t id;
int32_t cmd;
uint8_t data[MAX_STRING_SIZE];
};
struct rcon_packet packet_build_new(int32_t id, int32_t cmd, char *string)
{
struct rcon_packet packet;
size_t string_length = strlen(string);
if (string_length > MAX_STRING_SIZE)
{
string_length = MAX_STRING_SIZE;
fprintf(stderr,
"Warning: command string is too long. Truncating to "
"%u characters.\n", (unsigned) MAX_STRING_SIZE
);
}
packet.size = 2 * sizeof(int32_t) + string_length + 2;
packet.id = id;
packet.cmd = cmd;
memcpy(packet.data, string, string_length);
packet.data[string_length] = 0;
packet.data[string_length + 1] = 0;
return packet;
}
int rcon_auth(int rsock, char *passwd)
{
int ret;
@ -603,11 +653,11 @@ int rcon_auth(int sock, char *passwd)
if (packet == NULL)
return 0;
ret = net_send_packet(sock, packet);
ret = net_send_packet(rsock, packet);
if (!ret)
return 0; // send failed
packet = net_recv_packet(sock);
packet = net_recv_packet(rsock);
if (packet == NULL)
return 0;
@ -615,25 +665,34 @@ int rcon_auth(int sock, char *passwd)
return packet->id == -1 ? 0 : 1;
}
int rcon_command(int sock, char *command)
int rcon_command(int rsock, char *command)
{
rc_packet *packet = packet_build(RCON_PID, RCON_EXEC_COMMAND, command);
if (packet == NULL)
int ret; (void) ret;
size_t size;
uint8_t *p = packet_build_malloc(&size, RCON_PID, RCON_EXEC_COMMAND, command);
if (p == NULL)
{
global_connection_alive = 0;
connection_alive = 0;
return 0;
}
net_send_packet(sock, packet);
net_send(rsock, p, size);
packet = net_recv_packet(sock);
free(p);
//ret = net_send_packet(rsock, packet);
//if(!ret) return 0; /* send failed */
rc_packet *packet;
packet = net_recv_packet(rsock);
if (packet == NULL)
return 0;
if (packet->id != RCON_PID)
return 0;
if (!global_silent_mode)
if (!silent_mode)
{
/*
if(packet->size == 10) {
@ -641,7 +700,7 @@ int rcon_command(int sock, char *command)
}
else
*/
if (packet->size > 10)
if (packet->size > 10)
packet_print(packet);
}
@ -650,43 +709,33 @@ int rcon_command(int sock, char *command)
int run_commands(int argc, char *argv[])
{
int i = optind;
int i, ok = 1, ret = 0;
for (;;)
for (i = optind; i < argc && ok; i++)
{
if (!rcon_command(global_rsock, argv[i]))
return EXIT_FAILURE;
if (++i >= argc)
return EXIT_SUCCESS;
if (global_wait_seconds > 0)
{
#ifdef _WIN32
Sleep(global_wait_seconds * 1000);
#else
sleep(global_wait_seconds);
#endif
}
ok = rcon_command(rsock, argv[i]);
ret += ok;
}
return ret;
}
// interactive terminal mode
int run_terminal_mode(int sock)
int run_terminal_mode(int rsock)
{
int ret = 0;
char command[DATA_BUFFSIZE] = {0x00};
puts("Logged in. Type \"Q\" to quit!");
while (global_connection_alive)
while (connection_alive)
{
int len = get_line(command, DATA_BUFFSIZE);
if(command[0] == 'Q' && command[1] == 0)
break;
if(len > 0 && global_connection_alive)
ret += rcon_command(sock, command);
if(len > 0 && connection_alive)
ret += rcon_command(rsock, command);
command[0] = len = 0;
}
@ -700,10 +749,10 @@ int get_line(char *buffer, int bsize)
int ch, len;
fputs(">", stdout);
char *ret = fgets(buffer, bsize, stdin);
if (ret == NULL) exit(EXIT_FAILURE);
(void) fgets(buffer, bsize, stdin);
if (buffer[0] == 0) global_connection_alive = 0;
if (buffer[0] == 0)
connection_alive = 0;
// remove unwanted characters from the buffer
buffer[strcspn(buffer, "\r\n")] = '\0';