1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 14:53:26 +01:00

file transfer improvements and bug fixes

This commit is contained in:
Jfreegman 2014-08-05 17:38:33 -04:00
parent fd65fbfd0c
commit 6ab184e7ce
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
10 changed files with 76 additions and 53 deletions

View File

@ -124,11 +124,14 @@ static void chat_set_window_name(ToxWindow *self, char *nick, int len)
snprintf(self->name, sizeof(self->name), "%s", nick); snprintf(self->name, sizeof(self->name), "%s", nick);
} }
void kill_chat_window(ToxWindow *self) static void close_all_file_receivers(Tox *m, int friendnum);
void kill_chat_window(ToxWindow *self, Tox *m)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
StatusBar *statusbar = self->stb; StatusBar *statusbar = self->stb;
close_all_file_receivers(m, self->num);
log_disable(ctx->log); log_disable(ctx->log);
line_info_cleanup(ctx->hst); line_info_cleanup(ctx->hst);
@ -293,7 +296,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
len += strlen(user_settings_->download_path); len += strlen(user_settings_->download_path);
} }
if (len >= sizeof(friends[num].file_receiver.filenames[filenum])) { if (len >= sizeof(friends[num].file_receiver[filenum].filename)) {
errmsg = "File name too long; discarding."; errmsg = "File name too long; discarding.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
return; return;
@ -333,9 +336,9 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type '/savefile %d' to accept the file transfer.", filenum); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type '/savefile %d' to accept the file transfer.", filenum);
friends[num].file_receiver.pending[filenum] = true; friends[num].file_receiver[filenum].pending = true;
friends[num].file_receiver.size[filenum] = filesize; friends[num].file_receiver[filenum].size = filesize;
strcpy(friends[num].file_receiver.filenames[filenum], filename); strcpy(friends[num].file_receiver[filenum].filename, filename);
if (self->active_box != -1) if (self->active_box != -1)
box_notify2(self, transfer_pending, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, box_notify2(self, transfer_pending, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box,
@ -352,13 +355,21 @@ void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
if (CTRL > 0) if (CTRL > 0)
tox_file_send_control(m, friendnum, 1, filenum, CTRL, 0, 0); tox_file_send_control(m, friendnum, 1, filenum, CTRL, 0, 0);
friends[friendnum].file_receiver.active[filenum] = false; FILE *file = friends[friendnum].file_receiver[filenum].file;
friends[friendnum].file_receiver.pending[filenum] = false;
FILE *file = friends[friendnum].file_receiver.files[filenum];
if (file != NULL) { if (file != NULL)
fclose(file); fclose(file);
friends[friendnum].file_receiver.files[filenum] = NULL;
memset(&friends[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver));
}
static void close_all_file_receivers(Tox *m, int friendnum)
{
int i;
for (i = 0; i < MAX_FILES; ++i) {
if (friends[friendnum].file_receiver[i].active)
chat_close_file_receiver(m, i, friendnum, TOX_FILECONTROL_KILL);
} }
} }
@ -373,7 +384,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
int i = 0; /* file_sender index */ int i = 0; /* file_sender index */
if (receive_send == 0) { if (receive_send == 0) {
filename = friends[num].file_receiver.filenames[filenum]; filename = friends[num].file_receiver[filenum].filename;
} else { } else {
for (i = 0; i < MAX_FILES; ++i) { for (i = 0; i < MAX_FILES; ++i) {
if (file_senders[i].active && file_senders[i].filenum == filenum) if (file_senders[i].active && file_senders[i].filenum == filenum)
@ -446,7 +457,7 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
if (self->num != num) if (self->num != num)
return; return;
FILE *fp = friends[num].file_receiver.files[filenum]; FILE *fp = friends[num].file_receiver[filenum].file;
if (fp) { if (fp) {
if (fwrite(data, length, 1, fp) != 1) { if (fwrite(data, length, 1, fp) != 1) {
@ -455,17 +466,17 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
} }
} }
friends[num].file_receiver.bps[filenum] += length; friends[num].file_receiver[filenum].bps += length;
double remain = (double) tox_file_data_remaining(m, num, filenum, 1); double remain = (double) tox_file_data_remaining(m, num, filenum, 1);
uint64_t curtime = get_unix_time(); uint64_t curtime = get_unix_time();
/* refresh line with percentage complete and transfer speed (must be called once per second) */ /* 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)) { if (!remain || timed_out(friends[num].file_receiver[filenum].last_progress, curtime, 1)) {
friends[num].file_receiver.last_progress[filenum] = curtime; friends[num].file_receiver[filenum].last_progress = curtime;
uint64_t size = friends[num].file_receiver.size[filenum]; uint64_t size = friends[num].file_receiver[filenum].size;
double pct_done = remain > 0 ? (1 - (remain / size)) * 100 : 100; double pct_done = remain > 0 ? (1 - (remain / size)) * 100 : 100;
print_progress_bar(self, filenum, num, pct_done); print_progress_bar(self, filenum, num, pct_done);
friends[num].file_receiver.bps[filenum] = 0; friends[num].file_receiver[filenum].bps = 0;
} }
} }
@ -819,7 +830,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (line[0] == '/') { if (line[0] == '/') {
if (strcmp(line, "/close") == 0) { if (strcmp(line, "/close") == 0) {
kill_chat_window(self); kill_chat_window(self, m);
return; return;
} else if (strncmp(line, "/me ", strlen("/me ")) == 0) { } else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
send_action(self, ctx, m, line + strlen("/me ")); send_action(self, ctx, m, line + strlen("/me "));

View File

@ -29,7 +29,7 @@
/* set CTRL to -1 if we don't want to send a control signal. /* set CTRL to -1 if we don't want to send a control signal.
set msg to NULL if we don't want to display a message */ set msg to NULL if we don't want to display a message */
void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL); void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL);
void kill_chat_window(ToxWindow *self); void kill_chat_window(ToxWindow *self, Tox *m);
ToxWindow new_chat(Tox *m, int32_t friendnum); ToxWindow new_chat(Tox *m, int32_t friendnum);
#endif /* end of include guard: CHAT_H_6489PZ13 */ #endif /* end of include guard: CHAT_H_6489PZ13 */

View File

@ -57,12 +57,12 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
} }
if (strcasecmp(inoutstr, "in") == 0) { /* cancel an incoming file transfer */ if (strcasecmp(inoutstr, "in") == 0) { /* cancel an incoming file transfer */
if (!friends[self->num].file_receiver.active[filenum]) { if (!friends[self->num].file_receiver[filenum].active) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
return; return;
} }
const char *filepath = friends[self->num].file_receiver.filenames[filenum]; const char *filepath = friends[self->num].file_receiver[filenum].filename;
char name[MAX_STR_SIZE]; char name[MAX_STR_SIZE];
get_file_name(name, sizeof(name), filepath); get_file_name(name, sizeof(name), filepath);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer for '%s' canceled.", name); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer for '%s' canceled.", name);
@ -159,12 +159,12 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
return; return;
} }
if (!friends[self->num].file_receiver.pending[filenum]) { if (!friends[self->num].file_receiver[filenum].pending) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
return; return;
} }
const char *filename = friends[self->num].file_receiver.filenames[filenum]; const char *filename = friends[self->num].file_receiver[filenum].filename;
if (tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_ACCEPT, 0, 0) == 0) { if (tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_ACCEPT, 0, 0) == 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%d] as: '%s'", filenum, filename); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%d] as: '%s'", filenum, filename);
@ -173,9 +173,9 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
char progline[MAX_STR_SIZE]; char progline[MAX_STR_SIZE];
prep_prog_line(progline); prep_prog_line(progline);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline);
friends[self->num].file_receiver.line_id[filenum] = self->chatwin->hst->line_end->id + 2; friends[self->num].file_receiver[filenum].line_id = self->chatwin->hst->line_end->id + 2;
if ((friends[self->num].file_receiver.files[filenum] = fopen(filename, "a")) == NULL) { if ((friends[self->num].file_receiver[filenum].file = fopen(filename, "a")) == NULL) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file.");
tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
} }
@ -183,8 +183,8 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed.");
} }
friends[self->num].file_receiver.pending[filenum] = false; friends[self->num].file_receiver[filenum].pending = false;
friends[self->num].file_receiver.active[filenum] = true; friends[self->num].file_receiver[filenum].active = true;
} }
void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -241,7 +241,6 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
for (i = 0; i < MAX_FILES; ++i) { for (i = 0; i < MAX_FILES; ++i) {
if (!file_senders[i].active) { if (!file_senders[i].active) {
file_senders[i].queue_pos = num_active_file_senders;
memcpy(file_senders[i].filename, filename, namelen + 1); memcpy(file_senders[i].filename, filename, namelen + 1);
file_senders[i].active = true; file_senders[i].active = true;
file_senders[i].toxwin = self; file_senders[i].toxwin = self;
@ -252,7 +251,6 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
file_senders[i].size = filesize; file_senders[i].size = filesize;
file_senders[i].piecelen = fread(file_senders[i].nextpiece, 1, file_senders[i].piecelen = fread(file_senders[i].nextpiece, 1,
tox_file_data_size(m, self->num), file_to_send); tox_file_data_size(m, self->num), file_to_send);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Sending file [%d]: '%s'", filenum, filename); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Sending file [%d]: '%s'", filenum, filename);
++num_active_file_senders; ++num_active_file_senders;
@ -260,6 +258,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
if (i == max_file_senders_index) if (i == max_file_senders_index)
++max_file_senders_index; ++max_file_senders_index;
reset_file_sender_queue();
return; return;
} }
} }

View File

@ -66,8 +66,8 @@ void print_progress_bar(ToxWindow *self, int idx, int friendnum, double pct_done
bps = file_senders[idx].bps; bps = file_senders[idx].bps;
line_id = file_senders[idx].line_id; line_id = file_senders[idx].line_id;
} else { } else {
bps = friends[friendnum].file_receiver.bps[idx]; bps = friends[friendnum].file_receiver[idx].bps;
line_id = friends[friendnum].file_receiver.line_id[idx]; line_id = friends[friendnum].file_receiver[idx].line_id;
} }
const char *unit; const char *unit;
@ -120,6 +120,18 @@ static void set_max_file_senders_index(void)
max_file_senders_index = j; max_file_senders_index = j;
} }
/* called whenever a file sender is opened or closed */
void reset_file_sender_queue(void)
{
int i;
int pos = 0;
for (i = 0; i < max_file_senders_index; ++i) {
if (file_senders[i].active)
file_senders[i].queue_pos = pos++;
}
}
/* set CTRL to -1 if we don't want to send a control signal. /* set CTRL to -1 if we don't want to send a control signal.
set msg to NULL if we don't want to display a message */ set msg to NULL if we don't want to display a message */
void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL, int filenum, int32_t friendnum) void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL, int filenum, int32_t friendnum)
@ -133,6 +145,7 @@ void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL
fclose(file_senders[i].file); fclose(file_senders[i].file);
memset(&file_senders[i], 0, sizeof(FileSender)); memset(&file_senders[i], 0, sizeof(FileSender));
set_max_file_senders_index(); set_max_file_senders_index();
reset_file_sender_queue();
--num_active_file_senders; --num_active_file_senders;
} }
@ -170,8 +183,7 @@ static void send_file_data(ToxWindow *self, Tox *m, int i, int32_t friendnum, in
double remain = (double) tox_file_data_remaining(m, friendnum, filenum, 0); double remain = (double) tox_file_data_remaining(m, friendnum, filenum, 0);
/* refresh line with percentage complete and transfer speed (must be called once per second) */ /* refresh line with percentage complete and transfer speed (must be called once per second) */
if ( (self->chatwin != NULL && timed_out(file_senders[i].last_progress, curtime, 1)) if (timed_out(file_senders[i].last_progress, curtime, 1) || (!remain && !file_senders[i].finished)) {
|| (!remain && !file_senders[i].finished) ) {
file_senders[i].last_progress = curtime; file_senders[i].last_progress = curtime;
double pct_done = remain > 0 ? (1 - (remain / file_senders[i].size)) * 100 : 100; double pct_done = remain > 0 ? (1 - (remain / file_senders[i].size)) * 100 : 100;
print_progress_bar(self, i, -1, pct_done); print_progress_bar(self, i, -1, pct_done);
@ -218,15 +230,13 @@ void do_file_senders(Tox *m)
sound_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, NULL); sound_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, NULL);
if (self->active_box != -1) if (self->active_box != -1)
box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg);
self->active_box, "File transfer for '%s' timed out.", filename );
else else
box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg);
self->name, "File transfer for '%s' timed out.", filename );
continue; continue;
} }
file_senders[i].queue_pos = num_active_file_senders - 1;
send_file_data(self, m, i, friendnum, filenum, filename); send_file_data(self, m, i, friendnum, filenum, filename);
file_senders[i].queue_pos = num_active_file_senders - 1;
} }
} }

View File

@ -61,6 +61,9 @@ void print_progress_bar(ToxWindow *self, int idx, int friendnum, double pct_rema
set msg to NULL if we don't want to display a message */ set msg to NULL if we don't want to display a message */
void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL, int filenum, int32_t friendnum); void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL, int filenum, int32_t friendnum);
/* called whenever a file sender is opened or closed */
void reset_file_sender_queue(void);
void close_all_file_senders(Tox *m); void close_all_file_senders(Tox *m);
void do_file_senders(Tox *m); void do_file_senders(Tox *m);

View File

@ -456,7 +456,7 @@ static void delete_friend(Tox *m, int32_t f_num)
ToxWindow *toxwin = get_window_ptr(friends[f_num].chatwin); ToxWindow *toxwin = get_window_ptr(friends[f_num].chatwin);
if (toxwin != NULL) { if (toxwin != NULL) {
kill_chat_window(toxwin); kill_chat_window(toxwin, m);
set_active_window(1); /* keep friendlist focused */ set_active_window(1); /* keep friendlist focused */
} }
} }

View File

@ -30,15 +30,15 @@
#include "file_senders.h" #include "file_senders.h"
struct FileReceiver { struct FileReceiver {
char filenames[MAX_FILES][MAX_STR_SIZE]; char filename[MAX_STR_SIZE];
FILE *files[MAX_FILES]; int filenum;
bool pending[MAX_FILES]; FILE *file;
bool active[MAX_FILES]; bool pending;
uint64_t size[MAX_FILES]; bool active;
double bps[MAX_FILES]; uint64_t size;
uint64_t last_progress[MAX_FILES]; double bps;
uint32_t line_id[MAX_FILES]; uint64_t last_progress;
int filenums[MAX_FILES]; uint32_t line_id;
}; };
struct LastOnline { struct LastOnline {
@ -63,7 +63,7 @@ typedef struct {
bool logging_on; /* saves preference for friend irrespective of chat windows */ bool logging_on; /* saves preference for friend irrespective of chat windows */
uint8_t status; uint8_t status;
struct LastOnline last_online; struct LastOnline last_online;
struct FileReceiver file_receiver; struct FileReceiver file_receiver[MAX_FILES];
} ToxicFriend; } ToxicFriend;
typedef struct { typedef struct {

View File

@ -105,7 +105,7 @@ void exit_toxic_success(Tox *m)
{ {
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
close_all_file_senders(m); close_all_file_senders(m);
kill_all_windows(); kill_all_windows(m);
free(DATA_FILE); free(DATA_FILE);
free(BLOCK_FILE); free(BLOCK_FILE);

View File

@ -497,7 +497,7 @@ int get_num_active_windows(void)
} }
/* destroys all chat and groupchat windows (should only be called on shutdown) */ /* destroys all chat and groupchat windows (should only be called on shutdown) */
void kill_all_windows(void) void kill_all_windows(Tox *m)
{ {
kill_prompt_window(prompt); kill_prompt_window(prompt);
@ -505,7 +505,7 @@ void kill_all_windows(void)
for (i = 0; i < MAX_WINDOWS_NUM; ++i) { for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].is_chat) if (windows[i].is_chat)
kill_chat_window(&windows[i]); kill_chat_window(&windows[i], m);
else if (windows[i].is_groupchat) else if (windows[i].is_groupchat)
kill_groupchat_window(&windows[i]); kill_groupchat_window(&windows[i]);
} }

View File

@ -223,7 +223,7 @@ int add_window(Tox *m, ToxWindow w);
void del_window(ToxWindow *w); void del_window(ToxWindow *w);
void set_active_window(int ch); void set_active_window(int ch);
int get_num_active_windows(void); int get_num_active_windows(void);
void kill_all_windows(void); /* should only be called on shutdown */ void kill_all_windows(Tox *m); /* should only be called on shutdown */
void on_window_resize(void); void on_window_resize(void);
ToxWindow *get_window_ptr(int i); ToxWindow *get_window_ptr(int i);