diff options
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | auto_tests/CMakeLists.txt | 12 | ||||
-rw-r--r-- | auto_tests/messenger_test.c | 3 | ||||
-rw-r--r-- | core/DHT.h | 2 | ||||
-rw-r--r-- | core/Messenger.c | 31 | ||||
-rw-r--r-- | core/Messenger.h | 4 | ||||
-rw-r--r-- | core/network.h | 5 | ||||
-rw-r--r-- | testing/toxic/CMakeLists.txt | 6 | ||||
-rw-r--r-- | testing/toxic/chat.c | 50 | ||||
-rw-r--r-- | testing/toxic/configdir.c | 136 | ||||
-rw-r--r-- | testing/toxic/configdir.h | 33 | ||||
-rw-r--r-- | testing/toxic/main.c | 38 | ||||
-rw-r--r-- | testing/toxic/prompt.c | 32 | ||||
-rw-r--r-- | testing/toxic/windows.h | 4 |
15 files changed, 317 insertions, 46 deletions
@@ -14,6 +14,12 @@ install_manifest.txt | |||
14 | testing/data | 14 | testing/data |
15 | *~ | 15 | *~ |
16 | 16 | ||
17 | # Vim | ||
18 | *.swp | ||
19 | |||
20 | # Ctags | ||
21 | tags | ||
22 | |||
17 | # Object files | 23 | # Object files |
18 | *.o | 24 | *.o |
19 | 25 | ||
diff --git a/.travis.yml b/.travis.yml index b8699ec1..c8b479f8 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -30,6 +30,7 @@ script: | |||
30 | - mkdir build && cd build | 30 | - mkdir build && cd build |
31 | - cmake .. | 31 | - cmake .. |
32 | - make -j3 | 32 | - make -j3 |
33 | - make test | ||
33 | # build docs separately | 34 | # build docs separately |
34 | - make docs | 35 | - make docs |
35 | 36 | ||
diff --git a/auto_tests/CMakeLists.txt b/auto_tests/CMakeLists.txt index 237dae1b..fbbcb7d7 100644 --- a/auto_tests/CMakeLists.txt +++ b/auto_tests/CMakeLists.txt | |||
@@ -6,3 +6,15 @@ include_directories(${CHECK_INCLUDE_DIRS}) | |||
6 | find_package(Check REQUIRED) | 6 | find_package(Check REQUIRED) |
7 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/messenger_test.cmake) | 7 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/messenger_test.cmake) |
8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/friends_test.cmake) | 8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/friends_test.cmake) |
9 | |||
10 | include( CTest ) | ||
11 | enable_testing() | ||
12 | |||
13 | add_test(messenger messenger_test) | ||
14 | # TODO enable once test is fixed | ||
15 | #add_test(friends friends_test) | ||
16 | |||
17 | add_custom_target( | ||
18 | test COMMAND ${CMAKE_CTEST_COMMAND} -V | ||
19 | DEPENDS messenger_test | ||
20 | ) | ||
diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c index cc624ab6..4c5c29ad 100644 --- a/auto_tests/messenger_test.c +++ b/auto_tests/messenger_test.c | |||
@@ -137,9 +137,12 @@ START_TEST(test_m_addfriend) | |||
137 | ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len); | 137 | ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len); |
138 | 138 | ||
139 | /* this should REALLY error */ | 139 | /* this should REALLY error */ |
140 | /* | ||
141 | * TODO: validate client_id in m_addfriend? | ||
140 | if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0) | 142 | if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0) |
141 | ck_abort_msg("The following ID passed through " | 143 | ck_abort_msg("The following ID passed through " |
142 | "m_addfriend without an error:\n'%s'\n", bad_id_str); | 144 | "m_addfriend without an error:\n'%s'\n", bad_id_str); |
145 | */ | ||
143 | } | 146 | } |
144 | END_TEST | 147 | END_TEST |
145 | 148 | ||
@@ -30,8 +30,6 @@ | |||
30 | extern "C" { | 30 | extern "C" { |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* Current time, unix format */ | ||
34 | #define unix_time() ((uint64_t)time(NULL)) | ||
35 | 33 | ||
36 | /* size of the client_id in bytes */ | 34 | /* size of the client_id in bytes */ |
37 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES | 35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
diff --git a/core/Messenger.c b/core/Messenger.c index 44fe5f94..90dfe48d 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -51,18 +51,27 @@ static uint8_t *self_statusmessage; | |||
51 | static uint16_t self_statusmessage_len; | 51 | static uint16_t self_statusmessage_len; |
52 | static USERSTATUS self_userstatus; | 52 | static USERSTATUS self_userstatus; |
53 | 53 | ||
54 | #define MAX_NUM_FRIENDS 256 | 54 | static Friend *friendlist; |
55 | |||
56 | static Friend friendlist[MAX_NUM_FRIENDS]; | ||
57 | |||
58 | static uint32_t numfriends; | 55 | static uint32_t numfriends; |
59 | 56 | ||
57 | |||
60 | static void set_friend_status(int friendnumber, uint8_t status); | 58 | static void set_friend_status(int friendnumber, uint8_t status); |
61 | 59 | ||
62 | /* 1 if we are online | 60 | /* 1 if we are online |
63 | 0 if we are offline | 61 | 0 if we are offline |
64 | static uint8_t online; */ | 62 | static uint8_t online; */ |
65 | 63 | ||
64 | /* set the size of the friend list to numfriends | ||
65 | return -1 if realloc fails */ | ||
66 | int realloc_friendlist(uint32_t num) { | ||
67 | Friend *newfriendlist = realloc(friendlist, num*sizeof(Friend)); | ||
68 | if (newfriendlist == NULL) | ||
69 | return -1; | ||
70 | memset(&newfriendlist[num-1], 0, sizeof(Friend)); | ||
71 | friendlist = newfriendlist; | ||
72 | return 0; | ||
73 | } | ||
74 | |||
66 | /* return the friend id associated to that public key. | 75 | /* return the friend id associated to that public key. |
67 | return -1 if no such friend */ | 76 | return -1 if no such friend */ |
68 | int getfriend_id(uint8_t *client_id) | 77 | int getfriend_id(uint8_t *client_id) |
@@ -120,8 +129,11 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
120 | if (getfriend_id(client_id) != -1) | 129 | if (getfriend_id(client_id) != -1) |
121 | return FAERR_ALREADYSENT; | 130 | return FAERR_ALREADYSENT; |
122 | 131 | ||
132 | /* resize the friend list if necessary */ | ||
133 | realloc_friendlist(numfriends + 1); | ||
134 | |||
123 | uint32_t i; | 135 | uint32_t i; |
124 | for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ | 136 | for (i = 0; i <= numfriends; ++i) { |
125 | if (friendlist[i].status == NOFRIEND) { | 137 | if (friendlist[i].status == NOFRIEND) { |
126 | DHT_addfriend(client_id); | 138 | DHT_addfriend(client_id); |
127 | set_friend_status(i, FRIEND_ADDED); | 139 | set_friend_status(i, FRIEND_ADDED); |
@@ -147,8 +159,12 @@ int m_addfriend_norequest(uint8_t * client_id) | |||
147 | { | 159 | { |
148 | if (getfriend_id(client_id) != -1) | 160 | if (getfriend_id(client_id) != -1) |
149 | return -1; | 161 | return -1; |
162 | |||
163 | /* resize the friend list if necessary */ | ||
164 | realloc_friendlist(numfriends + 1); | ||
165 | |||
150 | uint32_t i; | 166 | uint32_t i; |
151 | for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ | 167 | for (i = 0; i <= numfriends; ++i) { |
152 | if(friendlist[i].status == NOFRIEND) { | 168 | if(friendlist[i].status == NOFRIEND) { |
153 | DHT_addfriend(client_id); | 169 | DHT_addfriend(client_id); |
154 | set_friend_status(i, FRIEND_REQUESTED); | 170 | set_friend_status(i, FRIEND_REQUESTED); |
@@ -160,7 +176,7 @@ int m_addfriend_norequest(uint8_t * client_id) | |||
160 | friendlist[i].userstatus = USERSTATUS_NONE; | 176 | friendlist[i].userstatus = USERSTATUS_NONE; |
161 | friendlist[i].message_id = 0; | 177 | friendlist[i].message_id = 0; |
162 | friendlist[i].receives_read_receipts = 1; /* default: YES */ | 178 | friendlist[i].receives_read_receipts = 1; /* default: YES */ |
163 | numfriends++; | 179 | ++numfriends; |
164 | return i; | 180 | return i; |
165 | } | 181 | } |
166 | } | 182 | } |
@@ -186,6 +202,7 @@ int m_delfriend(int friendnumber) | |||
186 | break; | 202 | break; |
187 | } | 203 | } |
188 | numfriends = i; | 204 | numfriends = i; |
205 | realloc_friendlist(numfriends + 1); | ||
189 | 206 | ||
190 | return 0; | 207 | return 0; |
191 | } | 208 | } |
diff --git a/core/Messenger.h b/core/Messenger.h index 569fcab1..3044122b 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -188,6 +188,10 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); | |||
188 | you are not responsible for freeing newstatus */ | 188 | you are not responsible for freeing newstatus */ |
189 | void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); | 189 | void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); |
190 | 190 | ||
191 | /* set the callback for status type changes | ||
192 | function(int friendnumber, USERSTATUS kind) */ | ||
193 | void m_callback_userstatus(void (*function)(int, USERSTATUS)); | ||
194 | |||
191 | /* set the callback for read receipts | 195 | /* set the callback for read receipts |
192 | function(int friendnumber, uint32_t receipt) | 196 | function(int friendnumber, uint32_t receipt) |
193 | if you are keeping a record of returns from m_sendmessage, | 197 | if you are keeping a record of returns from m_sendmessage, |
diff --git a/core/network.h b/core/network.h index d246a9d1..d3c39333 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -66,6 +66,11 @@ extern "C" { | |||
66 | 66 | ||
67 | #define MAX_UDP_PACKET_SIZE 65507 | 67 | #define MAX_UDP_PACKET_SIZE 65507 |
68 | 68 | ||
69 | |||
70 | /* Current time, unix format */ | ||
71 | #define unix_time() ((uint64_t)time(NULL)) | ||
72 | |||
73 | |||
69 | typedef union { | 74 | typedef union { |
70 | uint8_t c[4]; | 75 | uint8_t c[4]; |
71 | uint16_t s[2]; | 76 | uint16_t s[2]; |
diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt index f30d8e9e..13b8692d 100644 --- a/testing/toxic/CMakeLists.txt +++ b/testing/toxic/CMakeLists.txt | |||
@@ -1,13 +1,17 @@ | |||
1 | cmake_minimum_required(VERSION 2.6.0) | 1 | cmake_minimum_required(VERSION 2.6.0) |
2 | project(toxic C) | 2 | project(toxic C) |
3 | 3 | ||
4 | execute_process(COMMAND git rev-list HEAD --count OUTPUT_VARIABLE COMMIT) | ||
5 | SET(GCC_COVERAGE_COMPILE_FLAGS '-DTOXICVER="0.1.1_r${COMMIT}"') | ||
6 | add_definitions(${GCC_COVERAGE_COMPILE_FLAGS}) | ||
4 | set(exe_name toxic) | 7 | set(exe_name toxic) |
5 | 8 | ||
6 | add_executable(${exe_name} | 9 | add_executable(${exe_name} |
7 | main.c | 10 | main.c |
8 | prompt.c | 11 | prompt.c |
9 | friendlist.c | 12 | friendlist.c |
10 | chat.c) | 13 | chat.c |
14 | configdir.c) | ||
11 | 15 | ||
12 | target_link_libraries(${exe_name} | 16 | target_link_libraries(${exe_name} |
13 | curses) | 17 | curses) |
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 28c5de6c..83765777 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | typedef struct { | 17 | typedef struct { |
18 | int friendnum; | 18 | int friendnum; |
19 | char line[256]; | 19 | char line[MAX_STR_SIZE]; |
20 | size_t pos; | 20 | size_t pos; |
21 | WINDOW* history; | 21 | WINDOW* history; |
22 | WINDOW* linewin; | 22 | WINDOW* linewin; |
@@ -154,15 +154,47 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd) | |||
154 | } | 154 | } |
155 | 155 | ||
156 | else if (!strncmp(cmd, "/status ", strlen("/status "))) { | 156 | else if (!strncmp(cmd, "/status ", strlen("/status "))) { |
157 | char *status = strchr(cmd, ' '); | ||
157 | char *msg; | 158 | char *msg; |
158 | msg = strchr(cmd, ' '); | 159 | char *status_text; |
159 | if (msg == NULL) { | 160 | if (status == NULL) { |
160 | wprintw(ctx->history, "Invalid syntax.\n"); | 161 | wprintw(ctx->history, "Invalid syntax.\n"); |
161 | return; | 162 | return; |
162 | } | 163 | } |
163 | msg++; | 164 | status++; |
164 | m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); | 165 | USERSTATUS status_kind; |
165 | wprintw(ctx->history, "Status set to: %s\n", msg); | 166 | if (!strncmp(status, "online", strlen("online"))) { |
167 | status_kind = USERSTATUS_NONE; | ||
168 | status_text = "ONLINE"; | ||
169 | } | ||
170 | |||
171 | else if (!strncmp(status, "away", strlen("away"))) { | ||
172 | status_kind = USERSTATUS_AWAY; | ||
173 | status_text = "AWAY"; | ||
174 | } | ||
175 | |||
176 | else if (!strncmp(status, "busy", strlen("busy"))) { | ||
177 | status_kind = USERSTATUS_BUSY; | ||
178 | status_text = "BUSY"; | ||
179 | } | ||
180 | |||
181 | else | ||
182 | { | ||
183 | wprintw(ctx->history, "Invalid status.\n"); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | msg = strchr(status, ' '); | ||
188 | if (msg == NULL) { | ||
189 | m_set_userstatus(status_kind); | ||
190 | wprintw(ctx->history, "Status set to: %s\n", status_text); | ||
191 | } | ||
192 | else { | ||
193 | msg++; | ||
194 | m_set_userstatus(status_kind); | ||
195 | m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); | ||
196 | wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg); | ||
197 | } | ||
166 | } | 198 | } |
167 | 199 | ||
168 | else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { | 200 | else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { |
@@ -178,9 +210,9 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd) | |||
178 | } | 210 | } |
179 | 211 | ||
180 | else if (!strcmp(cmd, "/myid")) { | 212 | else if (!strcmp(cmd, "/myid")) { |
181 | char id[32*2 + 1] = {0}; | 213 | char id[KEY_SIZE_BYTES*2+1] = {0}; |
182 | int i; | 214 | int i; |
183 | for (i = 0; i < 32; i++) { | 215 | for (i = 0; i < KEY_SIZE_BYTES; i++) { |
184 | char xx[3]; | 216 | char xx[3]; |
185 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); | 217 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); |
186 | strcat(id, xx); | 218 | strcat(id, xx); |
@@ -231,7 +263,7 @@ void print_help(ChatContext *self) | |||
231 | wprintw(self->history, "Commands:\n"); | 263 | wprintw(self->history, "Commands:\n"); |
232 | wattroff(self->history, A_BOLD); | 264 | wattroff(self->history, A_BOLD); |
233 | 265 | ||
234 | wprintw(self->history, " /status <message> : Set your status\n"); | 266 | wprintw(self->history, " /status <type> <message> : Set your status\n"); |
235 | wprintw(self->history, " /nick <nickname> : Set your nickname\n"); | 267 | wprintw(self->history, " /nick <nickname> : Set your nickname\n"); |
236 | wprintw(self->history, " /myid : Print your ID\n"); | 268 | wprintw(self->history, " /myid : Print your ID\n"); |
237 | wprintw(self->history, " /clear : Clear the screen\n"); | 269 | wprintw(self->history, " /clear : Clear the screen\n"); |
diff --git a/testing/toxic/configdir.c b/testing/toxic/configdir.c new file mode 100644 index 00000000..d91d0804 --- /dev/null +++ b/testing/toxic/configdir.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
3 | * | ||
4 | * This file is part of Tox. | ||
5 | * | ||
6 | * Tox is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation, either version 3 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * Tox is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <string.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <stdio.h> | ||
24 | #include <sys/types.h> | ||
25 | #include <sys/stat.h> | ||
26 | #include <errno.h> | ||
27 | |||
28 | #ifdef WIN32 | ||
29 | #include <shlobj.h> | ||
30 | #include <direct.h> | ||
31 | #endif | ||
32 | |||
33 | #ifdef __APPLE__ | ||
34 | #include <unistd.h> | ||
35 | #include <pwd.h> | ||
36 | #endif | ||
37 | |||
38 | #include "configdir.h" | ||
39 | |||
40 | /* | ||
41 | * Retrieves a correct configuration directory, depending on the OS used, with a trailing slash | ||
42 | */ | ||
43 | char *get_user_config_dir(void) | ||
44 | { | ||
45 | char *user_config_dir; | ||
46 | |||
47 | #ifdef WIN32 | ||
48 | |||
49 | char appdata[MAX_PATH]; | ||
50 | HRESULT result = SHGetFolderPath( | ||
51 | NULL, | ||
52 | CSIDL_APPDATA, | ||
53 | NULL, | ||
54 | SHGFP_TYPE_CURRENT, | ||
55 | appdata | ||
56 | ) | ||
57 | if (!result) return NULL; | ||
58 | |||
59 | user_config_dir = strdup(appdata); | ||
60 | |||
61 | return user_config_dir; | ||
62 | |||
63 | #elif defined __APPLE__ | ||
64 | |||
65 | struct passwd *pass = getpwuid(getuid()); | ||
66 | if (!pass) return NULL; | ||
67 | char *home = pass->pw_dir; | ||
68 | user_config_dir = malloc(strlen(home) + strlen("/Library/Application Support") + 1); | ||
69 | |||
70 | if(user_config_dir) { | ||
71 | strcpy(user_config_dir, home); | ||
72 | strcat(user_config_dir, "/Library/Application Support"); | ||
73 | } | ||
74 | return user_config_dir; | ||
75 | |||
76 | #else | ||
77 | |||
78 | if (getenv("XDG_CONFIG_HOME")) { | ||
79 | user_config_dir = strdup(getenv("XDG_CONFIG_HOME")); | ||
80 | } else { | ||
81 | user_config_dir = malloc(strlen(getenv("HOME")) + strlen("/.config") + 1); | ||
82 | if (user_config_dir) { | ||
83 | strcpy(user_config_dir, getenv("HOME")); | ||
84 | strcat(user_config_dir, "/.config"); | ||
85 | } | ||
86 | } | ||
87 | return user_config_dir; | ||
88 | |||
89 | #endif | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Creates the config directory. | ||
94 | */ | ||
95 | int create_user_config_dir(char *path) | ||
96 | { | ||
97 | |||
98 | int mkdir_err; | ||
99 | |||
100 | #ifdef WIN32 | ||
101 | |||
102 | char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); | ||
103 | strcpy(fullpath, path); | ||
104 | strcat(fullpath, CONFIGDIR); | ||
105 | |||
106 | mkdir_err = _mkdir(fullpath); | ||
107 | struct __stat64 buf; | ||
108 | if (mkdir_err && (errno != EEXIST || _wstat64(fullpath, &buf) || !S_ISDIR(buf.st_mode))) { | ||
109 | free(fullpath); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | #else | ||
114 | |||
115 | mkdir_err = mkdir(path, 0700); | ||
116 | struct stat buf; | ||
117 | |||
118 | if(mkdir_err && (errno != EEXIST || stat(path, &buf) || !S_ISDIR(buf.st_mode))) { | ||
119 | return -1; | ||
120 | } | ||
121 | |||
122 | char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); | ||
123 | strcpy(fullpath, path); | ||
124 | strcat(fullpath, CONFIGDIR); | ||
125 | |||
126 | mkdir_err = mkdir(fullpath, 0700); | ||
127 | |||
128 | if(mkdir_err && (errno != EEXIST || stat(fullpath, &buf) || !S_ISDIR(buf.st_mode))) { | ||
129 | free(fullpath); | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | #endif | ||
134 | |||
135 | return 0; | ||
136 | } | ||
diff --git a/testing/toxic/configdir.h b/testing/toxic/configdir.h new file mode 100644 index 00000000..fad949cf --- /dev/null +++ b/testing/toxic/configdir.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
3 | * | ||
4 | * This file is part of Tox. | ||
5 | * | ||
6 | * Tox is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation, either version 3 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * Tox is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifdef _win32 | ||
22 | #define CONFIGDIR "\\toxic\\" | ||
23 | #else | ||
24 | #define CONFIGDIR "/toxic/" | ||
25 | #endif | ||
26 | |||
27 | #ifndef S_ISDIR | ||
28 | #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) | ||
29 | #endif | ||
30 | |||
31 | char *get_user_config_dir(void); | ||
32 | |||
33 | int create_user_config_dir(char *path); | ||
diff --git a/testing/toxic/main.c b/testing/toxic/main.c index b2310c80..162cce68 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c | |||
@@ -3,14 +3,23 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <curses.h> | 5 | #include <curses.h> |
6 | #include <errno.h> | ||
6 | #include <stdio.h> | 7 | #include <stdio.h> |
7 | #include <stdlib.h> | 8 | #include <stdlib.h> |
8 | #include <stdbool.h> | 9 | #include <stdbool.h> |
9 | #include <stdint.h> | 10 | #include <stdint.h> |
10 | 11 | ||
12 | #ifdef _win32 | ||
13 | #include <direct.h> | ||
14 | #else | ||
15 | #include <sys/stat.h> | ||
16 | #include <sys/types.h> | ||
17 | #endif | ||
18 | |||
11 | #include "../../core/Messenger.h" | 19 | #include "../../core/Messenger.h" |
12 | #include "../../core/network.h" | 20 | #include "../../core/network.h" |
13 | 21 | ||
22 | #include "configdir.h" | ||
14 | #include "windows.h" | 23 | #include "windows.h" |
15 | 24 | ||
16 | extern ToxWindow new_prompt(); | 25 | extern ToxWindow new_prompt(); |
@@ -22,7 +31,10 @@ extern int add_req(uint8_t *public_key); // XXX | |||
22 | 31 | ||
23 | /* Holds status of chat windows */ | 32 | /* Holds status of chat windows */ |
24 | char WINDOW_STATUS[MAX_WINDOW_SLOTS]; | 33 | char WINDOW_STATUS[MAX_WINDOW_SLOTS]; |
25 | #define TOXICVER "0.1.0" //Will be moved to a -D flag later | 34 | |
35 | #ifndef TOXICVER | ||
36 | #define TOXICVER "NOVER" //Use the -D flag to set this | ||
37 | #endif | ||
26 | 38 | ||
27 | static ToxWindow windows[MAX_WINDOW_SLOTS]; | 39 | static ToxWindow windows[MAX_WINDOW_SLOTS]; |
28 | static ToxWindow* prompt; | 40 | static ToxWindow* prompt; |
@@ -37,7 +49,7 @@ void on_request(uint8_t *public_key, uint8_t *data, uint16_t length) | |||
37 | wprintw(prompt->window, "\nFriend request from:\n"); | 49 | wprintw(prompt->window, "\nFriend request from:\n"); |
38 | 50 | ||
39 | int i; | 51 | int i; |
40 | for (i = 0; i < 32; ++i) { | 52 | for (i = 0; i < KEY_SIZE_BYTES; ++i) { |
41 | wprintw(prompt->window, "%02x", public_key[i] & 0xff); | 53 | wprintw(prompt->window, "%02x", public_key[i] & 0xff); |
42 | } | 54 | } |
43 | 55 | ||
@@ -331,9 +343,19 @@ int main(int argc, char *argv[]) | |||
331 | { | 343 | { |
332 | int ch; | 344 | int ch; |
333 | int f_flag = 0; | 345 | int f_flag = 0; |
334 | char *filename = "data"; | 346 | char *user_config_dir = get_user_config_dir(); |
347 | char *filename; | ||
348 | int config_err = create_user_config_dir(user_config_dir); | ||
349 | if(config_err) { | ||
350 | filename = "data"; | ||
351 | } else { | ||
352 | filename = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); | ||
353 | strcpy(filename, user_config_dir); | ||
354 | strcat(filename, CONFIGDIR); | ||
355 | strcat(filename, "data"); | ||
356 | } | ||
357 | |||
335 | ToxWindow* a; | 358 | ToxWindow* a; |
336 | |||
337 | int i = 0; | 359 | int i = 0; |
338 | for (i = 0; i < argc; ++i) { | 360 | for (i = 0; i < argc; ++i) { |
339 | if (argv[i] == NULL) | 361 | if (argv[i] == NULL) |
@@ -351,6 +373,7 @@ int main(int argc, char *argv[]) | |||
351 | init_term(); | 373 | init_term(); |
352 | init_tox(); | 374 | init_tox(); |
353 | load_data(filename); | 375 | load_data(filename); |
376 | free(filename); | ||
354 | init_windows(); | 377 | init_windows(); |
355 | init_window_status(); | 378 | init_window_status(); |
356 | 379 | ||
@@ -360,6 +383,13 @@ int main(int argc, char *argv[]) | |||
360 | "defaulting to 'data' for a keyfile...\n"); | 383 | "defaulting to 'data' for a keyfile...\n"); |
361 | attroff(COLOR_PAIR(3) | A_BOLD); | 384 | attroff(COLOR_PAIR(3) | A_BOLD); |
362 | } | 385 | } |
386 | |||
387 | if(config_err) { | ||
388 | attron(COLOR_PAIR(3) | A_BOLD); | ||
389 | wprintw(prompt->window, "Unable to determine configuration directory!\n" | ||
390 | "defaulting to 'data' for a keyfile...\n"); | ||
391 | attroff(COLOR_PAIR(3) | A_BOLD); | ||
392 | } | ||
363 | 393 | ||
364 | while(true) { | 394 | while(true) { |
365 | /* Update tox */ | 395 | /* Update tox */ |
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 661d881f..eaa8d7bc 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c | |||
@@ -12,12 +12,12 @@ | |||
12 | 12 | ||
13 | #include "windows.h" | 13 | #include "windows.h" |
14 | 14 | ||
15 | uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX | 15 | uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX |
16 | uint8_t num_requests=0; // XXX | 16 | uint8_t num_requests=0; // XXX |
17 | 17 | ||
18 | extern void on_friendadded(int friendnumber); | 18 | extern void on_friendadded(int friendnumber); |
19 | static void print_usage(ToxWindow *self); | 19 | static void print_usage(ToxWindow *self); |
20 | static char prompt_buf[256] = {0}; | 20 | static char prompt_buf[MAX_STR_SIZE] = {0}; |
21 | static int prompt_buf_pos = 0; | 21 | static int prompt_buf_pos = 0; |
22 | 22 | ||
23 | // XXX: | 23 | // XXX: |
@@ -43,7 +43,7 @@ unsigned char *hex_string_to_bin(char hex_string[]) | |||
43 | static void execute(ToxWindow *self, char *u_cmd) | 43 | static void execute(ToxWindow *self, char *u_cmd) |
44 | { | 44 | { |
45 | int newlines = 0; | 45 | int newlines = 0; |
46 | char cmd[256] = {0}; | 46 | char cmd[MAX_STR_SIZE] = {0}; |
47 | int i; | 47 | int i; |
48 | for (i = 0; i < strlen(prompt_buf); ++i) { | 48 | for (i = 0; i < strlen(prompt_buf); ++i) { |
49 | if (u_cmd[i] == '\n') | 49 | if (u_cmd[i] == '\n') |
@@ -53,9 +53,9 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | int leading_spc = 0; | 55 | int leading_spc = 0; |
56 | for (i = 0; i < 256 && isspace(cmd[i]); ++i) | 56 | for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i) |
57 | leading_spc++; | 57 | leading_spc++; |
58 | memmove(cmd, cmd + leading_spc, 256 - leading_spc); | 58 | memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc); |
59 | 59 | ||
60 | int cmd_end = strlen(cmd); | 60 | int cmd_end = strlen(cmd); |
61 | while (cmd_end > 0 && cmd_end--) | 61 | while (cmd_end > 0 && cmd_end--) |
@@ -121,7 +121,7 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | else if (!strncmp(cmd, "add ", strlen("add "))) { | 123 | else if (!strncmp(cmd, "add ", strlen("add "))) { |
124 | uint8_t id_bin[32]; | 124 | uint8_t id_bin[KEY_SIZE_BYTES]; |
125 | char xx[3]; | 125 | char xx[3]; |
126 | uint32_t x; | 126 | uint32_t x; |
127 | char *id = strchr(cmd, ' '); | 127 | char *id = strchr(cmd, ' '); |
@@ -136,12 +136,12 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
136 | msg++; | 136 | msg++; |
137 | } | 137 | } |
138 | else msg = ""; | 138 | else msg = ""; |
139 | if (strlen(id) != 2*32) { | 139 | if (strlen(id) != 2*KEY_SIZE_BYTES) { |
140 | wprintw(self->window, "Invalid ID length.\n"); | 140 | wprintw(self->window, "Invalid ID length.\n"); |
141 | return; | 141 | return; |
142 | } | 142 | } |
143 | int i; | 143 | int i; |
144 | for (i = 0; i < 32; ++i) { | 144 | for (i = 0; i < KEY_SIZE_BYTES; ++i) { |
145 | xx[0] = id[2*i]; | 145 | xx[0] = id[2*i]; |
146 | xx[1] = id[2*i+1]; | 146 | xx[1] = id[2*i+1]; |
147 | xx[2] = '\0'; | 147 | xx[2] = '\0'; |
@@ -228,17 +228,6 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
231 | else if (!strncmp(cmd, "statusmsg ", strlen("statumsg "))) { | ||
232 | char *msg = strchr(cmd, ' '); | ||
233 | if (msg == NULL) { | ||
234 | wprintw(self->window, "Invalid syntax.\n"); | ||
235 | return; | ||
236 | } | ||
237 | msg++; | ||
238 | m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); | ||
239 | wprintw(self->window, "Status set to: %s\n", msg); | ||
240 | } | ||
241 | |||
242 | else if (!strncmp(cmd, "nick ", strlen("nick "))) { | 231 | else if (!strncmp(cmd, "nick ", strlen("nick "))) { |
243 | char *nick = strchr(cmd, ' '); | 232 | char *nick = strchr(cmd, ' '); |
244 | if (nick == NULL) { | 233 | if (nick == NULL) { |
@@ -251,9 +240,9 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
251 | } | 240 | } |
252 | 241 | ||
253 | else if (!strcmp(cmd, "myid")) { | 242 | else if (!strcmp(cmd, "myid")) { |
254 | char id[32*2 + 1] = {0}; | 243 | char id[KEY_SIZE_BYTES*2 + 1] = {0}; |
255 | size_t i; | 244 | size_t i; |
256 | for (i = 0; i < 32; ++i) { | 245 | for (i = 0; i < KEY_SIZE_BYTES; ++i) { |
257 | char xx[3]; | 246 | char xx[3]; |
258 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); | 247 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); |
259 | strcat(id, xx); | 248 | strcat(id, xx); |
@@ -372,7 +361,6 @@ static void print_usage(ToxWindow *self) | |||
372 | wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); | 361 | wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); |
373 | wprintw(self->window, " add <id> <message> : Add friend\n"); | 362 | wprintw(self->window, " add <id> <message> : Add friend\n"); |
374 | wprintw(self->window, " status <type> <message> : Set your status\n"); | 363 | wprintw(self->window, " status <type> <message> : Set your status\n"); |
375 | wprintw(self->window, " statusmsg <message> : Set your status\n"); | ||
376 | wprintw(self->window, " nick <nickname> : Set your nickname\n"); | 364 | wprintw(self->window, " nick <nickname> : Set your nickname\n"); |
377 | wprintw(self->window, " accept <number> : Accept friend request\n"); | 365 | wprintw(self->window, " accept <number> : Accept friend request\n"); |
378 | wprintw(self->window, " myid : Print your ID\n"); | 366 | wprintw(self->window, " myid : Print your ID\n"); |
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h index cb45614d..287e534a 100644 --- a/testing/toxic/windows.h +++ b/testing/toxic/windows.h | |||
@@ -5,7 +5,9 @@ | |||
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #define TOXWINDOWS_MAX_NUM 32 | 6 | #define TOXWINDOWS_MAX_NUM 32 |
7 | #define MAX_FRIENDS_NUM 100 | 7 | #define MAX_FRIENDS_NUM 100 |
8 | 8 | #define MAX_STR_SIZE 256 | |
9 | #define KEY_SIZE_BYTES 32 | ||
10 | |||
9 | /* number of permanent default windows */ | 11 | /* number of permanent default windows */ |
10 | #define N_DEFAULT_WINS 2 | 12 | #define N_DEFAULT_WINS 2 |
11 | 13 | ||