summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--.travis.yml13
-rw-r--r--INSTALL.md12
-rw-r--r--README.md9
-rw-r--r--core/Lossless_UDP.c6
-rw-r--r--core/Messenger.c31
-rw-r--r--core/Messenger.h18
-rw-r--r--docs/commands.md25
-rw-r--r--docs/using_tox.md38
-rw-r--r--other/bootstrap_serverdaemon/CMakeLists.txt3
-rw-r--r--other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c11
-rw-r--r--other/bootstrap_serverdaemon/cmake/Modules/FindLibConfig.cmake73
-rw-r--r--other/bootstrap_serverdaemon/server.cfg4
-rw-r--r--start_guide.de.md40
-rw-r--r--start_guide.md38
-rw-r--r--testing/DHT_cryptosendfiletest.c4
-rw-r--r--testing/nTox.c57
-rw-r--r--testing/nTox_win32.c1
-rw-r--r--testing/toxic/CMakeLists.txt3
-rw-r--r--testing/toxic/friendlist.c125
-rw-r--r--testing/toxic/main.c49
-rw-r--r--testing/toxic/prompt.c109
22 files changed, 595 insertions, 82 deletions
diff --git a/.gitignore b/.gitignore
index 010561a2..9969b38d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,11 @@ install_manifest.txt
12 12
13testing/data 13testing/data
14*~ 14*~
15
16# Object files
17*.o
18
19# Executables
20*.exe
21*.out
22*.app
diff --git a/.travis.yml b/.travis.yml
index 9de4e282..8e71c327 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,12 +11,17 @@ before_script:
11 - ./autogen.sh 11 - ./autogen.sh
12 - ./configure && make check -j3 12 - ./configure && make check -j3
13 - sudo make install 13 - sudo make install
14 - sudo ldconfig
15 - cd .. 14 - cd ..
16# installing libconfig, needed for DHT_bootstrap_daemon 15# installing libconfig, needed for DHT_bootstrap_daemon
17 - sudo sed -i 's/precise/quantal/' /etc/apt/sources.list # needed for libconfig-dev 16 - wget http://www.hyperrealm.com/libconfig/libconfig-1.4.9.tar.gz
18 - sudo apt-get update -qq 17 - tar -xvzf libconfig-1.4.9.tar.gz
19 - yes | sudo apt-get install libconfig-dev 18 - cd libconfig-1.4.9
19 - ./configure && make -j3
20 - sudo make install
21 - cd ..
22# creating librarys' links and updating cache
23 - sudo ldconfig
24
20 25
21script: 26script:
22 - mkdir build && cd build 27 - mkdir build && cd build
diff --git a/INSTALL.md b/INSTALL.md
index 3459a5c7..9efa7ee9 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -42,7 +42,17 @@ make
42 42
43###OSX: 43###OSX:
44 44
45Much the same as above, remember to install the latest XCode and the developer tools (Preferences -> Downloads -> Command Line Tools). 45####Homebrew:
46```
47brew install libtool automake autoconf libconfig libsodium
48cmake .
49make
50sudo make install
51```
52
53####Non-homebrew:
54
55Much the same as Linux, remember to install the latest XCode and the developer tools (Preferences -> Downloads -> Command Line Tools).
46Users running Mountain Lion and the latest version of XCode (4.6.3) will also need to install libtool, automake and autoconf. 56Users running Mountain Lion and the latest version of XCode (4.6.3) will also need to install libtool, automake and autoconf.
47They are easy enough to install, grab them from http://www.gnu.org/software/libtool/, http://www.gnu.org/software/autoconf/ and http://www.gnu.org/software/automake/, then follow these steps for each: 57They are easy enough to install, grab them from http://www.gnu.org/software/libtool/, http://www.gnu.org/software/autoconf/ and http://www.gnu.org/software/automake/, then follow these steps for each:
48 58
diff --git a/README.md b/README.md
index 8f903bc0..19bbb759 100644
--- a/README.md
+++ b/README.md
@@ -6,27 +6,28 @@ With the rise of governmental monitoring programs, Tox aims to be an easy to use
6 6
7 7
8 8
9**IRC**: #tox on Freenode, alternatively, you can use the [webchat](http://webchat.freenode.net/?channels=#tox).<br /> 9**IRC**: #tox on freenode, alternatively, you can use the [webchat](http://webchat.freenode.net/?channels=#tox).<br />
10**Website**: [http://tox.im](http://tox.im) 10**Website**: [http://tox.im](http://tox.im)
11 11
12**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/>
13**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)
14 14
15 15**How to build Tox on Linux**: [YouTube video](http://www.youtube.com/watch?v=M4WXE4VKmyg)<br />
16**How to use Tox on Windows**: [YouTube video](http://www.youtube.com/watch?v=qg_j_sDb6WQ)
16 17
17## The Complex Stuff: 18## The Complex Stuff:
18+ Tox must use UDP simply because you can't hole punch with TCP. It's possible, but it doesn't work all the time. 19+ Tox must use UDP simply because you can't hole punch with TCP. It's possible, but it doesn't work all the time.
19+ Every peer is represented as a byte string (the public key of the peer [client id]) 20+ Every peer is represented as a byte string (the public key of the peer [client id])
20+ We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID. 21+ We're using torrent-style DHT so that peers can find the IP of the other peers when they have their ID.
21+ 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)) 22+ 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))
22+ When both peers are securely connect with the encryption, they can securely exchange messages, initiate a video chat, send files, etc.<br /> 23+ When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications.<br />
23+ Current build status: [![Build Status](https://travis-ci.org/irungentoo/ProjectTox-Core.png?branch=master)](https://travis-ci.org/irungentoo/ProjectTox-Core) 24+ Current build status: [![Build Status](https://travis-ci.org/irungentoo/ProjectTox-Core.png?branch=master)](https://travis-ci.org/irungentoo/ProjectTox-Core)
24 25
25## Roadmap: 26## Roadmap:
26- [x] Get our DHT working perfectly.(Done, needs large scale testing though.) 27- [x] Get our DHT working perfectly.(Done, needs large scale testing though.)
27- [x] Reliable connection (See Lossless_UDP protocol) to other peers according to client id. (Done, see DHT_sendfiletest.c for an example) 28- [x] Reliable connection (See Lossless_UDP protocol) to other peers according to client id. (Done, see DHT_sendfiletest.c for an example)
28- [x] Encryption. (Done) 29- [x] Encryption. (Done)
29- [ ] Get a simple text only im client working perfectly. (This is where we are) 30- [ ] Get a simple text only IM client working perfectly. (This is where we are)
30- [ ] Streaming media 31- [ ] Streaming media
31- [ ] ??? 32- [ ] ???
32 33
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index eb1314d1..6be8328f 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -308,12 +308,16 @@ IP_Port connection_ip(int connection_id)
308/* returns the number of packets in the queue waiting to be successfully sent. */ 308/* returns the number of packets in the queue waiting to be successfully sent. */
309uint32_t sendqueue(int connection_id) 309uint32_t sendqueue(int connection_id)
310{ 310{
311 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
312 return 0;
311 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; 313 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent;
312} 314}
313 315
314/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 316/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
315uint32_t recvqueue(int connection_id) 317uint32_t recvqueue(int connection_id)
316{ 318{
319 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
320 return 0;
317 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; 321 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read;
318} 322}
319 323
@@ -321,6 +325,8 @@ uint32_t recvqueue(int connection_id)
321 return -1 if no packet in queue */ 325 return -1 if no packet in queue */
322char id_packet(int connection_id) 326char id_packet(int connection_id)
323{ 327{
328 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
329 return -1;
324 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) 330 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0)
325 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; 331 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
326 return -1; 332 return -1;
diff --git a/core/Messenger.c b/core/Messenger.c
index 4c76dd30..872d7407 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -99,18 +99,21 @@ int getclient_id(int friend_id, uint8_t *client_id)
99 client_id is the client id of the friend 99 client_id is the client id of the friend
100 data is the data and length is the length 100 data is the data and length is the length
101 returns the friend number if success 101 returns the friend number if success
102 return -1 if failure. */ 102 return -1 if key length is wrong.
103 return -2 if user's own key
104 return -3 if already a friend
105 return -4 for other*/
103int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) 106int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
104{ 107{
105 if (length == 0 || length >= 108 if (length == 0 || length >=
106 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) 109 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
107 return -1; 110 return -1;
108 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 111 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
109 return -1; 112 return -2;
110 if (getfriend_id(client_id) != -1) 113 if (getfriend_id(client_id) != -1)
111 return -1; 114 return -3;
112 uint32_t i; 115 uint32_t i;
113 for (i = 0; i <= numfriends; ++i) { 116 for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/
114 if(friendlist[i].status == 0) { 117 if(friendlist[i].status == 0) {
115 DHT_addfriend(client_id); 118 DHT_addfriend(client_id);
116 friendlist[i].status = 1; 119 friendlist[i].status = 1;
@@ -126,7 +129,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
126 return i; 129 return i;
127 } 130 }
128 } 131 }
129 return -1; 132 return -4;
130} 133}
131 134
132int m_addfriend_norequest(uint8_t * client_id) 135int m_addfriend_norequest(uint8_t * client_id)
@@ -134,7 +137,7 @@ int m_addfriend_norequest(uint8_t * client_id)
134 if (getfriend_id(client_id) != -1) 137 if (getfriend_id(client_id) != -1)
135 return -1; 138 return -1;
136 uint32_t i; 139 uint32_t i;
137 for (i = 0; i <= numfriends; ++i) { 140 for (i = 0; i <= numfriends; ++i) {/*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/
138 if(friendlist[i].status == 0) { 141 if(friendlist[i].status == 0) {
139 DHT_addfriend(client_id); 142 DHT_addfriend(client_id);
140 friendlist[i].status = 2; 143 friendlist[i].status = 2;
@@ -164,7 +167,7 @@ int m_delfriend(int friendnumber)
164 memset(&friendlist[friendnumber], 0, sizeof(Friend)); 167 memset(&friendlist[friendnumber], 0, sizeof(Friend));
165 uint32_t i; 168 uint32_t i;
166 for (i = numfriends; i != 0; --i) { 169 for (i = numfriends; i != 0; --i) {
167 if (friendlist[i].status != 0) 170 if (friendlist[i-1].status != 0)
168 break; 171 break;
169 } 172 }
170 numfriends = i; 173 numfriends = i;
@@ -178,7 +181,7 @@ int m_delfriend(int friendnumber)
178 return 0 if there is no friend with that number */ 181 return 0 if there is no friend with that number */
179int m_friendstatus(int friendnumber) 182int m_friendstatus(int friendnumber)
180{ 183{
181 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 184 if (friendnumber < 0 || friendnumber >= numfriends)
182 return 0; 185 return 0;
183 return friendlist[friendnumber].status; 186 return friendlist[friendnumber].status;
184} 187}
@@ -188,7 +191,7 @@ int m_friendstatus(int friendnumber)
188 return 0 if it was not */ 191 return 0 if it was not */
189int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) 192int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
190{ 193{
191 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 194 if (friendnumber < 0 || friendnumber >= numfriends)
192 return 0; 195 return 0;
193 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) 196 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
194 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 197 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
@@ -240,6 +243,16 @@ int setname(uint8_t * name, uint16_t length)
240 return 0; 243 return 0;
241} 244}
242 245
246/* get our nickname
247 put it in name
248 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
249 return the length of the name */
250uint16_t getself_name(uint8_t *name)
251{
252 memcpy(name, self_name, self_name_length);
253 return self_name_length;
254}
255
243/* get name of friendnumber 256/* get name of friendnumber
244 put it in name 257 put it in name
245 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 258 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
diff --git a/core/Messenger.h b/core/Messenger.h
index 7263901c..9ce96fb4 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -46,11 +46,14 @@ extern "C" {
46 to an absurdly large number later */ 46 to an absurdly large number later */
47 47
48/* add a friend 48/* add a friend
49 set the data that will be sent along with friend request 49 set the data that will be sent along with friend request
50 client_id is the client id of the friend 50 client_id is the client id of the friend
51 data is the data and length is the length 51 data is the data and length is the length
52 returns the friend number if success 52 returns the friend number if success
53 return -1 if failure. */ 53 return -1 if key length is wrong.
54 return -2 if user's own key
55 return -3 if already a friend
56 return -4 for other*/
54int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); 57int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
55 58
56 59
@@ -92,6 +95,11 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
92 return -1 if failure */ 95 return -1 if failure */
93int setname(uint8_t *name, uint16_t length); 96int setname(uint8_t *name, uint16_t length);
94 97
98/* get our nickname
99 put it in name
100 return the length of the name*/
101uint16_t getself_name(uint8_t *name);
102
95/* get name of friendnumber 103/* get name of friendnumber
96 put it in name 104 put it in name
97 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 105 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
diff --git a/docs/commands.md b/docs/commands.md
new file mode 100644
index 00000000..8669bb9b
--- /dev/null
+++ b/docs/commands.md
@@ -0,0 +1,25 @@
1# Tox User Commands
2Here's a list of commands that nTox accepts,
3which can all be used by starting your line with
4a */*. Currently there can be no spaces before this.
5
6* */f* [ID]
7 + Add a friend with ID [ID].
8* */d*
9 + Call doMessenger() which does...something?
10* */m* \[FRIEND\_NUM\] \[MESSAGE\]
11 + Message \[FRIEND\_NUM\] \[MESSAGE\].
12* */n* \[NAME\]
13 + Change your username to \[NAME\].
14* */l*
15 + Print your list of friends. (like you have any)
16* */s* \[STATUS\]
17 + Set your status to \[STATUS\].
18* */a* \[ID\]
19 + Accept friend request from \[ID\].
20* */i*
21 + Print useful info about your client.
22* */h*
23 + Print some help.
24* */q/*
25 + Quit Tox. (why ;_;)
diff --git a/docs/using_tox.md b/docs/using_tox.md
new file mode 100644
index 00000000..b4f4310d
--- /dev/null
+++ b/docs/using_tox.md
@@ -0,0 +1,38 @@
1# Using Tox
21. Build Tox
32. Fix errors
43. Consult IRC for help
54. Go on debugging journy for devs
65. Build Tox for real
76. ???
8
9For all the work we've put into Tox so far,
10there isn't yet a decent guide for how you _use_
11Tox. Here's a user-friendly attempt at it.
12
131. Connect to the network!
14 + You need to connect to a bootstrapping server, to give you a public key.
15 + Where can I find a public server? Right here, as of now:
16 (the help message from running nTox with no args will help)
17 + 198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
18 + 192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
19 + 66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
20 + 192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
212. Find a friend!
22 + Now that you're on the network, you need a friend. To get one of those,
23 you need to to send or receive a request. What's a request, you ask?
24 It's like a friend request, but we use really scary and cryptic numbers
25 instead of names. When nTox starts, it shows your _your_ long, scary number,
26 called your *public key*. Give that to people, and they can add you as
27 as "friend". Or, you can add someone else, with the */f* command, if you like.
283. Chat it up!
29 + Now use the */m* command to send a message to someone. Wow, you're chatting!
304. But something broke!
31 + Yeah, pre-alpha-alpha software tends to do that. We're working on it.
32 + Please report all crashes to either the github page, or #tox-dev on freenode.
335. Nothing broke, but what does */f* mean?
34 + nTox parses text as a command if the first character is a forward-slash ('/').
35 You can check all commands in commands.md.
366. Use and support Tox!
37 + Code for us, debug for us, document for us, translate for us, even just talk about us!
38 + The more interest we get, the more work gets done, the better Tox is.
diff --git a/other/bootstrap_serverdaemon/CMakeLists.txt b/other/bootstrap_serverdaemon/CMakeLists.txt
index a9cfdff7..512179f3 100644
--- a/other/bootstrap_serverdaemon/CMakeLists.txt
+++ b/other/bootstrap_serverdaemon/CMakeLists.txt
@@ -14,3 +14,6 @@ target_link_libraries(${exe_name}
14 ${LIBCONFIG_LIBRARY}) 14 ${LIBCONFIG_LIBRARY})
15 15
16linkCoreLibraries(${exe_name}) 16linkCoreLibraries(${exe_name})
17
18set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
19find_package(LibConfig REQUIRED)
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
index 8e278b28..4f28fb3c 100644
--- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
+++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
@@ -123,11 +123,12 @@ void manage_keys(char *keys_file)
123{ 123{
124 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 124 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
125 uint8_t keys[KEYS_SIZE]; 125 uint8_t keys[KEYS_SIZE];
126 126 struct stat existence;
127 /* TODO: stat the file before trying to open it. We aren't cave people! */ 127 FILE *keysf;
128 FILE *keysf = fopen(keys_file, "r"); 128
129 if (keysf != NULL) { 129 /* Check if file exits, proceed to open and load keys */
130 /* if file was opened successfully -- load keys */ 130 if(stat(keys_file,&existence) >= 0) {
131 keysf = fopen(keys_file, "r");
131 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keysf); 132 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keysf);
132 if (read_size != KEYS_SIZE) { 133 if (read_size != KEYS_SIZE) {
133 printf("Error while reading the key file\nExiting.\n"); 134 printf("Error while reading the key file\nExiting.\n");
diff --git a/other/bootstrap_serverdaemon/cmake/Modules/FindLibConfig.cmake b/other/bootstrap_serverdaemon/cmake/Modules/FindLibConfig.cmake
new file mode 100644
index 00000000..7d6270e6
--- /dev/null
+++ b/other/bootstrap_serverdaemon/cmake/Modules/FindLibConfig.cmake
@@ -0,0 +1,73 @@
1#Ref: https://github.com/schnorr/pajeng/blob/master/cmake/FindLibConfig.cmake
2#
3# This module defines
4# LIBCONFIG_INCLUDE_DIR, where to find cppunit include files, etc.
5# LIBCONFIG_LIBRARIES, the libraries to link against to use CppUnit.
6# LIBCONFIG_STATIC_LIBRARIY_PATH
7# LIBCONFIG_FOUND, If false, do not try to use CppUnit.
8
9# also defined, but not for general use are
10# LIBCONFIG_LIBRARY, where to find the CUnit library.
11
12#MESSAGE("Searching for libconfig library")
13
14FIND_PATH(LIBCONFIG_INCLUDE_DIR libconfig.h
15 /usr/local/include
16 /usr/include
17)
18
19FIND_PATH(LIBCONFIGPP_INCLUDE_DIR libconfig.h++
20 /usr/local/include
21 /usr/include
22)
23
24FIND_LIBRARY(LIBCONFIG_LIBRARY config
25 /usr/local/lib
26 /usr/lib
27)
28
29FIND_LIBRARY(LIBCONFIGPP_LIBRARY config++
30 /usr/local/lib
31 /usr/lib
32)
33
34FIND_LIBRARY(LIBCONFIG_STATIC_LIBRARY "libconfig${CMAKE_STATIC_LIBRARY_SUFFIX}"
35 /usr/local/lib
36 /usr/lib
37)
38
39FIND_LIBRARY(LIBCONFIGPP_STATIC_LIBRARY "libconfig++${CMAKE_STATIC_LIBRARY_SUFFIX}"
40 /usr/local/lib
41 /usr/lib
42)
43
44
45IF(LIBCONFIG_INCLUDE_DIR)
46 IF(LIBCONFIG_LIBRARY)
47 SET(LIBCONFIG_FOUND TRUE)
48 SET(LIBCONFIG_LIBRARIES ${LIBCONFIG_LIBRARY})
49 SET(LIBCONFIG_STATIC_LIBRARY_PATH ${LIBCONFIG_STATIC_LIBRARY})
50 ENDIF(LIBCONFIG_LIBRARY)
51ENDIF(LIBCONFIG_INCLUDE_DIR)
52
53IF(LIBCONFIGPP_INCLUDE_DIR)
54 IF(LIBCONFIGPP_LIBRARY)
55 SET(LIBCONFIGPP_FOUND TRUE)
56 SET(LIBCONFIGPP_LIBRARIES ${LIBCONFIGPP_LIBRARY})
57 SET(LIBCONFIGPP_STATIC_LIBRARY_PATH ${LIBCONFIGPP_STATIC_LIBRARY})
58 ENDIF(LIBCONFIGPP_LIBRARY)
59ENDIF(LIBCONFIGPP_INCLUDE_DIR)
60
61IF (LIBCONFIG_FOUND)
62 IF (NOT LibConfig_FIND_QUIETLY)
63 MESSAGE(STATUS "Found LibConfig++: ${LIBCONFIGPP_LIBRARIES}" )
64 MESSAGE(STATUS "Found LibConfig: ${LIBCONFIG_LIBRARIES}")
65 MESSAGE(STATUS "static LibConfig path: ${LIBCONFIG_STATIC_LIBRARY_PATH}")
66 ENDIF (NOT LibConfig_FIND_QUIETLY)
67ELSE (LIBCONFIG_FOUND)
68 IF (LibConfig_FIND_REQUIRED)
69 MESSAGE(SEND_ERROR "Could NOT find LibConfig")
70 ENDIF (LibConfig_FIND_REQUIRED)
71ENDIF (LIBCONFIG_FOUND)
72
73MARK_AS_ADVANCED(LIBCONFIG_INCLUDE_DIR LIBCONFIG_LIBRARIES)
diff --git a/other/bootstrap_serverdaemon/server.cfg b/other/bootstrap_serverdaemon/server.cfg
index 8ef516ca..527c2a72 100644
--- a/other/bootstrap_serverdaemon/server.cfg
+++ b/other/bootstrap_serverdaemon/server.cfg
@@ -6,11 +6,15 @@ port = 33445;
6// The key file 6// The key file
7// make sure that the user who runs the server 7// make sure that the user who runs the server
8// does have permissions to read it/write to it 8// does have permissions to read it/write to it
9// Remember to replace the provided example with
10// the directory the DHT server will run in.
9keys_file = "/home/tom/.bootstrap_server.keys" 11keys_file = "/home/tom/.bootstrap_server.keys"
10 12
11// The PID file written to by bootstrap_server, 13// The PID file written to by bootstrap_server,
12// make sure that the user who runs the server 14// make sure that the user who runs the server
13// does have permissions to write to it 15// does have permissions to write to it
16// Remember to replace the provided example with
17// the directory the DHT server will run in.
14pid_file = "/home/tom/.bootstrap_server.pid"; 18pid_file = "/home/tom/.bootstrap_server.pid";
15 19
16// The info of the node bootstap_server will 20// The info of the node bootstap_server will
diff --git a/start_guide.de.md b/start_guide.de.md
new file mode 100644
index 00000000..7dfd52ca
--- /dev/null
+++ b/start_guide.de.md
@@ -0,0 +1,40 @@
1# Tox nutzen
21. Tox erstellen
32. Fehler korrigieren
43. Im IRC nach Hilfe fragen
54. Auf Debug-Reise für Entwickler
65. Tox wirklich erstellen
76. ???
8
9Trotz der ganzen Arbeit, die wir bisher in Tox
10gesteckt haben, gibt es noch keine richtige
11Anleitung, wie man Tox _benutzt_.
12Dies ist ein anwenderfreundlicher Versuch.
13
141. Verbinde dich zum Netzwerk!
15 + Du musst dich zu einem Bootstrap-Server verbinden, um einen öffentlichen Schlüssel zu erhalten.
16 + Wo finde ich einen öffentlichen Server? Zur Zeit hier:
17 (die Hilfe-Nachricht von nTox ohne Kommandos hilft auch)
18 + 198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
19 + 192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
20 + 66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
21 + 192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
222. Finde einen Freund!
23 + Jetzt, da du im Netzwerk bist, brauchst du einen Freund. Um einen zu bekommen,
24 musst du eine Anfrage senden oder erhalten. Was eine Anfrage ist?
25 Es ist wie eine Freundschaftsanfrage, jedoch benutzen wir unglaublich schaurige
26 und kryptische Nummern anstatt Namen. When nTox startet, erscheint _deine_ lange,
27 schaurige Nummer, auch *öffentlicher Schlüssel* genannt. Diesen kannst du an
28 andere Personen weitergeben und sie können dich als "Freund" hinzufügen. Oder du
29 fügst andere Personen mit dem */f*-Befehl hinzu, wenn du möchtest.
303. Chatte drauf los!
31 + Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu senden. Wow, du chattest!
324. Mach etwas kaputt!
33 + Jep, pre-alpha-alpha-Software stürzt manchmal ab. Wir arbeiten daran.
34 + Bitte melde alle Abstürze entweder an die GitHub-Seite oder #tox-dev im freenode-IRC.
355. Nichts ist kaputt, aber was bedeutet */f*?
36 + nTox liest einen Text als Befehl, wenn das erste Zeichen ein Schrägstrich ist ('/').
37 Du kannst alle Befehle in commands.md nachlesen.
386. Benutze und unterstütze Tox!
39 + Programmiere, debugge, dokumentiere, übersetze für uns, oder sprich einfach über uns!
40 + Je mehr Interesse wir erhalten, desto mehr Arbeit wird getan und desto besser wird Tox.
diff --git a/start_guide.md b/start_guide.md
new file mode 100644
index 00000000..b4f4310d
--- /dev/null
+++ b/start_guide.md
@@ -0,0 +1,38 @@
1# Using Tox
21. Build Tox
32. Fix errors
43. Consult IRC for help
54. Go on debugging journy for devs
65. Build Tox for real
76. ???
8
9For all the work we've put into Tox so far,
10there isn't yet a decent guide for how you _use_
11Tox. Here's a user-friendly attempt at it.
12
131. Connect to the network!
14 + You need to connect to a bootstrapping server, to give you a public key.
15 + Where can I find a public server? Right here, as of now:
16 (the help message from running nTox with no args will help)
17 + 198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
18 + 192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
19 + 66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
20 + 192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
212. Find a friend!
22 + Now that you're on the network, you need a friend. To get one of those,
23 you need to to send or receive a request. What's a request, you ask?
24 It's like a friend request, but we use really scary and cryptic numbers
25 instead of names. When nTox starts, it shows your _your_ long, scary number,
26 called your *public key*. Give that to people, and they can add you as
27 as "friend". Or, you can add someone else, with the */f* command, if you like.
283. Chat it up!
29 + Now use the */m* command to send a message to someone. Wow, you're chatting!
304. But something broke!
31 + Yeah, pre-alpha-alpha software tends to do that. We're working on it.
32 + Please report all crashes to either the github page, or #tox-dev on freenode.
335. Nothing broke, but what does */f* mean?
34 + nTox parses text as a command if the first character is a forward-slash ('/').
35 You can check all commands in commands.md.
366. Use and support Tox!
37 + Code for us, debug for us, document for us, translate for us, even just talk about us!
38 + The more interest we get, the more work gets done, the better Tox is.
diff --git a/testing/DHT_cryptosendfiletest.c b/testing/DHT_cryptosendfiletest.c
index c7c33531..888dac0f 100644
--- a/testing/DHT_cryptosendfiletest.c
+++ b/testing/DHT_cryptosendfiletest.c
@@ -186,7 +186,7 @@ int main(int argc, char *argv[])
186 fclose(file2); 186 fclose(file2);
187 } 187 }
188 } 188 }
189 /* if buffer is empty and the connection timed out. */ 189 /* if buffer is empty and the connection timed out. */
190 else if(is_cryptoconnected(inconnection) == 4) { 190 else if(is_cryptoconnected(inconnection) == 4) {
191 crypto_kill(inconnection); 191 crypto_kill(inconnection);
192 } 192 }
@@ -209,7 +209,7 @@ int main(int argc, char *argv[])
209 fclose(file2); 209 fclose(file2);
210 } 210 }
211 } 211 }
212 /* if buffer is empty and the connection timed out. */ 212 /* if buffer is empty and the connection timed out. */
213 else if(is_cryptoconnected(connection) == 4) { 213 else if(is_cryptoconnected(connection) == 4) {
214 crypto_kill(connection); 214 crypto_kill(connection);
215 } 215 }
diff --git a/testing/nTox.c b/testing/nTox.c
index 97a39a12..6aef1d7b 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -35,6 +35,8 @@
35 35
36char lines[HISTORY][STRING_LENGTH]; 36char lines[HISTORY][STRING_LENGTH];
37char line[STRING_LENGTH]; 37char line[STRING_LENGTH];
38char *help = "[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)\n"
39 "[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)";
38int x,y; 40int x,y;
39 41
40uint8_t pending_requests[256][CLIENT_ID_SIZE]; 42uint8_t pending_requests[256][CLIENT_ID_SIZE];
@@ -50,6 +52,7 @@ void new_lines(char *line)
50 do_refresh(); 52 do_refresh();
51} 53}
52 54
55
53void print_friendlist() 56void print_friendlist()
54{ 57{
55 char name[MAX_NAME_LENGTH]; 58 char name[MAX_NAME_LENGTH];
@@ -69,6 +72,26 @@ void print_friendlist()
69 } 72 }
70} 73}
71 74
75char *format_message(char *message, int friendnum)
76{
77 char name[MAX_NAME_LENGTH];
78 if(friendnum != -1) {
79 getname(friendnum, (uint8_t*)name);
80 } else {
81 getself_name((uint8_t*)name);
82 }
83 char *msg = malloc(100+strlen(message)+strlen(name)+1);
84 time_t rawtime;
85 struct tm * timeinfo;
86 time ( &rawtime );
87 timeinfo = localtime ( &rawtime );
88 char* time = asctime(timeinfo);
89 size_t len = strlen(time);
90 time[len-1]='\0';
91 sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); // timestamp
92 return msg;
93}
94
72void line_eval(char lines[HISTORY][STRING_LENGTH], char *line) 95void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
73{ 96{
74 if (line[0] == '/') { 97 if (line[0] == '/') {
@@ -107,6 +130,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
107 int num = atoi(numstring); 130 int num = atoi(numstring);
108 if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) { 131 if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) {
109 new_lines("[i] could not send message"); 132 new_lines("[i] could not send message");
133 } else {
134 new_lines(format_message(message, -1));
110 } 135 }
111 } 136 }
112 else if (line[1] == 'n') { 137 else if (line[1] == 'n') {
@@ -153,10 +178,31 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
153 } 178 }
154 179
155 else if (line[1] == 'h') { //help 180 else if (line[1] == 'h') { //help
156 new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)"); 181 new_lines(help);
157 new_lines("[i] /l list (list friends), /h for help, /n nick (to change nickname), /q (to quit)");
158 } 182 }
159 183
184 else if (line[1] == 'i') { //info
185 char idstring0[200];
186 char idstring1[32][5];
187 char idstring2[32][5];
188 uint32_t i;
189 for(i = 0; i < 32; i++)
190 {
191 if(self_public_key[i] < 16)
192 strcpy(idstring1[i],"0");
193 else
194 strcpy(idstring1[i], "");
195 sprintf(idstring2[i], "%hhX",self_public_key[i]);
196 }
197 //
198 strcpy(idstring0,"[i] ID: ");
199 for (i=0; i<32; i++) {
200 strcat(idstring0,idstring1[i]);
201 strcat(idstring0,idstring2[i]);
202 }
203 new_lines(idstring0);
204 }
205
160 else if (line[1] == 'q') { //exit 206 else if (line[1] == 'q') { //exit
161 endwin(); 207 endwin();
162 exit(EXIT_SUCCESS); 208 exit(EXIT_SUCCESS);
@@ -255,7 +301,7 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
255 size_t len = strlen(temp); 301 size_t len = strlen(temp);
256 temp[len-1]='\0'; 302 temp[len-1]='\0';
257 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp 303 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp
258 new_lines(msg); 304 new_lines(format_message((char*)string, friendnumber));
259} 305}
260 306
261void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) { 307void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) {
@@ -344,8 +390,7 @@ int main(int argc, char *argv[])
344 raw(); 390 raw();
345 getmaxyx(stdscr,y,x); 391 getmaxyx(stdscr,y,x);
346 new_lines(idstring0); 392 new_lines(idstring0);
347 new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)"); 393 new_lines(help);
348 new_lines("[i] /l list (list friends), /n nick (to change nickname), /q (to quit)");
349 strcpy(line, ""); 394 strcpy(line, "");
350 IP_Port bootstrap_ip_port; 395 IP_Port bootstrap_ip_port;
351 bootstrap_ip_port.port = htons(atoi(argv[2])); 396 bootstrap_ip_port.port = htons(atoi(argv[2]));
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
index 3a9caaf5..a870c210 100644
--- a/testing/nTox_win32.c
+++ b/testing/nTox_win32.c
@@ -317,6 +317,7 @@ int main(int argc, char *argv[])
317 } 317 }
318 318
319 doMessenger(); 319 doMessenger();
320 Sleep(1);
320 } 321 }
321 322
322 return 0; 323 return 0;
diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt
index 4f9785d5..c70babb7 100644
--- a/testing/toxic/CMakeLists.txt
+++ b/testing/toxic/CMakeLists.txt
@@ -5,7 +5,8 @@ set(exe_name toxic)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 main.c 7 main.c
8 prompt.c) 8 prompt.c
9 friendlist.c)
9 10
10target_link_libraries(${exe_name} 11target_link_libraries(${exe_name}
11 curses) 12 curses)
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
new file mode 100644
index 00000000..f8b8c840
--- /dev/null
+++ b/testing/toxic/friendlist.c
@@ -0,0 +1,125 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <curses.h>
6#include <string.h>
7#include <stdint.h>
8#include <ctype.h>
9
10#include "../../core/Messenger.h"
11#include "../../core/network.h"
12
13#include "windows.h"
14
15#define MAX_FRIENDS_NUM 100
16
17typedef struct {
18 uint8_t name[MAX_NAME_LENGTH];
19 uint8_t status[MAX_USERSTATUS_LENGTH];
20 int num;
21
22} friend_t;
23
24static friend_t friends[MAX_FRIENDS_NUM];
25static int num_friends = 0;
26
27
28void fix_name(uint8_t* name) {
29
30 // Remove all non alphanumeric characters.
31 uint8_t* p = name;
32 uint8_t* q = name;
33
34 while(*p != 0) {
35 if(isalnum(*p)) {
36 *q++ = *p;
37 }
38
39 p++;
40 }
41
42 *q = 0;
43}
44
45int friendlist_nickchange(int num, uint8_t* str, uint16_t len) {
46
47 if(len >= MAX_NAME_LENGTH || num >= num_friends)
48 return -1;
49
50 memcpy((char*) &friends[num].name, (char*) str, len);
51 friends[num].name[len] = 0;
52 fix_name(friends[num].name);
53
54 return 0;
55}
56
57int friendlist_statuschange(int num, uint8_t* str, uint16_t len) {
58
59 if(len >= MAX_USERSTATUS_LENGTH || num >= num_friends)
60 return -1;
61
62 memcpy((char*) &friends[num].status, (char*) str, len);
63 friends[num].status[len] = 0;
64 fix_name(friends[num].status);
65
66 return 0;
67}
68
69int friendlist_addfriend(int num) {
70
71 if(num_friends == MAX_FRIENDS_NUM)
72 return -1;
73
74 friends[num_friends].num = num;
75 getname(num, friends[num_friends].name);
76 strcpy((char*) friends[num_friends].name, "unknown");
77 strcpy((char*) friends[num_friends].status, "unknown");
78
79 num_friends++;
80 return 0;
81}
82
83static void friendlist_onKey(ToxWindow* self, int key) {
84
85}
86
87static void friendlist_onDraw(ToxWindow* self) {
88 size_t i;
89
90 wclear(self->window);
91
92 if(num_friends == 0) {
93 wprintw(self->window, "Empty. Add some friends! :-)\n");
94 }
95
96 wprintw(self->window, "\n");
97
98 for(i=0; i<num_friends; i++) {
99 wprintw(self->window, "[%d] ", friends[i].num);
100
101 attron(A_BOLD);
102 wprintw(self->window, "%s ", friends[i].name);
103 attroff(A_BOLD);
104
105 wprintw(self->window, "(%s)\n", friends[i].status);
106 }
107
108 wrefresh(self->window);
109}
110
111static void friendlist_onInit(ToxWindow* self) {
112
113}
114
115
116ToxWindow new_friendlist() {
117 ToxWindow ret;
118
119 ret.onKey = &friendlist_onKey;
120 ret.onDraw = &friendlist_onDraw;
121 ret.onInit = &friendlist_onInit;
122 strcpy(ret.title, "[friends]");
123
124 return ret;
125}
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 0aad6777..e1d1ebd0 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -14,6 +14,12 @@
14#include "windows.h" 14#include "windows.h"
15 15
16extern ToxWindow new_prompt(); 16extern ToxWindow new_prompt();
17extern ToxWindow new_friendlist();
18
19extern int friendlist_addfriend(int num);
20extern int friendlist_nickchange(int num, uint8_t* str, uint16_t len);
21extern int friendlist_statuschange(int num, uint8_t* str, uint16_t len);
22
17extern int add_req(uint8_t* public_key); // XXX 23extern int add_req(uint8_t* public_key); // XXX
18 24
19#define TOXWINDOWS_MAX_NUM 32 25#define TOXWINDOWS_MAX_NUM 32
@@ -35,11 +41,19 @@ void on_message(int friendnumber, uint8_t* string, uint16_t length) {
35} 41}
36 42
37void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) { 43void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) {
38 wprintw(prompt->window, "\n(nick) %d: %s!\n", friendnumber, string); 44 wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string);
45
46 friendlist_nickchange(friendnumber, string, length);
39} 47}
40 48
41void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) { 49void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) {
42 wprintw(prompt->window, "\n(status) %d: %s!\n", friendnumber, string); 50 wprintw(prompt->window, "\n(statuschange) %d: %s!\n", friendnumber, string);
51
52 friendlist_statuschange(friendnumber, string, length);
53}
54
55void on_friendadded(int friendnumber) {
56 friendlist_addfriend(friendnumber);
43} 57}
44// CALLBACKS END 58// CALLBACKS END
45 59
@@ -95,7 +109,7 @@ static void init_windows() {
95 w_num = 0; 109 w_num = 0;
96 w_active = 0; 110 w_active = 0;
97 111
98 if(add_window(new_prompt()) == -1) { 112 if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) {
99 fprintf(stderr, "add_window() failed.\n"); 113 fprintf(stderr, "add_window() failed.\n");
100 114
101 endwin(); 115 endwin();
@@ -134,14 +148,18 @@ static void load_data() {
134 148
135 if(buf == NULL) { 149 if(buf == NULL) {
136 fprintf(stderr, "malloc() failed.\n"); 150 fprintf(stderr, "malloc() failed.\n");
151
137 fclose(fd); 152 fclose(fd);
153 endwin();
138 exit(1); 154 exit(1);
139 } 155 }
140 156
141 if(fread(buf, len, 1, fd) != 1){ 157 if(fread(buf, len, 1, fd) != 1){
142 fprintf(stderr, "fread() failed.\n"); 158 fprintf(stderr, "fread() failed.\n");
159
143 free(buf); 160 free(buf);
144 fclose(fd); 161 fclose(fd);
162 endwin();
145 exit(1); 163 exit(1);
146 } 164 }
147 165
@@ -153,6 +171,7 @@ static void load_data() {
153 171
154 if(buf == NULL) { 172 if(buf == NULL) {
155 fprintf(stderr, "malloc() failed.\n"); 173 fprintf(stderr, "malloc() failed.\n");
174 endwin();
156 exit(1); 175 exit(1);
157 } 176 }
158 177
@@ -161,14 +180,18 @@ static void load_data() {
161 fd = fopen("data", "w"); 180 fd = fopen("data", "w");
162 if(fd == NULL) { 181 if(fd == NULL) {
163 fprintf(stderr, "fopen() failed.\n"); 182 fprintf(stderr, "fopen() failed.\n");
183
164 free(buf); 184 free(buf);
185 endwin();
165 exit(1); 186 exit(1);
166 } 187 }
167 188
168 if(fwrite(buf, len, 1, fd) != 1){ 189 if(fwrite(buf, len, 1, fd) != 1){
169 fprintf(stderr, "fwrite() failed.\n"); 190 fprintf(stderr, "fwrite() failed.\n");
191
170 free(buf); 192 free(buf);
171 fclose(fd); 193 fclose(fd);
194 endwin();
172 exit(1); 195 exit(1);
173 } 196 }
174 } 197 }
@@ -186,12 +209,16 @@ static void draw_bar() {
186 209
187 move(LINES - 1, 0); 210 move(LINES - 1, 0);
188 211
212 attron(COLOR_PAIR(3) | A_BOLD);
213 printw(" TOXIC 1.0 |");
214 attroff(COLOR_PAIR(3) | A_BOLD);
215
189 for(i=0; i<w_num; i++) { 216 for(i=0; i<w_num; i++) {
190 if(i == w_active) { 217 if(i == w_active) {
191 attron(A_BOLD); 218 attron(A_BOLD);
192 } 219 }
193 220
194 printw(" %s ", windows[i].title); 221 printw(" %s", windows[i].title);
195 222
196 if(i == w_active) { 223 if(i == w_active) {
197 attroff(A_BOLD); 224 attroff(A_BOLD);
@@ -201,6 +228,11 @@ static void draw_bar() {
201 refresh(); 228 refresh();
202} 229}
203 230
231void prepare_window(WINDOW* w) {
232 mvwin(w, 0, 0);
233 wresize(w, LINES-2, COLS);
234}
235
204int main(int argc, char* argv[]) { 236int main(int argc, char* argv[]) {
205 int ch; 237 int ch;
206 ToxWindow* a; 238 ToxWindow* a;
@@ -211,14 +243,21 @@ int main(int argc, char* argv[]) {
211 init_windows(); 243 init_windows();
212 244
213 while(true) { 245 while(true) {
246 // Update tox.
214 do_tox(); 247 do_tox();
215 248
249 // Draw.
216 a = &windows[w_active]; 250 a = &windows[w_active];
251 prepare_window(a->window);
217 a->onDraw(a); 252 a->onDraw(a);
218 draw_bar(); 253 draw_bar();
219 254
255 // Handle input.
220 ch = getch(); 256 ch = getch();
221 if(ch != ERR) { 257 if(ch == '\t') {
258 w_active = (w_active + 1) % w_num;
259 }
260 else if(ch != ERR) {
222 a->onKey(a, ch); 261 a->onKey(a, ch);
223 } 262 }
224 263
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 4a59cc7b..0cd10730 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -15,6 +15,8 @@
15uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX 15uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX
16uint8_t num_requests=0; // XXX 16uint8_t num_requests=0; // XXX
17 17
18extern void on_friendadded(int friendnumber);
19
18// XXX: 20// XXX:
19int add_req(uint8_t* public_key) { 21int add_req(uint8_t* public_key) {
20 memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); 22 memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
@@ -40,7 +42,6 @@ static int prompt_buf_pos=0;
40 42
41static void execute(ToxWindow* self, char* cmd) { 43static void execute(ToxWindow* self, char* cmd) {
42 44
43 // quit/exit: Exit program.
44 if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { 45 if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) {
45 endwin(); 46 endwin();
46 exit(0); 47 exit(0);
@@ -53,33 +54,32 @@ static void execute(ToxWindow* self, char* cmd) {
53 54
54 ip = strchr(cmd, ' '); 55 ip = strchr(cmd, ' ');
55 if(ip == NULL) { 56 if(ip == NULL) {
57 wprintw(self->window, "Invalid syntax.\n");
56 return; 58 return;
57 } 59 }
58
59 ip++; 60 ip++;
60 61
61 port = strchr(ip, ' '); 62 port = strchr(ip, ' ');
62 if(port == NULL) { 63 if(port == NULL) {
64 wprintw(self->window, "Invalid syntax.\n");
63 return; 65 return;
64 } 66 }
65
66 port[0] = 0; 67 port[0] = 0;
67 port++; 68 port++;
68 69
69 key = strchr(port, ' '); 70 key = strchr(port, ' ');
70 if(key == NULL) { 71 if(key == NULL) {
72 wprintw(self->window, "Invalid syntax.\n");
71 return; 73 return;
72 } 74 }
73
74 key[0] = 0; 75 key[0] = 0;
75 key++; 76 key++;
76 77
77 if(atoi(port) == 0) { 78 if(atoi(port) == 0) {
79 wprintw(self->window, "Invalid syntax.\n");
78 return; 80 return;
79 } 81 }
80 82
81 wprintw(self->window, "ip=%s, port=%s, key=%s\n", ip, port, key);
82
83 dht.port = htons(atoi(port)); 83 dht.port = htons(atoi(port));
84 84
85 int resolved_address = resolve_addr(ip); 85 int resolved_address = resolve_addr(ip);
@@ -91,38 +91,62 @@ static void execute(ToxWindow* self, char* cmd) {
91 DHT_bootstrap(dht, hex_string_to_bin(key)); 91 DHT_bootstrap(dht, hex_string_to_bin(key));
92 } 92 }
93 else if(!strncmp(cmd, "add ", strlen("add "))) { 93 else if(!strncmp(cmd, "add ", strlen("add "))) {
94 uint8_t id_bin[32];
95 size_t i;
96 char xx[3];
97 uint32_t x;
98
94 char* id; 99 char* id;
95 char* msg; 100 char* msg;
96 int num; 101 int num;
97 102
98 id = strchr(cmd, ' '); 103 id = strchr(cmd, ' ');
99
100 if(id == NULL) { 104 if(id == NULL) {
105 wprintw(self->window, "Invalid syntax.\n");
101 return; 106 return;
102 } 107 }
103
104 id++; 108 id++;
105 109
106 msg = strchr(id, ' '); 110 msg = strchr(id, ' ');
107 if(msg == NULL) { 111 if(msg != NULL) {
112 msg[0] = 0;
113 msg++;
114 }
115 else msg = "";
116
117 if(strlen(id) != 2*32) {
118 wprintw(self->window, "Invalid ID length.\n");
108 return; 119 return;
109 } 120 }
110 121
111 msg[0] = 0; 122 for(i=0; i<32; i++) {
112 msg++; 123 xx[0] = id[2*i];
124 xx[1] = id[2*i+1];
125 xx[2] = '\0';
126
127 if(sscanf(xx, "%02x", &x) != 1) {
128 wprintw(self->window, "Invalid ID.\n");
129 return;
130 }
131
132 id_bin[i] = x;
133 }
134
135 num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1);
113 136
114 num = m_addfriend((uint8_t*) id, (uint8_t*) msg, strlen(msg)+1);
115 wprintw(self->window, "Friend added as %d.\n", num); 137 wprintw(self->window, "Friend added as %d.\n", num);
138 on_friendadded(num);
116 } 139 }
117 else if(!strncmp(cmd, "status ", strlen("status "))) { 140 else if(!strncmp(cmd, "status ", strlen("status "))) {
118 char* msg; 141 char* msg;
119 142
120 msg = strchr(cmd, ' '); 143 msg = strchr(cmd, ' ');
121 if(msg == NULL) { 144 if(msg == NULL) {
145 wprintw(self->window, "Invalid syntax.\n");
122 return; 146 return;
123 } 147 }
124
125 msg++; 148 msg++;
149
126 m_set_userstatus((uint8_t*) msg, strlen(msg)+1); 150 m_set_userstatus((uint8_t*) msg, strlen(msg)+1);
127 wprintw(self->window, "Status set to: %s.\n", msg); 151 wprintw(self->window, "Status set to: %s.\n", msg);
128 } 152 }
@@ -133,33 +157,22 @@ static void execute(ToxWindow* self, char* cmd) {
133 if(nick == NULL) { 157 if(nick == NULL) {
134 return; 158 return;
135 } 159 }
136
137 nick++; 160 nick++;
161
138 setname((uint8_t*) nick, strlen(nick)+1); 162 setname((uint8_t*) nick, strlen(nick)+1);
139 wprintw(self->window, "Nickname set to: %s.\n", nick); 163 wprintw(self->window, "Nickname set to: %s.\n", nick);
140 } 164 }
141 else if(!strcmp(cmd, "myid")) { 165 else if(!strcmp(cmd, "myid")) {
142 // XXX: Clean this up 166 char id[32*2 + 1] = {0};
143 char idstring0[200]; 167 size_t i;
144 char idstring1[32][5]; 168
145 char idstring2[32][5]; 169 for(i=0; i<32; i++) {
146 uint32_t i; 170 char xx[3];
147 171 snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff);
148 for(i = 0; i < 32; i++) { 172 strcat(id, xx);
149 if(self_public_key[i] < 16)
150 strcpy(idstring1[i], "0");
151 else
152 strcpy(idstring1[i], "");
153
154 sprintf(idstring2[i], "%hhX", self_public_key[i]);
155 } 173 }
156 174
157 for (i=0; i<32; i++) { 175 wprintw(self->window, "%s\n", id);
158 strcat(idstring0, idstring1[i]);
159 strcat(idstring0, idstring2[i]);
160 }
161
162 wprintw(self->window, "%s\n", idstring0);
163 } 176 }
164 else if(!strncmp(cmd, "accept ", strlen("accept "))) { 177 else if(!strncmp(cmd, "accept ", strlen("accept "))) {
165 char* id; 178 char* id;
@@ -167,17 +180,26 @@ static void execute(ToxWindow* self, char* cmd) {
167 180
168 id = strchr(cmd, ' '); 181 id = strchr(cmd, ' ');
169 if(id == NULL) { 182 if(id == NULL) {
183 wprintw(self->window, "Invalid syntax.\n");
170 return; 184 return;
171 } 185 }
172 id++; 186 id++;
173 187
174 num = atoi(id); 188 num = atoi(id);
175 if(num >= num_requests) { 189 if(num >= num_requests) {
190 wprintw(self->window, "Invalid syntax.\n");
176 return; 191 return;
177 } 192 }
178 193
179 num = m_addfriend_norequest(pending_requests[num]); 194 num = m_addfriend_norequest(pending_requests[num]);
180 wprintw(self->window, "Friend accepted as: %d.\n", num); 195
196 if(num == -1) {
197 wprintw(self->window, "Failed to add friend.\n");
198 }
199 else {
200 wprintw(self->window, "Friend accepted as: %d.\n", num);
201 on_friendadded(num);
202 }
181 } 203 }
182 else if(!strncmp(cmd, "msg ", strlen("msg "))) { 204 else if(!strncmp(cmd, "msg ", strlen("msg "))) {
183 char* id; 205 char* id;
@@ -186,16 +208,16 @@ static void execute(ToxWindow* self, char* cmd) {
186 id = strchr(cmd, ' '); 208 id = strchr(cmd, ' ');
187 209
188 if(id == NULL) { 210 if(id == NULL) {
211 wprintw(self->window, "Invalid syntax.\n");
189 return; 212 return;
190 } 213 }
191
192 id++; 214 id++;
193 215
194 msg = strchr(id, ' '); 216 msg = strchr(id, ' ');
195 if(msg == NULL) { 217 if(msg == NULL) {
218 wprintw(self->window, "Invalid syntax.\n");
196 return; 219 return;
197 } 220 }
198
199 msg[0] = 0; 221 msg[0] = 0;
200 msg++; 222 msg++;
201 223
@@ -206,6 +228,9 @@ static void execute(ToxWindow* self, char* cmd) {
206 wprintw(self->window, "Message successfully sent.\n"); 228 wprintw(self->window, "Message successfully sent.\n");
207 } 229 }
208 } 230 }
231 else {
232 wprintw(self->window, "Invalid syntax.\n");
233 }
209} 234}
210 235
211static void prompt_onKey(ToxWindow* self, int key) { 236static void prompt_onKey(ToxWindow* self, int key) {
@@ -242,9 +267,6 @@ static void prompt_onKey(ToxWindow* self, int key) {
242static void prompt_onDraw(ToxWindow* self) { 267static void prompt_onDraw(ToxWindow* self) {
243 int x, y; 268 int x, y;
244 269
245 mvwin(self->window,0,0);
246 wresize(self->window, LINES-2, COLS);
247
248 getyx(self->window, y, x); 270 getyx(self->window, y, x);
249 (void) x; 271 (void) x;
250 272
@@ -265,11 +287,18 @@ static void print_usage(ToxWindow* self) {
265 287
266 wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); 288 wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n");
267 wprintw(self->window, " add <id> <message> : Add friend\n"); 289 wprintw(self->window, " add <id> <message> : Add friend\n");
290 wprintw(self->window, " msg <number> <message> : Send message\n");
268 wprintw(self->window, " status <message> : Set your status\n"); 291 wprintw(self->window, " status <message> : Set your status\n");
269 wprintw(self->window, " nick <nickname> : Set your nickname\n"); 292 wprintw(self->window, " nick <nickname> : Set your nickname\n");
270 wprintw(self->window, " accept <number> : Accept friend request\n"); 293 wprintw(self->window, " accept <number> : Accept friend request\n");
271 wprintw(self->window, " myid : Print your ID\n"); 294 wprintw(self->window, " myid : Print your ID\n");
272 wprintw(self->window, " quit/exit : Exit program\n"); 295 wprintw(self->window, " quit/exit : Exit program\n");
296
297
298 wattron(self->window, A_BOLD);
299 wprintw(self->window, "Use the TAB key to navigate through the tabs.\n");
300 wattroff(self->window, A_BOLD);
301
273 wattroff(self->window, COLOR_PAIR(2)); 302 wattroff(self->window, COLOR_PAIR(2));
274} 303}
275 304