From 12c880ab51394e5a6c344679c67052819f48d7aa Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sun, 29 Mar 2015 19:05:24 -0400 Subject: [PATCH] fix bootstrapping --- src/file_senders.c | 297 ------------------------------------------- src/file_senders.h | 76 ----------- src/file_transfers.c | 2 +- src/file_transfers.h | 4 +- src/toxic.c | 36 +++++- 5 files changed, 35 insertions(+), 380 deletions(-) delete mode 100644 src/file_senders.c delete mode 100644 src/file_senders.h diff --git a/src/file_senders.c b/src/file_senders.c deleted file mode 100644 index 41eb7e1..0000000 --- a/src/file_senders.c +++ /dev/null @@ -1,297 +0,0 @@ -/* file_senders.c - * - * - * Copyright (C) 2014 Toxic All Rights Reserved. - * - * This file is part of Toxic. - * - * Toxic is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Toxic is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Toxic. If not, see . - * - */ - -#include -#include -#include -#include - -#include "toxic.h" -#include "windows.h" -#include "friendlist.h" -#include "file_senders.h" -#include "line_info.h" -#include "misc_tools.h" -#include "notify.h" - -FileSender file_senders[MAX_FILES]; -uint8_t max_file_senders_index; -uint8_t num_active_file_senders; -extern FriendsList Friends; - -#define NUM_PROG_MARKS 50 /* number of "#"'s in file transfer progress bar. Keep well below MAX_STR_SIZE */ - -/* creates initial progress line that will be updated during file transfer. - Assumes progline is of size MAX_STR_SIZE */ -void prep_prog_line(char *progline) -{ - strcpy(progline, "0.0 B/s ["); - int i; - - for (i = 0; i < NUM_PROG_MARKS; ++i) - strcat(progline, "-"); - - strcat(progline, "] 0%"); -} - -/* prints a progress bar for file transfers. - if friendnum is -1 we're sending the file, otherwise we're receiving. */ -void print_progress_bar(ToxWindow *self, int idx, int friendnum, double pct_done) -{ - double bps; - uint32_t line_id; - - if (friendnum < 0) { - bps = file_senders[idx].bps; - line_id = file_senders[idx].line_id; - } else { - bps = Friends.list[friendnum].file_receiver[idx].bps; - line_id = Friends.list[friendnum].file_receiver[idx].line_id; - } - - char msg[MAX_STR_SIZE]; - bytes_convert_str(msg, sizeof(msg), bps); - strcat(msg, "/s ["); - - int n = pct_done / (100 / NUM_PROG_MARKS); - int i, j; - - for (i = 0; i < n; ++i) - strcat(msg, "#"); - - for (j = i; j < NUM_PROG_MARKS; ++j) - strcat(msg, "-"); - - strcat(msg, "] "); - - char pctstr[16]; - const char *frmt = pct_done == 100 ? "%.f%%" : "%.1f%%"; - snprintf(pctstr, sizeof(pctstr), frmt, pct_done); - strcat(msg, pctstr); - - line_info_set(self, line_id, msg); -} - -/* refreshes active file receiver status bars */ -static void refresh_recv_prog(Tox *m) -{ - int i; - uint64_t curtime = get_unix_time(); - - for (i = 2; i < MAX_WINDOWS_NUM; ++i) { - ToxWindow *toxwin = get_window_ptr(i); - - if (toxwin == NULL || !toxwin->is_chat) - continue; - - int fnum = toxwin->num; - int j; - - for (j = 0; j < MAX_FILES; ++j) { - if (!Friends.list[fnum].file_receiver[j].active) - continue; - - int filenum = Friends.list[fnum].file_receiver[j].filenum; - double remain = (double) tox_file_data_remaining(m, fnum, filenum, 1); - - /* must be called once per second */ - if (timed_out(Friends.list[fnum].file_receiver[filenum].last_progress, curtime, 1)) { - Friends.list[fnum].file_receiver[filenum].last_progress = curtime; - uint64_t size = Friends.list[fnum].file_receiver[filenum].size; - double pct_done = remain > 0 ? (1 - (remain / size)) * 100 : 100; - print_progress_bar(toxwin, filenum, fnum, pct_done); - Friends.list[fnum].file_receiver[filenum].bps = 0; - } - } - } -} - -/* refreshes active file sender status bars */ -static void refresh_sender_prog(Tox *m) -{ - int i; - uint64_t curtime = get_unix_time(); - - for (i = 0; i < max_file_senders_index; ++i) { - if (!file_senders[i].active || file_senders[i].finished) - continue; - - int filenum = file_senders[i].filenum; - uint32_t friendnum = file_senders[i].friendnum; - double remain = (double) tox_file_data_remaining(m, friendnum, filenum, 0); - - /* must be called once per second */ - if (timed_out(file_senders[i].last_progress, curtime, 1)) { - file_senders[i].last_progress = curtime; - double pct_done = remain > 0 ? (1 - (remain / file_senders[i].size)) * 100 : 100; - print_progress_bar(file_senders[i].toxwin, i, -1, pct_done); - file_senders[i].bps = 0; - } - } -} - -static void set_max_file_senders_index(void) -{ - int j; - - for (j = max_file_senders_index; j > 0; --j) { - if (file_senders[j - 1].active) - break; - } - - 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, uint32_t friendnum) -{ - if (msg != NULL) - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", msg); - - if (CTRL > 0) - tox_file_send_control(m, friendnum, 0, filenum, CTRL, 0, 0); - - 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; -} - -void close_all_file_senders(Tox *m) -{ - uint8_t i; - - for (i = 0; i < max_file_senders_index; ++i) { - if (file_senders[i].active) { - fclose(file_senders[i].file); - tox_file_send_control(m, file_senders[i].friendnum, 0, file_senders[i].filenum, - TOX_FILECONTROL_KILL, 0, 0); - memset(&file_senders[i], 0, sizeof(FileSender)); - } - - set_max_file_senders_index(); - } -} - -static void send_file_data(ToxWindow *self, Tox *m, uint8_t i, uint32_t friendnum, uint32_t filenum, - const char *filename) -{ - FILE *fp = file_senders[i].file; - - while (true) { - TOX_ERR_FILE_SEND_CHUNK err; - if (!tox_file_send_chunk(m, friendnum, filenum, (uint8_t *) file_senders[i].nextpiece, - file_senders[i].piecelen, &err) { - fprintf(stderr, "tox_file_send_chunk failed with error %d\n", err); - return; - } - - file_senders[i].timestamp = get_unix_time(); - file_senders[i].bps += file_senders[i].piecelen; - file_senders[i].piecelen = fread(file_senders[i].nextpiece, 1, - tox_file_data_size(m, friendnum), fp); - - /* note: file sender is closed in chat_onFileControl callback after receiving reply */ - if (file_senders[i].piecelen == 0) { - if (feof(fp) != 0) { /* make sure we're really at eof */ - print_progress_bar(self, i, -1, 100.0); - tox_file_send_control(m, friendnum, 0, filenum, TOX_FILECONTROL_FINISHED, 0, 0); - file_senders[i].finished = true; - } else { - char msg[MAX_STR_SIZE]; - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Read error.", file_senders[i].filename); - close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum); - 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, "%s", msg); - else - box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg); - } - - return; - } - } -} - -void do_file_senders(Tox *m) -{ - int i; - - for (i = 0; i < max_file_senders_index; ++i) { - if (!file_senders[i].active) - continue; - - if (file_senders[i].queue_pos > 0) { - --file_senders[i].queue_pos; - continue; - } - - ToxWindow *self = file_senders[i].toxwin; - char *filename = file_senders[i].filename; - int filenum = file_senders[i].filenum; - uint32_t friendnum = file_senders[i].friendnum; - - /* kill file transfer if chatwindow is closed */ - if (self->chatwin == NULL) { - close_file_sender(self, m, i, NULL, TOX_FILECONTROL_KILL, filenum, friendnum); - continue; - } - - /* If file transfer has timed out kill transfer and send kill control */ - if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER) - && (!file_senders[i].paused || (file_senders[i].paused && file_senders[i].noconnection))) { - char msg[MAX_STR_SIZE]; - snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", filename); - close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum); - - if (self->active_box != -1) - 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, "%s", msg); - - continue; - } - - if ( !(file_senders[i].paused | file_senders[i].noconnection | file_senders[i].finished) ) - send_file_data(self, m, i, friendnum, filenum, filename); - - file_senders[i].queue_pos = num_active_file_senders - 1; - } - - refresh_sender_prog(m); - refresh_recv_prog(m); -} diff --git a/src/file_senders.h b/src/file_senders.h deleted file mode 100644 index 2c46bce..0000000 --- a/src/file_senders.h +++ /dev/null @@ -1,76 +0,0 @@ -/* file_senders.h - * - * - * Copyright (C) 2014 Toxic All Rights Reserved. - * - * This file is part of Toxic. - * - * Toxic is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Toxic is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Toxic. If not, see . - * - */ - -#ifndef FILESENDERS_H -#define FILESENDERS_H - -#include "toxic.h" -#include "windows.h" - -#define KiB 1024 -#define MiB 1048576 /* 1024 ^ 2 */ -#define GiB 1073741824 /* 1024 ^ 3 */ - -#define FILE_PIECE_SIZE 2048 /* must be >= (MAX_CRYPTO_DATA_SIZE - 2) in toxcore/net_crypto.h */ -#define MAX_FILES 32 -#define TIMEOUT_FILESENDER 120 - -typedef struct { - FILE *file; - ToxWindow *toxwin; - uint32_t friendnum; - bool active; - bool noconnection; /* set when the connection has been interrupted */ - bool paused; /* set when transfer has been explicitly paused */ - bool finished; /* set after entire file has been sent but no TOX_FILECONTROL_FINISHED receieved */ - bool started; /* set after TOX_FILECONTROL_ACCEPT received */ - int filenum; - char nextpiece[FILE_PIECE_SIZE]; - size_t piecelen; - char filename[MAX_STR_SIZE]; - uint64_t timestamp; /* marks the last time data was successfully transfered */ - uint64_t last_progress; /* marks the last time the progress bar was refreshed */ - double bps; - uint64_t size; - uint32_t line_id; - uint8_t queue_pos; -} FileSender; - -/* creates initial progress line that will be updated during file transfer. - Assumes progline is of size MAX_STR_SIZE */ -void prep_prog_line(char *progline); - -/* prints a progress bar for file transfers. - if friendnum is -1 we're sending the file, otherwise we're receiving. */ -void print_progress_bar(ToxWindow *self, int idx, int friendnum, double pct_remain); - -/* 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); - -/* 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); - -#endif /* #define FILESENDERS_H */ diff --git a/src/file_transfers.c b/src/file_transfers.c index 8be40f0..1b49ced 100644 --- a/src/file_transfers.c +++ b/src/file_transfers.c @@ -131,7 +131,7 @@ struct FileTransfer *get_file_transfer_struct(uint32_t friendnum, uint32_t filen return NULL; } -/* Returns a pointer to friendnum's file receiver associated with index with the direction specified. +/* Returns a pointer to the FileTransfer struct associated with index with the direction specified. * Returns NULL on failure. */ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnum, uint32_t index, diff --git a/src/file_transfers.h b/src/file_transfers.h index b71a3d1..ba12886 100644 --- a/src/file_transfers.h +++ b/src/file_transfers.h @@ -71,7 +71,7 @@ void prep_prog_line(char *progline); /* prints a progress bar for file transfers */ void print_progress_bar(ToxWindow *self, double pct_done, double bps, uint32_t line_id); -/* refreshes active file receiver status bars for friendnum */ +/* refreshes active file transfer status bars for friendnum */ void refresh_file_transfer_progress(ToxWindow *self, Tox *m, uint32_t friendnum); /* Returns a pointer to friendnum's FileTransfer struct associated with filenum. @@ -80,7 +80,7 @@ void refresh_file_transfer_progress(ToxWindow *self, Tox *m, uint32_t friendnum) struct FileTransfer *get_file_transfer_struct(uint32_t friendnum, uint32_t filenum); -/* Returns a pointer to friendnum's file receiver associated with index with the direction specified. +/* Returns a pointer to the FileTransfer struct associated with index with the direction specified. * Returns NULL on failure. */ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnum, uint32_t index, diff --git a/src/toxic.c b/src/toxic.c index 64896ee..dacc12a 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -685,13 +685,38 @@ static Tox *load_toxic(char *data_path) return m; } +#define TRY_BOOTSTRAP_INTERVAL 5 +static uint64_t last_bootstrap_time = 0; + +static void do_bootstrap(Tox *m) +{ + static int conn_err = 0; + uint64_t curtime = get_unix_time(); + + if (!timed_out(last_bootstrap_time, curtime, TRY_BOOTSTRAP_INTERVAL)) + return; + + if (tox_self_get_connection_status(m) != TOX_CONNECTION_NONE) + return; + + if (conn_err != 0) + return; + + last_bootstrap_time = curtime; + conn_err = init_connection(m); + + if (conn_err != 0) + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Auto-connect failed with error code %d", conn_err); +} + static void do_toxic(Tox *m, ToxWindow *prompt) { + if (arg_opts.no_connect) + return; + pthread_mutex_lock(&Winthread.lock); - - if (arg_opts.no_connect == 0) - tox_iterate(m); /* main toxcore loop */ - + tox_iterate(m); + do_bootstrap(m); pthread_mutex_unlock(&Winthread.lock); } @@ -998,6 +1023,9 @@ int main(int argc, char *argv[]) int config_err = init_default_data_files(); bool datafile_exists = file_exists(DATA_FILE); + if (datafile_exists) + last_bootstrap_time = get_unix_time(); + if (!datafile_exists && !arg_opts.unencrypt_data) first_time_encrypt("Creating new data file. Would you like to encrypt it? Y/n (q to quit)"); else if (arg_opts.encrypt_data)