summaryrefslogtreecommitdiff
path: root/testing/toxic/prompt.c
diff options
context:
space:
mode:
Diffstat (limited to 'testing/toxic/prompt.c')
-rw-r--r--testing/toxic/prompt.c509
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
15extern char *DATA_FILE;
16extern int store_data(Messenger *m, char *path);
17
18uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX
19uint8_t num_requests = 0; // XXX
20
21static char prompt_buf[MAX_STR_SIZE] = {0};
22static int prompt_buf_pos = 0;
23
24/* commands */
25void cmd_accept(ToxWindow *, Messenger *m, char **);
26void cmd_add(ToxWindow *, Messenger *m, char **);
27void cmd_clear(ToxWindow *, Messenger *m, char **);
28void cmd_connect(ToxWindow *, Messenger *m, char **);
29void cmd_help(ToxWindow *, Messenger *m, char **);
30void cmd_msg(ToxWindow *, Messenger *m, char **);
31void cmd_myid(ToxWindow *, Messenger *m, char **);
32void cmd_nick(ToxWindow *, Messenger *m, char **);
33void cmd_mynick(ToxWindow *, Messenger *m, char **);
34void cmd_quit(ToxWindow *, Messenger *m, char **);
35void cmd_status(ToxWindow *, Messenger *m, char **);
36void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
37
38#define NUM_COMMANDS 14
39
40static 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:
62int 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
70unsigned 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
83void 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
102void 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
180void cmd_clear(ToxWindow *self, Messenger *m, char **args)
181{
182 wclear(self->window);
183}
184
185void 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
210void cmd_quit(ToxWindow *self, Messenger *m, char **args)
211{
212 endwin();
213 exit(0);
214}
215
216void 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
242void 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
253void 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
269void 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
280void 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
288void 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
321void 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
328static 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
436static 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
472static 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
493static 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
500ToxWindow 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}