From ee509a7cec11b561302aa8d126f21e76b6040f04 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Thu, 14 Nov 2013 19:14:54 -0500 Subject: [PATCH] add file sender timeouts --- src/chat.c | 1 + src/chat_commands.c | 1 + src/friendlist.c | 13 ++++++----- src/main.c | 53 ++++++++++++++++++++++++++++++--------------- src/misc_tools.c | 6 +++++ src/misc_tools.h | 3 +++ src/toxic_windows.h | 6 +++-- 7 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/chat.c b/src/chat.c index 5c14774..b6693f4 100644 --- a/src/chat.c +++ b/src/chat.c @@ -181,6 +181,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int num, uint8_t receive break; case TOX_FILECONTROL_KILL: wprintw(ctx->history, "File transfer for '%s' failed.\n", filename); + friends[num].file_receiver.pending[filenum] = false; break; case TOX_FILECONTROL_FINISHED: wprintw(ctx->history, "File transfer for '%s' complete.\n", filename); diff --git a/src/chat_commands.c b/src/chat_commands.c index f360653..63e3d78 100644 --- a/src/chat_commands.c +++ b/src/chat_commands.c @@ -168,6 +168,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *prompt, Tox *m, int num, int argc, file_senders[i].file = file_to_send; file_senders[i].filenum = (uint8_t) filenum; file_senders[i].friendnum = num; + file_senders[i].timestamp = (uint64_t)time(NULL); file_senders[i].piecelen = fread(file_senders[i].nextpiece, 1, tox_filedata_size(m, num), file_to_send); diff --git a/src/friendlist.c b/src/friendlist.c index d22ab6f..d10461c 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -34,12 +34,13 @@ void sort_friendlist_index(void) /* split friends into online and offline groups */ for (i = 0; i < max_friends_index; ++i) { - if (friends[i].active) { - if (friends[i].online) - on_friends[on_cnt++] = friends[i].num; - else - off_friends[off_cnt++] = friends[i].num; - } + if (!friends[i].active) + continue; + + if (friends[i].online) + on_friends[on_cnt++] = friends[i].num; + else + off_friends[off_cnt++] = friends[i].num; } /* update friendlist_index, putting online friends before offline friends */ diff --git a/src/main.c b/src/main.c index 682e850..0da1a3f 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -347,7 +348,23 @@ static void load_data(Tox *m, char *path) } } -void do_file_senders(Tox *m) +static void close_file_sender(Tox *m, int i) +{ + fclose(file_senders[i].file); + memset(&file_senders[i], 0, sizeof(FileSender)); + + int j; + + for (j = num_file_senders; j > 0; --j) { + if (file_senders[j-1].active) + break; + } + + num_file_senders = j; + return; +} + +static void do_file_senders(Tox *m) { int i; @@ -356,33 +373,33 @@ void do_file_senders(Tox *m) continue; while (true) { + uint8_t *pathname = file_senders[i].pathname; uint8_t filenum = file_senders[i].filenum; + uint64_t current_time = (uint64_t)time(NULL); int friendnum = file_senders[i].friendnum; if (!tox_file_senddata(m, friendnum, filenum, file_senders[i].nextpiece, - file_senders[i].piecelen)) - return; + file_senders[i].piecelen)) { + /* If file transfer has timed out kill transfer and send kill control */ + if (timed_out(file_senders[i].timestamp, current_time, TIMEOUT_FILESENDER)) { + wprintw(file_senders[i].chatwin, "File transfer for '%s' timed out.\n", + pathname); + tox_file_sendcontrol(m, friendnum, 0, filenum, TOX_FILECONTROL_KILL, 0, 0); + close_file_sender(m, i); + } + + return; + } + + file_senders[i].timestamp = current_time; file_senders[i].piecelen = fread(file_senders[i].nextpiece, 1, tox_filedata_size(m, friendnum), file_senders[i].file); if (file_senders[i].piecelen == 0) { - fclose(file_senders[i].file); - memset(&file_senders[i], 0, sizeof(FileSender)); - - tox_file_sendcontrol(m, friendnum, 0, filenum, TOX_FILECONTROL_FINISHED, 0, 0); - - uint8_t *pathname = file_senders[i].pathname; wprintw(file_senders[i].chatwin, "File '%s' successfuly sent.\n", pathname); - - int i; - - for (i = num_file_senders; i > 0; --i) { - if (file_senders[i-1].active) - break; - } - - num_file_senders = i; + tox_file_sendcontrol(m, friendnum, 0, filenum, TOX_FILECONTROL_FINISHED, 0, 0); + close_file_sender(m, i); return; } } diff --git a/src/misc_tools.c b/src/misc_tools.c index 5d8007c..bdccadf 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -100,3 +100,9 @@ char *wc_to_char(wchar_t ch) return ret; } + +/* Returns true if connection has timed out, false otherwise */ +bool timed_out(uint64_t timestamp, uint64_t curtime, uint64_t timeout) +{ + return timestamp + timeout <= curtime; +} \ No newline at end of file diff --git a/src/misc_tools.h b/src/misc_tools.h index 6a1254e..dec1bd1 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -19,3 +19,6 @@ uint8_t *wcs_to_char(wchar_t *string); /* convert a wide char to null terminated string */ char *wc_to_char(wchar_t ch); + +/* Returns true if connection has timed out, false otherwise */ +bool timed_out(uint64_t timestamp, uint64_t timeout, uint64_t curtime); \ No newline at end of file diff --git a/src/toxic_windows.h b/src/toxic_windows.h index 24bda56..dc56d03 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -101,6 +101,7 @@ typedef struct { #define MAX_FILES 256 #define FILE_PIECE_SIZE 1024 +#define TIMEOUT_FILESENDER 300 typedef struct { FILE *file; @@ -111,14 +112,15 @@ typedef struct { uint8_t nextpiece[FILE_PIECE_SIZE]; uint16_t piecelen; uint8_t pathname[MAX_STR_SIZE]; + uint64_t timestamp; } FileSender; FileSender file_senders[MAX_FILES]; uint8_t num_file_senders; typedef struct { - uint8_t filenames[MAX_FILES][MAX_STR_SIZE]; - bool pending[MAX_FILES]; + uint8_t filenames[MAX_FILES][MAX_STR_SIZE]; + bool pending[MAX_FILES]; } FileReceiver; /* End file transfer code */