diff options
Diffstat (limited to 'testing/toxic/prompt.c')
-rw-r--r-- | testing/toxic/prompt.c | 509 |
1 files changed, 0 insertions, 509 deletions
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c deleted file mode 100644 index b00dba20..00000000 --- a/testing/toxic/prompt.c +++ /dev/null | |||
@@ -1,509 +0,0 @@ | |||
1 | /* | ||
2 | * Toxic -- Tox Curses Client | ||
3 | */ | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include <ctype.h> | ||
8 | |||
9 | #include "../../core/Messenger.h" | ||
10 | #include "../../core/network.h" | ||
11 | |||
12 | #include "windows.h" | ||
13 | #include "prompt.h" | ||
14 | |||
15 | extern char *DATA_FILE; | ||
16 | extern int store_data(Messenger *m, char *path); | ||
17 | |||
18 | uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX | ||
19 | uint8_t num_requests = 0; // XXX | ||
20 | |||
21 | static char prompt_buf[MAX_STR_SIZE] = {0}; | ||
22 | static int prompt_buf_pos = 0; | ||
23 | |||
24 | /* commands */ | ||
25 | void cmd_accept(ToxWindow *, Messenger *m, char **); | ||
26 | void cmd_add(ToxWindow *, Messenger *m, char **); | ||
27 | void cmd_clear(ToxWindow *, Messenger *m, char **); | ||
28 | void cmd_connect(ToxWindow *, Messenger *m, char **); | ||
29 | void cmd_help(ToxWindow *, Messenger *m, char **); | ||
30 | void cmd_msg(ToxWindow *, Messenger *m, char **); | ||
31 | void cmd_myid(ToxWindow *, Messenger *m, char **); | ||
32 | void cmd_nick(ToxWindow *, Messenger *m, char **); | ||
33 | void cmd_mynick(ToxWindow *, Messenger *m, char **); | ||
34 | void cmd_quit(ToxWindow *, Messenger *m, char **); | ||
35 | void cmd_status(ToxWindow *, Messenger *m, char **); | ||
36 | void cmd_statusmsg(ToxWindow *, Messenger *m, char **); | ||
37 | |||
38 | #define NUM_COMMANDS 14 | ||
39 | |||
40 | static struct { | ||
41 | char *name; | ||
42 | int numargs; | ||
43 | void (*func)(ToxWindow *, Messenger *m, char **); | ||
44 | } commands[] = { | ||
45 | { "accept", 1, cmd_accept }, | ||
46 | { "add", 1, cmd_add }, | ||
47 | { "clear", 0, cmd_clear }, | ||
48 | { "connect", 3, cmd_connect }, | ||
49 | { "exit", 0, cmd_quit }, | ||
50 | { "help", 0, cmd_help }, | ||
51 | { "msg", 2, cmd_msg }, | ||
52 | { "myid", 0, cmd_myid }, | ||
53 | { "nick", 1, cmd_nick }, | ||
54 | { "mynick", 0, cmd_mynick }, | ||
55 | { "q", 0, cmd_quit }, | ||
56 | { "quit", 0, cmd_quit }, | ||
57 | { "status", 2, cmd_status }, | ||
58 | { "statusmsg", 1, cmd_statusmsg }, | ||
59 | }; | ||
60 | |||
61 | // XXX: | ||
62 | int add_req(uint8_t *public_key) | ||
63 | { | ||
64 | memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); | ||
65 | ++num_requests; | ||
66 | return num_requests - 1; | ||
67 | } | ||
68 | |||
69 | // XXX: FIX | ||
70 | unsigned char *hex_string_to_bin(char hex_string[]) | ||
71 | { | ||
72 | size_t len = strlen(hex_string); | ||
73 | unsigned char *val = malloc(len); | ||
74 | char *pos = hex_string; | ||
75 | int i; | ||
76 | |||
77 | for (i = 0; i < len; ++i, pos += 2) | ||
78 | sscanf(pos, "%2hhx", &val[i]); | ||
79 | |||
80 | return val; | ||
81 | } | ||
82 | |||
83 | void cmd_accept(ToxWindow *self, Messenger *m, char **args) | ||
84 | { | ||
85 | int num = atoi(args[1]); | ||
86 | |||
87 | if (num >= num_requests) { | ||
88 | wprintw(self->window, "Invalid syntax.\n"); | ||
89 | return; | ||
90 | } | ||
91 | |||
92 | num = m_addfriend_norequest(m, pending_requests[num]); | ||
93 | |||
94 | if (num == -1) | ||
95 | wprintw(self->window, "Failed to add friend.\n"); | ||
96 | else { | ||
97 | wprintw(self->window, "Friend accepted as: %d.\n", num); | ||
98 | on_friendadded(m, num); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | void cmd_add(ToxWindow *self, Messenger *m, char **args) | ||
103 | { | ||
104 | uint8_t id_bin[FRIEND_ADDRESS_SIZE]; | ||
105 | char xx[3]; | ||
106 | uint32_t x; | ||
107 | char *id = args[1]; | ||
108 | char *msg = args[2]; | ||
109 | |||
110 | if (!id) { | ||
111 | wprintw(self->window, "Invalid command: add expected at least one argument.\n"); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | if (!msg) | ||
116 | msg = ""; | ||
117 | |||
118 | if (strlen(id) != 2 * FRIEND_ADDRESS_SIZE) { | ||
119 | wprintw(self->window, "Invalid ID length.\n"); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | int i; | ||
124 | |||
125 | for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) { | ||
126 | xx[0] = id[2 * i]; | ||
127 | xx[1] = id[2 * i + 1]; | ||
128 | xx[2] = '\0'; | ||
129 | |||
130 | if (sscanf(xx, "%02x", &x) != 1) { | ||
131 | wprintw(self->window, "Invalid ID.\n"); | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | id_bin[i] = x; | ||
136 | } | ||
137 | |||
138 | for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) { | ||
139 | id[i] = toupper(id[i]); | ||
140 | } | ||
141 | |||
142 | int num = m_addfriend(m, id_bin, (uint8_t *) msg, strlen(msg) + 1); | ||
143 | |||
144 | switch (num) { | ||
145 | case FAERR_TOOLONG: | ||
146 | wprintw(self->window, "Message is too long.\n"); | ||
147 | break; | ||
148 | |||
149 | case FAERR_NOMESSAGE: | ||
150 | wprintw(self->window, "Please add a message to your request.\n"); | ||
151 | break; | ||
152 | |||
153 | case FAERR_OWNKEY: | ||
154 | wprintw(self->window, "That appears to be your own ID.\n"); | ||
155 | break; | ||
156 | |||
157 | case FAERR_ALREADYSENT: | ||
158 | wprintw(self->window, "Friend request already sent.\n"); | ||
159 | break; | ||
160 | |||
161 | case FAERR_UNKNOWN: | ||
162 | wprintw(self->window, "Undefined error when adding friend.\n"); | ||
163 | break; | ||
164 | |||
165 | case FAERR_BADCHECKSUM: | ||
166 | wprintw(self->window, "Bad checksum in address.\n"); | ||
167 | break; | ||
168 | |||
169 | case FAERR_SETNEWNOSPAM: | ||
170 | wprintw(self->window, "Nospam was different.\n"); | ||
171 | break; | ||
172 | |||
173 | default: | ||
174 | wprintw(self->window, "Friend added as %d.\n", num); | ||
175 | on_friendadded(m, num); | ||
176 | break; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void cmd_clear(ToxWindow *self, Messenger *m, char **args) | ||
181 | { | ||
182 | wclear(self->window); | ||
183 | } | ||
184 | |||
185 | void cmd_connect(ToxWindow *self, Messenger *m, char **args) | ||
186 | { | ||
187 | IP_Port dht; | ||
188 | char *ip = args[1]; | ||
189 | char *port = args[2]; | ||
190 | char *key = args[3]; | ||
191 | |||
192 | if (atoi(port) == 0) { | ||
193 | wprintw(self->window, "Invalid syntax.\n"); | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | dht.port = htons(atoi(port)); | ||
198 | uint32_t resolved_address = resolve_addr(ip); | ||
199 | |||
200 | if (resolved_address == 0) { | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | dht.ip.i = resolved_address; | ||
205 | unsigned char *binary_string = hex_string_to_bin(key); | ||
206 | DHT_bootstrap(m->dht, dht, binary_string); | ||
207 | free(binary_string); | ||
208 | } | ||
209 | |||
210 | void cmd_quit(ToxWindow *self, Messenger *m, char **args) | ||
211 | { | ||
212 | endwin(); | ||
213 | exit(0); | ||
214 | } | ||
215 | |||
216 | void cmd_help(ToxWindow *self, Messenger *m, char **args) | ||
217 | { | ||
218 | wclear(self->window); | ||
219 | wattron(self->window, COLOR_PAIR(2) | A_BOLD); | ||
220 | wprintw(self->window, "Commands:\n"); | ||
221 | wattroff(self->window, A_BOLD); | ||
222 | |||
223 | wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); | ||
224 | wprintw(self->window, " add <id> <message> : Add friend\n"); | ||
225 | wprintw(self->window, " status <type> <message> : Set your status\n"); | ||
226 | wprintw(self->window, " statusmsg <message> : Set your status\n"); | ||
227 | wprintw(self->window, " nick <nickname> : Set your nickname\n"); | ||
228 | wprintw(self->window, " mynick : Print your current nickname\n"); | ||
229 | wprintw(self->window, " accept <number> : Accept friend request\n"); | ||
230 | wprintw(self->window, " myid : Print your ID\n"); | ||
231 | wprintw(self->window, " quit/exit : Exit program\n"); | ||
232 | wprintw(self->window, " help : Print this message again\n"); | ||
233 | wprintw(self->window, " clear : Clear this window\n"); | ||
234 | |||
235 | wattron(self->window, A_BOLD); | ||
236 | wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); | ||
237 | wattroff(self->window, A_BOLD); | ||
238 | |||
239 | wattroff(self->window, COLOR_PAIR(2)); | ||
240 | } | ||
241 | |||
242 | void cmd_msg(ToxWindow *self, Messenger *m, char **args) | ||
243 | { | ||
244 | char *id = args[1]; | ||
245 | char *msg = args[2]; | ||
246 | |||
247 | if (m_sendmessage(m, atoi(id), (uint8_t *) msg, strlen(msg) + 1) == 0) | ||
248 | wprintw(self->window, "Error occurred while sending message.\n"); | ||
249 | else | ||
250 | wprintw(self->window, "Message successfully sent.\n"); | ||
251 | } | ||
252 | |||
253 | void cmd_myid(ToxWindow *self, Messenger *m, char **args) | ||
254 | { | ||
255 | char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0}; | ||
256 | size_t i; | ||
257 | uint8_t address[FRIEND_ADDRESS_SIZE]; | ||
258 | getaddress(m, address); | ||
259 | |||
260 | for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) { | ||
261 | char xx[3]; | ||
262 | snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff); | ||
263 | strcat(id, xx); | ||
264 | } | ||
265 | |||
266 | wprintw(self->window, "%s\n", id); | ||
267 | } | ||
268 | |||
269 | void cmd_nick(ToxWindow *self, Messenger *m, char **args) | ||
270 | { | ||
271 | char *nick = args[1]; | ||
272 | setname(m, (uint8_t *) nick, strlen(nick) + 1); | ||
273 | wprintw(self->window, "Nickname set to: %s\n", nick); | ||
274 | |||
275 | if (store_data(m, DATA_FILE)) { | ||
276 | wprintw(self->window, "\nCould not store Messenger data\n"); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | void cmd_mynick(ToxWindow *self, Messenger *m, char **args) | ||
281 | { | ||
282 | uint8_t *nick = malloc(m->name_length); | ||
283 | getself_name(m, nick, m->name_length); | ||
284 | wprintw(self->window, "Current nickname: %s\n", nick); | ||
285 | free(nick); | ||
286 | } | ||
287 | |||
288 | void cmd_status(ToxWindow *self, Messenger *m, char **args) | ||
289 | { | ||
290 | char *status = args[1]; | ||
291 | char *status_text; | ||
292 | |||
293 | USERSTATUS status_kind; | ||
294 | |||
295 | if (!strncmp(status, "online", strlen("online"))) { | ||
296 | status_kind = USERSTATUS_NONE; | ||
297 | status_text = "ONLINE"; | ||
298 | } else if (!strncmp(status, "away", strlen("away"))) { | ||
299 | status_kind = USERSTATUS_AWAY; | ||
300 | status_text = "AWAY"; | ||
301 | } else if (!strncmp(status, "busy", strlen("busy"))) { | ||
302 | status_kind = USERSTATUS_BUSY; | ||
303 | status_text = "BUSY"; | ||
304 | } else { | ||
305 | wprintw(self->window, "Invalid status.\n"); | ||
306 | return; | ||
307 | } | ||
308 | |||
309 | char *msg = args[2]; | ||
310 | |||
311 | if (msg == NULL) { | ||
312 | m_set_userstatus(m, status_kind); | ||
313 | wprintw(self->window, "Status set to: %s\n", status_text); | ||
314 | } else { | ||
315 | m_set_userstatus(m, status_kind); | ||
316 | m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1); | ||
317 | wprintw(self->window, "Status set to: %s, %s\n", status_text, msg); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args) | ||
322 | { | ||
323 | char *msg = args[1]; | ||
324 | m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1); | ||
325 | wprintw(self->window, "Status set to: %s\n", msg); | ||
326 | } | ||
327 | |||
328 | static void execute(ToxWindow *self, Messenger *m, char *u_cmd) | ||
329 | { | ||
330 | int newlines = 0; | ||
331 | char cmd[MAX_STR_SIZE] = {0}; | ||
332 | int i; | ||
333 | |||
334 | for (i = 0; i < strlen(prompt_buf); ++i) { | ||
335 | if (u_cmd[i] == '\n') | ||
336 | ++newlines; | ||
337 | else | ||
338 | cmd[i - newlines] = u_cmd[i]; | ||
339 | } | ||
340 | |||
341 | int leading_spc = 0; | ||
342 | |||
343 | for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i) | ||
344 | leading_spc++; | ||
345 | |||
346 | memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc); | ||
347 | |||
348 | int cmd_end = strlen(cmd); | ||
349 | |||
350 | while (cmd_end > 0 && cmd_end--) | ||
351 | if (!isspace(cmd[cmd_end])) | ||
352 | break; | ||
353 | |||
354 | cmd[cmd_end + 1] = '\0'; | ||
355 | |||
356 | /* insert \0 at argument boundaries */ | ||
357 | int numargs = 0; | ||
358 | |||
359 | for (i = 0; i < MAX_STR_SIZE; i++) { | ||
360 | char quote_chr; | ||
361 | if (cmd[i] == '\"' || cmd[i] == '\'') { | ||
362 | quote_chr = cmd[i]; | ||
363 | while (cmd[++i] != quote_chr && i < MAX_STR_SIZE); /* skip over strings */ | ||
364 | /* Check if got qoute character */ | ||
365 | if (cmd[i] != quote_chr) { | ||
366 | wprintw(self->window, "Missing terminating %c character\n", quote_chr); | ||
367 | return; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | if (cmd[i] == ' ') { | ||
372 | cmd[i] = '\0'; | ||
373 | |||
374 | int j = i; | ||
375 | |||
376 | while (++j < MAX_STR_SIZE && isspace(cmd[j])); | ||
377 | |||
378 | i = j - 1; | ||
379 | |||
380 | numargs++; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* excessive arguments */ | ||
385 | if (numargs > 3) { | ||
386 | wprintw(self->window, "Invalid command: too many arguments.\n"); | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | /* read arguments into array */ | ||
391 | char *cmdargs[5]; | ||
392 | int pos = 0; | ||
393 | |||
394 | for (i = 0; i < 5; i++) { | ||
395 | cmdargs[i] = cmd + pos; | ||
396 | pos += strlen(cmdargs[i]) + 1; | ||
397 | |||
398 | while (isspace(cmd[pos]) && pos < MAX_STR_SIZE) | ||
399 | ++pos; | ||
400 | } | ||
401 | |||
402 | /* no input */ | ||
403 | if (strlen(cmdargs[0]) == 0) | ||
404 | return; | ||
405 | |||
406 | /* match input to command list */ | ||
407 | for (i = 0; i < NUM_COMMANDS; i++) { | ||
408 | if (!strcmp(cmdargs[0], commands[i].name)) { | ||
409 | /* check for missing arguments */ | ||
410 | int j; | ||
411 | |||
412 | for (j = 0; j <= commands[i].numargs; j++) { | ||
413 | if (strlen(cmdargs[j]) == 0) { | ||
414 | wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n", | ||
415 | commands[i].name, commands[i].numargs, j - 1); | ||
416 | return; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | /* check for excess arguments */ | ||
421 | if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) { | ||
422 | wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name); | ||
423 | return; | ||
424 | } | ||
425 | |||
426 | /* pass arguments to command function */ | ||
427 | (commands[i].func)(self, m, cmdargs); | ||
428 | return; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /* no match */ | ||
433 | wprintw(self->window, "Invalid command.\n"); | ||
434 | } | ||
435 | |||
436 | static void prompt_onKey(ToxWindow *self, Messenger *m, wint_t key) | ||
437 | { | ||
438 | /* Add printable characters to line */ | ||
439 | if (isprint(key)) { | ||
440 | if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) { | ||
441 | wprintw(self->window, "\nToo Long.\n"); | ||
442 | prompt_buf_pos = 0; | ||
443 | prompt_buf[0] = 0; | ||
444 | } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) | ||
445 | && (prompt_buf_pos % (COLS - 3) == 0)) { | ||
446 | prompt_buf[prompt_buf_pos++] = '\n'; | ||
447 | } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) | ||
448 | && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { | ||
449 | prompt_buf[prompt_buf_pos++] = '\n'; | ||
450 | } | ||
451 | |||
452 | prompt_buf[prompt_buf_pos++] = key; | ||
453 | prompt_buf[prompt_buf_pos] = 0; | ||
454 | } | ||
455 | |||
456 | /* RETURN key: execute command */ | ||
457 | else if (key == '\n') { | ||
458 | wprintw(self->window, "\n"); | ||
459 | execute(self, m, prompt_buf); | ||
460 | prompt_buf_pos = 0; | ||
461 | prompt_buf[0] = 0; | ||
462 | } | ||
463 | |||
464 | /* BACKSPACE key: Remove one character from line */ | ||
465 | else if (key == 0x107 || key == 0x8 || key == 0x7f) { | ||
466 | if (prompt_buf_pos != 0) { | ||
467 | prompt_buf[--prompt_buf_pos] = 0; | ||
468 | } | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static void prompt_onDraw(ToxWindow *self, Messenger *m) | ||
473 | { | ||
474 | curs_set(1); | ||
475 | int x, y; | ||
476 | getyx(self->window, y, x); | ||
477 | (void) x; | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < (strlen(prompt_buf)); ++i) { | ||
481 | if ((prompt_buf[i] == '\n') && (y != 0)) | ||
482 | --y; | ||
483 | } | ||
484 | |||
485 | wattron(self->window, COLOR_PAIR(1)); | ||
486 | mvwprintw(self->window, y, 0, "# "); | ||
487 | wattroff(self->window, COLOR_PAIR(1)); | ||
488 | mvwprintw(self->window, y, 2, "%s", prompt_buf); | ||
489 | wclrtoeol(self->window); | ||
490 | wrefresh(self->window); | ||
491 | } | ||
492 | |||
493 | static void prompt_onInit(ToxWindow *self, Messenger *m) | ||
494 | { | ||
495 | scrollok(self->window, 1); | ||
496 | cmd_help(self, m, NULL); | ||
497 | wclrtoeol(self->window); | ||
498 | } | ||
499 | |||
500 | ToxWindow new_prompt() | ||
501 | { | ||
502 | ToxWindow ret; | ||
503 | memset(&ret, 0, sizeof(ret)); | ||
504 | ret.onKey = &prompt_onKey; | ||
505 | ret.onDraw = &prompt_onDraw; | ||
506 | ret.onInit = &prompt_onInit; | ||
507 | strcpy(ret.title, "[prompt]"); | ||
508 | return ret; | ||
509 | } | ||