aboutsummaryrefslogtreecommitdiff
path: root/rcon
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2021-02-26 13:36:37 -0800
committerTrumeet <yuuta@yuuta.moe>2021-02-26 13:36:37 -0800
commit3c80cd2b7744a366d39de684c6451285b94a4d1b (patch)
tree9b267dc4afb3cd2e7278167678c4badf946e0245 /rcon
downloadminebridge-3c80cd2b7744a366d39de684c6451285b94a4d1b.tar
minebridge-3c80cd2b7744a366d39de684c6451285b94a4d1b.tar.gz
minebridge-3c80cd2b7744a366d39de684c6451285b94a4d1b.tar.bz2
minebridge-3c80cd2b7744a366d39de684c6451285b94a4d1b.zip
First Commit
Diffstat (limited to 'rcon')
-rw-r--r--rcon/rcon.c133
-rw-r--r--rcon/rcon.h29
2 files changed, 162 insertions, 0 deletions
diff --git a/rcon/rcon.c b/rcon/rcon.c
new file mode 100644
index 0000000..ea29ee9
--- /dev/null
+++ b/rcon/rcon.c
@@ -0,0 +1,133 @@
+/*
+ * Adopted from mcrcon, Copyright (c) 2012-2020, Tiiffi <tiiffi at gmail>.
+ * https://github.com/Tiiffi/mcrcon/tree/b02201d689b3032bc681b28f175fd3d83d167293
+ */
+
+#include "rcon.h"
+#include "../common.h"
+
+#include <sys/socket.h>
+#include <sysexits.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+int rcon_send_packet(int sd, RconPacket *packet)
+{
+ int len;
+ int total = 0; // bytes we've sent
+ int bytesleft; // bytes left to send
+ int ret = -1;
+
+ bytesleft = len = packet->size + sizeof(int);
+
+ while (total < len)
+ {
+ ret = send(sd, (char *) packet + total, bytesleft, 0);
+ if(ret == -1)
+ {
+ fprintf(stderr, _("send(): %s.\n"), strerror(errno));
+ return EX_IOERR;
+ }
+ total += ret;
+ bytesleft -= ret;
+ }
+
+ return EX_OK;
+}
+
+int rcon_build_packet(RconPacket *out, int id, int cmd, char *s1)
+{
+ // size + id + cmd + s1 + s2 NULL terminator
+ int s1_len = strlen(s1);
+ if (s1_len > RCON_DATA_BUFFSIZE)
+ {
+ fprintf(stderr, _("Warning: Command string too long (%d). Maximum allowed: %d.\n"), s1_len, RCON_DATA_BUFFSIZE);
+ return EX_DATAERR;
+ }
+
+ out->size = sizeof(int) * 2 + s1_len + 2;
+ out->id = id;
+ out->cmd = cmd;
+ strncpy(out->data, s1, RCON_DATA_BUFFSIZE);
+
+ return EX_OK;
+}
+
+
+void rcon_print_packet(RconPacket *packet)
+{
+ int i;
+
+ for (i = 0; (unsigned char) packet->data[i] != 0; ++i)
+ {
+ if ((unsigned char) packet->data[i] == 0xc2 && (unsigned char) packet->data[i+1] == 0xa7)
+ {
+ i+=2;
+ continue;
+ }
+ putchar(packet->data[i]);
+ }
+
+ // print newline if string has no newline
+ if (packet->data[i-1] != 10 && packet->data[i-1] != 13) putchar('\n');
+}
+
+int rcon_recv_packet(RconPacket *out, int sd)
+{
+ int psize;
+
+ int ret = recv(sd, (char *) &psize, sizeof(int), 0);
+
+ if (ret == 0)
+ {
+ fprintf(stderr, _("Connection lost.\n"));
+ return EX_IOERR;
+ }
+ if(ret == -1)
+ {
+ fprintf(stderr, _("recv(): %d\n"), errno);
+ return EX_IOERR;
+ }
+
+ if (ret != sizeof(int))
+ {
+ fprintf(stderr, _("Error: recv() failed. Invalid packet size (%d).\n"), ret);
+ return EX_IOERR;
+ }
+
+ if (psize < 10 || psize > RCON_DATA_BUFFSIZE)
+ {
+ fprintf(stderr, _("Warning: invalid packet size (%d). Must over 10 and less than %d.\n"), psize, RCON_DATA_BUFFSIZE);
+
+ if(psize > RCON_DATA_BUFFSIZE || psize < 0) psize = RCON_DATA_BUFFSIZE;
+ // Former net_clean_incoming.
+ char tmp[psize];
+ ret = recv(sd, tmp, psize, 0);
+
+ if(ret == 0)
+ {
+ fprintf(stderr, _("Connection lost.\n"));
+ }
+
+ return EX_DATAERR;
+ }
+
+ out->size = psize;
+
+ int received = 0;
+ while (received < psize)
+ {
+ ret = recv(sd, (char *) out + sizeof(int) + received, psize - received, 0);
+ if (ret == 0) // connection closed before completing receving
+ {
+ fprintf(stderr, _("Connection lost.\n"));
+ return EX_IOERR;
+ }
+
+ received += ret;
+ }
+
+ return EX_OK;
+}
+
diff --git a/rcon/rcon.h b/rcon/rcon.h
new file mode 100644
index 0000000..fc7fd45
--- /dev/null
+++ b/rcon/rcon.h
@@ -0,0 +1,29 @@
+/*
+ * Adopted from mcrcon, Copyright (c) 2012-2020, Tiiffi <tiiffi at gmail>.
+ * https://github.com/Tiiffi/mcrcon/tree/b02201d689b3032bc681b28f175fd3d83d167293
+ */
+
+#ifndef _RCON_H
+#define _RCON_H
+
+#define RCON_DATA_BUFFSIZE 4096
+#define RCON_EXEC_COMMAND 2
+#define RCON_AUTHENTICATE 3
+#define RCON_RESPONSEVALUE 0
+#define RCON_AUTH_RESPONSE 2
+#define RCON_PID 0xBADC0DE
+
+typedef struct rc_packet {
+ int size;
+ int id;
+ int cmd;
+ char data[RCON_DATA_BUFFSIZE];
+ // ignoring string2 for now
+} RconPacket;
+
+int rcon_send_packet(int sd, RconPacket *packet);
+int rcon_build_packet(RconPacket *out, int id, int cmd, char *s1);
+void rcon_print_packet(RconPacket *packet);
+int rcon_recv_packet(RconPacket *out, int sd);
+
+#endif // _RCON_H