-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrcon.c
113 lines (92 loc) · 2.81 KB
/
rcon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* 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, struct rc_packet *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(struct rc_packet *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;
}
int rcon_recv_packet(struct rc_packet *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;
}