ffi-tox 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/ProjectTox-Core/AUTHORS +0 -0
  3. data/ProjectTox-Core/ChangeLog +0 -0
  4. data/ProjectTox-Core/INSTALL +370 -0
  5. data/ProjectTox-Core/INSTALL.md +455 -56
  6. data/ProjectTox-Core/Makefile.am +35 -0
  7. data/ProjectTox-Core/NEWS +0 -0
  8. data/ProjectTox-Core/README +43 -0
  9. data/ProjectTox-Core/README.md +34 -44
  10. data/ProjectTox-Core/auto_tests/Makefile.inc +110 -0
  11. data/ProjectTox-Core/auto_tests/TCP_test.c +519 -0
  12. data/ProjectTox-Core/auto_tests/assoc_test.c +160 -0
  13. data/ProjectTox-Core/auto_tests/crypto_test.c +302 -0
  14. data/ProjectTox-Core/auto_tests/dht_test.c +362 -0
  15. data/ProjectTox-Core/auto_tests/encryptsave_test.c +104 -0
  16. data/ProjectTox-Core/auto_tests/friends_test.c +238 -0
  17. data/ProjectTox-Core/auto_tests/helpers.h +15 -0
  18. data/ProjectTox-Core/auto_tests/messenger_test.c +365 -0
  19. data/ProjectTox-Core/auto_tests/network_test.c +171 -0
  20. data/ProjectTox-Core/auto_tests/onion_test.c +363 -0
  21. data/ProjectTox-Core/auto_tests/skeleton_test.c +49 -0
  22. data/ProjectTox-Core/auto_tests/tox_test.c +454 -0
  23. data/ProjectTox-Core/auto_tests/toxav_basic_test.c +597 -0
  24. data/ProjectTox-Core/auto_tests/toxav_many_test.c +402 -0
  25. data/ProjectTox-Core/autogen.sh +6 -0
  26. data/ProjectTox-Core/build/Makefile.am +14 -0
  27. data/ProjectTox-Core/configure.ac +694 -0
  28. data/ProjectTox-Core/dist-build/android-arm.sh +3 -0
  29. data/ProjectTox-Core/dist-build/android-armv7.sh +3 -0
  30. data/ProjectTox-Core/dist-build/android-build.sh +59 -0
  31. data/ProjectTox-Core/dist-build/android-mips.sh +3 -0
  32. data/ProjectTox-Core/dist-build/android-x86.sh +3 -0
  33. data/ProjectTox-Core/docs/Group-Chats.md +71 -0
  34. data/ProjectTox-Core/docs/Hardening.txt +60 -0
  35. data/ProjectTox-Core/docs/Hardening_docs.txt +30 -0
  36. data/ProjectTox-Core/docs/Prevent_Tracking.txt +160 -0
  37. data/ProjectTox-Core/docs/TCP_Network.txt +154 -0
  38. data/ProjectTox-Core/docs/TODO +62 -0
  39. data/ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt +120 -0
  40. data/ProjectTox-Core/docs/av_api.md +194 -0
  41. data/ProjectTox-Core/libtoxav.pc.in +11 -0
  42. data/ProjectTox-Core/libtoxcore.pc.in +11 -0
  43. data/ProjectTox-Core/m4/ax_have_epoll.m4 +104 -0
  44. data/ProjectTox-Core/m4/ax_pthread.m4 +317 -0
  45. data/ProjectTox-Core/m4/pkg.m4 +199 -0
  46. data/ProjectTox-Core/other/DHT_bootstrap.c +121 -58
  47. data/ProjectTox-Core/other/DHTnodes +3 -0
  48. data/ProjectTox-Core/other/Makefile.inc +20 -0
  49. data/ProjectTox-Core/other/bootstrap_node_packets.c +65 -0
  50. data/ProjectTox-Core/other/tox.png +0 -0
  51. data/ProjectTox-Core/testing/DHT_test.c +170 -98
  52. data/ProjectTox-Core/testing/Makefile.inc +112 -0
  53. data/ProjectTox-Core/testing/Messenger_test.c +133 -69
  54. data/ProjectTox-Core/testing/dns3_test.c +115 -0
  55. data/ProjectTox-Core/testing/misc_tools.c +59 -13
  56. data/ProjectTox-Core/testing/nTox.c +1127 -264
  57. data/ProjectTox-Core/testing/nTox.h +10 -19
  58. data/ProjectTox-Core/testing/tox_shell.c +159 -0
  59. data/ProjectTox-Core/testing/tox_sync.c +299 -0
  60. data/ProjectTox-Core/tools/README +11 -0
  61. data/ProjectTox-Core/tools/astylerc +11 -0
  62. data/ProjectTox-Core/tools/pre-commit +17 -0
  63. data/ProjectTox-Core/toxav/Makefile.inc +36 -0
  64. data/ProjectTox-Core/toxav/codec.c +357 -0
  65. data/ProjectTox-Core/toxav/codec.h +116 -0
  66. data/ProjectTox-Core/toxav/msi.c +1949 -0
  67. data/ProjectTox-Core/toxav/msi.h +267 -0
  68. data/ProjectTox-Core/toxav/rtp.c +600 -0
  69. data/ProjectTox-Core/toxav/rtp.h +196 -0
  70. data/ProjectTox-Core/toxav/toxav.c +1148 -0
  71. data/ProjectTox-Core/toxav/toxav.h +389 -0
  72. data/ProjectTox-Core/toxcore/DHT.c +2521 -0
  73. data/ProjectTox-Core/toxcore/DHT.h +412 -0
  74. data/ProjectTox-Core/toxcore/LAN_discovery.c +322 -0
  75. data/ProjectTox-Core/{core → toxcore}/LAN_discovery.h +17 -12
  76. data/ProjectTox-Core/toxcore/Makefile.inc +67 -0
  77. data/ProjectTox-Core/toxcore/Messenger.c +3006 -0
  78. data/ProjectTox-Core/toxcore/Messenger.h +818 -0
  79. data/ProjectTox-Core/toxcore/TCP_client.c +858 -0
  80. data/ProjectTox-Core/toxcore/TCP_client.h +156 -0
  81. data/ProjectTox-Core/toxcore/TCP_server.c +1332 -0
  82. data/ProjectTox-Core/toxcore/TCP_server.h +181 -0
  83. data/ProjectTox-Core/toxcore/assoc.c +1033 -0
  84. data/ProjectTox-Core/toxcore/assoc.h +104 -0
  85. data/ProjectTox-Core/toxcore/crypto_core.c +278 -0
  86. data/ProjectTox-Core/toxcore/crypto_core.h +151 -0
  87. data/ProjectTox-Core/toxcore/friend_requests.c +175 -0
  88. data/ProjectTox-Core/toxcore/friend_requests.h +83 -0
  89. data/ProjectTox-Core/toxcore/group_chats.c +837 -0
  90. data/ProjectTox-Core/toxcore/group_chats.h +199 -0
  91. data/ProjectTox-Core/toxcore/list.c +256 -0
  92. data/ProjectTox-Core/toxcore/list.h +85 -0
  93. data/ProjectTox-Core/toxcore/logger.c +153 -0
  94. data/ProjectTox-Core/toxcore/logger.h +84 -0
  95. data/ProjectTox-Core/toxcore/misc_tools.h +70 -0
  96. data/ProjectTox-Core/toxcore/net_crypto.c +2753 -0
  97. data/ProjectTox-Core/toxcore/net_crypto.h +410 -0
  98. data/ProjectTox-Core/toxcore/network.c +979 -0
  99. data/ProjectTox-Core/toxcore/network.h +367 -0
  100. data/ProjectTox-Core/toxcore/onion.c +540 -0
  101. data/ProjectTox-Core/toxcore/onion.h +150 -0
  102. data/ProjectTox-Core/toxcore/onion_announce.c +433 -0
  103. data/ProjectTox-Core/toxcore/onion_announce.h +139 -0
  104. data/ProjectTox-Core/toxcore/onion_client.c +1347 -0
  105. data/ProjectTox-Core/toxcore/onion_client.h +253 -0
  106. data/ProjectTox-Core/toxcore/ping.c +346 -0
  107. data/ProjectTox-Core/toxcore/ping.h +47 -0
  108. data/ProjectTox-Core/toxcore/ping_array.c +162 -0
  109. data/ProjectTox-Core/toxcore/ping_array.h +75 -0
  110. data/ProjectTox-Core/toxcore/tox.c +940 -0
  111. data/ProjectTox-Core/toxcore/tox.h +734 -0
  112. data/ProjectTox-Core/toxcore/util.c +193 -0
  113. data/ProjectTox-Core/toxcore/util.h +63 -0
  114. data/ProjectTox-Core/toxdns/Makefile.inc +29 -0
  115. data/ProjectTox-Core/toxdns/toxdns.c +238 -0
  116. data/ProjectTox-Core/toxdns/toxdns.h +88 -0
  117. data/ProjectTox-Core/toxencryptsave/Makefile.inc +45 -0
  118. data/ProjectTox-Core/toxencryptsave/toxencryptsave.c +179 -0
  119. data/ProjectTox-Core/toxencryptsave/toxencryptsave.h +74 -0
  120. data/interfaces/libtox.i +2 -6
  121. data/lib/ffi-tox/libtox.rb +406 -28
  122. metadata +124 -46
  123. data/ProjectTox-Core/CMakeLists.txt +0 -50
  124. data/ProjectTox-Core/cmake/FindLIBCONFIG.cmake +0 -15
  125. data/ProjectTox-Core/cmake/FindNaCl.cmake +0 -17
  126. data/ProjectTox-Core/cmake/FindSODIUM.cmake +0 -15
  127. data/ProjectTox-Core/core/CMakeLists.txt +0 -19
  128. data/ProjectTox-Core/core/DHT.c +0 -1104
  129. data/ProjectTox-Core/core/DHT.h +0 -111
  130. data/ProjectTox-Core/core/LAN_discovery.c +0 -79
  131. data/ProjectTox-Core/core/Lossless_UDP.c +0 -755
  132. data/ProjectTox-Core/core/Lossless_UDP.h +0 -106
  133. data/ProjectTox-Core/core/Messenger.c +0 -596
  134. data/ProjectTox-Core/core/Messenger.h +0 -165
  135. data/ProjectTox-Core/core/friend_requests.c +0 -131
  136. data/ProjectTox-Core/core/friend_requests.h +0 -51
  137. data/ProjectTox-Core/core/net_crypto.c +0 -575
  138. data/ProjectTox-Core/core/net_crypto.h +0 -134
  139. data/ProjectTox-Core/core/network.c +0 -205
  140. data/ProjectTox-Core/core/network.h +0 -134
  141. data/ProjectTox-Core/docs/commands.md +0 -25
  142. data/ProjectTox-Core/docs/start_guide.de.md +0 -40
  143. data/ProjectTox-Core/docs/start_guide.md +0 -38
  144. data/ProjectTox-Core/other/CMakeLists.txt +0 -9
  145. data/ProjectTox-Core/testing/CMakeLists.txt +0 -18
  146. data/ProjectTox-Core/testing/DHT_cryptosendfiletest.c +0 -228
  147. data/ProjectTox-Core/testing/DHT_sendfiletest.c +0 -176
  148. data/ProjectTox-Core/testing/Lossless_UDP_testclient.c +0 -214
  149. data/ProjectTox-Core/testing/Lossless_UDP_testserver.c +0 -201
  150. data/ProjectTox-Core/testing/misc_tools.h +0 -29
  151. data/ProjectTox-Core/testing/nTox_win32.c +0 -387
  152. data/ProjectTox-Core/testing/nTox_win32.h +0 -40
  153. data/ProjectTox-Core/testing/rect.py +0 -45
@@ -1,5 +1,5 @@
1
1
  /* misc_tools.c
2
- *
2
+ *
3
3
  * Miscellaneous functions and data structures for doing random things.
4
4
  *
5
5
  * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -18,23 +18,69 @@
18
18
  *
19
19
  * You should have received a copy of the GNU General Public License
20
20
  * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
- *
21
+ *
22
22
  */
23
-
24
- #include "misc_tools.h"
23
+
24
+ #ifdef HAVE_CONFIG_H
25
+ #include "config.h"
26
+ #endif
25
27
 
26
28
  #include <string.h>
27
29
  #include <stdlib.h>
28
- #include <stdio.h> /* for sscanf */
30
+ #include <stdio.h>
31
+ #include <stdint.h>
32
+
33
+ #ifdef DEBUG
34
+ #include <assert.h>
35
+ #endif // DEBUG
29
36
 
30
- /* TODO: rewrite */
31
- unsigned char * hex_string_to_bin(char hex_string[])
37
+ // You are responsible for freeing the return value!
38
+ uint8_t *hex_string_to_bin(char *hex_string)
32
39
  {
33
- size_t len = strlen(hex_string);
34
- unsigned char *val = malloc(len);
40
+ // byte is represented by exactly 2 hex digits, so lenth of binary string
41
+ // is half of that of the hex one. only hex string with even length
42
+ // valid. the more proper implementation would be to check if strlen(hex_string)
43
+ // is odd and return error code if it is. we assume strlen is even. if it's not
44
+ // then the last byte just won't be written in 'ret'.
45
+ size_t i, len = strlen(hex_string) / 2;
46
+ uint8_t *ret = malloc(len);
35
47
  char *pos = hex_string;
36
- int i;
37
- for(i = 0; i < len; ++i, pos+=2)
38
- sscanf(pos,"%2hhx",&val[i]);
39
- return val;
48
+
49
+ for (i = 0; i < len; ++i, pos += 2)
50
+ sscanf(pos, "%2hhx", &ret[i]);
51
+
52
+ return ret;
40
53
  }
54
+
55
+ int cmdline_parsefor_ipv46(int argc, char **argv, uint8_t *ipv6enabled)
56
+ {
57
+ int argvoffset = 0, argi;
58
+
59
+ for (argi = 1; argi < argc; argi++)
60
+ if (!strncasecmp(argv[argi], "--ipv", 5)) {
61
+ if (argv[argi][5] && !argv[argi][6]) {
62
+ char c = argv[argi][5];
63
+
64
+ if (c == '4')
65
+ *ipv6enabled = 0;
66
+ else if (c == '6')
67
+ *ipv6enabled = 1;
68
+ else {
69
+ printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]);
70
+ return -1;
71
+ }
72
+ } else {
73
+ printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]);
74
+ return -1;
75
+ }
76
+
77
+ if (argvoffset != argi - 1) {
78
+ printf("Argument must come first: %s.\n", argv[argi]);
79
+ return -1;
80
+ }
81
+
82
+ argvoffset++;
83
+ }
84
+
85
+ return argvoffset;
86
+ };
@@ -18,15 +18,34 @@
18
18
  *
19
19
  * You should have received a copy of the GNU General Public License
20
20
  * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
- *
21
+ *
22
22
  */
23
+ #ifdef HAVE_CONFIG_H
24
+ #include "config.h"
25
+ #endif
26
+
27
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
28
+ #define _WIN32_WINNT 0x501
29
+ #include <winsock2.h>
30
+ #include <ws2tcpip.h>
31
+ #else
32
+ #include <sys/socket.h>
33
+ #include <netinet/in.h>
34
+ #include <arpa/inet.h>
35
+ #include <sys/types.h>
36
+ #include <netdb.h>
37
+ #endif
38
+
39
+ #include <sys/select.h>
40
+
23
41
  #include "nTox.h"
24
- #include "misc_tools.h"
42
+ #include "misc_tools.c"
25
43
 
26
44
  #include <stdio.h>
27
45
  #include <time.h>
46
+ #include <locale.h>
28
47
 
29
- #ifdef WIN32
48
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
30
49
  #define c_sleep(x) Sleep(1*x)
31
50
  #else
32
51
  #include <unistd.h>
@@ -34,429 +53,1273 @@
34
53
  #endif
35
54
 
36
55
  char lines[HISTORY][STRING_LENGTH];
37
- char line[STRING_LENGTH];
56
+ uint8_t flag[HISTORY];
57
+ char input_line[STRING_LENGTH];
58
+
59
+ /* wrap: continuation mark */
60
+ const size_t wrap_cont_len = 3;
61
+ const char wrap_cont_str[] = "\n+ ";
62
+
63
+ #define STRING_LENGTH_WRAPPED (STRING_LENGTH + 16 * (wrap_cont_len + 1))
64
+
65
+ /* documented: fdmnlsahxgiztq(c[rfg]) */
66
+ /* undocumented: d (tox_do()) */
67
+
68
+ /* 251+1 characters */
69
+ char *help_main =
70
+ "[i] Available main commands:\n+ "
71
+ "/x (to print one's own id)|"
72
+ "/s status (to change status, e.g. AFK)|"
73
+ "/n nick (to change your nickname)|"
74
+ "/q (to quit)|"
75
+ "/cr (to reset conversation)|"
76
+ "/h friend (for friend related commands)|"
77
+ "/h group (for group related commands)";
78
+
79
+ /* 190+1 characters */
80
+ char *help_friend1 =
81
+ "[i] Available friend commands (1/2):\n+ "
82
+ "/l list (to list friends)|"
83
+ "/r friend no. (to remove from the friend list)|"
84
+ "/f ID (to send a friend request)|"
85
+ "/a request no. (to accept a friend request)";
86
+
87
+ /* 187+1 characters */
88
+ char *help_friend2 =
89
+ "[i] Available friend commands (2/2):\n+ "
90
+ "/m friend no. message (to send a message)|"
91
+ "/t friend no. filename (to send a file to a friend)|"
92
+ "/cf friend no. (to talk to that friend per default)";
93
+
94
+ /* 253+1 characters */
95
+ char *help_group =
96
+ "[i] Available group commands:\n+ "
97
+ "/g (to create a group)|"
98
+ "/i friend no. group no. (to invite a friend to a group)|"
99
+ "/z group no. message (to send a message to a group)|"
100
+ "/p group no. (to list a group's peers)|"
101
+ "/cg group no. (to talk to that group per default)";
38
102
 
39
- char *help = "[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)\n"
40
- "[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)";
41
103
  int x, y;
42
104
 
105
+ int conversation_default = 0;
106
+
107
+ typedef struct {
108
+ uint8_t id[TOX_CLIENT_ID_SIZE];
109
+ uint8_t accepted;
110
+ } Friend_request;
43
111
 
44
- uint8_t pending_requests[256][CLIENT_ID_SIZE];
112
+ Friend_request pending_requests[256];
45
113
  uint8_t num_requests = 0;
46
114
 
47
- void new_lines(char *line)
115
+ #define NUM_FILE_SENDERS 256
116
+ typedef struct {
117
+ FILE *file;
118
+ uint16_t friendnum;
119
+ uint8_t filenumber;
120
+ uint8_t nextpiece[1024];
121
+ uint16_t piecelength;
122
+ } File_Sender;
123
+ File_Sender file_senders[NUM_FILE_SENDERS];
124
+ uint8_t numfilesenders;
125
+
126
+ void send_filesenders(Tox *m)
48
127
  {
49
- int i;
50
- for (i = HISTORY-1; i > 0; i--)
51
- strcpy(lines[i], lines[i-1]);
52
-
53
- strcpy(lines[0], line);
128
+ uint32_t i;
129
+
130
+ for (i = 0; i < NUM_FILE_SENDERS; ++i) {
131
+ if (file_senders[i].file == 0)
132
+ continue;
133
+
134
+ while (1) {
135
+ if (tox_file_send_data(m, file_senders[i].friendnum, file_senders[i].filenumber, file_senders[i].nextpiece,
136
+ file_senders[i].piecelength) == -1)
137
+ break;
138
+
139
+ file_senders[i].piecelength = fread(file_senders[i].nextpiece, 1, tox_file_data_size(m, file_senders[i].friendnum),
140
+ file_senders[i].file);
141
+
142
+ if (file_senders[i].piecelength == 0) {
143
+ fclose(file_senders[i].file);
144
+ file_senders[i].file = 0;
145
+ tox_file_send_control(m, file_senders[i].friendnum, 0, file_senders[i].filenumber, 3, 0, 0);
146
+ char msg[512];
147
+ sprintf(msg, "[t] %u file transfer: %u completed", file_senders[i].friendnum, file_senders[i].filenumber);
148
+ new_lines(msg);
149
+ break;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ int add_filesender(Tox *m, uint16_t friendnum, char *filename)
155
+ {
156
+ FILE *tempfile = fopen(filename, "r");
157
+
158
+ if (tempfile == 0)
159
+ return -1;
160
+
161
+ fseek(tempfile, 0, SEEK_END);
162
+ uint64_t filesize = ftell(tempfile);
163
+ fseek(tempfile, 0, SEEK_SET);
164
+ int filenum = tox_new_file_sender(m, friendnum, filesize, (uint8_t *)filename, strlen(filename) + 1);
165
+
166
+ if (filenum == -1)
167
+ return -1;
168
+
169
+ file_senders[numfilesenders].file = tempfile;
170
+ file_senders[numfilesenders].piecelength = fread(file_senders[numfilesenders].nextpiece, 1, tox_file_data_size(m,
171
+ file_senders[numfilesenders].friendnum),
172
+ file_senders[numfilesenders].file);
173
+ file_senders[numfilesenders].friendnum = friendnum;
174
+ file_senders[numfilesenders].filenumber = filenum;
175
+ ++numfilesenders;
176
+ return filenum;
177
+ }
178
+
179
+
180
+
181
+ #define FRADDR_TOSTR_CHUNK_LEN 8
182
+ #define FRADDR_TOSTR_BUFSIZE (TOX_FRIEND_ADDRESS_SIZE * 2 + TOX_FRIEND_ADDRESS_SIZE / FRADDR_TOSTR_CHUNK_LEN + 1)
183
+
184
+ static void fraddr_to_str(uint8_t *id_bin, char *id_str)
185
+ {
186
+ uint32_t i, delta = 0, pos_extra, sum_extra = 0;
187
+
188
+ for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
189
+ sprintf(&id_str[2 * i + delta], "%02hhX", id_bin[i]);
190
+
191
+ if ((i + 1) == TOX_CLIENT_ID_SIZE)
192
+ pos_extra = 2 * (i + 1) + delta;
193
+
194
+ if (i >= TOX_CLIENT_ID_SIZE)
195
+ sum_extra |= id_bin[i];
196
+
197
+ if (!((i + 1) % FRADDR_TOSTR_CHUNK_LEN)) {
198
+ id_str[2 * (i + 1) + delta] = ' ';
199
+ delta++;
200
+ }
201
+ }
202
+
203
+ id_str[2 * i + delta] = 0;
204
+
205
+ if (!sum_extra)
206
+ id_str[pos_extra] = 0;
207
+ }
208
+
209
+ void get_id(Tox *m, char *data)
210
+ {
211
+ sprintf(data, "[i] ID: ");
212
+ int offset = strlen(data);
213
+ uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
214
+ tox_get_address(m, address);
215
+ fraddr_to_str(address, data + offset);
216
+ }
217
+
218
+ int getfriendname_terminated(Tox *m, int friendnum, char *namebuf)
219
+ {
220
+ int res = tox_get_name(m, friendnum, (uint8_t *)namebuf);
221
+
222
+ if (res >= 0)
223
+ namebuf[res] = 0;
224
+ else
225
+ namebuf[0] = 0;
226
+
227
+ return res;
228
+ }
229
+
230
+ void new_lines_mark(char *line, uint8_t special)
231
+ {
232
+ int i = 0;
233
+
234
+ for (i = HISTORY - 1; i > 0; i--) {
235
+ strncpy(lines[i], lines[i - 1], STRING_LENGTH - 1);
236
+ flag[i] = flag[i - 1];
237
+ }
238
+
239
+ strncpy(lines[0], line, STRING_LENGTH - 1);
240
+ flag[i] = special;
241
+
54
242
  do_refresh();
55
243
  }
56
244
 
245
+ void new_lines(char *line)
246
+ {
247
+ new_lines_mark(line, 0);
248
+ }
249
+
57
250
 
58
- void print_friendlist()
251
+ const char ptrn_friend[] = "[i] Friend %i: %s\n+ id: %s";
252
+ const int id_str_len = TOX_FRIEND_ADDRESS_SIZE * 2 + 3;
253
+ void print_friendlist(Tox *m)
59
254
  {
60
- char name[MAX_NAME_LENGTH];
61
255
  new_lines("[i] Friend List:");
62
- uint32_t i;
63
- for (i = 0; i <= num_requests; i++) {
64
- char fstring[128];
65
- getname(i, (uint8_t*)name);
256
+
257
+ char name[TOX_MAX_NAME_LENGTH + 1];
258
+ uint8_t fraddr_bin[TOX_FRIEND_ADDRESS_SIZE];
259
+ char fraddr_str[FRADDR_TOSTR_BUFSIZE];
260
+
261
+ /* account for the longest name and the longest "base" string and number (int) and id_str */
262
+ char fstring[TOX_MAX_NAME_LENGTH + strlen(ptrn_friend) + 21 + id_str_len];
263
+
264
+ uint32_t i = 0;
265
+
266
+ while (getfriendname_terminated(m, i, name) != -1) {
267
+ if (!tox_get_client_id(m, i, fraddr_bin))
268
+ fraddr_to_str(fraddr_bin, fraddr_str);
269
+ else
270
+ sprintf(fraddr_str, "???");
271
+
66
272
  if (strlen(name) <= 0) {
67
- sprintf(fstring, "[i] Friend: NULL\n\tid: %i", i);
273
+ sprintf(fstring, ptrn_friend, i, "No name?", fraddr_str);
68
274
  } else {
69
- sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t*)name, i);
275
+ sprintf(fstring, ptrn_friend, i, (uint8_t *)name, fraddr_str);
70
276
  }
277
+
278
+ i++;
71
279
  new_lines(fstring);
72
280
  }
281
+
282
+ if (i == 0)
283
+ new_lines("+ no friends! D:");
73
284
  }
74
285
 
75
- char *format_message(char *message, int friendnum)
286
+ static int fmtmsg_tm_mday = -1;
287
+
288
+ static void print_formatted_message(Tox *m, char *message, int friendnum, uint8_t outgoing)
76
289
  {
77
- char name[MAX_NAME_LENGTH];
78
- if (friendnum != -1) {
79
- getname(friendnum, (uint8_t*)name);
80
- } else {
81
- getself_name((uint8_t*)name);
82
- }
83
- char *msg = malloc(100+strlen(message)+strlen(name)+1);
290
+ char name[TOX_MAX_NAME_LENGTH + 1];
291
+ getfriendname_terminated(m, friendnum, name);
292
+
293
+ char msg[100 + strlen(message) + strlen(name) + 1];
84
294
 
85
295
  time_t rawtime;
86
- struct tm * timeinfo;
296
+ struct tm *timeinfo;
87
297
  time ( &rawtime );
88
298
  timeinfo = localtime ( &rawtime );
89
- char* time = asctime(timeinfo);
90
- size_t len = strlen(time);
91
- time[len-1] = '\0';
92
- sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); // timestamp
93
- return msg;
299
+
300
+ /* assume that printing the date once a day is enough */
301
+ if (fmtmsg_tm_mday != timeinfo->tm_mday) {
302
+ fmtmsg_tm_mday = timeinfo->tm_mday;
303
+ /* strftime(msg, 100, "Today is %a %b %d %Y.", timeinfo); */
304
+ /* %x is the locale's preferred date format */
305
+ strftime(msg, 100, "Today is %x.", timeinfo);
306
+ new_lines(msg);
307
+ }
308
+
309
+ char time[64];
310
+ /* strftime(time, 64, "%I:%M:%S %p", timeinfo); */
311
+ /* %X is the locale's preferred time format */
312
+ strftime(time, 64, "%X", timeinfo);
313
+
314
+ if (outgoing) {
315
+ /* tgt: friend */
316
+ sprintf(msg, "[%d] %s =>{%s} %s", friendnum, time, name, message);
317
+ } else {
318
+ /* src: friend */
319
+ sprintf(msg, "[%d] %s <%s>: %s", friendnum, time, name, message);
320
+ }
321
+
322
+ new_lines(msg);
94
323
  }
95
324
 
96
- void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
325
+ /* forward declarations */
326
+ static int save_data(Tox *m);
327
+ void print_groupchatpeers(Tox *m, int groupnumber);
328
+
329
+ void line_eval(Tox *m, char *line)
97
330
  {
98
331
  if (line[0] == '/') {
99
332
  char inpt_command = line[1];
100
- char prompt[STRING_LENGTH+2] = "> ";
333
+ char prompt[STRING_LENGTH + 2] = "> ";
101
334
  int prompt_offset = 3;
102
335
  strcat(prompt, line);
103
336
  new_lines(prompt);
337
+
104
338
  if (inpt_command == 'f') { // add friend command: /f ID
105
- int i;
339
+ int i, delta = 0;
106
340
  char temp_id[128];
107
- for (i = 0; i < 128; i++)
108
- temp_id[i] = line[i+prompt_offset];
109
- int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
341
+
342
+ for (i = 0; i < 128; i++) {
343
+ temp_id[i - delta] = line[i + prompt_offset];
344
+
345
+ if ((temp_id[i - delta] == ' ') || (temp_id[i - delta] == '+'))
346
+ delta++;
347
+ }
348
+
349
+ unsigned char *bin_string = hex_string_to_bin(temp_id);
350
+ int num = tox_add_friend(m, bin_string, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
351
+ free(bin_string);
110
352
  char numstring[100];
353
+
111
354
  switch (num) {
112
- case -1:
113
- sprintf(numstring, "[i] Incorrect key length");
355
+ case TOX_FAERR_TOOLONG:
356
+ sprintf(numstring, "[i] Message is too long.");
357
+ break;
358
+
359
+ case TOX_FAERR_NOMESSAGE:
360
+ sprintf(numstring, "[i] Please add a message to your request.");
114
361
  break;
115
- case -2:
116
- sprintf(numstring, "[i] That appears to be your own key");
362
+
363
+ case TOX_FAERR_OWNKEY:
364
+ sprintf(numstring, "[i] That appears to be your own ID.");
117
365
  break;
118
- case -3:
119
- sprintf(numstring, "[i] Friend request already sent");
366
+
367
+ case TOX_FAERR_ALREADYSENT:
368
+ sprintf(numstring, "[i] Friend request already sent.");
120
369
  break;
121
- case -4:
122
- sprintf(numstring, "[i] Could not add friend");
370
+
371
+ case TOX_FAERR_UNKNOWN:
372
+ sprintf(numstring, "[i] Undefined error when adding friend.");
123
373
  break;
374
+
124
375
  default:
125
- sprintf(numstring, "[i] Added friend %d", num);
376
+ if (num >= 0) {
377
+ sprintf(numstring, "[i] Added friend as %d.", num);
378
+ save_data(m);
379
+ } else
380
+ sprintf(numstring, "[i] Unknown error %i.", num);
381
+
126
382
  break;
127
383
  }
384
+
128
385
  new_lines(numstring);
129
- do_refresh();
130
- }
131
- else if (inpt_command == 'd') {
132
- doMessenger();
133
- }
134
- else if (inpt_command == 'm') { //message command: /m friendnumber messsage
135
- size_t len = strlen(line);
136
- if(len < 3)
137
- return;
138
-
139
- char numstring[len-3];
140
- char message[len-3];
141
- int i;
142
- for (i = 0; i < len; i++) {
143
- if (line[i+3] != ' ') {
144
- numstring[i] = line[i+3];
386
+ } else if (inpt_command == 'd') {
387
+ tox_do(m);
388
+ } else if (inpt_command == 'm') { //message command: /m friendnumber messsage
389
+ char *posi[1];
390
+ int num = strtoul(line + prompt_offset, posi, 0);
391
+
392
+ if (**posi != 0) {
393
+ if (tox_send_message(m, num, (uint8_t *) *posi + 1, strlen(*posi + 1)) < 1) {
394
+ char sss[256];
395
+ sprintf(sss, "[i] could not send message to friend num %u", num);
396
+ new_lines(sss);
145
397
  } else {
146
- int j;
147
- for (j = (i+1); j < (len+1); j++)
148
- message[j-i-1] = line[j+3];
149
- break;
398
+ print_formatted_message(m, *posi + 1, num, 1);
150
399
  }
151
- }
152
- int num = atoi(numstring);
153
- if (m_sendmessage(num, (uint8_t*) message, strlen(message) + 1) != 1) {
154
- new_lines("[i] could not send message");
155
- } else {
156
- new_lines(format_message(message, -1));
157
- }
158
- }
159
- else if (inpt_command == 'n') {
160
- uint8_t name[MAX_NAME_LENGTH];
161
- int i = 0;
162
- size_t len = strlen(line);
400
+ } else
401
+ new_lines("Error, bad input.");
402
+ } else if (inpt_command == 'n') {
403
+ uint8_t name[TOX_MAX_NAME_LENGTH];
404
+ size_t i, len = strlen(line);
405
+
163
406
  for (i = 3; i < len; i++) {
164
407
  if (line[i] == 0 || line[i] == '\n') break;
165
- name[i-3] = line[i];
408
+
409
+ name[i - 3] = line[i];
166
410
  }
167
- name[i-3] = 0;
168
- setname(name, i - 2);
411
+
412
+ name[i - 3] = 0;
413
+ tox_set_name(m, name, i - 2);
169
414
  char numstring[100];
170
- sprintf(numstring, "[i] changed nick to %s", (char*)name);
415
+ sprintf(numstring, "[i] changed nick to %s", (char *)name);
171
416
  new_lines(numstring);
172
- }
173
- else if (inpt_command == 'l') {
174
- print_friendlist();
175
- }
176
- else if (inpt_command == 's') {
177
- uint8_t status[MAX_USERSTATUS_LENGTH];
178
- int i = 0;
179
- size_t len = strlen(line);
417
+ } else if (inpt_command == 'l') {
418
+ print_friendlist(m);
419
+ } else if (inpt_command == 's') {
420
+ uint8_t status[TOX_MAX_STATUSMESSAGE_LENGTH];
421
+ size_t i, len = strlen(line);
422
+
180
423
  for (i = 3; i < len; i++) {
181
424
  if (line[i] == 0 || line[i] == '\n') break;
182
- status[i-3] = line[i];
425
+
426
+ status[i - 3] = line[i];
183
427
  }
184
- status[i-3] = 0;
185
- m_set_userstatus(status, strlen((char*)status) + 1);
428
+
429
+ status[i - 3] = 0;
430
+ tox_set_status_message(m, status, strlen((char *)status));
186
431
  char numstring[100];
187
- sprintf(numstring, "[i] changed status to %s", (char*)status);
432
+ sprintf(numstring, "[i] changed status to %s", (char *)status);
188
433
  new_lines(numstring);
189
- }
190
- else if (inpt_command == 'a') {
434
+ } else if (inpt_command == 'a') { // /a #: accept
191
435
  uint8_t numf = atoi(line + 3);
192
436
  char numchar[100];
193
- int num = m_addfriend_norequest(pending_requests[numf]);
194
- if (num != -1) {
195
- sprintf(numchar, "[i] friend request %u accepted", numf);
196
- new_lines(numchar);
197
- sprintf(numchar, "[i] added friendnumber %d", num);
437
+
438
+ if (numf >= num_requests || pending_requests[numf].accepted) {
439
+ sprintf(numchar, "[i] you either didn't receive that request or you already accepted it");
198
440
  new_lines(numchar);
199
441
  } else {
200
- sprintf(numchar, "[i] failed to add friend");
201
- new_lines(numchar);
442
+ int num = tox_add_friend_norequest(m, pending_requests[numf].id);
443
+
444
+ if (num != -1) {
445
+ pending_requests[numf].accepted = 1;
446
+ sprintf(numchar, "[i] friend request %u accepted as friend no. %d", numf, num);
447
+ new_lines(numchar);
448
+ save_data(m);
449
+ } else {
450
+ sprintf(numchar, "[i] failed to add friend");
451
+ new_lines(numchar);
452
+ }
202
453
  }
203
- do_refresh();
204
- }
205
- else if (inpt_command == 'h') { //help
206
- new_lines("[i] commands: /f ID (to add friend), /m friendnumber message (to send message), /s status (to change status)");
207
- new_lines("[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)");
208
- }
209
- else if (inpt_command == 'i') { //info
210
- char idstring0[200];
211
- char idstring1[PUB_KEY_BYTES][5];
212
- char idstring2[PUB_KEY_BYTES][5];
213
- int i;
214
- for (i = 0; i < PUB_KEY_BYTES; i++)
215
- {
216
- if (self_public_key[i] < (PUB_KEY_BYTES/2))
217
- strcpy(idstring1[i],"0");
218
- else
219
- strcpy(idstring1[i], "");
220
- sprintf(idstring2[i], "%hhX", self_public_key[i]);
221
- }
222
- //
223
- strcpy(idstring0,"[i] ID: ");
224
- int j;
225
- for (j = 0; j < PUB_KEY_BYTES; j++) {
226
- strcat(idstring0,idstring1[j]);
227
- strcat(idstring0,idstring2[j]);
228
- }
229
- new_lines(idstring0);
230
- }
231
-
232
- else if (inpt_command == 'q') { //exit
454
+ } else if (inpt_command == 'r') { // /r #: remove friend
455
+ uint8_t numf = atoi(line + 3);
456
+
457
+ if (!tox_friend_exists(m, numf)) {
458
+ char err[64];
459
+ sprintf(err, "You don't have a friend %i.", numf);
460
+ new_lines(err);
461
+ return;
462
+ }
463
+
464
+ char msg[128 + TOX_MAX_NAME_LENGTH];
465
+ char fname[TOX_MAX_NAME_LENGTH ];
466
+ getfriendname_terminated(m, numf, fname);
467
+ sprintf(msg, "Are you sure you want to delete friend %i: %s? (y/n)", numf, fname);
468
+ input_line[0] = 0;
469
+ new_lines(msg);
470
+
471
+ int c;
472
+
473
+ do {
474
+ c = getchar();
475
+ } while ((c != 'y') && (c != 'n') && (c != EOF));
476
+
477
+ if (c == 'y') {
478
+ int res = tox_del_friend(m, numf);
479
+
480
+ if (res == 0)
481
+ sprintf(msg, "[i] [%i: %s] is no longer your friend", numf, fname);
482
+ else
483
+ sprintf(msg, "[i] failed to remove friend");
484
+
485
+ new_lines(msg);
486
+ }
487
+ } else if (inpt_command == 'h') { //help
488
+ if (line[2] == ' ') {
489
+ if (line[3] == 'f') {
490
+ new_lines_mark(help_friend1, 1);
491
+ new_lines_mark(help_friend2, 1);
492
+ return;
493
+ } else if (line[3] == 'g') {
494
+ new_lines_mark(help_group, 1);
495
+ return;
496
+ }
497
+ }
498
+
499
+ new_lines_mark(help_main, 1);
500
+ } else if (inpt_command == 'x') { //info
501
+ char idstring[200];
502
+ get_id(m, idstring);
503
+ new_lines(idstring);
504
+ } else if (inpt_command == 'g') { //create new group chat
505
+ char msg[256];
506
+ sprintf(msg, "[g] Created new group chat with number: %u", tox_add_groupchat(m));
507
+ new_lines(msg);
508
+ } else if (inpt_command == 'i') { //invite friendnum to groupnum
509
+ char *posi[1];
510
+ int friendnumber = strtoul(line + prompt_offset, posi, 0);
511
+ int groupnumber = strtoul(*posi + 1, NULL, 0);
512
+ char msg[256];
513
+ sprintf(msg, "[g] Invited friend number %u to group number %u, returned: %u (0 means success)", friendnumber,
514
+ groupnumber, tox_invite_friend(m, friendnumber, groupnumber));
515
+ new_lines(msg);
516
+ } else if (inpt_command == 'z') { //send message to groupnum
517
+ char *posi[1];
518
+ int groupnumber = strtoul(line + prompt_offset, posi, 0);
519
+
520
+ if (**posi != 0) {
521
+ int res = tox_group_message_send(m, groupnumber, (uint8_t *)*posi + 1, strlen(*posi + 1));
522
+
523
+ if (res == 0) {
524
+ char msg[32 + STRING_LENGTH];
525
+ sprintf(msg, "[g] #%u: YOU: %s", groupnumber, *posi + 1);
526
+ new_lines(msg);
527
+ } else {
528
+ char msg[128];
529
+ sprintf(msg, "[i] could not send message to group no. %u: %i", groupnumber, res);
530
+ new_lines(msg);
531
+ }
532
+ }
533
+ } else if (inpt_command == 't') {
534
+ char *posi[1];
535
+ int friendnum = strtoul(line + prompt_offset, posi, 0);
536
+
537
+ if (**posi != 0) {
538
+ char msg[512];
539
+ sprintf(msg, "[t] Sending file %s to friendnum %u filenumber is %i (-1 means failure)", *posi + 1, friendnum,
540
+ add_filesender(m, friendnum, *posi + 1));
541
+ new_lines(msg);
542
+ }
543
+ } else if (inpt_command == 'q') { //exit
544
+ save_data(m);
233
545
  endwin();
546
+ tox_kill(m);
234
547
  exit(EXIT_SUCCESS);
235
- } else {
548
+ } else if (inpt_command == 'c') { //set conversation partner
549
+ if (line[2] == 'r') {
550
+ if (conversation_default != 0) {
551
+ conversation_default = 0;
552
+ new_lines("[i] default conversation reset");
553
+ } else
554
+ new_lines("[i] default conversation wasn't set, nothing to do");
555
+ } else if (line[3] != ' ') {
556
+ new_lines("[i] invalid command");
557
+ } else {
558
+ int num = atoi(line + 4);
559
+
560
+ /* zero is also returned for not-a-number */
561
+ if (!num && strcmp(line + 4, "0"))
562
+ num = -1;
563
+
564
+ if (num < 0)
565
+ new_lines("[i] invalid command parameter");
566
+ else if (line[2] == 'f') {
567
+ conversation_default = num + 1;
568
+ char buffer[128];
569
+ sprintf(buffer, "[i] default conversation is now to friend %i", num);
570
+ new_lines(buffer);
571
+ } else if (line[2] == 'g') {
572
+ char buffer[128];
573
+ conversation_default = - (num + 1);
574
+ sprintf(buffer, "[i] default conversation is now to group %i", num);
575
+ new_lines(buffer);
576
+ } else
577
+ new_lines("[i] invalid command");
578
+ }
579
+ } else if (inpt_command == 'p') { //list peers
580
+ char *posi = NULL;
581
+ int group_number = strtoul(line + prompt_offset, &posi, 0);
582
+
583
+ if (posi != NULL) {
584
+ char msg[64];
585
+ int peer_cnt = tox_group_number_peers(m, group_number);
586
+
587
+ if (peer_cnt < 0) {
588
+ new_lines("[g] Invalid group number.");
589
+ } else if (peer_cnt == 0) {
590
+ sprintf(msg, "[g] #%i: No peers in group.", group_number);
591
+ new_lines(msg);
592
+ } else {
593
+ sprintf(msg, "[g] #%i: Group has %i peers. Names:", group_number, peer_cnt);
594
+ new_lines(msg);
595
+ print_groupchatpeers(m, group_number);
596
+ }
597
+ }
598
+ } else {
236
599
  new_lines("[i] invalid command");
237
600
  }
238
601
  } else {
239
- new_lines("[i] invalid command");
240
- //new_lines(line);
602
+ if (conversation_default != 0) {
603
+ if (conversation_default > 0) {
604
+ int friendnumber = conversation_default - 1;
605
+ uint32_t res = tox_send_message(m, friendnumber, (uint8_t *)line, strlen(line));
606
+
607
+ if (res == 0) {
608
+ char sss[128];
609
+ sprintf(sss, "[i] could not send message to friend no. %u", friendnumber);
610
+ new_lines(sss);
611
+ } else
612
+ print_formatted_message(m, line, friendnumber, 1);
613
+ } else {
614
+ int groupnumber = - conversation_default - 1;
615
+ int res = tox_group_message_send(m, groupnumber, (uint8_t *)line, strlen(line));
616
+
617
+ if (res == 0) {
618
+ char msg[32 + STRING_LENGTH];
619
+ sprintf(msg, "[g] #%u: YOU: %s", groupnumber, line);
620
+ new_lines(msg);
621
+ } else {
622
+ char msg[128];
623
+ sprintf(msg, "[i] could not send message to group no. %u: %i", groupnumber, res);
624
+ new_lines(msg);
625
+ }
626
+ }
627
+ } else
628
+ new_lines("[i] invalid input: neither command nor in conversation");
241
629
  }
242
630
  }
243
631
 
244
- void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
632
+ /* basic wrap, ignores embedded '\t', '\n' or '|'
633
+ * inserts continuation markers if there's enough space left,
634
+ * otherwise turns spaces into newlines if possible */
635
+ void wrap(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], int line_width)
245
636
  {
246
- strcpy(output,input);
247
- size_t len = strlen(output);
248
- int i = 0;
249
- for (i = line_width; i < len; i = i + line_width) {
250
- while (output[i] != ' ' && i != 0) {
251
- i--;
637
+ size_t i, len = strlen(input);
638
+
639
+ if ((line_width < 4) || (len < (size_t)line_width)) {
640
+ /* if line_width ridiculously tiny, it's not worth the effort */
641
+ strcpy(output, input);
642
+ return;
643
+ }
644
+
645
+ /* how much can we shift? */
646
+ size_t delta_is = 0, delta_remain = STRING_LENGTH_WRAPPED - len - 1;
647
+
648
+ /* if the line is very very short, don't insert continuation markers,
649
+ * as they would use up too much of the line */
650
+ if ((size_t)line_width < 2 * wrap_cont_len)
651
+ delta_remain = 0;
652
+
653
+ for (i = line_width; i < len; i += line_width) {
654
+ /* look backward for a space to expand/turn into a new line */
655
+ size_t k = i;
656
+ size_t m = i - line_width;
657
+
658
+ while (input[k] != ' ' && k > m) {
659
+ k--;
660
+ }
661
+
662
+ if (k > m) {
663
+ if (delta_remain > wrap_cont_len) {
664
+ /* replace space with continuation, then
665
+ * set the pos. after the space as new line start
666
+ * (i.e. space is being "eaten") */
667
+ memcpy(output + m + delta_is, input + m, k - m);
668
+ strcpy(output + k + delta_is, wrap_cont_str);
669
+
670
+ delta_remain -= wrap_cont_len - 1;
671
+ delta_is += wrap_cont_len - 1;
672
+ i = k + 1;
673
+ } else {
674
+ /* no more space to push forward: replace the space,
675
+ * use its pos. + 1 as starting point for the next line */
676
+ memcpy(output + m + delta_is, input + m, k - m);
677
+ output[k + delta_is] = '\n';
678
+ i = k + 1;
679
+ }
680
+ } else {
681
+ /* string ends right here:
682
+ * don't add a continuation marker with nothing following */
683
+ if (i == len - 1)
684
+ break;
685
+
686
+ /* nothing found backwards */
687
+ if (delta_remain > wrap_cont_len) {
688
+ /* break at the end of the line,
689
+ * i.e. in the middle of the word at the border */
690
+ memcpy(output + m + delta_is, input + m, line_width);
691
+ strcpy(output + i + delta_is, wrap_cont_str);
692
+
693
+ delta_remain -= wrap_cont_len;
694
+ delta_is += wrap_cont_len;
695
+ } else {
696
+ /* no more space to push, no space to convert:
697
+ * just copy the whole line and move on;
698
+ * means the line count calc'ed will be off */
699
+ memcpy(output + m + delta_is, input + m, line_width);
700
+ }
252
701
  }
253
- if (i > 0) {
254
- output[i] = '\n';
702
+ }
703
+
704
+ i -= line_width;
705
+ memcpy(output + i + delta_is, input + i, len - i);
706
+
707
+ output[len + delta_is] = 0;
708
+ }
709
+
710
+ /*
711
+ * extended wrap, honors '\n', accepts '|' as "break here when necessary"
712
+ * marks wrapped lines with "+ " in front, which does expand output
713
+ * does NOT honor '\t': would require a lot more work (and tab width isn't always 8)
714
+ */
715
+ void wrap_bars(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], size_t line_width)
716
+ {
717
+ size_t len = strlen(input);
718
+ size_t ipos, opos = 0;
719
+ size_t bar_avail = 0, space_avail = 0, nl_got = 0; /* in opos */
720
+
721
+ for (ipos = 0; ipos < len; ipos++) {
722
+ if (opos - nl_got < line_width) {
723
+ /* not yet at the limit */
724
+ char c = input[ipos];
725
+
726
+ if (c == ' ')
727
+ space_avail = opos;
728
+
729
+ output[opos++] = input[ipos];
730
+
731
+ if (opos >= STRING_LENGTH_WRAPPED) {
732
+ opos = STRING_LENGTH_WRAPPED - 1;
733
+ break;
734
+ }
735
+
736
+ if (c == '|') {
737
+ output[opos - 1] = ' ';
738
+ bar_avail = opos;
739
+
740
+ if (opos + 2 >= STRING_LENGTH_WRAPPED) {
741
+ opos = STRING_LENGTH_WRAPPED - 1;
742
+ break;
743
+ }
744
+
745
+ output[opos++] = '|';
746
+ output[opos++] = ' ';
747
+ }
748
+
749
+ if (c == '\n')
750
+ nl_got = opos;
751
+
752
+ continue;
753
+ } else {
754
+ /* at the limit */
755
+ if (bar_avail > nl_got) {
756
+ /* overwrite */
757
+ memcpy(output + bar_avail - 1, wrap_cont_str, wrap_cont_len);
758
+ nl_got = bar_avail;
759
+
760
+ ipos--;
761
+ continue;
762
+ }
763
+
764
+ if (space_avail > nl_got) {
765
+ if (opos + wrap_cont_len - 1 >= STRING_LENGTH_WRAPPED) {
766
+ opos = STRING_LENGTH_WRAPPED - 1;
767
+ break;
768
+ }
769
+
770
+ /* move forward by 2 characters */
771
+ memmove(output + space_avail + 3, output + space_avail + 1, opos - (space_avail + 1));
772
+ memcpy(output + space_avail, wrap_cont_str, wrap_cont_len);
773
+ nl_got = space_avail + 1;
774
+
775
+ opos += 2;
776
+ ipos--;
777
+ continue;
778
+ }
779
+
780
+ char c = input[ipos];
781
+
782
+ if ((c == '|') || (c == ' ') || (c == '\n')) {
783
+ if (opos + wrap_cont_len >= STRING_LENGTH_WRAPPED) {
784
+ opos = STRING_LENGTH_WRAPPED - 1;
785
+ break;
786
+ }
787
+
788
+ memcpy(output + opos, wrap_cont_str, wrap_cont_len);
789
+
790
+ nl_got = opos;
791
+ opos += wrap_cont_len;
792
+ }
793
+
794
+ output[opos++] = input[ipos];
795
+
796
+ if (opos >= STRING_LENGTH_WRAPPED) {
797
+ opos = STRING_LENGTH_WRAPPED - 1;
798
+ break;
799
+ }
800
+
801
+ continue;
255
802
  }
256
803
  }
804
+
805
+ if (opos >= STRING_LENGTH_WRAPPED)
806
+ opos = STRING_LENGTH_WRAPPED - 1;
807
+
808
+ output[opos] = 0;
257
809
  }
258
810
 
259
811
  int count_lines(char *string)
260
812
  {
261
- size_t len = strlen(string);
813
+ size_t i, len = strlen(string);
262
814
  int count = 1;
263
- int i;
815
+
264
816
  for (i = 0; i < len; i++) {
265
817
  if (string[i] == '\n')
266
818
  count++;
267
819
  }
820
+
268
821
  return count;
269
822
  }
270
823
 
271
824
  char *appender(char *str, const char c)
272
825
  {
273
826
  size_t len = strlen(str);
827
+
274
828
  if (len < STRING_LENGTH) {
275
- str[len+1] = str[len];
829
+ str[len + 1] = str[len];
276
830
  str[len] = c;
277
831
  }
832
+
278
833
  return str;
279
834
  }
280
835
 
281
836
  void do_refresh()
282
837
  {
283
- int count=0;
284
- char wrap_output[STRING_LENGTH];
285
- int L;
838
+ int count = 0;
839
+ char wrap_output[STRING_LENGTH_WRAPPED];
286
840
  int i;
841
+
287
842
  for (i = 0; i < HISTORY; i++) {
288
- wrap(wrap_output, lines[i], x);
289
- L = count_lines(wrap_output);
843
+ if (flag[i])
844
+ wrap_bars(wrap_output, lines[i], x);
845
+ else
846
+ wrap(wrap_output, lines[i], x);
847
+
848
+ int L = count_lines(wrap_output);
290
849
  count = count + L;
850
+
291
851
  if (count < y) {
292
- move(y-1-count, 0);
293
- printw(wrap_output);
852
+ move(y - 1 - count, 0);
853
+ printw("%s", wrap_output);
294
854
  clrtoeol();
295
855
  }
296
856
  }
297
- move(y-1, 0);
857
+
858
+ move(y - 1, 0);
298
859
  clrtoeol();
299
860
  printw(">> ");
300
- printw(line);
861
+ printw("%s", input_line);
301
862
  clrtoeol();
302
863
  refresh();
303
864
  }
304
865
 
305
- void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
866
+ void print_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
306
867
  {
307
868
  new_lines("[i] received friend request with message:");
308
869
  new_lines((char *)data);
309
870
  char numchar[100];
310
871
  sprintf(numchar, "[i] accept request with /a %u", num_requests);
311
872
  new_lines(numchar);
312
- memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
873
+ memcpy(pending_requests[num_requests].id, public_key, TOX_CLIENT_ID_SIZE);
874
+ pending_requests[num_requests].accepted = 0;
313
875
  ++num_requests;
314
876
  do_refresh();
315
877
  }
316
878
 
317
- void print_message(int friendnumber, uint8_t * string, uint16_t length)
879
+ void print_message(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
318
880
  {
319
- char name[MAX_NAME_LENGTH];
320
- getname(friendnumber, (uint8_t*)name);
321
- char msg[100+length+strlen(name)+1];
322
- time_t rawtime;
323
- struct tm * timeinfo;
324
- time ( &rawtime );
325
- timeinfo = localtime ( &rawtime );
326
- char* temp = asctime(timeinfo);
327
- size_t len = strlen(temp);
328
- temp[len-1] = '\0';
329
- sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp
330
- new_lines(format_message((char*)string, friendnumber));
881
+ /* ensure null termination */
882
+ uint8_t null_string[length + 1];
883
+ memcpy(null_string, string, length);
884
+ null_string[length] = 0;
885
+ print_formatted_message(m, (char *)null_string, friendnumber, 0);
331
886
  }
332
887
 
333
- void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
888
+ void print_nickchange(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
334
889
  {
335
- char name[MAX_NAME_LENGTH];
336
- getname(friendnumber, (uint8_t*)name);
337
- char msg[100+length];
338
- sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string);
339
- new_lines(msg);
890
+ char name[TOX_MAX_NAME_LENGTH + 1];
891
+
892
+ if (getfriendname_terminated(m, friendnumber, name) != -1) {
893
+ char msg[100 + length];
894
+
895
+ if (name[0] != 0)
896
+ sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string);
897
+ else
898
+ sprintf(msg, "[i] [%d] Friend's name is %s.", friendnumber, string);
899
+
900
+ new_lines(msg);
901
+ }
340
902
  }
341
903
 
342
- void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
904
+ void print_statuschange(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
343
905
  {
344
- char name[MAX_NAME_LENGTH];
345
- getname(friendnumber, (uint8_t*)name);
346
- char msg[100+length+strlen(name)+1];
347
- sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string);
348
- new_lines(msg);
906
+ char name[TOX_MAX_NAME_LENGTH + 1];
907
+
908
+ if (getfriendname_terminated(m, friendnumber, name) != -1) {
909
+ char msg[100 + length + strlen(name) + 1];
910
+
911
+ if (name[0] != 0)
912
+ sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string);
913
+ else
914
+ sprintf(msg, "[i] [%d] Their status changed to %s.", friendnumber, string);
915
+
916
+ new_lines(msg);
917
+ }
349
918
  }
350
919
 
351
- void load_key()
920
+ static char *data_file_name = NULL;
921
+
922
+ static int load_data(Tox *m)
352
923
  {
353
- FILE *data_file = NULL;
354
- data_file = fopen("data","r");
924
+ FILE *data_file = fopen(data_file_name, "r");
925
+
355
926
  if (data_file) {
356
- //load keys
357
927
  fseek(data_file, 0, SEEK_END);
358
- int size = ftell(data_file);
359
- fseek(data_file, 0, SEEK_SET);
928
+ size_t size = ftell(data_file);
929
+ rewind(data_file);
930
+
360
931
  uint8_t data[size];
361
- if (fread(data, sizeof(uint8_t), size, data_file) != size){
362
- printf("[i] could not read data file\n[i] exiting\n");
363
- exit(1);
932
+
933
+ if (fread(data, sizeof(uint8_t), size, data_file) != size) {
934
+ fputs("[!] could not read data file!\n", stderr);
935
+ fclose(data_file);
936
+ return 0;
364
937
  }
365
- Messenger_load(data, size);
366
- } else {
367
- //else save new keys
368
- int size = Messenger_size();
369
- uint8_t data[size];
370
- Messenger_save(data);
371
- data_file = fopen("data","w");
372
- if (fwrite(data, sizeof(uint8_t), size, data_file) != size){
373
- printf("[i] could not write data file\n[i] exiting\n");
374
- exit(1);
938
+
939
+ tox_load(m, data, size);
940
+
941
+ if (fclose(data_file) < 0) {
942
+ perror("[!] fclose failed");
943
+ /* we got it open and the expected data read... let it be ok */
944
+ /* return 0; */
375
945
  }
946
+
947
+ return 1;
376
948
  }
377
- fclose(data_file);
949
+
950
+ return 0;
378
951
  }
379
952
 
380
- int main(int argc, char *argv[])
953
+ static int save_data(Tox *m)
381
954
  {
382
- if (argc < 4) {
383
- printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
384
- exit(0);
955
+ FILE *data_file = fopen(data_file_name, "w");
956
+
957
+ if (!data_file) {
958
+ perror("[!] load_key");
959
+ return 0;
385
960
  }
386
- int c;
387
- int on = 0;
388
- initMessenger();
389
- //if keyfiles exist
390
- if(argc > 4){
391
- if(strncmp(argv[4], "nokey", 6) < 0){
392
- //load_key();
961
+
962
+ int res = 1;
963
+ size_t size = tox_size(m);
964
+ uint8_t data[size];
965
+ tox_save(m, data);
966
+
967
+ if (fwrite(data, sizeof(uint8_t), size, data_file) != size) {
968
+ fputs("[!] could not write data file (1)!", stderr);
969
+ res = 0;
970
+ }
971
+
972
+ if (fclose(data_file) < 0) {
973
+ perror("[!] could not write data file (2)");
974
+ res = 0;
975
+ }
976
+
977
+ return res;
978
+ }
979
+
980
+ static int load_data_or_init(Tox *m, char *path)
981
+ {
982
+ data_file_name = path;
983
+
984
+ if (load_data(m))
985
+ return 1;
986
+
987
+ if (save_data(m))
988
+ return 1;
989
+
990
+ return 0;
991
+ }
992
+
993
+ void print_help(char *prog_name)
994
+ {
995
+ printf("nTox %.1f - Command-line tox-core client\n", 0.1);
996
+ printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile]\n", prog_name);
997
+
998
+ puts("Options: (order IS relevant)");
999
+ puts(" --ipv4 / --ipv6 [Optional] Support IPv4 only or IPv4 & IPv6.");
1000
+ puts(" IP PORT KEY [REQUIRED] A node to connect to (IP/Port) and its key.");
1001
+ puts(" -f keyfile [Optional] Specify a keyfile to read from and write to.");
1002
+ }
1003
+
1004
+ void print_invite(Tox *m, int friendnumber, const uint8_t *group_public_key, void *userdata)
1005
+ {
1006
+ char msg[256];
1007
+ sprintf(msg, "[i] received group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber,
1008
+ tox_join_groupchat(m, friendnumber, group_public_key));
1009
+ new_lines(msg);
1010
+ }
1011
+
1012
+ void print_groupchatpeers(Tox *m, int groupnumber)
1013
+ {
1014
+ int num = tox_group_number_peers(m, groupnumber);
1015
+
1016
+ if (num < 0)
1017
+ return;
1018
+
1019
+ if (!num) {
1020
+ new_lines("[g]+ no peers left in group.");
1021
+ return;
1022
+ }
1023
+
1024
+ uint8_t names[num][TOX_MAX_NAME_LENGTH];
1025
+ uint16_t lengths[num];
1026
+ tox_group_get_names(m, groupnumber, names, lengths, num);
1027
+ int i;
1028
+ char numstr[16];
1029
+ char header[] = "[g]+ ";
1030
+ size_t header_len = strlen(header);
1031
+ char msg[STRING_LENGTH];
1032
+ strcpy(msg, header);
1033
+ size_t len_total = header_len;
1034
+
1035
+ for (i = 0; i < num; ++i) {
1036
+ size_t len_name = lengths[i];
1037
+ size_t len_num = sprintf(numstr, "%i: ", i);
1038
+
1039
+ if (len_num + len_name + len_total + 3 >= STRING_LENGTH) {
1040
+ new_lines_mark(msg, 1);
1041
+
1042
+ strcpy(msg, header);
1043
+ len_total = header_len;
1044
+ }
1045
+
1046
+ strcpy(msg + len_total, numstr);
1047
+ len_total += len_num;
1048
+ memcpy(msg + len_total, (char *)names[i], len_name);
1049
+ len_total += len_name;
1050
+
1051
+ if (i < num - 1) {
1052
+ strcpy(msg + len_total, "|");
1053
+ len_total++;
1054
+ }
1055
+ }
1056
+
1057
+ new_lines_mark(msg, 1);
1058
+ }
1059
+
1060
+ void print_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *message, uint16_t length,
1061
+ void *userdata)
1062
+ {
1063
+ char msg[256 + length];
1064
+ uint8_t name[TOX_MAX_NAME_LENGTH] = {0};
1065
+ int len = tox_group_peername(m, groupnumber, peernumber, name);
1066
+
1067
+ //print_groupchatpeers(m, groupnumber);
1068
+ if (len <= 0)
1069
+ name[0] = 0;
1070
+
1071
+ if (name[0] != 0)
1072
+ sprintf(msg, "[g] %u: %u <%s>: %s", groupnumber, peernumber, name, message);
1073
+ else
1074
+ sprintf(msg, "[g] #%u: %u Unknown: %s", groupnumber, peernumber, message);
1075
+
1076
+ new_lines(msg);
1077
+ }
1078
+ void print_groupnamelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata)
1079
+ {
1080
+ char msg[256];
1081
+
1082
+ if (change == TOX_CHAT_CHANGE_PEER_ADD) {
1083
+ sprintf(msg, "[g] #%i: New peer %i.", groupnumber, peernumber);
1084
+ new_lines(msg);
1085
+ } else if (change == TOX_CHAT_CHANGE_PEER_DEL) {
1086
+ /* if peer was the last in list, it simply dropped,
1087
+ * otherwise it was overwritten by the last peer
1088
+ *
1089
+ * adjust output
1090
+ */
1091
+ int peers_total = tox_group_number_peers(m, groupnumber);
1092
+
1093
+ if (peers_total == peernumber) {
1094
+ sprintf(msg, "[g] #%i: Peer %i left.", groupnumber, peernumber);
1095
+ new_lines(msg);
1096
+ } else {
1097
+ uint8_t peername[TOX_MAX_NAME_LENGTH] = {0};
1098
+ int len = tox_group_peername(m, groupnumber, peernumber, peername);
1099
+
1100
+ if (len <= 0)
1101
+ peername[0] = 0;
1102
+
1103
+ sprintf(msg, "[g] #%i: Peer %i left. Former peer [%i: <%s>] is now peer %i.", groupnumber, peernumber,
1104
+ peers_total, peername, peernumber);
1105
+ new_lines(msg);
393
1106
  }
1107
+ } else if (change == TOX_CHAT_CHANGE_PEER_NAME) {
1108
+ uint8_t peername[TOX_MAX_NAME_LENGTH] = {0};
1109
+ int len = tox_group_peername(m, groupnumber, peernumber, peername);
1110
+
1111
+ if (len <= 0)
1112
+ peername[0] = 0;
1113
+
1114
+ sprintf(msg, "[g] #%i: Peer %i's name changed: %s", groupnumber, peernumber, peername);
1115
+ new_lines(msg);
394
1116
  } else {
395
- load_key();
1117
+ sprintf(msg, "[g] #%i: Name list changed (peer %i, change %i?):", groupnumber, peernumber, change);
1118
+ new_lines(msg);
1119
+ print_groupchatpeers(m, groupnumber);
396
1120
  }
397
- m_callback_friendrequest(print_request);
398
- m_callback_friendmessage(print_message);
399
- m_callback_namechange(print_nickchange);
400
- m_callback_userstatus(print_statuschange);
401
- char idstring0[200];
402
- char idstring1[PUB_KEY_BYTES][5];
403
- char idstring2[PUB_KEY_BYTES][5];
404
- int i;
405
- for(i = 0; i < PUB_KEY_BYTES; i++)
406
- {
407
- if (self_public_key[i] < (PUB_KEY_BYTES / 2))
408
- strcpy(idstring1[i],"0");
409
- else
410
- strcpy(idstring1[i], "");
411
- sprintf(idstring2[i], "%hhX",self_public_key[i]);
1121
+ }
1122
+ void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *filename,
1123
+ uint16_t filename_length, void *userdata)
1124
+ {
1125
+ char msg[512];
1126
+ sprintf(msg, "[t] %u is sending us: %s of size %llu", friendnumber, filename, (long long unsigned int)filesize);
1127
+ new_lines(msg);
1128
+
1129
+ if (tox_file_send_control(m, friendnumber, 1, filenumber, 0, 0, 0) == 0) {
1130
+ sprintf(msg, "Accepted file transfer. (saving file as: %u.%u.bin)", friendnumber, filenumber);
1131
+ new_lines(msg);
1132
+ } else
1133
+ new_lines("Could not accept file transfer.");
1134
+ }
1135
+
1136
+ void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type,
1137
+ const uint8_t *data, uint16_t length, void *userdata)
1138
+ {
1139
+ char msg[512] = {0};
1140
+
1141
+ if (control_type == 0)
1142
+ sprintf(msg, "[t] %u accepted file transfer: %u", friendnumber, filenumber);
1143
+ else if (control_type == 3)
1144
+ sprintf(msg, "[t] %u file transfer: %u completed", friendnumber, filenumber);
1145
+ else
1146
+ sprintf(msg, "[t] control %u received", control_type);
1147
+
1148
+ new_lines(msg);
1149
+ }
1150
+
1151
+ void write_file(Tox *m, int friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata)
1152
+ {
1153
+ char filename[256];
1154
+ sprintf(filename, "%u.%u.bin", friendnumber, filenumber);
1155
+ FILE *pFile = fopen(filename, "a");
1156
+
1157
+ if (tox_file_data_remaining(m, friendnumber, filenumber, 1) == 0) {
1158
+ //file_control(m, friendnumber, 1, filenumber, 3, 0, 0);
1159
+ char msg[512];
1160
+ sprintf(msg, "[t] %u file transfer: %u completed", friendnumber, filenumber);
1161
+ new_lines(msg);
1162
+ }
1163
+
1164
+ if (fwrite(data, length, 1, pFile) != 1)
1165
+ new_lines("Error writing to file");
1166
+
1167
+ fclose(pFile);
1168
+ }
1169
+
1170
+ char timeout_getch(Tox *m)
1171
+ {
1172
+ char c;
1173
+ int slpval = tox_do_interval(m);
1174
+
1175
+ fd_set fds;
1176
+ FD_ZERO(&fds);
1177
+ FD_SET(0, &fds);
1178
+ struct timeval tv;
1179
+ tv.tv_sec = 0;
1180
+ tv.tv_usec = slpval * 1000;
1181
+
1182
+ c = ERR;
1183
+ int n = select(1, &fds, NULL, NULL, &tv);
1184
+
1185
+ if (n < 0) {
1186
+ new_lines("select error: maybe interupted");
1187
+ } else if (n == 0) {
1188
+ } else {
1189
+ c = getch();
1190
+ }
1191
+
1192
+ return c;
1193
+ }
1194
+
1195
+ int main(int argc, char *argv[])
1196
+ {
1197
+ /* minimalistic locale support (i.e. when printing dates) */
1198
+ setlocale(LC_ALL, "");
1199
+
1200
+ if (argc < 4) {
1201
+ if ((argc == 2) && !strcmp(argv[1], "-h")) {
1202
+ print_help(argv[0]);
1203
+ exit(0);
1204
+ }
1205
+
1206
+ printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile] (or %s -h for help)\n", argv[0], argv[0]);
1207
+ exit(0);
412
1208
  }
413
- strcpy(idstring0,"[i] your ID: ");
414
- int j;
415
- for (j = 0; j < PUB_KEY_BYTES; j++) {
416
- strcat(idstring0,idstring1[j]);
417
- strcat(idstring0,idstring2[j]);
1209
+
1210
+ /* let user override default by cmdline */
1211
+ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
1212
+ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
1213
+
1214
+ if (argvoffset < 0)
1215
+ exit(1);
1216
+
1217
+ int on = 0;
1218
+ char *filename = "data";
1219
+ char idstring[200] = {0};
1220
+ Tox *m;
1221
+
1222
+ /* [-f keyfile] MUST be last two arguments, no point in walking over the list
1223
+ * especially not a good idea to accept it anywhere in the middle */
1224
+ if (argc > argvoffset + 3)
1225
+ if (!strcmp(argv[argc - 2], "-f"))
1226
+ filename = argv[argc - 1];
1227
+
1228
+ m = tox_new(0);
1229
+
1230
+ if ( !m ) {
1231
+ fputs("Failed to allocate Messenger datastructure", stderr);
1232
+ exit(0);
418
1233
  }
1234
+
1235
+ load_data_or_init(m, filename);
1236
+
1237
+ tox_callback_friend_request(m, print_request, NULL);
1238
+ tox_callback_friend_message(m, print_message, NULL);
1239
+ tox_callback_name_change(m, print_nickchange, NULL);
1240
+ tox_callback_status_message(m, print_statuschange, NULL);
1241
+ tox_callback_group_invite(m, print_invite, NULL);
1242
+ tox_callback_group_message(m, print_groupmessage, NULL);
1243
+ tox_callback_file_data(m, write_file, NULL);
1244
+ tox_callback_file_control(m, file_print_control, NULL);
1245
+ tox_callback_file_send_request(m, file_request_accept, NULL);
1246
+ tox_callback_group_namelist_change(m, print_groupnamelistchange, NULL);
1247
+
419
1248
  initscr();
420
1249
  noecho();
421
1250
  raw();
422
1251
  getmaxyx(stdscr, y, x);
423
- new_lines(idstring0);
424
- new_lines(help);
425
- strcpy(line, "");
426
- IP_Port bootstrap_ip_port;
427
- bootstrap_ip_port.port = htons(atoi(argv[2]));
428
- int resolved_address = resolve_addr(argv[1]);
429
- if (resolved_address != 0)
430
- bootstrap_ip_port.ip.i = resolved_address;
431
- else
1252
+
1253
+ new_lines("/h for list of commands");
1254
+ get_id(m, idstring);
1255
+ new_lines(idstring);
1256
+ strcpy(input_line, "");
1257
+
1258
+ uint16_t port = atoi(argv[argvoffset + 2]);
1259
+ unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
1260
+ int res = tox_bootstrap_from_address(m, argv[argvoffset + 1], port, binary_string);
1261
+
1262
+ if (!res) {
1263
+ printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
1264
+ endwin();
432
1265
  exit(1);
433
-
434
- DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
1266
+ }
1267
+
435
1268
  nodelay(stdscr, TRUE);
436
- while(true) {
437
- if (on == 0 && DHT_isconnected()) {
438
- new_lines("[i] connected to DHT\n[i] define username with /n");
439
- on = 1;
1269
+
1270
+ new_lines("[i] change username with /n");
1271
+ uint8_t name[TOX_MAX_NAME_LENGTH + 1];
1272
+ uint16_t namelen = tox_get_self_name(m, name);
1273
+ name[namelen] = 0;
1274
+
1275
+ if (namelen > 0) {
1276
+ char whoami[128 + TOX_MAX_NAME_LENGTH];
1277
+ snprintf(whoami, sizeof(whoami), "[i] your current username is: %s", name);
1278
+ new_lines(whoami);
1279
+ }
1280
+
1281
+ time_t timestamp0 = time(NULL);
1282
+
1283
+ while (1) {
1284
+ if (on == 0) {
1285
+ if (tox_isconnected(m)) {
1286
+ new_lines("[i] connected to DHT");
1287
+ on = 1;
1288
+ } else {
1289
+ time_t timestamp1 = time(NULL);
1290
+
1291
+ if (timestamp0 + 10 < timestamp1) {
1292
+ timestamp0 = timestamp1;
1293
+ tox_bootstrap_from_address(m, argv[argvoffset + 1], port, binary_string);
1294
+ }
1295
+ }
440
1296
  }
441
1297
 
442
- doMessenger();
443
- c_sleep(1);
1298
+
1299
+
1300
+ send_filesenders(m);
1301
+ tox_do(m);
444
1302
  do_refresh();
445
1303
 
446
- c = getch();
1304
+ int c = timeout_getch(m);
1305
+
447
1306
  if (c == ERR || c == 27)
448
1307
  continue;
449
1308
 
450
1309
  getmaxyx(stdscr, y, x);
451
- if (c == '\n') {
452
- line_eval(lines, line);
453
- strcpy(line, "");
454
- } else if (c == 127) {
455
- line[strlen(line)-1] = '\0';
1310
+
1311
+ if ((c == 0x0d) || (c == 0x0a)) {
1312
+ line_eval(m, input_line);
1313
+ strcpy(input_line, "");
1314
+ } else if (c == 8 || c == 127) {
1315
+ input_line[strlen(input_line) - 1] = '\0';
456
1316
  } else if (isalnum(c) || ispunct(c) || c == ' ') {
457
- strcpy(line, appender(line, (char) c));
1317
+ strcpy(input_line, appender(input_line, (char) c));
458
1318
  }
459
1319
  }
1320
+
1321
+ free(binary_string);
1322
+ tox_kill(m);
460
1323
  endwin();
461
1324
  return 0;
462
1325
  }