/* deletes contact from friendlist and puts in blocklist */ void block_friend(Tox *m, uint32_t fnum) { if (Friends.num_friends <= 0) return; realloc_blocklist(Blocked.max_idx + 1); memset(&Blocked.list[Blocked.max_idx], 0, sizeof(BlockedFriend)); int i; for (i = 0; i <= Blocked.max_idx; ++i) { if (Blocked.list[i].active) continue; Blocked.list[i].active = true; Blocked.list[i].num = i; Blocked.list[i].namelength = Friends.list[fnum].namelength; Blocked.list[i].last_on = Friends.list[fnum].last_online.last_on; memcpy(Blocked.list[i].pub_key, Friends.list[fnum].pub_key, TOX_PUBLIC_KEY_SIZE); memcpy(Blocked.list[i].name, Friends.list[fnum].name, Friends.list[fnum].namelength + 1); ++Blocked.num_blocked; if (i == Blocked.max_idx) ++Blocked.max_idx; delete_friend(m, fnum); save_blocklist(BLOCK_FILE); sort_blocklist_index(); sort_friendlist_index(); return; } }
/* puts blocked friend back in friendlist. fnum is new friend number, bnum is blocked number */ static void friendlist_add_blocked(Tox *m, uint32_t fnum, uint32_t bnum) { realloc_friends(Friends.max_idx + 1); memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend)); int i; for (i = 0; i <= Friends.max_idx; ++i) { if (Friends.list[i].active) continue; ++Friends.num_friends; Friends.list[i].num = fnum; Friends.list[i].active = true; Friends.list[i].chatwin = -1; Friends.list[i].status = TOX_USER_STATUS_NONE; Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; Friends.list[i].namelength = Blocked.list[bnum].namelength; update_friend_last_online(i, Blocked.list[bnum].last_on); memcpy(Friends.list[i].name, Blocked.list[bnum].name, Friends.list[i].namelength + 1); memcpy(Friends.list[i].pub_key, Blocked.list[bnum].pub_key, TOX_PUBLIC_KEY_SIZE); if (i == Friends.max_idx) ++Friends.max_idx; sort_blocklist_index(); sort_friendlist_index(); return; } }
int load_blocklist(char *path) { if (path == NULL) return -1; FILE *fp = fopen(path, "rb"); if (fp == NULL) return -1; off_t len = file_size(path); if (len == 0) { fclose(fp); return -1; } char data[len]; if (fread(data, len, 1, fp) != 1) { fclose(fp); return -1; } if (len % sizeof(BlockedFriend) != 0) { fclose(fp); return -1; } int num = len / sizeof(BlockedFriend); Blocked.max_idx = num; realloc_blocklist(num); int i; for (i = 0; i < num; ++i) { BlockedFriend tmp; memset(&tmp, 0, sizeof(BlockedFriend)); memset(&Blocked.list[i], 0, sizeof(BlockedFriend)); memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend)); Blocked.list[i].active = true; Blocked.list[i].num = i; Blocked.list[i].namelength = ntohs(tmp.namelength); memcpy(Blocked.list[i].name, tmp.name, Blocked.list[i].namelength + 1); memcpy(Blocked.list[i].pub_key, tmp.pub_key, TOX_PUBLIC_KEY_SIZE); uint8_t lastonline[sizeof(uint64_t)]; memcpy(lastonline, &tmp.last_on, sizeof(uint64_t)); net_to_host(lastonline, sizeof(uint64_t)); memcpy(&Blocked.list[i].last_on, lastonline, sizeof(uint64_t)); ++Blocked.num_blocked; } fclose(fp); sort_blocklist_index(); return 0; }
/* deletes contact from friendlist and puts in blocklist */ void block_friend(Tox *m, int32_t fnum) { if (Blocked_Contacts.max_index >= MAX_FRIENDS_NUM || num_friends <= 0) return; 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; Blocked_Contacts.list[i].last_on = friends[fnum].last_online.last_on; 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; } }
/* 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; update_friend_last_online(i, Blocked_Contacts.list[bnum].last_on); 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; } }
/* deactivates delete friend popup and deletes friend if instructed */ static void del_friend_deactivate(ToxWindow *self, Tox *m, wint_t key) { if (key == 'y') { if (blocklist_view == 0) { delete_friend(m, PendingDelete.num); sort_friendlist_index(); } else { delete_blocked_friend(PendingDelete.num); sort_blocklist_index(); } } delwin(PendingDelete.popup); memset(&PendingDelete, 0, sizeof(PendingDelete)); clear(); refresh(); }
/* removes friend from blocklist, puts back in friendlist */ static void unblock_friend(Tox *m, int32_t bnum) { if (Blocked.num_blocked <= 0) return; int32_t friendnum = tox_add_friend_norequest(m, (uint8_t *) Blocked.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); delete_blocked_friend(bnum); sort_blocklist_index(); sort_friendlist_index(); }
/* removes friend from blocklist, puts back in friendlist */ static void unblock_friend(Tox *m, uint32_t bnum) { if (Blocked.num_blocked <= 0) return; TOX_ERR_FRIEND_ADD err; uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err); if (err != TOX_ERR_FRIEND_ADD_OK) { line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)", err); return; } friendlist_add_blocked(m, friendnum, bnum); delete_blocked_friend(bnum); sort_blocklist_index(); sort_friendlist_index(); }
int load_blocklist(char *path) { if (path == NULL) return -1; FILE *fp = fopen(path, "rb"); if (fp == NULL) return -1; off_t len = file_size(path); if (len == -1) { fclose(fp); return -1; } 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); Blocked.max_idx = num; realloc_blocklist(num); int i; for (i = 0; i < num; ++i) { memset(&Blocked.list[i], 0, sizeof(BlockedFriend)); BlockedFriend tmp; memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend)); Blocked.list[i].active = true; Blocked.list[i].num = i; Blocked.list[i].namelength = ntohs(tmp.namelength); memcpy(Blocked.list[i].name, tmp.name, Blocked.list[i].namelength + 1); memcpy(Blocked.list[i].pub_key, tmp.pub_key, TOX_CLIENT_ID_SIZE); uint8_t lastonline[sizeof(uint64_t)]; memcpy(lastonline, &tmp.last_on, sizeof(uint64_t)); net_to_host(lastonline, sizeof(uint64_t)); memcpy(&Blocked.list[i].last_on, lastonline, sizeof(uint64_t)); ++Blocked.num_blocked; } free(data); fclose(fp); sort_blocklist_index(); return 0; }