summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--testing/CMakeLists.txt5
-rw-r--r--testing/DHT_cryptosendfiletest.c258
-rw-r--r--testing/DHT_sendfiletest.c196
-rw-r--r--testing/cmake/DHT_cryptosendfiletest.cmake10
-rw-r--r--testing/cmake/DHT_sendfiletest.cmake9
-rw-r--r--testing/cmake/nTox_win32.cmake9
-rw-r--r--testing/nTox_win32.c505
-rw-r--r--testing/nTox_win32.h48
-rw-r--r--testing/toxic/CMakeLists.txt28
-rw-r--r--testing/toxic/chat.c445
-rw-r--r--testing/toxic/chat.h6
-rw-r--r--testing/toxic/configdir.c165
-rw-r--r--testing/toxic/configdir.h33
-rw-r--r--testing/toxic/dhtstatus.c99
-rw-r--r--testing/toxic/dhtstatus.h8
-rw-r--r--testing/toxic/friendlist.c145
-rw-r--r--testing/toxic/friendlist.h11
-rw-r--r--testing/toxic/main.c345
-rw-r--r--testing/toxic/prompt.c509
-rw-r--r--testing/toxic/prompt.h12
-rw-r--r--testing/toxic/windows.c247
-rw-r--r--testing/toxic/windows.h56
22 files changed, 1 insertions, 3148 deletions
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt
index e3cdc838..9bab6efb 100644
--- a/testing/CMakeLists.txt
+++ b/testing/CMakeLists.txt
@@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 2.6.0)
2 2
3cmake_policy(SET CMP0011 NEW) 3cmake_policy(SET CMP0011 NEW)
4 4
5#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_cryptosendfiletest.cmake)
6#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_sendfiletest.cmake)
7include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_test.cmake) 5include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_test.cmake)
8include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake) 6include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake)
9include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) 7include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake)
@@ -11,8 +9,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake)
11include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_speed_test.cmake) 9include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_speed_test.cmake)
12 10
13if(WIN32) 11if(WIN32)
14# include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) 12 #Do nothing
15else() 13else()
16 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake) 14 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake)
17 add_subdirectory(toxic)
18endif() 15endif()
diff --git a/testing/DHT_cryptosendfiletest.c b/testing/DHT_cryptosendfiletest.c
deleted file mode 100644
index 42635b35..00000000
--- a/testing/DHT_cryptosendfiletest.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/* DHT cryptosendfiletest
2 *
3 * This program sends or receives a friend request.
4 *
5 * it also sends the encrypted data from a file to another client.
6 * Receives the file data that that client sends us.
7 *
8 * NOTE: this program simulates 33% packet loss.
9 *
10 * This is how I compile it: gcc -O2 -Wall -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/DHT.c ../nacl/build/$HOSTNAME/lib/amd64/* DHT_cryptosendfiletest.c
11 *
12 *
13 * Command line arguments are the ip and port of a node (for bootstrapping).
14 *
15 * Saves all received data to: received.txt
16 *
17 * EX: ./test 127.0.0.1 33445 filename.txt
18 *
19 * Copyright (C) 2013 Tox project All Rights Reserved.
20 *
21 * This file is part of Tox.
22 *
23 * Tox is free software: you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation, either version 3 of the License, or
26 * (at your option) any later version.
27 *
28 * Tox is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
35 *
36 */
37
38#include "../core/network.h"
39#include "../core/DHT.h"
40#include "../core/net_crypto.h"
41#include "misc_tools.h"
42
43#include <string.h>
44
45/* Sleep function (x = milliseconds) */
46#ifdef WIN32
47
48#define c_sleep(x) Sleep(1*x)
49
50#else
51#include <unistd.h>
52#include <arpa/inet.h>
53#define c_sleep(x) usleep(1000*x)
54
55#endif
56
57#define PORT 33445
58
59void printip(IP_Port ip_port)
60{
61 printf("\nIP: %u.%u.%u.%u Port: %u\n", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3],
62 ntohs(ip_port.port));
63}
64
65uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
66
67int main(int argc, char *argv[])
68{
69 if (argc < 4) {
70 printf("usage %s ip port filename(of file to send)\n", argv[0]);
71 exit(0);
72 }
73
74 new_keys();
75 printf("OUR ID: ");
76 uint32_t i;
77
78 for (i = 0; i < 32; i++) {
79 if (self_public_key[i] < 16)
80 printf("0");
81
82 printf("%hhX", self_public_key[i]);
83 }
84
85 printf("\n");
86
87 memcpy(self_client_id, self_public_key, 32);
88
89 char temp_id[128];
90 printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n");
91 scanf("%s", temp_id);
92
93 uint8_t friend_id[32];
94 memcpy(friend_id, hex_string_to_bin(temp_id), 32);
95
96 /* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */
97
98
99 DHT_addfriend(friend_id);
100 IP_Port friend_ip;
101 int connection = -1;
102 int inconnection = -1;
103
104 uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES];
105 int friendrequest = -1;
106 uint8_t request_data[512];
107
108 /* initialize networking
109 * bind to ip 0.0.0.0:PORT */
110 IP ip;
111 ip.i = 0;
112 init_networking(ip, PORT);
113 initNetCrypto();
114
115 perror("Initialization");
116 IP_Port bootstrap_ip_port;
117 bootstrap_ip_port.port = htons(atoi(argv[2]));
118 bootstrap_ip_port.ip.i = inet_addr(argv[1]);
119 DHT_bootstrap(bootstrap_ip_port);
120
121 IP_Port ip_port;
122 uint8_t data[MAX_UDP_PACKET_SIZE];
123 uint32_t length;
124
125 uint8_t buffer1[128];
126 int read1 = 0;
127 uint8_t buffer2[128];
128 int read2 = 0;
129 FILE *file1 = fopen(argv[3], "rb");
130
131 if ( file1 == NULL ) {
132 printf("Error opening file.\n");
133 return 1;
134 }
135
136 FILE *file2 = fopen("received.txt", "wb");
137
138 if ( file2 == NULL ) {
139 return 1;
140 }
141
142 read1 = fread(buffer1, 1, 128, file1);
143
144 while (1) {
145 while (receivepacket(&ip_port, data, &length) != -1) {
146 if (rand() % 3 != 1) { /* simulate packet loss */
147 if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
148 /* if packet is not recognized */
149 printf("Received unhandled packet with length: %u\n", length);
150 } else {
151 printf("Received handled packet with length: %u\n", length);
152 }
153 }
154 }
155
156 friend_ip = DHT_getfriendip(friend_id);
157
158 if (friend_ip.ip.i != 0) {
159 if (connection == -1 && friendrequest == -1) {
160 printf("Sending friend request to peer:");
161 printip(friend_ip);
162 friendrequest = send_friendrequest(friend_id, friend_ip, (uint8_t *) "Hello World", 12);
163 /* connection = crypto_connect((uint8_t *)friend_id, friend_ip); */
164 /* connection = new_connection(friend_ip); */
165 }
166
167 if (check_friendrequest(friendrequest) == 1) {
168 printf("Started connecting to friend:");
169 connection = crypto_connect(friend_id, friend_ip);
170 }
171 }
172
173 if (inconnection == -1) {
174 uint8_t secret_nonce[crypto_box_NONCEBYTES];
175 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
176 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
177 inconnection = crypto_inbound(public_key, secret_nonce, session_key);
178 inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key);
179
180 /* inconnection = incoming_connection(); */
181 if (inconnection != -1) {
182 printf("Someone connected to us:\n");
183 /* printip(connection_ip(inconnection)); */
184 }
185 }
186
187 if (handle_friendrequest(acceptedfriend_public_key, request_data) > 1) {
188 printf("RECEIVED FRIEND REQUEST: %s\n", request_data);
189 }
190
191 /* if someone connected to us write what he sends to a file
192 * also send him our file. */
193 if (inconnection != -1) {
194 if (write_cryptpacket(inconnection, buffer1, read1)) {
195 printf("Wrote data1.\n");
196 read1 = fread(buffer1, 1, 128, file1);
197 }
198
199 read2 = read_cryptpacket(inconnection, buffer2);
200
201 if (read2 != 0) {
202 printf("Received data1.\n");
203
204 if (!fwrite(buffer2, read2, 1, file2)) {
205 printf("file write error1\n");
206 }
207
208 if (read2 < 128) {
209 printf("Closed file1 %u\n", read2);
210 fclose(file2);
211 }
212 }
213 /* if buffer is empty and the connection timed out. */
214 else if (is_cryptoconnected(inconnection) == 4) {
215 crypto_kill(inconnection);
216 }
217 }
218
219 /* if we are connected to a friend send him data from the file.
220 * also put what he sends us in a file. */
221 if (is_cryptoconnected(connection) >= 3) {
222 if (write_cryptpacket(0, buffer1, read1)) {
223 printf("Wrote data2.\n");
224 read1 = fread(buffer1, 1, 128, file1);
225 }
226
227 read2 = read_cryptpacket(0, buffer2);
228
229 if (read2 != 0) {
230 printf("Received data2.\n");
231
232 if (!fwrite(buffer2, read2, 1, file2)) {
233 printf("file write error2\n");
234 }
235
236 if (read2 < 128) {
237 printf("Closed file2 %u\n", read2);
238 fclose(file2);
239 }
240 }
241 /* if buffer is empty and the connection timed out. */
242 else if (is_cryptoconnected(connection) == 4) {
243 crypto_kill(connection);
244 }
245 }
246
247 doDHT();
248 doLossless_UDP();
249 doNetCrypto();
250 /*print_clientlist();
251 *print_friendlist();
252 *c_sleep(300); */
253 c_sleep(1);
254 }
255
256 shutdown_networking();
257 return 0;
258}
diff --git a/testing/DHT_sendfiletest.c b/testing/DHT_sendfiletest.c
deleted file mode 100644
index f839be57..00000000
--- a/testing/DHT_sendfiletest.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/* DHT sendfiletest
2 *
3 * Sends the data from a file to another client.
4 * Receives the file data that that client sends us.
5 *
6 * NOTE: this program simulates 33% packet loss.
7 *
8 * Compile with: gcc -O2 -Wall -o test ../core/DHT.c ../core/network.c ../core/Lossless_UDP.c DHT_sendfiletest.c
9 *
10 * Command line arguments are the ip and port of a node (for bootstrapping), the
11 * client_id (32 bytes) of the friend you want to send the data in filename to and
12 * the client_id this node will take.
13 *
14 * Saves all received data to: received.txt
15 *
16 * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg
17 *
18 * Copyright (C) 2013 Tox project All Rights Reserved.
19 *
20 * This file is part of Tox.
21 *
22 * Tox is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation, either version 3 of the License, or
25 * (at your option) any later version.
26 *
27 * Tox is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
34 *
35 */
36
37#include "../core/network.h"
38#include "../core/DHT.h"
39#include "../core/Lossless_UDP.h"
40
41#include <string.h>
42
43//Sleep function (x = milliseconds)
44#ifdef WIN32
45
46#define c_sleep(x) Sleep(1*x)
47
48#else
49#include <unistd.h>
50#include <arpa/inet.h>
51#define c_sleep(x) usleep(1000*x)
52
53#endif
54
55#define PORT 33445
56
57void printip(IP_Port ip_port)
58{
59 printf("\nIP: %u.%u.%u.%u Port: %u\n", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3],
60 ntohs(ip_port.port));
61}
62
63int main(int argc, char *argv[])
64{
65 //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
66
67 if (argc < 6) {
68 printf("usage %s ip port client_id(of friend to find ip_port of) filename(of file to send) client_id(ours)\n", argv[0]);
69 exit(0);
70 }
71
72 DHT_addfriend((uint8_t *)argv[3]);
73 IP_Port friend_ip;
74 int connection = -1;
75 int inconnection = -1;
76
77 //initialize networking
78 //bind to ip 0.0.0.0:PORT
79 IP ip;
80 ip.i = 0;
81 init_networking(ip, PORT);
82
83 memcpy(self_client_id, argv[5], 32);
84
85
86 perror("Initialization");
87 IP_Port bootstrap_ip_port;
88 bootstrap_ip_port.port = htons(atoi(argv[2]));
89 bootstrap_ip_port.ip.i = inet_addr(argv[1]);
90 DHT_bootstrap(bootstrap_ip_port);
91
92 IP_Port ip_port;
93 uint8_t data[MAX_UDP_PACKET_SIZE];
94 uint32_t length;
95
96 uint8_t buffer1[128];
97 int read1 = 0;
98 uint8_t buffer2[128];
99 int read2 = 0;
100 FILE *file1 = fopen(argv[4], "rb");
101
102 if (file1 == NULL) {
103 printf("Error opening file.\n");
104 return 1;
105 }
106
107 FILE *file2 = fopen("received.txt", "wb");
108
109 if (file2 == NULL)
110 return 1;
111
112 read1 = fread(buffer1, 1, 128, file1);
113
114 while (1) {
115 while (receivepacket(&ip_port, data, &length) != -1) {
116 if (rand() % 3 != 1) { /* simulate packet loss */
117 if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port))
118 printf("Received unhandled packet with length: %u\n", length); /* if packet is not recognized */
119 else
120 printf("Received handled packet with length: %u\n", length);
121 }
122 }
123
124 friend_ip = DHT_getfriendip((uint8_t *)argv[3]);
125
126 if (friend_ip.ip.i != 0) {
127 if (connection == -1) {
128 printf("Started connecting to friend:");
129 printip(friend_ip);
130 connection = new_connection(friend_ip);
131 }
132 }
133
134 if (inconnection == -1) {
135 inconnection = incoming_connection();
136
137 if (inconnection != -1) {
138 printf("Someone connected to us:");
139 printip(connection_ip(inconnection));
140 }
141 }
142
143 /* if someone connected to us write what he sends to a file */
144 /* also send him our file. */
145 if (inconnection != -1) {
146 if (write_packet(inconnection, buffer1, read1)) {
147 printf("Wrote data.\n");
148 read1 = fread(buffer1, 1, 128, file1);
149 }
150
151 read2 = read_packet(inconnection, buffer2);
152
153 if (read2 != 0) {
154 printf("Received data.\n");
155
156 if (!fwrite(buffer2, read2, 1, file2))
157 printf("file write error\n");
158
159 if (read2 < 128) {
160 fclose(file2);
161 }
162 }
163 }
164
165 /* if we are connected to a friend send him data from the file.
166 * also put what he sends us in a file. */
167 if (is_connected(connection) == 3) {
168 if (write_packet(0, buffer1, read1)) {
169 printf("Wrote data.\n");
170 read1 = fread(buffer1, 1, 128, file1);
171 }
172
173 read2 = read_packet(0, buffer2);
174
175 if (read2 != 0) {
176 printf("Received data.\n");
177
178 if (!fwrite(buffer2, read2, 1, file2))
179 printf("file write error\n");
180
181 if (read2 < 128)
182 fclose(file2);
183 }
184 }
185
186 doDHT();
187 doLossless_UDP();
188 /* print_clientlist();
189 * print_friendlist();
190 * c_sleep(300); */
191 c_sleep(1);
192 }
193
194 shutdown_networking();
195 return 0;
196} \ No newline at end of file
diff --git a/testing/cmake/DHT_cryptosendfiletest.cmake b/testing/cmake/DHT_cryptosendfiletest.cmake
deleted file mode 100644
index 5470d02a..00000000
--- a/testing/cmake/DHT_cryptosendfiletest.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(DHT_cryptosendfiletest C)
3
4set(exe_name DHT_cryptosendfiletest)
5
6add_executable(${exe_name}
7 DHT_cryptosendfiletest.c
8 misc_tools.c)
9
10linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/DHT_sendfiletest.cmake b/testing/cmake/DHT_sendfiletest.cmake
deleted file mode 100644
index 298db46c..00000000
--- a/testing/cmake/DHT_sendfiletest.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(DHT_sendfiletest C)
3
4set(exe_name DHT_sendfiletest)
5
6add_executable(${exe_name}
7 DHT_sendfiletest.c)
8
9linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/nTox_win32.cmake b/testing/cmake/nTox_win32.cmake
deleted file mode 100644
index 0e33913f..00000000
--- a/testing/cmake/nTox_win32.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(nTox_win32 C)
3
4set(exe_name nTox_win32)
5
6add_executable(${exe_name}
7 nTox_win32.c misc_tools.c)
8
9linkCoreLibraries(${exe_name})
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
deleted file mode 100644
index c26d9d16..00000000
--- a/testing/nTox_win32.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/* nTox_win32.c
2 *
3 * Textual frontend for Tox - Windows version
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include "nTox_win32.h"
25#include "misc_tools.h"
26
27#include <process.h>
28
29typedef struct {
30 uint8_t id[CLIENT_ID_SIZE];
31 uint8_t accepted;
32} Friend_request;
33
34Friend_request pending_requests[256];
35uint8_t num_requests = 0;
36uint32_t maxnumfriends;
37
38char line[STRING_LENGTH];
39char users_id[200];
40int friend_request_received;
41
42Messenger *messenger;
43
44void do_header()
45{
46 system("cls");
47 printf(users_id);
48 printf("\n---------------------------------");
49 printf("\n[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status), /n nick (to change nickname), /l (lists friends), /d friendnumber (deletes friend), /q (to quit), /r (reset screen)");
50 printf("\n---------------------------------");
51}
52
53void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
54{
55 friend_request_received = 1;
56 printf("\n\n[i] received friend request with message\n");
57 printf("'%s'", (char *)data);
58 char numchar[100];
59 sprintf(numchar, "\n[i] accept request with /a %u\n\n", num_requests);
60 printf(numchar);
61 memcpy(pending_requests[num_requests].id, public_key, CLIENT_ID_SIZE);
62 pending_requests[num_requests].accepted = 0;
63 ++num_requests;
64}
65
66void print_message(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
67{
68 char name[MAX_NAME_LENGTH];
69 getname(messenger, friendnumber, (uint8_t *)name);
70 char msg[100 + length + strlen(name) + 1];
71 time_t rawtime;
72 struct tm *timeinfo;
73 time (&rawtime);
74 timeinfo = localtime (&rawtime);
75 char *temp = asctime(timeinfo);
76 size_t len = strlen(temp);
77 temp[len - 1] = '\0';
78 sprintf(msg, "\n[%d] %s <%s> %s\n\n", friendnumber, temp, name, string); // timestamp
79 printf(msg);
80}
81
82void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
83{
84 char name[MAX_NAME_LENGTH];
85 getname(messenger, friendnumber, (uint8_t *)name);
86 char msg[100 + length];
87 sprintf(msg, "\n\n[i] [%d] %s is now known as %s.\n\n", friendnumber, name, string);
88 printf(msg);
89}
90
91void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
92{
93 char name[MAX_NAME_LENGTH];
94 getname(messenger, friendnumber, (uint8_t *)name);
95 char msg[100 + length + strlen(name) + 1];
96 sprintf(msg, "\n\n[i] [%d] %s's status changed to %s.\n\n", friendnumber, name, string);
97 printf(msg);
98}
99
100void load_key()
101{
102 FILE *data_file = NULL;
103 data_file = fopen("data", "r");
104
105 if (data_file) {
106 fseek(data_file, 0, SEEK_END);
107 int size = ftell(data_file);
108 fseek(data_file, 0, SEEK_SET);
109 uint8_t data[size];
110
111 if (fread(data, sizeof(uint8_t), size, data_file) != size) {
112 printf("\n[i] Could not read the data file. Exiting.");
113 exit(1);
114 }
115
116 Messenger_load(messenger, data, size);
117 } else {
118 int size = Messenger_size(messenger);
119 uint8_t data[size];
120 Messenger_save(messenger, data);
121 fclose(data_file);
122 data_file = fopen("data", "w");
123
124 if (fwrite(data, sizeof(uint8_t), size, data_file) != size) {
125 printf("\n[i] Could not write data to file. Exiting.");
126 exit(1);
127 }
128 }
129
130 fclose(data_file);
131}
132
133void add_friend()
134{
135 int i;
136 char temp_id[128];
137
138 for (i = 0; i < 128; i++)
139 temp_id[i] = line[i + 3];
140
141 int num = m_addfriend(messenger, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
142
143 if (num >= 0) {
144 char numstring[100];
145 sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
146 printf(numstring);
147 ++maxnumfriends;
148 } else if (num == -1)
149 printf("\n[i] Message is too long.\n\n");
150
151 else if (num == -2)
152 printf("\n[i] Please add a message to your friend request.\n\n");
153
154 else if (num == -3)
155 printf("\n[i] That appears to be your own ID.\n\n");
156
157 else if (num == -4)
158 printf("\n[i] Friend request already sent.\n\n");
159
160 else if (num == -5)
161 printf("\n[i] Undefined error when adding friend\n\n");
162}
163
164void list_friends()
165{
166 int i;
167
168 printf("\n[i] Friend List");
169
170 printf("----- PENDING -----\n\n");
171
172 for (i = 0; i <= maxnumfriends; i++) {
173 char name[MAX_NAME_LENGTH];
174 getname(messenger, i, (uint8_t *)name);
175
176 if (m_friendstatus(messenger, i) > 0 && m_friendstatus(messenger, i) < 4)
177 printf("[%d] %s\n", i, (uint8_t *)name);
178 }
179
180 printf("\n");
181
182 printf("----- ACTIVE -----\n\n");
183
184 for (i = 0; i <= maxnumfriends; i++) {
185 char name[MAX_NAME_LENGTH];
186 getname(messenger, i, (uint8_t *)name);
187
188 if (m_friendstatus(messenger, i) == 4)
189 printf("[%d] %s\n", i, (uint8_t *)name);
190 }
191
192 printf("\n");
193}
194
195void delete_friend()
196{
197 size_t len = strlen(line);
198 char numstring[len - 3];
199 int i;
200
201 for (i = 0; i < len; i++) {
202 if (line[i + 3] != ' ')
203 numstring[i] = line[i + 3];
204 }
205
206 int num = atoi(numstring);
207 m_delfriend(messenger, num);
208 --maxnumfriends;
209 printf("\n\n");
210}
211
212void message_friend()
213{
214 size_t len = strlen(line);
215 char numstring[len - 3];
216 char message[len - 3];
217 int i;
218
219 for (i = 0; i < len; i++) {
220
221 if (line[i + 3] != ' ')
222 numstring[i] = line[i + 3];
223
224 else {
225 int j;
226
227 for (j = (i + 1); j < len; j++)
228 message[j - i - 1] = line[j + 3];
229
230 break;
231 }
232 }
233
234 int num = atoi(numstring);
235
236 if (m_sendmessage(messenger, num, (uint8_t *) message, sizeof(message)) != 1)
237 printf("\n[i] could not send message (they may be offline): %s\n", message);
238
239 else
240 printf("\n");
241}
242
243void change_nickname()
244{
245 uint8_t name[MAX_NAME_LENGTH];
246 int i = 0;
247 size_t len = strlen(line);
248
249 for (i = 3; i < len; i++) {
250
251 if (line[i] == 0 || line[i] == '\n')
252 break;
253
254 name[i - 3] = line[i];
255 }
256
257 name[i - 3] = 0;
258 setname(messenger, name, i);
259 char numstring[100];
260 sprintf(numstring, "\n[i] changed nick to %s\n\n", (char *)name);
261 printf(numstring);
262
263 FILE *name_file = NULL;
264 name_file = fopen("namefile.txt", "w");
265 fprintf(name_file, "%s", (char *)name);
266 fclose(name_file);
267}
268
269void change_status(int savetofile)
270{
271 uint8_t status[MAX_STATUSMESSAGE_LENGTH];
272 int i = 0;
273 size_t len = strlen(line);
274
275 for (i = 3; i < len; i++) {
276 if (line[i] == 0 || line[i] == '\n')
277 break;
278
279 status[i - 3] = line[i];
280 }
281
282 status[i - 3] = 0;
283 m_set_statusmessage(messenger, status, strlen((char *)status));
284 char numstring[100];
285 sprintf(numstring, "\n[i] changed status to %s\n\n", (char *)status);
286 printf(numstring);
287
288 if (savetofile == 1) {
289 FILE *status_file = NULL;
290 status_file = fopen("statusfile.txt", "w");
291 fprintf(status_file, "%s", (char *)status);
292 fclose(status_file);
293 }
294}
295
296void accept_friend_request()
297{
298 friend_request_received = 0;
299 uint8_t numf = atoi(line + 3);
300 char numchar[100];
301
302 if (numf >= num_requests || pending_requests[numf].accepted) {
303 sprintf(numchar, "\n[i] you either didn't receive that request or you already accepted it");
304 printf(numchar);
305 } else {
306 int num = m_addfriend_norequest(messenger, pending_requests[numf].id);
307
308 if (num != -1) {
309 pending_requests[numf].accepted = 1;
310 sprintf(numchar, "\n[i] Added friendnumber: %d\n\n", num);
311 printf(numchar);
312 ++maxnumfriends;
313 } else {
314 sprintf(numchar, "[i] failed to add friend");
315 printf(numchar);
316 }
317 }
318}
319
320void line_eval(char *line)
321{
322 if (line[0] == '/') {
323
324 char inpt_command = line[1];
325
326 if (inpt_command == 'f') {
327 add_friend();
328 }
329
330 else if (inpt_command == 'r') {
331 do_header();
332 printf("\n\n");
333 }
334
335 else if (inpt_command == 'l') {
336 list_friends();
337 }
338
339 else if (inpt_command == 'd') {
340 delete_friend();
341 }
342 /* Send message to friend */
343 else if (inpt_command == 'm') {
344 message_friend();
345 }
346
347 else if (inpt_command == 'n') {
348 change_nickname();
349 }
350
351 else if (inpt_command == 's') {
352 change_status(1);
353 }
354
355 else if (inpt_command == 'a') {
356 if (friend_request_received == 1)
357 accept_friend_request();
358 }
359 /* EXIT */
360 else if (inpt_command == 'q') {
361 strcpy(line, "---Offline");
362 change_status(0);
363 exit(EXIT_SUCCESS);
364 }
365 }
366}
367
368void get_input()
369{
370 while (1) {
371 fgets(line, STRING_LENGTH, stdin);
372 line_eval(line);
373 strcpy(line, "");
374 }
375}
376
377int main(int argc, char *argv[])
378{
379 if (argc < 4) {
380 printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
381 exit(0);
382 }
383
384 messenger = initMessenger();
385
386 if (messenger == 0) {
387 printf("initMessenger failed");
388 exit(0);
389 }
390
391 if (argc > 4) {
392 if (strncmp(argv[4], "nokey", 6) < 0) {
393 }
394 } else {
395 load_key();
396 }
397
398 int nameloaded = 0;
399 int statusloaded = 0;
400
401 FILE *name_file = NULL;
402 name_file = fopen("namefile.txt", "r");
403
404 if (name_file) {
405 uint8_t name[MAX_NAME_LENGTH];
406
407 while (fgets(line, MAX_NAME_LENGTH, name_file) != NULL) {
408 sscanf(line, "%s", (char *)name);
409 }
410
411 setname(messenger, name, strlen((char *)name) + 1);
412 nameloaded = 1;
413 printf("%s\n", name);
414 fclose(name_file);
415 }
416
417 FILE *status_file = NULL;
418 status_file = fopen("statusfile.txt", "r");
419
420 if (status_file) {
421 uint8_t status[MAX_STATUSMESSAGE_LENGTH];
422
423 while (fgets(line, MAX_STATUSMESSAGE_LENGTH, status_file) != NULL) {
424 sscanf(line, "%s", (char *)status);
425 }
426
427 m_set_statusmessage(messenger, status, strlen((char *)status) + 1);
428 statusloaded = 1;
429 printf("%s\n", status);
430 fclose(status_file);
431 }
432
433 m_callback_friendrequest(messenger, print_request, &status_file);
434 m_callback_friendmessage(messenger, print_message, &status_file);
435 m_callback_namechange(messenger, print_nickchange, &status_file);
436 m_callback_statusmessage(messenger, print_statuschange, &status_file);
437 char idstring1[PUB_KEY_BYTES][5];
438 char idstring2[PUB_KEY_BYTES][5];
439 int i;
440
441 for (i = 0; i < PUB_KEY_BYTES; i++) {
442 if (self_public_key[i] < (PUB_KEY_BYTES / 2))
443 strcpy(idstring1[i], "0");
444 else
445 strcpy(idstring1[i], "");
446
447 sprintf(idstring2[i], "%hhX", self_public_key[i]);
448 }
449
450 strcpy(users_id, "[i] your ID: ");
451 int j;
452
453 for (j = 0; j < PUB_KEY_BYTES; j++) {
454 strcat(users_id, idstring1[j]);
455 strcat(users_id, idstring2[j]);
456 }
457
458 do_header();
459
460 IP_Port bootstrap_ip_port;
461 bootstrap_ip_port.port = htons(atoi(argv[2]));
462 int resolved_address = resolve_addr(argv[1]);
463
464 if (resolved_address != 0)
465 bootstrap_ip_port.ip.i = resolved_address;
466 else
467 exit(1);
468
469 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
470
471 int c;
472 int on = 0;
473
474 _beginthread(get_input, 0, NULL);
475
476 if (nameloaded == 1) {
477 printf("\nNickname automatically loaded");
478 printf("\n---------------------------------");
479 }
480
481 if (statusloaded == 1) {
482 printf("\nStatus automatically loaded");
483 printf("\n---------------------------------");
484 }
485
486 while (1) {
487 if (on == 1 && DHT_isconnected() == -1) {
488 printf("\n---------------------------------");
489 printf("\n[i] Disconnected from the DHT");
490 printf("\n---------------------------------\n\n");
491 on = 0;
492 }
493
494 if (on == 0 && DHT_isconnected()) {
495 printf("\n[i] Connected to DHT");
496 printf("\n---------------------------------\n\n");
497 on = 1;
498 }
499
500 doMessenger(messenger);
501 Sleep(1);
502 }
503
504 return 0;
505}
diff --git a/testing/nTox_win32.h b/testing/nTox_win32.h
deleted file mode 100644
index b174edcc..00000000
--- a/testing/nTox_win32.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* nTox_win32.h
2 *
3 * Textual frontend for Tox - Windows version
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#ifndef NTOX_WIN32_H
24#define NTOX_WIN32_H
25
26#include "../core/Messenger.h"
27#include "../core/network.h"
28
29#define STRING_LENGTH 256
30#define PUB_KEY_BYTES 32
31
32void do_header();
33void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata);
34void print_message(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
35void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
36void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
37void load_key();
38void add_friend();
39void list_friends();
40void delete_friend();
41void message_friend();
42void change_nickname();
43void change_status(int savetofile);
44void accept_friend_request();
45void line_eval(char *line);
46void get_input();
47
48#endif
diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt
deleted file mode 100644
index b59cb55e..00000000
--- a/testing/toxic/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(toxic C)
3
4execute_process(COMMAND git rev-list HEAD --count OUTPUT_VARIABLE COMMIT)
5SET(GCC_COVERAGE_COMPILE_FLAGS '-DTOXICVER="0.1.1_r${COMMIT}"')
6add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
7set(exe_name toxic)
8
9add_executable(${exe_name}
10 main.c
11 windows.c
12 prompt.c
13 friendlist.c
14 dhtstatus.c
15 chat.c
16 configdir.c)
17
18if(CURSES_HAVE_WIDE_CHAR)
19 add_definitions( -D_XOPEN_SOURCE_EXTENDED )
20 add_definitions( -DHAVE_WIDE_CHAR )
21endif()
22
23include_directories(${CURSES_INCLUDE_DIR})
24
25target_link_libraries(${exe_name}
26 ${CURSES_LIBRARIES})
27
28linkCoreLibraries(${exe_name})
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
deleted file mode 100644
index 9454010f..00000000
--- a/testing/toxic/chat.c
+++ /dev/null
@@ -1,445 +0,0 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <stdlib.h>
6#include <string.h>
7#include <stdint.h>
8#include <ctype.h>
9#include <time.h>
10#include <limits.h>
11
12#include "../../core/Messenger.h"
13#include "../../core/network.h"
14
15#include "windows.h"
16#include "friendlist.h"
17#include "chat.h"
18
19#define CURS_Y_OFFSET 3
20
21typedef struct {
22 int friendnum;
23 wchar_t line[MAX_STR_SIZE];
24 size_t pos;
25 WINDOW *history;
26 WINDOW *linewin;
27} ChatContext;
28
29void print_help(ChatContext *self);
30void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd);
31
32struct tm *get_time(void)
33{
34 struct tm *timeinfo;
35 time_t now;
36 time(&now);
37 timeinfo = localtime(&now);
38 return timeinfo;
39}
40
41static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len)
42{
43 ChatContext *ctx = (ChatContext *) self->x;
44 uint8_t nick[MAX_NAME_LENGTH] = {0};
45 struct tm *timeinfo = get_time();
46
47 if (ctx->friendnum != num)
48 return;
49
50 getname(m, num, (uint8_t *) &nick);
51 msg[len - 1] = '\0';
52 nick[MAX_NAME_LENGTH - 1] = '\0';
53
54 wattron(ctx->history, COLOR_PAIR(2));
55 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
56 wattroff(ctx->history, COLOR_PAIR(2));
57 wattron(ctx->history, COLOR_PAIR(4));
58 wprintw(ctx->history, "%s: ", nick);
59 wattroff(ctx->history, COLOR_PAIR(4));
60 wprintw(ctx->history, "%s\n", msg);
61
62 self->blink = true;
63 beep();
64}
65
66static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len)
67{
68 ChatContext *ctx = (ChatContext *) self->x;
69 struct tm *timeinfo = get_time();
70
71 if (ctx->friendnum != num)
72 return;
73
74 action[len - 1] = '\0';
75
76 wattron(ctx->history, COLOR_PAIR(2));
77 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
78 wattroff(ctx->history, COLOR_PAIR(2));
79
80 wattron(ctx->history, COLOR_PAIR(5));
81 wprintw(ctx->history, "%s\n", action);
82 wattroff(ctx->history, COLOR_PAIR(5));
83
84 self->blink = true;
85 beep();
86}
87
88static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len)
89{
90 ChatContext *ctx = (ChatContext *) self->x;
91 struct tm *timeinfo = get_time();
92
93 if (ctx->friendnum != num)
94 return;
95
96 wattron(ctx->history, COLOR_PAIR(2));
97 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
98 wattroff(ctx->history, COLOR_PAIR(2));
99
100 nick[len - 1] = '\0';
101 snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
102
103 wattron(ctx->history, COLOR_PAIR(3));
104 wprintw(ctx->history, "* Your partner changed nick to '%s'\n", nick);
105 wattroff(ctx->history, COLOR_PAIR(3));
106}
107
108static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint16_t len)
109{
110 ChatContext *ctx = (ChatContext *) self->x;
111 struct tm *timeinfo = get_time();
112
113 if (ctx->friendnum != num)
114 return;
115
116 wattron(ctx->history, COLOR_PAIR(2));
117 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
118 wattroff(ctx->history, COLOR_PAIR(2));
119
120 status[len - 1] = '\0';
121 snprintf(self->title, sizeof(self->title), "[%s (%d)]", status, num);
122
123 wattron(ctx->history, COLOR_PAIR(3));
124 wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
125 wattroff(ctx->history, COLOR_PAIR(3));
126
127}
128
129/* check that the string has one non-space character */
130int string_is_empty(char *string)
131{
132 int rc = 0;
133 char *copy = strdup(string);
134 rc = ((strtok(copy, " ") == NULL) ? 1 : 0);
135 free(copy);
136 return rc;
137}
138
139/* convert wide characters to null terminated string */
140static char *wcs_to_char(wchar_t *string)
141{
142 size_t len = 0;
143 char *ret = NULL;
144
145 len = wcstombs(NULL, string, 0);
146 if (len != (size_t) -1) {
147 len++;
148 ret = malloc(len);
149 wcstombs(ret, string, len);
150 } else {
151 ret = malloc(2);
152 ret[0] = ' ';
153 ret[1] = '\0';
154 }
155 return ret;
156}
157
158/* convert a wide char to null terminated string */
159static char *wc_to_char(wchar_t ch)
160{
161 int len = 0;
162 static char ret[MB_LEN_MAX + 1];
163
164 len = wctomb(ret, ch);
165 if (len == -1) {
166 ret[0] = ' ';
167 ret[1] = '\0';
168 } else {
169 ret[len] = '\0';
170 }
171
172 return ret;
173}
174
175static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key)
176{
177 ChatContext *ctx = (ChatContext *) self->x;
178 struct tm *timeinfo = get_time();
179
180 int x, y, y2, x2;
181 getyx(self->window, y, x);
182 getmaxyx(self->window, y2, x2);
183
184 /* Add printable chars to buffer and print on input space */
185#if HAVE_WIDECHAR
186 if (iswprint(key)) {
187#else
188 if (isprint(key)) {
189#endif
190 if (ctx->pos != sizeof(ctx->line) - 1) {
191 mvwaddstr(self->window, y, x, wc_to_char(key));
192 ctx->line[ctx->pos++] = key;
193 ctx->line[ctx->pos] = L'\0';
194 }
195 }
196
197 /* BACKSPACE key: Remove one character from line */
198 else if (key == 0x107 || key == 0x8 || key == 0x7f) {
199 if (ctx->pos > 0) {
200 ctx->line[--ctx->pos] = L'\0';
201
202 if (x == 0)
203 mvwdelch(self->window, y - 1, x2 - 1);
204 else
205 mvwdelch(self->window, y, x - 1);
206 }
207 }
208
209 /* RETURN key: Execute command or print line */
210 else if (key == '\n') {
211 char *line = wcs_to_char(ctx->line);
212 wclear(ctx->linewin);
213 wmove(self->window, y2 - CURS_Y_OFFSET, 0);
214 wclrtobot(self->window);
215
216 if (line[0] == '/')
217 execute(self, ctx, m, line);
218 else {
219 /* make sure the string has at least non-space character */
220 if (!string_is_empty(line)) {
221 uint8_t selfname[MAX_NAME_LENGTH];
222 getself_name(m, selfname, sizeof(selfname));
223
224 wattron(ctx->history, COLOR_PAIR(2));
225 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
226 wattroff(ctx->history, COLOR_PAIR(2));
227 wattron(ctx->history, COLOR_PAIR(1));
228 wprintw(ctx->history, "%s: ", selfname);
229 wattroff(ctx->history, COLOR_PAIR(1));
230 wprintw(ctx->history, "%s\n", line);
231
232 if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
233 wattron(ctx->history, COLOR_PAIR(3));
234 wprintw(ctx->history, " * Failed to send message.\n");
235 wattroff(ctx->history, COLOR_PAIR(3));
236 }
237 }
238 }
239
240 ctx->line[0] = L'\0';
241 ctx->pos = 0;
242 free(line);
243 }
244}
245
246void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
247{
248 if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
249 wclear(self->window);
250 wclear(ctx->history);
251 int x, y;
252 getmaxyx(self->window, y, x);
253 (void) x;
254 wmove(self->window, y - CURS_Y_OFFSET, 0);
255 }
256
257 else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
258 print_help(ctx);
259
260 else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
261 endwin();
262 exit(0);
263 }
264
265 else if (!strncmp(cmd, "/me ", strlen("/me "))) {
266 struct tm *timeinfo = get_time();
267 char *action = strchr(cmd, ' ');
268
269 if (action == NULL) {
270 wprintw(self->window, "Invalid syntax.\n");
271 return;
272 }
273
274 action++;
275
276 wattron(ctx->history, COLOR_PAIR(2));
277 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
278 wattroff(ctx->history, COLOR_PAIR(2));
279
280 uint8_t selfname[MAX_NAME_LENGTH];
281 int len = getself_name(m, selfname, sizeof(selfname));
282 char msg[MAX_STR_SIZE - len - 4];
283 snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t *) selfname, action);
284
285 wattron(ctx->history, COLOR_PAIR(5));
286 wprintw(ctx->history, msg);
287 wattroff(ctx->history, COLOR_PAIR(5));
288
289 if (m_sendaction(m, ctx->friendnum, (uint8_t *) msg, strlen(msg) + 1) < 0) {
290 wattron(ctx->history, COLOR_PAIR(3));
291 wprintw(ctx->history, " * Failed to send action\n");
292 wattroff(ctx->history, COLOR_PAIR(3));
293 }
294 }
295
296 else if (!strncmp(cmd, "/status ", strlen("/status "))) {
297 char *status = strchr(cmd, ' ');
298 char *msg;
299 char *status_text;
300
301 if (status == NULL) {
302 wprintw(ctx->history, "Invalid syntax.\n");
303 return;
304 }
305
306 status++;
307 USERSTATUS status_kind;
308
309 if (!strncmp(status, "online", strlen("online"))) {
310 status_kind = USERSTATUS_NONE;
311 status_text = "ONLINE";
312 }
313
314 else if (!strncmp(status, "away", strlen("away"))) {
315 status_kind = USERSTATUS_AWAY;
316 status_text = "AWAY";
317 }
318
319 else if (!strncmp(status, "busy", strlen("busy"))) {
320 status_kind = USERSTATUS_BUSY;
321 status_text = "BUSY";
322 }
323
324 else {
325 wprintw(ctx->history, "Invalid status.\n");
326 return;
327 }
328
329 msg = strchr(status, ' ');
330
331 if (msg == NULL) {
332 m_set_userstatus(m, status_kind);
333 wprintw(ctx->history, "Status set to: %s\n", status_text);
334 } else {
335 msg++;
336 m_set_userstatus(m, status_kind);
337 m_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1);
338 wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
339 }
340 }
341
342 else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
343 char *nick;
344 nick = strchr(cmd, ' ');
345
346 if (nick == NULL) {
347 wprintw(ctx->history, "Invalid syntax.\n");
348 return;
349 }
350
351 nick++;
352 setname(m, (uint8_t *) nick, strlen(nick) + 1);
353 wprintw(ctx->history, "Nickname set to: %s\n", nick);
354 }
355
356 else if (!strcmp(cmd, "/myid")) {
357 char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
358 int i;
359 uint8_t address[FRIEND_ADDRESS_SIZE];
360 getaddress(m, address);
361
362 for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
363 char xx[3];
364 snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
365 strcat(id, xx);
366 }
367
368 wprintw(ctx->history, "%s\n", id);
369 }
370
371 else if (strcmp(cmd, "/close") == 0) {
372 int f_num = ctx->friendnum;
373 delwin(ctx->linewin);
374 del_window(self);
375 disable_chatwin(f_num);
376 }
377
378 else
379 wprintw(ctx->history, "Invalid command.\n");
380}
381
382static void chat_onDraw(ToxWindow *self, Messenger *m)
383{
384 curs_set(1);
385 int x, y;
386 getmaxyx(self->window, y, x);
387 (void) y;
388 ChatContext *ctx = (ChatContext *) self->x;
389 mvwhline(ctx->linewin, 0, 0, '_', x);
390 wrefresh(self->window);
391}
392
393static void chat_onInit(ToxWindow *self, Messenger *m)
394{
395 int x, y;
396 ChatContext *ctx = (ChatContext *) self->x;
397 getmaxyx(self->window, y, x);
398 ctx->history = subwin(self->window, y - 4, x, 0, 0);
399 scrollok(ctx->history, 1);
400 ctx->linewin = subwin(self->window, 2, x, y - 4, 0);
401 print_help(ctx);
402 wmove(self->window, y - CURS_Y_OFFSET, 0);
403}
404
405void print_help(ChatContext *self)
406{
407 wattron(self->history, COLOR_PAIR(2) | A_BOLD);
408 wprintw(self->history, "Commands:\n");
409 wattroff(self->history, A_BOLD);
410
411 wprintw(self->history, " /status <type> <message> : Set your status\n");
412 wprintw(self->history, " /nick <nickname> : Set your nickname\n");
413 wprintw(self->history, " /me <action> : Do an action\n");
414 wprintw(self->history, " /myid : Print your ID\n");
415 wprintw(self->history, " /clear : Clear the screen\n");
416 wprintw(self->history, " /close : Close the current chat window\n");
417 wprintw(self->history, " /quit or /exit : Exit program\n");
418 wprintw(self->history, " /help : Print this message again\n\n");
419
420 wattroff(self->history, COLOR_PAIR(2));
421}
422
423ToxWindow new_chat(Messenger *m, int friendnum)
424{
425 ToxWindow ret;
426 memset(&ret, 0, sizeof(ret));
427
428 ret.onKey = &chat_onKey;
429 ret.onDraw = &chat_onDraw;
430 ret.onInit = &chat_onInit;
431 ret.onMessage = &chat_onMessage;
432 ret.onNickChange = &chat_onNickChange;
433 ret.onStatusChange = &chat_onStatusChange;
434 ret.onAction = &chat_onAction;
435
436 uint8_t nick[MAX_NAME_LENGTH] = {0};
437 getname(m, friendnum, (uint8_t *) &nick);
438
439 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
440
441 ChatContext *x = calloc(1, sizeof(ChatContext));
442 x->friendnum = friendnum;
443 ret.x = (void *) x;
444 return ret;
445}
diff --git a/testing/toxic/chat.h b/testing/toxic/chat.h
deleted file mode 100644
index 7599d462..00000000
--- a/testing/toxic/chat.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef CHAT_H_6489PZ13
2#define CHAT_H_6489PZ13
3
4ToxWindow new_chat(Messenger *m, int friendnum);
5
6#endif /* end of include guard: CHAT_H_6489PZ13 */
diff --git a/testing/toxic/configdir.c b/testing/toxic/configdir.c
deleted file mode 100644
index a43dd1de..00000000
--- a/testing/toxic/configdir.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * Copyright (C) 2013 Tox project All Rights Reserved.
3 *
4 * This file is part of Tox.
5 *
6 * Tox is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Tox is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <string.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <errno.h>
27
28#ifdef WIN32
29#include <shlobj.h>
30#include <direct.h>
31#else /* WIN32 */
32#include <unistd.h>
33#include <pwd.h>
34#endif /* WIN32 */
35
36#include "configdir.h"
37
38/**
39 * @brief Get the users config directory.
40 *
41 * This is without a trailing slash.
42 *
43 * @return The users config dir or NULL on error.
44 */
45char *get_user_config_dir(void)
46{
47 char *user_config_dir;
48#ifdef WIN32
49 char appdata[MAX_PATH];
50 BOOL ok;
51
52 ok = SHGetSpecialFolderPathA(NULL, appdata, CSIDL_PROFILE, TRUE);
53
54 if (!ok) {
55 return NULL;
56 }
57
58 user_config_dir = strdup(appdata);
59
60 return user_config_dir;
61
62#else /* WIN32 */
63
64#ifndef NSS_BUFLEN_PASSWD
65#define NSS_BUFLEN_PASSWD 4096
66#endif /* NSS_BUFLEN_PASSWD */
67
68 struct passwd pwd;
69 struct passwd *pwdbuf;
70 const char *home;
71 char buf[NSS_BUFLEN_PASSWD];
72 size_t len;
73 int rc;
74
75 rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
76
77 if (rc == 0) {
78 home = pwd.pw_dir;
79 } else {
80 home = getenv("HOME");
81
82 if (home == NULL) {
83 return NULL;
84 }
85
86 /* env variables can be tainted */
87 snprintf(buf, sizeof(buf), "%s", home);
88 home = buf;
89 }
90
91# if defined(__APPLE__)
92 len = strlen(home) + strlen("/Library/Application Support") + 1;
93 user_config_dir = malloc(len);
94
95 if (user_config_dir == NULL) {
96 return NULL;
97 }
98
99 snprintf(user_config_dir, len, "%s/Library/Application Support", home);
100# else /* __APPLE__ */
101
102 if (!(user_config_dir = getenv("XDG_CONFIG_HOME"))) {
103 len = strlen(home) + strlen("/.config") + 1;
104 user_config_dir = malloc(len);
105
106 if (user_config_dir == NULL) {
107 return NULL;
108 }
109
110 snprintf(user_config_dir, len, "%s/.config", home);
111 }
112
113# endif /* __APPLE__ */
114
115 return user_config_dir;
116#undef NSS_BUFLEN_PASSWD
117#endif /* WIN32 */
118}
119
120/*
121 * Creates the config directory.
122 */
123int create_user_config_dir(char *path)
124{
125
126 int mkdir_err;
127
128#ifdef WIN32
129
130 char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1);
131 strcpy(fullpath, path);
132 strcat(fullpath, CONFIGDIR);
133
134 mkdir_err = _mkdir(fullpath);
135 struct __stat64 buf;
136
137 if (mkdir_err && (errno != EEXIST || _wstat64(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
138 free(fullpath);
139 return -1;
140 }
141
142#else
143
144 mkdir_err = mkdir(path, 0700);
145 struct stat buf;
146
147 if (mkdir_err && (errno != EEXIST || stat(path, &buf) || !S_ISDIR(buf.st_mode))) {
148 return -1;
149 }
150
151 char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1);
152 strcpy(fullpath, path);
153 strcat(fullpath, CONFIGDIR);
154
155 mkdir_err = mkdir(fullpath, 0700);
156
157 if (mkdir_err && (errno != EEXIST || stat(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
158 free(fullpath);
159 return -1;
160 }
161
162#endif
163 free(fullpath);
164 return 0;
165}
diff --git a/testing/toxic/configdir.h b/testing/toxic/configdir.h
deleted file mode 100644
index e886e53a..00000000
--- a/testing/toxic/configdir.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (C) 2013 Tox project All Rights Reserved.
3 *
4 * This file is part of Tox.
5 *
6 * Tox is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Tox is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifdef _win32
22#define CONFIGDIR "\\tox\\"
23#else
24#define CONFIGDIR "/tox/"
25#endif
26
27#ifndef S_ISDIR
28#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
29#endif
30
31char *get_user_config_dir(void);
32
33int create_user_config_dir(char *path);
diff --git a/testing/toxic/dhtstatus.c b/testing/toxic/dhtstatus.c
deleted file mode 100644
index 33300772..00000000
--- a/testing/toxic/dhtstatus.c
+++ /dev/null
@@ -1,99 +0,0 @@
1#include "dhtstatus.h"
2#include "string.h"
3#include "../../core/network.h"
4#include "../../core/DHT.h"
5
6typedef uint8_t ipbuf[3 * 4 + 3 + 1];
7static int num_selected = 0;
8
9static void printip(ipbuf buf, IP ip)
10{
11 sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]);
12}
13
14static void dhtstatus_onKey(ToxWindow *self, Messenger *m, wint_t key)
15{
16 switch (key) {
17 case KEY_UP:
18 case 'k':
19 if (--num_selected < 0)
20 num_selected = CLIENT_ID_SIZE - 1;
21
22 break;
23
24 case KEY_DOWN:
25 case 'j':
26 num_selected = (num_selected + 1) % CLIENT_ID_SIZE;
27 break;
28
29 case '\n':
30 break;
31
32 default:
33 break;
34 }
35}
36
37static void dhtstatus_onDraw(ToxWindow *self, Messenger *m)
38{
39 Client_data *close_clientlist = DHT_get_close_list(m->dht);
40 curs_set(0);
41 werase(self->window);
42
43 uint64_t now = unix_time();
44 uint32_t i, j;
45 ipbuf ipbuf;
46 wprintw(self->window,
47 "\n%llu ______________________ CLOSE LIST ________________________ ___ IP ADDR ___ _PRT_ LST PNG ____ SELF ____ _PRT_ LST\n\n",
48 now);
49
50 for (i = 0; i < 32; i++) { /*Number of nodes in closelist*/
51 Client_data *client = close_clientlist + i;
52
53 if (i == num_selected) wattron(self->window, COLOR_PAIR(3));
54
55 wprintw(self->window, "[%02i] ", i);
56 uint16_t port = ntohs(client->ip_port.port);
57
58 if (port) {
59 for (j = 0; j < CLIENT_ID_SIZE; j++)
60 wprintw(self->window, "%02hhx", client->client_id[j]);
61
62 printip(ipbuf, client->ip_port.ip);
63 wprintw(self->window, " %15s %5u ", ipbuf, port);
64 wprintw(self->window, " %3llu ", now - client->timestamp);
65 wprintw(self->window, " %3llu ", now - client->last_pinged);
66
67 port = ntohs(client->ret_ip_port.port);
68
69 if (port) {
70 printip(ipbuf, client->ret_ip_port.ip);
71 wprintw(self->window, " %15s %5u %3llu", ipbuf, port, now - close_clientlist[i].ret_timestamp);
72 }
73 }
74
75 wprintw(self->window, "\n");
76
77 if (i == num_selected) wattroff(self->window, COLOR_PAIR(3));
78 }
79
80 wrefresh(self->window);
81}
82
83static void dhtstatus_onInit(ToxWindow *self, Messenger *m)
84{
85
86}
87
88ToxWindow new_dhtstatus()
89{
90 ToxWindow ret;
91 memset(&ret, 0, sizeof(ret));
92
93 ret.onKey = &dhtstatus_onKey;
94 ret.onDraw = &dhtstatus_onDraw;
95 ret.onInit = &dhtstatus_onInit;
96
97 strcpy(ret.title, "[dht status]");
98 return ret;
99}
diff --git a/testing/toxic/dhtstatus.h b/testing/toxic/dhtstatus.h
deleted file mode 100644
index 2b30e5a3..00000000
--- a/testing/toxic/dhtstatus.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef _dhtstatus_h
2#define _dhtstatus_h
3
4#include "windows.h"
5
6ToxWindow new_dhtstatus();
7
8#endif
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
deleted file mode 100644
index 8fa3b473..00000000
--- a/testing/toxic/friendlist.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <string.h>
6#include <stdint.h>
7#include <ctype.h>
8
9#include "../../core/Messenger.h"
10#include "../../core/network.h"
11
12#include "windows.h"
13#include "friendlist.h"
14
15
16typedef struct {
17 uint8_t name[MAX_NAME_LENGTH];
18 uint8_t status[MAX_STATUSMESSAGE_LENGTH];
19 int num;
20 int chatwin;
21} friend_t;
22
23static friend_t friends[MAX_FRIENDS_NUM];
24static int num_friends = 0;
25static int num_selected = 0;
26
27
28void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
29{
30 if (num >= num_friends)
31 return;
32
33 if (friends[num].chatwin == -1) {
34 friends[num].chatwin = add_window(m, new_chat(m, num));
35 }
36}
37
38void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
39{
40 if (len >= MAX_NAME_LENGTH || num >= num_friends)
41 return;
42
43 memcpy((char *) &friends[num].name, (char *) str, len);
44 friends[num].name[len] = 0;
45}
46
47void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
48{
49 if (len >= MAX_STATUSMESSAGE_LENGTH || num >= num_friends)
50 return;
51
52 memcpy((char *) &friends[num].status, (char *) str, len);
53 friends[num].status[len] = 0;
54}
55
56int friendlist_onFriendAdded(Messenger *m, int num)
57{
58 if (num_friends == MAX_FRIENDS_NUM)
59 return -1;
60
61 friends[num_friends].num = num;
62 getname(m, num, friends[num_friends].name);
63 strcpy((char *) friends[num_friends].name, "unknown");
64 strcpy((char *) friends[num_friends].status, "unknown");
65 friends[num_friends++].chatwin = -1;
66 return 0;
67}
68
69static void friendlist_onKey(ToxWindow *self, Messenger *m, wint_t key)
70{
71 if (key == KEY_UP) {
72 if (--num_selected < 0)
73 num_selected = num_friends - 1;
74 } else if (key == KEY_DOWN) {
75 if (num_friends != 0)
76 num_selected = (num_selected + 1) % num_friends;
77 } else if (key == '\n') {
78 /* Jump to chat window if already open */
79 if (friends[num_selected].chatwin != -1) {
80 set_active_window(friends[num_selected].chatwin);
81 } else {
82 friends[num_selected].chatwin = add_window(m, new_chat(m, num_selected));
83 }
84 }
85}
86
87static void friendlist_onDraw(ToxWindow *self, Messenger *m)
88{
89 curs_set(0);
90 werase(self->window);
91
92 if (num_friends == 0) {
93 wprintw(self->window, "Empty. Add some friends! :-)\n");
94 } else {
95 wattron(self->window, COLOR_PAIR(2) | A_BOLD);
96 wprintw(self->window, "Open chat with.. (up/down keys, enter)\n");
97 wattroff(self->window, COLOR_PAIR(2) | A_BOLD);
98 }
99
100 wprintw(self->window, "\n");
101 int i;
102
103 for (i = 0; i < num_friends; ++i) {
104 if (i == num_selected) wattron(self->window, COLOR_PAIR(3));
105
106 wprintw(self->window, " [#%d] ", friends[i].num);
107
108 if (i == num_selected) wattroff(self->window, COLOR_PAIR(3));
109
110 attron(A_BOLD);
111 wprintw(self->window, "%s ", friends[i].name);
112 attroff(A_BOLD);
113
114 wprintw(self->window, "(%s)\n", friends[i].status);
115 }
116
117 wrefresh(self->window);
118}
119
120void disable_chatwin(int f_num)
121{
122 friends[f_num].chatwin = -1;
123}
124
125static void friendlist_onInit(ToxWindow *self, Messenger *m)
126{
127
128}
129
130ToxWindow new_friendlist()
131{
132 ToxWindow ret;
133 memset(&ret, 0, sizeof(ret));
134
135 ret.onKey = &friendlist_onKey;
136 ret.onDraw = &friendlist_onDraw;
137 ret.onInit = &friendlist_onInit;
138 ret.onMessage = &friendlist_onMessage;
139 ret.onAction = &friendlist_onMessage; // Action has identical behaviour to message
140 ret.onNickChange = &friendlist_onNickChange;
141 ret.onStatusChange = &friendlist_onStatusChange;
142
143 strcpy(ret.title, "[friends]");
144 return ret;
145}
diff --git a/testing/toxic/friendlist.h b/testing/toxic/friendlist.h
deleted file mode 100644
index 6f045d4a..00000000
--- a/testing/toxic/friendlist.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef FRIENDLIST_H_53I41IM
2#define FRIENDLIST_H_53I41IM
3
4#include "windows.h"
5#include "chat.h"
6
7ToxWindow new_friendlist();
8int friendlist_onFriendAdded(Messenger *m, int num);
9void disable_chatwin(int f_num);
10
11#endif /* end of include guard: FRIENDLIST_H_53I41IM */
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
deleted file mode 100644
index 2d4a39ad..00000000
--- a/testing/toxic/main.c
+++ /dev/null
@@ -1,345 +0,0 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <curses.h>
6#include <errno.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <stdbool.h>
10#include <stdint.h>
11#include <signal.h>
12#include <locale.h>
13
14#ifdef _win32
15#include <direct.h>
16#else
17#include <sys/stat.h>
18#include <sys/types.h>
19#endif
20
21#include "../../core/Messenger.h"
22#include "../../core/network.h"
23
24#include "configdir.h"
25#include "windows.h"
26#include "prompt.h"
27#include "friendlist.h"
28
29/* Export for use in Callbacks */
30char *DATA_FILE = NULL;
31char *SRVLIST_FILE = NULL;
32
33void on_window_resize(int sig)
34{
35 endwin();
36 refresh();
37 clear();
38}
39
40static void init_term()
41{
42 /* Setup terminal */
43 signal(SIGWINCH, on_window_resize);
44 setlocale(LC_ALL, "");
45 initscr();
46 cbreak();
47 keypad(stdscr, 1);
48 noecho();
49 timeout(100);
50
51 if (has_colors()) {
52 start_color();
53 init_pair(1, COLOR_GREEN, COLOR_BLACK);
54 init_pair(2, COLOR_CYAN, COLOR_BLACK);
55 init_pair(3, COLOR_RED, COLOR_BLACK);
56 init_pair(4, COLOR_BLUE, COLOR_BLACK);
57 init_pair(5, COLOR_YELLOW, COLOR_BLACK);
58 init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
59 init_pair(7, COLOR_BLACK, COLOR_BLACK);
60 init_pair(8, COLOR_BLACK, COLOR_WHITE);
61
62 }
63
64 refresh();
65}
66
67static Messenger *init_tox()
68{
69 /* Init core */
70 Messenger *m = initMessenger();
71
72 /* Callbacks */
73 m_callback_friendrequest(m, on_request, NULL);
74 m_callback_friendmessage(m, on_message, NULL);
75 m_callback_namechange(m, on_nickchange, NULL);
76 m_callback_statusmessage(m, on_statuschange, NULL);
77 m_callback_action(m, on_action, NULL);
78#ifdef __linux__
79 setname(m, (uint8_t *) "Cool guy", sizeof("Cool guy"));
80#elif defined(WIN32)
81 setname(m, (uint8_t *) "I should install GNU/Linux", sizeof("I should install GNU/Linux"));
82#elif defined(__APPLE__)
83 setname(m, (uint8_t *) "Hipster", sizeof("Hipster")); //This used to users of other Unixes are hipsters
84#else
85 setname(m, (uint8_t *) "Registered Minix user #4", sizeof("Registered Minix user #4"));
86#endif
87 return m;
88}
89
90#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */
91#define MINLINE 70
92#define MAXSERVERS 50
93
94/* Connects to a random DHT server listed in the DHTservers file */
95int init_connection(Messenger *m)
96{
97 FILE *fp = NULL;
98
99 if (DHT_isconnected(m->dht))
100 return 0;
101
102 fp = fopen(SRVLIST_FILE, "r");
103
104 if (!fp)
105 return 1;
106
107 char servers[MAXSERVERS][MAXLINE];
108 char line[MAXLINE];
109 int linecnt = 0;
110
111 while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) {
112 if (strlen(line) > MINLINE)
113 strcpy(servers[linecnt++], line);
114 }
115
116 if (linecnt < 1) {
117 fclose(fp);
118 return 2;
119 }
120
121 fclose(fp);
122
123 char *server = servers[rand() % linecnt];
124 char *ip = strtok(server, " ");
125 char *port = strtok(NULL, " ");
126 char *key = strtok(NULL, " ");
127
128 if (!ip || !port || !key)
129 return 3;
130
131 IP_Port dht;
132 dht.port = htons(atoi(port));
133 uint32_t resolved_address = resolve_addr(ip);
134
135 if (resolved_address == 0)
136 return 0;
137
138 dht.ip.i = resolved_address;
139 unsigned char *binary_string = hex_string_to_bin(key);
140 DHT_bootstrap(m->dht, dht, binary_string);
141 free(binary_string);
142 return 0;
143}
144
145static void do_tox(Messenger *m, ToxWindow *prompt)
146{
147 static int conn_try = 0;
148 static int conn_err = 0;
149 static bool dht_on = false;
150
151 if (!dht_on && !DHT_isconnected(m->dht) && !(conn_try++ % 100)) {
152 if (!conn_err) {
153 conn_err = init_connection(m);
154 wprintw(prompt->window, "\nEstablishing connection...\n");
155
156 if (conn_err)
157 wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
158 }
159 } else if (!dht_on && DHT_isconnected(m->dht)) {
160 dht_on = true;
161 wprintw(prompt->window, "\nDHT connected.\n");
162 } else if (dht_on && !DHT_isconnected(m->dht)) {
163 dht_on = false;
164 wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
165 }
166
167 doMessenger(m);
168}
169
170int f_loadfromfile;
171
172/*
173 * Store Messenger to given location
174 * Return 0 stored successfully
175 * Return 1 malloc failed
176 * Return 2 opening path failed
177 * Return 3 fwrite failed
178 */
179int store_data(Messenger *m, char *path)
180{
181 if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
182 return 0;
183
184 FILE *fd;
185 size_t len;
186 uint8_t *buf;
187
188 len = Messenger_size(m);
189 buf = malloc(len);
190
191 if (buf == NULL) {
192 return 1;
193 }
194
195 Messenger_save(m, buf);
196
197 fd = fopen(path, "w");
198
199 if (fd == NULL) {
200 free(buf);
201 return 2;
202 }
203
204 if (fwrite(buf, len, 1, fd) != 1) {
205 free(buf);
206 fclose(fd);
207 return 3;
208 }
209
210 free(buf);
211 fclose(fd);
212 return 0;
213}
214
215static void load_data(Messenger *m, char *path)
216{
217 if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
218 return;
219
220 FILE *fd;
221 size_t len;
222 uint8_t *buf;
223
224 if ((fd = fopen(path, "r")) != NULL) {
225 fseek(fd, 0, SEEK_END);
226 len = ftell(fd);
227 fseek(fd, 0, SEEK_SET);
228
229 buf = malloc(len);
230
231 if (buf == NULL) {
232 fprintf(stderr, "malloc() failed.\n");
233 fclose(fd);
234 endwin();
235 exit(1);
236 }
237
238 if (fread(buf, len, 1, fd) != 1) {
239 fprintf(stderr, "fread() failed.\n");
240 free(buf);
241 fclose(fd);
242 endwin();
243 exit(1);
244 }
245
246 Messenger_load(m, buf, len);
247
248 uint32_t i;
249
250 for (i = 0; i < m->numfriends; i++) {
251 on_friendadded(m, i);
252 }
253
254 free(buf);
255 fclose(fd);
256 } else {
257 int st;
258
259 if ((st = store_data(m, path)) != 0) {
260 fprintf(stderr, "Store messenger failed with return code: %d\n", st);
261 endwin();
262 exit(1);
263 }
264 }
265}
266
267int main(int argc, char *argv[])
268{
269 char *user_config_dir = get_user_config_dir();
270 int config_err = 0;
271
272 f_loadfromfile = 1;
273 int f_flag = 0;
274 int i = 0;
275
276 for (i = 0; i < argc; ++i) {
277 if (argv[i] == NULL)
278 break;
279 else if (argv[i][0] == '-') {
280 if (argv[i][1] == 'f') {
281 if (argv[i + 1] != NULL)
282 DATA_FILE = strdup(argv[i + 1]);
283 else
284 f_flag = -1;
285 } else if (argv[i][1] == 'n') {
286 f_loadfromfile = 0;
287 }
288 }
289 }
290
291 if (DATA_FILE == NULL ) {
292 config_err = create_user_config_dir(user_config_dir);
293
294 if (config_err) {
295 DATA_FILE = strdup("data");
296 SRVLIST_FILE = strdup("../../other/DHTservers");
297 } else {
298 DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
299 strcpy(DATA_FILE, user_config_dir);
300 strcat(DATA_FILE, CONFIGDIR);
301 strcat(DATA_FILE, "data");
302
303 SRVLIST_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("DHTservers") + 1);
304 strcpy(SRVLIST_FILE, user_config_dir);
305 strcat(SRVLIST_FILE, CONFIGDIR);
306 strcat(SRVLIST_FILE, "DHTservers");
307 }
308 }
309
310 free(user_config_dir);
311
312 init_term();
313 Messenger *m = init_tox();
314 ToxWindow *prompt = init_windows(m);
315
316 if (f_loadfromfile)
317 load_data(m, DATA_FILE);
318
319 if (f_flag == -1) {
320 attron(COLOR_PAIR(3) | A_BOLD);
321 wprintw(prompt->window, "You passed '-f' without giving an argument.\n"
322 "defaulting to 'data' for a keyfile...\n");
323 attroff(COLOR_PAIR(3) | A_BOLD);
324 }
325
326 if (config_err) {
327 attron(COLOR_PAIR(3) | A_BOLD);
328 wprintw(prompt->window, "Unable to determine configuration directory.\n"
329 "defaulting to 'data' for a keyfile...\n");
330 attroff(COLOR_PAIR(3) | A_BOLD);
331 }
332
333 while (true) {
334 /* Update tox */
335 do_tox(m, prompt);
336
337 /* Draw */
338 draw_active_window(m);
339 }
340
341 cleanupMessenger(m);
342 free(DATA_FILE);
343 free(SRVLIST_FILE);
344 return 0;
345}
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
deleted file mode 100644
index b00dba20..00000000
--- a/testing/toxic/prompt.c
+++ /dev/null
@@ -1,509 +0,0 @@
1/*
2* Toxic -- Tox Curses Client
3*/
4
5#include <stdlib.h>
6#include <string.h>
7#include <ctype.h>
8
9#include "../../core/Messenger.h"
10#include "../../core/network.h"
11
12#include "windows.h"
13#include "prompt.h"
14
15extern char *DATA_FILE;
16extern int store_data(Messenger *m, char *path);
17
18uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX
19uint8_t num_requests = 0; // XXX
20
21static char prompt_buf[MAX_STR_SIZE] = {0};
22static int prompt_buf_pos = 0;
23
24/* commands */
25void cmd_accept(ToxWindow *, Messenger *m, char **);
26void cmd_add(ToxWindow *, Messenger *m, char **);
27void cmd_clear(ToxWindow *, Messenger *m, char **);
28void cmd_connect(ToxWindow *, Messenger *m, char **);
29void cmd_help(ToxWindow *, Messenger *m, char **);
30void cmd_msg(ToxWindow *, Messenger *m, char **);
31void cmd_myid(ToxWindow *, Messenger *m, char **);
32void cmd_nick(ToxWindow *, Messenger *m, char **);
33void cmd_mynick(ToxWindow *, Messenger *m, char **);
34void cmd_quit(ToxWindow *, Messenger *m, char **);
35void cmd_status(ToxWindow *, Messenger *m, char **);
36void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
37
38#define NUM_COMMANDS 14
39
40static struct {
41 char *name;
42 int numargs;
43 void (*func)(ToxWindow *, Messenger *m, char **);
44} commands[] = {
45 { "accept", 1, cmd_accept },
46 { "add", 1, cmd_add },
47 { "clear", 0, cmd_clear },
48 { "connect", 3, cmd_connect },
49 { "exit", 0, cmd_quit },
50 { "help", 0, cmd_help },
51 { "msg", 2, cmd_msg },
52 { "myid", 0, cmd_myid },
53 { "nick", 1, cmd_nick },
54 { "mynick", 0, cmd_mynick },
55 { "q", 0, cmd_quit },
56 { "quit", 0, cmd_quit },
57 { "status", 2, cmd_status },
58 { "statusmsg", 1, cmd_statusmsg },
59};
60
61// XXX:
62int add_req(uint8_t *public_key)
63{
64 memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
65 ++num_requests;
66 return num_requests - 1;
67}
68
69// XXX: FIX
70unsigned char *hex_string_to_bin(char hex_string[])
71{
72 size_t len = strlen(hex_string);
73 unsigned char *val = malloc(len);
74 char *pos = hex_string;
75 int i;
76
77 for (i = 0; i < len; ++i, pos += 2)
78 sscanf(pos, "%2hhx", &val[i]);
79
80 return val;
81}
82
83void cmd_accept(ToxWindow *self, Messenger *m, char **args)
84{
85 int num = atoi(args[1]);
86
87 if (num >= num_requests) {
88 wprintw(self->window, "Invalid syntax.\n");
89 return;
90 }
91
92 num = m_addfriend_norequest(m, pending_requests[num]);
93
94 if (num == -1)
95 wprintw(self->window, "Failed to add friend.\n");
96 else {
97 wprintw(self->window, "Friend accepted as: %d.\n", num);
98 on_friendadded(m, num);
99 }
100}
101
102void cmd_add(ToxWindow *self, Messenger *m, char **args)
103{
104 uint8_t id_bin[FRIEND_ADDRESS_SIZE];
105 char xx[3];
106 uint32_t x;
107 char *id = args[1];
108 char *msg = args[2];
109
110 if (!id) {
111 wprintw(self->window, "Invalid command: add expected at least one argument.\n");
112 return;
113 }
114
115 if (!msg)
116 msg = "";
117
118 if (strlen(id) != 2 * FRIEND_ADDRESS_SIZE) {
119 wprintw(self->window, "Invalid ID length.\n");
120 return;
121 }
122
123 int i;
124
125 for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
126 xx[0] = id[2 * i];
127 xx[1] = id[2 * i + 1];
128 xx[2] = '\0';
129
130 if (sscanf(xx, "%02x", &x) != 1) {
131 wprintw(self->window, "Invalid ID.\n");
132 return;
133 }
134
135 id_bin[i] = x;
136 }
137
138 for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
139 id[i] = toupper(id[i]);
140 }
141
142 int num = m_addfriend(m, id_bin, (uint8_t *) msg, strlen(msg) + 1);
143
144 switch (num) {
145 case FAERR_TOOLONG:
146 wprintw(self->window, "Message is too long.\n");
147 break;
148
149 case FAERR_NOMESSAGE:
150 wprintw(self->window, "Please add a message to your request.\n");
151 break;
152
153 case FAERR_OWNKEY:
154 wprintw(self->window, "That appears to be your own ID.\n");
155 break;
156
157 case FAERR_ALREADYSENT:
158 wprintw(self->window, "Friend request already sent.\n");
159 break;
160
161 case FAERR_UNKNOWN:
162 wprintw(self->window, "Undefined error when adding friend.\n");
163 break;
164
165 case FAERR_BADCHECKSUM:
166 wprintw(self->window, "Bad checksum in address.\n");
167 break;
168
169 case FAERR_SETNEWNOSPAM:
170 wprintw(self->window, "Nospam was different.\n");
171 break;
172
173 default:
174 wprintw(self->window, "Friend added as %d.\n", num);
175 on_friendadded(m, num);
176 break;
177 }
178}
179
180void cmd_clear(ToxWindow *self, Messenger *m, char **args)
181{
182 wclear(self->window);
183}
184
185void cmd_connect(ToxWindow *self, Messenger *m, char **args)
186{
187 IP_Port dht;
188 char *ip = args[1];
189 char *port = args[2];
190 char *key = args[3];
191
192 if (atoi(port) == 0) {
193 wprintw(self->window, "Invalid syntax.\n");
194 return;
195 }
196
197 dht.port = htons(atoi(port));
198 uint32_t resolved_address = resolve_addr(ip);
199
200 if (resolved_address == 0) {
201 return;
202 }
203
204 dht.ip.i = resolved_address;
205 unsigned char *binary_string = hex_string_to_bin(key);
206 DHT_bootstrap(m->dht, dht, binary_string);
207 free(binary_string);
208}
209
210void cmd_quit(ToxWindow *self, Messenger *m, char **args)
211{
212 endwin();
213 exit(0);
214}
215
216void cmd_help(ToxWindow *self, Messenger *m, char **args)
217{
218 wclear(self->window);
219 wattron(self->window, COLOR_PAIR(2) | A_BOLD);
220 wprintw(self->window, "Commands:\n");
221 wattroff(self->window, A_BOLD);
222
223 wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n");
224 wprintw(self->window, " add <id> <message> : Add friend\n");
225 wprintw(self->window, " status <type> <message> : Set your status\n");
226 wprintw(self->window, " statusmsg <message> : Set your status\n");
227 wprintw(self->window, " nick <nickname> : Set your nickname\n");
228 wprintw(self->window, " mynick : Print your current nickname\n");
229 wprintw(self->window, " accept <number> : Accept friend request\n");
230 wprintw(self->window, " myid : Print your ID\n");
231 wprintw(self->window, " quit/exit : Exit program\n");
232 wprintw(self->window, " help : Print this message again\n");
233 wprintw(self->window, " clear : Clear this window\n");
234
235 wattron(self->window, A_BOLD);
236 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
237 wattroff(self->window, A_BOLD);
238
239 wattroff(self->window, COLOR_PAIR(2));
240}
241
242void cmd_msg(ToxWindow *self, Messenger *m, char **args)
243{
244 char *id = args[1];
245 char *msg = args[2];
246
247 if (m_sendmessage(m, atoi(id), (uint8_t *) msg, strlen(msg) + 1) == 0)
248 wprintw(self->window, "Error occurred while sending message.\n");
249 else
250 wprintw(self->window, "Message successfully sent.\n");
251}
252
253void cmd_myid(ToxWindow *self, Messenger *m, char **args)
254{
255 char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
256 size_t i;
257 uint8_t address[FRIEND_ADDRESS_SIZE];
258 getaddress(m, address);
259
260 for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
261 char xx[3];
262 snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
263 strcat(id, xx);
264 }
265
266 wprintw(self->window, "%s\n", id);
267}
268
269void cmd_nick(ToxWindow *self, Messenger *m, char **args)
270{
271 char *nick = args[1];
272 setname(m, (uint8_t *) nick, strlen(nick) + 1);
273 wprintw(self->window, "Nickname set to: %s\n", nick);
274
275 if (store_data(m, DATA_FILE)) {
276 wprintw(self->window, "\nCould not store Messenger data\n");
277 }
278}
279
280void cmd_mynick(ToxWindow *self, Messenger *m, char **args)
281{
282 uint8_t *nick = malloc(m->name_length);
283 getself_name(m, nick, m->name_length);
284 wprintw(self->window, "Current nickname: %s\n", nick);
285 free(nick);
286}
287
288void cmd_status(ToxWindow *self, Messenger *m, char **args)
289{
290 char *status = args[1];
291 char *status_text;
292
293 USERSTATUS status_kind;
294
295 if (!strncmp(status, "online", strlen("online"))) {
296 status_kind = USERSTATUS_NONE;
297 status_text = "ONLINE";
298 } else if (!strncmp(status, "away", strlen("away"))) {
299 status_kind = USERSTATUS_AWAY;
300 status_text = "AWAY";
301 } else if (!strncmp(status, "busy", strlen("busy"))) {
302 status_kind = USERSTATUS_BUSY;
303 status_text = "BUSY";
304 } else {
305 wprintw(self->window, "Invalid status.\n");
306 return;
307 }
308
309 char *msg = args[2];
310
311 if (msg == NULL) {
312 m_set_userstatus(m, status_kind);
313 wprintw(self->window, "Status set to: %s\n", status_text);
314 } else {
315 m_set_userstatus(m, status_kind);
316 m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1);
317 wprintw(self->window, "Status set to: %s, %s\n", status_text, msg);
318 }
319}
320
321void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args)
322{
323 char *msg = args[1];
324 m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1);
325 wprintw(self->window, "Status set to: %s\n", msg);
326}
327
328static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
329{
330 int newlines = 0;
331 char cmd[MAX_STR_SIZE] = {0};
332 int i;
333
334 for (i = 0; i < strlen(prompt_buf); ++i) {
335 if (u_cmd[i] == '\n')
336 ++newlines;
337 else
338 cmd[i - newlines] = u_cmd[i];
339 }
340
341 int leading_spc = 0;
342
343 for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i)
344 leading_spc++;
345
346 memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc);
347
348 int cmd_end = strlen(cmd);
349
350 while (cmd_end > 0 && cmd_end--)
351 if (!isspace(cmd[cmd_end]))
352 break;
353
354 cmd[cmd_end + 1] = '\0';
355
356 /* insert \0 at argument boundaries */
357 int numargs = 0;
358
359 for (i = 0; i < MAX_STR_SIZE; i++) {
360 char quote_chr;
361 if (cmd[i] == '\"' || cmd[i] == '\'') {
362 quote_chr = cmd[i];
363 while (cmd[++i] != quote_chr && i < MAX_STR_SIZE); /* skip over strings */
364 /* Check if got qoute character */
365 if (cmd[i] != quote_chr) {
366 wprintw(self->window, "Missing terminating %c character\n", quote_chr);
367 return;
368 }
369 }
370
371 if (cmd[i] == ' ') {
372 cmd[i] = '\0';
373
374 int j = i;
375
376 while (++j < MAX_STR_SIZE && isspace(cmd[j]));
377
378 i = j - 1;
379
380 numargs++;
381 }
382 }
383
384 /* excessive arguments */
385 if (numargs > 3) {
386 wprintw(self->window, "Invalid command: too many arguments.\n");
387 return;
388 }
389
390 /* read arguments into array */
391 char *cmdargs[5];
392 int pos = 0;
393
394 for (i = 0; i < 5; i++) {
395 cmdargs[i] = cmd + pos;
396 pos += strlen(cmdargs[i]) + 1;
397
398 while (isspace(cmd[pos]) && pos < MAX_STR_SIZE)
399 ++pos;
400 }
401
402 /* no input */
403 if (strlen(cmdargs[0]) == 0)
404 return;
405
406 /* match input to command list */
407 for (i = 0; i < NUM_COMMANDS; i++) {
408 if (!strcmp(cmdargs[0], commands[i].name)) {
409 /* check for missing arguments */
410 int j;
411
412 for (j = 0; j <= commands[i].numargs; j++) {
413 if (strlen(cmdargs[j]) == 0) {
414 wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n",
415 commands[i].name, commands[i].numargs, j - 1);
416 return;
417 }
418 }
419
420 /* check for excess arguments */
421 if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
422 wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
423 return;
424 }
425
426 /* pass arguments to command function */
427 (commands[i].func)(self, m, cmdargs);
428 return;
429 }
430 }
431
432 /* no match */
433 wprintw(self->window, "Invalid command.\n");
434}
435
436static void prompt_onKey(ToxWindow *self, Messenger *m, wint_t key)
437{
438 /* Add printable characters to line */
439 if (isprint(key)) {
440 if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) {
441 wprintw(self->window, "\nToo Long.\n");
442 prompt_buf_pos = 0;
443 prompt_buf[0] = 0;
444 } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS)
445 && (prompt_buf_pos % (COLS - 3) == 0)) {
446 prompt_buf[prompt_buf_pos++] = '\n';
447 } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS)
448 && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) {
449 prompt_buf[prompt_buf_pos++] = '\n';
450 }
451
452 prompt_buf[prompt_buf_pos++] = key;
453 prompt_buf[prompt_buf_pos] = 0;
454 }
455
456 /* RETURN key: execute command */
457 else if (key == '\n') {
458 wprintw(self->window, "\n");
459 execute(self, m, prompt_buf);
460 prompt_buf_pos = 0;
461 prompt_buf[0] = 0;
462 }
463
464 /* BACKSPACE key: Remove one character from line */
465 else if (key == 0x107 || key == 0x8 || key == 0x7f) {
466 if (prompt_buf_pos != 0) {
467 prompt_buf[--prompt_buf_pos] = 0;
468 }
469 }
470}
471
472static void prompt_onDraw(ToxWindow *self, Messenger *m)
473{
474 curs_set(1);
475 int x, y;
476 getyx(self->window, y, x);
477 (void) x;
478 int i;
479
480 for (i = 0; i < (strlen(prompt_buf)); ++i) {
481 if ((prompt_buf[i] == '\n') && (y != 0))
482 --y;
483 }
484
485 wattron(self->window, COLOR_PAIR(1));
486 mvwprintw(self->window, y, 0, "# ");
487 wattroff(self->window, COLOR_PAIR(1));
488 mvwprintw(self->window, y, 2, "%s", prompt_buf);
489 wclrtoeol(self->window);
490 wrefresh(self->window);
491}
492
493static void prompt_onInit(ToxWindow *self, Messenger *m)
494{
495 scrollok(self->window, 1);
496 cmd_help(self, m, NULL);
497 wclrtoeol(self->window);
498}
499
500ToxWindow new_prompt()
501{
502 ToxWindow ret;
503 memset(&ret, 0, sizeof(ret));
504 ret.onKey = &prompt_onKey;
505 ret.onDraw = &prompt_onDraw;
506 ret.onInit = &prompt_onInit;
507 strcpy(ret.title, "[prompt]");
508 return ret;
509}
diff --git a/testing/toxic/prompt.h b/testing/toxic/prompt.h
deleted file mode 100644
index 8e12a42f..00000000
--- a/testing/toxic/prompt.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef PROMPT_H_UZYGWFFL
2#define PROMPT_H_UZYGWFFL
3
4#include "windows.h"
5
6ToxWindow new_prompt();
7int add_req(uint8_t *public_key);
8unsigned char *hex_string_to_bin(char hex_string[]);
9
10#endif /* end of include guard: PROMPT_H_UZYGWFFL */
11
12
diff --git a/testing/toxic/windows.c b/testing/toxic/windows.c
deleted file mode 100644
index 7f547d0a..00000000
--- a/testing/toxic/windows.c
+++ /dev/null
@@ -1,247 +0,0 @@
1#include "friendlist.h"
2#include "prompt.h"
3#include "dhtstatus.h"
4#include "windows.h"
5
6extern char *DATA_FILE;
7extern int store_data(Messenger *m, char *path);
8
9static ToxWindow windows[MAX_WINDOWS_NUM];
10static ToxWindow *active_window;
11static ToxWindow *prompt;
12static Messenger *m;
13
14/* CALLBACKS START */
15void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
16{
17 int n = add_req(public_key);
18 wprintw(prompt->window, "\nFriend request from:\n");
19
20 int i;
21
22 for (i = 0; i < KEY_SIZE_BYTES; ++i) {
23 wprintw(prompt->window, "%02x", public_key[i] & 0xff);
24 }
25
26 wprintw(prompt->window, "\nWith the message: %s\n", data);
27 wprintw(prompt->window, "\nUse \"accept %d\" to accept it.\n", n);
28
29 for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
30 if (windows[i].onFriendRequest != NULL)
31 windows[i].onFriendRequest(&windows[i], public_key, data, length);
32 }
33}
34
35void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
36{
37 int i;
38
39 for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
40 if (windows[i].onMessage != NULL)
41 windows[i].onMessage(&windows[i], m, friendnumber, string, length);
42 }
43}
44
45void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
46{
47 int i;
48
49 for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
50 if (windows[i].onAction != NULL)
51 windows[i].onAction(&windows[i], m, friendnumber, string, length);
52 }
53}
54
55void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
56{
57 wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string);
58 int i;
59
60 for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
61 if (windows[i].onNickChange != NULL)
62 windows[i].onNickChange(&windows[i], friendnumber, string, length);
63 }
64}
65
66void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
67{
68 wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string);
69 int i;
70
71 for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
72 if (windows[i].onStatusChange != NULL)
73 windows[i].onStatusChange(&windows[i], friendnumber, string, length);
74 }
75}
76
77void on_friendadded(Messenger *m, int friendnumber)
78{
79 friendlist_onFriendAdded(m, friendnumber);
80
81 if (store_data(m, DATA_FILE)) {
82 wprintw(prompt->window, "\nCould not store Messenger data\n");
83 }
84}
85/* CALLBACKS END */
86
87int add_window(Messenger *m, ToxWindow w)
88{
89 if (LINES < 2)
90 return -1;
91
92 int i;
93
94 for (i = 0; i < MAX_WINDOWS_NUM; i++) {
95 if (windows[i].window)
96 continue;
97
98 w.window = newwin(LINES - 2, COLS, 0, 0);
99
100 if (w.window == NULL)
101 return -1;
102
103 windows[i] = w;
104 w.onInit(&w, m);
105
106 active_window = windows + i;
107 return i;
108 }
109
110 return -1;
111}
112
113/* Deletes window w and cleans up */
114void del_window(ToxWindow *w)
115{
116 active_window = windows; // Go to prompt screen
117 delwin(w->window);
118
119 if (w->x)
120 free(w->x);
121
122 w->window = NULL;
123 memset(w, 0, sizeof(ToxWindow));
124 clear();
125 refresh();
126}
127
128/* Shows next window when tab or back-tab is pressed */
129void set_next_window(int ch)
130{
131 ToxWindow *end = windows + MAX_WINDOWS_NUM - 1;
132 ToxWindow *inf = active_window;
133
134 while (true) {
135 if (ch == '\t') {
136 if (++active_window > end)
137 active_window = windows;
138 } else if (--active_window < windows)
139 active_window = end;
140
141 if (active_window->window)
142 return;
143
144 if (active_window == inf) { // infinite loop check
145 endwin();
146 exit(2);
147 }
148 }
149}
150
151void set_active_window(int index)
152{
153 if (index < 0 || index >= MAX_WINDOWS_NUM)
154 return;
155
156 active_window = windows + index;
157}
158
159ToxWindow *init_windows()
160{
161 int n_prompt = add_window(m, new_prompt());
162
163 if (n_prompt == -1
164 || add_window(m, new_friendlist()) == -1
165 || add_window(m, new_dhtstatus()) == -1) {
166 fprintf(stderr, "add_window() failed.\n");
167 endwin();
168 exit(1);
169 }
170
171 prompt = &windows[n_prompt];
172 active_window = prompt;
173
174 return prompt;
175}
176
177static void draw_bar()
178{
179 static int odd = 0;
180 int blinkrate = 30;
181
182 attron(COLOR_PAIR(4));
183 mvhline(LINES - 2, 0, '_', COLS);
184 attroff(COLOR_PAIR(4));
185
186 move(LINES - 1, 0);
187
188 attron(COLOR_PAIR(4) | A_BOLD);
189 printw(" TOXIC " TOXICVER "|");
190 attroff(COLOR_PAIR(4) | A_BOLD);
191
192 int i;
193
194 for (i = 0; i < (MAX_WINDOWS_NUM); ++i) {
195 if (windows[i].window) {
196 if (windows + i == active_window)
197 attron(A_BOLD);
198
199 odd = (odd + 1) % blinkrate;
200
201 if (windows[i].blink && (odd < (blinkrate / 2)))
202 attron(COLOR_PAIR(3));
203
204 clrtoeol();
205 printw(" %s", windows[i].title);
206
207 if (windows[i].blink && (odd < (blinkrate / 2)))
208 attroff(COLOR_PAIR(3));
209
210 if (windows + i == active_window) {
211 attroff(A_BOLD);
212 }
213 }
214 }
215
216 refresh();
217}
218
219void prepare_window(WINDOW *w)
220{
221 mvwin(w, 0, 0);
222 wresize(w, LINES - 2, COLS);
223}
224
225void draw_active_window(Messenger *m)
226{
227
228 ToxWindow *a = active_window;
229 wint_t ch = 0;
230
231 prepare_window(a->window);
232 a->blink = false;
233 draw_bar();
234 a->onDraw(a, m);
235
236 /* Handle input */
237#ifdef HAVE_WIDECHAR
238 get_wch(&ch);
239#else
240 ch = getch();
241#endif
242
243 if (ch == '\t' || ch == KEY_BTAB)
244 set_next_window((int) ch);
245 else if (ch != ERR)
246 a->onKey(a, m, ch);
247}
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h
deleted file mode 100644
index 0f3b82bd..00000000
--- a/testing/toxic/windows.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4#ifndef _windows_h
5#define _windows_h
6
7#include <curses.h>
8#include <stdint.h>
9#include <stdbool.h>
10#include <wctype.h>
11#include <wchar.h>
12#include "../../core/Messenger.h"
13#define MAX_WINDOWS_NUM 32
14#define MAX_FRIENDS_NUM 100
15#define MAX_STR_SIZE 256
16#define KEY_SIZE_BYTES 32
17
18/* number of permanent default windows */
19#define N_DEFAULT_WINS 3
20
21#ifndef TOXICVER
22#define TOXICVER "NOVER" //Use the -D flag to set this
23#endif
24
25typedef struct ToxWindow_ ToxWindow;
26
27struct ToxWindow_ {
28 void(*onKey)(ToxWindow *, Messenger *, wint_t);
29 void(*onDraw)(ToxWindow *, Messenger *);
30 void(*onInit)(ToxWindow *, Messenger *);
31 void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);
32 void(*onMessage)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
33 void(*onNickChange)(ToxWindow *, int, uint8_t *, uint16_t);
34 void(*onStatusChange)(ToxWindow *, int, uint8_t *, uint16_t);
35 void(*onAction)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
36 char title[256];
37
38 void *x;
39 bool blink;
40
41 WINDOW *window;
42};
43
44void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata);
45void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
46void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
47void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
48void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
49void on_friendadded(Messenger *m, int friendnumber);
50ToxWindow *init_windows();
51void draw_active_window(Messenger *m);
52int add_window(Messenger *m, ToxWindow w);
53void del_window(ToxWindow *w);
54void set_active_window(int ch);
55#endif
56