mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-30 09:16:52 +01:00 
			
		
		
		
	Fixed a bunch of bugs in TOXIC, added friendlist and more.
This commit is contained in:
		| @@ -5,7 +5,8 @@ set(exe_name toxic) | ||||
|  | ||||
| add_executable(${exe_name} | ||||
| 	main.c | ||||
| 	prompt.c) | ||||
| 	prompt.c | ||||
| 	friendlist.c) | ||||
|  | ||||
| target_link_libraries(${exe_name} | ||||
| 	curses) | ||||
|   | ||||
							
								
								
									
										125
									
								
								friendlist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								friendlist.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| /* | ||||
|  * Toxic -- Tox Curses Client | ||||
|  */ | ||||
|  | ||||
| #include <curses.h> | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
| #include <ctype.h> | ||||
|  | ||||
| #include "../../core/Messenger.h" | ||||
| #include "../../core/network.h" | ||||
|  | ||||
| #include "windows.h" | ||||
|  | ||||
| #define MAX_FRIENDS_NUM 100 | ||||
|  | ||||
| typedef struct { | ||||
|   uint8_t name[MAX_NAME_LENGTH]; | ||||
|   uint8_t status[MAX_USERSTATUS_LENGTH]; | ||||
|   int     num; | ||||
|  | ||||
| } friend_t; | ||||
|  | ||||
| static friend_t friends[MAX_FRIENDS_NUM]; | ||||
| static int num_friends = 0; | ||||
|  | ||||
|  | ||||
| void fix_name(uint8_t* name) { | ||||
|  | ||||
|   // Remove all non alphanumeric characters. | ||||
|   uint8_t* p = name; | ||||
|   uint8_t* q = name; | ||||
|  | ||||
|   while(*p != 0) { | ||||
|     if(isalnum(*p)) { | ||||
|       *q++ = *p; | ||||
|     } | ||||
|  | ||||
|     p++; | ||||
|   } | ||||
|  | ||||
|   *q = 0; | ||||
| } | ||||
|  | ||||
| int friendlist_nickchange(int num, uint8_t* str, uint16_t len) { | ||||
|  | ||||
|   if(len >= MAX_NAME_LENGTH || num >= num_friends) | ||||
|     return -1; | ||||
|  | ||||
|   memcpy((char*) &friends[num].name, (char*) str, len); | ||||
|   friends[num].name[len] = 0; | ||||
|   fix_name(friends[num].name); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int friendlist_statuschange(int num, uint8_t* str, uint16_t len) { | ||||
|  | ||||
|   if(len >= MAX_USERSTATUS_LENGTH || num >= num_friends) | ||||
|     return -1; | ||||
|  | ||||
|   memcpy((char*) &friends[num].status, (char*) str, len); | ||||
|   friends[num].status[len] = 0; | ||||
|   fix_name(friends[num].status); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int friendlist_addfriend(int num) { | ||||
|  | ||||
|   if(num_friends == MAX_FRIENDS_NUM) | ||||
|     return -1; | ||||
|  | ||||
|   friends[num_friends].num = num; | ||||
|   getname(num, friends[num_friends].name); | ||||
|   strcpy((char*) friends[num_friends].name, "unknown"); | ||||
|   strcpy((char*) friends[num_friends].status, "unknown"); | ||||
|  | ||||
|   num_friends++; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| static void friendlist_onKey(ToxWindow* self, int key) { | ||||
|  | ||||
| } | ||||
|  | ||||
| static void friendlist_onDraw(ToxWindow* self) { | ||||
|   size_t i; | ||||
|  | ||||
|   wclear(self->window); | ||||
|  | ||||
|   if(num_friends == 0) { | ||||
|     wprintw(self->window, "Empty. Add some friends! :-)\n"); | ||||
|   } | ||||
|  | ||||
|   wprintw(self->window, "\n"); | ||||
|  | ||||
|   for(i=0; i<num_friends; i++) { | ||||
|     wprintw(self->window, "[%d] ", friends[i].num); | ||||
|  | ||||
|     attron(A_BOLD); | ||||
|     wprintw(self->window, "%s ", friends[i].name); | ||||
|     attroff(A_BOLD); | ||||
|  | ||||
|     wprintw(self->window, "(%s)\n", friends[i].status); | ||||
|   } | ||||
|  | ||||
|   wrefresh(self->window); | ||||
| } | ||||
|  | ||||
| static void friendlist_onInit(ToxWindow* self) { | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| ToxWindow new_friendlist() { | ||||
|   ToxWindow ret; | ||||
|  | ||||
|   ret.onKey = &friendlist_onKey; | ||||
|   ret.onDraw = &friendlist_onDraw; | ||||
|   ret.onInit = &friendlist_onInit; | ||||
|   strcpy(ret.title, "[friends]"); | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
							
								
								
									
										49
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								main.c
									
									
									
									
									
								
							| @@ -14,6 +14,12 @@ | ||||
| #include "windows.h" | ||||
|  | ||||
| extern ToxWindow new_prompt(); | ||||
| extern ToxWindow new_friendlist(); | ||||
|  | ||||
| extern int friendlist_addfriend(int num); | ||||
| extern int friendlist_nickchange(int num, uint8_t* str, uint16_t len); | ||||
| extern int friendlist_statuschange(int num, uint8_t* str, uint16_t len); | ||||
|  | ||||
| extern int add_req(uint8_t* public_key); // XXX | ||||
|  | ||||
| #define TOXWINDOWS_MAX_NUM 32 | ||||
| @@ -35,11 +41,19 @@ void on_message(int friendnumber, uint8_t* string, uint16_t length) { | ||||
| } | ||||
|  | ||||
| void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) { | ||||
|   wprintw(prompt->window, "\n(nick) %d: %s!\n", friendnumber, string); | ||||
|   wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string); | ||||
|  | ||||
|   friendlist_nickchange(friendnumber, string, length); | ||||
| } | ||||
|  | ||||
| void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) { | ||||
|   wprintw(prompt->window, "\n(status) %d: %s!\n", friendnumber, string); | ||||
|   wprintw(prompt->window, "\n(statuschange) %d: %s!\n", friendnumber, string); | ||||
|  | ||||
|   friendlist_statuschange(friendnumber, string, length); | ||||
| } | ||||
|  | ||||
| void on_friendadded(int friendnumber) { | ||||
|   friendlist_addfriend(friendnumber); | ||||
| } | ||||
| // CALLBACKS END | ||||
|  | ||||
| @@ -95,7 +109,7 @@ static void init_windows() { | ||||
|   w_num = 0; | ||||
|   w_active = 0; | ||||
|  | ||||
|   if(add_window(new_prompt()) == -1) { | ||||
|   if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) { | ||||
|     fprintf(stderr, "add_window() failed.\n"); | ||||
|  | ||||
|     endwin(); | ||||
| @@ -134,14 +148,18 @@ static void load_data() { | ||||
|  | ||||
|     if(buf == NULL) { | ||||
|       fprintf(stderr, "malloc() failed.\n"); | ||||
|  | ||||
|       fclose(fd); | ||||
|       endwin(); | ||||
|       exit(1); | ||||
|     } | ||||
|  | ||||
|     if(fread(buf, len, 1, fd) != 1){ | ||||
|       fprintf(stderr, "fread() failed.\n"); | ||||
|  | ||||
|       free(buf); | ||||
|       fclose(fd); | ||||
|       endwin(); | ||||
|       exit(1); | ||||
|     } | ||||
|  | ||||
| @@ -153,6 +171,7 @@ static void load_data() { | ||||
|  | ||||
|     if(buf == NULL) { | ||||
|       fprintf(stderr, "malloc() failed.\n"); | ||||
|       endwin(); | ||||
|       exit(1); | ||||
|     } | ||||
|  | ||||
| @@ -161,14 +180,18 @@ static void load_data() { | ||||
|     fd = fopen("data", "w"); | ||||
|     if(fd == NULL) { | ||||
|       fprintf(stderr, "fopen() failed.\n"); | ||||
|  | ||||
|       free(buf); | ||||
|       endwin(); | ||||
|       exit(1); | ||||
|     } | ||||
|  | ||||
|     if(fwrite(buf, len, 1, fd) != 1){ | ||||
|       fprintf(stderr, "fwrite() failed.\n"); | ||||
|  | ||||
|       free(buf); | ||||
|       fclose(fd); | ||||
|       endwin(); | ||||
|       exit(1); | ||||
|     } | ||||
|   } | ||||
| @@ -186,12 +209,16 @@ static void draw_bar() { | ||||
|  | ||||
|   move(LINES - 1, 0); | ||||
|  | ||||
|   attron(COLOR_PAIR(3) | A_BOLD); | ||||
|   printw(" TOXIC 1.0 |"); | ||||
|   attroff(COLOR_PAIR(3) | A_BOLD); | ||||
|  | ||||
|   for(i=0; i<w_num; i++) { | ||||
|     if(i == w_active) { | ||||
|       attron(A_BOLD); | ||||
|     } | ||||
|  | ||||
|     printw(" %s ", windows[i].title); | ||||
|     printw(" %s", windows[i].title); | ||||
|  | ||||
|     if(i == w_active) { | ||||
|       attroff(A_BOLD); | ||||
| @@ -201,6 +228,11 @@ static void draw_bar() { | ||||
|   refresh(); | ||||
| } | ||||
|  | ||||
| void prepare_window(WINDOW* w) { | ||||
|   mvwin(w, 0, 0); | ||||
|   wresize(w, LINES-2, COLS); | ||||
| } | ||||
|  | ||||
| int main(int argc, char* argv[]) { | ||||
|   int ch; | ||||
|   ToxWindow* a; | ||||
| @@ -211,14 +243,21 @@ int main(int argc, char* argv[]) { | ||||
|   init_windows(); | ||||
|  | ||||
|   while(true) { | ||||
|     // Update tox. | ||||
|     do_tox(); | ||||
|  | ||||
|     // Draw. | ||||
|     a = &windows[w_active]; | ||||
|     prepare_window(a->window); | ||||
|     a->onDraw(a); | ||||
|     draw_bar(); | ||||
|  | ||||
|     // Handle input. | ||||
|     ch = getch(); | ||||
|     if(ch != ERR) { | ||||
|     if(ch == '\t') { | ||||
|       w_active = (w_active + 1) % w_num; | ||||
|     } | ||||
|     else if(ch != ERR) { | ||||
|       a->onKey(a, ch); | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										105
									
								
								prompt.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								prompt.c
									
									
									
									
									
								
							| @@ -15,6 +15,8 @@ | ||||
| uint8_t pending_requests[256][CLIENT_ID_SIZE]; // XXX | ||||
| uint8_t num_requests=0; // XXX | ||||
|  | ||||
| extern void on_friendadded(int friendnumber); | ||||
|  | ||||
| // XXX: | ||||
| int add_req(uint8_t* public_key) { | ||||
|   memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); | ||||
| @@ -40,7 +42,6 @@ static int prompt_buf_pos=0; | ||||
|  | ||||
| static void execute(ToxWindow* self, char* cmd) { | ||||
|  | ||||
|   // quit/exit: Exit program. | ||||
|   if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { | ||||
|     endwin(); | ||||
|     exit(0); | ||||
| @@ -53,33 +54,32 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|  | ||||
|     ip = strchr(cmd, ' '); | ||||
|     if(ip == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     ip++; | ||||
|  | ||||
|     port = strchr(ip, ' '); | ||||
|     if(port == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     port[0] = 0; | ||||
|     port++; | ||||
|  | ||||
|     key = strchr(port, ' '); | ||||
|     if(key == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     key[0] = 0; | ||||
|     key++; | ||||
|  | ||||
|     if(atoi(port) == 0) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     wprintw(self->window, "ip=%s, port=%s, key=%s\n", ip, port, key); | ||||
|  | ||||
|     dht.port = htons(atoi(port)); | ||||
|  | ||||
|     int resolved_address = resolve_addr(ip); | ||||
| @@ -91,38 +91,62 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|     DHT_bootstrap(dht, hex_string_to_bin(key)); | ||||
|   } | ||||
|   else if(!strncmp(cmd, "add ", strlen("add "))) { | ||||
|     uint8_t id_bin[32]; | ||||
|     size_t i; | ||||
|     char xx[3]; | ||||
|     uint32_t x; | ||||
|  | ||||
|     char* id; | ||||
|     char* msg; | ||||
|     int num; | ||||
|  | ||||
|     id = strchr(cmd, ' '); | ||||
|  | ||||
|     if(id == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     id++; | ||||
|  | ||||
|     msg = strchr(id, ' '); | ||||
|     if(msg == NULL) { | ||||
|     if(msg != NULL) { | ||||
|       msg[0] = 0; | ||||
|       msg++; | ||||
|     } | ||||
|     else msg = ""; | ||||
|  | ||||
|     if(strlen(id) != 2*32) { | ||||
|       wprintw(self->window, "Invalid ID length.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     msg[0] = 0; | ||||
|     msg++; | ||||
|     for(i=0; i<32; i++) { | ||||
|       xx[0] = id[2*i]; | ||||
|       xx[1] = id[2*i+1]; | ||||
|       xx[2] = '\0'; | ||||
|  | ||||
|       if(sscanf(xx, "%02x", &x) != 1) { | ||||
| 	wprintw(self->window, "Invalid ID.\n"); | ||||
| 	return; | ||||
|       } | ||||
|  | ||||
|       id_bin[i] = x; | ||||
|     } | ||||
|  | ||||
|     num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); | ||||
|  | ||||
|     num = m_addfriend((uint8_t*) id, (uint8_t*) msg, strlen(msg)+1); | ||||
|     wprintw(self->window, "Friend added as %d.\n", num); | ||||
|     on_friendadded(num); | ||||
|   } | ||||
|   else if(!strncmp(cmd, "status ", strlen("status "))) { | ||||
|     char* msg; | ||||
|  | ||||
|     msg = strchr(cmd, ' '); | ||||
|     if(msg == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     msg++; | ||||
|  | ||||
|     m_set_userstatus((uint8_t*) msg, strlen(msg)+1); | ||||
|     wprintw(self->window, "Status set to: %s.\n", msg); | ||||
|   } | ||||
| @@ -133,33 +157,22 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|     if(nick == NULL) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     nick++; | ||||
|  | ||||
|     setname((uint8_t*) nick, strlen(nick)+1); | ||||
|     wprintw(self->window, "Nickname set to: %s.\n", nick); | ||||
|   } | ||||
|   else if(!strcmp(cmd, "myid")) { | ||||
|     // XXX: Clean this up | ||||
|     char idstring0[200]; | ||||
|     char idstring1[32][5]; | ||||
|     char idstring2[32][5]; | ||||
|     uint32_t i; | ||||
|     char id[32*2 + 1] = {0}; | ||||
|     size_t i; | ||||
|  | ||||
|     for(i = 0; i < 32; i++) { | ||||
|       if(self_public_key[i] < 16) | ||||
| 	strcpy(idstring1[i], "0"); | ||||
|       else  | ||||
| 	strcpy(idstring1[i], ""); | ||||
|  | ||||
|       sprintf(idstring2[i], "%hhX", self_public_key[i]); | ||||
|     for(i=0; i<32; i++) { | ||||
|       char xx[3]; | ||||
|       snprintf(xx, sizeof(xx), "%02x",  self_public_key[i] & 0xff); | ||||
|       strcat(id, xx); | ||||
|     } | ||||
|      | ||||
|     for (i=0; i<32; i++) { | ||||
|       strcat(idstring0, idstring1[i]); | ||||
|       strcat(idstring0, idstring2[i]); | ||||
|     } | ||||
|  | ||||
|     wprintw(self->window, "%s\n", idstring0); | ||||
|     wprintw(self->window, "%s\n", id); | ||||
|   } | ||||
|   else if(!strncmp(cmd, "accept ", strlen("accept "))) { | ||||
|     char* id; | ||||
| @@ -167,17 +180,26 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|  | ||||
|     id = strchr(cmd, ' '); | ||||
|     if(id == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|     id++; | ||||
|  | ||||
|     num = atoi(id); | ||||
|     if(num >= num_requests) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     num = m_addfriend_norequest(pending_requests[num]); | ||||
|     wprintw(self->window, "Friend accepted as: %d.\n", num); | ||||
|  | ||||
|     if(num == -1) { | ||||
|       wprintw(self->window, "Failed to add friend.\n"); | ||||
|     } | ||||
|     else { | ||||
|       wprintw(self->window, "Friend accepted as: %d.\n", num); | ||||
|       on_friendadded(num); | ||||
|     } | ||||
|   } | ||||
|   else if(!strncmp(cmd, "msg ", strlen("msg "))) { | ||||
|     char* id; | ||||
| @@ -186,16 +208,16 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|     id = strchr(cmd, ' '); | ||||
|  | ||||
|     if(id == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     id++; | ||||
|  | ||||
|     msg = strchr(id, ' '); | ||||
|     if(msg == NULL) { | ||||
|       wprintw(self->window, "Invalid syntax.\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     msg[0] = 0; | ||||
|     msg++; | ||||
|  | ||||
| @@ -206,6 +228,9 @@ static void execute(ToxWindow* self, char* cmd) { | ||||
|       wprintw(self->window, "Message successfully sent.\n"); | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     wprintw(self->window, "Invalid syntax.\n"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void prompt_onKey(ToxWindow* self, int key) { | ||||
| @@ -242,9 +267,6 @@ static void prompt_onKey(ToxWindow* self, int key) { | ||||
| static void prompt_onDraw(ToxWindow* self) { | ||||
|   int x, y; | ||||
|  | ||||
|   mvwin(self->window,0,0); | ||||
|   wresize(self->window, LINES-2, COLS); | ||||
|  | ||||
|   getyx(self->window, y, x); | ||||
|   (void) x; | ||||
|  | ||||
| @@ -265,11 +287,18 @@ static void print_usage(ToxWindow* self) { | ||||
|    | ||||
|   wprintw(self->window, "      connect <ip> <port> <key> : Connect to DHT server\n"); | ||||
|   wprintw(self->window, "      add <id> <message>        : Add friend\n"); | ||||
|   wprintw(self->window, "      msg <number> <message>    : Send message\n"); | ||||
|   wprintw(self->window, "      status <message>          : Set your status\n"); | ||||
|   wprintw(self->window, "      nick <nickname>           : Set your nickname\n"); | ||||
|   wprintw(self->window, "      accept <number>           : Accept friend request\n"); | ||||
|   wprintw(self->window, "      myid                      : Print your ID\n"); | ||||
|   wprintw(self->window, "      quit/exit                 : Exit program\n"); | ||||
|  | ||||
|  | ||||
|   wattron(self->window, A_BOLD); | ||||
|   wprintw(self->window, "Use the TAB key to navigate through the tabs.\n"); | ||||
|   wattroff(self->window, A_BOLD); | ||||
|  | ||||
|   wattroff(self->window, COLOR_PAIR(2)); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user