1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-13 02:23:01 +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);
}
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;
StatusBar *statusbar = self->stb;
close_all_file_receivers(m, self->num);
log_disable(ctx->log);
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);
}
if (len >= sizeof(friends[num].file_receiver.filenames[filenum])) {
if (len >= sizeof(friends[num].file_receiver[filenum].filename)) {
errmsg = "File name too long; discarding.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
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);
friends[num].file_receiver.pending[filenum] = true;
friends[num].file_receiver.size[filenum] = filesize;
strcpy(friends[num].file_receiver.filenames[filenum], filename);
friends[num].file_receiver[filenum].pending = true;
friends[num].file_receiver[filenum].size = filesize;
strcpy(friends[num].file_receiver[filenum].filename, filename);
if (self->active_box != -1)
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)
tox_file_send_control(m, friendnum, 1, filenum, CTRL, 0, 0);
friends[friendnum].file_receiver.active[filenum] = false;
friends[friendnum].file_receiver.pending[filenum] = false;
FILE *file = friends[friendnum].file_receiver.files[filenum];
FILE *file = friends[friendnum].file_receiver[filenum].file;
if (file != NULL) {
if (file != NULL)
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 */
if (receive_send == 0) {
filename = friends[num].file_receiver.filenames[filenum];
filename = friends[num].file_receiver[filenum].filename;
} else {
for (i = 0; i < MAX_FILES; ++i) {
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)
return;
FILE *fp = friends[num].file_receiver.files[filenum];
FILE *fp = friends[num].file_receiver[filenum].file;
if (fp) {
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);
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];
if (!remain || timed_out(friends[num].file_receiver[filenum].last_progress, curtime, 1)) {
friends[num].file_receiver[filenum].last_progress = curtime;
uint64_t size = friends[num].file_receiver[filenum].size;
double pct_done = remain > 0 ? (1 - (remain / size)) * 100 : 100;
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 (strcmp(line, "/close") == 0) {
kill_chat_window(self);
kill_chat_window(self, m);
return;
} else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
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 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 kill_chat_window(ToxWindow *self);
void kill_chat_window(ToxWindow *self, Tox *m);
ToxWindow new_chat(Tox *m, int32_t friendnum);
#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 (!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.");
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];
get_file_name(name, sizeof(name), filepath);
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;
}
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.");
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) {
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];
prep_prog_line(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.");
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.");
}
friends[self->num].file_receiver.pending[filenum] = false;
friends[self->num].file_receiver.active[filenum] = true;
friends[self->num].file_receiver[filenum].pending = false;
friends[self->num].file_receiver[filenum].active = true;
}
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) {
if (!file_senders[i].active) {
file_senders[i].queue_pos = num_active_file_senders;
memcpy(file_senders[i].filename, filename, namelen + 1);
file_senders[i].active = true;
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].piecelen = fread(file_senders[i].nextpiece, 1,
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);
++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)
++max_file_senders_index;
reset_file_sender_queue();
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;
line_id = file_senders[idx].line_id;
} else {
bps = friends[friendnum].file_receiver.bps[idx];
line_id = friends[friendnum].file_receiver.line_id[idx];
bps = friends[friendnum].file_receiver[idx].bps;
line_id = friends[friendnum].file_receiver[idx].line_id;
}
const char *unit;
@ -120,6 +120,18 @@ static void set_max_file_senders_index(void)
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 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)
@ -133,6 +145,7 @@ void close_file_sender(ToxWindow *self, Tox *m, int i, const char *msg, int CTRL
fclose(file_senders[i].file);
memset(&file_senders[i], 0, sizeof(FileSender));
set_max_file_senders_index();
reset_file_sender_queue();
--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);
/* 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))
|| (!remain && !file_senders[i].finished) ) {
if (timed_out(file_senders[i].last_progress, curtime, 1) || (!remain && !file_senders[i].finished)) {
file_senders[i].last_progress = curtime;
double pct_done = remain > 0 ? (1 - (remain / file_senders[i].size)) * 100 : 100;
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);
if (self->active_box != -1)
box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2,
self->active_box, "File transfer for '%s' timed out.", filename );
box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg);
else
box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box,
self->name, "File transfer for '%s' timed out.", filename );
box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg);
continue;
}
file_senders[i].queue_pos = num_active_file_senders - 1;
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 */
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 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);
if (toxwin != NULL) {
kill_chat_window(toxwin);
kill_chat_window(toxwin, m);
set_active_window(1); /* keep friendlist focused */
}
}

View File

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

View File

@ -105,7 +105,7 @@ void exit_toxic_success(Tox *m)
{
store_data(m, DATA_FILE);
close_all_file_senders(m);
kill_all_windows();
kill_all_windows(m);
free(DATA_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) */
void kill_all_windows(void)
void kill_all_windows(Tox *m)
{
kill_prompt_window(prompt);
@ -505,7 +505,7 @@ void kill_all_windows(void)
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].is_chat)
kill_chat_window(&windows[i]);
kill_chat_window(&windows[i], m);
else if (windows[i].is_groupchat)
kill_groupchat_window(&windows[i]);
}

View File

@ -223,7 +223,7 @@ int add_window(Tox *m, ToxWindow w);
void del_window(ToxWindow *w);
void set_active_window(int ch);
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);
ToxWindow *get_window_ptr(int i);