From 3bc7f15fe5a306ced566e1258ad4f9c4f89cd463 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 01:57:29 -0400 Subject: [PATCH 01/25] added ability to close and reopen chat windows & other minor changes --- testing/toxic/chat.c | 15 +++- testing/toxic/friendlist.c | 40 +++++++--- testing/toxic/main.c | 157 +++++++++++++++++++++++-------------- testing/toxic/prompt.c | 5 +- testing/toxic/windows.h | 8 ++ 5 files changed, 150 insertions(+), 75 deletions(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 936eb868..c11a7f12 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -25,6 +25,8 @@ typedef struct { } ChatContext; +extern void del_window(ToxWindow *w, int f_num); +extern int focus_window(int num); extern void fix_name(uint8_t* name); void print_help(ChatContext* self); void execute(ToxWindow* self, ChatContext* ctx, char* cmd); @@ -50,7 +52,7 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) fix_name(nick); wattron(ctx->history, COLOR_PAIR(2)); - wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); wattroff(ctx->history, COLOR_PAIR(2)); wattron(ctx->history, COLOR_PAIR(4)); wprintw(ctx->history, "%s: ", nick); @@ -116,7 +118,7 @@ static void chat_onKey(ToxWindow* self, int key) { if(!string_is_empty(ctx->line)) { /* make sure the string has at least non-space character */ wattron(ctx->history, COLOR_PAIR(2)); - wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); wattroff(ctx->history, COLOR_PAIR(2)); wattron(ctx->history, COLOR_PAIR(1)); wprintw(ctx->history, "you: ", ctx->line); @@ -185,6 +187,12 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) } wprintw(ctx->history, "Your ID: %s\n", id); } + else if (strcmp(ctx->line, "/close") == 0) { + focus_window(0); // Go to prompt screen + int f_num = ctx->friendnum; + delwin(ctx->linewin); + del_window(self, f_num); + } else wprintw(ctx->history, "Invalid command.\n"); } @@ -256,6 +264,5 @@ ToxWindow new_chat(int friendnum) { x->friendnum = friendnum; ret.x = (void*) x; - free(x); return ret; -} +} \ No newline at end of file diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index b4b619a2..2d060ae0 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c @@ -12,12 +12,11 @@ #include "windows.h" +extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM]; extern int add_window(ToxWindow w); extern int focus_window(int num); extern ToxWindow new_chat(int friendnum); -#define MAX_FRIENDS_NUM 100 - typedef struct { uint8_t name[MAX_NAME_LENGTH]; uint8_t status[MAX_USERSTATUS_LENGTH]; @@ -86,14 +85,11 @@ int friendlist_onFriendAdded(int num) { getname(num, friends[num_friends].name); strcpy((char*) friends[num_friends].name, "unknown"); strcpy((char*) friends[num_friends].status, "unknown"); - friends[num_friends].chatwin = -1; - - num_friends++; + friends[num_friends++].chatwin = -1; return 0; } static void friendlist_onKey(ToxWindow* self, int key) { - if(key == KEY_UP) { if(num_selected != 0) num_selected--; @@ -103,12 +99,26 @@ static void friendlist_onKey(ToxWindow* self, int key) { num_selected = (num_selected+1) % num_friends; } else if(key == '\n') { - - if(friends[num_selected].chatwin != -1) - return; - - friends[num_selected].chatwin = add_window(new_chat(num_selected)); - focus_window(friends[num_selected].chatwin); + /* Jump to chat window if already open */ + if (friends[num_selected].chatwin != -1) { + int i; + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + if (WINDOW_STATUS[i] == num_selected) { + focus_window(i); + break; + } + } + }else { + friends[num_selected].chatwin = add_window(new_chat(num_selected)); + focus_window(friends[num_selected].chatwin); + int i; + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { // Find open slot + if (WINDOW_STATUS[i] == -1) { + WINDOW_STATUS[i] = num_selected; + break; + } + } + } } } @@ -145,6 +155,10 @@ static void friendlist_onDraw(ToxWindow* self) { wrefresh(self->window); } +void disable_chatwin(int f_num) { + friends[f_num].chatwin = -1; +} + static void friendlist_onInit(ToxWindow* self) { } @@ -164,4 +178,4 @@ ToxWindow new_friendlist() { strcpy(ret.title, "[friends]"); return ret; -} +} \ No newline at end of file diff --git a/testing/toxic/main.c b/testing/toxic/main.c index e0e23708..e55cb85d 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -17,13 +17,12 @@ extern ToxWindow new_prompt(); extern ToxWindow new_friendlist(); extern int friendlist_onFriendAdded(int num); - +extern void disable_chatwin(int f_num); extern int add_req(uint8_t* public_key); // XXX -#define TOXWINDOWS_MAX_NUM 32 - -static ToxWindow windows[TOXWINDOWS_MAX_NUM]; -static int w_num; +char WINDOW_STATUS[MAX_WINDOW_SLOTS]; // Holds status of chat windows +static ToxWindow windows[MAX_WINDOW_SLOTS]; +int w_num; static int w_active; static ToxWindow* prompt; @@ -115,6 +114,16 @@ static void init_tox() { m_callback_userstatus(on_statuschange); } +void init_window_status() { + int i; + for (i = 0; i < N_DEFAULT_WINS; i++) + WINDOW_STATUS[i] = i; + + int j; + for (j = N_DEFAULT_WINS; j < MAX_WINDOW_SLOTS; j++) + WINDOW_STATUS[j] = -1; +} + int add_window(ToxWindow w) { if(w_num == TOXWINDOWS_MAX_NUM) return -1; @@ -133,6 +142,21 @@ int add_window(ToxWindow w) { return w_num - 1; } +/* Deletes window w and cleans up */ +void del_window(ToxWindow *w, int f_num) { + delwin(w->window); + int i; + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + if (WINDOW_STATUS[i] == f_num) { + WINDOW_STATUS[i] = -1; + disable_chatwin(f_num); + break; + } + } + clear(); + refresh(); +} + int focus_window(int num) { if(num >= w_num || num < 0) return -1; @@ -143,7 +167,6 @@ int focus_window(int num) { static void init_windows() { w_num = 0; - w_active = 0; if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) { fprintf(stderr, "add_window() failed.\n"); @@ -151,7 +174,6 @@ static void init_windows() { endwin(); exit(1); } - prompt = &windows[0]; } @@ -238,7 +260,6 @@ static void load_data(char *path) { static void draw_bar() { static int odd = 0; - size_t i; attron(COLOR_PAIR(4)); mvhline(LINES - 2, 0, '_', COLS); @@ -250,28 +271,26 @@ static void draw_bar() { printw(" TOXIC 1.0 |"); attroff(COLOR_PAIR(4) | A_BOLD); - for(i=0; i max) { // infinite loop check + endwin(); + clear(); + exit(2); + } + } + }else { + int i = w_active - 1; + if (i < 0) i = max; + while (true) { + if (WINDOW_STATUS[i] != -1) { + w_active = i; + return; + } + if (--i < 0) i = max; + if (f_inf++ > max) { + endwin(); + clear(); + exit(2); + } + } + } +} + int main(int argc, char* argv[]) { int ch; - int i = 0; - int f_flag = 0; - char *filename = "data"; ToxWindow* a; - for(i = 0; i < argc; i++) { - if(argv[i][0] == '-') { - if(argv[i][1] == 'f') { - if(argv[i + 1] != NULL) - filename = argv[i + 1]; - else { - f_flag = -1; - } - } - } - } - init_term(); init_tox(); - load_data(filename); + init_window_status(); init_windows(); + char *filename = "data"; + load_data(filename); - if(f_flag == -1) { - attron(COLOR_PAIR(3) | A_BOLD); - wprintw(prompt->window, "You passed '-f' without giving an argument!\n" + int i; + for(i = 0; i < argc; i++) { + if(argv[i][0] == '-' && argv[i][1] == 'f') { + if(argv[i + 1] != NULL) + filename = argv[i + 1]; + else { + attron(COLOR_PAIR(3) | A_BOLD); + wprintw(prompt->window, "You passed '-f' without giving an argument!\n" "defaulting to 'data' for a keyfile...\n"); - attroff(COLOR_PAIR(3) | A_BOLD); + attroff(COLOR_PAIR(3) | A_BOLD); + } + } } - - while(true) { // Update tox. do_tox(); @@ -325,18 +372,14 @@ int main(int argc, char* argv[]) { // Handle input. ch = getch(); - if(ch == '\t') { - w_active = (w_active + 1) % w_num; - } - else if(ch == KEY_BTAB) { - w_active = (w_active + w_num - 1) % w_num; + if(ch == '\t' || ch == KEY_BTAB) + set_active_window(ch); + else if(ch != ERR) { + a->onKey(a, ch); } else if(ch != ERR) { a->onKey(a, ch); } - } - return 0; -} - +} \ No newline at end of file diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 463b9352..d40fb2a6 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -254,7 +254,9 @@ static void execute(ToxWindow* self, char* cmd) { wprintw(self->window, "Message successfully sent.\n"); } } - + else if (!strncmp(cmd, "clear", strlen("clear"))) { + wclear(self->window); + } else { wprintw(self->window, "Invalid command.\n"); } @@ -314,6 +316,7 @@ static void print_usage(ToxWindow* self) { 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, " clear : Clear the screen\n"); wprintw(self->window, " quit/exit : Exit program\n"); wprintw(self->window, " help : Print this message again\n"); diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h index dde1430f..cb45614d 100644 --- a/testing/toxic/windows.h +++ b/testing/toxic/windows.h @@ -3,6 +3,14 @@ */ #include +#define TOXWINDOWS_MAX_NUM 32 +#define MAX_FRIENDS_NUM 100 + +/* number of permanent default windows */ +#define N_DEFAULT_WINS 2 + +/* maximum window slots for WINDOW_STATUS array */ +#define MAX_WINDOW_SLOTS N_DEFAULT_WINS+MAX_FRIENDS_NUM typedef struct ToxWindow_ ToxWindow; From e479f338c18abdafae88c5f02b9996659d1fd6a7 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 02:32:50 -0400 Subject: [PATCH 02/25] test --- testing/toxic/chat.c | 4 +++- testing/toxic/main.c | 39 ++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index c11a7f12..eb297f7c 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -236,6 +236,7 @@ void print_help(ChatContext* self) { wprintw(self->history, " /nick : Set your nickname\n"); wprintw(self->history, " /myid : Print your ID\n"); wprintw(self->history, " /clear : Clear the screen\n"); + wprintw(self->history, " /close : Closes the current chat window\n"); wprintw(self->history, " /quit or /exit : Exit program\n"); wprintw(self->history, " /help : Print this message again\n\n"); @@ -264,5 +265,6 @@ ToxWindow new_chat(int friendnum) { x->friendnum = friendnum; ret.x = (void*) x; + free(x); return ret; -} \ No newline at end of file +} diff --git a/testing/toxic/main.c b/testing/toxic/main.c index e55cb85d..42657e88 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -337,28 +337,37 @@ void set_active_window(int ch) { int main(int argc, char* argv[]) { int ch; + int i = 0; + int f_flag = 0; + char *filename = "data"; ToxWindow* a; + for(i = 0; i < argc; i++) { + if (argv[i] == NULL){ + break; + } else if(argv[i][0] == '-') { + if(argv[i][1] == 'f') { + if(argv[i + 1] != NULL) + filename = argv[i + 1]; + else { + f_flag = -1; + } + } + } + } + init_term(); init_tox(); - init_window_status(); - init_windows(); - char *filename = "data"; load_data(filename); + init_windows(); - int i; - for(i = 0; i < argc; i++) { - if(argv[i][0] == '-' && argv[i][1] == 'f') { - if(argv[i + 1] != NULL) - filename = argv[i + 1]; - else { - attron(COLOR_PAIR(3) | A_BOLD); - wprintw(prompt->window, "You passed '-f' without giving an argument!\n" + if(f_flag == -1) { + attron(COLOR_PAIR(3) | A_BOLD); + wprintw(prompt->window, "You passed '-f' without giving an argument!\n" "defaulting to 'data' for a keyfile...\n"); - attroff(COLOR_PAIR(3) | A_BOLD); - } - } + attroff(COLOR_PAIR(3) | A_BOLD); } + while(true) { // Update tox. do_tox(); @@ -382,4 +391,4 @@ int main(int argc, char* argv[]) { } } return 0; -} \ No newline at end of file +} From 29880b4299a1eedcf1b8c732925a088b54be1358 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 02:48:59 -0400 Subject: [PATCH 03/25] init array --- testing/toxic/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/toxic/main.c b/testing/toxic/main.c index 42657e88..c8cf73ed 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -360,6 +360,7 @@ int main(int argc, char* argv[]) { init_tox(); load_data(filename); init_windows(); + init_window_status(); if(f_flag == -1) { attron(COLOR_PAIR(3) | A_BOLD); From 4b76983a692e0234b220b1c8fee87edb12673be2 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 16:04:06 -0400 Subject: [PATCH 04/25] chat window deleting and re-adding - it just werks --- testing/toxic/chat.c | 6 +++--- testing/toxic/friendlist.c | 27 +++++++++++++++++-------- testing/toxic/main.c | 41 ++++++++++++++++---------------------- testing/toxic/prompt.c | 9 ++++----- 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 2c1f1072..5d0e14ad 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -25,8 +25,8 @@ typedef struct { } ChatContext; +extern int w_active; extern void del_window(ToxWindow *w, int f_num); -extern int focus_window(int num); extern void fix_name(uint8_t* name); void print_help(ChatContext* self); void execute(ToxWindow* self, ChatContext* ctx, char* cmd); @@ -188,7 +188,7 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) wprintw(ctx->history, "Your ID: %s\n", id); } else if (strcmp(ctx->line, "/close") == 0) { - focus_window(0); // Go to prompt screen + w_active = 0; // Go to prompt screen int f_num = ctx->friendnum; delwin(ctx->linewin); del_window(self, f_num); @@ -236,7 +236,7 @@ void print_help(ChatContext* self) { wprintw(self->history, " /nick : Set your nickname\n"); wprintw(self->history, " /myid : Print your ID\n"); wprintw(self->history, " /clear : Clear the screen\n"); - wprintw(self->history, " /close : Closes the current chat window\n"); + wprintw(self->history, " /close : Close the current chat window\n"); wprintw(self->history, " /quit or /exit : Exit program\n"); wprintw(self->history, " /help : Print this message again\n\n"); diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index 2d060ae0..647f563d 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c @@ -13,9 +13,9 @@ #include "windows.h" extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM]; -extern int add_window(ToxWindow w); -extern int focus_window(int num); +extern int add_window(ToxWindow w, int n); extern ToxWindow new_chat(int friendnum); +extern int w_active; typedef struct { uint8_t name[MAX_NAME_LENGTH]; @@ -52,7 +52,17 @@ void friendlist_onMessage(ToxWindow* self, int num, uint8_t* str, uint16_t len) return; if(friends[num].chatwin == -1) { - friends[num].chatwin = add_window(new_chat(num)); + friends[num].chatwin = num; + int i; + /* Find first open slot to hold chat window */ + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + if (WINDOW_STATUS[i] == -1) { + WINDOW_STATUS[i] = num; + add_window(new_chat(num_selected), i); + w_active = i; + break; + } + } } } @@ -104,17 +114,18 @@ static void friendlist_onKey(ToxWindow* self, int key) { int i; for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { if (WINDOW_STATUS[i] == num_selected) { - focus_window(i); + w_active = i; break; } } }else { - friends[num_selected].chatwin = add_window(new_chat(num_selected)); - focus_window(friends[num_selected].chatwin); int i; - for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { // Find open slot + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { if (WINDOW_STATUS[i] == -1) { WINDOW_STATUS[i] = num_selected; + friends[num_selected].chatwin = num_selected; + add_window(new_chat(num_selected), i); + w_active = i; break; } } @@ -178,4 +189,4 @@ ToxWindow new_friendlist() { strcpy(ret.title, "[friends]"); return ret; -} \ No newline at end of file +} diff --git a/testing/toxic/main.c b/testing/toxic/main.c index c8cf73ed..892f812a 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -23,7 +23,7 @@ extern int add_req(uint8_t* public_key); // XXX char WINDOW_STATUS[MAX_WINDOW_SLOTS]; // Holds status of chat windows static ToxWindow windows[MAX_WINDOW_SLOTS]; int w_num; -static int w_active; +int w_active; static ToxWindow* prompt; // CALLBACKS START @@ -40,7 +40,7 @@ void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) { wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n); - for(i=0; iwindow, "\n(message) %d: %s\n", friendnumber, string); - for(i=0; iwindow, "\n(nickchange) %d: %s!\n", friendnumber, string); - for(i=0; iwindow, "\n(statuschange) %d: %s!\n", friendnumber, string); - for(i=0; i= TOXWINDOWS_MAX_NUM) return -1; if(LINES < 2) return -1; w.window = newwin(LINES - 2, COLS, 0, 0); - if(w.window == NULL) return -1; - windows[w_num++] = w; + windows[n] = w; w.onInit(&w); - - return w_num - 1; + w_num++; + return n; } /* Deletes window w and cleans up */ @@ -157,24 +157,17 @@ void del_window(ToxWindow *w, int f_num) { refresh(); } -int focus_window(int num) { - if(num >= w_num || num < 0) - return -1; - - w_active = num; - return 0; -} - static void init_windows() { w_num = 0; - - if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) { + int n_prompt = 0; + int n_friendslist = 1; + if(add_window(new_prompt(), n_prompt) == -1 + || add_window(new_friendlist(), n_friendslist) == -1) { fprintf(stderr, "add_window() failed.\n"); - endwin(); exit(1); } - prompt = &windows[0]; + prompt = &windows[n_prompt]; } static void do_tox() { diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index d40fb2a6..f973afd7 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -158,7 +158,9 @@ static void execute(ToxWindow* self, char* cmd) { break; } } - + else if (!strcmp(cmd, "clear")) { + wclear(self->window); + } else if(!strcmp(cmd, "help")) { print_usage(self); } @@ -254,9 +256,6 @@ static void execute(ToxWindow* self, char* cmd) { wprintw(self->window, "Message successfully sent.\n"); } } - else if (!strncmp(cmd, "clear", strlen("clear"))) { - wclear(self->window); - } else { wprintw(self->window, "Invalid command.\n"); } @@ -316,7 +315,7 @@ static void print_usage(ToxWindow* self) { 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, " clear : Clear the screen\n"); + wprintw(self->window, " clear : Clear this window\n"); wprintw(self->window, " quit/exit : Exit program\n"); wprintw(self->window, " help : Print this message again\n"); From 16a74ffaf991ffed364fce823c1689eb68b26bc9 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 16:34:55 -0400 Subject: [PATCH 05/25] list commands on chat window popup --- testing/toxic/chat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 5d0e14ad..175c6b05 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -225,11 +225,12 @@ static void chat_onInit(ToxWindow* self) { scrollok(ctx->history, 1); ctx->linewin = subwin(self->window, 2, x, y - 3, 0); + print_help(ctx); } void print_help(ChatContext* self) { wattron(self->history, COLOR_PAIR(2) | A_BOLD); - wprintw(self->history, "\nCommands:\n"); + wprintw(self->history, "Commands:\n"); wattroff(self->history, A_BOLD); wprintw(self->history, " /status : Set your status\n"); From 3f712d2650937c78735375f9695d73a8dbc95a91 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 18:07:08 -0400 Subject: [PATCH 06/25] bug fix and added wrapping on friends list --- testing/toxic/friendlist.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index 647f563d..a1f9851e 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c @@ -58,11 +58,11 @@ void friendlist_onMessage(ToxWindow* self, int num, uint8_t* str, uint16_t len) for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { if (WINDOW_STATUS[i] == -1) { WINDOW_STATUS[i] = num; - add_window(new_chat(num_selected), i); + add_window(new_chat(num), i); w_active = i; break; - } } + } } } @@ -101,8 +101,9 @@ int friendlist_onFriendAdded(int num) { static void friendlist_onKey(ToxWindow* self, int key) { if(key == KEY_UP) { - if(num_selected != 0) - num_selected--; + num_selected--; + if (num_selected < 0) + num_selected = num_friends-1; } else if(key == KEY_DOWN) { if(num_friends != 0) From 663764e046fa7f83d03138e370ba074fc851909d Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Mon, 5 Aug 2013 18:38:55 -0400 Subject: [PATCH 07/25] spacing didn't match outgoing msgs --- testing/toxic/chat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 175c6b05..15d124bc 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -52,7 +52,7 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) fix_name(nick); wattron(ctx->history, COLOR_PAIR(2)); - wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); wattroff(ctx->history, COLOR_PAIR(2)); wattron(ctx->history, COLOR_PAIR(4)); wprintw(ctx->history, "%s: ", nick); From 3cd6aeb541781e23d9129c9503611740134c45e2 Mon Sep 17 00:00:00 2001 From: "Christoph J. Thompson" Date: Tue, 6 Aug 2013 06:33:32 +0200 Subject: [PATCH 08/25] On UNIX, if pkg-config is available, use it to find the location of libconfig's headers. modified: cmake/FindLIBCONFIG.cmake --- cmake/FindLIBCONFIG.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/FindLIBCONFIG.cmake b/cmake/FindLIBCONFIG.cmake index d5018240..b3ae4d11 100644 --- a/cmake/FindLIBCONFIG.cmake +++ b/cmake/FindLIBCONFIG.cmake @@ -5,7 +5,12 @@ # LIBCONFIG_FOUND # -FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h) +if (UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_LIBCONFIG QUIET libconfig) +endif () + +FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h HINTS ${_LIBCONFIG_INCLUDEDIR}) FIND_LIBRARY(LIBCONFIG_LIBRARY NAMES config) From 1f001b2f915710e254d039c1f74c533196826235 Mon Sep 17 00:00:00 2001 From: Nominate Date: Tue, 6 Aug 2013 08:10:05 +0100 Subject: [PATCH 09/25] Stops line-spamming and clears before printing help This addresses one issue in #340 perfectly and slightly improves the other. --- testing/toxic/prompt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 16750c5d..c832db39 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -159,10 +159,11 @@ static void execute(ToxWindow* self, char* cmd) { } } else if(!strcmp(cmd, "clear")) { - wclear(self->window); + wclear(self->window); } else if(!strcmp(cmd, "help")) { - print_usage(self); + wclear(self->window); + print_usage(self); } else if(!strncmp(cmd, "status ", strlen("status "))) { char* msg; @@ -265,8 +266,8 @@ static void execute(ToxWindow* self, char* cmd) { static void prompt_onKey(ToxWindow* self, int key) { // PRINTABLE characters: Add to line. if(isprint(key)) { - if(prompt_buf_pos == (sizeof(prompt_buf) - 1)) { - return; + if(prompt_buf_pos == (COLS - 3)) { + return; } prompt_buf[prompt_buf_pos++] = key; prompt_buf[prompt_buf_pos] = 0; From 45c84e55e6e25bd95b5b6c86368845ff20dec7e9 Mon Sep 17 00:00:00 2001 From: Nominate Date: Tue, 6 Aug 2013 11:16:17 +0100 Subject: [PATCH 10/25] Corrected wrap-around This should allow wrap-around and allow proper execution. --- testing/toxic/prompt.c | 80 ++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index c832db39..742b35f8 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -1,6 +1,6 @@ /* - * Toxic -- Tox Curses Client - */ +* Toxic -- Tox Curses Client +*/ #include #include @@ -41,7 +41,17 @@ unsigned char * hex_string_to_bin(char hex_string[]) static char prompt_buf[256] = {0}; static int prompt_buf_pos=0; -static void execute(ToxWindow* self, char* cmd) { +static void execute(ToxWindow* self, char* u_cmd) { + int i; + int newlines = 0; + char cmd[256] = {0}; + for(i = 0; i < strlen(prompt_buf); i++) + { + if (u_cmd[i] == '\n') + ++newlines; + else + cmd[i - newlines] = u_cmd[i]; + } if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { endwin(); @@ -158,7 +168,7 @@ static void execute(ToxWindow* self, char* cmd) { break; } } - else if(!strcmp(cmd, "clear")) { + else if(!strcmp(cmd, "clear")) { wclear(self->window); } else if(!strcmp(cmd, "help")) { @@ -197,7 +207,7 @@ static void execute(ToxWindow* self, char* cmd) { for(i=0; i<32; i++) { char xx[3]; - snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); + snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); strcat(id, xx); } @@ -266,8 +276,16 @@ static void execute(ToxWindow* self, char* cmd) { static void prompt_onKey(ToxWindow* self, int key) { // PRINTABLE characters: Add to line. if(isprint(key)) { - if(prompt_buf_pos == (COLS - 3)) { - return; + if (prompt_buf_pos == 255){ + wprintw(self->window, "\nToo Long.\n"); + prompt_buf_pos = 0; + prompt_buf[0] = 0; + } + else if(!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) && (prompt_buf_pos % (COLS - 3) == 0)) { + prompt_buf[prompt_buf_pos++] = '\n'; + } + else if(!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { + prompt_buf[prompt_buf_pos++] = '\n'; } prompt_buf[prompt_buf_pos++] = key; prompt_buf[prompt_buf_pos] = 0; @@ -290,20 +308,22 @@ static void prompt_onKey(ToxWindow* self, int key) { } static void prompt_onDraw(ToxWindow* self) { - curs_set(1); - int x, y; - - getyx(self->window, y, x); - (void) x; - - wattron(self->window, COLOR_PAIR(1)); - mvwprintw(self->window, y, 0, "# "); - wattroff(self->window, COLOR_PAIR(1)); - - mvwprintw(self->window, y, 2, "%s", prompt_buf); - wclrtoeol(self->window); - - wrefresh(self->window); + curs_set(1); + int x, y; + getyx(self->window, y, x); + (void) x; + int i; + for (i = 0; i < (strlen(prompt_buf)); i++) + { + if ((prompt_buf[i] == '\n') && (y != 0)) + --y; + } + wattron(self->window, COLOR_PAIR(1)); + mvwprintw(self->window, y, 0, "# "); + wattroff(self->window, COLOR_PAIR(1)); + mvwprintw(self->window, y, 2, "%s", prompt_buf); + wclrtoeol(self->window); + wrefresh(self->window); } static void print_usage(ToxWindow* self) { @@ -311,15 +331,15 @@ static void print_usage(ToxWindow* self) { wprintw(self->window, "Commands:\n"); wattroff(self->window, A_BOLD); - wprintw(self->window, " connect : Connect to DHT server\n"); - wprintw(self->window, " add : Add friend\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"); - wprintw(self->window, " help : Print this message again\n"); - wprintw(self->window, " clear : Clear this window\n"); + wprintw(self->window, " connect : Connect to DHT server\n"); + wprintw(self->window, " add : Add friend\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"); + wprintw(self->window, " help : Print this message again\n"); + wprintw(self->window, " clear : Clear this window\n"); wattron(self->window, A_BOLD); wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); From fb9791bc6946fd893e101537fb19fea3b351b0ce Mon Sep 17 00:00:00 2001 From: Nominate Date: Tue, 6 Aug 2013 11:20:11 +0100 Subject: [PATCH 11/25] Update prompt.c --- testing/toxic/prompt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 742b35f8..3006b8a6 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -44,12 +44,12 @@ static int prompt_buf_pos=0; static void execute(ToxWindow* self, char* u_cmd) { int i; int newlines = 0; - char cmd[256] = {0}; + char cmd[256] = {0}; for(i = 0; i < strlen(prompt_buf); i++) { if (u_cmd[i] == '\n') - ++newlines; - else + ++newlines; + else cmd[i - newlines] = u_cmd[i]; } @@ -276,7 +276,7 @@ static void execute(ToxWindow* self, char* u_cmd) { static void prompt_onKey(ToxWindow* self, int key) { // PRINTABLE characters: Add to line. if(isprint(key)) { - if (prompt_buf_pos == 255){ + if (prompt_buf_pos == (sizeof(prompt_buf) - 1)){ wprintw(self->window, "\nToo Long.\n"); prompt_buf_pos = 0; prompt_buf[0] = 0; From 532f16a377616442ba499f48285b9fff4c138a3c Mon Sep 17 00:00:00 2001 From: Nominate Date: Tue, 6 Aug 2013 11:50:10 +0100 Subject: [PATCH 12/25] Fixed formatting --- testing/toxic/prompt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 3006b8a6..a53c163f 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -43,8 +43,8 @@ static int prompt_buf_pos=0; static void execute(ToxWindow* self, char* u_cmd) { int i; - int newlines = 0; - char cmd[256] = {0}; + int newlines = 0; + char cmd[256] = {0}; for(i = 0; i < strlen(prompt_buf); i++) { if (u_cmd[i] == '\n') @@ -331,15 +331,15 @@ static void print_usage(ToxWindow* self) { wprintw(self->window, "Commands:\n"); wattroff(self->window, A_BOLD); - wprintw(self->window, " connect : Connect to DHT server\n"); - wprintw(self->window, " add : Add friend\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"); - wprintw(self->window, " help : Print this message again\n"); - wprintw(self->window, " clear : Clear this window\n"); + wprintw(self->window, " connect : Connect to DHT server\n"); + wprintw(self->window, " add : Add friend\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"); + wprintw(self->window, " help : Print this message again\n"); + wprintw(self->window, " clear : Clear this window\n"); wattron(self->window, A_BOLD); wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); From 99d9ecf74cab43ca6ae24ab5dd62a3b758b3e666 Mon Sep 17 00:00:00 2001 From: plutooo Date: Mon, 5 Aug 2013 15:04:38 -0700 Subject: [PATCH 13/25] core: Move send ping packets functions to ping.c --- core/DHT.c | 84 ++++++-------------------------------------------- core/packets.h | 33 ++++++++++++++++++++ core/ping.c | 67 +++++++++++++++++++++++++++++++++++++--- core/ping.h | 3 +- core/util.c | 11 ++++++- core/util.h | 3 ++ 6 files changed, 121 insertions(+), 80 deletions(-) create mode 100644 core/packets.h diff --git a/core/DHT.c b/core/DHT.c index 01abfdd2..fa36d41f 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -24,6 +24,7 @@ /*----------------------------------------------------------------------------------*/ #include "DHT.h" +#include "packets.h" #include "ping.h" /* maximum number of clients stored per friend. */ @@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port) return 0; } -/* send a ping request, only works if none has been sent to that ip/port - * in the last 5 seconds. - */ -static int pingreq(IP_Port ip_port, uint8_t * public_key) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) - return 1; - - uint64_t ping_id = add_ping(ip_port); - if(ping_id == 0) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, - nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 0; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - -/* send a ping response */ -static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key)) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 1; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - /* send a getnodes request */ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) { @@ -641,8 +577,8 @@ static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) if(len != sizeof(ping_id)) return 1; - pingres(source, packet + 1, ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_response(source, (clientid_t*) (packet + 1), ping_id); + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -701,7 +637,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) memcpy(&ping_id, plain, sizeof(ping_id)); sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -741,7 +677,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) uint32_t i; for(i = 0; i < num_nodes; ++i) { - pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); + send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); } @@ -831,8 +767,8 @@ static void doDHTFriends(void) /* if node is not dead. */ if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( friends_list[i].client_list[j].ip_port, - friends_list[i].client_list[j].client_id ); + send_ping_request( friends_list[i].client_list[j].ip_port, + (clientid_t*) &friends_list[i].client_list[j].client_id ); friends_list[i].client_list[j].last_pinged = temp_time; } /* if node is good. */ @@ -869,8 +805,8 @@ static void doClose(void) /* if node is not dead. */ if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( close_clientlist[i].ip_port, - close_clientlist[i].client_id ); + send_ping_request( close_clientlist[i].ip_port, + (clientid_t*) &close_clientlist[i].client_id ); close_clientlist[i].last_pinged = temp_time; } /* if node is good. */ @@ -1151,7 +1087,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t /*TODO: improve port guessing algorithm*/ uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); IP_Port pinging = {ip, htons(port)}; - pingreq(pinging, friends_list[friend_num].client_id); + send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); } friends_list[friend_num].punching_index = i; } diff --git a/core/packets.h b/core/packets.h new file mode 100644 index 00000000..b6d3d364 --- /dev/null +++ b/core/packets.h @@ -0,0 +1,33 @@ +/* + * packet.h -- Packet structure + * + * This file is donated to the Tox Project. + * Copyright 2013 plutooo + */ + +typedef struct { + uint8_t id[CLIENT_ID_SIZE]; +} __attribute__((packed)) clientid_t; + +typedef enum { + PACKET_PING_REQ = 0, + PACKET_PING_RES = 1 +} packetid_t; + +// Ping packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; +} __attribute__((packed)) pingreq_t; + +// Pong packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; +} __attribute__((packed)) pingres_t; diff --git a/core/ping.c b/core/ping.c index 8a7d534f..646b0839 100644 --- a/core/ping.c +++ b/core/ping.c @@ -8,6 +8,9 @@ #include #include +#include "DHT.h" +#include "net_crypto.h" +#include "packets.h" #include "network.h" #include "util.h" @@ -20,9 +23,12 @@ typedef struct { uint64_t timestamp; } pinged_t; -static pinged_t pings[PING_NUM_MAX]; -static size_t num_pings; -static size_t pos_pings; +static pinged_t pings[PING_NUM_MAX]; +static size_t num_pings; +static size_t pos_pings; +static clientid_t* self_id = (clientid_t*) &self_public_key; + +extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c void init_ping() { @@ -86,10 +92,63 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n) for(i=0; i #include -#include "network.h" +#include "DHT.h" +#include "packets.h" uint64_t now() { return time(NULL); @@ -29,3 +30,11 @@ uint64_t random_64b() { bool ipp_eq(IP_Port a, IP_Port b) { return (a.ip.i == b.ip.i) && (a.port == b.port); } + +bool id_eq(clientid_t* dest, clientid_t* src) { + return memcmp(dest, src, sizeof(clientid_t)) == 0; +} + +void id_cpy(clientid_t* dest, clientid_t* src) { + memcpy(dest, src, sizeof(clientid_t)); +} diff --git a/core/util.h b/core/util.h index aab2ead9..a93be08a 100644 --- a/core/util.h +++ b/core/util.h @@ -8,3 +8,6 @@ uint64_t now(); uint64_t random_64b(); bool ipp_eq(IP_Port a, IP_Port b); +bool id_eq(clientid_t* dest, clientid_t* src); +void id_cpy(clientid_t* dest, clientid_t* src); + From e71413d8f1fab4928be0e024821d58147f6f1b0e Mon Sep 17 00:00:00 2001 From: plutooo Date: Mon, 5 Aug 2013 15:04:38 -0700 Subject: [PATCH 14/25] core: Move send ping packets functions to ping.c --- core/DHT.c | 84 +++-------------------- core/packets.h | 37 ++++++++++ core/ping.c | 178 ++++++++++++++++++++++++++++++++++--------------- core/ping.h | 3 +- core/util.c | 38 +++++++---- core/util.h | 3 + 6 files changed, 202 insertions(+), 141 deletions(-) create mode 100644 core/packets.h diff --git a/core/DHT.c b/core/DHT.c index 01abfdd2..fa36d41f 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -24,6 +24,7 @@ /*----------------------------------------------------------------------------------*/ #include "DHT.h" +#include "packets.h" #include "ping.h" /* maximum number of clients stored per friend. */ @@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port) return 0; } -/* send a ping request, only works if none has been sent to that ip/port - * in the last 5 seconds. - */ -static int pingreq(IP_Port ip_port, uint8_t * public_key) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) - return 1; - - uint64_t ping_id = add_ping(ip_port); - if(ping_id == 0) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, - nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 0; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - -/* send a ping response */ -static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) -{ - /* check if packet is gonna be sent to ourself */ - if(id_equal(public_key, self_public_key)) - return 1; - - uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; - uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); - - int len = encrypt_data( public_key, - self_secret_key, nonce, - (uint8_t *)&ping_id, - sizeof(ping_id), - encrypt ); - - if(len != sizeof(ping_id) + ENCRYPTION_PADDING) - return -1; - - data[0] = 1; - memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); - memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); - memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); - - return sendpacket(ip_port, data, sizeof(data)); -} - /* send a getnodes request */ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) { @@ -641,8 +577,8 @@ static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) if(len != sizeof(ping_id)) return 1; - pingres(source, packet + 1, ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_response(source, (clientid_t*) (packet + 1), ping_id); + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -701,7 +637,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) memcpy(&ping_id, plain, sizeof(ping_id)); sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); - pingreq(source, packet + 1); /* TODO: make this smarter? */ + send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ return 0; } @@ -741,7 +677,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) uint32_t i; for(i = 0; i < num_nodes; ++i) { - pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); + send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); } @@ -831,8 +767,8 @@ static void doDHTFriends(void) /* if node is not dead. */ if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( friends_list[i].client_list[j].ip_port, - friends_list[i].client_list[j].client_id ); + send_ping_request( friends_list[i].client_list[j].ip_port, + (clientid_t*) &friends_list[i].client_list[j].client_id ); friends_list[i].client_list[j].last_pinged = temp_time; } /* if node is good. */ @@ -869,8 +805,8 @@ static void doClose(void) /* if node is not dead. */ if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { - pingreq( close_clientlist[i].ip_port, - close_clientlist[i].client_id ); + send_ping_request( close_clientlist[i].ip_port, + (clientid_t*) &close_clientlist[i].client_id ); close_clientlist[i].last_pinged = temp_time; } /* if node is good. */ @@ -1151,7 +1087,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t /*TODO: improve port guessing algorithm*/ uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); IP_Port pinging = {ip, htons(port)}; - pingreq(pinging, friends_list[friend_num].client_id); + send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); } friends_list[friend_num].punching_index = i; } diff --git a/core/packets.h b/core/packets.h new file mode 100644 index 00000000..222b1425 --- /dev/null +++ b/core/packets.h @@ -0,0 +1,37 @@ +/* + * packet.h -- Packet structure + * + * This file is donated to the Tox Project. + * Copyright 2013 plutooo + */ + +typedef struct { + uint8_t id[CLIENT_ID_SIZE]; + +} __attribute__((packed)) clientid_t; + +typedef enum { + PACKET_PING_REQ = 0, + PACKET_PING_RES = 1 + +} packetid_t; + +// Ping packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; + +} __attribute__((packed)) pingreq_t; + +// Pong packet +typedef struct { + uint8_t magic; + clientid_t client_id; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint64_t ping_id; + uint8_t padding[ENCRYPTION_PADDING]; + +} __attribute__((packed)) pingres_t; diff --git a/core/ping.c b/core/ping.c index 8a7d534f..37f1b7ae 100644 --- a/core/ping.c +++ b/core/ping.c @@ -8,6 +8,9 @@ #include #include +#include "DHT.h" +#include "net_crypto.h" +#include "packets.h" #include "network.h" #include "util.h" @@ -20,76 +23,143 @@ typedef struct { uint64_t timestamp; } pinged_t; -static pinged_t pings[PING_NUM_MAX]; -static size_t num_pings; -static size_t pos_pings; +static pinged_t pings[PING_NUM_MAX]; +static size_t num_pings; +static size_t pos_pings; +static clientid_t* self_id = (clientid_t*) &self_public_key; + +extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c -void init_ping() { - num_pings = 0; - pos_pings = 0; +void init_ping() +{ + num_pings = 0; + pos_pings = 0; } -static bool is_timeout(uint64_t time) { - return (time + PING_TIMEOUT) < now(); +static bool is_timeout(uint64_t time) +{ + return (time + PING_TIMEOUT) < now(); } -static void remove_timeouts() { // O(n) - size_t i, id; - size_t new_pos = pos_pings; - size_t new_num = num_pings; +static void remove_timeouts() // O(n) +{ + size_t i, id; + size_t new_pos = pos_pings; + size_t new_num = num_pings; - // Loop through buffer, oldest first - for(i=0; i #include -#include "network.h" +#include "DHT.h" +#include "packets.h" -uint64_t now() { - return time(NULL); +uint64_t now() +{ + return time(NULL); } -uint64_t random_64b() { - uint64_t r; +uint64_t random_64b() +{ + uint64_t r; - // This is probably not random enough? - r = random_int(); - r <<= 32; - r |= random_int(); + // This is probably not random enough? + r = random_int(); + r <<= 32; + r |= random_int(); - return r; + return r; } -bool ipp_eq(IP_Port a, IP_Port b) { - return (a.ip.i == b.ip.i) && (a.port == b.port); +bool ipp_eq(IP_Port a, IP_Port b) +{ + return (a.ip.i == b.ip.i) && (a.port == b.port); +} + +bool id_eq(clientid_t* dest, clientid_t* src) +{ + return memcmp(dest, src, sizeof(clientid_t)) == 0; +} + +void id_cpy(clientid_t* dest, clientid_t* src) +{ + memcpy(dest, src, sizeof(clientid_t)); } diff --git a/core/util.h b/core/util.h index aab2ead9..a93be08a 100644 --- a/core/util.h +++ b/core/util.h @@ -8,3 +8,6 @@ uint64_t now(); uint64_t random_64b(); bool ipp_eq(IP_Port a, IP_Port b); +bool id_eq(clientid_t* dest, clientid_t* src); +void id_cpy(clientid_t* dest, clientid_t* src); + From 6e610749ebfc0bfe153ab88bcf76f4f9b24ff3fa Mon Sep 17 00:00:00 2001 From: plutooo Date: Tue, 6 Aug 2013 09:42:53 -0700 Subject: [PATCH 15/25] core: Move ping request/response into ping.c --- core/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ping.c b/core/ping.c index 37f1b7ae..d1cc182f 100644 --- a/core/ping.c +++ b/core/ping.c @@ -102,7 +102,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) id = (pos_pings + i) % PING_NUM_MAX; // ping_id = 0 means match any id - if(ipp_eq(pings[id].ipp, ipp) && (ping_id == 0 || pings[id].id == ping_id)) { + if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { return true; } } From 543b129ba72210c54abd7bf7a898e3f02a136e25 Mon Sep 17 00:00:00 2001 From: Konstantin Kowalski Date: Tue, 6 Aug 2013 13:52:05 -0400 Subject: [PATCH 16/25] Added a linked list implementation. --- testing/misc_tools.c | 12 ++++- testing/misc_tools.h | 111 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/testing/misc_tools.c b/testing/misc_tools.c index aa546a88..fa7f42c9 100644 --- a/testing/misc_tools.c +++ b/testing/misc_tools.c @@ -25,7 +25,11 @@ #include #include -#include /* for sscanf */ +#include + +#ifdef DEBUG +#include +#endif // DEBUG /* TODO: rewrite */ unsigned char * hex_string_to_bin(char hex_string[]) @@ -39,3 +43,9 @@ unsigned char * hex_string_to_bin(char hex_string[]) return val; } + + + + + + diff --git a/testing/misc_tools.h b/testing/misc_tools.h index 5079e15d..4e09d40d 100644 --- a/testing/misc_tools.h +++ b/testing/misc_tools.h @@ -25,5 +25,114 @@ #define MISC_TOOLS_H unsigned char * hex_string_to_bin(char hex_string[]); - + + + + + +/************************Linked List*********************** + * This is a simple linked list implementation, very similar + * to Linux kernel's /include/linux/list.h (which we can't + * use because Tox is GPLv3 and Linux is GPLv2.) + * + * TODO: Make the lists easier to use with some sweat pre- + * processor syntactic sugar. + **********************************************************/ + +/* Example usage + +This sample program makes a new struct which contains a +character and a tox_list_t. It then prompts a user for +input until he enters q or e. It then adds each character +to the list, and uses a special for loop to print them. +It then removes all the 'z' characters, and prints the list +again. + +//Notice that the data to be put in the list *contains* tox_list_t; +//usually, this is the other way around! +typedef struct tox_string { + char c; + tox_list_t tox_lst; //Notice that tox_lst is *NOT* a pointer. +} tox_string_t; + +int main() +{ + tox_list_t head; + tox_list_new(&head); //initialize head + + //input a new character, until user enters q or e + char c = '\0'; + while (c != 'q' && c != 'e') { + scanf("%c", &c); + tox_string_t* tmp = malloc(sizeof(tox_string_t)); + tmp->c = c; + tox_list_add(&head, &tmp->tox_lst); //add it to the list + } + +TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop. + +TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t. +You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst), +and the type of structure to return. + + TOX_LIST_FOR_EACH(head, tmp) + printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); + + TOX_LIST_FOR_EACH(head, tmp) { + if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') { + //If you delete tmp, you have to quit the loop, or it will go on infinitly. + //This will be fixed later on. + tox_list_remove(tmp); + break; + } + } + + printf("\n"); + TOX_LIST_FOR_EACH(head, tmp) + printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); + + + return 0; +} +*/ + +#define MEMBER_OFFSET(var_name_in_parent, parent_type) \ + (&(((parent_type*)0)->var_name_in_parent)) + +#define GET_PARENT(var, var_name_in_parent, parent_type) \ + (*((parent_type*)((uint64_t)(&(var)) - (uint64_t)(MEMBER_OFFSET(var_name_in_parent, parent_type))))) + +#define TOX_LIST_FOR_EACH(lst, tmp_name) \ + for (tox_list_t* tmp_name = lst.next; tmp_name != &lst; tmp_name = tmp_name->next) + +#define TOX_LIST_GET_VALUE(tmp_name, name_in_parent, parent_type) GET_PARENT(tmp_name, name_in_parent, parent_type) + +typedef struct tox_list { + struct tox_list *prev, *next; +} tox_list_t; + +/* Returns a new tox_list_t. */ +static inline void tox_list_new(tox_list_t* lst) { + lst->prev = lst->next = lst; +} + +/* Inserts a new tox_lst after lst and returns it. */ +static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) { + tox_list_new(new_lst); + + new_lst->next = lst->next; + new_lst->next->prev = new_lst; + + lst->next = new_lst; + new_lst->prev = lst; +} + +static inline void tox_list_remove(tox_list_t* lst) { +#ifdef DEBUG /* TODO: check how debugging is done in Tox. */ + assert(lst->next != lst && lst->prev != lst); +#endif + lst->prev->next = lst->next; + lst->next->prev = lst->prev; +} + #endif // MISC_TOOLS_H From 9e0ee5b7df3417b1ca6ae446aa3724106e447ed4 Mon Sep 17 00:00:00 2001 From: plutooo Date: Tue, 6 Aug 2013 13:09:14 -0700 Subject: [PATCH 17/25] core: Moved handle ping packets to ping.c --- core/DHT.c | 62 +++-------------------------------------------------- core/DHT.h | 2 ++ core/ping.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ core/ping.h | 2 ++ 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/core/DHT.c b/core/DHT.c index fa36d41f..2db46962 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -352,7 +352,7 @@ static int replace_good( Client_data * list, /* Attempt to add client with ip_port and client_id to the friends client list * and close_clientlist */ -static void addto_lists(IP_Port ip_port, uint8_t * client_id) +void addto_lists(IP_Port ip_port, uint8_t * client_id) { uint32_t i; @@ -554,62 +554,6 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); } -/* Packet handling functions, one to handle each types of packets we receive - * Returns 0 if handled correctly, 1 if packet is bad. - */ -static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) -{ - uint64_t ping_id; - if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) - return 1; - - /* check if packet is from ourself. */ - if(id_equal(packet + 1, self_public_key)) - return 1; - - int len = decrypt_data( packet + 1, - self_secret_key, - packet + 1 + CLIENT_ID_SIZE, - packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, - sizeof(ping_id) + ENCRYPTION_PADDING, - (uint8_t *)&ping_id ); - - if(len != sizeof(ping_id)) - return 1; - - send_ping_response(source, (clientid_t*) (packet + 1), ping_id); - send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ - - return 0; -} - -static int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) -{ - uint64_t ping_id; - if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) - return 1; - - /* check if packet is from ourself. */ - if(id_equal(packet + 1, self_public_key)) - return 1; - - int len = decrypt_data( packet + 1, - self_secret_key, - packet + 1 + CLIENT_ID_SIZE, - packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, - sizeof(ping_id) + ENCRYPTION_PADDING, - (uint8_t *)&ping_id ); - - if(len != sizeof(ping_id)) - return 1; - - if(is_pinging(source, ping_id)) { - addto_lists(source, packet + 1); - return 0; - } - return 1; -} - static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) { uint64_t ping_id; @@ -1134,10 +1078,10 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) { switch (packet[0]) { case 0: - return handle_pingreq(packet, length, source); + return handle_ping_request(packet, length, source); case 1: - return handle_pingres(packet, length, source); + return handle_ping_response(packet, length, source); case 2: return handle_getnodes(packet, length, source); diff --git a/core/DHT.h b/core/DHT.h index 0edaebf3..2308abd8 100644 --- a/core/DHT.h +++ b/core/DHT.h @@ -104,6 +104,8 @@ int DHT_load(uint8_t *data, uint32_t size); returns 1 if we are */ int DHT_isconnected(); +void addto_lists(IP_Port ip_port, uint8_t * client_id); + #ifdef __cplusplus } #endif diff --git a/core/ping.c b/core/ping.c index d1cc182f..3f70b26d 100644 --- a/core/ping.c +++ b/core/ping.c @@ -163,3 +163,59 @@ int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); } + +int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source) +{ + pingreq_t* p = (pingreq_t*) packet; + int rc; + uint64_t ping_id; + + if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id)) + return 1; + + // Decrypt ping_id + rc = decrypt_data((uint8_t*) &p->client_id, + self_secret_key, + (uint8_t*) &p->nonce, + (uint8_t*) &p->ping_id, + sizeof(ping_id) + ENCRYPTION_PADDING, + (uint8_t*) &ping_id); + + if (rc != sizeof(ping_id)) + return 1; + + // Send response + send_ping_response(source, &p->client_id, ping_id); + send_ping_request(source, &p->client_id); // Make this smarter? + + return 0; +} + +int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source) +{ + pingres_t* p = (pingres_t*) packet; + int rc; + uint64_t ping_id; + + if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id)) + return 1; + + // Decrypt ping_id + rc = decrypt_data((uint8_t*) &p->client_id, + self_secret_key, + (uint8_t*) &p->nonce, + (uint8_t*) &p->ping_id, + sizeof(ping_id) + ENCRYPTION_PADDING, + (uint8_t*) &ping_id); + + if (rc != sizeof(ping_id)) + return 1; + + // Make sure ping_id is correct + if(!is_pinging(source, ping_id)) + return 1; + + // Associate source ip with client_id + addto_lists(source, (uint8_t*) &p->client_id); + return 0; +} diff --git a/core/ping.h b/core/ping.h index f2770a00..2cab7d59 100644 --- a/core/ping.h +++ b/core/ping.h @@ -12,3 +12,5 @@ uint64_t add_ping(IP_Port ipp); bool is_pinging(IP_Port ipp, uint64_t ping_id); int send_ping_request(IP_Port ipp, clientid_t* client_id); int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); +int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source); +int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source); From 3dfaa464ac008ac1f3f0e87be55d2918e6f6b667 Mon Sep 17 00:00:00 2001 From: Konstantin Kowalski Date: Tue, 6 Aug 2013 16:47:15 -0400 Subject: [PATCH 18/25] Added ERROR() and WARNING() for debugging. --- testing/misc_tools.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/testing/misc_tools.h b/testing/misc_tools.h index 4e09d40d..eb09693e 100644 --- a/testing/misc_tools.h +++ b/testing/misc_tools.h @@ -26,9 +26,40 @@ unsigned char * hex_string_to_bin(char hex_string[]); +/* WARNING(msg) takes a printf()-styled string and prints it + * with some additional details. + * ERROR(exit_status, msg) does the same thing as WARNING(), but + * also exits the program with the given exit status. + * Examples: + * WARNING(""); + * int exit_status = 2; + * ERROR(exit_status, "exiting with status %i", exit_status); + */ +#ifdef DEBUG + #include + #include + #include + #define DEBUG_PRINT(str, ...) do { \ + char msg[1000]; \ + sprintf(msg, "%s(): line %d (file %s): %s%%c\n", __FUNCTION__, __LINE__, __FILE__, str); \ + fprintf(stderr, msg, __VA_ARGS__); \ + } while (0) + #define WARNING(...) do { \ + fprintf(stderr, "warning in "); \ + DEBUG_PRINT(__VA_ARGS__, ' '); \ + } while (0) + #define ERROR(exit_status, ...) do { \ + fprintf(stderr, "error in "); \ + DEBUG_PRINT(__VA_ARGS__, ' '); \ + exit(exit_status); \ + } while (0) +#else + #define WARNING(...) + #define ERROR(...) +#endif // DEBUG /************************Linked List*********************** * This is a simple linked list implementation, very similar From 29773d97fc78b703c96d73b883b83b75fa17198f Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 6 Aug 2013 17:25:32 -0400 Subject: [PATCH 19/25] Small bug fixed. --- core/Messenger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/Messenger.c b/core/Messenger.c index d8bf3413..9fa643bb 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -352,7 +352,7 @@ static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) memcpy(thepacket + 2, status, length); thepacket[0] = PACKET_ID_USERSTATUS; thepacket[1] = self_userstatus_kind; - int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1); + int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 2); free(thepacket); return written; } From 16b3ec746e9ab518a1efa221524391f8f692f75b Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Tue, 6 Aug 2013 18:27:51 -0400 Subject: [PATCH 20/25] code format/clean up --- testing/toxic/chat.c | 110 +++++++------- testing/toxic/friendlist.c | 104 +++++++------- testing/toxic/main.c | 217 ++++++++++++++-------------- testing/toxic/prompt.c | 288 +++++++++++++++++-------------------- 4 files changed, 337 insertions(+), 382 deletions(-) diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 7262e722..20c01620 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c @@ -16,38 +16,34 @@ typedef struct { int friendnum; - char line[256]; size_t pos; - WINDOW* history; WINDOW* linewin; - } ChatContext; -extern int w_active; -extern void del_window(ToxWindow *w, int f_num); -extern void fix_name(uint8_t* name); -void print_help(ChatContext* self); -void execute(ToxWindow* self, ChatContext* ctx, char* cmd); +extern int active_window; -static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) { - ChatContext* ctx = (ChatContext*) self->x; +extern void del_window(ToxWindow *w, int f_num); +extern void fix_name(uint8_t *name); +void print_help(ChatContext *self); +void execute(ToxWindow *self, ChatContext *ctx, char *cmd); + +static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len) +{ + ChatContext *ctx = (ChatContext*) self->x; uint8_t nick[MAX_NAME_LENGTH] = {0}; - time_t now; time(&now); struct tm * timeinfo; timeinfo = localtime(&now); - if(ctx->friendnum != num) + if (ctx->friendnum != num) return; getname(num, (uint8_t*) &nick); - msg[len-1] = '\0'; nick[MAX_NAME_LENGTH-1] = '\0'; - fix_name(msg); fix_name(nick); @@ -64,15 +60,14 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) flash(); } -static void chat_onNickChange(ToxWindow* self, int num, uint8_t* nick, uint16_t len) { - ChatContext* ctx = (ChatContext*) self->x; - - if(ctx->friendnum != num) +static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len) +{ + ChatContext *ctx = (ChatContext*) self->x; + if (ctx->friendnum != num) return; nick[len-1] = '\0'; fix_name(nick); - snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num); wattron(ctx->history, COLOR_PAIR(3)); @@ -80,7 +75,8 @@ static void chat_onNickChange(ToxWindow* self, int num, uint8_t* nick, uint16_t wattroff(ctx->history, COLOR_PAIR(3)); } -static void chat_onStatusChange(ToxWindow* self, int num, uint8_t* status, uint16_t len) { +static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint16_t len) +{ } @@ -89,35 +85,33 @@ int string_is_empty(char *string) { int rc = 0; char *copy = strdup(string); - rc = ((strtok(copy, " ") == NULL) ? 1:0); free(copy); - return rc; } -static void chat_onKey(ToxWindow* self, int key) { - ChatContext* ctx = (ChatContext*) self->x; - +static void chat_onKey(ToxWindow *self, int key) +{ + ChatContext *ctx = (ChatContext*) self->x; time_t now; time(&now); struct tm * timeinfo; timeinfo = localtime(&now); - /* PRINTABLE characters: Add to line */ - if(isprint(key)) { - if(ctx->pos != sizeof(ctx->line)-1) { + /* Add printable characters to line */ + if (isprint(key)) { + if (ctx->pos != sizeof(ctx->line)-1) { ctx->line[ctx->pos++] = key; ctx->line[ctx->pos] = '\0'; } } /* RETURN key: Execute command or print line */ - else if(key == '\n') { + else if (key == '\n') { if (ctx->line[0] == '/') execute(self, ctx, ctx->line); else { - if(!string_is_empty(ctx->line)) { + if (!string_is_empty(ctx->line)) { /* make sure the string has at least non-space character */ wattron(ctx->history, COLOR_PAIR(2)); wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); @@ -127,7 +121,7 @@ static void chat_onKey(ToxWindow* self, int key) { wattroff(ctx->history, COLOR_PAIR(1)); wprintw(ctx->history, "%s\n", ctx->line); } - if(m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) { + if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) { wattron(ctx->history, COLOR_PAIR(3)); wprintw(ctx->history, " * Failed to send message.\n"); wattroff(ctx->history, COLOR_PAIR(3)); @@ -138,29 +132,32 @@ static void chat_onKey(ToxWindow* self, int key) { } /* BACKSPACE key: Remove one character from line */ - else if(key == 0x107 || key == 0x8 || key == 0x7f) { - if(ctx->pos != 0) { + else if (key == 0x107 || key == 0x8 || key == 0x7f) { + if (ctx->pos != 0) { ctx->line[--ctx->pos] = '\0'; } } } -void execute(ToxWindow* self, ChatContext* ctx, char* cmd) +void execute(ToxWindow *self, ChatContext *ctx, char *cmd) { if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) { wclear(self->window); wclear(ctx->history); } + else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h")) print_help(ctx); + else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) { endwin(); exit(0); } + else if (!strncmp(cmd, "/status ", strlen("/status "))) { - char* msg; + char *msg; msg = strchr(cmd, ' '); - if(msg == NULL) { + if (msg == NULL) { wprintw(ctx->history, "Invalid syntax.\n"); return; } @@ -168,10 +165,11 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) m_set_userstatus(USERSTATUS_KIND_RETAIN, (uint8_t*) msg, strlen(msg)+1); wprintw(ctx->history, "Status set to: %s\n", msg); } + else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { - char* nick; + char *nick; nick = strchr(cmd, ' '); - if(nick == NULL) { + if (nick == NULL) { wprintw(ctx->history, "Invalid syntax.\n"); return; } @@ -179,7 +177,8 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) setname((uint8_t*) nick, strlen(nick)+1); wprintw(ctx->history, "Nickname set to: %s\n", nick); } - else if(!strcmp(cmd, "/myid")) { + + else if (!strcmp(cmd, "/myid")) { char id[32*2 + 1] = {0}; int i; for (i = 0; i < 32; i++) { @@ -189,48 +188,46 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) } wprintw(ctx->history, "Your ID: %s\n", id); } + else if (strcmp(ctx->line, "/close") == 0) { - w_active = 0; // Go to prompt screen + active_window = 0; // Go to prompt screen int f_num = ctx->friendnum; delwin(ctx->linewin); del_window(self, f_num); } + else wprintw(ctx->history, "Invalid command.\n"); } -static void chat_onDraw(ToxWindow* self) { +static void chat_onDraw(ToxWindow *self) +{ curs_set(1); int x, y; - ChatContext* ctx = (ChatContext*) self->x; - + ChatContext *ctx = (ChatContext*) self->x; getmaxyx(self->window, y, x); - (void) x; - if(y < 3) - return; + if (y < 3) return; wclear(ctx->linewin); mvwhline(ctx->linewin, 0, 0, '_', COLS); mvwprintw(self->window, y-1, 0, "%s\n", ctx->line); - wrefresh(self->window); } -static void chat_onInit(ToxWindow* self) { +static void chat_onInit(ToxWindow *self) +{ int x, y; - ChatContext* ctx = (ChatContext*) self->x; - + ChatContext *ctx = (ChatContext*) self->x; getmaxyx(self->window, y, x); - ctx->history = subwin(self->window, y - 4, x, 0, 0); scrollok(ctx->history, 1); - ctx->linewin = subwin(self->window, 2, x, y - 3, 0); print_help(ctx); } -void print_help(ChatContext* self) { +void print_help(ChatContext *self) +{ wattron(self->history, COLOR_PAIR(2) | A_BOLD); wprintw(self->history, "Commands:\n"); wattroff(self->history, A_BOLD); @@ -246,9 +243,9 @@ void print_help(ChatContext* self) { wattroff(self->history, COLOR_PAIR(2)); } -ToxWindow new_chat(int friendnum) { +ToxWindow new_chat(int friendnum) +{ ToxWindow ret; - memset(&ret, 0, sizeof(ret)); ret.onKey = &chat_onKey; @@ -264,9 +261,8 @@ ToxWindow new_chat(int friendnum) { snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); - ChatContext* x = calloc(1, sizeof(ChatContext)); + ChatContext *x = calloc(1, sizeof(ChatContext)); x->friendnum = friendnum; - ret.x = (void*) x; return ret; } diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index 94e8fb47..f03914e6 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c @@ -15,60 +15,56 @@ extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM]; extern int add_window(ToxWindow w, int n); extern ToxWindow new_chat(int friendnum); -extern int w_active; + +extern int active_window; typedef struct { uint8_t name[MAX_NAME_LENGTH]; uint8_t status[MAX_USERSTATUS_LENGTH]; - int num; - int chatwin; + int num; + int chatwin; } friend_t; static friend_t friends[MAX_FRIENDS_NUM]; static int num_friends = 0; static int num_selected = 0; - -void fix_name(uint8_t* name) { - - // Remove all non alphanumeric characters. - uint8_t* p = name; - uint8_t* q = name; - +void fix_name(uint8_t *name) +{ + /* Remove all non alphanumeric characters */ + uint8_t *p = name; + uint8_t *q = name; while(*p != 0) { - if(isprint(*p)) { + if (isprint(*p)) *q++ = *p; - } - p++; } - *q = 0; } -void friendlist_onMessage(ToxWindow* self, int num, uint8_t* str, uint16_t len) { - - if(num >= num_friends) +void friendlist_onMessage(ToxWindow *self, int num, uint8_t *str, uint16_t len) +{ + if (num >= num_friends) return; - if(friends[num].chatwin == -1) { + if (friends[num].chatwin == -1) { friends[num].chatwin = num; int i; /* Find first open slot to hold chat window */ - for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { if (WINDOW_STATUS[i] == -1) { WINDOW_STATUS[i] = num; add_window(new_chat(num), i); - w_active = i; + active_window = i; break; } } } } -void friendlist_onNickChange(ToxWindow* self, int num, uint8_t* str, uint16_t len) { - - if(len >= MAX_NAME_LENGTH || num >= num_friends) +void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t len) +{ + if (len >= MAX_NAME_LENGTH || num >= num_friends) return; memcpy((char*) &friends[num].name, (char*) str, len); @@ -76,9 +72,9 @@ void friendlist_onNickChange(ToxWindow* self, int num, uint8_t* str, uint16_t le fix_name(friends[num].name); } -void friendlist_onStatusChange(ToxWindow* self, int num, uint8_t* str, uint16_t len) { - - if(len >= MAX_USERSTATUS_LENGTH || num >= num_friends) +void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len) +{ + if (len >= MAX_USERSTATUS_LENGTH || num >= num_friends) return; memcpy((char*) &friends[num].status, (char*) str, len); @@ -86,9 +82,9 @@ void friendlist_onStatusChange(ToxWindow* self, int num, uint8_t* str, uint16_t fix_name(friends[num].status); } -int friendlist_onFriendAdded(int num) { - - if(num_friends == MAX_FRIENDS_NUM) +int friendlist_onFriendAdded(int num) +{ + if (num_friends == MAX_FRIENDS_NUM) return -1; friends[num_friends].num = num; @@ -99,34 +95,34 @@ int friendlist_onFriendAdded(int num) { return 0; } -static void friendlist_onKey(ToxWindow* self, int key) { - if(key == KEY_UP) { - num_selected--; - if (num_selected < 0) +static void friendlist_onKey(ToxWindow *self, int key) +{ + if (key == KEY_UP) { + if (--num_selected < 0) num_selected = num_friends-1; } - else if(key == KEY_DOWN) { - if(num_friends != 0) + else if (key == KEY_DOWN) { + if (num_friends != 0) num_selected = (num_selected+1) % num_friends; } - else if(key == '\n') { + else if (key == '\n') { /* Jump to chat window if already open */ if (friends[num_selected].chatwin != -1) { int i; - for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { if (WINDOW_STATUS[i] == num_selected) { - w_active = i; + active_window = i; break; } } }else { int i; - for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { if (WINDOW_STATUS[i] == -1) { WINDOW_STATUS[i] = num_selected; friends[num_selected].chatwin = num_selected; add_window(new_chat(num_selected), i); - w_active = i; + active_window = i; break; } } @@ -134,13 +130,11 @@ static void friendlist_onKey(ToxWindow* self, int key) { } } -static void friendlist_onDraw(ToxWindow* self) { +static void friendlist_onDraw(ToxWindow *self) +{ curs_set(0); - size_t i; - werase(self->window); - - if(num_friends == 0) { + if (num_friends == 0) { wprintw(self->window, "Empty. Add some friends! :-)\n"); } else { @@ -150,12 +144,11 @@ static void friendlist_onDraw(ToxWindow* self) { } wprintw(self->window, "\n"); - - for(i=0; iwindow, COLOR_PAIR(3)); + int i; + for (i = 0; i < num_friends; ++i) { + if (i == num_selected) wattron(self->window, COLOR_PAIR(3)); wprintw(self->window, " [#%d] ", friends[i].num); - if(i == num_selected) wattroff(self->window, COLOR_PAIR(3)); + if (i == num_selected) wattroff(self->window, COLOR_PAIR(3)); attron(A_BOLD); wprintw(self->window, "%s ", friends[i].name); @@ -163,22 +156,21 @@ static void friendlist_onDraw(ToxWindow* self) { wprintw(self->window, "(%s)\n", friends[i].status); } - wrefresh(self->window); } -void disable_chatwin(int f_num) { +void disable_chatwin(int f_num) +{ friends[f_num].chatwin = -1; } -static void friendlist_onInit(ToxWindow* self) { +static void friendlist_onInit(ToxWindow *self) +{ } - ToxWindow new_friendlist() { ToxWindow ret; - memset(&ret, 0, sizeof(ret)); ret.onKey = &friendlist_onKey; @@ -187,7 +179,7 @@ ToxWindow new_friendlist() { ret.onMessage = &friendlist_onMessage; ret.onNickChange = &friendlist_onNickChange; ret.onStatusChange = &friendlist_onStatusChange; - strcpy(ret.title, "[friends]"); + strcpy(ret.title, "[friends]"); return ret; } diff --git a/testing/toxic/main.c b/testing/toxic/main.c index 19a0b959..1ba8b6c9 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -18,106 +18,108 @@ extern ToxWindow new_friendlist(); extern int friendlist_onFriendAdded(int num); extern void disable_chatwin(int f_num); -extern int add_req(uint8_t* public_key); // XXX +extern int add_req(uint8_t *public_key); // XXX + +/* Holds status of chat windows */ +char WINDOW_STATUS[MAX_WINDOW_SLOTS]; -char WINDOW_STATUS[MAX_WINDOW_SLOTS]; // Holds status of chat windows static ToxWindow windows[MAX_WINDOW_SLOTS]; -int w_num; -int w_active; static ToxWindow* prompt; -// CALLBACKS START -void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) { - size_t i; - int n = add_req(public_key); +int w_num; +int active_window; +/* CALLBACKS START */ +void on_request(uint8_t *public_key, uint8_t *data, uint16_t length) +{ + int n = add_req(public_key); wprintw(prompt->window, "\nFriend request from:\n"); - for(i=0; i<32; i++) { + int i; + for (i = 0; i < 32; ++i) { wprintw(prompt->window, "%02x", public_key[i] & 0xff); } + wprintw(prompt->window, "\n"); - wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n); - - for(i=0; iwindow, "\n(message) %d: %s\n", friendnumber, string); - - for(i=0; iwindow, "\n(nickchange) %d: %s!\n", friendnumber, string); - - for(i=0; iwindow, "\n(statuschange) %d: %s\n", friendnumber, string); - - for(i=0; i= TOXWINDOWS_MAX_NUM) +int add_window(ToxWindow w, int n) +{ + if (w_num >= TOXWINDOWS_MAX_NUM) return -1; - if(LINES < 2) + if (LINES < 2) return -1; w.window = newwin(LINES - 2, COLS, 0, 0); - if(w.window == NULL) + if (w.window == NULL) return -1; windows[n] = w; @@ -143,10 +146,11 @@ int add_window(ToxWindow w, int n) { } /* Deletes window w and cleans up */ -void del_window(ToxWindow *w, int f_num) { +void del_window(ToxWindow *w, int f_num) +{ delwin(w->window); int i; - for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { + for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { if (WINDOW_STATUS[i] == f_num) { WINDOW_STATUS[i] = -1; disable_chatwin(f_num); @@ -157,11 +161,12 @@ void del_window(ToxWindow *w, int f_num) { refresh(); } -static void init_windows() { +static void init_windows() +{ w_num = 0; int n_prompt = 0; int n_friendslist = 1; - if(add_window(new_prompt(), n_prompt) == -1 + if (add_window(new_prompt(), n_prompt) == -1 || add_window(new_friendlist(), n_friendslist) == -1) { fprintf(stderr, "add_window() failed.\n"); endwin(); @@ -170,88 +175,79 @@ static void init_windows() { prompt = &windows[n_prompt]; } -static void do_tox() { +static void do_tox() +{ static bool dht_on = false; - - if(!dht_on && DHT_isconnected()) { + if (!dht_on && DHT_isconnected()) { dht_on = true; wprintw(prompt->window, "\nDHT connected!\n"); } - else if(dht_on && !DHT_isconnected()) { + else if (dht_on && !DHT_isconnected()) { dht_on = false; wprintw(prompt->window, "\nDHT disconnected!\n"); } - doMessenger(); } -static void load_data(char *path) { - FILE* fd; +static void load_data(char *path) +{ + FILE *fd; size_t len; - uint8_t* buf; + uint8_t *buf; - if((fd = fopen(path, "r")) != NULL) { + if ((fd = fopen(path, "r")) != NULL) { fseek(fd, 0, SEEK_END); len = ftell(fd); fseek(fd, 0, SEEK_SET); buf = malloc(len); - - if(buf == NULL) { + if (buf == NULL) { fprintf(stderr, "malloc() failed.\n"); - fclose(fd); endwin(); exit(1); } - - if(fread(buf, len, 1, fd) != 1){ + if (fread(buf, len, 1, fd) != 1){ fprintf(stderr, "fread() failed.\n"); - free(buf); fclose(fd); endwin(); exit(1); } - Messenger_load(buf, len); } else { len = Messenger_size(); buf = malloc(len); - - if(buf == NULL) { + if (buf == NULL) { fprintf(stderr, "malloc() failed.\n"); endwin(); exit(1); } - Messenger_save(buf); fd = fopen(path, "w"); - if(fd == NULL) { + if (fd == NULL) { fprintf(stderr, "fopen() failed.\n"); - free(buf); endwin(); exit(1); } - if(fwrite(buf, len, 1, fd) != 1){ + if (fwrite(buf, len, 1, fd) != 1){ fprintf(stderr, "fwrite() failed.\n"); - free(buf); fclose(fd); endwin(); exit(1); } } - free(buf); fclose(fd); } -static void draw_bar() { +static void draw_bar() +{ static int odd = 0; attron(COLOR_PAIR(4)); @@ -265,21 +261,21 @@ static void draw_bar() { attroff(COLOR_PAIR(4) | A_BOLD); int i; - for (i = 0; i < (MAX_WINDOW_SLOTS-1); i++) { + for (i = 0; i < (MAX_WINDOW_SLOTS); ++i) { if (WINDOW_STATUS[i] != -1) { - if (i == w_active) + if (i == active_window) attron(A_BOLD); odd = (odd+1) % 10; - if(windows[i].blink && (odd < 5)) { + if (windows[i].blink && (odd < 5)) { attron(COLOR_PAIR(3)); } printw(" %s", windows[i].title); - if(windows[i].blink && (odd < 5)) { + if (windows[i].blink && (odd < 5)) { attron(COLOR_PAIR(3)); } - if(i == w_active) { + if (i == active_window) { attroff(A_BOLD); } } @@ -287,35 +283,37 @@ static void draw_bar() { refresh(); } -void prepare_window(WINDOW* w) { +void prepare_window(WINDOW *w) +{ mvwin(w, 0, 0); wresize(w, LINES-2, COLS); } /* Shows next window when tab or back-tab is pressed */ -void set_active_window(int ch) { +void set_active_window(int ch) +{ int f_inf = 0; int max = MAX_WINDOW_SLOTS-1; if (ch == '\t') { - int i = (w_active + 1) % max; + int i = (active_window + 1) % max; while (true) { if (WINDOW_STATUS[i] != -1) { - w_active = i; + active_window = i; return; } i = (i + 1) % max; - if (f_inf++ > max) { // infinite loop check + if (f_inf++ > max) { // infinite loop check endwin(); clear(); exit(2); } } }else { - int i = w_active - 1; + int i = active_window - 1; if (i < 0) i = max; while (true) { if (WINDOW_STATUS[i] != -1) { - w_active = i; + active_window = i; return; } if (--i < 0) i = max; @@ -328,26 +326,26 @@ void set_active_window(int ch) { } } -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) +{ int ch; - int i = 0; int f_flag = 0; char *filename = "data"; ToxWindow* a; - for(i = 0; i < argc; i++) { - if (argv[i] == NULL){ - break; - } else if(argv[i][0] == '-') { - if(argv[i][1] == 'f') { - if(argv[i + 1] != NULL) - filename = argv[i + 1]; - else { - f_flag = -1; - } - } - } + int i = 0; + for (i = 0; i < argc; ++i) { + if (argv[i] == NULL) + break; + else if (argv[i][0] == '-') { + if (argv[i][1] == 'f') { + if (argv[i + 1] != NULL) + filename = argv[i + 1]; + else + f_flag = -1; + } } + } init_term(); init_tox(); @@ -355,7 +353,7 @@ int main(int argc, char* argv[]) { init_windows(); init_window_status(); - if(f_flag == -1) { + if (f_flag == -1) { attron(COLOR_PAIR(3) | A_BOLD); wprintw(prompt->window, "You passed '-f' without giving an argument!\n" "defaulting to 'data' for a keyfile...\n"); @@ -363,24 +361,21 @@ int main(int argc, char* argv[]) { } while(true) { - // Update tox. + /* Update tox */ do_tox(); - // Draw. - a = &windows[w_active]; + /* Draw */ + a = &windows[active_window]; prepare_window(a->window); a->blink = false; draw_bar(); a->onDraw(a); - // Handle input. + /* Handle input */ ch = getch(); - if(ch == '\t' || ch == KEY_BTAB) + if (ch == '\t' || ch == KEY_BTAB) set_active_window(ch); - else if(ch != ERR) { - a->onKey(a, ch); - } - else if(ch != ERR) { + else if (ch != ERR) { a->onKey(a, ch); } } diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 20f6b480..89c87d8f 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c @@ -16,83 +16,78 @@ uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX uint8_t num_requests=0; // XXX extern void on_friendadded(int friendnumber); -static void print_usage(ToxWindow* self); +static void print_usage(ToxWindow *self); +static char prompt_buf[256] = {0}; +static int prompt_buf_pos = 0; // XXX: -int add_req(uint8_t* public_key) { +int add_req(uint8_t *public_key) +{ memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); ++num_requests; - return num_requests-1; } // XXX: FIX -unsigned char * hex_string_to_bin(char hex_string[]) +unsigned char *hex_string_to_bin(char hex_string[]) { - size_t len = strlen(hex_string); - unsigned char *val = malloc(len); - char *pos = hex_string; - int i; - for(i = 0; i < len; ++i, pos+=2) - sscanf(pos,"%2hhx",&val[i]); - return val; + size_t len = strlen(hex_string); + unsigned char *val = malloc(len); + char *pos = hex_string; + int i; + for (i = 0; i < len; ++i, pos+=2) + sscanf(pos,"%2hhx",&val[i]); + return val; } -static char prompt_buf[256] = {0}; -static int prompt_buf_pos=0; - -static void execute(ToxWindow* self, char* u_cmd) { - int i; - int newlines = 0; - char cmd[256] = {0}; - for(i = 0; i < strlen(prompt_buf); i++) - { +static void execute(ToxWindow *self, char *u_cmd) +{ + int newlines = 0; + char cmd[256] = {0}; + int i; + for (i = 0; i < strlen(prompt_buf); ++i) { if (u_cmd[i] == '\n') - ++newlines; - else - cmd[i - newlines] = u_cmd[i]; - } + ++newlines; + else + cmd[i - newlines] = u_cmd[i]; + } - if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { + if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { endwin(); exit(0); } - else if(!strncmp(cmd, "connect ", strlen("connect "))) { - char* ip; - char* port; - char* key; - IP_Port dht; - ip = strchr(cmd, ' '); - if(ip == NULL) { + else if (!strncmp(cmd, "connect ", strlen("connect "))) { + IP_Port dht; + char *ip = strchr(cmd, ' '); + if (ip == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } ip++; - port = strchr(ip, ' '); - if(port == NULL) { + char *port = strchr(ip, ' '); + if (port == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } port[0] = 0; port++; - key = strchr(port, ' '); - if(key == NULL) { + char *key = strchr(port, ' '); + if (key == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } key[0] = 0; key++; - if(atoi(port) == 0) { + if (atoi(port) == 0) { wprintw(self->window, "Invalid syntax.\n"); return; } dht.port = htons(atoi(port)); - uint32_t resolved_address = resolve_addr(ip); if (resolved_address == 0) { return; @@ -103,49 +98,39 @@ static void execute(ToxWindow* self, char* u_cmd) { DHT_bootstrap(dht, binary_string); free(binary_string); } - else if(!strncmp(cmd, "add ", strlen("add "))) { + + 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) { + char *id = strchr(cmd, ' '); + if (id == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } id++; - - msg = strchr(id, ' '); - if(msg != NULL) { + char *msg = strchr(id, ' '); + if (msg != NULL) { msg[0] = 0; msg++; } else msg = ""; - - if(strlen(id) != 2*32) { + if (strlen(id) != 2*32) { wprintw(self->window, "Invalid ID length.\n"); return; } - - for(i=0; i<32; i++) { + int i; + 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) { + 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); + int num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); switch (num) { case -1: wprintw(self->window, "Message is too long.\n"); @@ -168,178 +153,167 @@ static void execute(ToxWindow* self, char* u_cmd) { break; } } - else if(!strcmp(cmd, "clear")) { - wclear(self->window); - } - else if(!strcmp(cmd, "help")) { - wclear(self->window); - print_usage(self); - } - else if(!strncmp(cmd, "status ", strlen("status "))) { - char* msg; - msg = strchr(cmd, ' '); - if(msg == NULL) { + else if (!strcmp(cmd, "clear")) { + wclear(self->window); + } + + else if (!strcmp(cmd, "help")) { + wclear(self->window); + print_usage(self); + } + + else if (!strncmp(cmd, "status ", strlen("status "))) { + char *msg = strchr(cmd, ' '); + if (msg == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } msg++; - m_set_userstatus(USERSTATUS_KIND_RETAIN, (uint8_t*) msg, strlen(msg)+1); wprintw(self->window, "Status set to: %s\n", msg); } - else if(!strncmp(cmd, "nick ", strlen("nick "))) { - char* nick; - nick = strchr(cmd, ' '); - if(nick == NULL) { + else if (!strncmp(cmd, "nick ", strlen("nick "))) { + char *nick = strchr(cmd, ' '); + if (nick == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } nick++; - setname((uint8_t*) nick, strlen(nick)+1); wprintw(self->window, "Nickname set to: %s\n", nick); } - else if(!strcmp(cmd, "myid")) { + + else if (!strcmp(cmd, "myid")) { char id[32*2 + 1] = {0}; size_t i; - - for(i=0; i<32; i++) { + for (i = 0; i < 32; ++i) { char xx[3]; snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); strcat(id, xx); } - wprintw(self->window, "Your ID: %s\n", id); } - else if(!strncmp(cmd, "accept ", strlen("accept "))) { - char* id; - int num; - id = strchr(cmd, ' '); - if(id == NULL) { + else if (!strncmp(cmd, "accept ", strlen("accept "))) { + char *id = strchr(cmd, ' '); + if (id == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } id++; - num = atoi(id); - if(num >= num_requests) { + int num = atoi(id); + if (num >= num_requests) { wprintw(self->window, "Invalid syntax.\n"); return; } num = m_addfriend_norequest(pending_requests[num]); - - if(num == -1) { + 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; - char* msg; - id = strchr(cmd, ' '); - - if(id == NULL) { + else if (!strncmp(cmd, "msg ", strlen("msg "))) { + char *id = strchr(cmd, ' '); + if (id == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } - id++; - - msg = strchr(id, ' '); - if(msg == NULL) { + char *msg = strchr(++id, ' '); + if (msg == NULL) { wprintw(self->window, "Invalid syntax.\n"); return; } msg[0] = 0; msg++; - - if(m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0) { + if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0) wprintw(self->window, "Error occurred while sending message.\n"); - } - else { + else wprintw(self->window, "Message successfully sent.\n"); - } } - else { + else wprintw(self->window, "Invalid command.\n"); - } } -static void prompt_onKey(ToxWindow* self, int key) { - // PRINTABLE characters: Add to line. - if(isprint(key)) { - if (prompt_buf_pos == (sizeof(prompt_buf) - 1)){ - wprintw(self->window, "\nToo Long.\n"); - prompt_buf_pos = 0; - prompt_buf[0] = 0; - } - else if(!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) && (prompt_buf_pos % (COLS - 3) == 0)) { - prompt_buf[prompt_buf_pos++] = '\n'; +static void prompt_onKey(ToxWindow *self, int key) +{ + /* Add printable characters to line */ + if (isprint(key)) { + if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) { + wprintw(self->window, "\nToo Long.\n"); + prompt_buf_pos = 0; + prompt_buf[0] = 0; } - else if(!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { - prompt_buf[prompt_buf_pos++] = '\n'; + else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) + && (prompt_buf_pos % (COLS - 3) == 0)) { + prompt_buf[prompt_buf_pos++] = '\n'; + } + else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) + && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { + prompt_buf[prompt_buf_pos++] = '\n'; } prompt_buf[prompt_buf_pos++] = key; prompt_buf[prompt_buf_pos] = 0; } - // RETURN key: execute command. - else if(key == '\n') { + /* RETURN key: execute command */ + else if (key == '\n') { wprintw(self->window, "\n"); execute(self, prompt_buf); prompt_buf_pos = 0; prompt_buf[0] = 0; } - // BACKSPACE key: Remove one character from line. - else if(key == 0x107 || key == 0x8 || key == 0x7f) { - if(prompt_buf_pos != 0) { + /* BACKSPACE key: Remove one character from line */ + else if (key == 0x107 || key == 0x8 || key == 0x7f) { + if (prompt_buf_pos != 0) { prompt_buf[--prompt_buf_pos] = 0; } } } -static void prompt_onDraw(ToxWindow* self) { - curs_set(1); - int x, y; - getyx(self->window, y, x); - (void) x; - int i; - for (i = 0; i < (strlen(prompt_buf)); i++) - { - if ((prompt_buf[i] == '\n') && (y != 0)) - --y; - } - wattron(self->window, COLOR_PAIR(1)); - mvwprintw(self->window, y, 0, "# "); - wattroff(self->window, COLOR_PAIR(1)); - mvwprintw(self->window, y, 2, "%s", prompt_buf); - wclrtoeol(self->window); - wrefresh(self->window); +static void prompt_onDraw(ToxWindow *self) +{ + curs_set(1); + int x, y; + getyx(self->window, y, x); + (void) x; + int i; + for (i = 0; i < (strlen(prompt_buf)); ++i) { + if ((prompt_buf[i] == '\n') && (y != 0)) + --y; + } + + wattron(self->window, COLOR_PAIR(1)); + mvwprintw(self->window, y, 0, "# "); + wattroff(self->window, COLOR_PAIR(1)); + mvwprintw(self->window, y, 2, "%s", prompt_buf); + wclrtoeol(self->window); + wrefresh(self->window); } -static void print_usage(ToxWindow* self) { +static void print_usage(ToxWindow *self) +{ wattron(self->window, COLOR_PAIR(2) | A_BOLD); wprintw(self->window, "Commands:\n"); wattroff(self->window, A_BOLD); - - wprintw(self->window, " connect : Connect to DHT server\n"); - wprintw(self->window, " add : Add friend\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"); - wprintw(self->window, " help : Print this message again\n"); - wprintw(self->window, " clear : Clear this window\n"); + wprintw(self->window, " connect : Connect to DHT server\n"); + wprintw(self->window, " add : Add friend\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"); + wprintw(self->window, " help : Print this message again\n"); + wprintw(self->window, " clear : Clear this window\n"); + wattron(self->window, A_BOLD); wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); wattroff(self->window, A_BOLD); @@ -347,22 +321,20 @@ static void print_usage(ToxWindow* self) { wattroff(self->window, COLOR_PAIR(2)); } -static void prompt_onInit(ToxWindow* self) { +static void prompt_onInit(ToxWindow *self) +{ scrollok(self->window, 1); - print_usage(self); wclrtoeol(self->window); } -ToxWindow new_prompt() { +ToxWindow new_prompt() +{ ToxWindow ret; - memset(&ret, 0, sizeof(ret)); - ret.onKey = &prompt_onKey; ret.onDraw = &prompt_onDraw; ret.onInit = &prompt_onInit; strcpy(ret.title, "[prompt]"); - return ret; } From 60f333328cea995585e7199b1e9fc93dfae53428 Mon Sep 17 00:00:00 2001 From: Konstantin Kowalski Date: Tue, 6 Aug 2013 13:52:05 -0400 Subject: [PATCH 21/25] Added a linked list implementation. --- testing/misc_tools.c | 12 ++++- testing/misc_tools.h | 111 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/testing/misc_tools.c b/testing/misc_tools.c index aa546a88..fa7f42c9 100644 --- a/testing/misc_tools.c +++ b/testing/misc_tools.c @@ -25,7 +25,11 @@ #include #include -#include /* for sscanf */ +#include + +#ifdef DEBUG +#include +#endif // DEBUG /* TODO: rewrite */ unsigned char * hex_string_to_bin(char hex_string[]) @@ -39,3 +43,9 @@ unsigned char * hex_string_to_bin(char hex_string[]) return val; } + + + + + + diff --git a/testing/misc_tools.h b/testing/misc_tools.h index 5079e15d..4e09d40d 100644 --- a/testing/misc_tools.h +++ b/testing/misc_tools.h @@ -25,5 +25,114 @@ #define MISC_TOOLS_H unsigned char * hex_string_to_bin(char hex_string[]); - + + + + + +/************************Linked List*********************** + * This is a simple linked list implementation, very similar + * to Linux kernel's /include/linux/list.h (which we can't + * use because Tox is GPLv3 and Linux is GPLv2.) + * + * TODO: Make the lists easier to use with some sweat pre- + * processor syntactic sugar. + **********************************************************/ + +/* Example usage + +This sample program makes a new struct which contains a +character and a tox_list_t. It then prompts a user for +input until he enters q or e. It then adds each character +to the list, and uses a special for loop to print them. +It then removes all the 'z' characters, and prints the list +again. + +//Notice that the data to be put in the list *contains* tox_list_t; +//usually, this is the other way around! +typedef struct tox_string { + char c; + tox_list_t tox_lst; //Notice that tox_lst is *NOT* a pointer. +} tox_string_t; + +int main() +{ + tox_list_t head; + tox_list_new(&head); //initialize head + + //input a new character, until user enters q or e + char c = '\0'; + while (c != 'q' && c != 'e') { + scanf("%c", &c); + tox_string_t* tmp = malloc(sizeof(tox_string_t)); + tmp->c = c; + tox_list_add(&head, &tmp->tox_lst); //add it to the list + } + +TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop. + +TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t. +You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst), +and the type of structure to return. + + TOX_LIST_FOR_EACH(head, tmp) + printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); + + TOX_LIST_FOR_EACH(head, tmp) { + if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') { + //If you delete tmp, you have to quit the loop, or it will go on infinitly. + //This will be fixed later on. + tox_list_remove(tmp); + break; + } + } + + printf("\n"); + TOX_LIST_FOR_EACH(head, tmp) + printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); + + + return 0; +} +*/ + +#define MEMBER_OFFSET(var_name_in_parent, parent_type) \ + (&(((parent_type*)0)->var_name_in_parent)) + +#define GET_PARENT(var, var_name_in_parent, parent_type) \ + (*((parent_type*)((uint64_t)(&(var)) - (uint64_t)(MEMBER_OFFSET(var_name_in_parent, parent_type))))) + +#define TOX_LIST_FOR_EACH(lst, tmp_name) \ + for (tox_list_t* tmp_name = lst.next; tmp_name != &lst; tmp_name = tmp_name->next) + +#define TOX_LIST_GET_VALUE(tmp_name, name_in_parent, parent_type) GET_PARENT(tmp_name, name_in_parent, parent_type) + +typedef struct tox_list { + struct tox_list *prev, *next; +} tox_list_t; + +/* Returns a new tox_list_t. */ +static inline void tox_list_new(tox_list_t* lst) { + lst->prev = lst->next = lst; +} + +/* Inserts a new tox_lst after lst and returns it. */ +static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) { + tox_list_new(new_lst); + + new_lst->next = lst->next; + new_lst->next->prev = new_lst; + + lst->next = new_lst; + new_lst->prev = lst; +} + +static inline void tox_list_remove(tox_list_t* lst) { +#ifdef DEBUG /* TODO: check how debugging is done in Tox. */ + assert(lst->next != lst && lst->prev != lst); +#endif + lst->prev->next = lst->next; + lst->next->prev = lst->prev; +} + #endif // MISC_TOOLS_H From f603342acfdc4196a91e0f2356f2ffb286b02d81 Mon Sep 17 00:00:00 2001 From: Konstantin Kowalski Date: Tue, 6 Aug 2013 16:47:15 -0400 Subject: [PATCH 22/25] Added ERROR() and WARNING() for debugging. --- testing/misc_tools.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/testing/misc_tools.h b/testing/misc_tools.h index 4e09d40d..eb09693e 100644 --- a/testing/misc_tools.h +++ b/testing/misc_tools.h @@ -26,9 +26,40 @@ unsigned char * hex_string_to_bin(char hex_string[]); +/* WARNING(msg) takes a printf()-styled string and prints it + * with some additional details. + * ERROR(exit_status, msg) does the same thing as WARNING(), but + * also exits the program with the given exit status. + * Examples: + * WARNING(""); + * int exit_status = 2; + * ERROR(exit_status, "exiting with status %i", exit_status); + */ +#ifdef DEBUG + #include + #include + #include + #define DEBUG_PRINT(str, ...) do { \ + char msg[1000]; \ + sprintf(msg, "%s(): line %d (file %s): %s%%c\n", __FUNCTION__, __LINE__, __FILE__, str); \ + fprintf(stderr, msg, __VA_ARGS__); \ + } while (0) + #define WARNING(...) do { \ + fprintf(stderr, "warning in "); \ + DEBUG_PRINT(__VA_ARGS__, ' '); \ + } while (0) + #define ERROR(exit_status, ...) do { \ + fprintf(stderr, "error in "); \ + DEBUG_PRINT(__VA_ARGS__, ' '); \ + exit(exit_status); \ + } while (0) +#else + #define WARNING(...) + #define ERROR(...) +#endif // DEBUG /************************Linked List*********************** * This is a simple linked list implementation, very similar From 7ddeb2bf6da9e68d8963ff703ec85284f7ed73ba Mon Sep 17 00:00:00 2001 From: Nick ODell Date: Tue, 6 Aug 2013 16:55:11 -0600 Subject: [PATCH 23/25] Fix bug where we could run past the end of the friends list --- core/Messenger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/Messenger.c b/core/Messenger.c index 9fa643bb..5532c9cc 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -116,7 +116,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) return FAERR_ALREADYSENT; uint32_t i; - for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ + for (i = 0; i < numfriends && i < MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ if(friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); friendlist[i].status = FRIEND_ADDED; @@ -141,7 +141,7 @@ int m_addfriend_norequest(uint8_t * client_id) if (getfriend_id(client_id) != -1) return -1; uint32_t i; - for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ + for (i = 0; i < numfriends && i < MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ if(friendlist[i].status == NOFRIEND) { DHT_addfriend(client_id); friendlist[i].status = FRIEND_REQUESTED; From eb546db56b7d30c970173d4a4d02672d3dc24a3a Mon Sep 17 00:00:00 2001 From: Nick ODell Date: Tue, 6 Aug 2013 17:07:45 -0600 Subject: [PATCH 24/25] Fix segfault when no broadcast device is found --- core/LAN_discovery.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 55953685..26b3930c 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c @@ -70,6 +70,10 @@ static uint32_t get_broadcast(void) } } close(sock); + if(sock_holder == NULL) { + perror("[!] no broadcast device found"); + return 0; + } return sock_holder->sin_addr.s_addr; } From 34f531553a6ec39ba55282dbf5b29e9a401d0880 Mon Sep 17 00:00:00 2001 From: Nick ODell Date: Tue, 6 Aug 2013 17:15:09 -0600 Subject: [PATCH 25/25] Fix bug where file handle wasn't closed on success --- testing/nTox.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/nTox.c b/testing/nTox.c index 63d0c32e..ecdba1e3 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -410,6 +410,8 @@ void load_key(char *path) } } + if(fclose(data_file) < 0) + perror("[!] fclose failed"); return; FILE_ERROR: