summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstonex <softukitu@gmail.com>2013-07-31 23:02:09 +0100
committerAstonex <softukitu@gmail.com>2013-07-31 23:02:09 +0100
commitf05aa308701f33f3bf9df022a4b376deeedef235 (patch)
treec10b8a3cca6822400853bfd3bc2c5fd1cca73f83
parent8dfba27242ca23fca5de852541f2101568dbf7cb (diff)
parentc558cb63f6db35bd51f2f2331e21df03105ee82a (diff)
Merge remote-tracking branch 'ProjectTox/master'
-rw-r--r--.gitignore8
-rw-r--r--.travis.yml13
-rwxr-xr-x[-rw-r--r--]CMakeLists.txt26
-rw-r--r--INSTALL.md19
-rw-r--r--README.md53
-rw-r--r--cmake/FindLIBCONFIG.cmake15
-rw-r--r--cmake/FindNaCl.cmake17
-rw-r--r--cmake/FindSODIUM.cmake15
-rw-r--r--core/CMakeLists.txt16
-rw-r--r--core/Lossless_UDP.c6
-rw-r--r--core/Messenger.c31
-rw-r--r--core/Messenger.h18
-rw-r--r--core/friend_requests.h2
-rw-r--r--core/network.c4
-rw-r--r--core/network.h8
-rw-r--r--docs/commands.md25
-rw-r--r--docs/using_tox.md38
-rw-r--r--other/bootstrap_serverdaemon/CMakeLists.txt13
-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--other/cmake/DHT_bootstrap.cmake3
-rw-r--r--start_guide.de.md40
-rw-r--r--start_guide.md38
-rw-r--r--testing/CMakeLists.txt4
-rw-r--r--testing/DHT_cryptosendfiletest.c4
-rw-r--r--testing/DHT_test.c6
-rw-r--r--testing/Lossless_UDP_testclient.c2
-rw-r--r--testing/Lossless_UDP_testserver.c2
-rw-r--r--testing/cmake/DHT_cryptosendfiletest.cmake3
-rw-r--r--testing/cmake/DHT_sendfiletest.cmake2
-rw-r--r--testing/cmake/DHT_test.cmake3
-rw-r--r--testing/cmake/Lossless_UDP_testclient.cmake2
-rw-r--r--testing/cmake/Lossless_UDP_testserver.cmake2
-rw-r--r--testing/cmake/Messenger_test.cmake2
-rw-r--r--testing/cmake/nTox.cmake7
-rw-r--r--testing/misc_tools.h2
-rw-r--r--testing/nTox.c211
-rw-r--r--testing/nTox.h1
-rw-r--r--testing/nTox_win32.c87
-rw-r--r--testing/nTox_win32.h1
-rw-r--r--testing/toxic/CMakeLists.txt (renamed from testing/cmake/toxic.cmake)10
-rw-r--r--testing/toxic/chat.c155
-rw-r--r--testing/toxic/friendlist.c166
-rw-r--r--testing/toxic/main.c103
-rw-r--r--testing/toxic/prompt.c118
-rw-r--r--testing/toxic/windows.h13
47 files changed, 1141 insertions, 261 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/CMakeLists.txt b/CMakeLists.txt
index c16ce6fe..9b7db143 100644..100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,31 @@
1cmake_minimum_required(VERSION 2.6.0) 1cmake_minimum_required(VERSION 2.6.0)
2 2
3set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
4
5if(NOT WIN32)
6 option(USE_NACL "Use NaCl library instead of libsodium")
7endif()
8
9if(USE_NACL)
10 find_package(NaCl REQUIRED)
11
12 include_directories(${NACL_INCLUDE_DIR})
13 add_definitions(-DVANILLA_NACL)
14
15 set(LINK_CRYPTO_LIBRARY ${NACL_LIBRARIES})
16endif()
17
3#MinGW prints more warnings for -Wall than gcc does, thus causing build to fail 18#MinGW prints more warnings for -Wall than gcc does, thus causing build to fail
4if(NOT WIN32) 19if(NOT WIN32)
5 if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")) 20 if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"))
6 message(STATUS "==== ${CMAKE_C_COMPILER_ID} detected - Adding compiler flags ====") 21 message(STATUS "==== ${CMAKE_C_COMPILER_ID} detected - Adding compiler flags ====")
7 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") 22 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
8 endif() 23 endif()
24 find_package(SODIUM REQUIRED)
25endif()
26
27if(NOT USE_NACL)
28 set(LINK_CRYPTO_LIBRARY ${SODIUM_LIBRARY})
9endif() 29endif()
10 30
11macro(linkCoreLibraries exe_name) 31macro(linkCoreLibraries exe_name)
@@ -16,8 +36,10 @@ macro(linkCoreLibraries exe_name)
16 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a 36 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a
17 ws2_32) 37 ws2_32)
18 else() 38 else()
39 include_directories(${SODIUM_INCLUDE_DIR})
19 target_link_libraries(${exe_name} core 40 target_link_libraries(${exe_name} core
20 sodium) 41 ${LINK_CRYPTO_LIBRARY})
42
21 endif() 43 endif()
22endmacro() 44endmacro()
23 45
@@ -25,4 +47,4 @@ cmake_policy(SET CMP0011 NEW)
25 47
26add_subdirectory(core) 48add_subdirectory(core)
27add_subdirectory(testing) 49add_subdirectory(testing)
28add_subdirectory(other) \ No newline at end of file 50add_subdirectory(other)
diff --git a/INSTALL.md b/INSTALL.md
index 8e67d848..9efa7ee9 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -5,8 +5,9 @@
5Build dependencies: 5Build dependencies:
6 6
7```bash 7```bash
8apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev 8apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall
9``` 9```
10Note that `libconfig-dev` should be >= 1.4.
10 11
11You should get and install [libsodium](https://github.com/jedisct1/libsodium): 12You should get and install [libsodium](https://github.com/jedisct1/libsodium):
12```bash 13```bash
@@ -15,7 +16,7 @@ cd libsodium
15git checkout tags/0.4.2 16git checkout tags/0.4.2
16./autogen.sh 17./autogen.sh
17./configure && make check 18./configure && make check
18sudo make install 19sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
19sudo ldconfig 20sudo ldconfig
20``` 21```
21 22
@@ -41,7 +42,17 @@ make
41 42
42###OSX: 43###OSX:
43 44
44Much 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).
45Users 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.
46They 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:
47 58
@@ -68,7 +79,7 @@ You have to [modify your PATH environment variable](http://www.computerhope.com/
68 79
69Then you should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere. 80Then you should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere.
70 81
71After that you should get precompiled packages of libsodium from [here](https://download.libsodium.org/libsodium/releases/) and extract the archive into this repo's root. That is, `sodium` folder should be along with `core`, `testing` and other folders. 82After that you should get precompiled package of libsodium from [here](https://download.libsodium.org/libsodium/releases/libsodium-win32-0.4.2.tar.gz) and extract the archive into this repo's root. That is, `sodium` folder should be along with `core`, `testing` and other folders.
72 83
73Navigate in `cmd` to this repo and run: 84Navigate in `cmd` to this repo and run:
74```cmd 85```cmd
diff --git a/README.md b/README.md
index b4381bc9..499d8202 100644
--- a/README.md
+++ b/README.md
@@ -1,54 +1,51 @@
1![Project Tox](https://rbt.asia/boards/g/img/0352/79/1373823047559.png "Project Tox") 1![Project Tox](https://rbt.asia/boards/g/img/0352/79/1373823047559.png "Project Tox")
2Project Tox, _also known as Tox_, is a FOSS instant messaging application aimed to replace Skype.<br /> 2Project Tox, _also known as Tox_, is a FOSS (Free and Open Source Software) instant messaging application aimed to replace Skype.<br />
3 3
4With the rise of governmental monitoring programs, Tox aims to be an easy to use application that allows people to connect with friends and loved ones without the worry of privacy.<br /> <br /> 4With the rise of governmental monitoring programs, Tox aims to be an easy to use, all-in-one communication platform (including audio, and videochats in the future) that ensures their users full privacy and secure message delivery.<br /> <br />
5 5
6 6
7 7
8 8**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) 9**Website**: [http://tox.im](http://tox.im)
11 10
12**Website translations**: [see stal888's repository](https://github.com/stal888/ProjectTox-Website)<br/> 11**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) 12**Qt GUI**: [see nurupo's repository](https://github.com/nurupo/ProjectTox-Qt-GUI)
14 13
14**How to build Tox on Linux**: [YouTube video](http://www.youtube.com/watch?v=M4WXE4VKmyg)<br />
15**How to use Tox on Windows**: [YouTube video](http://www.youtube.com/watch?v=qg_j_sDb6WQ)
16
17### Objectives:
15 18
19Keep everything really simple.
16 20
17## The Complex Stuff: 21## 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. 22+ Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable.
19+ Every peer is represented as a byte string (the public key of the peer [client id]) 23+ Every peer is represented as a [byte string](https://en.wikipedia.org/wiki/String_(computer_science)) (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. 24+ 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) 25+ 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 /> 26+ When both peers are securely connected, they can exchange messages, initiate a video chat, send files, etc, all using encrypted communications.
23+ Current build status: [![Build Status](https://travis-ci.org/irungentoo/ProjectTox-Core.png?branch=master)](https://travis-ci.org/irungentoo/ProjectTox-Core) 27+ Current build status: [![Build Status](https://travis-ci.org/irungentoo/ProjectTox-Core.png?branch=master)](https://travis-ci.org/irungentoo/ProjectTox-Core)
24 28
25## Roadmap: 29## Roadmap:
26- [x] Get our DHT working perfectly.(Done, needs large scale testing though.) 30- [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) 31- [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) 32- [x] Encryption. (Done)
29- [ ] Get a simple text only im client working perfectly. (This is where we are) 33- [ ] Get a simple text only IM client working perfectly. (This is where we are)
30- [ ] Streaming media 34- [ ] Streaming media
31- [ ] ??? 35- [ ] ???
32 36
33For further information, check our [To-do list](https://github.com/irungentoo/ProjectTox-Core/wiki/TODO) 37For further information, check our [To-do list](https://github.com/irungentoo/ProjectTox-Core/wiki/TODO)
34 38
39### Why are you doing this? There are already a bunch of free skype alternatives.
40The goal of this project is to create a configuration-free P2P skype
41replacement. Configuration-free means that the user will simply have to open the program and
42without any account configuration will be capable of adding people to his
43friends list and start conversing with them. There are many so called skype replacements and all of them are either hard to
44configure for the normal user or suffer from being way too centralized.
35 45
36### Important-stuff: 46### Documentation:
37
38Use the same UDP socket for everything
39
40Keep everything really simple.
41
42### Details and Documents:
43 47
44[DHT Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/DHT)<br /> 48[DHT Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/DHT)<br />
45[Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br /> 49[Lossless UDP Protocol](https://github.com/irungentoo/ProjectTox-Core/wiki/Lossless-UDP)<br />
46[Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br /> 50[Crypto](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto)<br />
47[Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas) 51[Ideas](https://github.com/irungentoo/ProjectTox-Core/wiki/Ideas)
48
49### Why are you doing this? There are already a bunch of free skype alternatives.
50The goal of this project is to create a configuration-free p2p skype
51replacement. Configuration-free means that the user will simply have to open the program and
52without any account configuration will be capable of adding people to his
53friends list and start conversing with them. There are many so called skype replacements and all of them are either hard to
54configure for the normal user or suffer from being much too centralized.
diff --git a/cmake/FindLIBCONFIG.cmake b/cmake/FindLIBCONFIG.cmake
new file mode 100644
index 00000000..d5018240
--- /dev/null
+++ b/cmake/FindLIBCONFIG.cmake
@@ -0,0 +1,15 @@
1# Find LIBCONFIG
2#
3# LIBCONFIG_INCLUDE_DIR
4# LIBCONFIG_LIBRARY
5# LIBCONFIG_FOUND
6#
7
8FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h)
9
10FIND_LIBRARY(LIBCONFIG_LIBRARY NAMES config)
11
12INCLUDE(FindPackageHandleStandardArgs)
13FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBCONFIG DEFAULT_MSG LIBCONFIG_LIBRARY LIBCONFIG_INCLUDE_DIR)
14
15MARK_AS_ADVANCED(LIBCONFIG_INCLUDE_DIR LIBCONFIG_LIBRARY)
diff --git a/cmake/FindNaCl.cmake b/cmake/FindNaCl.cmake
new file mode 100644
index 00000000..cdd6248a
--- /dev/null
+++ b/cmake/FindNaCl.cmake
@@ -0,0 +1,17 @@
1find_path(NACL_INCLUDE_DIR crypto_box.h
2 $ENV{NACL_INCLUDE_DIR} /usr/include/nacl/
3 DOC "Directory which contain NaCl headers")
4
5find_path(NACL_LIBRARY_DIR libnacl.a
6 $ENV{NACL_LIBRARY_DIR} /usr/lib/nacl
7 DOC "Directory which contain libnacl.a, cpucycles.o, and randombytes.o")
8
9if(NACL_LIBRARY_DIR)
10 set(NACL_LIBRARIES
11 "${NACL_LIBRARY_DIR}/cpucycles.o"
12 "${NACL_LIBRARY_DIR}/libnacl.a"
13 "${NACL_LIBRARY_DIR}/randombytes.o")
14endif()
15
16include(FindPackageHandleStandardArgs)
17find_package_handle_standard_args(NaCl DEFAULT_MSG NACL_INCLUDE_DIR NACL_LIBRARY_DIR NACL_LIBRARIES)
diff --git a/cmake/FindSODIUM.cmake b/cmake/FindSODIUM.cmake
new file mode 100644
index 00000000..ffb6a1f7
--- /dev/null
+++ b/cmake/FindSODIUM.cmake
@@ -0,0 +1,15 @@
1# Find SODIUM
2#
3# SODIUM_INCLUDE_DIR
4# SODIUM_LIBRARY
5# SODIUM_FOUND
6#
7
8FIND_PATH(SODIUM_INCLUDE_DIR NAMES sodium.h)
9
10FIND_LIBRARY(SODIUM_LIBRARY NAMES sodium)
11
12INCLUDE(FindPackageHandleStandardArgs)
13FIND_PACKAGE_HANDLE_STANDARD_ARGS(SODIUM DEFAULT_MSG SODIUM_LIBRARY SODIUM_INCLUDE_DIR)
14
15MARK_AS_ADVANCED(SODIUM_INCLUDE_DIR SODIUM_LIBRARY)
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 6ddd5b9b..44ae980c 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -3,15 +3,17 @@ project(core C)
3 3
4if(WIN32) 4if(WIN32)
5 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/) 5 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
6else(WIN32)
7 include_directories(${SODIUM_INCLUDE_DIR})
6endif() 8endif()
7 9
8set(core_sources 10set(core_sources
9 DHT.c 11 DHT.c
10 network.c 12 network.c
11 Lossless_UDP.c 13 Lossless_UDP.c
12 net_crypto.c 14 net_crypto.c
13 friend_requests.c 15 friend_requests.c
14 LAN_discovery.c 16 LAN_discovery.c
15 Messenger.c) 17 Messenger.c)
16 18
17add_library(core ${core_sources}) 19add_library(core ${core_sources})
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 d7770dfe..eb59b81a 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;
@@ -165,7 +168,7 @@ int m_delfriend(int friendnumber)
165 uint32_t i; 168 uint32_t i;
166 169
167 for (i = numfriends; i != 0; --i) { 170 for (i = numfriends; i != 0; --i) {
168 if (friendlist[i].status != 0) 171 if (friendlist[i-1].status != 0)
169 break; 172 break;
170 } 173 }
171 numfriends = i; 174 numfriends = i;
@@ -180,7 +183,7 @@ int m_delfriend(int friendnumber)
180 return 0 if there is no friend with that number */ 183 return 0 if there is no friend with that number */
181int m_friendstatus(int friendnumber) 184int m_friendstatus(int friendnumber)
182{ 185{
183 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 186 if (friendnumber < 0 || friendnumber >= numfriends)
184 return 0; 187 return 0;
185 return friendlist[friendnumber].status; 188 return friendlist[friendnumber].status;
186} 189}
@@ -190,7 +193,7 @@ int m_friendstatus(int friendnumber)
190 return 0 if it was not */ 193 return 0 if it was not */
191int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) 194int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
192{ 195{
193 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 196 if (friendnumber < 0 || friendnumber >= numfriends)
194 return 0; 197 return 0;
195 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) 198 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
196 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 199 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
@@ -242,6 +245,16 @@ int setname(uint8_t * name, uint16_t length)
242 return 0; 245 return 0;
243} 246}
244 247
248/* get our nickname
249 put it in name
250 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
251 return the length of the name */
252uint16_t getself_name(uint8_t *name)
253{
254 memcpy(name, self_name, self_name_length);
255 return self_name_length;
256}
257
245/* get name of friendnumber 258/* get name of friendnumber
246 put it in name 259 put it in name
247 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 260 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/core/friend_requests.h b/core/friend_requests.h
index e38f7edc..4dfc5130 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -48,4 +48,4 @@ int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
48} 48}
49#endif 49#endif
50 50
51#endif \ No newline at end of file 51#endif
diff --git a/core/network.c b/core/network.c
index aa16bda9..a7a4efcd 100644
--- a/core/network.c
+++ b/core/network.c
@@ -169,7 +169,7 @@ void shutdown_networking()
169 address should represent IPv4, IPv6 or a hostname 169 address should represent IPv4, IPv6 or a hostname
170 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i 170 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i
171 on failure returns -1 */ 171 on failure returns -1 */
172int resolve_addr(char *address) 172int resolve_addr(const char *address)
173{ 173{
174 struct addrinfo hints; 174 struct addrinfo hints;
175 memset(&hints, 0, sizeof(hints)); 175 memset(&hints, 0, sizeof(hints));
@@ -178,7 +178,7 @@ int resolve_addr(char *address)
178 178
179 struct addrinfo *server = NULL; 179 struct addrinfo *server = NULL;
180 180
181 int success = getaddrinfo(address, "7", &hints, &server); 181 int success = getaddrinfo(address, "echo", &hints, &server);
182 if(success != 0) 182 if(success != 0)
183 return -1; 183 return -1;
184 184
diff --git a/core/network.h b/core/network.h
index aaaaa409..3277070c 100644
--- a/core/network.h
+++ b/core/network.h
@@ -56,11 +56,7 @@
56/* we use libsodium by default */ 56/* we use libsodium by default */
57#include <sodium.h> 57#include <sodium.h>
58#else 58#else
59 59#include <crypto_box.h>
60/* TODO: Including stuff like this is bad. This needs fixing.
61 We keep support for the original NaCl for now. */
62#include "../nacl/build/Linux/include/amd64/crypto_box.h"
63
64#endif 60#endif
65 61
66#ifdef __cplusplus 62#ifdef __cplusplus
@@ -125,7 +121,7 @@ void shutdown_networking();
125 address should represent IPv4, IPv6 or a hostname 121 address should represent IPv4, IPv6 or a hostname
126 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i 122 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i
127 on failure returns -1 */ 123 on failure returns -1 */
128int resolve_addr(char *address); 124int resolve_addr(const char *address);
129 125
130#ifdef __cplusplus 126#ifdef __cplusplus
131} 127}
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 6aa4dbee..512179f3 100644
--- a/other/bootstrap_serverdaemon/CMakeLists.txt
+++ b/other/bootstrap_serverdaemon/CMakeLists.txt
@@ -3,8 +3,17 @@ project(DHT_bootstrap_daemon C)
3 3
4set(exe_name DHT_bootstrap_daemon) 4set(exe_name DHT_bootstrap_daemon)
5 5
6find_package(LIBCONFIG REQUIRED)
7
8include_directories(${LIBCONFIG_INCLUDE_DIR})
9
6add_executable(${exe_name} 10add_executable(${exe_name}
7 DHT_bootstrap_daemon.c) 11 DHT_bootstrap_daemon.c)
12
13target_link_libraries(${exe_name}
14 ${LIBCONFIG_LIBRARY})
8 15
9target_link_libraries(${exe_name} config)
10linkCoreLibraries(${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/other/cmake/DHT_bootstrap.cmake b/other/cmake/DHT_bootstrap.cmake
index e2b164ba..403522ab 100644
--- a/other/cmake/DHT_bootstrap.cmake
+++ b/other/cmake/DHT_bootstrap.cmake
@@ -4,6 +4,7 @@ project(DHT_bootstrap C)
4set(exe_name DHT_bootstrap) 4set(exe_name DHT_bootstrap)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 DHT_bootstrap.c ../testing/misc_tools.c) 7 DHT_bootstrap.c
8 ../testing/misc_tools.c)
8 9
9linkCoreLibraries(${exe_name}) 10linkCoreLibraries(${exe_name})
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/CMakeLists.txt b/testing/CMakeLists.txt
index 988efe42..abbc278e 100644
--- a/testing/CMakeLists.txt
+++ b/testing/CMakeLists.txt
@@ -11,8 +11,8 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake)
11if(WIN32) 11if(WIN32)
12 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) 12 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake)
13endif() 13endif()
14
14if(NOT WIN32) 15if(NOT WIN32)
15 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake) 16 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake)
16include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/toxic.cmake) 17 add_subdirectory(toxic)
17
18endif() 18endif()
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/DHT_test.c b/testing/DHT_test.c
index 2e9c2ac2..588450e2 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -87,7 +87,7 @@ void print_friendlist()
87 for(i = 0; i < 4; i++) { 87 for(i = 0; i < 4; i++) {
88 printf("ClientID: "); 88 printf("ClientID: ");
89 for(j = 0; j < 32; j++) { 89 for(j = 0; j < 32; j++) {
90 if(0 <= friends_list[k].client_list[i].client_id[j] && friends_list[k].client_list[i].client_id[j] < 16) 90 if(friends_list[k].client_list[i].client_id[j] < 16)
91 printf("0"); 91 printf("0");
92 printf("%hhX", friends_list[k].client_list[i].client_id[j]); 92 printf("%hhX", friends_list[k].client_list[i].client_id[j]);
93 } 93 }
@@ -134,7 +134,9 @@ int main(int argc, char *argv[])
134 134
135 char temp_id[128]; 135 char temp_id[128];
136 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); 136 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
137 scanf("%s", temp_id); 137 if(scanf("%s", temp_id) != 1)
138 exit(0);
139
138 DHT_addfriend(hex_string_to_bin(temp_id)); 140 DHT_addfriend(hex_string_to_bin(temp_id));
139 141
140 /* initialize networking */ 142 /* initialize networking */
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c
index c1eaa69d..b96756ab 100644
--- a/testing/Lossless_UDP_testclient.c
+++ b/testing/Lossless_UDP_testclient.c
@@ -211,4 +211,4 @@ int main(int argc, char *argv[])
211 } 211 }
212 212
213 return 0; 213 return 0;
214} \ No newline at end of file 214}
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c
index 4b437f0e..29b0ade5 100644
--- a/testing/Lossless_UDP_testserver.c
+++ b/testing/Lossless_UDP_testserver.c
@@ -198,4 +198,4 @@ int main(int argc, char *argv[])
198 } 198 }
199 199
200 return 0; 200 return 0;
201} \ No newline at end of file 201}
diff --git a/testing/cmake/DHT_cryptosendfiletest.cmake b/testing/cmake/DHT_cryptosendfiletest.cmake
index c98a2bcd..5470d02a 100644
--- a/testing/cmake/DHT_cryptosendfiletest.cmake
+++ b/testing/cmake/DHT_cryptosendfiletest.cmake
@@ -4,6 +4,7 @@ project(DHT_cryptosendfiletest C)
4set(exe_name DHT_cryptosendfiletest) 4set(exe_name DHT_cryptosendfiletest)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 DHT_cryptosendfiletest.c misc_tools.c) 7 DHT_cryptosendfiletest.c
8 misc_tools.c)
8 9
9linkCoreLibraries(${exe_name}) 10linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/DHT_sendfiletest.cmake b/testing/cmake/DHT_sendfiletest.cmake
index 93737914..298db46c 100644
--- a/testing/cmake/DHT_sendfiletest.cmake
+++ b/testing/cmake/DHT_sendfiletest.cmake
@@ -4,6 +4,6 @@ project(DHT_sendfiletest C)
4set(exe_name DHT_sendfiletest) 4set(exe_name DHT_sendfiletest)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 DHT_sendfiletest.c) 7 DHT_sendfiletest.c)
8 8
9linkCoreLibraries(${exe_name}) 9linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/DHT_test.cmake b/testing/cmake/DHT_test.cmake
index 74fdf35d..bb5bf05f 100644
--- a/testing/cmake/DHT_test.cmake
+++ b/testing/cmake/DHT_test.cmake
@@ -4,6 +4,7 @@ project(DHT_test C)
4set(exe_name DHT_test) 4set(exe_name DHT_test)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 DHT_test.c misc_tools.c) 7 DHT_test.c
8 misc_tools.c)
8 9
9linkCoreLibraries(${exe_name}) 10linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/Lossless_UDP_testclient.cmake b/testing/cmake/Lossless_UDP_testclient.cmake
index e894d228..5f651807 100644
--- a/testing/cmake/Lossless_UDP_testclient.cmake
+++ b/testing/cmake/Lossless_UDP_testclient.cmake
@@ -4,6 +4,6 @@ project(Lossless_UDP_testclient C)
4set(exe_name Lossless_UDP_testclient) 4set(exe_name Lossless_UDP_testclient)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 Lossless_UDP_testclient.c) 7 Lossless_UDP_testclient.c)
8 8
9linkCoreLibraries(${exe_name}) 9linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/Lossless_UDP_testserver.cmake b/testing/cmake/Lossless_UDP_testserver.cmake
index 04306c1a..26f9302e 100644
--- a/testing/cmake/Lossless_UDP_testserver.cmake
+++ b/testing/cmake/Lossless_UDP_testserver.cmake
@@ -4,6 +4,6 @@ project(Lossless_UDP_testserver C)
4set(exe_name Lossless_UDP_testserver) 4set(exe_name Lossless_UDP_testserver)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 Lossless_UDP_testserver.c) 7 Lossless_UDP_testserver.c)
8 8
9linkCoreLibraries(${exe_name}) 9linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/Messenger_test.cmake b/testing/cmake/Messenger_test.cmake
index b2f54d0a..15fcd77b 100644
--- a/testing/cmake/Messenger_test.cmake
+++ b/testing/cmake/Messenger_test.cmake
@@ -4,6 +4,6 @@ project(Messenger_test C)
4set(exe_name Messenger_test) 4set(exe_name Messenger_test)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 Messenger_test.c misc_tools.c) 7 Messenger_test.c misc_tools.c)
8 8
9linkCoreLibraries(${exe_name}) 9linkCoreLibraries(${exe_name})
diff --git a/testing/cmake/nTox.cmake b/testing/cmake/nTox.cmake
index 4c6905e5..44476b8f 100644
--- a/testing/cmake/nTox.cmake
+++ b/testing/cmake/nTox.cmake
@@ -4,8 +4,9 @@ project(nTox C)
4set(exe_name nTox) 4set(exe_name nTox)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 nTox.c misc_tools.c) 7 nTox.c misc_tools.c)
8 8
9target_link_libraries(${exe_name} ncurses) 9target_link_libraries(${exe_name}
10 ncurses)
10 11
11linkCoreLibraries(${exe_name}) 12linkCoreLibraries(${exe_name})
diff --git a/testing/misc_tools.h b/testing/misc_tools.h
index 29b37ce5..5079e15d 100644
--- a/testing/misc_tools.h
+++ b/testing/misc_tools.h
@@ -26,4 +26,4 @@
26 26
27unsigned char * hex_string_to_bin(char hex_string[]); 27unsigned char * hex_string_to_bin(char hex_string[]);
28 28
29#endif // MISC_TOOLS_H \ No newline at end of file 29#endif // MISC_TOOLS_H
diff --git a/testing/nTox.c b/testing/nTox.c
index 960dfb27..7c84871f 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -20,12 +20,12 @@
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
24#include "nTox.h" 23#include "nTox.h"
25#include "misc_tools.h" 24#include "misc_tools.h"
26 25
27#include <stdio.h> 26#include <stdio.h>
28#include <time.h> 27#include <time.h>
28
29#ifdef WIN32 29#ifdef WIN32
30#define c_sleep(x) Sleep(1*x) 30#define c_sleep(x) Sleep(1*x)
31#else 31#else
@@ -35,31 +35,75 @@
35 35
36char lines[HISTORY][STRING_LENGTH]; 36char lines[HISTORY][STRING_LENGTH];
37char line[STRING_LENGTH]; 37char line[STRING_LENGTH];
38int x,y; 38
39char *help = "[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)\n"
40 "[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)";
41int x, y;
42
39 43
40uint8_t pending_requests[256][CLIENT_ID_SIZE]; 44uint8_t pending_requests[256][CLIENT_ID_SIZE];
41uint8_t num_requests; 45uint8_t num_requests = 0;
42 46
43void new_lines(char *line) 47void new_lines(char *line)
44{ 48{
45 int i; 49 int i;
46 for (i = HISTORY-1; i > 0; i--) 50 for (i = HISTORY-1; i > 0; i--)
47 strcpy(lines[i],lines[i-1]); 51 strcpy(lines[i], lines[i-1]);
48 52
49 strcpy(lines[0],line); 53 strcpy(lines[0], line);
50 do_refresh(); 54 do_refresh();
51} 55}
52 56
57
58void print_friendlist()
59{
60 char name[MAX_NAME_LENGTH];
61 new_lines("[i] Friend List:");
62 uint32_t i;
63 for (i = 0; i <= num_requests; i++) {
64 char fstring[128];
65 getname(i, (uint8_t*)name);
66 if (strlen(name) <= 0) {
67 sprintf(fstring, "[i] Friend: NULL\n\tid: %i", i);
68 } else {
69 sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t*)name, i);
70 }
71 new_lines(fstring);
72 }
73}
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
85 time_t rawtime;
86 struct tm * timeinfo;
87 time ( &rawtime );
88 timeinfo = localtime ( &rawtime );
89 char* time = asctime(timeinfo);
90 size_t len = strlen(time);
91 time[len-1] = '\0';
92 sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); // timestamp
93 return msg;
94}
95
53void line_eval(char lines[HISTORY][STRING_LENGTH], char *line) 96void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
54{ 97{
55 if (line[0] == '/') { 98 if (line[0] == '/') {
56 char command[STRING_LENGTH + 2] = "> "; 99 char inpt_command = line[1];
57 strcat(command, line); 100 char prompt[STRING_LENGTH + 2] = "> ";
58 new_lines(command); 101 strcat(prompt, line);
59 if (line[1] == 'f') { // add friend command: /f ID 102 new_lines(prompt);
103 if (inpt_command == 'f') { // add friend command: /f ID
60 int i; 104 int i;
61 char temp_id[128]; 105 char temp_id[128];
62 for (i=0; i<128; i++) 106 for (i = 0; i < 128; i++)
63 temp_id[i] = line[i+3]; 107 temp_id[i] = line[i+3];
64 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 108 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
65 char numstring[100]; 109 char numstring[100];
@@ -67,82 +111,121 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
67 new_lines(numstring); 111 new_lines(numstring);
68 do_refresh(); 112 do_refresh();
69 } 113 }
70 else if (line[1] == 'd') { 114 else if (inpt_command == 'd') {
71 doMessenger(); 115 doMessenger();
72 } 116 }
73 else if (line[1] == 'm') { //message command: /m friendnumber messsage 117 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
74 int i;
75 size_t len = strlen(line); 118 size_t len = strlen(line);
76 char numstring[len-3]; 119 char numstring[len-3];
77 char message[len-3]; 120 char message[len-3];
78 for (i=0; i<len; i++) { 121 int i;
122 for (i = 0; i < len; i++) {
79 if (line[i+3] != ' ') { 123 if (line[i+3] != ' ') {
80 numstring[i] = line[i+3]; 124 numstring[i] = line[i+3];
81 } else { 125 } else {
82 int j; 126 int j;
83 for (j=i+1; j<len; j++) 127 for (j = (i+1); j < len; j++)
84 message[j-i-1] = line[j+3]; 128 message[j-i-1] = line[j+3];
85 break; 129 break;
86 } 130 }
87 } 131 }
88 int num = atoi(numstring); 132 int num = atoi(numstring);
89 if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) { 133 if (m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) {
90 new_lines("[i] could not send message"); 134 new_lines("[i] could not send message");
135 } else {
136 new_lines(format_message(message, -1));
91 } 137 }
92 } 138 }
93 else if (line[1] == 'n') { 139 else if (inpt_command == 'n') {
94 uint8_t name[MAX_NAME_LENGTH]; 140 uint8_t name[MAX_NAME_LENGTH];
95 int i = 0; 141 int i = 0;
96 size_t len = strlen(line); 142 size_t len = strlen(line);
97 for (i=3; i<len; i++) { 143 for (i = 3; i < len; i++) {
98 if (line[i] == 0 || line[i] == '\n') break; 144 if (line[i] == 0 || line[i] == '\n') break;
99 name[i - 3] = line[i]; 145 name[i-3] = line[i];
100 } 146 }
101 name[i - 3] = 0; 147 name[i-3] = 0;
102 setname(name, i); 148 setname(name, i);
103 char numstring[100]; 149 char numstring[100];
104 sprintf(numstring, "[i] changed nick to %s", (char*)name); 150 sprintf(numstring, "[i] changed nick to %s", (char*)name);
105 new_lines(numstring); 151 new_lines(numstring);
106 } 152 }
107 else if (line[1] == 's') { 153 else if (inpt_command == 'l') {
154 print_friendlist();
155 }
156 else if (inpt_command == 's') {
108 uint8_t status[MAX_USERSTATUS_LENGTH]; 157 uint8_t status[MAX_USERSTATUS_LENGTH];
109 int i = 0; 158 int i = 0;
110 size_t len = strlen(line); 159 size_t len = strlen(line);
111 for (i=3; i<len; i++) { 160 for (i = 3; i < len; i++) {
112 if (line[i] == 0 || line[i] == '\n') break; 161 if (line[i] == 0 || line[i] == '\n') break;
113 status[i - 3] = line[i]; 162 status[i-3] = line[i];
114 } 163 }
115 status[i - 3] = 0; 164 status[i-3] = 0;
116 m_set_userstatus(status, strlen((char*)status)); 165 m_set_userstatus(status, strlen((char*)status));
117 char numstring[100]; 166 char numstring[100];
118 sprintf(numstring, "[i] changed status to %s", (char*)status); 167 sprintf(numstring, "[i] changed status to %s", (char*)status);
119 new_lines(numstring); 168 new_lines(numstring);
120 } 169 }
121 else if (line[1] == 'a') { 170 else if (inpt_command == 'a') {
122 uint8_t numf = atoi(line + 3); 171 uint8_t numf = atoi(line + 3);
123 char numchar[100]; 172 char numchar[100];
124 sprintf(numchar, "[i] friend request %u accepted", numf);
125 new_lines(numchar);
126 int num = m_addfriend_norequest(pending_requests[numf]); 173 int num = m_addfriend_norequest(pending_requests[numf]);
127 sprintf(numchar, "[i] added friendnumber %d", num); 174 if (num != -1) {
128 new_lines(numchar); 175 sprintf(numchar, "[i] friend request %u accepted", numf);
176 new_lines(numchar);
177 sprintf(numchar, "[i] added friendnumber %d", num);
178 new_lines(numchar);
179 } else {
180 sprintf(numchar, "[i] failed to add friend");
181 new_lines(numchar);
182 }
129 do_refresh(); 183 do_refresh();
130
131 } 184 }
132 else if (line[1] == 'q') { //exit 185 else if (inpt_command == 'h') { //help
186 new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)");
187 new_lines("[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)");
188 }
189 else if (inpt_command == 'i') { //info
190 char idstring0[200];
191 char idstring1[PUB_KEY_BYTES][5];
192 char idstring2[PUB_KEY_BYTES][5];
193 int i;
194 for (i = 0; i < PUB_KEY_BYTES; i++)
195 {
196 if (self_public_key[i] < (PUB_KEY_BYTES/2))
197 strcpy(idstring1[i],"0");
198 else
199 strcpy(idstring1[i], "");
200 sprintf(idstring2[i], "%hhX", self_public_key[i]);
201 }
202 //
203 strcpy(idstring0,"[i] ID: ");
204 int j;
205 for (j = 0; j < PUB_KEY_BYTES; j++) {
206 strcat(idstring0,idstring1[j]);
207 strcat(idstring0,idstring2[j]);
208 }
209 new_lines(idstring0);
210 }
211
212 else if (inpt_command == 'q') { //exit
133 endwin(); 213 endwin();
134 exit(EXIT_SUCCESS); 214 exit(EXIT_SUCCESS);
215 } else {
216 new_lines("[i] invalid command");
135 } 217 }
136 } else { 218 } else {
219 new_lines("[i] invalid command");
137 //new_lines(line); 220 //new_lines(line);
138 } 221 }
139} 222}
140 223
141void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) 224void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
142{ 225{
143 int i = 0;
144 strcpy(output,input); 226 strcpy(output,input);
145 size_t len = strlen(output); 227 size_t len = strlen(output);
228 int i = 0;
146 for (i = line_width; i < len; i = i + line_width) { 229 for (i = line_width; i < len; i = i + line_width) {
147 while (output[i] != ' ' && i != 0) { 230 while (output[i] != ' ' && i != 0) {
148 i--; 231 i--;
@@ -156,9 +239,9 @@ void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
156int count_lines(char *string) 239int count_lines(char *string)
157{ 240{
158 size_t len = strlen(string); 241 size_t len = strlen(string);
159 int i;
160 int count = 1; 242 int count = 1;
161 for (i=0; i < len; i++) { 243 int i;
244 for (i = 0; i < len; i++) {
162 if (string[i] == '\n') 245 if (string[i] == '\n')
163 count++; 246 count++;
164 } 247 }
@@ -169,7 +252,7 @@ char *appender(char *str, const char c)
169{ 252{
170 size_t len = strlen(str); 253 size_t len = strlen(str);
171 if (len < STRING_LENGTH) { 254 if (len < STRING_LENGTH) {
172 str[len + 1] = str[len]; 255 str[len+1] = str[len];
173 str[len] = c; 256 str[len] = c;
174 } 257 }
175 return str; 258 return str;
@@ -177,21 +260,21 @@ char *appender(char *str, const char c)
177 260
178void do_refresh() 261void do_refresh()
179{ 262{
180 int i;
181 int count=0; 263 int count=0;
182 int l;
183 char wrap_output[STRING_LENGTH]; 264 char wrap_output[STRING_LENGTH];
184 for (i=0; i<HISTORY; i++) { 265 int L;
266 int i;
267 for (i = 0; i < HISTORY; i++) {
185 wrap(wrap_output, lines[i], x); 268 wrap(wrap_output, lines[i], x);
186 l = count_lines(wrap_output); 269 L = count_lines(wrap_output);
187 count = count + l; 270 count = count + L;
188 if (count < y) { 271 if (count < y) {
189 move(y-1-count,0); 272 move(y-1-count, 0);
190 printw(wrap_output); 273 printw(wrap_output);
191 clrtoeol(); 274 clrtoeol();
192 } 275 }
193 } 276 }
194 move(y-1,0); 277 move(y-1, 0);
195 clrtoeol(); 278 clrtoeol();
196 printw(">> "); 279 printw(">> ");
197 printw(line); 280 printw(line);
@@ -222,12 +305,13 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
222 timeinfo = localtime ( &rawtime ); 305 timeinfo = localtime ( &rawtime );
223 char* temp = asctime(timeinfo); 306 char* temp = asctime(timeinfo);
224 size_t len = strlen(temp); 307 size_t len = strlen(temp);
225 temp[len-1]='\0'; 308 temp[len-1] = '\0';
226 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp 309 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp
227 new_lines(msg); 310 new_lines(format_message((char*)string, friendnumber));
228} 311}
229 312
230void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) { 313void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
314{
231 char name[MAX_NAME_LENGTH]; 315 char name[MAX_NAME_LENGTH];
232 getname(friendnumber, (uint8_t*)name); 316 getname(friendnumber, (uint8_t*)name);
233 char msg[100+length]; 317 char msg[100+length];
@@ -235,7 +319,8 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) {
235 new_lines(msg); 319 new_lines(msg);
236} 320}
237 321
238void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) { 322void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
323{
239 char name[MAX_NAME_LENGTH]; 324 char name[MAX_NAME_LENGTH];
240 getname(friendnumber, (uint8_t*)name); 325 getname(friendnumber, (uint8_t*)name);
241 char msg[100+length+strlen(name)+1]; 326 char msg[100+length+strlen(name)+1];
@@ -243,15 +328,17 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) {
243 new_lines(msg); 328 new_lines(msg);
244} 329}
245 330
246void load_key(){ 331void load_key()
332{
247 FILE *data_file = NULL; 333 FILE *data_file = NULL;
248 if ((data_file = fopen("data","r"))) { 334 data_file = fopen("data","r");
335 if (data_file) {
249 //load keys 336 //load keys
250 fseek(data_file, 0, SEEK_END); 337 fseek(data_file, 0, SEEK_END);
251 int size = ftell(data_file); 338 int size = ftell(data_file);
252 fseek(data_file, 0, SEEK_SET); 339 fseek(data_file, 0, SEEK_SET);
253 uint8_t data[size]; 340 uint8_t data[size];
254 if(fread(data, sizeof(uint8_t), size, data_file) != size){ 341 if (fread(data, sizeof(uint8_t), size, data_file) != size){
255 printf("[i] could not read data file\n[i] exiting\n"); 342 printf("[i] could not read data file\n[i] exiting\n");
256 exit(1); 343 exit(1);
257 } 344 }
@@ -262,7 +349,7 @@ void load_key(){
262 uint8_t data[size]; 349 uint8_t data[size];
263 Messenger_save(data); 350 Messenger_save(data);
264 data_file = fopen("data","w"); 351 data_file = fopen("data","w");
265 if(fwrite(data, sizeof(uint8_t), size, data_file) != size){ 352 if (fwrite(data, sizeof(uint8_t), size, data_file) != size){
266 printf("[i] could not write data file\n[i] exiting\n"); 353 printf("[i] could not write data file\n[i] exiting\n");
267 exit(1); 354 exit(1);
268 } 355 }
@@ -292,28 +379,29 @@ int main(int argc, char *argv[])
292 m_callback_namechange(print_nickchange); 379 m_callback_namechange(print_nickchange);
293 m_callback_userstatus(print_statuschange); 380 m_callback_userstatus(print_statuschange);
294 char idstring0[200]; 381 char idstring0[200];
295 char idstring1[32][5]; 382 char idstring1[PUB_KEY_BYTES][5];
296 char idstring2[32][5]; 383 char idstring2[PUB_KEY_BYTES][5];
297 uint32_t i; 384 int i;
298 for(i = 0; i < 32; i++) 385 for(i = 0; i < PUB_KEY_BYTES; i++)
299 { 386 {
300 if(self_public_key[i] < 16) 387 if (self_public_key[i] < (PUB_KEY_BYTES / 2))
301 strcpy(idstring1[i],"0"); 388 strcpy(idstring1[i],"0");
302 else 389 else
303 strcpy(idstring1[i], ""); 390 strcpy(idstring1[i], "");
304 sprintf(idstring2[i], "%hhX",self_public_key[i]); 391 sprintf(idstring2[i], "%hhX",self_public_key[i]);
305 } 392 }
306 strcpy(idstring0,"[i] your ID: "); 393 strcpy(idstring0,"[i] your ID: ");
307 for (i=0; i<32; i++) { 394 int j;
308 strcat(idstring0,idstring1[i]); 395 for (j = 0; j < PUB_KEY_BYTES; j++) {
309 strcat(idstring0,idstring2[i]); 396 strcat(idstring0,idstring1[j]);
397 strcat(idstring0,idstring2[j]);
310 } 398 }
311 initscr(); 399 initscr();
312 noecho(); 400 noecho();
313 raw(); 401 raw();
314 getmaxyx(stdscr,y,x); 402 getmaxyx(stdscr, y, x);
315 new_lines(idstring0); 403 new_lines(idstring0);
316 new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status), /n nick (to change nickname), /q (to quit)"); 404 new_lines(help);
317 strcpy(line, ""); 405 strcpy(line, "");
318 IP_Port bootstrap_ip_port; 406 IP_Port bootstrap_ip_port;
319 bootstrap_ip_port.port = htons(atoi(argv[2])); 407 bootstrap_ip_port.port = htons(atoi(argv[2]));
@@ -336,7 +424,6 @@ int main(int argc, char *argv[])
336 do_refresh(); 424 do_refresh();
337 425
338 c = getch(); 426 c = getch();
339
340 if (c == ERR || c == 27) 427 if (c == ERR || c == 27)
341 continue; 428 continue;
342 429
@@ -345,7 +432,7 @@ int main(int argc, char *argv[])
345 line_eval(lines, line); 432 line_eval(lines, line);
346 strcpy(line, ""); 433 strcpy(line, "");
347 } else if (c == 127) { 434 } else if (c == 127) {
348 line[strlen(line) - 1] = '\0'; 435 line[strlen(line)-1] = '\0';
349 } else if (isalnum(c) || ispunct(c) || c == ' ') { 436 } else if (isalnum(c) || ispunct(c) || c == ' ') {
350 strcpy(line, appender(line, (char) c)); 437 strcpy(line, appender(line, (char) c));
351 } 438 }
diff --git a/testing/nTox.h b/testing/nTox.h
index 9b69d959..9d82556c 100644
--- a/testing/nTox.h
+++ b/testing/nTox.h
@@ -39,6 +39,7 @@
39#include "../core/network.h" 39#include "../core/network.h"
40#define STRING_LENGTH 256 40#define STRING_LENGTH 256
41#define HISTORY 50 41#define HISTORY 50
42#define PUB_KEY_BYTES 32
42 43
43void new_lines(char *line); 44void new_lines(char *line);
44void line_eval(char lines[HISTORY][STRING_LENGTH], char *line); 45void line_eval(char lines[HISTORY][STRING_LENGTH], char *line);
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
index 514ce463..ad114f46 100644
--- a/testing/nTox_win32.c
+++ b/testing/nTox_win32.c
@@ -27,7 +27,7 @@
27#include <process.h> 27#include <process.h>
28 28
29uint8_t pending_requests[256][CLIENT_ID_SIZE]; 29uint8_t pending_requests[256][CLIENT_ID_SIZE];
30uint8_t num_requests; 30uint8_t num_requests = 0;
31 31
32char line[STRING_LENGTH]; 32char line[STRING_LENGTH];
33char users_id[200]; 33char users_id[200];
@@ -89,14 +89,13 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
89void load_key() 89void load_key()
90{ 90{
91 FILE *data_file = NULL; 91 FILE *data_file = NULL;
92 92 data_file = fopen("data","r");
93 if ((data_file = fopen("data", "r"))) { 93 if (data_file) {
94 fseek(data_file, 0, SEEK_END); 94 fseek(data_file, 0, SEEK_END);
95 int size = ftell(data_file); 95 int size = ftell(data_file);
96 fseek(data_file, 0, SEEK_SET); 96 fseek(data_file, 0, SEEK_SET);
97 uint8_t data[size]; 97 uint8_t data[size];
98 98 if (fread(data, sizeof(uint8_t), size, data_file) != size) {
99 if(fread(data, sizeof(uint8_t), size, data_file) != size) {
100 printf("\n[i] Could not read the data file. Exiting."); 99 printf("\n[i] Could not read the data file. Exiting.");
101 exit(1); 100 exit(1);
102 } 101 }
@@ -108,23 +107,23 @@ void load_key()
108 Messenger_save(data); 107 Messenger_save(data);
109 data_file = fopen("data", "w"); 108 data_file = fopen("data", "w");
110 109
111 if(fwrite(data, sizeof(uint8_t), size, data_file) != size) { 110 if (fwrite(data, sizeof(uint8_t), size, data_file) != size) {
112 printf("\n[i] Could not write data to file. Exiting."); 111 printf("\n[i] Could not write data to file. Exiting.");
113 exit(1); 112 exit(1);
114 } 113 }
115 } 114 }
116
117 fclose(data_file); 115 fclose(data_file);
118} 116}
119 117
120void line_eval(char* line) 118void line_eval(char* line)
121{ 119{
122 if(line[0] == '/') { 120 if(line[0] == '/') {
121 char inpt_command = line[1];
123 /* Add friend */ 122 /* Add friend */
124 if(line[1] == 'f') { 123 if(inpt_command == 'f') {
125 int i; 124 int i;
126 char temp_id[128]; 125 char temp_id[128];
127 for (i=0; i<128; i++) 126 for (i = 0; i < 128; i++)
128 temp_id[i] = line[i+3]; 127 temp_id[i] = line[i+3];
129 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 128 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
130 char numstring[100]; 129 char numstring[100];
@@ -132,17 +131,16 @@ void line_eval(char* line)
132 printf(numstring); 131 printf(numstring);
133 } 132 }
134 133
135 else if (line[1] == 'r') { 134 else if (inpt_command == 'r') {
136 do_header(); 135 do_header();
137 printf("\n\n"); 136 printf("\n\n");
138 } 137 }
139 138
140 else if (line[1] == 'l') { 139 else if (inpt_command == 'l') {
141 printf("\n[i] Friend List | Total: %d\n\n", getnumfriends()); 140 printf("\n[i] Friend List | Total: %d\n\n", getnumfriends());
142 141
143 int i; 142 int i;
144 143 for (i = 0; i < getnumfriends(); i++) {
145 for (i=0; i < getnumfriends(); i++) {
146 char name[MAX_NAME_LENGTH]; 144 char name[MAX_NAME_LENGTH];
147 getname(i, (uint8_t*)name); 145 getname(i, (uint8_t*)name);
148 if (m_friendstatus(i) == 0) 146 if (m_friendstatus(i) == 0)
@@ -152,11 +150,11 @@ void line_eval(char* line)
152 } 150 }
153 } 151 }
154 152
155 else if (line[1] == 'd') { 153 else if (inpt_command == 'd') {
156 size_t len = strlen(line); 154 size_t len = strlen(line);
157 char numstring[len-3]; 155 char numstring[len-3];
158 int i; 156 int i;
159 for (i=0; i<len; i++) { 157 for (i = 0; i < len; i++) {
160 if (line[i+3] != ' ') { 158 if (line[i+3] != ' ') {
161 numstring[i] = line[i+3]; 159 numstring[i] = line[i+3];
162 } 160 }
@@ -166,17 +164,17 @@ void line_eval(char* line)
166 printf("\n\n"); 164 printf("\n\n");
167 } 165 }
168 /* Send message to friend */ 166 /* Send message to friend */
169 else if (line[1] == 'm') { 167 else if (inpt_command == 'm') {
170 int i;
171 size_t len = strlen(line); 168 size_t len = strlen(line);
172 char numstring[len-3]; 169 char numstring[len-3];
173 char message[len-3]; 170 char message[len-3];
174 for (i=0; i<len; i++) { 171 int i;
172 for (i = 0; i < len; i++) {
175 if (line[i+3] != ' ') { 173 if (line[i+3] != ' ') {
176 numstring[i] = line[i+3]; 174 numstring[i] = line[i+3];
177 } else { 175 } else {
178 int j; 176 int j;
179 for (j=i+1; j<len; j++) 177 for (j = (i+1); j < len; j++)
180 message[j-i-1] = line[j+3]; 178 message[j-i-1] = line[j+3];
181 break; 179 break;
182 } 180 }
@@ -190,37 +188,37 @@ void line_eval(char* line)
190 } 188 }
191 } 189 }
192 190
193 else if (line[1] == 'n') { 191 else if (inpt_command == 'n') {
194 uint8_t name[MAX_NAME_LENGTH]; 192 uint8_t name[MAX_NAME_LENGTH];
195 int i = 0; 193 int i = 0;
196 size_t len = strlen(line); 194 size_t len = strlen(line);
197 for (i=3; i<len; i++) { 195 for (i = 3; i < len; i++) {
198 if (line[i] == 0 || line[i] == '\n') break; 196 if (line[i] == 0 || line[i] == '\n') break;
199 name[i - 3] = line[i]; 197 name[i-3] = line[i];
200 } 198 }
201 name[i - 3] = 0; 199 name[i-3] = 0;
202 setname(name, i); 200 setname(name, i);
203 char numstring[100]; 201 char numstring[100];
204 sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name); 202 sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name);
205 printf(numstring); 203 printf(numstring);
206 } 204 }
207 205
208 else if (line[1] == 's') { 206 else if (inpt_command == 's') {
209 uint8_t status[MAX_USERSTATUS_LENGTH]; 207 uint8_t status[MAX_USERSTATUS_LENGTH];
210 int i = 0; 208 int i = 0;
211 size_t len = strlen(line); 209 size_t len = strlen(line);
212 for (i=3; i<len; i++) { 210 for (i = 3; i < len; i++) {
213 if (line[i] == 0 || line[i] == '\n') break; 211 if (line[i] == 0 || line[i] == '\n') break;
214 status[i - 3] = line[i]; 212 status[i-3] = line[i];
215 } 213 }
216 status[i - 3] = 0; 214 status[i-3] = 0;
217 m_set_userstatus(status, strlen((char*)status)); 215 m_set_userstatus(status, strlen((char*)status));
218 char numstring[100]; 216 char numstring[100];
219 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status); 217 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status);
220 printf(numstring); 218 printf(numstring);
221 } 219 }
222 220
223 else if (line[1] == 'a') { 221 else if (inpt_command == 'a') {
224 uint8_t numf = atoi(line + 3); 222 uint8_t numf = atoi(line + 3);
225 char numchar[100]; 223 char numchar[100];
226 sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf); 224 sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf);
@@ -230,12 +228,10 @@ void line_eval(char* line)
230 printf(numchar); 228 printf(numchar);
231 } 229 }
232 /* EXIT */ 230 /* EXIT */
233 else if (line[1] == 'q') { 231 else if (inpt_command == 'q') {
234 exit(EXIT_SUCCESS); 232 exit(EXIT_SUCCESS);
235 } 233 }
236 } 234 } else {
237
238 else {
239 //nothing atm 235 //nothing atm
240 } 236 }
241} 237}
@@ -255,12 +251,10 @@ int main(int argc, char *argv[])
255 printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]); 251 printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
256 exit(0); 252 exit(0);
257 } 253 }
258
259 if (initMessenger() == -1) { 254 if (initMessenger() == -1) {
260 printf("initMessenger failed"); 255 printf("initMessenger failed");
261 exit(0); 256 exit(0);
262 } 257 }
263
264 if (argc > 4) { 258 if (argc > 4) {
265 if(strncmp(argv[4], "nokey", 6) < 0) { 259 if(strncmp(argv[4], "nokey", 6) < 0) {
266 } 260 }
@@ -272,26 +266,25 @@ int main(int argc, char *argv[])
272 m_callback_friendmessage(print_message); 266 m_callback_friendmessage(print_message);
273 m_callback_namechange(print_nickchange); 267 m_callback_namechange(print_nickchange);
274 m_callback_userstatus(print_statuschange); 268 m_callback_userstatus(print_statuschange);
275 269 char idstring1[PUB_KEY_BYTES][5];
276 char idstring1[32][5]; 270 char idstring2[PUB_KEY_BYTES][5];
277 char idstring2[32][5]; 271 int i;
278 uint32_t i; 272 for(i = 0; i < PUB_KEY_BYTES; i++)
279 for(i = 0; i < 32; i++)
280 { 273 {
281 if(self_public_key[i] < 16) 274 if(self_public_key[i] < (PUB_KEY_BYTES/2))
282 strcpy(idstring1[i],"0"); 275 strcpy(idstring1[i],"0");
283 else 276 else
284 strcpy(idstring1[i], ""); 277 strcpy(idstring1[i], "");
285 sprintf(idstring2[i], "%hhX",self_public_key[i]); 278 sprintf(idstring2[i], "%hhX",self_public_key[i]);
286 } 279 }
287 strcpy(users_id,"[i] your ID: "); 280 strcpy(users_id,"[i] your ID: ");
288 for (i=0; i<32; i++) { 281 int j;
289 strcat(users_id,idstring1[i]); 282 for (j = 0; j < PUB_KEY_BYTES; j++) {
290 strcat(users_id,idstring2[i]); 283 strcat(users_id,idstring1[j]);
284 strcat(users_id,idstring2[j]);
291 } 285 }
292 286
293 do_header(); 287 do_header();
294
295 IP_Port bootstrap_ip_port; 288 IP_Port bootstrap_ip_port;
296 bootstrap_ip_port.port = htons(atoi(argv[2])); 289 bootstrap_ip_port.port = htons(atoi(argv[2]));
297 int resolved_address = resolve_addr(argv[1]); 290 int resolved_address = resolve_addr(argv[1]);
@@ -301,12 +294,9 @@ int main(int argc, char *argv[])
301 exit(1); 294 exit(1);
302 295
303 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 296 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
304
305 int c; 297 int c;
306 int on = 0; 298 int on = 0;
307
308 _beginthread(get_input, 0, NULL); 299 _beginthread(get_input, 0, NULL);
309
310 while(1) { 300 while(1) {
311 if (on == 1 && DHT_isconnected() == -1) { 301 if (on == 1 && DHT_isconnected() == -1) {
312 printf("\n---------------------------------"); 302 printf("\n---------------------------------");
@@ -314,16 +304,13 @@ int main(int argc, char *argv[])
314 printf("\n---------------------------------\n\n"); 304 printf("\n---------------------------------\n\n");
315 on = 0; 305 on = 0;
316 } 306 }
317
318 if (on == 0 && DHT_isconnected()) { 307 if (on == 0 && DHT_isconnected()) {
319 printf("\n[i] Connected to DHT"); 308 printf("\n[i] Connected to DHT");
320 printf("\n---------------------------------\n\n"); 309 printf("\n---------------------------------\n\n");
321 on = 1; 310 on = 1;
322 } 311 }
323
324 doMessenger(); 312 doMessenger();
325 Sleep(1); 313 Sleep(1);
326 } 314 }
327
328 return 0; 315 return 0;
329} \ No newline at end of file 316} \ No newline at end of file
diff --git a/testing/nTox_win32.h b/testing/nTox_win32.h
index dacabc74..374348a4 100644
--- a/testing/nTox_win32.h
+++ b/testing/nTox_win32.h
@@ -27,6 +27,7 @@
27#include "../core/network.h" 27#include "../core/network.h"
28 28
29#define STRING_LENGTH 256 29#define STRING_LENGTH 256
30#define PUB_KEY_BYTES 32
30 31
31void do_header(); 32void do_header();
32void print_message(int friendnumber, uint8_t * string, uint16_t length); 33void print_message(int friendnumber, uint8_t * string, uint16_t length);
diff --git a/testing/cmake/toxic.cmake b/testing/toxic/CMakeLists.txt
index 1ffab788..f30d8e9e 100644
--- a/testing/cmake/toxic.cmake
+++ b/testing/toxic/CMakeLists.txt
@@ -4,8 +4,12 @@ project(toxic C)
4set(exe_name toxic) 4set(exe_name toxic)
5 5
6add_executable(${exe_name} 6add_executable(${exe_name}
7 toxic/main.c toxic/prompt.c) 7 main.c
8 8 prompt.c
9target_link_libraries(${exe_name} curses) 9 friendlist.c
10 chat.c)
11
12target_link_libraries(${exe_name}
13 curses)
10 14
11linkCoreLibraries(${exe_name}) 15linkCoreLibraries(${exe_name})
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
new file mode 100644
index 00000000..dceb1d7b
--- /dev/null
+++ b/testing/toxic/chat.c
@@ -0,0 +1,155 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <curses.h>
6#include <stdlib.h>
7#include <string.h>
8#include <stdint.h>
9#include <ctype.h>
10
11#include "../../core/Messenger.h"
12#include "../../core/network.h"
13
14#include "windows.h"
15
16typedef struct {
17 int friendnum;
18
19 char line[256];
20 size_t pos;
21
22 WINDOW* history;
23 WINDOW* linewin;
24
25} ChatContext;
26
27extern void fix_name(uint8_t* name);
28
29
30static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) {
31 ChatContext* ctx = (ChatContext*) self->x;
32 uint8_t nick[MAX_NAME_LENGTH] = {0};
33
34 if(ctx->friendnum != num)
35 return;
36
37 getname(num, (uint8_t*) &nick);
38
39 msg[len-1] = '\0';
40 nick[MAX_NAME_LENGTH-1] = '\0';
41
42 fix_name(msg);
43 fix_name(nick);
44
45 wattron(ctx->history, COLOR_PAIR(4));
46 wprintw(ctx->history, "%s: ", nick);
47 wattroff(ctx->history, COLOR_PAIR(4));
48
49 wprintw(ctx->history, "%s\n", msg);
50
51 self->blink = true;
52}
53
54static void chat_onNickChange(ToxWindow* self, int num, uint8_t* nick, uint16_t len) {
55 ChatContext* ctx = (ChatContext*) self->x;
56
57 if(ctx->friendnum != num)
58 return;
59
60 nick[len-1] = '\0';
61 fix_name(nick);
62
63 wattron(ctx->history, COLOR_PAIR(3));
64 wprintw(ctx->history, " * Your partner changed nick to '%s'\n", nick);
65 wattroff(ctx->history, COLOR_PAIR(3));
66}
67
68static void chat_onStatusChange(ToxWindow* self, int num, uint8_t* status, uint16_t len) {
69
70}
71
72static void chat_onKey(ToxWindow* self, int key) {
73 ChatContext* ctx = (ChatContext*) self->x;
74
75 if(isprint(key)) {
76
77 if(ctx->pos != sizeof(ctx->line)-1) {
78 ctx->line[ctx->pos++] = key;
79 ctx->line[ctx->pos] = '\0';
80 }
81 }
82 else if(key == '\n') {
83 wattron(ctx->history, COLOR_PAIR(1));
84 wprintw(ctx->history, "you: ", ctx->line);
85 wattroff(ctx->history, COLOR_PAIR(1));
86
87 wprintw(ctx->history, "%s\n", ctx->line);
88
89 if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) {
90 wattron(ctx->history, COLOR_PAIR(3));
91 wprintw(ctx->history, " * Failed to send message.\n");
92 wattroff(ctx->history, COLOR_PAIR(3));
93 }
94
95 ctx->line[0] = '\0';
96 ctx->pos = 0;
97 }
98 else if(key == 0x107 || key == 0x8 || key == 0x7f) {
99 if(ctx->pos != 0) {
100 ctx->line[--ctx->pos] = '\0';
101 }
102 }
103
104}
105
106static void chat_onDraw(ToxWindow* self) {
107 int x, y;
108 ChatContext* ctx = (ChatContext*) self->x;
109
110 getmaxyx(self->window, y, x);
111
112 (void) x;
113 if(y < 3)
114 return;
115
116 wclear(ctx->linewin);
117 mvwhline(ctx->linewin, 0, 0, '_', COLS);
118 mvwprintw(ctx->linewin, 1, 0, "%s\n", ctx->line);
119
120 wrefresh(self->window);
121}
122
123static void chat_onInit(ToxWindow* self) {
124 int x, y;
125 ChatContext* ctx = (ChatContext*) self->x;
126
127 getmaxyx(self->window, y, x);
128
129 ctx->history = subwin(self->window, y - 4, x, 0, 0);
130 scrollok(ctx->history, 1);
131
132 ctx->linewin = subwin(self->window, 2, x, y - 3, 0);
133}
134
135ToxWindow new_chat(int friendnum) {
136 ToxWindow ret;
137
138 memset(&ret, 0, sizeof(ret));
139
140 ret.onKey = &chat_onKey;
141 ret.onDraw = &chat_onDraw;
142 ret.onInit = &chat_onInit;
143 ret.onMessage = &chat_onMessage;
144 ret.onNickChange = &chat_onNickChange;
145 ret.onStatusChange = &chat_onStatusChange;
146
147 snprintf(ret.title, sizeof(ret.title), "[chat %d]", friendnum);
148
149 ChatContext* x = calloc(1, sizeof(ChatContext));
150 x->friendnum = friendnum;
151
152 ret.x = (void*) x;
153
154 return ret;
155}
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
new file mode 100644
index 00000000..f9a413f9
--- /dev/null
+++ b/testing/toxic/friendlist.c
@@ -0,0 +1,166 @@
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
15extern int add_window(ToxWindow w);
16extern int focus_window(int num);
17extern ToxWindow new_chat(int friendnum);
18
19#define MAX_FRIENDS_NUM 100
20
21typedef struct {
22 uint8_t name[MAX_NAME_LENGTH];
23 uint8_t status[MAX_USERSTATUS_LENGTH];
24 int num;
25 int chatwin;
26} friend_t;
27
28static friend_t friends[MAX_FRIENDS_NUM];
29static int num_friends = 0;
30static int num_selected = 0;
31
32
33void fix_name(uint8_t* name) {
34
35 // Remove all non alphanumeric characters.
36 uint8_t* p = name;
37 uint8_t* q = name;
38
39 while(*p != 0) {
40 if(isprint(*p)) {
41 *q++ = *p;
42 }
43
44 p++;
45 }
46
47 *q = 0;
48}
49
50void friendlist_onMessage(ToxWindow* self, int num, uint8_t* str, uint16_t len) {
51
52 if(num >= num_friends)
53 return;
54
55 if(friends[num].chatwin == -1) {
56 friends[num].chatwin = add_window(new_chat(num));
57 }
58}
59
60void friendlist_onNickChange(ToxWindow* self, int num, uint8_t* str, uint16_t len) {
61
62 if(len >= MAX_NAME_LENGTH || num >= num_friends)
63 return;
64
65 memcpy((char*) &friends[num].name, (char*) str, len);
66 friends[num].name[len] = 0;
67 fix_name(friends[num].name);
68}
69
70void friendlist_onStatusChange(ToxWindow* self, int num, uint8_t* str, uint16_t len) {
71
72 if(len >= MAX_USERSTATUS_LENGTH || num >= num_friends)
73 return;
74
75 memcpy((char*) &friends[num].status, (char*) str, len);
76 friends[num].status[len] = 0;
77 fix_name(friends[num].status);
78}
79
80int friendlist_onFriendAdded(int num) {
81
82 if(num_friends == MAX_FRIENDS_NUM)
83 return -1;
84
85 friends[num_friends].num = num;
86 getname(num, friends[num_friends].name);
87 strcpy((char*) friends[num_friends].name, "unknown");
88 strcpy((char*) friends[num_friends].status, "unknown");
89 friends[num_friends].chatwin = -1;
90
91 num_friends++;
92 return 0;
93}
94
95static void friendlist_onKey(ToxWindow* self, int key) {
96
97 if(key == KEY_UP) {
98 if(num_selected != 0)
99 num_selected--;
100 }
101 else if(key == KEY_DOWN) {
102 if(num_friends != 0)
103 num_selected = (num_selected+1) % num_friends;
104 }
105 else if(key == '\n') {
106
107 if(friends[num_selected].chatwin != -1)
108 return;
109
110 friends[num_selected].chatwin = add_window(new_chat(num_selected));
111 focus_window(friends[num_selected].chatwin);
112 }
113}
114
115static void friendlist_onDraw(ToxWindow* self) {
116 size_t i;
117
118 wclear(self->window);
119
120 if(num_friends == 0) {
121 wprintw(self->window, "Empty. Add some friends! :-)\n");
122 }
123 else {
124 wattron(self->window, COLOR_PAIR(2) | A_BOLD);
125 wprintw(self->window, "Open chat with.. (up/down keys, enter)\n");
126 wattroff(self->window, COLOR_PAIR(2) | A_BOLD);
127 }
128
129 wprintw(self->window, "\n");
130
131 for(i=0; i<num_friends; i++) {
132
133 if(i == num_selected) wattron(self->window, COLOR_PAIR(3));
134 wprintw(self->window, " [#%d] ", friends[i].num);
135 if(i == num_selected) wattroff(self->window, COLOR_PAIR(3));
136
137 attron(A_BOLD);
138 wprintw(self->window, "%s ", friends[i].name);
139 attroff(A_BOLD);
140
141 wprintw(self->window, "(%s)\n", friends[i].status);
142 }
143
144 wrefresh(self->window);
145}
146
147static void friendlist_onInit(ToxWindow* self) {
148
149}
150
151
152ToxWindow new_friendlist() {
153 ToxWindow ret;
154
155 memset(&ret, 0, sizeof(ret));
156
157 ret.onKey = &friendlist_onKey;
158 ret.onDraw = &friendlist_onDraw;
159 ret.onInit = &friendlist_onInit;
160 ret.onMessage = &friendlist_onMessage;
161 ret.onNickChange = &friendlist_onNickChange;
162 ret.onStatusChange = &friendlist_onStatusChange;
163 strcpy(ret.title, "[friends]");
164
165 return ret;
166}
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 0aad6777..fffc3f84 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -14,6 +14,10 @@
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_onFriendAdded(int num);
20
17extern int add_req(uint8_t* public_key); // XXX 21extern int add_req(uint8_t* public_key); // XXX
18 22
19#define TOXWINDOWS_MAX_NUM 32 23#define TOXWINDOWS_MAX_NUM 32
@@ -25,21 +29,59 @@ static ToxWindow* prompt;
25 29
26// CALLBACKS START 30// CALLBACKS START
27void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) { 31void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) {
32 size_t i;
28 int n = add_req(public_key); 33 int n = add_req(public_key);
29 34
30 wprintw(prompt->window, "\nFriend request.\nUse \"accept %d\" to accept it.\n", n); 35 wprintw(prompt->window, "\nFriend request from:\n");
36
37 for(i=0; i<32; i++) {
38 wprintw(prompt->window, "%02x", public_key[i] & 0xff);
39 }
40 wprintw(prompt->window, "\n");
41
42 wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n);
43
44 for(i=0; i<w_num; i++) {
45 if(windows[i].onFriendRequest != NULL)
46 windows[i].onFriendRequest(&windows[i], public_key, data, length);
47 }
31} 48}
32 49
33void 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;
52
34 wprintw(prompt->window, "\n(message) %d: %s!\n", friendnumber, string); 53 wprintw(prompt->window, "\n(message) %d: %s!\n", friendnumber, string);
54
55 for(i=0; i<w_num; i++) {
56 if(windows[i].onMessage != NULL)
57 windows[i].onMessage(&windows[i], friendnumber, string, length);
58 }
35} 59}
36 60
37void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) { 61void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) {
38 wprintw(prompt->window, "\n(nick) %d: %s!\n", friendnumber, string); 62 size_t i;
63
64 wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string);
65
66 for(i=0; i<w_num; i++) {
67 if(windows[i].onNickChange != NULL)
68 windows[i].onNickChange(&windows[i], friendnumber, string, length);
69 }
39} 70}
40 71
41void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) { 72void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) {
42 wprintw(prompt->window, "\n(status) %d: %s!\n", friendnumber, string); 73 size_t i;
74
75 wprintw(prompt->window, "\n(statuschange) %d: %s!\n", friendnumber, string);
76
77 for(i=0; i<w_num; i++) {
78 if(windows[i].onStatusChange != NULL)
79 windows[i].onStatusChange(&windows[i], friendnumber, string, length);
80 }
81}
82
83void on_friendadded(int friendnumber) {
84 friendlist_onFriendAdded(friendnumber);
43} 85}
44// CALLBACKS END 86// CALLBACKS END
45 87
@@ -73,7 +115,7 @@ static void init_tox() {
73 m_callback_userstatus(on_statuschange); 115 m_callback_userstatus(on_statuschange);
74} 116}
75 117
76static int add_window(ToxWindow w) { 118int add_window(ToxWindow w) {
77 if(w_num == TOXWINDOWS_MAX_NUM) 119 if(w_num == TOXWINDOWS_MAX_NUM)
78 return -1; 120 return -1;
79 121
@@ -88,14 +130,22 @@ static int add_window(ToxWindow w) {
88 windows[w_num++] = w; 130 windows[w_num++] = w;
89 w.onInit(&w); 131 w.onInit(&w);
90 132
91 return w_num; 133 return w_num - 1;
134}
135
136int focus_window(int num) {
137 if(num >= w_num || num < 0)
138 return -1;
139
140 w_active = num;
141 return 0;
92} 142}
93 143
94static void init_windows() { 144static void init_windows() {
95 w_num = 0; 145 w_num = 0;
96 w_active = 0; 146 w_active = 0;
97 147
98 if(add_window(new_prompt()) == -1) { 148 if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) {
99 fprintf(stderr, "add_window() failed.\n"); 149 fprintf(stderr, "add_window() failed.\n");
100 150
101 endwin(); 151 endwin();
@@ -134,14 +184,18 @@ static void load_data() {
134 184
135 if(buf == NULL) { 185 if(buf == NULL) {
136 fprintf(stderr, "malloc() failed.\n"); 186 fprintf(stderr, "malloc() failed.\n");
187
137 fclose(fd); 188 fclose(fd);
189 endwin();
138 exit(1); 190 exit(1);
139 } 191 }
140 192
141 if(fread(buf, len, 1, fd) != 1){ 193 if(fread(buf, len, 1, fd) != 1){
142 fprintf(stderr, "fread() failed.\n"); 194 fprintf(stderr, "fread() failed.\n");
195
143 free(buf); 196 free(buf);
144 fclose(fd); 197 fclose(fd);
198 endwin();
145 exit(1); 199 exit(1);
146 } 200 }
147 201
@@ -153,6 +207,7 @@ static void load_data() {
153 207
154 if(buf == NULL) { 208 if(buf == NULL) {
155 fprintf(stderr, "malloc() failed.\n"); 209 fprintf(stderr, "malloc() failed.\n");
210 endwin();
156 exit(1); 211 exit(1);
157 } 212 }
158 213
@@ -161,14 +216,18 @@ static void load_data() {
161 fd = fopen("data", "w"); 216 fd = fopen("data", "w");
162 if(fd == NULL) { 217 if(fd == NULL) {
163 fprintf(stderr, "fopen() failed.\n"); 218 fprintf(stderr, "fopen() failed.\n");
219
164 free(buf); 220 free(buf);
221 endwin();
165 exit(1); 222 exit(1);
166 } 223 }
167 224
168 if(fwrite(buf, len, 1, fd) != 1){ 225 if(fwrite(buf, len, 1, fd) != 1){
169 fprintf(stderr, "fwrite() failed.\n"); 226 fprintf(stderr, "fwrite() failed.\n");
227
170 free(buf); 228 free(buf);
171 fclose(fd); 229 fclose(fd);
230 endwin();
172 exit(1); 231 exit(1);
173 } 232 }
174 } 233 }
@@ -178,6 +237,7 @@ static void load_data() {
178} 237}
179 238
180static void draw_bar() { 239static void draw_bar() {
240 static int odd = 0;
181 size_t i; 241 size_t i;
182 242
183 attron(COLOR_PAIR(4)); 243 attron(COLOR_PAIR(4));
@@ -186,12 +246,26 @@ static void draw_bar() {
186 246
187 move(LINES - 1, 0); 247 move(LINES - 1, 0);
188 248
249 attron(COLOR_PAIR(4) | A_BOLD);
250 printw(" TOXIC 1.0 |");
251 attroff(COLOR_PAIR(4) | A_BOLD);
252
189 for(i=0; i<w_num; i++) { 253 for(i=0; i<w_num; i++) {
190 if(i == w_active) { 254 if(i == w_active) {
191 attron(A_BOLD); 255 attron(A_BOLD);
192 } 256 }
193 257
194 printw(" %s ", windows[i].title); 258 odd = (odd+1) % 2;
259
260 if(windows[i].blink && odd) {
261 attron(COLOR_PAIR(3));
262 }
263
264 printw(" %s", windows[i].title);
265
266 if(windows[i].blink && odd) {
267 attron(COLOR_PAIR(3));
268 }
195 269
196 if(i == w_active) { 270 if(i == w_active) {
197 attroff(A_BOLD); 271 attroff(A_BOLD);
@@ -201,6 +275,11 @@ static void draw_bar() {
201 refresh(); 275 refresh();
202} 276}
203 277
278void prepare_window(WINDOW* w) {
279 mvwin(w, 0, 0);
280 wresize(w, LINES-2, COLS);
281}
282
204int main(int argc, char* argv[]) { 283int main(int argc, char* argv[]) {
205 int ch; 284 int ch;
206 ToxWindow* a; 285 ToxWindow* a;
@@ -211,14 +290,22 @@ int main(int argc, char* argv[]) {
211 init_windows(); 290 init_windows();
212 291
213 while(true) { 292 while(true) {
293 // Update tox.
214 do_tox(); 294 do_tox();
215 295
296 // Draw.
216 a = &windows[w_active]; 297 a = &windows[w_active];
298 prepare_window(a->window);
299 a->blink = false;
217 a->onDraw(a); 300 a->onDraw(a);
218 draw_bar(); 301 draw_bar();
219 302
303 // Handle input.
220 ch = getch(); 304 ch = getch();
221 if(ch != ERR) { 305 if(ch == '\t') {
306 w_active = (w_active + 1) % w_num;
307 }
308 else if(ch != ERR) {
222 a->onKey(a, ch); 309 a->onKey(a, ch);
223 } 310 }
224 311
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 4a59cc7b..f1b6e689 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,8 +42,7 @@ 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. 45 if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) {
44 if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) {
45 endwin(); 46 endwin();
46 exit(0); 47 exit(0);
47 } 48 }
@@ -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,26 +208,29 @@ 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
202 if(m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) != 1) { 224 if(m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0) {
203 wprintw(self->window, "Error occurred while sending message.\n"); 225 wprintw(self->window, "Error occurred while sending message.\n");
204 } 226 }
205 else { 227 else {
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) {
@@ -231,7 +256,7 @@ static void prompt_onKey(ToxWindow* self, int key) {
231 } 256 }
232 257
233 // BACKSPACE key: Remove one character from line. 258 // BACKSPACE key: Remove one character from line.
234 else if(key == 0x107) { 259 else if(key == 0x107 || key == 0x8 || key == 0x7f) {
235 260
236 if(prompt_buf_pos != 0) { 261 if(prompt_buf_pos != 0) {
237 prompt_buf[--prompt_buf_pos] = 0; 262 prompt_buf[--prompt_buf_pos] = 0;
@@ -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
@@ -260,7 +282,7 @@ static void prompt_onDraw(ToxWindow* self) {
260 282
261static void print_usage(ToxWindow* self) { 283static void print_usage(ToxWindow* self) {
262 wattron(self->window, COLOR_PAIR(2) | A_BOLD); 284 wattron(self->window, COLOR_PAIR(2) | A_BOLD);
263 wprintw(self->window, "Usage:\n"); 285 wprintw(self->window, "Commands:\n");
264 wattroff(self->window, A_BOLD); 286 wattroff(self->window, A_BOLD);
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");
@@ -270,6 +292,12 @@ static void print_usage(ToxWindow* self) {
270 wprintw(self->window, " accept <number> : Accept friend request\n"); 292 wprintw(self->window, " accept <number> : Accept friend request\n");
271 wprintw(self->window, " myid : Print your ID\n"); 293 wprintw(self->window, " myid : Print your ID\n");
272 wprintw(self->window, " quit/exit : Exit program\n"); 294 wprintw(self->window, " quit/exit : Exit program\n");
295
296
297 wattron(self->window, A_BOLD);
298 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
299 wattroff(self->window, A_BOLD);
300
273 wattroff(self->window, COLOR_PAIR(2)); 301 wattroff(self->window, COLOR_PAIR(2));
274} 302}
275 303
@@ -283,6 +311,8 @@ static void prompt_onInit(ToxWindow* self) {
283ToxWindow new_prompt() { 311ToxWindow new_prompt() {
284 ToxWindow ret; 312 ToxWindow ret;
285 313
314 memset(&ret, 0, sizeof(ret));
315
286 ret.onKey = &prompt_onKey; 316 ret.onKey = &prompt_onKey;
287 ret.onDraw = &prompt_onDraw; 317 ret.onDraw = &prompt_onDraw;
288 ret.onInit = &prompt_onInit; 318 ret.onInit = &prompt_onInit;
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h
index 2e082ca9..dde1430f 100644
--- a/testing/toxic/windows.h
+++ b/testing/toxic/windows.h
@@ -1,10 +1,23 @@
1/*
2 * Toxic -- Tox Curses Client
3 */
4
5#include <stdbool.h>
6
1typedef struct ToxWindow_ ToxWindow; 7typedef struct ToxWindow_ ToxWindow;
2 8
3struct ToxWindow_ { 9struct ToxWindow_ {
4 void(*onKey)(ToxWindow*, int); 10 void(*onKey)(ToxWindow*, int);
5 void(*onDraw)(ToxWindow*); 11 void(*onDraw)(ToxWindow*);
6 void(*onInit)(ToxWindow*); 12 void(*onInit)(ToxWindow*);
13 void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t);
14 void(*onMessage)(ToxWindow*, int, uint8_t*, uint16_t);
15 void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t);
16 void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t);
7 char title[256]; 17 char title[256];
8 18
19 void* x;
20 bool blink;
21
9 WINDOW* window; 22 WINDOW* window;
10}; 23};