summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt10
-rw-r--r--INSTALL.md22
-rw-r--r--README.md5
-rw-r--r--core/CMakeLists.txt4
-rw-r--r--core/DHT.c160
-rw-r--r--core/network.h1
-rw-r--r--testing/nTox.c24
-rw-r--r--testing/nTox_win32.c67
-rw-r--r--testing/nTox_win32.h2
-rw-r--r--testing/toxic/chat.c25
-rw-r--r--testing/toxic/friendlist.c1
-rw-r--r--testing/toxic/main.c56
-rw-r--r--testing/toxic/prompt.c2
13 files changed, 228 insertions, 151 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bf709e72..07098391 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 2.6.0)
2 2
3set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 3set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
4 4
5if(UNIX)
6 find_package(Curses REQUIRED)
7endif()
8
5if(NOT WIN32) 9if(NOT WIN32)
6 option(USE_NACL "Use NaCl library instead of libsodium") 10 option(USE_NACL "Use NaCl library instead of libsodium")
7endif() 11endif()
@@ -29,15 +33,15 @@ if(NOT USE_NACL)
29endif() 33endif()
30 34
31macro(linkCoreLibraries exe_name) 35macro(linkCoreLibraries exe_name)
32 add_dependencies(${exe_name} core) 36 add_dependencies(${exe_name} toxcore)
33 if(WIN32) 37 if(WIN32)
34 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/) 38 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
35 target_link_libraries(${exe_name} core 39 target_link_libraries(${exe_name} toxcore
36 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a 40 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a
37 ws2_32) 41 ws2_32)
38 else() 42 else()
39 include_directories(${SODIUM_INCLUDE_DIR}) 43 include_directories(${SODIUM_INCLUDE_DIR})
40 target_link_libraries(${exe_name} core 44 target_link_libraries(${exe_name} toxcore
41 ${LINK_CRYPTO_LIBRARY}) 45 ${LINK_CRYPTO_LIBRARY})
42 46
43 endif() 47 endif()
diff --git a/INSTALL.md b/INSTALL.md
index d6a5b3f9..625a9c6d 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -18,6 +18,14 @@ Build dependencies:
18```bash 18```bash
19apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall 19apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall
20``` 20```
21
22On Fedora:
23
24```bash
25yum groupinstall "Development Tools"
26yum install libtool autoconf automake libconfig-devel ncurses-devel cmake
27```
28
21Note that `libconfig-dev` should be >= 1.4. 29Note that `libconfig-dev` should be >= 1.4.
22 30
23You should get and install [libsodium](https://github.com/jedisct1/libsodium): 31You should get and install [libsodium](https://github.com/jedisct1/libsodium):
@@ -31,6 +39,20 @@ sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
31sudo ldconfig 39sudo ldconfig
32``` 40```
33 41
42Or if checkinstall is not easily available for your distribution (e.g. Fedora),
43this will install the libs to /usr/local/lib and the headers to /usr/local/include:
44
45```bash
46git clone git://github.com/jedisct1/libsodium.git
47cd libsodium
48git checkout tags/0.4.2
49./autogen.sh
50./configure
51make check
52sudo make install
53```
54
55
34Then clone this repo and generate makefile: 56Then clone this repo and generate makefile:
35```bash 57```bash
36git clone git://github.com/irungentoo/ProjectTox-Core.git 58git clone git://github.com/irungentoo/ProjectTox-Core.git
diff --git a/README.md b/README.md
index dcb1cf1b..745fbb10 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ With the rise of governmental monitoring programs, Tox aims to be an easy to use
7 7
8**IRC**: #tox on freenode, alternatively, you can use the [webchat](http://webchat.freenode.net/?channels=#tox).<br /> 8**IRC**: #tox on freenode, alternatively, you can use the [webchat](http://webchat.freenode.net/?channels=#tox).<br />
9**Website**: [http://tox.im](http://tox.im) 9**Website**: [http://tox.im](http://tox.im)
10**Developer Blog**: [http://dev.tox.im](http://dev.tox.im)
10 11
11**Website translations**: [see stal888's repository](https://github.com/stal888/ProjectTox-Website)<br/> 12**Website translations**: [see stal888's repository](https://github.com/stal888/ProjectTox-Website)<br/>
12**Qt GUI**: [see nurupo's repository](https://github.com/nurupo/ProjectTox-Qt-GUI) 13**Qt GUI**: [see nurupo's repository](https://github.com/nurupo/ProjectTox-Qt-GUI)
@@ -21,7 +22,7 @@ Keep everything really simple.
21 22
22## The Complex Stuff: 23## The Complex Stuff:
23+ Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable. 24+ Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable.
24+ Every peer is represented as a [byte string](https://en.wikipedia.org/wiki/String_(computer_science)) (the public key of the peer [client ID]). 25+ Every peer is represented as a [byte string][String] (the public key of the peer [client ID]).
25+ We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID. 26+ We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID.
26+ Once the client has the IP of that peer, they start initiating a secure connection with each other. (See [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)) 27+ Once the client has the IP of that peer, they start initiating a secure connection with each other. (See [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto))
27+ When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications. 28+ When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications.
@@ -52,3 +53,5 @@ configure for the normal user or suffer from being way too centralized.
52- [Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br /> 53- [Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br />
53- [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br /> 54- [Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br />
54- [Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas) 55- [Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas)
56
57[String]: https://en.wikipedia.org/wiki/String_(computer_science)
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 44ae980c..36acb6cf 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -1,5 +1,5 @@
1cmake_minimum_required(VERSION 2.6.0) 1cmake_minimum_required(VERSION 2.6.0)
2project(core C) 2project(toxcore C)
3 3
4if(WIN32) 4if(WIN32)
5 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/) 5 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
@@ -16,4 +16,4 @@ set(core_sources
16 LAN_discovery.c 16 LAN_discovery.c
17 Messenger.c) 17 Messenger.c)
18 18
19add_library(core ${core_sources}) 19add_library(toxcore SHARED ${core_sources})
diff --git a/core/DHT.c b/core/DHT.c
index 6972fdeb..5d5910e0 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -119,23 +119,39 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
119 * return 1 if client_id1 is closer 119 * return 1 if client_id1 is closer
120 * return 2 if client_id2 is closer 120 * return 2 if client_id2 is closer
121 */ 121 */
122int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) 122int id_closest(uint8_t * id, uint8_t * id1, uint8_t * id2)
123{ 123{
124 uint32_t i; 124 size_t i;
125 uint8_t tmp1, tmp2; 125 uint8_t distance1, distance2;
126 126
127 for(i = 0; i < CLIENT_ID_SIZE; ++i) { 127 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
128 tmp1 = abs(client_id[i] ^ client_id1[i]); 128
129 tmp2 = abs(client_id[i] ^ client_id2[i]); 129 distance1 = abs(id[i] ^ id1[i]);
130 distance2 = abs(id[i] ^ id2[i]);
130 131
131 if(tmp1 < tmp2) 132 if(distance1 < distance2)
132 return 1; 133 return 1;
133 else if(tmp1 > tmp2) 134 if(distance1 > distance2)
134 return 2; 135 return 2;
135 } 136 }
136 return 0; 137 return 0;
137} 138}
138 139
140int ipport_equal(IP_Port a, IP_Port b)
141{
142 return (a.ip.i == b.ip.i) && (a.port == b.port);
143}
144
145int id_equal(uint8_t* a, uint8_t* b)
146{
147 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
148}
149
150int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
151{
152 return timestamp + timeout <= time_now;
153}
154
139/* check if client with client_id is already in list of length length. 155/* check if client with client_id is already in list of length length.
140 * if it is then set its corresponding timestamp to current time. 156 * if it is then set its corresponding timestamp to current time.
141 * if the id is already in the list with a different ip_port, update it. 157 * if the id is already in the list with a different ip_port, update it.
@@ -150,12 +166,11 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
150 166
151 for(i = 0; i < length; ++i) { 167 for(i = 0; i < length; ++i) {
152 /*If ip_port is assigned to a different client_id replace it*/ 168 /*If ip_port is assigned to a different client_id replace it*/
153 if(list[i].ip_port.ip.i == ip_port.ip.i && 169 if(ipport_equal(list[i].ip_port, ip_port)) {
154 list[i].ip_port.port == ip_port.port) {
155 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 170 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
156 } 171 }
157 172
158 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 173 if(id_equal(list[i].client_id, client_id)) {
159 /* Refresh the client timestamp. */ 174 /* Refresh the client timestamp. */
160 list[i].timestamp = temp_time; 175 list[i].timestamp = temp_time;
161 list[i].ip_port.ip.i = ip_port.ip.i; 176 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -172,10 +187,12 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
172int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 187int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
173{ 188{
174 uint32_t i; 189 uint32_t i;
190
175 for(i = 0; i < length; ++i) { 191 for(i = 0; i < length; ++i) {
176 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 192 if(id_equal(list[i].client_id, client_id))
177 return 1; 193 return 1;
178 } 194 }
195
179 return 0; 196 return 0;
180} 197}
181 198
@@ -184,10 +201,12 @@ int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
184static int friend_number(uint8_t * client_id) 201static int friend_number(uint8_t * client_id)
185{ 202{
186 uint32_t i; 203 uint32_t i;
204
187 for(i = 0; i < num_friends; ++i) { 205 for(i = 0; i < num_friends; ++i) {
188 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 206 if(id_equal(friends_list[i].client_id, client_id))
189 return i; 207 return i;
190 } 208 }
209
191 return -1; 210 return -1;
192} 211}
193 212
@@ -199,11 +218,11 @@ static int friend_number(uint8_t * client_id)
199int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 218int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
200{ 219{
201 uint32_t i, j, k; 220 uint32_t i, j, k;
202 uint64_t temp_time = unix_time(); 221 uint64_t temp_time = unix_time();
203 int num_nodes = 0, closest, tout, inlist; 222 int num_nodes = 0, closest, tout, inlist;
204 223
205 for (i = 0; i < LCLIENT_LIST; ++i) { 224 for (i = 0; i < LCLIENT_LIST; ++i) {
206 tout = close_clientlist[i].timestamp <= temp_time - BAD_NODE_TIMEOUT; 225 tout = is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT);
207 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); 226 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
208 227
209 /* if node isn't good or is already in list. */ 228 /* if node isn't good or is already in list. */
@@ -218,7 +237,9 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
218 237
219 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 238 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
220 num_nodes++; 239 num_nodes++;
240
221 } else { 241 } else {
242
222 for(j = 0; j < MAX_SENT_NODES; ++j) { 243 for(j = 0; j < MAX_SENT_NODES; ++j) {
223 closest = id_closest( client_id, 244 closest = id_closest( client_id,
224 nodes_list[j].client_id, 245 nodes_list[j].client_id,
@@ -237,7 +258,8 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
237 258
238 for(i = 0; i < num_friends; ++i) { 259 for(i = 0; i < num_friends; ++i) {
239 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 260 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
240 tout = friends_list[i].client_list[j].timestamp <= temp_time - BAD_NODE_TIMEOUT; 261
262 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT);
241 inlist = client_in_nodelist( nodes_list, 263 inlist = client_in_nodelist( nodes_list,
242 MAX_SENT_NODES, 264 MAX_SENT_NODES,
243 friends_list[i].client_list[j].client_id); 265 friends_list[i].client_list[j].client_id);
@@ -288,7 +310,7 @@ int replace_bad( Client_data * list,
288 uint64_t temp_time = unix_time(); 310 uint64_t temp_time = unix_time();
289 for(i = 0; i < length; ++i) { 311 for(i = 0; i < length; ++i) {
290 /* if node is bad */ 312 /* if node is bad */
291 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { 313 if(is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) {
292 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 314 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
293 list[i].ip_port = ip_port; 315 list[i].ip_port = ip_port;
294 list[i].timestamp = temp_time; 316 list[i].timestamp = temp_time;
@@ -376,27 +398,23 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
376 uint32_t i, j; 398 uint32_t i, j;
377 uint64_t temp_time = unix_time(); 399 uint64_t temp_time = unix_time();
378 400
379 if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { 401 if (id_equal(client_id, self_public_key)) {
380 for (i = 0; i < LCLIENT_LIST; ++i) {
381 402
382 if (memcmp( nodeclient_id, 403 for (i = 0; i < LCLIENT_LIST; ++i) {
383 close_clientlist[i].client_id, 404 if (id_equal(nodeclient_id, close_clientlist[i].client_id)) {
384 CLIENT_ID_SIZE ) == 0) {
385 close_clientlist[i].ret_ip_port = ip_port; 405 close_clientlist[i].ret_ip_port = ip_port;
386 close_clientlist[i].ret_timestamp = temp_time; 406 close_clientlist[i].ret_timestamp = temp_time;
387 return; 407 return;
388 } 408 }
389 } 409 }
410
390 } else { 411 } else {
412
391 for (i = 0; i < num_friends; ++i) { 413 for (i = 0; i < num_friends; ++i) {
392 if (memcmp( client_id, 414 if (id_equal(client_id, friends_list[i].client_id)) {
393 friends_list[i].client_id,
394 CLIENT_ID_SIZE ) == 0) {
395 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
396 415
397 if (memcmp( nodeclient_id, 416 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
398 friends_list[i].client_list[j].client_id, 417 if (id_equal(nodeclient_id, friends_list[i].client_list[j].client_id)) {
399 CLIENT_ID_SIZE ) == 0) {
400 friends_list[i].client_list[j].ret_ip_port = ip_port; 418 friends_list[i].client_list[j].ret_ip_port = ip_port;
401 friends_list[i].client_list[j].ret_timestamp = temp_time; 419 friends_list[i].client_list[j].ret_timestamp = temp_time;
402 return; 420 return;
@@ -404,6 +422,7 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
404 } 422 }
405 } 423 }
406 } 424 }
425
407 } 426 }
408} 427}
409 428
@@ -419,14 +438,15 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
419 uint64_t temp_time = unix_time(); 438 uint64_t temp_time = unix_time();
420 439
421 for (i = 0; i < LPING_ARRAY; ++i ) { 440 for (i = 0; i < LPING_ARRAY; ++i ) {
422 if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) { 441 if (!is_timeout(temp_time, pings[i].timestamp, PING_TIMEOUT)) {
423 pinging = 0; 442 pinging = 0;
424 if (ip_port.ip.i != 0 && 443
425 pings[i].ip_port.ip.i == ip_port.ip.i && 444 if (ip_port.ip.i != 0 && ipport_equal(pings[i].ip_port, ip_port))
426 pings[i].ip_port.port == ip_port.port)
427 ++pinging; 445 ++pinging;
446
428 if (ping_id != 0 && pings[i].ping_id == ping_id) 447 if (ping_id != 0 && pings[i].ping_id == ping_id)
429 ++pinging; 448 ++pinging;
449
430 if (pinging == ((ping_id != 0) + (ip_port.ip.i != 0))) 450 if (pinging == ((ping_id != 0) + (ip_port.ip.i != 0)))
431 return 1; 451 return 1;
432 } 452 }
@@ -443,14 +463,15 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
443 uint64_t temp_time = unix_time(); 463 uint64_t temp_time = unix_time();
444 464
445 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) { 465 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
446 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { 466 if(!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) {
447 pinging = 0; 467 pinging = 0;
448 if(ip_port.ip.i != 0 && 468
449 send_nodes[i].ip_port.ip.i == ip_port.ip.i && 469 if(ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port))
450 send_nodes[i].ip_port.port == ip_port.port)
451 ++pinging; 470 ++pinging;
471
452 if(ping_id != 0 && send_nodes[i].ping_id == ping_id) 472 if(ping_id != 0 && send_nodes[i].ping_id == ping_id)
453 ++pinging; 473 ++pinging;
474
454 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 475 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
455 return 1; 476 return 1;
456 } 477 }
@@ -471,10 +492,9 @@ uint64_t add_pinging(IP_Port ip_port)
471 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 492 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
472 uint64_t temp_time = unix_time(); 493 uint64_t temp_time = unix_time();
473 494
474
475 for(i = 0; i < PING_TIMEOUT; ++i ) { 495 for(i = 0; i < PING_TIMEOUT; ++i ) {
476 for(j = 0; j < LPING_ARRAY; ++j ) { 496 for(j = 0; j < LPING_ARRAY; ++j ) {
477 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { 497 if(is_timeout(temp_time, pings[j].timestamp, PING_TIMEOUT - i)) {
478 pings[j].timestamp = temp_time; 498 pings[j].timestamp = temp_time;
479 pings[j].ip_port = ip_port; 499 pings[j].ip_port = ip_port;
480 pings[j].ping_id = ping_id; 500 pings[j].ping_id = ping_id;
@@ -495,7 +515,7 @@ uint64_t add_gettingnodes(IP_Port ip_port)
495 515
496 for(i = 0; i < PING_TIMEOUT; ++i ) { 516 for(i = 0; i < PING_TIMEOUT; ++i ) {
497 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) { 517 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
498 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { 518 if(is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) {
499 send_nodes[j].timestamp = temp_time; 519 send_nodes[j].timestamp = temp_time;
500 send_nodes[j].ip_port = ip_port; 520 send_nodes[j].ip_port = ip_port;
501 send_nodes[j].ping_id = ping_id; 521 send_nodes[j].ping_id = ping_id;
@@ -513,8 +533,7 @@ uint64_t add_gettingnodes(IP_Port ip_port)
513static int pingreq(IP_Port ip_port, uint8_t * public_key) 533static int pingreq(IP_Port ip_port, uint8_t * public_key)
514{ 534{
515 /* check if packet is gonna be sent to ourself */ 535 /* check if packet is gonna be sent to ourself */
516 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0 536 if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0))
517 || is_pinging(ip_port, 0))
518 return 1; 537 return 1;
519 538
520 uint64_t ping_id = add_pinging(ip_port); 539 uint64_t ping_id = add_pinging(ip_port);
@@ -548,7 +567,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
548static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) 567static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
549{ 568{
550 /* check if packet is gonna be sent to ourself */ 569 /* check if packet is gonna be sent to ourself */
551 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 570 if(id_equal(public_key, self_public_key))
552 return 1; 571 return 1;
553 572
554 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; 573 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
@@ -577,8 +596,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
577static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 596static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
578{ 597{
579 /* check if packet is gonna be sent to ourself */ 598 /* check if packet is gonna be sent to ourself */
580 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0 599 if(id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0))
581 || is_gettingnodes(ip_port, 0))
582 return 1; 600 return 1;
583 601
584 uint64_t ping_id = add_gettingnodes(ip_port); 602 uint64_t ping_id = add_gettingnodes(ip_port);
@@ -617,7 +635,7 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
617static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 635static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
618{ 636{
619 /* check if packet is gonna be sent to ourself */ 637 /* check if packet is gonna be sent to ourself */
620 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 638 if(id_equal(public_key, self_public_key))
621 return 1; 639 return 1;
622 640
623 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 641 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
@@ -665,7 +683,7 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
665 return 1; 683 return 1;
666 684
667 /* check if packet is from ourself. */ 685 /* check if packet is from ourself. */
668 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 686 if(id_equal(packet + 1, self_public_key))
669 return 1; 687 return 1;
670 688
671 int len = decrypt_data( packet + 1, 689 int len = decrypt_data( packet + 1,
@@ -691,7 +709,7 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
691 return 1; 709 return 1;
692 710
693 /* check if packet is from ourself. */ 711 /* check if packet is from ourself. */
694 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 712 if(id_equal(packet + 1, self_public_key))
695 return 1; 713 return 1;
696 714
697 int len = decrypt_data( packet + 1, 715 int len = decrypt_data( packet + 1,
@@ -720,7 +738,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
720 return 1; 738 return 1;
721 739
722 /* check if packet is from ourself. */ 740 /* check if packet is from ourself. */
723 if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 741 if (id_equal(packet + 1, self_public_key))
724 return 1; 742 return 1;
725 743
726 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 744 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
@@ -810,16 +828,20 @@ int DHT_delfriend(uint8_t * client_id)
810 Friend * temp; 828 Friend * temp;
811 for (i = 0; i < num_friends; ++i) { 829 for (i = 0; i < num_friends; ++i) {
812 /* Equal */ 830 /* Equal */
813 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 831 if (id_equal(friends_list[i].client_id, client_id)) {
814 --num_friends; 832 --num_friends;
833
815 if (num_friends != i) { 834 if (num_friends != i) {
816 memcpy( friends_list[i].client_id, 835 memcpy( friends_list[i].client_id,
817 friends_list[num_friends].client_id, 836 friends_list[num_friends].client_id,
818 CLIENT_ID_SIZE ); 837 CLIENT_ID_SIZE );
819 } 838 }
839
820 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 840 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
821 if (temp != NULL) 841 if (temp == NULL)
822 friends_list = temp; 842 return 1;
843
844 friends_list = temp;
823 return 0; 845 return 0;
824 } 846 }
825 } 847 }
@@ -836,12 +858,9 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
836 858
837 for (i = 0; i < num_friends; ++i) { 859 for (i = 0; i < num_friends; ++i) {
838 /* Equal */ 860 /* Equal */
839 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 861 if (id_equal(friends_list[i].client_id, client_id)) {
840 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 862 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
841 if (memcmp( friends_list[i].client_list[j].client_id, 863 if (id_equal(friends_list[i].client_list[j].client_id, client_id) && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT))
842 client_id,
843 CLIENT_ID_SIZE ) == 0 &&
844 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
845 return friends_list[i].client_list[j].ip_port; 864 return friends_list[i].client_list[j].ip_port;
846 } 865 }
847 return empty; 866 return empty;
@@ -865,14 +884,14 @@ void doDHTFriends()
865 uint32_t num_nodes = 0; 884 uint32_t num_nodes = 0;
866 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 885 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
867 /* if node is not dead. */ 886 /* if node is not dead. */
868 if (friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { 887 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
869 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 888 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
870 pingreq( friends_list[i].client_list[j].ip_port, 889 pingreq( friends_list[i].client_list[j].ip_port,
871 friends_list[i].client_list[j].client_id ); 890 friends_list[i].client_list[j].client_id );
872 friends_list[i].client_list[j].last_pinged = temp_time; 891 friends_list[i].client_list[j].last_pinged = temp_time;
873 } 892 }
874 /* if node is good. */ 893 /* if node is good. */
875 if (friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { 894 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
876 index[num_nodes] = j; 895 index[num_nodes] = j;
877 ++num_nodes; 896 ++num_nodes;
878 } 897 }
@@ -903,14 +922,14 @@ void doClose()
903 922
904 for (i = 0; i < LCLIENT_LIST; ++i) { 923 for (i = 0; i < LCLIENT_LIST; ++i) {
905 /* if node is not dead. */ 924 /* if node is not dead. */
906 if (close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { 925 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
907 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 926 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
908 pingreq( close_clientlist[i].ip_port, 927 pingreq( close_clientlist[i].ip_port,
909 close_clientlist[i].client_id ); 928 close_clientlist[i].client_id );
910 close_clientlist[i].last_pinged = temp_time; 929 close_clientlist[i].last_pinged = temp_time;
911 } 930 }
912 /* if node is good. */ 931 /* if node is good. */
913 if (close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { 932 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) {
914 index[num_nodes] = i; 933 index[num_nodes] = i;
915 ++num_nodes; 934 ++num_nodes;
916 } 935 }
@@ -937,10 +956,12 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
937int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 956int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
938{ 957{
939 uint32_t i; 958 uint32_t i;
959
940 for (i = 0; i < LCLIENT_LIST; ++i) { 960 for (i = 0; i < LCLIENT_LIST; ++i) {
941 if (memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) 961 if (id_equal(client_id, close_clientlist[i].client_id))
942 return sendpacket(close_clientlist[i].ip_port, packet, length); 962 return sendpacket(close_clientlist[i].ip_port, packet, length);
943 } 963 }
964
944 return -1; 965 return -1;
945} 966}
946 967
@@ -966,10 +987,9 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
966 client = &friend->client_list[i]; 987 client = &friend->client_list[i];
967 988
968 /*If ip is not zero and node is good */ 989 /*If ip is not zero and node is good */
969 if (client->ret_ip_port.ip.i != 0 && 990 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
970 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
971 991
972 if (memcmp(client->client_id, friend->client_id, CLIENT_ID_SIZE) == 0) 992 if (id_equal(client->client_id, friend->client_id))
973 return 0; 993 return 0;
974 994
975 ip_portlist[num_ips] = client->ret_ip_port; 995 ip_portlist[num_ips] = client->ret_ip_port;
@@ -997,8 +1017,7 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
997 client = &friend->client_list[i]; 1017 client = &friend->client_list[i];
998 1018
999 /*If ip is not zero and node is good */ 1019 /*If ip is not zero and node is good */
1000 if (client->ret_ip_port.ip.i != 0 && 1020 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
1001 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1002 1021
1003 if (sendpacket(client->ip_port, packet, length) == length) 1022 if (sendpacket(client->ip_port, packet, length) == length)
1004 ++sent; 1023 ++sent;
@@ -1028,8 +1047,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1028 client = &friend->client_list[i]; 1047 client = &friend->client_list[i];
1029 1048
1030 /*If ip is not zero and node is good */ 1049 /*If ip is not zero and node is good */
1031 if(client->ret_ip_port.ip.i != 0 && 1050 if(client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
1032 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1033 ip_list[n] = client->ip_port; 1051 ip_list[n] = client->ip_port;
1034 ++n; 1052 ++n;
1035 } 1053 }
@@ -1052,7 +1070,7 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
1052 uint32_t i; 1070 uint32_t i;
1053 for (i = 0; i < num_friends; ++i) { 1071 for (i = 0; i < num_friends; ++i) {
1054 /* Equal */ 1072 /* Equal */
1055 if (memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) 1073 if (id_equal(friends_list[i].client_id, friend_id))
1056 return friend_iplist(ip_portlist, i); 1074 return friend_iplist(ip_portlist, i);
1057 } 1075 }
1058 return -1; 1076 return -1;
@@ -1094,7 +1112,7 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1094 return 1; 1112 return 1;
1095 1113
1096 /* check if request is for us. */ 1114 /* check if request is for us. */
1097 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 1115 if (id_equal(packet + 1, self_public_key)) {
1098 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 1116 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
1099 uint8_t data[MAX_DATA_SIZE]; 1117 uint8_t data[MAX_DATA_SIZE];
1100 1118
@@ -1329,7 +1347,7 @@ int DHT_isconnected()
1329 uint64_t temp_time = unix_time(); 1347 uint64_t temp_time = unix_time();
1330 1348
1331 for(i = 0; i < LCLIENT_LIST; ++i) { 1349 for(i = 0; i < LCLIENT_LIST; ++i) {
1332 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) 1350 if(!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT))
1333 return 1; 1351 return 1;
1334 } 1352 }
1335 return 0; 1353 return 0;
diff --git a/core/network.h b/core/network.h
index a5f7899b..a7559ebe 100644
--- a/core/network.h
+++ b/core/network.h
@@ -57,6 +57,7 @@
57#include <sodium.h> 57#include <sodium.h>
58#else 58#else
59#include <crypto_box.h> 59#include <crypto_box.h>
60#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
60#endif 61#endif
61 62
62#ifdef __cplusplus 63#ifdef __cplusplus
diff --git a/testing/nTox.c b/testing/nTox.c
index 312484d6..15e209a9 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23#include "nTox.h" 23#include "nTox.h"
24#include "misc_tools.h" 24#include "misc_tools.h"
@@ -55,7 +55,7 @@ void get_id(char *data)
55 { 55 {
56 if (self_public_key[i] < (PUB_KEY_BYTES / 2)) 56 if (self_public_key[i] < (PUB_KEY_BYTES / 2))
57 strcpy(idstring1[i],"0"); 57 strcpy(idstring1[i],"0");
58 else 58 else
59 strcpy(idstring1[i], ""); 59 strcpy(idstring1[i], "");
60 sprintf(idstring2[i], "%hhX",self_public_key[i]); 60 sprintf(idstring2[i], "%hhX",self_public_key[i]);
61 } 61 }
@@ -72,9 +72,9 @@ void get_id(char *data)
72void new_lines(char *line) 72void new_lines(char *line)
73{ 73{
74 int i = 0; 74 int i = 0;
75 for (i = HISTORY-1; i > 0; i--) 75 for (i = HISTORY-1; i > 0; i--)
76 strncpy(lines[i], lines[i-1], STRING_LENGTH - 1); 76 strncpy(lines[i], lines[i-1], STRING_LENGTH - 1);
77 77
78 strncpy(lines[0], line, STRING_LENGTH - 1); 78 strncpy(lines[0], line, STRING_LENGTH - 1);
79 do_refresh(); 79 do_refresh();
80} 80}
@@ -139,7 +139,7 @@ void line_eval(char *line)
139 if (inpt_command == 'f') { // add friend command: /f ID 139 if (inpt_command == 'f') { // add friend command: /f ID
140 int i; 140 int i;
141 char temp_id[128]; 141 char temp_id[128];
142 for (i = 0; i < 128; i++) 142 for (i = 0; i < 128; i++)
143 temp_id[i] = line[i+prompt_offset]; 143 temp_id[i] = line[i+prompt_offset];
144 144
145 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 145 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
@@ -172,8 +172,8 @@ void line_eval(char *line)
172 } 172 }
173 else if (inpt_command == 'm') { //message command: /m friendnumber messsage 173 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
174 size_t len = strlen(line); 174 size_t len = strlen(line);
175 if(len < 3) 175 if(len < 3)
176 return; 176 return;
177 177
178 char numstring[len-3]; 178 char numstring[len-3];
179 char message[len-3]; 179 char message[len-3];
@@ -253,7 +253,7 @@ void line_eval(char *line)
253 else if (inpt_command == 'q') { //exit 253 else if (inpt_command == 'q') { //exit
254 endwin(); 254 endwin();
255 exit(EXIT_SUCCESS); 255 exit(EXIT_SUCCESS);
256 } else { 256 } else {
257 new_lines("[i] invalid command"); 257 new_lines("[i] invalid command");
258 } 258 }
259 } else { 259 } else {
@@ -340,7 +340,7 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
340 new_lines(format_message((char*)string, friendnumber)); 340 new_lines(format_message((char*)string, friendnumber));
341} 341}
342 342
343void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) 343void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
344{ 344{
345 char name[MAX_NAME_LENGTH]; 345 char name[MAX_NAME_LENGTH];
346 getname(friendnumber, (uint8_t*)name); 346 getname(friendnumber, (uint8_t*)name);
@@ -349,7 +349,7 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
349 new_lines(msg); 349 new_lines(msg);
350} 350}
351 351
352void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) 352void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
353{ 353{
354 char name[MAX_NAME_LENGTH]; 354 char name[MAX_NAME_LENGTH];
355 getname(friendnumber, (uint8_t*)name); 355 getname(friendnumber, (uint8_t*)name);
@@ -453,7 +453,7 @@ int main(int argc, char *argv[])
453 int resolved_address = resolve_addr(argv[1]); 453 int resolved_address = resolve_addr(argv[1]);
454 if (resolved_address != 0) 454 if (resolved_address != 0)
455 bootstrap_ip_port.ip.i = resolved_address; 455 bootstrap_ip_port.ip.i = resolved_address;
456 else 456 else
457 exit(1); 457 exit(1);
458 458
459 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 459 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
@@ -476,7 +476,7 @@ int main(int argc, char *argv[])
476 if (c == '\n') { 476 if (c == '\n') {
477 line_eval(line); 477 line_eval(line);
478 strcpy(line, ""); 478 strcpy(line, "");
479 } else if (c == 127) { 479 } else if (c == 8 || c == 127) {
480 line[strlen(line)-1] = '\0'; 480 line[strlen(line)-1] = '\0';
481 } else if (isalnum(c) || ispunct(c) || c == ' ') { 481 } else if (isalnum(c) || ispunct(c) || c == ' ') {
482 strcpy(line, appender(line, (char) c)); 482 strcpy(line, appender(line, (char) c));
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
index 3b6fb043..5501ecf5 100644
--- a/testing/nTox_win32.c
+++ b/testing/nTox_win32.c
@@ -32,6 +32,7 @@ uint32_t maxnumfriends;
32 32
33char line[STRING_LENGTH]; 33char line[STRING_LENGTH];
34char users_id[200]; 34char users_id[200];
35int friend_request_received;
35 36
36void do_header() 37void do_header()
37{ 38{
@@ -44,10 +45,11 @@ void do_header()
44 45
45void print_request(uint8_t *public_key, uint8_t *data, uint16_t length) 46void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
46{ 47{
48 friend_request_received = 1;
47 printf("\n\n[i] received friend request with message\n"); 49 printf("\n\n[i] received friend request with message\n");
48 printf((char *)data); 50 printf("'%s'",(char *)data);
49 char numchar[100]; 51 char numchar[100];
50 sprintf(numchar, "\n\n[i] accept request with /a %u\n\n", num_requests); 52 sprintf(numchar, "\n[i] accept request with /a %u\n\n", num_requests);
51 printf(numchar); 53 printf(numchar);
52 memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); 54 memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
53 ++num_requests; 55 ++num_requests;
@@ -151,23 +153,32 @@ void add_friend()
151 153
152void list_friends() 154void list_friends()
153{ 155{
154 int activefriends = 0;
155 int i; 156 int i;
157
158 printf("\n[i] Friend List");
159
160 printf("----- PENDING -----\n\n");
156 161
157 for (i = 0; i <= maxnumfriends; i++) { 162 for (i = 0; i <= maxnumfriends; i++) {
158 if (m_friendstatus(i) == 4) 163 char name[MAX_NAME_LENGTH];
159 activefriends++; 164 getname(i, (uint8_t*)name);
165 if (m_friendstatus(i) > 0 && m_friendstatus(i) < 4)
166 printf("[%d] %s\n", i, (uint8_t*)name);
160 } 167 }
168
169 printf("\n");
161 170
162 printf("\n[i] Friend List | Total: %d\n\n", activefriends); 171 printf("----- ACTIVE -----\n\n");
163 172
164 for (i = 0; i <= 256; i++) {/* TODO: fix this properly*/ 173 for (i = 0; i <= maxnumfriends; i++) {
165 char name[MAX_NAME_LENGTH]; 174 char name[MAX_NAME_LENGTH];
166 getname(i, (uint8_t*)name); 175 getname(i, (uint8_t*)name);
167 176
168 if (m_friendstatus(i) == 4) 177 if (m_friendstatus(i) == 4)
169 printf("[%d] %s\n\n", i, (uint8_t*)name); 178 printf("[%d] %s\n", i, (uint8_t*)name);
170 } 179 }
180
181 printf("\n");
171} 182}
172 183
173void delete_friend() 184void delete_friend()
@@ -244,7 +255,7 @@ void change_nickname()
244 fclose(name_file); 255 fclose(name_file);
245} 256}
246 257
247void change_status() 258void change_status(int savetofile)
248{ 259{
249 uint8_t status[MAX_USERSTATUS_LENGTH]; 260 uint8_t status[MAX_USERSTATUS_LENGTH];
250 int i = 0; 261 int i = 0;
@@ -263,20 +274,21 @@ void change_status()
263 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status); 274 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status);
264 printf(numstring); 275 printf(numstring);
265 276
266 FILE* status_file = NULL; 277 if (savetofile == 1) {
267 status_file = fopen("statusfile.txt", "w"); 278 FILE* status_file = NULL;
268 fprintf(status_file, "%s", (char*)status); 279 status_file = fopen("statusfile.txt", "w");
269 fclose(status_file); 280 fprintf(status_file, "%s", (char*)status);
281 fclose(status_file);
282 }
270} 283}
271 284
272void accept_friend_request() 285void accept_friend_request()
273{ 286{
287 friend_request_received = 0;
274 uint8_t numf = atoi(line + 3); 288 uint8_t numf = atoi(line + 3);
275 char numchar[100]; 289 char numchar[100];
276 sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf);
277 printf(numchar);
278 int num = m_addfriend_norequest(pending_requests[numf]); 290 int num = m_addfriend_norequest(pending_requests[numf]);
279 sprintf(numchar, "\n[i] added friendnumber %d\n\n", num); 291 sprintf(numchar, "\n[i] Added friendnumber: %d\n\n", num);
280 printf(numchar); 292 printf(numchar);
281 ++maxnumfriends; 293 ++maxnumfriends;
282} 294}
@@ -288,7 +300,7 @@ void line_eval(char* line)
288 char inpt_command = line[1]; 300 char inpt_command = line[1];
289 301
290 if(inpt_command == 'f') { 302 if(inpt_command == 'f') {
291 add_friend(line); 303 add_friend();
292 } 304 }
293 305
294 else if (inpt_command == 'r') { 306 else if (inpt_command == 'r') {
@@ -297,32 +309,33 @@ void line_eval(char* line)
297 } 309 }
298 310
299 else if (inpt_command == 'l') { 311 else if (inpt_command == 'l') {
300 list_friends(line); 312 list_friends();
301 } 313 }
302 314
303 else if (inpt_command == 'd') { 315 else if (inpt_command == 'd') {
304 delete_friend(line); 316 delete_friend();
305 } 317 }
306 /* Send message to friend */ 318 /* Send message to friend */
307 else if (inpt_command == 'm') { 319 else if (inpt_command == 'm') {
308 message_friend(line); 320 message_friend();
309 } 321 }
310 322
311 else if (inpt_command == 'n') { 323 else if (inpt_command == 'n') {
312 change_nickname(line); 324 change_nickname();
313 } 325 }
314 326
315 else if (inpt_command == 's') { 327 else if (inpt_command == 's') {
316 change_status(line); 328 change_status(1);
317 } 329 }
318 330
319 else if (inpt_command == 'a') { 331 else if (inpt_command == 'a') {
320 accept_friend_request(line); 332 if (friend_request_received == 1)
333 accept_friend_request(line);
321 } 334 }
322 /* EXIT */ 335 /* EXIT */
323 else if (inpt_command == 'q') { 336 else if (inpt_command == 'q') {
324 uint8_t status[MAX_USERSTATUS_LENGTH] = "Offline"; 337 strcpy(line, "---Offline");
325 m_set_userstatus(status, strlen((char*)status)); 338 change_status(0);
326 exit(EXIT_SUCCESS); 339 exit(EXIT_SUCCESS);
327 } 340 }
328 } 341 }
@@ -368,8 +381,7 @@ int main(int argc, char *argv[])
368 nameloaded = 1; 381 nameloaded = 1;
369 printf("%s\n", name); 382 printf("%s\n", name);
370 fclose(name_file); 383 fclose(name_file);
371 } 384 }
372
373 385
374 FILE* status_file = NULL; 386 FILE* status_file = NULL;
375 status_file = fopen("statusfile.txt", "r"); 387 status_file = fopen("statusfile.txt", "r");
@@ -383,7 +395,6 @@ int main(int argc, char *argv[])
383 printf("%s\n", status); 395 printf("%s\n", status);
384 fclose(status_file); 396 fclose(status_file);
385 } 397 }
386
387 398
388 m_callback_friendrequest(print_request); 399 m_callback_friendrequest(print_request);
389 m_callback_friendmessage(print_message); 400 m_callback_friendmessage(print_message);
diff --git a/testing/nTox_win32.h b/testing/nTox_win32.h
index 211ac95f..271403b8 100644
--- a/testing/nTox_win32.h
+++ b/testing/nTox_win32.h
@@ -39,7 +39,7 @@ void list_friends();
39void delete_friend(); 39void delete_friend();
40void message_friend(); 40void message_friend();
41void change_nickname(); 41void change_nickname();
42void change_status(); 42void change_status(int savetofile);
43void accept_friend_request(); 43void accept_friend_request();
44void line_eval(char* line); 44void line_eval(char* line);
45void get_input(); 45void get_input();
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index 854d3817..7cae1c0a 100644
--- a/testing/toxic/chat.c
+++ b/testing/toxic/chat.c
@@ -7,6 +7,7 @@
7#include <string.h> 7#include <string.h>
8#include <stdint.h> 8#include <stdint.h>
9#include <ctype.h> 9#include <ctype.h>
10#include <time.h>
10 11
11#include "../../core/Messenger.h" 12#include "../../core/Messenger.h"
12#include "../../core/network.h" 13#include "../../core/network.h"
@@ -26,11 +27,15 @@ typedef struct {
26 27
27extern void fix_name(uint8_t* name); 28extern void fix_name(uint8_t* name);
28 29
29
30static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) { 30static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) {
31 ChatContext* ctx = (ChatContext*) self->x; 31 ChatContext* ctx = (ChatContext*) self->x;
32 uint8_t nick[MAX_NAME_LENGTH] = {0}; 32 uint8_t nick[MAX_NAME_LENGTH] = {0};
33 33
34 time_t now;
35 time(&now);
36 struct tm * timeinfo;
37 timeinfo = localtime(&now);
38
34 if(ctx->friendnum != num) 39 if(ctx->friendnum != num)
35 return; 40 return;
36 41
@@ -42,10 +47,11 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len)
42 fix_name(msg); 47 fix_name(msg);
43 fix_name(nick); 48 fix_name(nick);
44 49
50 wattron(ctx->history, COLOR_PAIR(2));
51 wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
45 wattron(ctx->history, COLOR_PAIR(4)); 52 wattron(ctx->history, COLOR_PAIR(4));
46 wprintw(ctx->history, "%s: ", nick); 53 wprintw(ctx->history, "%s: ", nick);
47 wattroff(ctx->history, COLOR_PAIR(4)); 54 wattroff(ctx->history, COLOR_PAIR(4));
48
49 wprintw(ctx->history, "%s\n", msg); 55 wprintw(ctx->history, "%s\n", msg);
50 56
51 self->blink = true; 57 self->blink = true;
@@ -74,6 +80,11 @@ static void chat_onStatusChange(ToxWindow* self, int num, uint8_t* status, uint1
74static void chat_onKey(ToxWindow* self, int key) { 80static void chat_onKey(ToxWindow* self, int key) {
75 ChatContext* ctx = (ChatContext*) self->x; 81 ChatContext* ctx = (ChatContext*) self->x;
76 82
83 time_t now;
84 time(&now);
85 struct tm * timeinfo;
86 timeinfo = localtime(&now);
87
77 if(isprint(key)) { 88 if(isprint(key)) {
78 89
79 if(ctx->pos != sizeof(ctx->line)-1) { 90 if(ctx->pos != sizeof(ctx->line)-1) {
@@ -82,10 +93,11 @@ static void chat_onKey(ToxWindow* self, int key) {
82 } 93 }
83 } 94 }
84 else if(key == '\n') { 95 else if(key == '\n') {
96 wattron(ctx->history, COLOR_PAIR(2));
97 wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
85 wattron(ctx->history, COLOR_PAIR(1)); 98 wattron(ctx->history, COLOR_PAIR(1));
86 wprintw(ctx->history, "you: ", ctx->line); 99 wprintw(ctx->history, "you: ", ctx->line);
87 wattroff(ctx->history, COLOR_PAIR(1)); 100 wattroff(ctx->history, COLOR_PAIR(1));
88
89 wprintw(ctx->history, "%s\n", ctx->line); 101 wprintw(ctx->history, "%s\n", ctx->line);
90 102
91 if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) { 103 if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) {
@@ -102,10 +114,11 @@ static void chat_onKey(ToxWindow* self, int key) {
102 ctx->line[--ctx->pos] = '\0'; 114 ctx->line[--ctx->pos] = '\0';
103 } 115 }
104 } 116 }
105 117
106} 118}
107 119
108static void chat_onDraw(ToxWindow* self) { 120static void chat_onDraw(ToxWindow* self) {
121 curs_set(1);
109 int x, y; 122 int x, y;
110 ChatContext* ctx = (ChatContext*) self->x; 123 ChatContext* ctx = (ChatContext*) self->x;
111 124
@@ -117,7 +130,7 @@ static void chat_onDraw(ToxWindow* self) {
117 130
118 wclear(ctx->linewin); 131 wclear(ctx->linewin);
119 mvwhline(ctx->linewin, 0, 0, '_', COLS); 132 mvwhline(ctx->linewin, 0, 0, '_', COLS);
120 mvwprintw(ctx->linewin, 1, 0, "%s\n", ctx->line); 133 mvwprintw(self->window, y-1, 0, "%s\n", ctx->line);
121 134
122 wrefresh(self->window); 135 wrefresh(self->window);
123} 136}
@@ -149,7 +162,7 @@ ToxWindow new_chat(int friendnum) {
149 uint8_t nick[MAX_NAME_LENGTH] = {0}; 162 uint8_t nick[MAX_NAME_LENGTH] = {0};
150 getname(friendnum, (uint8_t*) &nick); 163 getname(friendnum, (uint8_t*) &nick);
151 fix_name(nick); 164 fix_name(nick);
152 165
153 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); 166 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
154 167
155 ChatContext* x = calloc(1, sizeof(ChatContext)); 168 ChatContext* x = calloc(1, sizeof(ChatContext));
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
index f9a413f9..b4b619a2 100644
--- a/testing/toxic/friendlist.c
+++ b/testing/toxic/friendlist.c
@@ -113,6 +113,7 @@ static void friendlist_onKey(ToxWindow* self, int key) {
113} 113}
114 114
115static void friendlist_onDraw(ToxWindow* self) { 115static void friendlist_onDraw(ToxWindow* self) {
116 curs_set(0);
116 size_t i; 117 size_t i;
117 118
118 wclear(self->window); 119 wclear(self->window);
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index c596b708..3b45a89f 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -50,7 +50,7 @@ void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) {
50void on_message(int friendnumber, uint8_t* string, uint16_t length) { 50void on_message(int friendnumber, uint8_t* string, uint16_t length) {
51 size_t i; 51 size_t i;
52 52
53 wprintw(prompt->window, "\n(message) %d: %s!\n", friendnumber, string); 53 wprintw(prompt->window, "\n(message) %d: %s\n", friendnumber, string);
54 54
55 for(i=0; i<w_num; i++) { 55 for(i=0; i<w_num; i++) {
56 if(windows[i].onMessage != NULL) 56 if(windows[i].onMessage != NULL)
@@ -170,12 +170,12 @@ static void do_tox() {
170 doMessenger(); 170 doMessenger();
171} 171}
172 172
173static void load_data() { 173static void load_data(char *path) {
174 FILE* fd; 174 FILE* fd;
175 size_t len; 175 size_t len;
176 uint8_t* buf; 176 uint8_t* buf;
177 177
178 if((fd = fopen("data", "r")) != NULL) { 178 if((fd = fopen(path, "r")) != NULL) {
179 fseek(fd, 0, SEEK_END); 179 fseek(fd, 0, SEEK_END);
180 len = ftell(fd); 180 len = ftell(fd);
181 fseek(fd, 0, SEEK_SET); 181 fseek(fd, 0, SEEK_SET);
@@ -213,7 +213,7 @@ static void load_data() {
213 213
214 Messenger_save(buf); 214 Messenger_save(buf);
215 215
216 fd = fopen("data", "w"); 216 fd = fopen(path, "w");
217 if(fd == NULL) { 217 if(fd == NULL) {
218 fprintf(stderr, "fopen() failed.\n"); 218 fprintf(stderr, "fopen() failed.\n");
219 219
@@ -280,35 +280,38 @@ void prepare_window(WINDOW* w) {
280 wresize(w, LINES-2, COLS); 280 wresize(w, LINES-2, COLS);
281} 281}
282 282
283/*
284 * Draws cursor relative to input on prompt window.
285 * Removes cursor on friends window and chat windows.
286 *
287 * TODO: Make it work for chat windows
288 */
289void position_cursor(WINDOW* w, char* title)
290{
291 curs_set(1);
292 if (strcmp(title, "[prompt]") == 0) { // main/prompt window
293 int x, y;
294 getyx(w, y, x);
295 move(y, x);
296 }
297 else if (strcmp(title, "[friends]") == 0) // friends window
298 curs_set(0);
299 else // any other window (i.e chat)
300 curs_set(0);
301}
302
303int main(int argc, char* argv[]) { 283int main(int argc, char* argv[]) {
304 int ch; 284 int ch;
285 int i = 0;
286 int f_flag = 0;
287 char *filename = "data";
305 ToxWindow* a; 288 ToxWindow* a;
306 289
290 for(i = 0; i < argc; i++) {
291 if(argv[i][0] == '-') {
292 if(argv[i][1] == 'f') {
293 if(argv[i + 1] != NULL)
294 filename = argv[i + 1];
295 else {
296 f_flag = -1;
297 }
298 }
299 }
300 }
301
307 init_term(); 302 init_term();
308 init_tox(); 303 init_tox();
309 load_data(); 304 load_data(filename);
310 init_windows(); 305 init_windows();
311 306
307 if(f_flag == -1) {
308 attron(COLOR_PAIR(3) | A_BOLD);
309 wprintw(prompt->window, "You passed '-f' without giving an argument!\n"
310 "defaulting to 'data' for a keyfile...\n");
311 attroff(COLOR_PAIR(3) | A_BOLD);
312 }
313
314
312 while(true) { 315 while(true) {
313 // Update tox. 316 // Update tox.
314 do_tox(); 317 do_tox();
@@ -317,9 +320,8 @@ int main(int argc, char* argv[]) {
317 a = &windows[w_active]; 320 a = &windows[w_active];
318 prepare_window(a->window); 321 prepare_window(a->window);
319 a->blink = false; 322 a->blink = false;
320 a->onDraw(a);
321 draw_bar(); 323 draw_bar();
322 position_cursor(a->window, a->title); 324 a->onDraw(a);
323 325
324 // Handle input. 326 // Handle input.
325 ch = getch(); 327 ch = getch();
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index b0f83811..1db60883 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -140,6 +140,7 @@ static void execute(ToxWindow* self, char* cmd) {
140 break; 140 break;
141 case -2: 141 case -2:
142 wprintw(self->window, "Please add a message to your request.\n"); 142 wprintw(self->window, "Please add a message to your request.\n");
143 break;
143 case -3: 144 case -3:
144 wprintw(self->window, "That appears to be your own ID.\n"); 145 wprintw(self->window, "That appears to be your own ID.\n");
145 break; 146 break;
@@ -287,6 +288,7 @@ static void prompt_onKey(ToxWindow* self, int key) {
287} 288}
288 289
289static void prompt_onDraw(ToxWindow* self) { 290static void prompt_onDraw(ToxWindow* self) {
291 curs_set(1);
290 int x, y; 292 int x, y;
291 293
292 getyx(self->window, y, x); 294 getyx(self->window, y, x);