summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorslvr <slvr@unsafeio.com>2013-08-12 23:08:48 +0100
committerslvr <slvr@unsafeio.com>2013-08-12 23:08:48 +0100
commitbe840b46b961080aee8871a1278d9383affa6f4f (patch)
tree2fb12430cdb2bd4d1aac6b4c87505363d0387c3e
parenta56d87cd3f7e20939e7f877a5c6419f28d9b8b24 (diff)
parentf9bfb42504ffb56fdcc028efbe1177fe1d45a26c (diff)
Merge remote-tracking branch 'upstream/master' into timer
Conflicts: core/Messenger.c
-rwxr-xr-xauto_tests/friends_test.c38
-rw-r--r--auto_tests/messenger_test.c50
-rw-r--r--core/Messenger.c546
-rw-r--r--core/Messenger.h134
-rw-r--r--core/friend_requests.c9
-rw-r--r--core/friend_requests.h2
-rw-r--r--testing/Messenger_test.c81
-rw-r--r--testing/nTox.c73
-rw-r--r--testing/nTox.h6
-rw-r--r--testing/toxic/chat.c36
-rw-r--r--testing/toxic/friendlist.c16
-rw-r--r--testing/toxic/main.c66
-rw-r--r--testing/toxic/prompt.c78
-rw-r--r--testing/toxic/windows.h10
14 files changed, 627 insertions, 518 deletions
diff --git a/auto_tests/friends_test.c b/auto_tests/friends_test.c
index 0ba42b61..3c15b35b 100755
--- a/auto_tests/friends_test.c
+++ b/auto_tests/friends_test.c
@@ -44,6 +44,8 @@
44#define c_sleep(x) usleep(1000*x) 44#define c_sleep(x) usleep(1000*x)
45#endif 45#endif
46 46
47static Messenger *m;
48
47uint8_t *parent_id = NULL; 49uint8_t *parent_id = NULL;
48uint8_t *child_id = NULL; 50uint8_t *child_id = NULL;
49 51
@@ -60,16 +62,16 @@ void do_tox(void)
60 dht_on = 0; 62 dht_on = 0;
61 } 63 }
62 64
63 doMessenger(); 65 doMessenger(m);
64} 66}
65 67
66void parent_confirm_message(int num, uint8_t *data, uint16_t length) 68void parent_confirm_message(Messenger *m, int num, uint8_t *data, uint16_t length, void* userdata)
67{ 69{
68 puts("OK"); 70 puts("OK");
69 request_flags |= SECOND_FLAG; 71 request_flags |= SECOND_FLAG;
70} 72}
71 73
72void parent_confirm_status(int num, uint8_t *data, uint16_t length) 74void parent_confirm_status(Messenger *m, int num, uint8_t *data, uint16_t length, void* userdata)
73{ 75{
74 puts("OK"); 76 puts("OK");
75 request_flags |= FIRST_FLAG; 77 request_flags |= FIRST_FLAG;
@@ -84,7 +86,7 @@ int parent_friend_request(void)
84 fputs("Sending child request.", stdout); 86 fputs("Sending child request.", stdout);
85 fflush(stdout); 87 fflush(stdout);
86 88
87 m_addfriend(child_id, (uint8_t *)message, len); 89 m_addfriend(m, child_id, (uint8_t *)message, len);
88 90
89 /* wait on the status change */ 91 /* wait on the status change */
90 for(i = 0; i < WAIT_COUNT; i++) { 92 for(i = 0; i < WAIT_COUNT; i++) {
@@ -106,15 +108,15 @@ int parent_friend_request(void)
106 return 0; 108 return 0;
107} 109}
108 110
109void child_got_request(uint8_t *public_key, uint8_t *data, uint16_t length) 111void child_got_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata)
110{ 112{
111 fputs("OK\nsending status to parent", stdout); 113 fputs("OK\nsending status to parent", stdout);
112 fflush(stdout); 114 fflush(stdout);
113 m_addfriend_norequest(public_key); 115 m_addfriend_norequest(m, public_key);
114 request_flags |= FIRST_FLAG; 116 request_flags |= FIRST_FLAG;
115} 117}
116 118
117void child_got_statuschange(int friend_num, uint8_t *string, uint16_t length) 119void child_got_statuschange(Messenger *m, int friend_num, uint8_t *string, uint16_t length, void* userdata)
118{ 120{
119 request_flags |= SECOND_FLAG; 121 request_flags |= SECOND_FLAG;
120} 122}
@@ -168,12 +170,13 @@ int main(int argc, char *argv[])
168 int i = 0; 170 int i = 0;
169 char *message = "Y-yes Mr. Watson?"; 171 char *message = "Y-yes Mr. Watson?";
170 172
171 initMessenger(); 173 m = initMessenger();
172 Messenger_save(child_id); 174
175 Messenger_save(m, child_id);
173 msync(child_id, crypto_box_PUBLICKEYBYTES, MS_SYNC); 176 msync(child_id, crypto_box_PUBLICKEYBYTES, MS_SYNC);
174 177
175 m_callback_friendrequest(child_got_request); 178 m_callback_friendrequest(m, child_got_request, NULL);
176 m_callback_statusmessage(child_got_statuschange); 179 m_callback_statusmessage(m, child_got_statuschange, NULL);
177 180
178 /* wait on the friend request */ 181 /* wait on the friend request */
179 while(!(request_flags & FIRST_FLAG)) 182 while(!(request_flags & FIRST_FLAG))
@@ -185,10 +188,12 @@ int main(int argc, char *argv[])
185 188
186 for(i = 0; i < 6; i++) { 189 for(i = 0; i < 6; i++) {
187 /* send the message six times, just to be sure */ 190 /* send the message six times, just to be sure */
188 m_sendmessage(0, (uint8_t *)message, strlen(message)); 191 m_sendmessage(m, 0, (uint8_t *)message, strlen(message));
189 do_tox(); 192 do_tox();
190 } 193 }
191 194
195 cleanupMessenger(m);
196
192 return 0; 197 return 0;
193 } 198 }
194 199
@@ -199,15 +204,16 @@ int main(int argc, char *argv[])
199 return -1; 204 return -1;
200 } 205 }
201 206
207 m = initMessenger();
208
202 msync(parent_id, crypto_box_PUBLICKEYBYTES, MS_SYNC); 209 msync(parent_id, crypto_box_PUBLICKEYBYTES, MS_SYNC);
203 m_callback_statusmessage(parent_confirm_status); 210 m_callback_statusmessage(m, parent_confirm_status, NULL);
204 m_callback_friendmessage(parent_confirm_message); 211 m_callback_friendmessage(m, parent_confirm_message, NULL);
205 212
206 /* hacky way to give the child time to set up */ 213 /* hacky way to give the child time to set up */
207 c_sleep(50); 214 c_sleep(50);
208 215
209 initMessenger(); 216 Messenger_save(m, parent_id);
210 Messenger_save(parent_id);
211 217
212 if(parent_friend_request() == -1) 218 if(parent_friend_request() == -1)
213 return -1; 219 return -1;
diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c
index af902083..64b44d5f 100644
--- a/auto_tests/messenger_test.c
+++ b/auto_tests/messenger_test.c
@@ -34,6 +34,8 @@ unsigned char *bad_id = NULL;
34 34
35int friend_id_num = 0; 35int friend_id_num = 0;
36 36
37Messenger *m;
38
37unsigned char * hex_string_to_bin(char hex_string[]) 39unsigned char * hex_string_to_bin(char hex_string[])
38{ 40{
39 size_t len = strlen(hex_string); 41 size_t len = strlen(hex_string);
@@ -52,22 +54,22 @@ START_TEST(test_m_sendmesage)
52 int bad_len = MAX_DATA_SIZE; 54 int bad_len = MAX_DATA_SIZE;
53 55
54 56
55 ck_assert(m_sendmessage(-1, (uint8_t *)message, good_len) == 0); 57 ck_assert(m_sendmessage(m, -1, (uint8_t *)message, good_len) == 0);
56 ck_assert(m_sendmessage(REALLY_BIG_NUMBER, (uint8_t *)message, good_len) == 0); 58 ck_assert(m_sendmessage(m, REALLY_BIG_NUMBER, (uint8_t *)message, good_len) == 0);
57 ck_assert(m_sendmessage(17, (uint8_t *)message, good_len) == 0); 59 ck_assert(m_sendmessage(m, 17, (uint8_t *)message, good_len) == 0);
58 ck_assert(m_sendmessage(friend_id_num, (uint8_t *)message, bad_len) == 0); 60 ck_assert(m_sendmessage(m, friend_id_num, (uint8_t *)message, bad_len) == 0);
59} 61}
60END_TEST 62END_TEST
61 63
62START_TEST(test_m_get_userstatus_size) 64START_TEST(test_m_get_userstatus_size)
63{ 65{
64 int rc = 0; 66 int rc = 0;
65 ck_assert_msg((m_get_statusmessage_size(-1) == -1), 67 ck_assert_msg((m_get_statusmessage_size(m, -1) == -1),
66 "m_get_statusmessage_size did NOT catch an argument of -1"); 68 "m_get_statusmessage_size did NOT catch an argument of -1");
67 ck_assert_msg((m_get_statusmessage_size(REALLY_BIG_NUMBER) == -1), 69 ck_assert_msg((m_get_statusmessage_size(m, REALLY_BIG_NUMBER) == -1),
68 "m_get_statusmessage_size did NOT catch the following argument: %d\n", 70 "m_get_statusmessage_size did NOT catch the following argument: %d\n",
69 REALLY_BIG_NUMBER); 71 REALLY_BIG_NUMBER);
70 rc = m_get_statusmessage_size(friend_id_num); 72 rc = m_get_statusmessage_size(m, friend_id_num);
71 73
72 /* this WILL error if the original m_addfriend_norequest() failed */ 74 /* this WILL error if the original m_addfriend_norequest() failed */
73 ck_assert_msg((rc > 0 && rc <= MAX_STATUSMESSAGE_LENGTH), 75 ck_assert_msg((rc > 0 && rc <= MAX_STATUSMESSAGE_LENGTH),
@@ -83,11 +85,11 @@ START_TEST(test_m_set_userstatus)
83 uint16_t good_length = strlen(status); 85 uint16_t good_length = strlen(status);
84 uint16_t bad_length = REALLY_BIG_NUMBER; 86 uint16_t bad_length = REALLY_BIG_NUMBER;
85 87
86 if(m_set_statusmessage((uint8_t *)status, bad_length) != -1) 88 if(m_set_statusmessage(m, (uint8_t *)status, bad_length) != -1)
87 ck_abort_msg("m_set_userstatus did NOT catch the following length: %d\n", 89 ck_abort_msg("m_set_userstatus did NOT catch the following length: %d\n",
88 REALLY_BIG_NUMBER); 90 REALLY_BIG_NUMBER);
89 91
90 if((m_set_statusmessage((uint8_t *)status, good_length)) != 0) 92 if((m_set_statusmessage(m, (uint8_t *)status, good_length)) != 0)
91 ck_abort_msg("m_set_userstatus did NOT return 0 on the following length: %d\n" 93 ck_abort_msg("m_set_userstatus did NOT return 0 on the following length: %d\n"
92 "MAX_STATUSMESSAGE_LENGTH: %d\n", good_length, MAX_STATUSMESSAGE_LENGTH); 94 "MAX_STATUSMESSAGE_LENGTH: %d\n", good_length, MAX_STATUSMESSAGE_LENGTH);
93} 95}
@@ -95,9 +97,9 @@ END_TEST
95 97
96START_TEST(test_m_friendstatus) 98START_TEST(test_m_friendstatus)
97{ 99{
98 ck_assert_msg((m_friendstatus(-1) == NOFRIEND), 100 ck_assert_msg((m_friendstatus(m, -1) == NOFRIEND),
99 "m_friendstatus did NOT catch an argument of -1.\n"); 101 "m_friendstatus did NOT catch an argument of -1.\n");
100 ck_assert_msg((m_friendstatus(REALLY_BIG_NUMBER) == NOFRIEND), 102 ck_assert_msg((m_friendstatus(m, REALLY_BIG_NUMBER) == NOFRIEND),
101 "m_friendstatus did NOT catch an argument of %d.\n", 103 "m_friendstatus did NOT catch an argument of %d.\n",
102 REALLY_BIG_NUMBER); 104 REALLY_BIG_NUMBER);
103} 105}
@@ -105,9 +107,9 @@ END_TEST
105 107
106START_TEST(test_m_delfriend) 108START_TEST(test_m_delfriend)
107{ 109{
108 ck_assert_msg((m_delfriend(-1) == -1), 110 ck_assert_msg((m_delfriend(m, -1) == -1),
109 "m_delfriend did NOT catch an argument of -1\n"); 111 "m_delfriend did NOT catch an argument of -1\n");
110 ck_assert_msg((m_delfriend(REALLY_BIG_NUMBER) == -1), 112 ck_assert_msg((m_delfriend(m, REALLY_BIG_NUMBER) == -1),
111 "m_delfriend did NOT catch the following number: %d\n", 113 "m_delfriend did NOT catch the following number: %d\n",
112 REALLY_BIG_NUMBER); 114 REALLY_BIG_NUMBER);
113} 115}
@@ -124,16 +126,16 @@ START_TEST(test_m_addfriend)
124 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES 126 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
125 + crypto_box_ZEROBYTES + 100); 127 + crypto_box_ZEROBYTES + 100);
126 128
127 if(m_addfriend((uint8_t *)friend_id, (uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG) 129 if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG)
128 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len); 130 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len);
129 131
130 /* this will error if the original m_addfriend_norequest() failed */ 132 /* this will error if the original m_addfriend_norequest() failed */
131 if(m_addfriend((uint8_t *)friend_id, (uint8_t *)good_data, good_len) != FAERR_ALREADYSENT) 133 if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, good_len) != FAERR_ALREADYSENT)
132 ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n" 134 ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n"
133 "(this can be caused by the error of m_addfriend_norequest in" 135 "(this can be caused by the error of m_addfriend_norequest in"
134 " the beginning of the suite)\n"); 136 " the beginning of the suite)\n");
135 137
136 if(m_addfriend((uint8_t *)good_id_b, (uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE) 138 if(m_addfriend(m, (uint8_t *)good_id_b, (uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE)
137 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len); 139 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len);
138 140
139 /* this should REALLY error */ 141 /* this should REALLY error */
@@ -152,10 +154,10 @@ START_TEST(test_setname)
152 int good_length = strlen(good_name); 154 int good_length = strlen(good_name);
153 int bad_length = REALLY_BIG_NUMBER; 155 int bad_length = REALLY_BIG_NUMBER;
154 156
155 if(setname((uint8_t *)good_name, bad_length) != -1) 157 if(setname(m, (uint8_t *)good_name, bad_length) != -1)
156 ck_abort_msg("setname() did NOT error on %d as a length argument!\n", 158 ck_abort_msg("setname() did NOT error on %d as a length argument!\n",
157 bad_length); 159 bad_length);
158 if(setname((uint8_t *)good_name, good_length) != 0) 160 if(setname(m, (uint8_t *)good_name, good_length) != 0)
159 ck_abort_msg("setname() did NOT return 0 on good arguments!\n"); 161 ck_abort_msg("setname() did NOT return 0 on good arguments!\n");
160} 162}
161END_TEST 163END_TEST
@@ -166,8 +168,8 @@ START_TEST(test_getself_name)
166 int len = strlen(nickname); 168 int len = strlen(nickname);
167 char nick_check[len]; 169 char nick_check[len];
168 170
169 setname((uint8_t *)nickname, len); 171 setname(m, (uint8_t *)nickname, len);
170 getself_name((uint8_t *)nick_check); 172 getself_name(m, (uint8_t *)nick_check);
171 173
172 ck_assert_msg((!STRINGS_EQUAL(nickname, nick_check)), 174 ck_assert_msg((!STRINGS_EQUAL(nickname, nick_check)),
173 "getself_name failed to return the known name!\n" 175 "getself_name failed to return the known name!\n"
@@ -256,13 +258,15 @@ int main(int argc, char *argv[])
256 good_id_b = hex_string_to_bin(good_id_b_str); 258 good_id_b = hex_string_to_bin(good_id_b_str);
257 bad_id = hex_string_to_bin(bad_id_str); 259 bad_id = hex_string_to_bin(bad_id_str);
258 260
261 m = initMessenger();
262
259 /* setup a default friend and friendnum */ 263 /* setup a default friend and friendnum */
260 if(m_addfriend_norequest((uint8_t *)friend_id) < 0) 264 if(m_addfriend_norequest(m, (uint8_t *)friend_id) < 0)
261 fputs("m_addfriend_norequest() failed on a valid ID!\n" 265 fputs("m_addfriend_norequest() failed on a valid ID!\n"
262 "this was CRITICAL to the test, and the build WILL fail.\n" 266 "this was CRITICAL to the test, and the build WILL fail.\n"
263 "the tests will continue now...\n\n", stderr); 267 "the tests will continue now...\n\n", stderr);
264 268
265 if((friend_id_num = getfriend_id((uint8_t *)friend_id)) < 0) 269 if((friend_id_num = getfriend_id(m, (uint8_t *)friend_id)) < 0)
266 fputs("getfriend_id() failed on a valid ID!\n" 270 fputs("getfriend_id() failed on a valid ID!\n"
267 "this was CRITICAL to the test, and the build WILL fail.\n" 271 "this was CRITICAL to the test, and the build WILL fail.\n"
268 "the tests will continue now...\n\n", stderr); 272 "the tests will continue now...\n\n", stderr);
@@ -276,5 +280,7 @@ int main(int argc, char *argv[])
276 free(good_id_b); 280 free(good_id_b);
277 free(bad_id); 281 free(bad_id);
278 282
283 cleanupMessenger(m);
284
279 return number_failed; 285 return number_failed;
280} 286}
diff --git a/core/Messenger.c b/core/Messenger.c
index 88f71b3d..58993a08 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -26,40 +26,8 @@
26 26
27#define MIN(a,b) (((a)<(b))?(a):(b)) 27#define MIN(a,b) (((a)<(b))?(a):(b))
28 28
29typedef struct { 29static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
30 uint8_t client_id[CLIENT_ID_SIZE]; 30static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
31 int crypt_connection_id;
32 uint64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
33 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */
34 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
35 uint8_t name[MAX_NAME_LENGTH];
36 uint8_t name_sent; /* 0 if we didn't send our name to this friend 1 if we have. */
37 uint8_t *statusmessage;
38 uint16_t statusmessage_length;
39 uint8_t statusmessage_sent;
40 USERSTATUS userstatus;
41 uint8_t userstatus_sent;
42 uint16_t info_size; /* length of the info */
43 uint32_t message_id; /* a semi-unique id used in read receipts */
44 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
45} Friend;
46
47uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
48
49static uint8_t self_name[MAX_NAME_LENGTH];
50static uint16_t self_name_length;
51
52static uint8_t self_statusmessage[MAX_STATUSMESSAGE_LENGTH];
53static uint16_t self_statusmessage_length;
54
55static USERSTATUS self_userstatus;
56
57static Friend *friendlist;
58static uint32_t numfriends;
59
60
61static void set_friend_status(int friendnumber, uint8_t status);
62static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
63 31
64/* 1 if we are online 32/* 1 if we are online
65 0 if we are offline 33 0 if we are offline
@@ -67,24 +35,24 @@ static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *da
67 35
68/* set the size of the friend list to numfriends 36/* set the size of the friend list to numfriends
69 return -1 if realloc fails */ 37 return -1 if realloc fails */
70int realloc_friendlist(uint32_t num) { 38int realloc_friendlist(Messenger *m, uint32_t num) {
71 Friend *newfriendlist = realloc(friendlist, num*sizeof(Friend)); 39 Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend));
72 if (newfriendlist == NULL) 40 if (newfriendlist == NULL)
73 return -1; 41 return -1;
74 memset(&newfriendlist[num-1], 0, sizeof(Friend)); 42 memset(&newfriendlist[num-1], 0, sizeof(Friend));
75 friendlist = newfriendlist; 43 m->friendlist = newfriendlist;
76 return 0; 44 return 0;
77} 45}
78 46
79/* return the friend id associated to that public key. 47/* return the friend id associated to that public key.
80 return -1 if no such friend */ 48 return -1 if no such friend */
81int getfriend_id(uint8_t *client_id) 49int getfriend_id(Messenger *m, uint8_t *client_id)
82{ 50{
83 uint32_t i; 51 uint32_t i;
84 52
85 for (i = 0; i < numfriends; ++i) { 53 for (i = 0; i < m->numfriends; ++i) {
86 if (friendlist[i].status > 0) 54 if (m->friendlist[i].status > 0)
87 if (memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) 55 if (memcmp(client_id, m->friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0)
88 return i; 56 return i;
89 } 57 }
90 58
@@ -95,13 +63,13 @@ int getfriend_id(uint8_t *client_id)
95 make sure that client_id is of size CLIENT_ID_SIZE. 63 make sure that client_id is of size CLIENT_ID_SIZE.
96 return 0 if success 64 return 0 if success
97 return -1 if failure. */ 65 return -1 if failure. */
98int getclient_id(int friend_id, uint8_t *client_id) 66int getclient_id(Messenger *m, int friend_id, uint8_t *client_id)
99{ 67{
100 if (friend_id >= numfriends || friend_id < 0) 68 if (friend_id >= m->numfriends || friend_id < 0)
101 return -1; 69 return -1;
102 70
103 if (friendlist[friend_id].status > 0) { 71 if (m->friendlist[friend_id].status > 0) {
104 memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE); 72 memcpy(client_id, m->friendlist[friend_id].client_id, CLIENT_ID_SIZE);
105 return 0; 73 return 0;
106 } 74 }
107 75
@@ -120,7 +88,7 @@ int getclient_id(int friend_id, uint8_t *client_id)
120 * return FAERR_ALREADYSENT if friend request already sent or already a friend 88 * return FAERR_ALREADYSENT if friend request already sent or already a friend
121 * return FAERR_UNKNOWN for unknown error 89 * return FAERR_UNKNOWN for unknown error
122 */ 90 */
123int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) 91int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length)
124{ 92{
125 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES 93 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
126 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES 94 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
@@ -130,57 +98,57 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
130 return FAERR_NOMESSAGE; 98 return FAERR_NOMESSAGE;
131 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 99 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
132 return FAERR_OWNKEY; 100 return FAERR_OWNKEY;
133 if (getfriend_id(client_id) != -1) 101 if (getfriend_id(m, client_id) != -1)
134 return FAERR_ALREADYSENT; 102 return FAERR_ALREADYSENT;
135 103
136 /* resize the friend list if necessary */ 104 /* resize the friend list if necessary */
137 realloc_friendlist(numfriends + 1); 105 realloc_friendlist(m, m->numfriends + 1);
138 106
139 uint32_t i; 107 uint32_t i;
140 for (i = 0; i <= numfriends; ++i) { 108 for (i = 0; i <= m->numfriends; ++i) {
141 if (friendlist[i].status == NOFRIEND) { 109 if (m->friendlist[i].status == NOFRIEND) {
142 DHT_addfriend(client_id); 110 DHT_addfriend(client_id);
143 friendlist[i].status = FRIEND_ADDED; 111 m->friendlist[i].status = FRIEND_ADDED;
144 friendlist[i].crypt_connection_id = -1; 112 m->friendlist[i].crypt_connection_id = -1;
145 friendlist[i].friend_request_id = -1; 113 m->friendlist[i].friend_request_id = -1;
146 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 114 memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
147 friendlist[i].statusmessage = calloc(1, 1); 115 m->friendlist[i].statusmessage = calloc(1, 1);
148 friendlist[i].statusmessage_length = 1; 116 m->friendlist[i].statusmessage_length = 1;
149 friendlist[i].userstatus = USERSTATUS_NONE; 117 m->friendlist[i].userstatus = USERSTATUS_NONE;
150 memcpy(friendlist[i].info, data, length); 118 memcpy(m->friendlist[i].info, data, length);
151 friendlist[i].info_size = length; 119 m->friendlist[i].info_size = length;
152 friendlist[i].message_id = 0; 120 m->friendlist[i].message_id = 0;
153 friendlist[i].receives_read_receipts = 1; /* default: YES */ 121 m->friendlist[i].receives_read_receipts = 1; /* default: YES */
154 122
155 ++numfriends; 123 ++ m->numfriends;
156 return i; 124 return i;
157 } 125 }
158 } 126 }
159 return FAERR_UNKNOWN; 127 return FAERR_UNKNOWN;
160} 128}
161 129
162int m_addfriend_norequest(uint8_t * client_id) 130int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
163{ 131{
164 if (getfriend_id(client_id) != -1) 132 if (getfriend_id(m, client_id) != -1)
165 return -1; 133 return -1;
166 134
167 /* resize the friend list if necessary */ 135 /* resize the friend list if necessary */
168 realloc_friendlist(numfriends + 1); 136 realloc_friendlist(m, m->numfriends + 1);
169 137
170 uint32_t i; 138 uint32_t i;
171 for (i = 0; i <= numfriends; ++i) { 139 for (i = 0; i <= m->numfriends; ++i) {
172 if(friendlist[i].status == NOFRIEND) { 140 if(m->friendlist[i].status == NOFRIEND) {
173 DHT_addfriend(client_id); 141 DHT_addfriend(client_id);
174 friendlist[i].status = FRIEND_REQUESTED; 142 m->friendlist[i].status = FRIEND_REQUESTED;
175 friendlist[i].crypt_connection_id = -1; 143 m->friendlist[i].crypt_connection_id = -1;
176 friendlist[i].friend_request_id = -1; 144 m->friendlist[i].friend_request_id = -1;
177 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 145 memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
178 friendlist[i].statusmessage = calloc(1, 1); 146 m->friendlist[i].statusmessage = calloc(1, 1);
179 friendlist[i].statusmessage_length = 1; 147 m->friendlist[i].statusmessage_length = 1;
180 friendlist[i].userstatus = USERSTATUS_NONE; 148 m->friendlist[i].userstatus = USERSTATUS_NONE;
181 friendlist[i].message_id = 0; 149 m->friendlist[i].message_id = 0;
182 friendlist[i].receives_read_receipts = 1; /* default: YES */ 150 m->friendlist[i].receives_read_receipts = 1; /* default: YES */
183 ++numfriends; 151 ++ m->numfriends;
184 return i; 152 return i;
185 } 153 }
186 } 154 }
@@ -190,23 +158,23 @@ int m_addfriend_norequest(uint8_t * client_id)
190/* remove a friend 158/* remove a friend
191 return 0 if success 159 return 0 if success
192 return -1 if failure */ 160 return -1 if failure */
193int m_delfriend(int friendnumber) 161int m_delfriend(Messenger *m, int friendnumber)
194{ 162{
195 if (friendnumber >= numfriends || friendnumber < 0) 163 if (friendnumber >= m->numfriends || friendnumber < 0)
196 return -1; 164 return -1;
197 165
198 DHT_delfriend(friendlist[friendnumber].client_id); 166 DHT_delfriend(m->friendlist[friendnumber].client_id);
199 crypto_kill(friendlist[friendnumber].crypt_connection_id); 167 crypto_kill(m->friendlist[friendnumber].crypt_connection_id);
200 free(friendlist[friendnumber].statusmessage); 168 free(m->friendlist[friendnumber].statusmessage);
201 memset(&friendlist[friendnumber], 0, sizeof(Friend)); 169 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
202 uint32_t i; 170 uint32_t i;
203 171
204 for (i = numfriends; i != 0; --i) { 172 for (i = m->numfriends; i != 0; --i) {
205 if (friendlist[i-1].status != NOFRIEND) 173 if (m->friendlist[i-1].status != NOFRIEND)
206 break; 174 break;
207 } 175 }
208 numfriends = i; 176 m->numfriends = i;
209 realloc_friendlist(numfriends + 1); 177 realloc_friendlist(m, m->numfriends + 1);
210 178
211 return 0; 179 return 0;
212} 180}
@@ -216,31 +184,31 @@ int m_delfriend(int friendnumber)
216 return FRIEND_REQUESTED if the friend request was sent 184 return FRIEND_REQUESTED if the friend request was sent
217 return FRIEND_ADDED if the friend was added 185 return FRIEND_ADDED if the friend was added
218 return NOFRIEND if there is no friend with that number */ 186 return NOFRIEND if there is no friend with that number */
219int m_friendstatus(int friendnumber) 187int m_friendstatus(Messenger *m, int friendnumber)
220{ 188{
221 if (friendnumber < 0 || friendnumber >= numfriends) 189 if (friendnumber < 0 || friendnumber >= m->numfriends)
222 return NOFRIEND; 190 return NOFRIEND;
223 return friendlist[friendnumber].status; 191 return m->friendlist[friendnumber].status;
224} 192}
225 193
226/* send a text chat message to an online friend 194/* send a text chat message to an online friend
227 return the message id if packet was successfully put into the send queue 195 return the message id if packet was successfully put into the send queue
228 return 0 if it was not */ 196 return 0 if it was not */
229uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) 197uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_t length)
230{ 198{
231 if (friendnumber < 0 || friendnumber >= numfriends) 199 if (friendnumber < 0 || friendnumber >= m->numfriends)
232 return 0; 200 return 0;
233 uint32_t msgid = ++friendlist[friendnumber].message_id; 201 uint32_t msgid = ++m->friendlist[friendnumber].message_id;
234 if (msgid == 0) 202 if (msgid == 0)
235 msgid = 1; /* otherwise, false error */ 203 msgid = 1; /* otherwise, false error */
236 if(m_sendmessage_withid(friendnumber, msgid, message, length)) { 204 if(m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
237 return msgid; 205 return msgid;
238 } 206 }
239 207
240 return 0; 208 return 0;
241} 209}
242 210
243uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) 211uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
244{ 212{
245 if (length >= (MAX_DATA_SIZE - sizeof(theid))) 213 if (length >= (MAX_DATA_SIZE - sizeof(theid)))
246 return 0; 214 return 0;
@@ -248,34 +216,34 @@ uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message
248 theid = htonl(theid); 216 theid = htonl(theid);
249 memcpy(temp, &theid, sizeof(theid)); 217 memcpy(temp, &theid, sizeof(theid));
250 memcpy(temp + sizeof(theid), message, length); 218 memcpy(temp + sizeof(theid), message, length);
251 return write_cryptpacket_id(friendnumber, PACKET_ID_MESSAGE, temp, length + sizeof(theid)); 219 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE, temp, length + sizeof(theid));
252} 220}
253 221
254/* send an action to an online friend 222/* send an action to an online friend
255 return 1 if packet was successfully put into the send queue 223 return 1 if packet was successfully put into the send queue
256 return 0 if it was not */ 224 return 0 if it was not */
257int m_sendaction(int friendnumber, uint8_t *action, uint32_t length) 225int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t length)
258{ 226{
259 return write_cryptpacket_id(friendnumber, PACKET_ID_ACTION, action, length); 227 return write_cryptpacket_id(m, friendnumber, PACKET_ID_ACTION, action, length);
260} 228}
261 229
262/* send a name packet to friendnumber 230/* send a name packet to friendnumber
263 length is the length with the NULL terminator*/ 231 length is the length with the NULL terminator*/
264static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) 232static int m_sendname(Messenger *m, int friendnumber, uint8_t * name, uint16_t length)
265{ 233{
266 if(length > MAX_NAME_LENGTH || length == 0) 234 if(length > MAX_NAME_LENGTH || length == 0)
267 return 0; 235 return 0;
268 return write_cryptpacket_id(friendnumber, PACKET_ID_NICKNAME, name, length); 236 return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length);
269} 237}
270 238
271/* set the name of a friend 239/* set the name of a friend
272 return 0 if success 240 return 0 if success
273 return -1 if failure */ 241 return -1 if failure */
274static int setfriendname(int friendnumber, uint8_t * name) 242static int setfriendname(Messenger *m, int friendnumber, uint8_t * name)
275{ 243{
276 if (friendnumber >= numfriends || friendnumber < 0) 244 if (friendnumber >= m->numfriends || friendnumber < 0)
277 return -1; 245 return -1;
278 memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH); 246 memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
279 return 0; 247 return 0;
280} 248}
281 249
@@ -285,15 +253,15 @@ static int setfriendname(int friendnumber, uint8_t * name)
285 length is the length of name with the NULL terminator 253 length is the length of name with the NULL terminator
286 return 0 if success 254 return 0 if success
287 return -1 if failure */ 255 return -1 if failure */
288int setname(uint8_t * name, uint16_t length) 256int setname(Messenger *m, uint8_t * name, uint16_t length)
289{ 257{
290 if (length > MAX_NAME_LENGTH || length == 0) 258 if (length > MAX_NAME_LENGTH || length == 0)
291 return -1; 259 return -1;
292 memcpy(self_name, name, length); 260 memcpy(m->name, name, length);
293 self_name_length = length; 261 m->name_length = length;
294 uint32_t i; 262 uint32_t i;
295 for (i = 0; i < numfriends; ++i) 263 for (i = 0; i < m->numfriends; ++i)
296 friendlist[i].name_sent = 0; 264 m->friendlist[i].name_sent = 0;
297 return 0; 265 return 0;
298} 266}
299 267
@@ -301,10 +269,10 @@ int setname(uint8_t * name, uint16_t length)
301 put it in name 269 put it in name
302 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 270 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
303 return the length of the name */ 271 return the length of the name */
304uint16_t getself_name(uint8_t *name) 272uint16_t getself_name(Messenger *m, uint8_t *name)
305{ 273{
306 memcpy(name, self_name, self_name_length); 274 memcpy(name, m->name, m->name_length);
307 return self_name_length; 275 return m->name_length;
308} 276}
309 277
310/* get name of friendnumber 278/* get name of friendnumber
@@ -312,272 +280,298 @@ uint16_t getself_name(uint8_t *name)
312 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 280 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
313 return 0 if success 281 return 0 if success
314 return -1 if failure */ 282 return -1 if failure */
315int getname(int friendnumber, uint8_t * name) 283int getname(Messenger *m, int friendnumber, uint8_t * name)
316{ 284{
317 if (friendnumber >= numfriends || friendnumber < 0) 285 if (friendnumber >= m->numfriends || friendnumber < 0)
318 return -1; 286 return -1;
319 memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH); 287 memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH);
320 return 0; 288 return 0;
321} 289}
322 290
323int m_set_statusmessage(uint8_t *status, uint16_t length) 291int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length)
324{ 292{
325 if (length > MAX_STATUSMESSAGE_LENGTH) 293 if (length > MAX_STATUSMESSAGE_LENGTH)
326 return -1; 294 return -1;
327 memcpy(self_statusmessage, status, length); 295 memcpy(m->statusmessage, status, length);
328 self_statusmessage_length = length; 296 m->statusmessage_length = length;
329 297
330 uint32_t i; 298 uint32_t i;
331 for (i = 0; i < numfriends; ++i) 299 for (i = 0; i < m->numfriends; ++i)
332 friendlist[i].statusmessage_sent = 0; 300 m->friendlist[i].statusmessage_sent = 0;
333 return 0; 301 return 0;
334} 302}
335 303
336int m_set_userstatus(USERSTATUS status) 304int m_set_userstatus(Messenger *m, USERSTATUS status)
337{ 305{
338 if (status >= USERSTATUS_INVALID) { 306 if (status >= USERSTATUS_INVALID) {
339 return -1; 307 return -1;
340 } 308 }
341 self_userstatus = status; 309 m->userstatus = status;
342 uint32_t i; 310 uint32_t i;
343 for (i = 0; i < numfriends; ++i) 311 for (i = 0; i < m->numfriends; ++i)
344 friendlist[i].userstatus_sent = 0; 312 m->friendlist[i].userstatus_sent = 0;
345 return 0; 313 return 0;
346} 314}
347 315
348/* return the size of friendnumber's user status 316/* return the size of friendnumber's user status
349 guaranteed to be at most MAX_STATUSMESSAGE_LENGTH */ 317 guaranteed to be at most MAX_STATUSMESSAGE_LENGTH */
350int m_get_statusmessage_size(int friendnumber) 318int m_get_statusmessage_size(Messenger *m, int friendnumber)
351{ 319{
352 if (friendnumber >= numfriends || friendnumber < 0) 320 if (friendnumber >= m->numfriends || friendnumber < 0)
353 return -1; 321 return -1;
354 return friendlist[friendnumber].statusmessage_length; 322 return m->friendlist[friendnumber].statusmessage_length;
355} 323}
356 324
357/* copy the user status of friendnumber into buf, truncating if needed to maxlen 325/* copy the user status of friendnumber into buf, truncating if needed to maxlen
358 bytes, use m_get_statusmessage_size to find out how much you need to allocate */ 326 bytes, use m_get_statusmessage_size to find out how much you need to allocate */
359int m_copy_statusmessage(int friendnumber, uint8_t * buf, uint32_t maxlen) 327int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t * buf, uint32_t maxlen)
360{ 328{
361 if (friendnumber >= numfriends || friendnumber < 0) 329 if (friendnumber >= m->numfriends || friendnumber < 0)
362 return -1; 330 return -1;
363 memset(buf, 0, maxlen); 331 memset(buf, 0, maxlen);
364 memcpy(buf, friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 332 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
365 return 0; 333 return 0;
366} 334}
367 335
368int m_copy_self_statusmessage(uint8_t * buf, uint32_t maxlen) 336int m_copy_self_statusmessage(Messenger *m, uint8_t * buf, uint32_t maxlen)
369{ 337{
370 memset(buf, 0, maxlen); 338 memset(buf, 0, maxlen);
371 memcpy(buf, self_statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 339 memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
372 return 0; 340 return 0;
373} 341}
374 342
375USERSTATUS m_get_userstatus(int friendnumber) 343USERSTATUS m_get_userstatus(Messenger *m, int friendnumber)
376{ 344{
377 if (friendnumber >= numfriends || friendnumber < 0) 345 if (friendnumber >= m->numfriends || friendnumber < 0)
378 return USERSTATUS_INVALID; 346 return USERSTATUS_INVALID;
379 USERSTATUS status = friendlist[friendnumber].userstatus; 347 USERSTATUS status = m->friendlist[friendnumber].userstatus;
380 if (status >= USERSTATUS_INVALID) { 348 if (status >= USERSTATUS_INVALID) {
381 status = USERSTATUS_NONE; 349 status = USERSTATUS_NONE;
382 } 350 }
383 return status; 351 return status;
384} 352}
385 353
386USERSTATUS m_get_self_userstatus(void) 354USERSTATUS m_get_self_userstatus(Messenger *m)
387{ 355{
388 return self_userstatus; 356 return m->userstatus;
389} 357}
390 358
391static int send_statusmessage(int friendnumber, uint8_t * status, uint16_t length) 359static int send_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length)
392{ 360{
393 return write_cryptpacket_id(friendnumber, PACKET_ID_STATUSMESSAGE, status, length); 361 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
394} 362}
395 363
396static int send_userstatus(int friendnumber, USERSTATUS status) 364static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
397{ 365{
398 uint8_t stat = status; 366 uint8_t stat = status;
399 return write_cryptpacket_id(friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); 367 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
400} 368}
401 369
402static int set_friend_statusmessage(int friendnumber, uint8_t * status, uint16_t length) 370static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length)
403{ 371{
404 if (friendnumber >= numfriends || friendnumber < 0) 372 if (friendnumber >= m->numfriends || friendnumber < 0)
405 return -1; 373 return -1;
406 uint8_t *newstatus = calloc(length, 1); 374 uint8_t *newstatus = calloc(length, 1);
407 memcpy(newstatus, status, length); 375 memcpy(newstatus, status, length);
408 free(friendlist[friendnumber].statusmessage); 376 free(m->friendlist[friendnumber].statusmessage);
409 friendlist[friendnumber].statusmessage = newstatus; 377 m->friendlist[friendnumber].statusmessage = newstatus;
410 friendlist[friendnumber].statusmessage_length = length; 378 m->friendlist[friendnumber].statusmessage_length = length;
411 return 0; 379 return 0;
412} 380}
413 381
414static void set_friend_userstatus(int friendnumber, USERSTATUS status) 382static void set_friend_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
415{ 383{
416 friendlist[friendnumber].userstatus = status; 384 m->friendlist[friendnumber].userstatus = status;
417} 385}
418 386
419/* Sets whether we send read receipts for friendnumber. */ 387/* Sets whether we send read receipts for friendnumber. */
420void m_set_sends_receipts(int friendnumber, int yesno) 388void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
421{ 389{
422 if (yesno != 0 || yesno != 1) 390 if (yesno != 0 || yesno != 1)
423 return; 391 return;
424 if (friendnumber >= numfriends || friendnumber < 0) 392 if (friendnumber >= m->numfriends || friendnumber < 0)
425 return; 393 return;
426 friendlist[friendnumber].receives_read_receipts = yesno; 394 m->friendlist[friendnumber].receives_read_receipts = yesno;
427} 395}
428 396
429/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 397/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
430static uint8_t friend_request_isset = 0; */ 398static uint8_t friend_request_isset = 0; */
431/* set the function that will be executed when a friend request is received. */ 399/* set the function that will be executed when a friend request is received. */
432void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) 400void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata)
433{ 401{
434 callback_friendrequest(function); 402 callback_friendrequest(function, userdata);
435} 403}
436 404
437static void (*friend_message)(int, uint8_t *, uint16_t);
438static uint8_t friend_message_isset = 0;
439
440/* set the function that will be executed when a message from a friend is received. */ 405/* set the function that will be executed when a message from a friend is received. */
441void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) 406void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata)
442{ 407{
443 friend_message = function; 408 m->friend_message = function;
444 friend_message_isset = 1; 409 m->friend_message_isset = 1;
410 m->friend_message_userdata = userdata;
445} 411}
446 412
447static void (*friend_action)(int, uint8_t *, uint16_t); 413void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata)
448static uint8_t friend_action_isset = 0;
449void m_callback_action(void (*function)(int, uint8_t *, uint16_t))
450{ 414{
451 friend_action = function; 415 m->friend_action = function;
452 friend_action_isset = 1; 416 m->friend_action_isset = 1;
417 m->friend_action_userdata = userdata;
453} 418}
454 419
455static void (*friend_namechange)(int, uint8_t *, uint16_t); 420void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata)
456static uint8_t friend_namechange_isset = 0;
457void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t))
458{ 421{
459 friend_namechange = function; 422 m->friend_namechange = function;
460 friend_namechange_isset = 1; 423 m->friend_namechange_isset = 1;
424 m->friend_namechange_userdata = userdata;
461} 425}
462 426
463static void (*friend_statusmessagechange)(int, uint8_t *, uint16_t); 427void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata)
464static uint8_t friend_statusmessagechange_isset = 0;
465void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t))
466{ 428{
467 friend_statusmessagechange = function; 429 m->friend_statusmessagechange = function;
468 friend_statusmessagechange_isset = 1; 430 m->friend_statusmessagechange_isset = 1;
431 m->friend_statuschange_userdata = userdata;
469} 432}
470 433
471static void (*friend_userstatuschange)(int, USERSTATUS); 434void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata)
472static uint8_t friend_userstatuschange_isset = 0;
473void m_callback_userstatus(void (*function)(int, USERSTATUS))
474{ 435{
475 friend_userstatuschange = function; 436 m->friend_userstatuschange = function;
476 friend_userstatuschange_isset = 1; 437 m->friend_userstatuschange_isset = 1;
438 m->friend_userstatuschange_userdata = userdata;
477} 439}
478 440
479static void (*read_receipt)(int, uint32_t); 441void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata)
480static uint8_t read_receipt_isset = 0;
481void m_callback_read_receipt(void (*function)(int, uint32_t))
482{ 442{
483 read_receipt = function; 443 m->read_receipt = function;
484 read_receipt_isset = 1; 444 m->read_receipt_isset = 1;
445 m->read_receipt_userdata = userdata;
485} 446}
486 447
487static void (*friend_connectionstatuschange)(int, uint8_t); 448void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata)
488static uint8_t friend_connectionstatuschange_isset = 0;
489void m_callback_connectionstatus(void (*function)(int, uint8_t))
490{ 449{
491 friend_connectionstatuschange = function; 450 m->friend_connectionstatuschange = function;
492 friend_connectionstatuschange_isset = 1; 451 m->friend_connectionstatuschange_isset = 1;
452 m->friend_connectionstatuschange_userdata = userdata;
493} 453}
494 454
495static void check_friend_connectionstatus(int friendnumber, uint8_t status) 455static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status)
496{ 456{
497 if (!friend_connectionstatuschange_isset) 457 if (!m->friend_connectionstatuschange_isset)
498 return; 458 return;
499 if (status == NOFRIEND) 459 if (status == NOFRIEND)
500 return; 460 return;
501 const uint8_t was_connected = friendlist[friendnumber].status == FRIEND_ONLINE; 461 const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE;
502 const uint8_t is_connected = status == FRIEND_ONLINE; 462 const uint8_t is_connected = status == FRIEND_ONLINE;
503 if (is_connected != was_connected) 463 if (is_connected != was_connected)
504 friend_connectionstatuschange(friendnumber, is_connected); 464 m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata);
505} 465}
506 466
507static void set_friend_status(int friendnumber, uint8_t status) 467void set_friend_status(Messenger *m, int friendnumber, uint8_t status)
508{ 468{
509 check_friend_connectionstatus(friendnumber, status); 469 check_friend_connectionstatus(m, friendnumber, status);
510 friendlist[friendnumber].status = status; 470 m->friendlist[friendnumber].status = status;
511} 471}
512 472
513static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) 473int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length)
514{ 474{
515 if (friendnumber < 0 || friendnumber >= numfriends) 475 if (friendnumber < 0 || friendnumber >= m->numfriends)
516 return 0; 476 return 0;
517 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) 477 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
518 return 0; 478 return 0;
519 uint8_t packet[length + 1]; 479 uint8_t packet[length + 1];
520 packet[0] = packet_id; 480 packet[0] = packet_id;
521 memcpy(packet + 1, data, length); 481 memcpy(packet + 1, data, length);
522 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, packet, length + 1); 482 return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1);
483}
484
485<<<<<<< HEAD
486=======
487#define PORT 33445
488/* run this at startup */
489Messenger * initMessenger(void)
490{
491 Messenger *m = calloc(1, sizeof(Messenger));
492 if( ! m )
493 return 0;
494
495 new_keys();
496 m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online"));
497 initNetCrypto();
498 IP ip;
499 ip.i = 0;
500
501 if(init_networking(ip,PORT) == -1)
502 return 0;
503
504 DHT_init();
505 LosslessUDP_init();
506 friendreq_init();
507 LANdiscovery_init();
508
509 return m;
523} 510}
524 511
512/* run this before closing shop */
513void cleanupMessenger(Messenger *m){
514 /* FIXME TODO it seems no one frees friendlist or all the elements status */
515 free(m);
516}
517
518>>>>>>> upstream/master
525//TODO: make this function not suck. 519//TODO: make this function not suck.
526static void doFriends(void) 520void doFriends(Messenger *m)
527{ 521{
528 /* TODO: add incoming connections and some other stuff. */ 522 /* TODO: add incoming connections and some other stuff. */
529 uint32_t i; 523 uint32_t i;
530 int len; 524 int len;
531 uint8_t temp[MAX_DATA_SIZE]; 525 uint8_t temp[MAX_DATA_SIZE];
532 for (i = 0; i < numfriends; ++i) { 526 for (i = 0; i < m->numfriends; ++i) {
533 if (friendlist[i].status == FRIEND_ADDED) { 527 if (m->friendlist[i].status == FRIEND_ADDED) {
534 int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); 528 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size);
535 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ 529 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
536 set_friend_status(i, FRIEND_REQUESTED); 530 set_friend_status(m, i, FRIEND_REQUESTED);
537 else if (fr > 0) 531 else if (fr > 0)
538 set_friend_status(i, FRIEND_REQUESTED); 532 set_friend_status(m, i, FRIEND_REQUESTED);
539 } 533 }
540 if (friendlist[i].status == FRIEND_REQUESTED || friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ 534 if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
541 if (friendlist[i].status == FRIEND_REQUESTED) { 535 if (m->friendlist[i].status == FRIEND_REQUESTED) {
542 if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ 536 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
543 send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); 537 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size);
544 friendlist[i].friend_request_id = unix_time(); 538 m->friendlist[i].friend_request_id = unix_time();
545 } 539 }
546 } 540 }
547 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); 541 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
548 switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) { 542 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) {
549 case 0: 543 case 0:
550 if (friendip.ip.i > 1) 544 if (friendip.ip.i > 1)
551 friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); 545 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
552 break; 546 break;
553 case 3: /* Connection is established */ 547 case 3: /* Connection is established */
554 set_friend_status(i, FRIEND_ONLINE); 548 set_friend_status(m, i, FRIEND_ONLINE);
555 friendlist[i].name_sent = 0; 549 m->friendlist[i].name_sent = 0;
556 friendlist[i].userstatus_sent = 0; 550 m->friendlist[i].userstatus_sent = 0;
557 friendlist[i].statusmessage_sent = 0; 551 m->friendlist[i].statusmessage_sent = 0;
558 break; 552 break;
559 case 4: 553 case 4:
560 crypto_kill(friendlist[i].crypt_connection_id); 554 crypto_kill(m->friendlist[i].crypt_connection_id);
561 friendlist[i].crypt_connection_id = -1; 555 m->friendlist[i].crypt_connection_id = -1;
562 break; 556 break;
563 default: 557 default:
564 break; 558 break;
565 } 559 }
566 } 560 }
567 while (friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ 561 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
568 if (friendlist[i].name_sent == 0) { 562 if (m->friendlist[i].name_sent == 0) {
569 if (m_sendname(i, self_name, self_name_length)) 563 if (m_sendname(m, i, m->name, m->name_length))
570 friendlist[i].name_sent = 1; 564 m->friendlist[i].name_sent = 1;
571 } 565 }
572 if (friendlist[i].statusmessage_sent == 0) { 566 if (m->friendlist[i].statusmessage_sent == 0) {
573 if (send_statusmessage(i, self_statusmessage, self_statusmessage_length)) 567 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
574 friendlist[i].statusmessage_sent = 1; 568 m->friendlist[i].statusmessage_sent = 1;
575 } 569 }
576 if (friendlist[i].userstatus_sent == 0) { 570 if (m->friendlist[i].userstatus_sent == 0) {
577 if (send_userstatus(i, self_userstatus)) 571 if (send_userstatus(m, i, m->userstatus))
578 friendlist[i].userstatus_sent = 1; 572 m->friendlist[i].userstatus_sent = 1;
579 } 573 }
580 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); 574 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
581 uint8_t packet_id = temp[0]; 575 uint8_t packet_id = temp[0];
582 uint8_t* data = temp + 1; 576 uint8_t* data = temp + 1;
583 int data_length = len - 1; 577 int data_length = len - 1;
@@ -586,10 +580,10 @@ static void doFriends(void)
586 case PACKET_ID_NICKNAME: { 580 case PACKET_ID_NICKNAME: {
587 if (data_length >= MAX_NAME_LENGTH || data_length == 0) 581 if (data_length >= MAX_NAME_LENGTH || data_length == 0)
588 break; 582 break;
589 if(friend_namechange_isset) 583 if(m->friend_namechange_isset)
590 friend_namechange(i, data, data_length); 584 m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata);
591 memcpy(friendlist[i].name, data, data_length); 585 memcpy(m->friendlist[i].name, data, data_length);
592 friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ 586 m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
593 break; 587 break;
594 } 588 }
595 case PACKET_ID_STATUSMESSAGE: { 589 case PACKET_ID_STATUSMESSAGE: {
@@ -597,9 +591,10 @@ static void doFriends(void)
597 break; 591 break;
598 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); 592 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
599 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 593 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
600 if (friend_statusmessagechange_isset) 594 if (m->friend_statusmessagechange_isset)
601 friend_statusmessagechange(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 595 m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH),
602 set_friend_statusmessage(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 596 m->friend_statuschange_userdata);
597 set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
603 free(status); 598 free(status);
604 break; 599 break;
605 } 600 }
@@ -607,9 +602,9 @@ static void doFriends(void)
607 if (data_length != 1) 602 if (data_length != 1)
608 break; 603 break;
609 USERSTATUS status = data[0]; 604 USERSTATUS status = data[0];
610 if (friend_userstatuschange_isset) 605 if (m->friend_userstatuschange_isset)
611 friend_userstatuschange(i, status); 606 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
612 set_friend_userstatus(i, status); 607 set_friend_userstatus(m, i, status);
613 break; 608 break;
614 } 609 }
615 case PACKET_ID_MESSAGE: { 610 case PACKET_ID_MESSAGE: {
@@ -617,16 +612,16 @@ static void doFriends(void)
617 uint8_t message_id_length = 4; 612 uint8_t message_id_length = 4;
618 uint8_t *message = data + message_id_length; 613 uint8_t *message = data + message_id_length;
619 uint16_t message_length = data_length - message_id_length; 614 uint16_t message_length = data_length - message_id_length;
620 if (friendlist[i].receives_read_receipts) { 615 if (m->friendlist[i].receives_read_receipts) {
621 write_cryptpacket_id(i, PACKET_ID_RECEIPT, message_id, message_id_length); 616 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
622 } 617 }
623 if (friend_message_isset) 618 if (m->friend_message_isset)
624 (*friend_message)(i, message, message_length); 619 (*m->friend_message)(m, i, message, message_length, m->friend_message_userdata);
625 break; 620 break;
626 } 621 }
627 case PACKET_ID_ACTION: { 622 case PACKET_ID_ACTION: {
628 if (friend_action_isset) 623 if (m->friend_action_isset)
629 (*friend_action)(i, data, data_length); 624 (*m->friend_action)(m, i, data, data_length, m->friend_action_userdata);
630 break; 625 break;
631 } 626 }
632 case PACKET_ID_RECEIPT: { 627 case PACKET_ID_RECEIPT: {
@@ -635,16 +630,16 @@ static void doFriends(void)
635 break; 630 break;
636 memcpy(&msgid, data, sizeof(msgid)); 631 memcpy(&msgid, data, sizeof(msgid));
637 msgid = ntohl(msgid); 632 msgid = ntohl(msgid);
638 if (read_receipt_isset) 633 if (m->read_receipt_isset)
639 (*read_receipt)(i, msgid); 634 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
640 break; 635 break;
641 } 636 }
642 } 637 }
643 } else { 638 } else {
644 if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ 639 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
645 crypto_kill(friendlist[i].crypt_connection_id); 640 crypto_kill(m->friendlist[i].crypt_connection_id);
646 friendlist[i].crypt_connection_id = -1; 641 m->friendlist[i].crypt_connection_id = -1;
647 set_friend_status(i, FRIEND_CONFIRMED); 642 set_friend_status(m, i, FRIEND_CONFIRMED);
648 } 643 }
649 break; 644 break;
650 } 645 }
@@ -652,20 +647,20 @@ static void doFriends(void)
652 } 647 }
653} 648}
654 649
655static void doInbound(void) 650void doInbound(Messenger *m)
656{ 651{
657 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 652 uint8_t secret_nonce[crypto_box_NONCEBYTES];
658 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 653 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
659 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 654 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
660 int inconnection = crypto_inbound(public_key, secret_nonce, session_key); 655 int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
661 if (inconnection != -1) { 656 if (inconnection != -1) {
662 int friend_id = getfriend_id(public_key); 657 int friend_id = getfriend_id(m, public_key);
663 if (friend_id != -1) { 658 if (friend_id != -1) {
664 crypto_kill(friendlist[friend_id].crypt_connection_id); 659 crypto_kill(m->friendlist[friend_id].crypt_connection_id);
665 friendlist[friend_id].crypt_connection_id = 660 m->friendlist[friend_id].crypt_connection_id =
666 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); 661 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
667 662
668 set_friend_status(friend_id, FRIEND_CONFIRMED); 663 set_friend_status(m, friend_id, FRIEND_CONFIRMED);
669 } 664 }
670 } 665 }
671} 666}
@@ -676,7 +671,11 @@ static void doInbound(void)
676#define LAN_DISCOVERY_INTERVAL 60 671#define LAN_DISCOVERY_INTERVAL 60
677 672
678/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 673/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
674<<<<<<< HEAD
679static int LANdiscovery_timercallback(timer* t, void* ignore) 675static int LANdiscovery_timercallback(timer* t, void* ignore)
676=======
677void LANdiscovery(Messenger *m)
678>>>>>>> upstream/master
680{ 679{
681 send_LANdiscovery(htons(PORT)); 680 send_LANdiscovery(htons(PORT));
682 timer_start(t, LAN_DISCOVERY_INTERVAL); 681 timer_start(t, LAN_DISCOVERY_INTERVAL);
@@ -707,9 +706,10 @@ int initMessenger(void)
707} 706}
708 707
709/* the main loop that needs to be run at least 200 times per second. */ 708/* the main loop that needs to be run at least 200 times per second. */
710void doMessenger(void) 709void doMessenger(Messenger *m)
711{ 710{
712 networking_poll(); 711 networking_poll();
712<<<<<<< HEAD
713 timer_poll(); 713 timer_poll();
714 714
715 doDHT(); 715 doDHT();
@@ -717,17 +717,26 @@ void doMessenger(void)
717 doNetCrypto(); 717 doNetCrypto();
718 doInbound(); 718 doInbound();
719 doFriends(); 719 doFriends();
720=======
721
722 doDHT();
723 doLossless_UDP();
724 doNetCrypto();
725 doInbound(m);
726 doFriends(m);
727 LANdiscovery(m);
728>>>>>>> upstream/master
720} 729}
721 730
722/* returns the size of the messenger data (for saving) */ 731/* returns the size of the messenger data (for saving) */
723uint32_t Messenger_size(void) 732uint32_t Messenger_size(Messenger *m)
724{ 733{
725 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES 734 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
726 + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; 735 + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * m->numfriends;
727} 736}
728 737
729/* save the messenger in data of size Messenger_size() */ 738/* save the messenger in data of size Messenger_size() */
730void Messenger_save(uint8_t *data) 739void Messenger_save(Messenger *m, uint8_t *data)
731{ 740{
732 save_keys(data); 741 save_keys(data);
733 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 742 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@@ -736,14 +745,14 @@ void Messenger_save(uint8_t *data)
736 data += sizeof(size); 745 data += sizeof(size);
737 DHT_save(data); 746 DHT_save(data);
738 data += size; 747 data += size;
739 size = sizeof(Friend) * numfriends; 748 size = sizeof(Friend) * m->numfriends;
740 memcpy(data, &size, sizeof(size)); 749 memcpy(data, &size, sizeof(size));
741 data += sizeof(size); 750 data += sizeof(size);
742 memcpy(data, friendlist, sizeof(Friend) * numfriends); 751 memcpy(data, m->friendlist, sizeof(Friend) * m->numfriends);
743} 752}
744 753
745/* load the messenger from data of size length. */ 754/* load the messenger from data of size length. */
746int Messenger_load(uint8_t * data, uint32_t length) 755int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
747{ 756{
748 if (length == ~0) 757 if (length == ~0)
749 return -1; 758 return -1;
@@ -775,11 +784,12 @@ int Messenger_load(uint8_t * data, uint32_t length)
775 uint32_t i; 784 uint32_t i;
776 for (i = 0; i < num; ++i) { 785 for (i = 0; i < num; ++i) {
777 if(temp[i].status != 0) { 786 if(temp[i].status != 0) {
778 int fnum = m_addfriend_norequest(temp[i].client_id); 787 int fnum = m_addfriend_norequest(m, temp[i].client_id);
779 setfriendname(fnum, temp[i].name); 788 setfriendname(m, fnum, temp[i].name);
780 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ 789 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
781 } 790 }
782 } 791 }
783 free(temp); 792 free(temp);
784 return 0; 793 return 0;
785} 794}
795
diff --git a/core/Messenger.h b/core/Messenger.h
index 9352cfbb..fa69d104 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -73,6 +73,66 @@ typedef enum {
73 USERSTATUS_INVALID 73 USERSTATUS_INVALID
74} USERSTATUS; 74} USERSTATUS;
75 75
76typedef struct {
77 uint8_t client_id[CLIENT_ID_SIZE];
78 int crypt_connection_id;
79 uint64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
80 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */
81 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
82 uint8_t name[MAX_NAME_LENGTH];
83 uint8_t name_sent; /* 0 if we didn't send our name to this friend 1 if we have. */
84 uint8_t *statusmessage;
85 uint16_t statusmessage_length;
86 uint8_t statusmessage_sent;
87 USERSTATUS userstatus;
88 uint8_t userstatus_sent;
89 uint16_t info_size; /* length of the info */
90 uint32_t message_id; /* a semi-unique id used in read receipts */
91 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
92} Friend;
93
94typedef struct Messenger {
95 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
96
97 uint8_t name[MAX_NAME_LENGTH];
98 uint16_t name_length;
99
100 uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH];
101 uint16_t statusmessage_length;
102
103 USERSTATUS userstatus;
104
105 Friend *friendlist;
106 uint32_t numfriends;
107
108 void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
109 uint8_t friend_message_isset;
110 void* friend_message_userdata;
111 void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
112 uint8_t friend_action_isset;
113 void* friend_action_userdata;
114 void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
115 uint8_t friend_namechange_isset;
116 void* friend_namechange_userdata;
117 void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
118 uint8_t friend_statusmessagechange_isset;
119 void* friend_statusmessagechange_userdata;
120 void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void*);
121 uint8_t friend_userstatuschange_isset;
122 void* friend_userstatuschange_userdata;
123 void (*read_receipt)(struct Messenger *m, int, uint32_t, void*);
124 uint8_t read_receipt_isset;
125 void* read_receipt_userdata;
126 void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void*);
127 uint8_t friend_statuschange_isset;
128 void* friend_statuschange_userdata;
129 void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void*);
130 uint8_t friend_connectionstatuschange_isset;
131 void* friend_connectionstatuschange_userdata;
132
133
134} Messenger;
135
76/* 136/*
77 * add a friend 137 * add a friend
78 * set the data that will be sent along with friend request 138 * set the data that will be sent along with friend request
@@ -85,33 +145,33 @@ typedef enum {
85 * return -4 if friend request already sent or already a friend 145 * return -4 if friend request already sent or already a friend
86 * return -5 for unknown error 146 * return -5 for unknown error
87 */ 147 */
88int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); 148int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length);
89 149
90 150
91/* add a friend without sending a friendrequest. 151/* add a friend without sending a friendrequest.
92 returns the friend number if success 152 returns the friend number if success
93 return -1 if failure. */ 153 return -1 if failure. */
94int m_addfriend_norequest(uint8_t *client_id); 154int m_addfriend_norequest(Messenger *m, uint8_t *client_id);
95 155
96/* return the friend id associated to that client id. 156/* return the friend id associated to that client id.
97 return -1 if no such friend */ 157 return -1 if no such friend */
98int getfriend_id(uint8_t *client_id); 158int getfriend_id(Messenger *m, uint8_t *client_id);
99 159
100/* copies the public key associated to that friend id into client_id buffer. 160/* copies the public key associated to that friend id into client_id buffer.
101 make sure that client_id is of size CLIENT_ID_SIZE. 161 make sure that client_id is of size CLIENT_ID_SIZE.
102 return 0 if success 162 return 0 if success
103 return -1 if failure */ 163 return -1 if failure */
104int getclient_id(int friend_id, uint8_t *client_id); 164int getclient_id(Messenger *m, int friend_id, uint8_t *client_id);
105 165
106/* remove a friend */ 166/* remove a friend */
107int m_delfriend(int friendnumber); 167int m_delfriend(Messenger *m, int friendnumber);
108 168
109/* return 4 if friend is online 169/* return 4 if friend is online
110 return 3 if friend is confirmed 170 return 3 if friend is confirmed
111 return 2 if the friend request was sent 171 return 2 if the friend request was sent
112 return 1 if the friend was added 172 return 1 if the friend was added
113 return 0 if there is no friend with that number */ 173 return 0 if there is no friend with that number */
114int m_friendstatus(int friendnumber); 174int m_friendstatus(Messenger *m, int friendnumber);
115 175
116/* send a text chat message to an online friend 176/* send a text chat message to an online friend
117 returns the message id if packet was successfully put into the send queue 177 returns the message id if packet was successfully put into the send queue
@@ -120,13 +180,13 @@ int m_friendstatus(int friendnumber);
120 if one is received. 180 if one is received.
121 m_sendmessage_withid will send a message with the id of your choosing, 181 m_sendmessage_withid will send a message with the id of your choosing,
122 however we can generate an id for you by calling plain m_sendmessage. */ 182 however we can generate an id for you by calling plain m_sendmessage. */
123uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); 183uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_t length);
124uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length); 184uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, uint8_t *message, uint32_t length);
125 185
126/* send an action to an online friend 186/* send an action to an online friend
127 returns 1 if packet was successfully put into the send queue 187 returns 1 if packet was successfully put into the send queue
128 return 0 if it was not */ 188 return 0 if it was not */
129int m_sendaction(int friendnumber, uint8_t *action, uint32_t length); 189int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t length);
130 190
131/* Set our nickname 191/* Set our nickname
132 name must be a string of maximum MAX_NAME_LENGTH length. 192 name must be a string of maximum MAX_NAME_LENGTH length.
@@ -134,73 +194,73 @@ int m_sendaction(int friendnumber, uint8_t *action, uint32_t length);
134 length is the length of name with the NULL terminator 194 length is the length of name with the NULL terminator
135 return 0 if success 195 return 0 if success
136 return -1 if failure */ 196 return -1 if failure */
137int setname(uint8_t *name, uint16_t length); 197int setname(Messenger *m, uint8_t *name, uint16_t length);
138 198
139/* get our nickname 199/* get our nickname
140 put it in name 200 put it in name
141 return the length of the name*/ 201 return the length of the name*/
142uint16_t getself_name(uint8_t *name); 202uint16_t getself_name(Messenger *m, uint8_t *name);
143 203
144/* get name of friendnumber 204/* get name of friendnumber
145 put it in name 205 put it in name
146 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 206 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
147 return 0 if success 207 return 0 if success
148 return -1 if failure */ 208 return -1 if failure */
149int getname(int friendnumber, uint8_t *name); 209int getname(Messenger *m, int friendnumber, uint8_t *name);
150 210
151/* set our user status 211/* set our user status
152 you are responsible for freeing status after 212 you are responsible for freeing status after
153 returns 0 on success, -1 on failure */ 213 returns 0 on success, -1 on failure */
154int m_set_statusmessage(uint8_t *status, uint16_t length); 214int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length);
155int m_set_userstatus(USERSTATUS status); 215int m_set_userstatus(Messenger *m, USERSTATUS status);
156 216
157/* return the length of friendnumber's status message, 217/* return the length of friendnumber's status message,
158 including null 218 including null
159 pass it into malloc */ 219 pass it into malloc */
160int m_get_statusmessage_size(int friendnumber); 220int m_get_statusmessage_size(Messenger *m, int friendnumber);
161 221
162/* copy friendnumber's status message into buf, truncating if size is over maxlen 222/* copy friendnumber's status message into buf, truncating if size is over maxlen
163 get the size you need to allocate from m_get_statusmessage_size 223 get the size you need to allocate from m_get_statusmessage_size
164 The self variant will copy our own status message. */ 224 The self variant will copy our own status message. */
165int m_copy_statusmessage(int friendnumber, uint8_t *buf, uint32_t maxlen); 225int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t *buf, uint32_t maxlen);
166int m_copy_self_statusmessage(uint8_t *buf, uint32_t maxlen); 226int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen);
167 227
168/* Return one of USERSTATUS values. 228/* Return one of USERSTATUS values.
169 * Values unknown to your application should be represented as USERSTATUS_NONE. 229 * Values unknown to your application should be represented as USERSTATUS_NONE.
170 * As above, the self variant will return our own USERSTATUS. 230 * As above, the self variant will return our own USERSTATUS.
171 * If friendnumber is invalid, this shall return USERSTATUS_INVALID. */ 231 * If friendnumber is invalid, this shall return USERSTATUS_INVALID. */
172USERSTATUS m_get_userstatus(int friendnumber); 232USERSTATUS m_get_userstatus(Messenger *m, int friendnumber);
173USERSTATUS m_get_self_userstatus(void); 233USERSTATUS m_get_self_userstatus(Messenger *m);
174 234
175/* Sets whether we send read receipts for friendnumber. 235/* Sets whether we send read receipts for friendnumber.
176 * This function is not lazy, and it will fail if yesno is not (0 or 1).*/ 236 * This function is not lazy, and it will fail if yesno is not (0 or 1).*/
177void m_set_sends_receipts(int friendnumber, int yesno); 237void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno);
178 238
179/* set the function that will be executed when a friend request is received. 239/* set the function that will be executed when a friend request is received.
180 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 240 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
181void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 241void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata);
182 242
183/* set the function that will be executed when a message from a friend is received. 243/* set the function that will be executed when a message from a friend is received.
184 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ 244 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
185void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); 245void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata);
186 246
187/* set the function that will be executed when an action from a friend is received. 247/* set the function that will be executed when an action from a friend is received.
188 function format is: function(int friendnumber, uint8_t * action, uint32_t length) */ 248 function format is: function(int friendnumber, uint8_t * action, uint32_t length) */
189void m_callback_action(void (*function)(int, uint8_t *, uint16_t)); 249void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata);
190 250
191/* set the callback for name changes 251/* set the callback for name changes
192 function(int friendnumber, uint8_t *newname, uint16_t length) 252 function(int friendnumber, uint8_t *newname, uint16_t length)
193 you are not responsible for freeing newname */ 253 you are not responsible for freeing newname */
194void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); 254void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata);
195 255
196/* set the callback for status message changes 256/* set the callback for status message changes
197 function(int friendnumber, uint8_t *newstatus, uint16_t length) 257 function(int friendnumber, uint8_t *newstatus, uint16_t length)
198 you are not responsible for freeing newstatus */ 258 you are not responsible for freeing newstatus */
199void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); 259void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata);
200 260
201/* set the callback for status type changes 261/* set the callback for status type changes
202 function(int friendnumber, USERSTATUS kind) */ 262 function(int friendnumber, USERSTATUS kind) */
203void m_callback_userstatus(void (*function)(int, USERSTATUS)); 263void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata);
204 264
205/* set the callback for read receipts 265/* set the callback for read receipts
206 function(int friendnumber, uint32_t receipt) 266 function(int friendnumber, uint32_t receipt)
@@ -209,7 +269,7 @@ void m_callback_userstatus(void (*function)(int, USERSTATUS));
209 has been received on the other side. since core doesn't 269 has been received on the other side. since core doesn't
210 track ids for you, receipt may not correspond to any message 270 track ids for you, receipt may not correspond to any message
211 in that case, you should discard it. */ 271 in that case, you should discard it. */
212void m_callback_read_receipt(void (*function)(int, uint32_t)); 272void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata);
213 273
214/* set the callback for connection status changes 274/* set the callback for connection status changes
215 function(int friendnumber, uint8_t status) 275 function(int friendnumber, uint8_t status)
@@ -219,26 +279,30 @@ void m_callback_read_receipt(void (*function)(int, uint32_t));
219 note that this callback is not called when adding friends, thus the "after 279 note that this callback is not called when adding friends, thus the "after
220 being previously online" part. it's assumed that when adding friends, 280 being previously online" part. it's assumed that when adding friends,
221 their connection status is offline. */ 281 their connection status is offline. */
222void m_callback_connectionstatus(void (*function)(int, uint8_t)); 282void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata);
223 283
224/* run this at startup 284/* run this at startup
225 returns 0 if no connection problems 285 * returns allocated instance of Messenger on success
226 returns -1 if there are problems */ 286 * returns 0 if there are problems */
227int initMessenger(void); 287Messenger * initMessenger(void);
288
289/* run this before closing shop
290 * free all datastructures */
291void cleanupMessenger(Messenger *M);
228 292
229/* the main loop that needs to be run at least 200 times per second */ 293/* the main loop that needs to be run at least 200 times per second */
230void doMessenger(void); 294void doMessenger(Messenger *m);
231 295
232/* SAVING AND LOADING FUNCTIONS: */ 296/* SAVING AND LOADING FUNCTIONS: */
233 297
234/* returns the size of the messenger data (for saving) */ 298/* returns the size of the messenger data (for saving) */
235uint32_t Messenger_size(void); 299uint32_t Messenger_size(Messenger *m);
236 300
237/* save the messenger in data (must be allocated memory of size Messenger_size()) */ 301/* save the messenger in data (must be allocated memory of size Messenger_size()) */
238void Messenger_save(uint8_t *data); 302void Messenger_save(Messenger *m, uint8_t *data);
239 303
240/* load the messenger from data of size length */ 304/* load the messenger from data of size length */
241int Messenger_load(uint8_t *data, uint32_t length); 305int Messenger_load(Messenger *m, uint8_t *data, uint32_t length);
242 306
243#ifdef __cplusplus 307#ifdef __cplusplus
244} 308}
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 422cc028..5e9b447c 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -57,14 +57,15 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
57 return num; 57 return num;
58} 58}
59 59
60static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t); 60static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void*);
61static uint8_t handle_friendrequest_isset = 0; 61static uint8_t handle_friendrequest_isset = 0;
62 62static void* handle_friendrequest_userdata;
63/* set the function that will be executed when a friend request is received. */ 63/* set the function that will be executed when a friend request is received. */
64void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) 64void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata)
65{ 65{
66 handle_friendrequest = function; 66 handle_friendrequest = function;
67 handle_friendrequest_isset = 1; 67 handle_friendrequest_isset = 1;
68 handle_friendrequest_userdata = userdata;
68} 69}
69 70
70 71
@@ -121,7 +122,7 @@ static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t len
121 return 1; 122 return 1;
122 123
123 addto_receivedlist(public_key); 124 addto_receivedlist(public_key);
124 (*handle_friendrequest)(public_key, data, len); 125 (*handle_friendrequest)(public_key, data, len, handle_friendrequest_userdata);
125 } else { /* if request is not for us, try routing it. */ 126 } else { /* if request is not for us, try routing it. */
126 if(route_packet(packet + 1, packet, length) == length) 127 if(route_packet(packet + 1, packet, length) == length)
127 return 0; 128 return 0;
diff --git a/core/friend_requests.h b/core/friend_requests.h
index 708d8f66..f18107ce 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -37,7 +37,7 @@ int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length);
37 37
38/* set the function that will be executed when a friend request for us is received. 38/* set the function that will be executed when a friend request for us is received.
39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
40void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 40void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata);
41 41
42/* sets up friendreq packet handlers */ 42/* sets up friendreq packet handlers */
43void friendreq_init(void); 43void friendreq_init(void);
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c
index a11d374b..fa5d6890 100644
--- a/testing/Messenger_test.c
+++ b/testing/Messenger_test.c
@@ -1,21 +1,21 @@
1/* Messenger test 1/* Messenger test
2 * 2 *
3 * This program adds a friend and accepts all friend requests with the proper message. 3 * This program adds a friend and accepts all friend requests with the proper message.
4 * 4 *
5 * It tries sending a message to the added friend. 5 * It tries sending a message to the added friend.
6 * 6 *
7 * If it receives a message from a friend it replies back. 7 * If it receives a message from a friend it replies back.
8 * 8 *
9 * 9 *
10 * This is how I compile it: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} Messenger_test.c 10 * This is how I compile it: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} Messenger_test.c
11 * 11 *
12 * 12 *
13 * Command line arguments are the ip, port and public_key of a node (for bootstrapping). 13 * Command line arguments are the ip, port and public_key of a node (for bootstrapping).
14 * 14 *
15 * EX: ./test 127.0.0.1 33445 CDCFD319CE3460824B33BE58FD86B8941C9585181D8FBD7C79C5721D7C2E9F7C 15 * EX: ./test 127.0.0.1 33445 CDCFD319CE3460824B33BE58FD86B8941C9585181D8FBD7C79C5721D7C2E9F7C
16 * 16 *
17 * Or the argument can be the path to the save file. 17 * Or the argument can be the path to the save file.
18 * 18 *
19 * EX: ./test Save.bak 19 * EX: ./test Save.bak
20 * 20 *
21 * Copyright (C) 2013 Tox project All Rights Reserved. 21 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -34,7 +34,7 @@
34 * 34 *
35 * You should have received a copy of the GNU General Public License 35 * You should have received a copy of the GNU General Public License
36 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 36 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
37 * 37 *
38 */ 38 */
39 39
40#include "../core/Messenger.h" 40#include "../core/Messenger.h"
@@ -51,7 +51,11 @@
51 51
52#endif 52#endif
53 53
54void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) 54/* FIXME needed as print_request has to match the interface expected by
55 * networking_requesthandler and so cannot take a Messenger * */
56static Messenger *m;
57
58void print_request(uint8_t * public_key, uint8_t * data, uint16_t length, void* userdata)
55{ 59{
56 printf("Friend request received from: \n"); 60 printf("Friend request received from: \n");
57 printf("ClientID: "); 61 printf("ClientID: ");
@@ -63,7 +67,7 @@ void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
63 printf("%hhX", public_key[j]); 67 printf("%hhX", public_key[j]);
64 } 68 }
65 printf("\nOf length: %u with data: %s \n", length, data); 69 printf("\nOf length: %u with data: %s \n", length, data);
66 70
67 if(length != sizeof("Install Gentoo")) 71 if(length != sizeof("Install Gentoo"))
68 { 72 {
69 return; 73 return;
@@ -72,14 +76,14 @@ void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
72 //if the request contained the message of peace the person is obviously a friend so we add him. 76 //if the request contained the message of peace the person is obviously a friend so we add him.
73 { 77 {
74 printf("Friend request accepted.\n"); 78 printf("Friend request accepted.\n");
75 m_addfriend_norequest(public_key); 79 m_addfriend_norequest(m, public_key);
76 } 80 }
77} 81}
78 82
79void print_message(int friendnumber, uint8_t * string, uint16_t length) 83void print_message(Messenger *m, int friendnumber, uint8_t * string, uint16_t length, void* userdata)
80{ 84{
81 printf("Message with length %u received from %u: %s \n", length, friendnumber, string); 85 printf("Message with length %u received from %u: %s \n", length, friendnumber, string);
82 m_sendmessage(friendnumber, (uint8_t*)"Test1", 6); 86 m_sendmessage(m, friendnumber, (uint8_t*)"Test1", 6);
83} 87}
84 88
85int main(int argc, char *argv[]) 89int main(int argc, char *argv[])
@@ -88,7 +92,13 @@ int main(int argc, char *argv[])
88 printf("usage %s ip port public_key (of the DHT bootstrap node)\n or\n %s Save.bak\n", argv[0], argv[0]); 92 printf("usage %s ip port public_key (of the DHT bootstrap node)\n or\n %s Save.bak\n", argv[0], argv[0]);
89 exit(0); 93 exit(0);
90 } 94 }
91 initMessenger(); 95
96 m = initMessenger();
97 if( !m ){
98 fputs("Failed to allocate messenger datastructure\n", stderr);
99 exit(0);
100 }
101
92 if(argc > 3) { 102 if(argc > 3) {
93 IP_Port bootstrap_ip_port; 103 IP_Port bootstrap_ip_port;
94 bootstrap_ip_port.port = htons(atoi(argv[2])); 104 bootstrap_ip_port.port = htons(atoi(argv[2]));
@@ -100,13 +110,13 @@ int main(int argc, char *argv[])
100 int read; 110 int read;
101 uint8_t buffer[128000]; 111 uint8_t buffer[128000];
102 read = fread(buffer, 1, 128000, file); 112 read = fread(buffer, 1, 128000, file);
103 printf("Messenger loaded: %i\n", Messenger_load(buffer, read)); 113 printf("Messenger loaded: %i\n", Messenger_load(m, buffer, read));
104 fclose(file); 114 fclose(file);
105 115
106 } 116 }
107 m_callback_friendrequest(print_request); 117 m_callback_friendrequest(m, print_request, NULL);
108 m_callback_friendmessage(print_message); 118 m_callback_friendmessage(m, print_message, NULL);
109 119
110 printf("OUR ID: "); 120 printf("OUR ID: ");
111 uint32_t i; 121 uint32_t i;
112 for(i = 0; i < 32; i++) { 122 for(i = 0; i < 32; i++) {
@@ -114,33 +124,34 @@ int main(int argc, char *argv[])
114 printf("0"); 124 printf("0");
115 printf("%hhX",self_public_key[i]); 125 printf("%hhX",self_public_key[i]);
116 } 126 }
117 127
118 setname((uint8_t *)"Anon", 5); 128 setname(m, (uint8_t *)"Anon", 5);
119 129
120 char temp_id[128]; 130 char temp_id[128];
121 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); 131 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
122 if(scanf("%s", temp_id) != 1) { 132 if(scanf("%s", temp_id) != 1) {
123 return 1; 133 return 1;
124 } 134 }
125 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 135 int num = m_addfriend(m, hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
126 136
127 perror("Initialization"); 137 perror("Initialization");
128 138
129 while(1) { 139 while(1) {
130 uint8_t name[128]; 140 uint8_t name[128];
131 getname(num, name); 141 getname(m, num, name);
132 printf("%s\n", name); 142 printf("%s\n", name);
133 143
134 m_sendmessage(num, (uint8_t*)"Test", 5); 144 m_sendmessage(m, num, (uint8_t*)"Test", 5);
135 doMessenger(); 145 doMessenger(m);
136 c_sleep(30); 146 c_sleep(30);
137 FILE *file = fopen("Save.bak", "wb"); 147 FILE *file = fopen("Save.bak", "wb");
138 if ( file==NULL ){return 1;} 148 if ( file==NULL ){return 1;}
139 uint8_t * buffer = malloc(Messenger_size()); 149 uint8_t * buffer = malloc(Messenger_size(m));
140 Messenger_save(buffer); 150 Messenger_save(m, buffer);
141 size_t write_result = fwrite(buffer, 1, Messenger_size(), file); 151 size_t write_result = fwrite(buffer, 1, Messenger_size(m), file);
142 if (write_result < Messenger_size()) {return 1;} 152 if (write_result < Messenger_size(m)) {return 1;}
143 free(buffer); 153 free(buffer);
144 fclose(file); 154 fclose(file);
145 } 155 }
156 cleanupMessenger(m);
146} 157}
diff --git a/testing/nTox.c b/testing/nTox.c
index ee4d7de4..59d1cbf6 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -85,12 +85,12 @@ void new_lines(char *line)
85} 85}
86 86
87 87
88void print_friendlist() 88void print_friendlist(Messenger *m)
89{ 89{
90 char name[MAX_NAME_LENGTH]; 90 char name[MAX_NAME_LENGTH];
91 int i = 0; 91 int i = 0;
92 new_lines("[i] Friend List:"); 92 new_lines("[i] Friend List:");
93 while(getname(i, (uint8_t *)name) != -1) { 93 while(getname(m, i, (uint8_t *)name) != -1) {
94 /* account for the longest name and the longest "base" string */ 94 /* account for the longest name and the longest "base" string */
95 char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")]; 95 char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")];
96 96
@@ -107,13 +107,13 @@ void print_friendlist()
107 new_lines("\tno friends! D:"); 107 new_lines("\tno friends! D:");
108} 108}
109 109
110char *format_message(char *message, int friendnum) 110char *format_message(Messenger *m, char *message, int friendnum)
111{ 111{
112 char name[MAX_NAME_LENGTH]; 112 char name[MAX_NAME_LENGTH];
113 if (friendnum != -1) { 113 if (friendnum != -1) {
114 getname(friendnum, (uint8_t*)name); 114 getname(m, friendnum, (uint8_t*)name);
115 } else { 115 } else {
116 getself_name((uint8_t*)name); 116 getself_name(m, (uint8_t*)name);
117 } 117 }
118 char *msg = malloc(100+strlen(message)+strlen(name)+1); 118 char *msg = malloc(100+strlen(message)+strlen(name)+1);
119 119
@@ -133,7 +133,7 @@ char *format_message(char *message, int friendnum)
133 return msg; 133 return msg;
134} 134}
135 135
136void line_eval(char *line) 136void line_eval(Messenger *m, char *line)
137{ 137{
138 if (line[0] == '/') { 138 if (line[0] == '/') {
139 char inpt_command = line[1]; 139 char inpt_command = line[1];
@@ -148,7 +148,7 @@ void line_eval(char *line)
148 temp_id[i] = line[i+prompt_offset]; 148 temp_id[i] = line[i+prompt_offset];
149 149
150 unsigned char *bin_string = hex_string_to_bin(temp_id); 150 unsigned char *bin_string = hex_string_to_bin(temp_id);
151 int num = m_addfriend(bin_string, (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 151 int num = m_addfriend(m, bin_string, (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
152 free(bin_string); 152 free(bin_string);
153 char numstring[100]; 153 char numstring[100];
154 switch (num) { 154 switch (num) {
@@ -175,7 +175,7 @@ void line_eval(char *line)
175 do_refresh(); 175 do_refresh();
176 } 176 }
177 else if (inpt_command == 'd') { 177 else if (inpt_command == 'd') {
178 doMessenger(); 178 doMessenger(m);
179 } 179 }
180 else if (inpt_command == 'm') { //message command: /m friendnumber messsage 180 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
181 size_t len = strlen(line); 181 size_t len = strlen(line);
@@ -196,10 +196,10 @@ void line_eval(char *line)
196 } 196 }
197 } 197 }
198 int num = atoi(numstring); 198 int num = atoi(numstring);
199 if (m_sendmessage(num, (uint8_t*) message, strlen(message) + 1) != 1) { 199 if (m_sendmessage(m, num, (uint8_t*) message, strlen(message) + 1) != 1) {
200 new_lines("[i] could not send message"); 200 new_lines("[i] could not send message");
201 } else { 201 } else {
202 new_lines(format_message(message, -1)); 202 new_lines(format_message(m, message, -1));
203 } 203 }
204 } 204 }
205 else if (inpt_command == 'n') { 205 else if (inpt_command == 'n') {
@@ -211,13 +211,13 @@ void line_eval(char *line)
211 name[i-3] = line[i]; 211 name[i-3] = line[i];
212 } 212 }
213 name[i-3] = 0; 213 name[i-3] = 0;
214 setname(name, i - 2); 214 setname(m, name, i - 2);
215 char numstring[100]; 215 char numstring[100];
216 sprintf(numstring, "[i] changed nick to %s", (char*)name); 216 sprintf(numstring, "[i] changed nick to %s", (char*)name);
217 new_lines(numstring); 217 new_lines(numstring);
218 } 218 }
219 else if (inpt_command == 'l') { 219 else if (inpt_command == 'l') {
220 print_friendlist(); 220 print_friendlist(m);
221 } 221 }
222 else if (inpt_command == 's') { 222 else if (inpt_command == 's') {
223 uint8_t status[MAX_STATUSMESSAGE_LENGTH]; 223 uint8_t status[MAX_STATUSMESSAGE_LENGTH];
@@ -228,7 +228,7 @@ void line_eval(char *line)
228 status[i-3] = line[i]; 228 status[i-3] = line[i];
229 } 229 }
230 status[i-3] = 0; 230 status[i-3] = 0;
231 m_set_statusmessage(status, strlen((char*)status) + 1); 231 m_set_statusmessage(m, status, strlen((char*)status) + 1);
232 char numstring[100]; 232 char numstring[100];
233 sprintf(numstring, "[i] changed status to %s", (char*)status); 233 sprintf(numstring, "[i] changed status to %s", (char*)status);
234 new_lines(numstring); 234 new_lines(numstring);
@@ -240,7 +240,7 @@ void line_eval(char *line)
240 sprintf(numchar,"[i] you either didn't receive that request or you already accepted it"); 240 sprintf(numchar,"[i] you either didn't receive that request or you already accepted it");
241 new_lines(numchar); 241 new_lines(numchar);
242 } else { 242 } else {
243 int num = m_addfriend_norequest(pending_requests[numf].id); 243 int num = m_addfriend_norequest(m, pending_requests[numf].id);
244 if (num != -1) { 244 if (num != -1) {
245 pending_requests[numf].accepted = 1; 245 pending_requests[numf].accepted = 1;
246 sprintf(numchar, "[i] friend request %u accepted", numf); 246 sprintf(numchar, "[i] friend request %u accepted", numf);
@@ -336,7 +336,7 @@ void do_refresh()
336 refresh(); 336 refresh();
337} 337}
338 338
339void print_request(uint8_t *public_key, uint8_t *data, uint16_t length) 339void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata)
340{ 340{
341 new_lines("[i] received friend request with message:"); 341 new_lines("[i] received friend request with message:");
342 new_lines((char *)data); 342 new_lines((char *)data);
@@ -349,32 +349,32 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
349 do_refresh(); 349 do_refresh();
350} 350}
351 351
352void print_message(int friendnumber, uint8_t * string, uint16_t length) 352void print_message(Messenger *m, int friendnumber, uint8_t * string, uint16_t length, void* userdata)
353{ 353{
354 new_lines(format_message((char*)string, friendnumber)); 354 new_lines(format_message(m, (char*)string, friendnumber));
355} 355}
356 356
357void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) 357void print_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
358{ 358{
359 char name[MAX_NAME_LENGTH]; 359 char name[MAX_NAME_LENGTH];
360 if(getname(friendnumber, (uint8_t*)name) != -1) { 360 if(getname(m, friendnumber, (uint8_t*)name) != -1) {
361 char msg[100+length]; 361 char msg[100+length];
362 sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string); 362 sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string);
363 new_lines(msg); 363 new_lines(msg);
364 } 364 }
365} 365}
366 366
367void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) 367void print_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
368{ 368{
369 char name[MAX_NAME_LENGTH]; 369 char name[MAX_NAME_LENGTH];
370 if(getname(friendnumber, (uint8_t*)name) != -1) { 370 if(getname(m, friendnumber, (uint8_t*)name) != -1) {
371 char msg[100+length+strlen(name)+1]; 371 char msg[100+length+strlen(name)+1];
372 sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string); 372 sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string);
373 new_lines(msg); 373 new_lines(msg);
374 } 374 }
375} 375}
376 376
377void load_key(char *path) 377void load_key(Messenger *m, char *path)
378{ 378{
379 FILE *data_file = fopen(path, "r"); 379 FILE *data_file = fopen(path, "r");
380 int size = 0; 380 int size = 0;
@@ -390,13 +390,13 @@ void load_key(char *path)
390 fputs("[!] could not read data file! exiting...\n", stderr); 390 fputs("[!] could not read data file! exiting...\n", stderr);
391 goto FILE_ERROR; 391 goto FILE_ERROR;
392 } 392 }
393 Messenger_load(data, size); 393 Messenger_load(m, data, size);
394 394
395 } else { 395 } else {
396 //else save new keys 396 //else save new keys
397 int size = Messenger_size(); 397 int size = Messenger_size(m);
398 uint8_t data[size]; 398 uint8_t data[size];
399 Messenger_save(data); 399 Messenger_save(m, data);
400 data_file = fopen(path, "w"); 400 data_file = fopen(path, "w");
401 401
402 if(!data_file) { 402 if(!data_file) {
@@ -435,6 +435,7 @@ int main(int argc, char *argv[])
435 int i = 0; 435 int i = 0;
436 char *filename = "data"; 436 char *filename = "data";
437 char idstring[200] = {0}; 437 char idstring[200] = {0};
438 Messenger *m;
438 439
439 if (argc < 4) { 440 if (argc < 4) {
440 printf("[!] Usage: %s [IP] [port] [public_key] <keyfile>\n", argv[0]); 441 printf("[!] Usage: %s [IP] [port] [public_key] <keyfile>\n", argv[0]);
@@ -458,13 +459,18 @@ int main(int argc, char *argv[])
458 } 459 }
459 } 460 }
460 461
461 initMessenger(); 462 m = initMessenger();
462 load_key(filename); 463 if( !m ){
464 fputs("Failed to allocate Messenger datastructure", stderr);
465 exit(0);
466 }
467
468 load_key(m, filename);
463 469
464 m_callback_friendrequest(print_request); 470 m_callback_friendrequest(m, print_request, NULL);
465 m_callback_friendmessage(print_message); 471 m_callback_friendmessage(m, print_message, NULL);
466 m_callback_namechange(print_nickchange); 472 m_callback_namechange(m, print_nickchange, NULL);
467 m_callback_statusmessage(print_statuschange); 473 m_callback_statusmessage(m, print_statuschange, NULL);
468 474
469 initscr(); 475 initscr();
470 noecho(); 476 noecho();
@@ -494,7 +500,7 @@ int main(int argc, char *argv[])
494 on = 1; 500 on = 1;
495 } 501 }
496 502
497 doMessenger(); 503 doMessenger(m);
498 c_sleep(1); 504 c_sleep(1);
499 do_refresh(); 505 do_refresh();
500 506
@@ -504,7 +510,7 @@ int main(int argc, char *argv[])
504 510
505 getmaxyx(stdscr, y, x); 511 getmaxyx(stdscr, y, x);
506 if (c == '\n') { 512 if (c == '\n') {
507 line_eval(line); 513 line_eval(m, line);
508 strcpy(line, ""); 514 strcpy(line, "");
509 } else if (c == 8 || c == 127) { 515 } else if (c == 8 || c == 127) {
510 line[strlen(line)-1] = '\0'; 516 line[strlen(line)-1] = '\0';
@@ -512,6 +518,7 @@ int main(int argc, char *argv[])
512 strcpy(line, appender(line, (char) c)); 518 strcpy(line, appender(line, (char) c));
513 } 519 }
514 } 520 }
521 cleanupMessenger(m);
515 endwin(); 522 endwin();
516 return 0; 523 return 0;
517} 524}
diff --git a/testing/nTox.h b/testing/nTox.h
index 47c73513..fdd88fb4 100644
--- a/testing/nTox.h
+++ b/testing/nTox.h
@@ -1,5 +1,5 @@
1/* nTox.h 1/* nTox.h
2 * 2 *
3 *Textual frontend for Tox. 3 *Textual frontend for Tox.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#ifndef NTOX_H 24#ifndef NTOX_H
@@ -43,7 +43,7 @@
43#define PUB_KEY_BYTES 32 43#define PUB_KEY_BYTES 32
44 44
45void new_lines(char *line); 45void new_lines(char *line);
46void line_eval(char *line); 46void line_eval(Messenger *m, char *line);
47void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) ; 47void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) ;
48int count_lines(char *string) ; 48int count_lines(char *string) ;
49char *appender(char *str, const char c); 49char *appender(char *str, const char c);
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index e1897230..112b20b7 100644
--- a/testing/toxic/chat.c
+++ b/testing/toxic/chat.c
@@ -29,9 +29,9 @@ extern int active_window;
29extern void del_window(ToxWindow *w, int f_num); 29extern void del_window(ToxWindow *w, int f_num);
30extern void fix_name(uint8_t *name); 30extern void fix_name(uint8_t *name);
31void print_help(ChatContext *self); 31void print_help(ChatContext *self);
32void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo); 32void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd, struct tm *timeinfo);
33 33
34static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len) 34static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len)
35{ 35{
36 ChatContext *ctx = (ChatContext*) self->x; 36 ChatContext *ctx = (ChatContext*) self->x;
37 uint8_t nick[MAX_NAME_LENGTH] = {0}; 37 uint8_t nick[MAX_NAME_LENGTH] = {0};
@@ -43,7 +43,7 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
43 if (ctx->friendnum != num) 43 if (ctx->friendnum != num)
44 return; 44 return;
45 45
46 getname(num, (uint8_t*) &nick); 46 getname(m, num, (uint8_t*) &nick);
47 msg[len-1] = '\0'; 47 msg[len-1] = '\0';
48 nick[MAX_NAME_LENGTH-1] = '\0'; 48 nick[MAX_NAME_LENGTH-1] = '\0';
49 fix_name(msg); 49 fix_name(msg);
@@ -61,7 +61,7 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
61 beep(); 61 beep();
62} 62}
63 63
64static void chat_onAction(ToxWindow *self, int num, uint8_t *action, uint16_t len) 64static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len)
65{ 65{
66 ChatContext *ctx = (ChatContext*) self->x; 66 ChatContext *ctx = (ChatContext*) self->x;
67 time_t now; 67 time_t now;
@@ -117,7 +117,7 @@ int string_is_empty(char *string)
117 return rc; 117 return rc;
118} 118}
119 119
120static void chat_onKey(ToxWindow *self, int key) 120static void chat_onKey(ToxWindow *self, Messenger *m, int key)
121{ 121{
122 ChatContext *ctx = (ChatContext*) self->x; 122 ChatContext *ctx = (ChatContext*) self->x;
123 time_t now; 123 time_t now;
@@ -155,7 +155,7 @@ static void chat_onKey(ToxWindow *self, int key)
155 wmove(self->window, y2-CURS_Y_OFFSET, 0); 155 wmove(self->window, y2-CURS_Y_OFFSET, 0);
156 wclrtobot(self->window); 156 wclrtobot(self->window);
157 if (ctx->line[0] == '/') 157 if (ctx->line[0] == '/')
158 execute(self, ctx, ctx->line, timeinfo); 158 execute(self, ctx, m, ctx->line, timeinfo);
159 else { 159 else {
160 if (!string_is_empty(ctx->line)) { 160 if (!string_is_empty(ctx->line)) {
161 /* make sure the string has at least non-space character */ 161 /* make sure the string has at least non-space character */
@@ -167,7 +167,7 @@ static void chat_onKey(ToxWindow *self, int key)
167 wattroff(ctx->history, COLOR_PAIR(1)); 167 wattroff(ctx->history, COLOR_PAIR(1));
168 wprintw(ctx->history, "%s\n", ctx->line); 168 wprintw(ctx->history, "%s\n", ctx->line);
169 } 169 }
170 if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) { 170 if (m_sendmessage(m, ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
171 wattron(ctx->history, COLOR_PAIR(3)); 171 wattron(ctx->history, COLOR_PAIR(3));
172 wprintw(ctx->history, " * Failed to send message.\n"); 172 wprintw(ctx->history, " * Failed to send message.\n");
173 wattroff(ctx->history, COLOR_PAIR(3)); 173 wattroff(ctx->history, COLOR_PAIR(3));
@@ -178,7 +178,7 @@ static void chat_onKey(ToxWindow *self, int key)
178 } 178 }
179} 179}
180 180
181void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo) 181void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd, struct tm *timeinfo)
182{ 182{
183 if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) { 183 if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
184 wclear(self->window); 184 wclear(self->window);
@@ -210,14 +210,14 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
210 wattroff(ctx->history, COLOR_PAIR(2)); 210 wattroff(ctx->history, COLOR_PAIR(2));
211 211
212 uint8_t selfname[MAX_NAME_LENGTH]; 212 uint8_t selfname[MAX_NAME_LENGTH];
213 int len = getself_name(selfname); 213 int len = getself_name(m, selfname);
214 char msg[MAX_STR_SIZE-len-4]; 214 char msg[MAX_STR_SIZE-len-4];
215 snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t*) selfname, action); 215 snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t*) selfname, action);
216 216
217 wattron(ctx->history, COLOR_PAIR(1)); 217 wattron(ctx->history, COLOR_PAIR(1));
218 wprintw(ctx->history, msg); 218 wprintw(ctx->history, msg);
219 wattroff(ctx->history, COLOR_PAIR(1)); 219 wattroff(ctx->history, COLOR_PAIR(1));
220 if (m_sendaction(ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) { 220 if (m_sendaction(m, ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) {
221 wattron(ctx->history, COLOR_PAIR(3)); 221 wattron(ctx->history, COLOR_PAIR(3));
222 wprintw(ctx->history, " * Failed to send action\n"); 222 wprintw(ctx->history, " * Failed to send action\n");
223 wattroff(ctx->history, COLOR_PAIR(3)); 223 wattroff(ctx->history, COLOR_PAIR(3));
@@ -256,13 +256,13 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
256 256
257 msg = strchr(status, ' '); 257 msg = strchr(status, ' ');
258 if (msg == NULL) { 258 if (msg == NULL) {
259 m_set_userstatus(status_kind); 259 m_set_userstatus(m, status_kind);
260 wprintw(ctx->history, "Status set to: %s\n", status_text); 260 wprintw(ctx->history, "Status set to: %s\n", status_text);
261 } 261 }
262 else { 262 else {
263 msg++; 263 msg++;
264 m_set_userstatus(status_kind); 264 m_set_userstatus(m, status_kind);
265 m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); 265 m_set_statusmessage(m, ( uint8_t*) msg, strlen(msg)+1);
266 wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg); 266 wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
267 } 267 }
268 } 268 }
@@ -275,7 +275,7 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
275 return; 275 return;
276 } 276 }
277 nick++; 277 nick++;
278 setname((uint8_t*) nick, strlen(nick)+1); 278 setname(m, (uint8_t*) nick, strlen(nick)+1);
279 wprintw(ctx->history, "Nickname set to: %s\n", nick); 279 wprintw(ctx->history, "Nickname set to: %s\n", nick);
280 } 280 }
281 281
@@ -312,7 +312,7 @@ static void chat_onDraw(ToxWindow *self)
312 wrefresh(self->window); 312 wrefresh(self->window);
313} 313}
314 314
315static void chat_onInit(ToxWindow *self) 315static void chat_onInit(ToxWindow *self, Messenger *m)
316{ 316{
317 int x, y; 317 int x, y;
318 ChatContext *ctx = (ChatContext*) self->x; 318 ChatContext *ctx = (ChatContext*) self->x;
@@ -329,7 +329,7 @@ void print_help(ChatContext *self)
329 wattron(self->history, COLOR_PAIR(2) | A_BOLD); 329 wattron(self->history, COLOR_PAIR(2) | A_BOLD);
330 wprintw(self->history, "Commands:\n"); 330 wprintw(self->history, "Commands:\n");
331 wattroff(self->history, A_BOLD); 331 wattroff(self->history, A_BOLD);
332 332
333 wprintw(self->history, " /status <type> <message> : Set your status\n"); 333 wprintw(self->history, " /status <type> <message> : Set your status\n");
334 wprintw(self->history, " /nick <nickname> : Set your nickname\n"); 334 wprintw(self->history, " /nick <nickname> : Set your nickname\n");
335 wprintw(self->history, " /me <action> : Do an action\n"); 335 wprintw(self->history, " /me <action> : Do an action\n");
@@ -342,7 +342,7 @@ void print_help(ChatContext *self)
342 wattroff(self->history, COLOR_PAIR(2)); 342 wattroff(self->history, COLOR_PAIR(2));
343} 343}
344 344
345ToxWindow new_chat(int friendnum) 345ToxWindow new_chat(Messenger *m, int friendnum)
346{ 346{
347 ToxWindow ret; 347 ToxWindow ret;
348 memset(&ret, 0, sizeof(ret)); 348 memset(&ret, 0, sizeof(ret));
@@ -356,7 +356,7 @@ ToxWindow new_chat(int friendnum)
356 ret.onAction = &chat_onAction; 356 ret.onAction = &chat_onAction;
357 357
358 uint8_t nick[MAX_NAME_LENGTH] = {0}; 358 uint8_t nick[MAX_NAME_LENGTH] = {0};
359 getname(friendnum, (uint8_t*) &nick); 359 getname(m, friendnum, (uint8_t*) &nick);
360 fix_name(nick); 360 fix_name(nick);
361 361
362 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); 362 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
index f2aa1cf4..56061cf9 100644
--- a/testing/toxic/friendlist.c
+++ b/testing/toxic/friendlist.c
@@ -14,7 +14,7 @@
14 14
15extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM]; 15extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM];
16extern int add_window(ToxWindow w, int n); 16extern int add_window(ToxWindow w, int n);
17extern ToxWindow new_chat(int friendnum); 17extern ToxWindow new_chat(Messenger *m, int friendnum);
18 18
19extern int active_window; 19extern int active_window;
20 20
@@ -42,7 +42,7 @@ void fix_name(uint8_t *name)
42 *q = 0; 42 *q = 0;
43} 43}
44 44
45void friendlist_onMessage(ToxWindow *self, int num, uint8_t *str, uint16_t len) 45void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
46{ 46{
47 if (num >= num_friends) 47 if (num >= num_friends)
48 return; 48 return;
@@ -54,7 +54,7 @@ void friendlist_onMessage(ToxWindow *self, int num, uint8_t *str, uint16_t len)
54 for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { 54 for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
55 if (WINDOW_STATUS[i] == -1) { 55 if (WINDOW_STATUS[i] == -1) {
56 WINDOW_STATUS[i] = num; 56 WINDOW_STATUS[i] = num;
57 add_window(new_chat(num), i); 57 add_window(new_chat(m, num), i);
58 active_window = i; 58 active_window = i;
59 break; 59 break;
60 } 60 }
@@ -82,20 +82,20 @@ void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t
82 fix_name(friends[num].status); 82 fix_name(friends[num].status);
83} 83}
84 84
85int friendlist_onFriendAdded(int num) 85int friendlist_onFriendAdded(Messenger *m, int num)
86{ 86{
87 if (num_friends == MAX_FRIENDS_NUM) 87 if (num_friends == MAX_FRIENDS_NUM)
88 return -1; 88 return -1;
89 89
90 friends[num_friends].num = num; 90 friends[num_friends].num = num;
91 getname(num, friends[num_friends].name); 91 getname(m, num, friends[num_friends].name);
92 strcpy((char*) friends[num_friends].name, "unknown"); 92 strcpy((char*) friends[num_friends].name, "unknown");
93 strcpy((char*) friends[num_friends].status, "unknown"); 93 strcpy((char*) friends[num_friends].status, "unknown");
94 friends[num_friends++].chatwin = -1; 94 friends[num_friends++].chatwin = -1;
95 return 0; 95 return 0;
96} 96}
97 97
98static void friendlist_onKey(ToxWindow *self, int key) 98static void friendlist_onKey(ToxWindow *self, Messenger *m, int key)
99{ 99{
100 if (key == KEY_UP) { 100 if (key == KEY_UP) {
101 if (--num_selected < 0) 101 if (--num_selected < 0)
@@ -121,7 +121,7 @@ static void friendlist_onKey(ToxWindow *self, int key)
121 if (WINDOW_STATUS[i] == -1) { 121 if (WINDOW_STATUS[i] == -1) {
122 WINDOW_STATUS[i] = num_selected; 122 WINDOW_STATUS[i] = num_selected;
123 friends[num_selected].chatwin = num_selected; 123 friends[num_selected].chatwin = num_selected;
124 add_window(new_chat(num_selected), i); 124 add_window(new_chat(m, num_selected), i);
125 active_window = i; 125 active_window = i;
126 break; 126 break;
127 } 127 }
@@ -164,7 +164,7 @@ void disable_chatwin(int f_num)
164 friends[f_num].chatwin = -1; 164 friends[f_num].chatwin = -1;
165} 165}
166 166
167static void friendlist_onInit(ToxWindow *self) 167static void friendlist_onInit(ToxWindow *self, Messenger *m)
168{ 168{
169 169
170} 170}
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 752453f2..397f9391 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -25,7 +25,7 @@
25extern ToxWindow new_prompt(); 25extern ToxWindow new_prompt();
26extern ToxWindow new_friendlist(); 26extern ToxWindow new_friendlist();
27 27
28extern int friendlist_onFriendAdded(int num); 28extern int friendlist_onFriendAdded(Messenger *m, int num);
29extern void disable_chatwin(int f_num); 29extern void disable_chatwin(int f_num);
30extern int add_req(uint8_t *public_key); // XXX 30extern int add_req(uint8_t *public_key); // XXX
31extern unsigned char *hex_string_to_bin(char hex_string[]); 31extern unsigned char *hex_string_to_bin(char hex_string[]);
@@ -40,11 +40,13 @@ char WINDOW_STATUS[MAX_WINDOW_SLOTS];
40static ToxWindow windows[MAX_WINDOW_SLOTS]; 40static ToxWindow windows[MAX_WINDOW_SLOTS];
41static ToxWindow* prompt; 41static ToxWindow* prompt;
42 42
43static Messenger *m;
44
43int w_num; 45int w_num;
44int active_window; 46int active_window;
45 47
46/* CALLBACKS START */ 48/* CALLBACKS START */
47void on_request(uint8_t *public_key, uint8_t *data, uint16_t length) 49void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata)
48{ 50{
49 int n = add_req(public_key); 51 int n = add_req(public_key);
50 wprintw(prompt->window, "\nFriend request from:\n"); 52 wprintw(prompt->window, "\nFriend request from:\n");
@@ -63,25 +65,25 @@ void on_request(uint8_t *public_key, uint8_t *data, uint16_t length)
63 } 65 }
64} 66}
65 67
66void on_message(int friendnumber, uint8_t *string, uint16_t length) 68void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
67{ 69{
68 int i; 70 int i;
69 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) { 71 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
70 if (windows[i].onMessage != NULL) 72 if (windows[i].onMessage != NULL)
71 windows[i].onMessage(&windows[i], friendnumber, string, length); 73 windows[i].onMessage(&windows[i], m, friendnumber, string, length);
72 } 74 }
73} 75}
74 76
75void on_action(int friendnumber, uint8_t *string, uint16_t length) 77void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
76{ 78{
77 int i; 79 int i;
78 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) { 80 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
79 if (windows[i].onAction != NULL) 81 if (windows[i].onAction != NULL)
80 windows[i].onAction(&windows[i], friendnumber, string, length); 82 windows[i].onAction(&windows[i], m, friendnumber, string, length);
81 } 83 }
82} 84}
83 85
84void on_nickchange(int friendnumber, uint8_t *string, uint16_t length) 86void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
85{ 87{
86 wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string); 88 wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string);
87 int i; 89 int i;
@@ -91,7 +93,7 @@ void on_nickchange(int friendnumber, uint8_t *string, uint16_t length)
91 } 93 }
92} 94}
93 95
94void on_statuschange(int friendnumber, uint8_t *string, uint16_t length) 96void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata)
95{ 97{
96 wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string); 98 wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string);
97 int i; 99 int i;
@@ -103,7 +105,7 @@ void on_statuschange(int friendnumber, uint8_t *string, uint16_t length)
103 105
104void on_friendadded(int friendnumber) 106void on_friendadded(int friendnumber)
105{ 107{
106 friendlist_onFriendAdded(friendnumber); 108 friendlist_onFriendAdded(m, friendnumber);
107} 109}
108/* CALLBACKS END */ 110/* CALLBACKS END */
109 111
@@ -129,14 +131,14 @@ static void init_term()
129static void init_tox() 131static void init_tox()
130{ 132{
131 /* Init core */ 133 /* Init core */
132 initMessenger(); 134 m = initMessenger();
133 135
134 /* Callbacks */ 136 /* Callbacks */
135 m_callback_friendrequest(on_request); 137 m_callback_friendrequest(m, on_request, NULL);
136 m_callback_friendmessage(on_message); 138 m_callback_friendmessage(m, on_message, NULL);
137 m_callback_namechange(on_nickchange); 139 m_callback_namechange(m, on_nickchange, NULL);
138 m_callback_statusmessage(on_statuschange); 140 m_callback_statusmessage(m, on_statuschange, NULL);
139 m_callback_action(on_action); 141 m_callback_action(m, on_action, NULL);
140} 142}
141 143
142#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */ 144#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */
@@ -157,8 +159,7 @@ int init_connection(void)
157 char line[MAXLINE]; 159 char line[MAXLINE];
158 int linecnt = 0; 160 int linecnt = 0;
159 while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) { 161 while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) {
160 int len = strlen(line); 162 if (strlen(line) > MINLINE)
161 if (len > MINLINE && len < MAXLINE)
162 strcpy(servers[linecnt++], line); 163 strcpy(servers[linecnt++], line);
163 } 164 }
164 if (linecnt < 1) { 165 if (linecnt < 1) {
@@ -211,7 +212,7 @@ int add_window(ToxWindow w, int n)
211 return -1; 212 return -1;
212 213
213 windows[n] = w; 214 windows[n] = w;
214 w.onInit(&w); 215 w.onInit(&w, m);
215 w_num++; 216 w_num++;
216 return n; 217 return n;
217} 218}
@@ -237,7 +238,7 @@ static void init_windows()
237 w_num = 0; 238 w_num = 0;
238 int n_prompt = 0; 239 int n_prompt = 0;
239 int n_friendslist = 1; 240 int n_friendslist = 1;
240 if (add_window(new_prompt(), n_prompt) == -1 241 if (add_window(new_prompt(), n_prompt) == -1
241 || add_window(new_friendlist(), n_friendslist) == -1) { 242 || add_window(new_friendlist(), n_friendslist) == -1) {
242 fprintf(stderr, "add_window() failed.\n"); 243 fprintf(stderr, "add_window() failed.\n");
243 endwin(); 244 endwin();
@@ -248,16 +249,22 @@ static void init_windows()
248 249
249static void do_tox() 250static void do_tox()
250{ 251{
252 static int conn_try = 0;
251 static bool dht_on = false; 253 static bool dht_on = false;
252 if (!dht_on && DHT_isconnected()) { 254 if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
255 init_connection();
256 wprintw(prompt->window, "\nEstablishing connection...\n");
257 }
258 else if (!dht_on && DHT_isconnected()) {
253 dht_on = true; 259 dht_on = true;
254 wprintw(prompt->window, "\nDHT connected.\n"); 260 wprintw(prompt->window, "\nDHT connected.\n");
255 } 261 }
256 else if (dht_on && !DHT_isconnected()) { 262 else if (dht_on && !DHT_isconnected()) {
257 dht_on = false; 263 dht_on = false;
258 wprintw(prompt->window, "\nDHT disconnected.\n"); 264 wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
265 init_connection();
259 } 266 }
260 doMessenger(); 267 doMessenger(m);
261} 268}
262 269
263static void load_data(char *path) 270static void load_data(char *path)
@@ -285,17 +292,17 @@ static void load_data(char *path)
285 endwin(); 292 endwin();
286 exit(1); 293 exit(1);
287 } 294 }
288 Messenger_load(buf, len); 295 Messenger_load(m, buf, len);
289 } 296 }
290 else { 297 else {
291 len = Messenger_size(); 298 len = Messenger_size(m);
292 buf = malloc(len); 299 buf = malloc(len);
293 if (buf == NULL) { 300 if (buf == NULL) {
294 fprintf(stderr, "malloc() failed.\n"); 301 fprintf(stderr, "malloc() failed.\n");
295 endwin(); 302 endwin();
296 exit(1); 303 exit(1);
297 } 304 }
298 Messenger_save(buf); 305 Messenger_save(m, buf);
299 306
300 fd = fopen(path, "w"); 307 fd = fopen(path, "w");
301 if (fd == NULL) { 308 if (fd == NULL) {
@@ -329,7 +336,7 @@ static void draw_bar()
329 move(LINES - 1, 0); 336 move(LINES - 1, 0);
330 337
331 attron(COLOR_PAIR(4) | A_BOLD); 338 attron(COLOR_PAIR(4) | A_BOLD);
332 printw(" TOXIC " TOXICVER "|"); 339 printw(" TOXIC " TOXICVER "|");
333 attroff(COLOR_PAIR(4) | A_BOLD); 340 attroff(COLOR_PAIR(4) | A_BOLD);
334 341
335 int i; 342 int i;
@@ -440,10 +447,6 @@ int main(int argc, char *argv[])
440 load_data(DATA_FILE); 447 load_data(DATA_FILE);
441 free(DATA_FILE); 448 free(DATA_FILE);
442 449
443 int connected = init_connection();
444 if (connected != 0)
445 wprintw(prompt->window, "Auto-connect failed (error code %d)\n", connected);
446
447 if (f_flag == -1) { 450 if (f_flag == -1) {
448 attron(COLOR_PAIR(3) | A_BOLD); 451 attron(COLOR_PAIR(3) | A_BOLD);
449 wprintw(prompt->window, "You passed '-f' without giving an argument.\n" 452 wprintw(prompt->window, "You passed '-f' without giving an argument.\n"
@@ -473,7 +476,8 @@ int main(int argc, char *argv[])
473 if (ch == '\t' || ch == KEY_BTAB) 476 if (ch == '\t' || ch == KEY_BTAB)
474 set_active_window(ch); 477 set_active_window(ch);
475 else if (ch != ERR) 478 else if (ch != ERR)
476 a->onKey(a, ch); 479 a->onKey(a, m, ch);
477 } 480 }
481 cleanupMessenger(m);
478 return 0; 482 return 0;
479} 483}
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index ab44e960..67f80fef 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -20,24 +20,24 @@ static char prompt_buf[MAX_STR_SIZE] = {0};
20static int prompt_buf_pos = 0; 20static int prompt_buf_pos = 0;
21 21
22/* commands */ 22/* commands */
23void cmd_accept(ToxWindow *, char **); 23void cmd_accept(ToxWindow *, Messenger *m, char **);
24void cmd_add(ToxWindow *, char **); 24void cmd_add(ToxWindow *, Messenger *m, char **);
25void cmd_clear(ToxWindow *, char **); 25void cmd_clear(ToxWindow *, Messenger *m, char **);
26void cmd_connect(ToxWindow *, char **); 26void cmd_connect(ToxWindow *, Messenger *m, char **);
27void cmd_help(ToxWindow *, char **); 27void cmd_help(ToxWindow *, Messenger *m, char **);
28void cmd_msg(ToxWindow *, char **); 28void cmd_msg(ToxWindow *, Messenger *m, char **);
29void cmd_myid(ToxWindow *, char **); 29void cmd_myid(ToxWindow *, Messenger *m, char **);
30void cmd_nick(ToxWindow *, char **); 30void cmd_nick(ToxWindow *, Messenger *m, char **);
31void cmd_quit(ToxWindow *, char **); 31void cmd_quit(ToxWindow *, Messenger *m, char **);
32void cmd_status(ToxWindow *, char **); 32void cmd_status(ToxWindow *, Messenger *m, char **);
33void cmd_statusmsg(ToxWindow *, char **); 33void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
34 34
35#define NUM_COMMANDS 13 35#define NUM_COMMANDS 13
36 36
37static struct { 37static struct {
38 char *name; 38 char *name;
39 int numargs; 39 int numargs;
40 void (*func)(ToxWindow *, char **); 40 void (*func)(ToxWindow *, Messenger *m, char **);
41} commands[] = { 41} commands[] = {
42 { "accept", 1, cmd_accept }, 42 { "accept", 1, cmd_accept },
43 { "add", 1, cmd_add }, 43 { "add", 1, cmd_add },
@@ -74,7 +74,7 @@ unsigned char *hex_string_to_bin(char hex_string[])
74 return val; 74 return val;
75} 75}
76 76
77void cmd_accept(ToxWindow *self, char **args) 77void cmd_accept(ToxWindow *self, Messenger *m, char **args)
78{ 78{
79 int num = atoi(args[1]); 79 int num = atoi(args[1]);
80 if (num >= num_requests) { 80 if (num >= num_requests) {
@@ -82,7 +82,7 @@ void cmd_accept(ToxWindow *self, char **args)
82 return; 82 return;
83 } 83 }
84 84
85 num = m_addfriend_norequest(pending_requests[num]); 85 num = m_addfriend_norequest(m, pending_requests[num]);
86 if (num == -1) 86 if (num == -1)
87 wprintw(self->window, "Failed to add friend.\n"); 87 wprintw(self->window, "Failed to add friend.\n");
88 else { 88 else {
@@ -91,7 +91,7 @@ void cmd_accept(ToxWindow *self, char **args)
91 } 91 }
92} 92}
93 93
94void cmd_add(ToxWindow *self, char **args) 94void cmd_add(ToxWindow *self, Messenger *m, char **args)
95{ 95{
96 uint8_t id_bin[KEY_SIZE_BYTES]; 96 uint8_t id_bin[KEY_SIZE_BYTES];
97 char xx[3]; 97 char xx[3];
@@ -121,7 +121,7 @@ void cmd_add(ToxWindow *self, char **args)
121 } 121 }
122 id_bin[i] = x; 122 id_bin[i] = x;
123 } 123 }
124 int num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); 124 int num = m_addfriend(m, id_bin, (uint8_t*) msg, strlen(msg)+1);
125 switch (num) { 125 switch (num) {
126 case FAERR_TOOLONG: 126 case FAERR_TOOLONG:
127 wprintw(self->window, "Message is too long.\n"); 127 wprintw(self->window, "Message is too long.\n");
@@ -145,12 +145,12 @@ void cmd_add(ToxWindow *self, char **args)
145 } 145 }
146} 146}
147 147
148void cmd_clear(ToxWindow *self, char **args) 148void cmd_clear(ToxWindow *self, Messenger *m, char **args)
149{ 149{
150 wclear(self->window); 150 wclear(self->window);
151} 151}
152 152
153void cmd_connect(ToxWindow *self, char **args) 153void cmd_connect(ToxWindow *self, Messenger *m, char **args)
154{ 154{
155 IP_Port dht; 155 IP_Port dht;
156 char *ip = args[1]; 156 char *ip = args[1];
@@ -174,13 +174,13 @@ void cmd_connect(ToxWindow *self, char **args)
174 free(binary_string); 174 free(binary_string);
175} 175}
176 176
177void cmd_quit(ToxWindow *self, char **args) 177void cmd_quit(ToxWindow *self, Messenger *m, char **args)
178{ 178{
179 endwin(); 179 endwin();
180 exit(0); 180 exit(0);
181} 181}
182 182
183void cmd_help(ToxWindow *self, char **args) 183void cmd_help(ToxWindow *self, Messenger *m, char **args)
184{ 184{
185 wclear(self->window); 185 wclear(self->window);
186 wattron(self->window, COLOR_PAIR(2) | A_BOLD); 186 wattron(self->window, COLOR_PAIR(2) | A_BOLD);
@@ -197,7 +197,7 @@ void cmd_help(ToxWindow *self, char **args)
197 wprintw(self->window, " quit/exit : Exit program\n"); 197 wprintw(self->window, " quit/exit : Exit program\n");
198 wprintw(self->window, " help : Print this message again\n"); 198 wprintw(self->window, " help : Print this message again\n");
199 wprintw(self->window, " clear : Clear this window\n"); 199 wprintw(self->window, " clear : Clear this window\n");
200 200
201 wattron(self->window, A_BOLD); 201 wattron(self->window, A_BOLD);
202 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); 202 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
203 wattroff(self->window, A_BOLD); 203 wattroff(self->window, A_BOLD);
@@ -205,17 +205,17 @@ void cmd_help(ToxWindow *self, char **args)
205 wattroff(self->window, COLOR_PAIR(2)); 205 wattroff(self->window, COLOR_PAIR(2));
206} 206}
207 207
208void cmd_msg(ToxWindow *self, char **args) 208void cmd_msg(ToxWindow *self, Messenger *m, char **args)
209{ 209{
210 char *id = args[1]; 210 char *id = args[1];
211 char *msg = args[2]; 211 char *msg = args[2];
212 if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0) 212 if (m_sendmessage(m, atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
213 wprintw(self->window, "Error occurred while sending message.\n"); 213 wprintw(self->window, "Error occurred while sending message.\n");
214 else 214 else
215 wprintw(self->window, "Message successfully sent.\n"); 215 wprintw(self->window, "Message successfully sent.\n");
216} 216}
217 217
218void cmd_myid(ToxWindow *self, char **args) 218void cmd_myid(ToxWindow *self, Messenger *m, char **args)
219{ 219{
220 char id[KEY_SIZE_BYTES*2 + 1] = {0}; 220 char id[KEY_SIZE_BYTES*2 + 1] = {0};
221 size_t i; 221 size_t i;
@@ -227,14 +227,14 @@ void cmd_myid(ToxWindow *self, char **args)
227 wprintw(self->window, "Your ID: %s\n", id); 227 wprintw(self->window, "Your ID: %s\n", id);
228} 228}
229 229
230void cmd_nick(ToxWindow *self, char **args) 230void cmd_nick(ToxWindow *self, Messenger *m, char **args)
231{ 231{
232 char *nick = args[1]; 232 char *nick = args[1];
233 setname((uint8_t*) nick, strlen(nick)+1); 233 setname(m, (uint8_t*) nick, strlen(nick)+1);
234 wprintw(self->window, "Nickname set to: %s\n", nick); 234 wprintw(self->window, "Nickname set to: %s\n", nick);
235} 235}
236 236
237void cmd_status(ToxWindow *self, char **args) 237void cmd_status(ToxWindow *self, Messenger *m, char **args)
238{ 238{
239 char *status = args[1]; 239 char *status = args[1];
240 char *status_text; 240 char *status_text;
@@ -260,24 +260,24 @@ void cmd_status(ToxWindow *self, char **args)
260 260
261 char *msg = args[2]; 261 char *msg = args[2];
262 if (msg == NULL) { 262 if (msg == NULL) {
263 m_set_userstatus(status_kind); 263 m_set_userstatus(m, status_kind);
264 wprintw(self->window, "Status set to: %s\n", status_text); 264 wprintw(self->window, "Status set to: %s\n", status_text);
265 } 265 }
266 else { 266 else {
267 m_set_userstatus(status_kind); 267 m_set_userstatus(m, status_kind);
268 m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); 268 m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1);
269 wprintw(self->window, "Status set to: %s, %s\n", status_text, msg); 269 wprintw(self->window, "Status set to: %s, %s\n", status_text, msg);
270 } 270 }
271} 271}
272 272
273void cmd_statusmsg(ToxWindow *self, char **args) 273void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args)
274{ 274{
275 char *msg = args[1]; 275 char *msg = args[1];
276 m_set_statusmessage((uint8_t*) msg, strlen(msg)+1); 276 m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1);
277 wprintw(self->window, "Status set to: %s\n", msg); 277 wprintw(self->window, "Status set to: %s\n", msg);
278} 278}
279 279
280static void execute(ToxWindow *self, char *u_cmd) 280static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
281{ 281{
282 int newlines = 0; 282 int newlines = 0;
283 char cmd[MAX_STR_SIZE] = {0}; 283 char cmd[MAX_STR_SIZE] = {0};
@@ -341,13 +341,13 @@ static void execute(ToxWindow *self, char *u_cmd)
341 return; 341 return;
342 } 342 }
343 } 343 }
344 /* check for excess arguments */ 344 /* check for excess arguments */
345 if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) { 345 if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
346 wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name); 346 wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
347 return; 347 return;
348 } 348 }
349 /* pass arguments to command function */ 349 /* pass arguments to command function */
350 (commands[i].func)(self, cmdargs); 350 (commands[i].func)(self, m, cmdargs);
351 return; 351 return;
352 } 352 }
353 } 353 }
@@ -356,7 +356,7 @@ static void execute(ToxWindow *self, char *u_cmd)
356 wprintw(self->window, "Invalid command.\n"); 356 wprintw(self->window, "Invalid command.\n");
357} 357}
358 358
359static void prompt_onKey(ToxWindow *self, int key) 359static void prompt_onKey(ToxWindow *self, Messenger *m, int key)
360{ 360{
361 /* Add printable characters to line */ 361 /* Add printable characters to line */
362 if (isprint(key)) { 362 if (isprint(key)) {
@@ -380,7 +380,7 @@ static void prompt_onKey(ToxWindow *self, int key)
380 /* RETURN key: execute command */ 380 /* RETURN key: execute command */
381 else if (key == '\n') { 381 else if (key == '\n') {
382 wprintw(self->window, "\n"); 382 wprintw(self->window, "\n");
383 execute(self, prompt_buf); 383 execute(self, m, prompt_buf);
384 prompt_buf_pos = 0; 384 prompt_buf_pos = 0;
385 prompt_buf[0] = 0; 385 prompt_buf[0] = 0;
386 } 386 }
@@ -413,10 +413,10 @@ static void prompt_onDraw(ToxWindow *self)
413 wrefresh(self->window); 413 wrefresh(self->window);
414} 414}
415 415
416static void prompt_onInit(ToxWindow *self) 416static void prompt_onInit(ToxWindow *self, Messenger *m)
417{ 417{
418 scrollok(self->window, 1); 418 scrollok(self->window, 1);
419 cmd_help(self, NULL); 419 cmd_help(self, m, NULL);
420 wclrtoeol(self->window); 420 wclrtoeol(self->window);
421} 421}
422 422
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h
index c6925ce1..648243d0 100644
--- a/testing/toxic/windows.h
+++ b/testing/toxic/windows.h
@@ -9,7 +9,7 @@
9#define KEY_SIZE_BYTES 32 9#define KEY_SIZE_BYTES 32
10 10
11/* number of permanent default windows */ 11/* number of permanent default windows */
12#define N_DEFAULT_WINS 2 12#define N_DEFAULT_WINS 2
13 13
14/* maximum window slots for WINDOW_STATUS array */ 14/* maximum window slots for WINDOW_STATUS array */
15#define MAX_WINDOW_SLOTS N_DEFAULT_WINS+MAX_FRIENDS_NUM 15#define MAX_WINDOW_SLOTS N_DEFAULT_WINS+MAX_FRIENDS_NUM
@@ -17,14 +17,14 @@
17typedef struct ToxWindow_ ToxWindow; 17typedef struct ToxWindow_ ToxWindow;
18 18
19struct ToxWindow_ { 19struct ToxWindow_ {
20 void(*onKey)(ToxWindow*, int); 20 void(*onKey)(ToxWindow*, Messenger*, int);
21 void(*onDraw)(ToxWindow*); 21 void(*onDraw)(ToxWindow*);
22 void(*onInit)(ToxWindow*); 22 void(*onInit)(ToxWindow*, Messenger*);
23 void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t); 23 void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t);
24 void(*onMessage)(ToxWindow*, int, uint8_t*, uint16_t); 24 void(*onMessage)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
25 void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t); 25 void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t);
26 void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t); 26 void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t);
27 void(*onAction)(ToxWindow*, int, uint8_t*, uint16_t); 27 void(*onAction)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
28 char title[256]; 28 char title[256];
29 29
30 void* x; 30 void* x;