summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-10-14 19:49:29 -0400
committerirungentoo <irungentoo@gmail.com>2014-10-14 19:49:29 -0400
commit6985353392e2dbd26641c37fd8a288abaebe919c (patch)
treec6ff682fc0ab1b5e788ab0f43a4a3059ae141c34
parent97707a74fee720cb2a290660ffcd3aaf341a23bb (diff)
Added basic IRC group syncbot to testing.
-rw-r--r--testing/Makefile.inc14
-rw-r--r--testing/irc_syncbot.c342
2 files changed, 356 insertions, 0 deletions
diff --git a/testing/Makefile.inc b/testing/Makefile.inc
index 6bb87913..8b93c8ac 100644
--- a/testing/Makefile.inc
+++ b/testing/Makefile.inc
@@ -120,6 +120,20 @@ test_avatars_LDADD = $(LIBSODIUM_LDFLAGS) \
120 $(NACL_OBJECTS) \ 120 $(NACL_OBJECTS) \
121 $(NACL_LIBS) 121 $(NACL_LIBS)
122 122
123
124noinst_PROGRAMS += irc_syncbot
125
126irc_syncbot_SOURCES = ../testing/irc_syncbot.c
127
128irc_syncbot_CFLAGS = $(LIBSODIUM_CFLAGS) \
129 $(NACL_CFLAGS)
130
131irc_syncbot_LDADD = $(LIBSODIUM_LDFLAGS) \
132 $(NACL_LDFLAGS) \
133 libtoxcore.la \
134 $(LIBSODIUM_LIBS) \
135 $(NACL_OBJECTS) \
136 $(NACL_LIBS)
123endif 137endif
124 138
125EXTRA_DIST += $(top_srcdir)/testing/misc_tools.c 139EXTRA_DIST += $(top_srcdir)/testing/misc_tools.c
diff --git a/testing/irc_syncbot.c b/testing/irc_syncbot.c
new file mode 100644
index 00000000..bd99683c
--- /dev/null
+++ b/testing/irc_syncbot.c
@@ -0,0 +1,342 @@
1
2#include <stdlib.h>
3#include <stdio.h>
4#include <stdint.h>
5#include <string.h>
6#include <time.h>
7
8
9#include <fcntl.h>
10#include <sys/socket.h>
11#include <netinet/in.h>
12#include <arpa/inet.h>
13#include <errno.h>
14#include <sys/time.h>
15#include <sys/types.h>
16#include <netdb.h>
17#include <unistd.h>
18
19#include <sys/ioctl.h>
20
21//IRC name and channel.
22#define IRC_NAME "Tox_syncbot"
23#define IRC_CHANNEL "#tox-real-ontopic"
24
25//IRC server ip and port.
26uint8_t ip[4] = {127, 0, 0, 1};
27uint16_t port = 6667;
28
29#define SILENT_TIMEOUT 20
30
31int sock;
32
33#define SERVER_CONNECT "NICK "IRC_NAME"\nUSER "IRC_NAME" 8 * :"IRC_NAME"\n"
34#define CHANNEL_JOIN "JOIN "IRC_CHANNEL"\n"
35
36uint64_t get_monotime_sec(void)
37{
38 struct timespec monotime;
39 clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
40 return monotime.tv_sec;
41}
42
43int reconnect(void)
44{
45 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
46
47 if (sock < 0) {
48 printf("error socket\n");
49 return -1;
50 }
51
52 struct sockaddr_storage addr = {0};
53
54 size_t addrsize;
55
56 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
57
58 addrsize = sizeof(struct sockaddr_in);
59
60 addr4->sin_family = AF_INET;
61
62 memcpy(&addr4->sin_addr, ip, 4);
63
64 addr4->sin_port = htons(port);
65
66 if (connect(sock, (struct sockaddr *)&addr, addrsize) != 0) {
67 printf("error connect\n");
68 return -1;
69 }
70
71 send(sock, SERVER_CONNECT, sizeof(SERVER_CONNECT) - 1, MSG_NOSIGNAL);
72
73 return sock;
74}
75
76#include "../toxcore/tox.h"
77#include "misc_tools.c"
78
79int current_group = -1;
80
81static void callback_group_invite(Tox *tox, int fid, const uint8_t *data, uint16_t length, void *userdata)
82{
83 if (current_group == -1)
84 current_group = tox_join_groupchat(tox, fid, data, length);
85}
86
87void callback_friend_message(Tox *tox, int fid, const uint8_t *message, uint16_t length, void *userdata)
88{
89 if (length == 1 && *message == 'c') {
90 if (tox_del_groupchat(tox, current_group) == 0)
91 current_group = -1;
92 }
93
94 if (length == 1 && *message == 'i') {
95 tox_invite_friend(tox, fid, current_group);
96 }
97
98 if (length == 1 && *message == 'j' && sock >= 0) {
99 send(sock, CHANNEL_JOIN, sizeof(CHANNEL_JOIN) - 1, MSG_NOSIGNAL);
100 }
101}
102
103static void copy_groupmessage(Tox *tox, int groupnumber, int friendgroupnumber, const uint8_t *message, uint16_t length,
104 void *userdata)
105{
106 if (tox_group_peernumber_is_ours(tox, groupnumber, friendgroupnumber))
107 return;
108
109 uint8_t name[TOX_MAX_NAME_LENGTH];
110 int namelen = tox_group_peername(tox, groupnumber, friendgroupnumber, name);
111
112 if (namelen == 0 || namelen == -1) {
113 memcpy(name, "<unknown>", 9);
114 namelen = 9;
115 }
116
117 uint8_t sendbuf[2048];
118 uint16_t send_len = 0;
119
120 memcpy(sendbuf, "PRIVMSG "IRC_CHANNEL" :", sizeof("PRIVMSG "IRC_CHANNEL" :"));
121 send_len += sizeof("PRIVMSG "IRC_CHANNEL" :") - 1;
122 memcpy(sendbuf + send_len, name, namelen);
123 send_len += namelen;
124 sendbuf[send_len] = ':';
125 send_len += 1;
126 sendbuf[send_len] = ' ';
127 send_len += 1;
128 memcpy(sendbuf + send_len, message, length);
129 send_len += length;
130 unsigned int i;
131
132 for (i = 0; i < send_len; ++i) {
133 if (sendbuf[i] == '\n')
134 sendbuf[i] = '|';
135 }
136
137 sendbuf[send_len] = '\n';
138 send_len += 1;
139
140 if (sock >= 0)
141 send(sock, sendbuf, send_len, MSG_NOSIGNAL);
142}
143
144void send_irc_group(Tox *tox, uint8_t *msg, uint16_t len)
145{
146 if (len > 1350 || len == 0 || len == 1)
147 return;
148
149 --len;
150
151 if (*msg != ':')
152 return;
153
154 uint8_t req[len];
155 unsigned int i;
156
157 for (i = 0; i < (len - 1); ++i) {
158 if (msg[i + 1] == ':') {
159 break;
160 }
161
162 req[i] = msg[i + 1];
163 }
164
165 unsigned int req_len = i;
166 req[i] = 0;
167
168 uint8_t message[len];
169 uint16_t length = 0;
170
171 uint8_t *pmsg = (uint8_t *)strstr((char *)req, " PRIVMSG");
172
173 if (pmsg == NULL)
174 return;
175
176 uint8_t *dt = req;
177
178 for (dt = req, i = 0; dt != pmsg && *dt != '!'; ++dt, ++i) {
179 message[i] = *dt;
180 ++length;
181 }
182
183 message[length] = ':';
184 length += 1;
185 message[length] = ' ';
186 length += 1;
187
188 if ((req_len + 2) >= len)
189 return;
190
191 memcpy(message + length, msg + req_len + 2, len - (req_len + 2));
192 length += len - (req_len + 2);
193 tox_group_message_send(tox, current_group, message, length);
194}
195
196Tox *init_tox(int argc, char *argv[])
197{
198 uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
199 int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
200
201 if (argvoffset < 0)
202 exit(1);
203
204 /* with optional --ipvx, now it can be 1-4 arguments... */
205 if ((argc != argvoffset + 2) && (argc != argvoffset + 4)) {
206 printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node)\n", argv[0]);
207 exit(0);
208 }
209
210 Tox *tox = tox_new(0);
211
212 if (!tox)
213 exit(1);
214
215 tox_set_name(tox, (uint8_t *)IRC_NAME, sizeof(IRC_NAME) - 1);
216 tox_callback_friend_message(tox, &callback_friend_message, 0);
217 tox_callback_group_invite(tox, &callback_group_invite, 0);
218 tox_callback_group_message(tox, &copy_groupmessage, 0);
219 tox_callback_group_action(tox, &copy_groupmessage, 0);
220
221 uint16_t port = atoi(argv[argvoffset + 2]);
222 unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
223 int res = tox_bootstrap_from_address(tox, argv[argvoffset + 1], port, binary_string);
224 free(binary_string);
225
226 char temp_id[128];
227 printf("\nEnter the address of irc_syncbots master (38 bytes HEX format):\n");
228
229 if (scanf("%s", temp_id) != 1) {
230 exit (1);
231 }
232
233 uint8_t *bin_id = hex_string_to_bin(temp_id);
234 int num = tox_add_friend(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo") - 1);
235 free(bin_id);
236
237 if (num < 0) {
238 printf("\nSomething went wrong when adding friend.\n");
239 exit(1);
240 }
241
242 return tox;
243}
244
245int main(int argc, char *argv[])
246{
247 Tox *tox = init_tox(argc, argv);
248
249 sock = reconnect();
250
251 if (sock < 0)
252 return 1;
253
254 uint64_t last_get = get_monotime_sec();
255 int connected = 0, ping_sent = 0;
256
257 while (1) {
258 int count = 0;
259 ioctl(sock, FIONREAD, &count);
260
261 if (count > 0) {
262 last_get = get_monotime_sec();
263 ping_sent = 0;
264 uint8_t data[count + 1];
265 data[count] = 0;
266 recv(sock, data, count, MSG_NOSIGNAL);
267 printf("%s", data);
268
269 if (!connected)
270 connected = 1;
271
272 if (count > 6 && data[0] == 'P' && data[1] == 'I' && data[2] == 'N' && data[3] == 'G') {
273 data[1] = 'O';
274 unsigned int i;
275
276 for (i = 0; i < count; ++i) {
277 if (data[i] == '\n') {
278 ++i;
279 break;
280 }
281 }
282
283 send(sock, data, i, MSG_NOSIGNAL);
284 }
285
286 unsigned int i, p_i = 0;
287
288 for (i = 1; data[0] == ':' && i < count; ++i) {
289 if (data[i] == ' ') {
290 if (i + 5 < count && memcmp(data + i, " 404 ", 5) == 0) {
291 connected = 1;
292 }
293
294 break;
295 }
296
297 if (data[i] == ':')
298 break;
299 }
300
301 for (i = 0; i < count; ++i) {
302 if (data[i] == '\n' && i != 0) {
303 send_irc_group(tox, data + p_i, i - p_i);
304 p_i = i + 1;
305 }
306 }
307 }
308
309 if (connected == 1) {
310 send(sock, CHANNEL_JOIN, sizeof(CHANNEL_JOIN) - 1, MSG_NOSIGNAL);
311 connected = 2;
312 }
313
314 if (!ping_sent && last_get + (SILENT_TIMEOUT / 2) < get_monotime_sec()) {
315 unsigned int p_s = sizeof("PING :test\n") - 1;
316
317 if (send(sock, "PING :test\n", p_s, MSG_NOSIGNAL) == p_s)
318 ping_sent = 1;
319 }
320
321 int error = 0;
322 socklen_t len = sizeof (error);
323
324 if (sock < 0 || last_get + SILENT_TIMEOUT < get_monotime_sec()
325 || getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len ) != 0) {
326 close(sock);
327 printf("reconnect\n");
328 sock = reconnect();
329
330 if (sock >= 0) {
331 last_get = get_monotime_sec();
332 connected = 0;
333 ping_sent = 0;
334 }
335 }
336
337 tox_do(tox);
338 usleep(1000 * 50);
339 }
340
341 return 0;
342}