From 026790e181a4dd26a60bcbada3e546a1c5e50888 Mon Sep 17 00:00:00 2001 From: plutooo Date: Tue, 30 Jul 2013 12:47:40 -0700 Subject: [PATCH] Fixed a bunch of bugs in TOXIC, added friendlist and more. --- testing/toxic/CMakeLists.txt | 3 +- testing/toxic/friendlist.c | 125 +++++++++++++++++++++++++++++++++++ testing/toxic/main.c | 49 ++++++++++++-- testing/toxic/prompt.c | 107 +++++++++++++++++++----------- 4 files changed, 239 insertions(+), 45 deletions(-) create mode 100644 testing/toxic/friendlist.c diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt index 4f9785d5..c70babb7 100644 --- a/testing/toxic/CMakeLists.txt +++ b/testing/toxic/CMakeLists.txt @@ -5,7 +5,8 @@ set(exe_name toxic) add_executable(${exe_name} main.c - prompt.c) + prompt.c + friendlist.c) target_link_libraries(${exe_name} curses) diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c new file mode 100644 index 00000000..f8b8c840 --- /dev/null +++ b/testing/toxic/friendlist.c @@ -0,0 +1,125 @@ +/* + * Toxic -- Tox Curses Client + */ + +#include +#include +#include +#include + +#include "../../core/Messenger.h" +#include "../../core/network.h" + +#include "windows.h" + +#define MAX_FRIENDS_NUM 100 + +typedef struct { + uint8_t name[MAX_NAME_LENGTH]; + uint8_t status[MAX_USERSTATUS_LENGTH]; + int num; + +} friend_t; + +static friend_t friends[MAX_FRIENDS_NUM]; +static int num_friends = 0; + + +void fix_name(uint8_t* name) { + + // Remove all non alphanumeric characters. + uint8_t* p = name; + uint8_t* q = name; + + while(*p != 0) { + if(isalnum(*p)) { + *q++ = *p; + } + + p++; + } + + *q = 0; +} + +int friendlist_nickchange(int num, uint8_t* str, uint16_t len) { + + if(len >= MAX_NAME_LENGTH || num >= num_friends) + return -1; + + memcpy((char*) &friends[num].name, (char*) str, len); + friends[num].name[len] = 0; + fix_name(friends[num].name); + + return 0; +} + +int friendlist_statuschange(int num, uint8_t* str, uint16_t len) { + + if(len >= MAX_USERSTATUS_LENGTH || num >= num_friends) + return -1; + + memcpy((char*) &friends[num].status, (char*) str, len); + friends[num].status[len] = 0; + fix_name(friends[num].status); + + return 0; +} + +int friendlist_addfriend(int num) { + + if(num_friends == MAX_FRIENDS_NUM) + return -1; + + friends[num_friends].num = num; + getname(num, friends[num_friends].name); + strcpy((char*) friends[num_friends].name, "unknown"); + strcpy((char*) friends[num_friends].status, "unknown"); + + num_friends++; + return 0; +} + +static void friendlist_onKey(ToxWindow* self, int key) { + +} + +static void friendlist_onDraw(ToxWindow* self) { + size_t i; + + wclear(self->window); + + if(num_friends == 0) { + wprintw(self->window, "Empty. Add some friends! :-)\n"); + } + + wprintw(self->window, "\n"); + + for(i=0; iwindow, "[%d] ", friends[i].num); + + attron(A_BOLD); + wprintw(self->window, "%s ", friends[i].name); + attroff(A_BOLD); + + wprintw(self->window, "(%s)\n", friends[i].status); + } + + wrefresh(self->window); +} + +static void friendlist_onInit(ToxWindow* self) { + +} + + +ToxWindow new_friendlist() { + ToxWindow ret; + + ret.onKey = &friendlist_onKey; + ret.onDraw = &friendlist_onDraw; + ret.onInit = &friendlist_onInit; + strcpy(ret.title, "[friends]"); + + return ret; +} diff --git a/testing/toxic/main.c b/testing/toxic/main.c index 0aad6777..e1d1ebd0 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -14,6 +14,12 @@ #include "windows.h" extern ToxWindow new_prompt(); +extern ToxWindow new_friendlist(); + +extern int friendlist_addfriend(int num); +extern int friendlist_nickchange(int num, uint8_t* str, uint16_t len); +extern int friendlist_statuschange(int num, uint8_t* str, uint16_t len); + extern int add_req(uint8_t* public_key); // XXX #define TOXWINDOWS_MAX_NUM 32 @@ -35,11 +41,19 @@ void on_message(int friendnumber, uint8_t* string, uint16_t length) { } void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) { - wprintw(prompt->window, "\n(nick) %d: %s!\n", friendnumber, string); + wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string); + + friendlist_nickchange(friendnumber, string, length); } void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) { - wprintw(prompt->window, "\n(status) %d: %s!\n", friendnumber, string); + wprintw(prompt->window, "\n(statuschange) %d: %s!\n", friendnumber, string); + + friendlist_statuschange(friendnumber, string, length); +} + +void on_friendadded(int friendnumber) { + friendlist_addfriend(friendnumber); } // CALLBACKS END @@ -95,7 +109,7 @@ static void init_windows() { w_num = 0; w_active = 0; - if(add_window(new_prompt()) == -1) { + if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) { fprintf(stderr, "add_window() failed.\n"); endwin(); @@ -134,14 +148,18 @@ static void load_data() { if(buf == NULL) { fprintf(stderr, "malloc() failed.\n"); + fclose(fd); + endwin(); exit(1); } if(fread(buf, len, 1, fd) != 1){ fprintf(stderr, "fread() failed.\n"); + free(buf); fclose(fd); + endwin(); exit(1); } @@ -153,6 +171,7 @@ static void load_data() { if(buf == NULL) { fprintf(stderr, "malloc() failed.\n"); + endwin(); exit(1); } @@ -161,14 +180,18 @@ static void load_data() { fd = fopen("data", "w"); if(fd == NULL) { fprintf(stderr, "fopen() failed.\n"); + free(buf); + endwin(); exit(1); } if(fwrite(buf, len, 1, fd) != 1){ fprintf(stderr, "fwrite() failed.\n"); + free(buf); fclose(fd); + endwin(); exit(1); } } @@ -186,12 +209,16 @@ static void draw_bar() { move(LINES - 1, 0); + attron(COLOR_PAIR(3) | A_BOLD); + printw(" TOXIC 1.0 |"); + attroff(COLOR_PAIR(3) | A_BOLD); + for(i=0; iwindow); a->onDraw(a); draw_bar(); + // Handle input. ch = getch(); - if(ch != ERR) { + if(ch == '\t') { + w_active = (w_active + 1) % w_num; + } + else if(ch != ERR) { a->onKey(a, ch); } diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 4a59cc7b..22d9eb9e 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -15,6 +15,8 @@ uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX uint8_t num_requests=0; // XXX +extern void on_friendadded(int friendnumber); + // XXX: int add_req(uint8_t* public_key) { memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); @@ -40,7 +42,6 @@ static int prompt_buf_pos=0; static void execute(ToxWindow* self, char* cmd) { - // quit/exit: Exit program. if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { endwin(); exit(0); @@ -53,33 +54,32 @@ static void execute(ToxWindow* self, char* cmd) { ip = strchr(cmd, ' '); if(ip == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - ip++; port = strchr(ip, ' '); if(port == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - port[0] = 0; port++; key = strchr(port, ' '); if(key == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - key[0] = 0; key++; if(atoi(port) == 0) { + wprintw(self->window, "Invalid syntax.\n"); return; } - wprintw(self->window, "ip=%s, port=%s, key=%s\n", ip, port, key); - dht.port = htons(atoi(port)); int resolved_address = resolve_addr(ip); @@ -91,38 +91,62 @@ static void execute(ToxWindow* self, char* cmd) { DHT_bootstrap(dht, hex_string_to_bin(key)); } else if(!strncmp(cmd, "add ", strlen("add "))) { + uint8_t id_bin[32]; + size_t i; + char xx[3]; + uint32_t x; + char* id; char* msg; int num; id = strchr(cmd, ' '); - if(id == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - id++; msg = strchr(id, ' '); - if(msg == NULL) { + if(msg != NULL) { + msg[0] = 0; + msg++; + } + else msg = ""; + + if(strlen(id) != 2*32) { + wprintw(self->window, "Invalid ID length.\n"); return; } - msg[0] = 0; - msg++; + for(i=0; i<32; i++) { + xx[0] = id[2*i]; + xx[1] = id[2*i+1]; + xx[2] = '\0'; + + if(sscanf(xx, "%02x", &x) != 1) { + wprintw(self->window, "Invalid ID.\n"); + return; + } + + id_bin[i] = x; + } + + num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); - num = m_addfriend((uint8_t*) id, (uint8_t*) msg, strlen(msg)+1); wprintw(self->window, "Friend added as %d.\n", num); + on_friendadded(num); } else if(!strncmp(cmd, "status ", strlen("status "))) { char* msg; msg = strchr(cmd, ' '); if(msg == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - msg++; + m_set_userstatus((uint8_t*) msg, strlen(msg)+1); wprintw(self->window, "Status set to: %s.\n", msg); } @@ -133,33 +157,22 @@ static void execute(ToxWindow* self, char* cmd) { if(nick == NULL) { return; } - nick++; + setname((uint8_t*) nick, strlen(nick)+1); wprintw(self->window, "Nickname set to: %s.\n", nick); } else if(!strcmp(cmd, "myid")) { - // XXX: Clean this up - char idstring0[200]; - char idstring1[32][5]; - char idstring2[32][5]; - uint32_t i; + char id[32*2 + 1] = {0}; + size_t i; - for(i = 0; i < 32; i++) { - if(self_public_key[i] < 16) - strcpy(idstring1[i], "0"); - else - strcpy(idstring1[i], ""); - - sprintf(idstring2[i], "%hhX", self_public_key[i]); + for(i=0; i<32; i++) { + char xx[3]; + snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); + strcat(id, xx); } - for (i=0; i<32; i++) { - strcat(idstring0, idstring1[i]); - strcat(idstring0, idstring2[i]); - } - - wprintw(self->window, "%s\n", idstring0); + wprintw(self->window, "%s\n", id); } else if(!strncmp(cmd, "accept ", strlen("accept "))) { char* id; @@ -167,17 +180,26 @@ static void execute(ToxWindow* self, char* cmd) { id = strchr(cmd, ' '); if(id == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } id++; - + num = atoi(id); if(num >= num_requests) { + wprintw(self->window, "Invalid syntax.\n"); return; } num = m_addfriend_norequest(pending_requests[num]); - wprintw(self->window, "Friend accepted as: %d.\n", num); + + if(num == -1) { + wprintw(self->window, "Failed to add friend.\n"); + } + else { + wprintw(self->window, "Friend accepted as: %d.\n", num); + on_friendadded(num); + } } else if(!strncmp(cmd, "msg ", strlen("msg "))) { char* id; @@ -186,16 +208,16 @@ static void execute(ToxWindow* self, char* cmd) { id = strchr(cmd, ' '); if(id == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - id++; msg = strchr(id, ' '); if(msg == NULL) { + wprintw(self->window, "Invalid syntax.\n"); return; } - msg[0] = 0; msg++; @@ -206,6 +228,9 @@ static void execute(ToxWindow* self, char* cmd) { wprintw(self->window, "Message successfully sent.\n"); } } + else { + wprintw(self->window, "Invalid syntax.\n"); + } } static void prompt_onKey(ToxWindow* self, int key) { @@ -242,9 +267,6 @@ static void prompt_onKey(ToxWindow* self, int key) { static void prompt_onDraw(ToxWindow* self) { int x, y; - mvwin(self->window,0,0); - wresize(self->window, LINES-2, COLS); - getyx(self->window, y, x); (void) x; @@ -265,11 +287,18 @@ static void print_usage(ToxWindow* self) { wprintw(self->window, " connect : Connect to DHT server\n"); wprintw(self->window, " add : Add friend\n"); + wprintw(self->window, " msg : Send message\n"); wprintw(self->window, " status : Set your status\n"); wprintw(self->window, " nick : Set your nickname\n"); wprintw(self->window, " accept : Accept friend request\n"); wprintw(self->window, " myid : Print your ID\n"); wprintw(self->window, " quit/exit : Exit program\n"); + + + wattron(self->window, A_BOLD); + wprintw(self->window, "Use the TAB key to navigate through the tabs.\n"); + wattroff(self->window, A_BOLD); + wattroff(self->window, COLOR_PAIR(2)); }