From fba0732faa6995152b7cf9c0a614a11281916a16 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Thu, 31 Jul 2014 12:48:49 -0400 Subject: [PATCH] implement contact blocking --- src/audio_call.c | 6 +- src/friendlist.c | 417 +++++++++++++++++++++++++++++++++++++++++++---- src/friendlist.h | 9 + src/toxic.c | 82 +++++----- src/windows.h | 8 + 5 files changed, 453 insertions(+), 69 deletions(-) diff --git a/src/audio_call.c b/src/audio_call.c index aa57f9a..439d7c3 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -576,7 +576,7 @@ on_error: print_err (self, error_str); } -void cmd_ccur_device(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) +void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { const char *msg; const char *error_str; @@ -651,7 +651,7 @@ void cmd_ccur_device(WINDOW * window, ToxWindow * self, Tox *m, int argc, char ( print_err (self, error_str); } -void cmd_mute(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) +void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { const char *msg; const char *error_str; @@ -699,7 +699,7 @@ void cmd_mute(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)[ print_err (self, error_str); } -void cmd_sense(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) +void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { const char *error_str; diff --git a/src/friendlist.c b/src/friendlist.c index 7dc69c8..e8af47a 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -42,26 +42,142 @@ extern char *DATA_FILE; +extern char *BLOCK_FILE; extern ToxWindow *prompt; - -static int max_friends_index = 0; /* marks the index of the last friend in friends array */ -static int num_selected = 0; -static int num_friends = 0; - extern struct _Winthread Winthread; extern struct user_settings *user_settings_; +extern struct arg_opts arg_opts; + +static uint8_t blocklist_view = 0; /* 0 if we're in friendlist view, 1 if we're in blocklist view */ +static int num_selected = 0; +static int max_friends_index = 0; /* 1 + the index of the last friend in friends array */ +static int num_friends = 0; ToxicFriend friends[MAX_FRIENDS_NUM]; static int friendlist_index[MAX_FRIENDS_NUM] = {0}; +static struct _Blocked_Contacts { + int num_selected; + int max_index; + int num_blocked; + BlockedFriend list[MAX_FRIENDS_NUM]; + int index[MAX_FRIENDS_NUM]; +} Blocked_Contacts; + static struct _pendingDel { int num; bool active; WINDOW *popup; } pendingdelete; -#define S_WEIGHT 100000 +static int save_blocklist(char *path) +{ + if (arg_opts.ignore_data_file) + return 0; + if (path == NULL) + return -1; + + int len = sizeof(BlockedFriend) * Blocked_Contacts.num_blocked; + char *data = malloc(len); + + if (data == NULL) + exit_toxic_err("Failed in save_blocklist", FATALERR_MEMORY); + + int i; + int count = 0; + + for (i = 0; i < Blocked_Contacts.max_index; ++i) { + if (count > Blocked_Contacts.num_blocked) + return -1; + + if (Blocked_Contacts.list[i].active) { + BlockedFriend tmp; + memset(&tmp, 0, sizeof(BlockedFriend)); + tmp.namelength = Blocked_Contacts.list[i].namelength; + memcpy(tmp.name, Blocked_Contacts.list[i].name, Blocked_Contacts.list[i].namelength + 1); + memcpy(tmp.pub_key, Blocked_Contacts.list[i].pub_key, TOX_CLIENT_ID_SIZE); + memcpy(data + count * sizeof(BlockedFriend), &tmp, sizeof(BlockedFriend)); + ++count; + } + } + + FILE *fp = fopen(path, "wb"); + + if (fp == NULL) { + free(data); + return -1; + } + + int ret = 0; + + if (fwrite(data, len, 1, fp) != 1) + ret = -1; + + fclose(fp); + free(data); + return ret; +} + +static void sort_blocklist_index(void); + +int load_blocklist(char *path) +{ + if (path == NULL) + return -1; + + FILE *fp = fopen(path, "rb"); + + if (fp == NULL) + return -1; + + fseek(fp, 0, SEEK_END); + int len = ftell(fp); + fseek(fp, 0, SEEK_SET); + + char *data = malloc(len); + + if (data == NULL) { + fclose(fp); + exit_toxic_err("Failed in load_blocklist", FATALERR_MEMORY); + } + + if (fread(data, len, 1, fp) != 1) { + fclose(fp); + free(data); + return -1; + } + + if (len % sizeof(BlockedFriend) != 0) { + fclose(fp); + free(data); + return -1; + } + + int num = len / sizeof(BlockedFriend); + int i; + + for (i = 0; i < num; ++i) { + BlockedFriend tmp; + memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend)); + Blocked_Contacts.list[i].active = true; + Blocked_Contacts.list[i].num = i; + Blocked_Contacts.list[i].namelength = tmp.namelength; + memcpy(Blocked_Contacts.list[i].name, tmp.name, tmp.namelength + 1); + memcpy(Blocked_Contacts.list[i].pub_key, tmp.pub_key, TOX_CLIENT_ID_SIZE); + ++Blocked_Contacts.num_blocked; + } + + Blocked_Contacts.max_index = i + 1; + + free(data); + fclose(fp); + sort_blocklist_index(); + + return 0; +} + +#define S_WEIGHT 100000 static int index_name_cmp(const void *n1, const void *n2) { int res = qsort_strcasecmp_hlpr(friends[*(int *) n1].name, friends[*(int *) n2].name); @@ -87,6 +203,24 @@ void sort_friendlist_index(void) qsort(friendlist_index, num_friends, sizeof(int), index_name_cmp); } +static int index_name_cmp_block(const void *n1, const void *n2) +{ + return qsort_strcasecmp_hlpr(Blocked_Contacts.list[*(int *) n1].name, Blocked_Contacts.list[*(int *) n2].name); +} + +static void sort_blocklist_index(void) +{ + int i; + int n = 0; + + for (i = 0; i < Blocked_Contacts.max_index; ++i) { + if (Blocked_Contacts.list[i].active) + Blocked_Contacts.index[n++] = Blocked_Contacts.list[i].num; + } + + qsort(Blocked_Contacts.index, Blocked_Contacts.num_blocked, sizeof(int), index_name_cmp_block); +} + static void update_friend_last_online(int32_t num, uint64_t timestamp) { friends[num].last_online.last_on = timestamp; @@ -207,6 +341,38 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort) } } +/* puts blocked friend back in friendlist. fnum is new friend number, bnum is blocked number */ +static void friendlist_add_blocked(Tox *m, int32_t fnum, int32_t bnum) +{ + if (max_friends_index >= MAX_FRIENDS_NUM) + return; + + int i; + + for (i = 0; i <= max_friends_index; ++i) { + if (friends[i].active) + continue; + + friends[i].num = fnum; + friends[i].active = true; + friends[i].chatwin = -1; + friends[i].status = TOX_USERSTATUS_NONE; + friends[i].logging_on = (bool) user_settings_->autolog == AUTOLOG_ON; + friends[i].namelength = Blocked_Contacts.list[bnum].namelength; + memcpy(friends[i].name, Blocked_Contacts.list[bnum].name, friends[i].namelength + 1); + memcpy(friends[i].pub_key, Blocked_Contacts.list[bnum].pub_key, TOX_CLIENT_ID_SIZE); + + num_friends = tox_count_friendlist(m); + + if (i == max_friends_index) + ++max_friends_index; + + sort_blocklist_index(); + sort_friendlist_index(); + return; + } +} + static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, uint64_t filesize, const char *filename, uint16_t filename_len) { @@ -253,13 +419,17 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const } } -static void select_friend(ToxWindow *self, Tox *m, wint_t key) +/* move friendlist/blocklist cursor up and down */ +static void select_friend(ToxWindow *self, wint_t key, int *selected, int count) { + if (count <= 0) + return; + if (key == KEY_UP) { - if (--num_selected < 0) - num_selected = num_friends - 1; + if (--(*selected) < 0) + *selected = count - 1; } else if (key == KEY_DOWN) { - num_selected = (num_selected + 1) % num_friends; + *selected = (*selected + 1) % count; } } @@ -282,7 +452,6 @@ static void delete_friend(Tox *m, int32_t f_num) if (num_friends && num_selected == num_friends) --num_selected; - sort_friendlist_index(); store_data(m, DATA_FILE); } @@ -294,11 +463,20 @@ static void del_friend_activate(ToxWindow *self, Tox *m, int32_t f_num) pendingdelete.num = f_num; } +static void remove_friend_blocked(int32_t bnum); + /* deactivates delete friend popup and deletes friend if instructed */ static void del_friend_deactivate(ToxWindow *self, Tox *m, wint_t key) { - if (key == 'y') - delete_friend(m, pendingdelete.num); + if (key == 'y') { + if (blocklist_view == 0) { + delete_friend(m, pendingdelete.num); + sort_friendlist_index(); + } else { + remove_friend_blocked(pendingdelete.num); + sort_blocklist_index(); + } + } delwin(pendingdelete.popup); memset(&pendingdelete, 0, sizeof(pendingdelete)); @@ -318,19 +496,99 @@ static void draw_popup(void) wmove(pendingdelete.popup, 1, 1); wprintw(pendingdelete.popup, "Delete contact "); wattron(pendingdelete.popup, A_BOLD); - wprintw(pendingdelete.popup, "%s", friends[pendingdelete.num].name); + + if (blocklist_view == 0) + wprintw(pendingdelete.popup, "%s", friends[pendingdelete.num].name); + else + wprintw(pendingdelete.popup, "%s", Blocked_Contacts.list[pendingdelete.num].name); + wattroff(pendingdelete.popup, A_BOLD); wprintw(pendingdelete.popup, "? y/n"); wrefresh(pendingdelete.popup); } -static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) +/* Deletes friend from friendlist, puts in blocklist */ +void block_friend(Tox *m, int32_t fnum) { - if (num_friends == 0) + if (Blocked_Contacts.max_index >= MAX_FRIENDS_NUM || num_friends <= 0) return; - int f = friendlist_index[num_selected]; + int i; + + for (i = 0; i <= Blocked_Contacts.max_index; ++i) { + if (Blocked_Contacts.list[i].active) + continue; + + Blocked_Contacts.list[i].active = true; + Blocked_Contacts.list[i].num = i; + Blocked_Contacts.list[i].namelength = friends[fnum].namelength; + memcpy(Blocked_Contacts.list[i].pub_key, friends[fnum].pub_key, TOX_CLIENT_ID_SIZE); + memcpy(Blocked_Contacts.list[i].name, friends[fnum].name, friends[fnum].namelength + 1); + + ++Blocked_Contacts.num_blocked; + + if (i == Blocked_Contacts.max_index) + ++Blocked_Contacts.max_index; + + delete_friend(m, fnum); + save_blocklist(BLOCK_FILE); + sort_blocklist_index(); + sort_friendlist_index(); + + return; + } +} + +/* permanently deletes friend from blocked list */ +static void remove_friend_blocked(int32_t bnum) +{ + memset(&Blocked_Contacts.list[bnum], 0, sizeof(BlockedFriend)); + + int i; + + for (i = Blocked_Contacts.max_index; i >= 0; --i) { + if (Blocked_Contacts.list[i - 1].active) + break; + } + + --Blocked_Contacts.num_blocked; + Blocked_Contacts.max_index = i; + save_blocklist(BLOCK_FILE); + + if (Blocked_Contacts.num_blocked && Blocked_Contacts.num_selected == Blocked_Contacts.num_blocked) + --Blocked_Contacts.num_selected; +} + +/* removes friend from blocklist, puts back in friendlist */ +static void unblock_friend(Tox *m, int32_t bnum) +{ + if (Blocked_Contacts.num_blocked <= 0) + return; + + int32_t friendnum = tox_add_friend_norequest(m, (uint8_t *) Blocked_Contacts.list[bnum].pub_key); + + if (friendnum == -1) { + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend"); + return; + } + + friendlist_add_blocked(m, friendnum, bnum); + remove_friend_blocked(bnum); + sort_blocklist_index(); + sort_friendlist_index(); +} + +static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) +{ + if (!blocklist_view && !num_friends && (key != KEY_RIGHT && key != KEY_LEFT)) + return; + + if (blocklist_view && !Blocked_Contacts.num_blocked && (key != KEY_RIGHT && key != KEY_LEFT)) + return; + + int f = blocklist_view == 1 ? Blocked_Contacts.index[Blocked_Contacts.num_selected] + : friendlist_index[num_selected]; /* lock screen and force decision on deletion popup */ if (pendingdelete.active) { @@ -340,8 +598,14 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) return; } - if (key != ltr) { - if (key == '\n') { + if (key == ltr) + return; + + switch (key) { + case '\n': + if (blocklist_view) + break; + /* Jump to chat window if already open */ if (friends[f].chatwin != -1) { set_active_window(friends[f].chatwin); @@ -351,19 +615,106 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) } else { const char *msg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg); - notify(prompt, error, NT_WNDALERT_1); } - } else if (key == KEY_DC) { + + break; + + case KEY_DC: del_friend_activate(self, m, f); - } else { - select_friend(self, m, key); - } + break; + + case 'b': + if (!blocklist_view) + block_friend(m, f); + else + unblock_friend(m, f); + break; + + case KEY_RIGHT: + case KEY_LEFT: + blocklist_view ^= 1; + break; + + default: + if (blocklist_view == 0) + select_friend(self, key, &num_selected, num_friends); + else + select_friend(self, key, &Blocked_Contacts.num_selected, Blocked_Contacts.num_blocked); + break; } } #define FLIST_OFST 6 /* Accounts for space at top and bottom */ +static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2) +{ + wattron(self->window, A_BOLD); + wprintw(self->window, " Blocked: "); + wattroff(self->window, A_BOLD); + wprintw(self->window, "%d\n\n", Blocked_Contacts.num_blocked); + + if ((y2 - FLIST_OFST) <= 0) + return; + + int selected_num = 0; + + /* Determine which portion of friendlist to draw based on current position */ + int page = Blocked_Contacts.num_selected / (y2 - FLIST_OFST); + int start = (y2 - FLIST_OFST) * page; + int end = y2 - FLIST_OFST + start; + + int i; + + for (i = start; i < Blocked_Contacts.num_blocked && i < end; ++i) { + int f = Blocked_Contacts.index[i]; + bool f_selected = false; + + if (i == Blocked_Contacts.num_selected) { + wattron(self->window, A_BOLD); + wprintw(self->window, " > "); + wattroff(self->window, A_BOLD); + selected_num = f; + f_selected = true; + } else { + wprintw(self->window, " "); + } + + wattron(self->window, COLOR_PAIR(RED)); + wprintw(self->window, "x"); + wattroff(self->window, COLOR_PAIR(RED)); + + if (f_selected) + wattron(self->window, COLOR_PAIR(BLUE)); + + wattron(self->window, A_BOLD); + wprintw(self->window, " %s\n", Blocked_Contacts.list[f].name); + wattroff(self->window, A_BOLD); + + if (f_selected) + wattroff(self->window, COLOR_PAIR(BLUE)); + } + + wprintw(self->window, "\n"); + self->x = x2; + + if (Blocked_Contacts.num_blocked) { + wmove(self->window, y2 - 1, 1); + + wattron(self->window, A_BOLD); + wprintw(self->window, "ID: "); + wattroff(self->window, A_BOLD); + + int i; + + for (i = 0; i < TOX_CLIENT_ID_SIZE; ++i) + wprintw(self->window, "%02X", Blocked_Contacts.list[selected_num].pub_key[i] & 0xff); + } + + wrefresh(self->window); + draw_popup(); +} + static void friendlist_onDraw(ToxWindow *self, Tox *m) { curs_set(0); @@ -371,9 +722,6 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) int x2, y2; getmaxyx(self->window, y2, x2); - uint64_t cur_time = get_unix_time(); - struct tm cur_loc_tm = *localtime((const time_t*)&cur_time); - bool fix_statuses = x2 != self->x; /* true if window max x value has changed */ wattron(self->window, COLOR_PAIR(CYAN)); @@ -385,9 +733,22 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) wattron(self->window, A_BOLD); wprintw(self->window, " Delete "); wattroff(self->window, A_BOLD); - wprintw(self->window, "key.\n\n"); + wprintw(self->window, "key.\n"); + wprintw(self->window, " Block a contact with the"); + wattron(self->window, A_BOLD); + wprintw(self->window, " b "); + wattroff(self->window, A_BOLD); + wprintw(self->window, "key, toggle blocklist with the."); wattroff(self->window, COLOR_PAIR(CYAN)); + if (blocklist_view == 1) { + blocklist_onDraw(self, m, y2, x2); + return; + } + + uint64_t cur_time = get_unix_time(); + struct tm cur_loc_tm = *localtime((const time_t *) &cur_time); + pthread_mutex_lock(&Winthread.lock); int nf = tox_get_num_online_friends(m); pthread_mutex_unlock(&Winthread.lock); diff --git a/src/friendlist.h b/src/friendlist.h index b4f6f7c..2a2b1dd 100644 --- a/src/friendlist.h +++ b/src/friendlist.h @@ -64,9 +64,18 @@ typedef struct { struct FileReceiver file_receiver; } ToxicFriend; +typedef struct { + char name[TOXIC_MAX_NAME_LENGTH]; + int namelength; + char pub_key[TOX_CLIENT_ID_SIZE]; + int32_t num; + bool active; +} BlockedFriend; + ToxWindow new_friendlist(void); void disable_chatwin(int32_t f_num); int get_friendnum(uint8_t *name); +int load_blocklist(char *data); void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort); diff --git a/src/toxic.c b/src/toxic.c index 22df49a..88f35c9 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -67,19 +67,13 @@ ToxAv *av; /* Export for use in Callbacks */ char *DATA_FILE = NULL; +char *BLOCK_FILE = NULL; ToxWindow *prompt = NULL; #define AUTOSAVE_FREQ 60 -struct arg_opts { - int ignore_data_file; - int use_ipv4; - int default_locale; - char config_path[MAX_STR_SIZE]; - char nodes_path[MAX_STR_SIZE]; -} arg_opts; - struct _Winthread Winthread; +struct arg_opts arg_opts; struct user_settings *user_settings_ = NULL; static void catch_SIGINT(int sig) @@ -371,15 +365,17 @@ static void load_friendlist(Tox *m) for (i = 0; i < numfriends; ++i) friendlist_onFriendAdded(NULL, m, i, false); + + sort_friendlist_index(); } /* * Store Messenger to given location * Return 0 stored successfully or ignoring data file - * Return 1 file path is NULL - * Return 2 malloc failed - * Return 3 opening path failed - * Return 4 fwrite failed + * Return -1 file path is NULL + * Return -2 malloc failed + * Return -3 opening path failed + * Return -4 fwrite failed */ int store_data(Tox *m, char *path) { @@ -387,13 +383,13 @@ int store_data(Tox *m, char *path) return 0; if (path == NULL) - return 1; + return -1; int len = tox_size(m); char *buf = malloc(len); if (buf == NULL) - return 2; + return -2; tox_save(m, (uint8_t *) buf); @@ -401,13 +397,13 @@ int store_data(Tox *m, char *path) if (fd == NULL) { free(buf); - return 3; + return -3; } if (fwrite(buf, len, 1, fd) != 1) { free(buf); fclose(fd); - return 4; + return -4; } free(buf); @@ -442,6 +438,7 @@ static void load_data(Tox *m, char *path) tox_load(m, (uint8_t *) buf, len); load_friendlist(m); + load_blocklist(BLOCK_FILE); free(buf); fclose(fd); @@ -526,10 +523,12 @@ static void parse_args(int argc, char *argv[]) switch (opt) { case 'f': DATA_FILE = strdup(optarg); + BLOCK_FILE = strdup(optarg); - if (DATA_FILE == NULL) + if (DATA_FILE == NULL || BLOCK_FILE == NULL) exit_toxic_err("failed in parse_args", FATALERR_MEMORY); + strcat(BLOCK_FILE, "-blocklist"); break; case 'x': @@ -560,39 +559,48 @@ static void parse_args(int argc, char *argv[]) } } -int main(int argc, char *argv[]) +#define DATANAME "data" +#define BLOCKNAME "data-blocklist" +static int init_data_files(void) { char *user_config_dir = get_user_config_dir(); - int config_err = 0; - - parse_args(argc, argv); - - /* Make sure all written files are read/writeable only by the current user. */ - umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - signal(SIGINT, catch_SIGINT); - - config_err = create_user_config_dir(user_config_dir); + int config_err = create_user_config_dir(user_config_dir); if (DATA_FILE == NULL ) { if (config_err) { - DATA_FILE = strdup("data"); + DATA_FILE = strdup(DATANAME); + BLOCK_FILE = strdup(BLOCKNAME); - if (DATA_FILE == NULL) - exit_toxic_err("failed in main", FATALERR_MEMORY); + if (DATA_FILE == NULL || BLOCK_FILE == NULL) + exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); } else { - DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); + DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1); + BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1); - if (DATA_FILE == NULL) - exit_toxic_err("failed in main", FATALERR_MEMORY); + if (DATA_FILE == NULL || BLOCK_FILE == NULL) + exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); strcpy(DATA_FILE, user_config_dir); strcat(DATA_FILE, CONFIGDIR); - strcat(DATA_FILE, "data"); + strcat(DATA_FILE, DATANAME); + + strcpy(BLOCK_FILE, user_config_dir); + strcat(BLOCK_FILE, CONFIGDIR); + strcat(BLOCK_FILE, BLOCKNAME); } } free(user_config_dir); + return config_err; +} + +int main(int argc, char *argv[]) +{ + parse_args(argc, argv); + /* Make sure all written files are read/writeable only by the current user. */ + umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + signal(SIGINT, catch_SIGINT); + int config_err = init_data_files(); /* init user_settings struct and load settings from conf file */ user_settings_ = calloc(1, sizeof(struct user_settings)); @@ -644,7 +652,7 @@ int main(int argc, char *argv[]) const char *msg; if (config_err) { - msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile..."; + msg = "Unable to determine configuration directory. Defaulting to 'data' for data file..."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); } @@ -653,8 +661,6 @@ int main(int argc, char *argv[]) line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); } - sort_friendlist_index(); - uint64_t last_save = (uint64_t) time(NULL); while (true) { diff --git a/src/windows.h b/src/windows.h index d56fa43..7522431 100644 --- a/src/windows.h +++ b/src/windows.h @@ -71,6 +71,14 @@ struct _Winthread { bool flag_resize; }; +struct arg_opts { + int ignore_data_file; + int use_ipv4; + int default_locale; + char config_path[MAX_STR_SIZE]; + char nodes_path[MAX_STR_SIZE]; +}; + typedef struct ToxWindow ToxWindow; typedef struct StatusBar StatusBar; typedef struct PromptBuf PromptBuf;