static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t receive_send, uint8_t filenum, uint8_t control_type, const char *data, uint16_t length) { if (self->num != num) return; const char *filename; char msg[MAX_STR_SIZE] = {0}; int i = 0; /* file_sender index */ if (receive_send == 0) { filename = friends[num].file_receiver.filenames[filenum]; } else { for (i = 0; i < MAX_FILES; ++i) { if (file_senders[i].filenum == filenum) break; } filename = file_senders[i].pathname; } switch (control_type) { case TOX_FILECONTROL_ACCEPT: if (receive_send == 1) { const char *r_msg = "File transfer for '%s' accepted."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, r_msg, filename); /* prep progress bar line */ char progline[MAX_STR_SIZE]; prep_prog_line(progline); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, progline); file_senders[i].line_id = self->chatwin->hst->line_end->id + 2; notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2); } break; case TOX_FILECONTROL_KILL: snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename); if (receive_send == 0) chat_close_file_receiver(num, filenum); notify(self, error, NT_NOFOCUS | NT_WNDALERT_2); break; case TOX_FILECONTROL_FINISHED: if (receive_send == 0) { snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename); chat_close_file_receiver(num, filenum); notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2); } break; } if (msg[0]) line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); }
static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, const char *data, uint16_t length) { if (self->num != num) return; FILE *fp = friends[num].file_receiver.files[filenum]; if (fp) { if (fwrite(data, length, 1, fp) != 1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Error writing to file."); tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); chat_close_file_receiver(num, filenum); } } friends[num].file_receiver.bps[filenum] += length; double remain = (double) tox_file_data_remaining(m, num, filenum, 1); uint64_t curtime = get_unix_time(); /* refresh line with percentage complete and transfer speed (must be called once per second) */ if (!remain || timed_out(friends[num].file_receiver.last_progress[filenum], curtime, 1)) { friends[num].file_receiver.last_progress[filenum] = curtime; uint64_t size = friends[num].file_receiver.size[filenum]; double pct_remain = remain > 0 ? (1 - (remain / size)) * 100 : 100; print_progress_bar(self, filenum, num, pct_remain); friends[num].file_receiver.bps[filenum] = 0; } }
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 2) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Requires type in|out and the file ID."); return; } const char *inoutstr = argv[1]; int filenum = atoi(argv[2]); if (filenum >= MAX_FILES || filenum < 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); return; } if (strcasecmp(inoutstr, "in") == 0) { /* cancel an incoming file transfer */ if (!Friends.list[self->num].file_receiver[filenum].active) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); return; } const char *filepath = Friends.list[self->num].file_receiver[filenum].filename; char name[MAX_STR_SIZE]; get_file_name(name, sizeof(name), filepath); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer for '%s' canceled.", name); chat_close_file_receiver(m, filenum, self->num, TOX_FILECONTROL_KILL); return; } else if (strcasecmp(inoutstr, "out") == 0) { /* cancel an outgoing file transfer */ int i; bool match = false; for (i = 0; i < MAX_FILES; ++i) { if (file_senders[i].active && file_senders[i].filenum == filenum) { match = true; break; } } if (!match) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); return; } const char *filename = file_senders[i].filename; char msg[MAX_STR_SIZE]; snprintf(msg, sizeof(msg), "File transfer for '%s' canceled.", filename); close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, self->num); return; } else { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type must be 'in' or 'out'."); return; } }