mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-22 20:33:02 +01:00
Implement file transfer queue for offline friends
File transfers initiated for offline friends are now added to a queue and initiated all at once when the friend appears online.
This commit is contained in:
parent
8d58e8f4d6
commit
6f8f6f0ac5
@ -248,6 +248,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, Tox_C
|
|||||||
|
|
||||||
if (prev_status == TOX_CONNECTION_NONE) {
|
if (prev_status == TOX_CONNECTION_NONE) {
|
||||||
chat_resume_file_senders(self, m, num);
|
chat_resume_file_senders(self, m, num);
|
||||||
|
file_send_queue_check(self, m, self->num);
|
||||||
|
|
||||||
msg = "has come online";
|
msg = "has come online";
|
||||||
line_info_add(self, true, nick, NULL, CONNECTION, 0, GREEN, msg);
|
line_info_add(self, true, nick, NULL, CONNECTION, 0, GREEN, msg);
|
||||||
|
@ -54,7 +54,13 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileTransfer *ft = NULL;
|
// first check transfer queue
|
||||||
|
if (file_send_queue_remove(self->num, idx) == 0) {
|
||||||
|
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Pending file transfer removed from queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTransfer *ft = NULL;
|
||||||
|
|
||||||
/* cancel an incoming file transfer */
|
/* cancel an incoming file transfer */
|
||||||
if (strcasecmp(inoutstr, "in") == 0) {
|
if (strcasecmp(inoutstr, "in") == 0) {
|
||||||
@ -239,7 +245,7 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
|
FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
|
||||||
|
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
|
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
|
||||||
@ -324,7 +330,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
FILE *file_to_send = fopen(path, "r");
|
FILE *file_to_send = fopen(path, "r");
|
||||||
|
|
||||||
if (file_to_send == NULL) {
|
if (file_to_send == NULL) {
|
||||||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File not found.");
|
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File `%s` not found.", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +353,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
goto on_send_error;
|
goto on_send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
|
FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
|
||||||
|
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
err = TOX_ERR_FILE_SEND_TOO_MANY;
|
err = TOX_ERR_FILE_SEND_TOO_MANY;
|
||||||
@ -367,29 +373,62 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
|
|
||||||
on_send_error:
|
on_send_error:
|
||||||
|
|
||||||
|
fclose(file_to_send);
|
||||||
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND:
|
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: {
|
||||||
errmsg = "File transfer failed: Invalid friend.";
|
errmsg = "File transfer failed: Invalid friend.";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED:
|
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: {
|
||||||
errmsg = "File transfer failed: Friend is offline.";
|
int queue_idx = file_send_queue_add(self->num, path, path_len);
|
||||||
|
|
||||||
|
char msg[MAX_STR_SIZE];
|
||||||
|
|
||||||
|
switch (queue_idx) {
|
||||||
|
case -1: {
|
||||||
|
snprintf(msg, sizeof(msg), "Invalid file name: path is null or length is zero.");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TOX_ERR_FILE_SEND_NAME_TOO_LONG:
|
case -2: {
|
||||||
|
snprintf(msg, sizeof(msg), "File name is too long.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -3: {
|
||||||
|
snprintf(msg, sizeof(msg), "File send queue is full.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
snprintf(msg, sizeof(msg), "File transfer queued. Type \"/cancel out %d\" to cancel.", queue_idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOX_ERR_FILE_SEND_NAME_TOO_LONG: {
|
||||||
errmsg = "File transfer failed: Filename is too long.";
|
errmsg = "File transfer failed: Filename is too long.";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TOX_ERR_FILE_SEND_TOO_MANY:
|
case TOX_ERR_FILE_SEND_TOO_MANY: {
|
||||||
errmsg = "File transfer failed: Too many concurrent file transfers.";
|
errmsg = "File transfer failed: Too many concurrent file transfers.";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
errmsg = "File transfer failed.";
|
errmsg = "File transfer failed.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", errmsg);
|
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", errmsg);
|
||||||
tox_file_control(m, self->num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
tox_file_control(m, self->num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
||||||
fclose(file_to_send);
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "execute.h"
|
||||||
#include "file_transfers.h"
|
#include "file_transfers.h"
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
@ -98,7 +99,7 @@ void print_progress_bar(ToxWindow *self, double bps, double pct_done, uint32_t l
|
|||||||
free(full_line);
|
free(full_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void refresh_progress_helper(ToxWindow *self, struct FileTransfer *ft)
|
static void refresh_progress_helper(ToxWindow *self, FileTransfer *ft)
|
||||||
{
|
{
|
||||||
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
||||||
return;
|
return;
|
||||||
@ -126,8 +127,8 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
|
|||||||
bool active = false;
|
bool active = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
|
FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
|
||||||
struct FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
|
FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
|
||||||
|
|
||||||
refresh_progress_helper(self, ft_r);
|
refresh_progress_helper(self, ft_r);
|
||||||
refresh_progress_helper(self, ft_s);
|
refresh_progress_helper(self, ft_s);
|
||||||
@ -140,9 +141,9 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
|
|||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_file_transfer(struct FileTransfer *ft)
|
static void clear_file_transfer(FileTransfer *ft)
|
||||||
{
|
{
|
||||||
*ft = (struct FileTransfer) {
|
*ft = (FileTransfer) {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -150,16 +151,16 @@ static void clear_file_transfer(struct FileTransfer *ft)
|
|||||||
/* Returns a pointer to friendnumber's FileTransfer struct associated with filenumber.
|
/* Returns a pointer to friendnumber's FileTransfer struct associated with filenumber.
|
||||||
* Returns NULL if filenumber is invalid.
|
* Returns NULL if filenumber is invalid.
|
||||||
*/
|
*/
|
||||||
struct FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
|
FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
|
FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
|
||||||
|
|
||||||
if (ft_send->state != FILE_TRANSFER_INACTIVE && ft_send->filenumber == filenumber) {
|
if (ft_send->state != FILE_TRANSFER_INACTIVE && ft_send->filenumber == filenumber) {
|
||||||
return ft_send;
|
return ft_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
|
FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
|
||||||
|
|
||||||
if (ft_recv->state != FILE_TRANSFER_INACTIVE && ft_recv->filenumber == filenumber) {
|
if (ft_recv->state != FILE_TRANSFER_INACTIVE && ft_recv->filenumber == filenumber) {
|
||||||
return ft_recv;
|
return ft_recv;
|
||||||
@ -172,7 +173,7 @@ struct FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t fi
|
|||||||
/* Returns a pointer to the FileTransfer struct 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.
|
* Returns NULL on failure.
|
||||||
*/
|
*/
|
||||||
struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
|
FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
|
||||||
FILE_TRANSFER_DIRECTION direction)
|
FILE_TRANSFER_DIRECTION direction)
|
||||||
{
|
{
|
||||||
if (direction != FILE_TRANSFER_RECV && direction != FILE_TRANSFER_SEND) {
|
if (direction != FILE_TRANSFER_RECV && direction != FILE_TRANSFER_SEND) {
|
||||||
@ -180,7 +181,7 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
|
FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
|
||||||
&Friends.list[friendnumber].file_sender[i] :
|
&Friends.list[friendnumber].file_sender[i] :
|
||||||
&Friends.list[friendnumber].file_receiver[i];
|
&Friends.list[friendnumber].file_receiver[i];
|
||||||
|
|
||||||
@ -195,10 +196,10 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
|
|||||||
/* Returns a pointer to an unused file sender.
|
/* Returns a pointer to an unused file sender.
|
||||||
* Returns NULL if all file senders are in use.
|
* Returns NULL if all file senders are in use.
|
||||||
*/
|
*/
|
||||||
static struct FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
|
static FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
|
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
|
||||||
|
|
||||||
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
||||||
clear_file_transfer(ft);
|
clear_file_transfer(ft);
|
||||||
@ -218,11 +219,11 @@ static struct FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnu
|
|||||||
/* Returns a pointer to an unused file receiver.
|
/* Returns a pointer to an unused file receiver.
|
||||||
* Returns NULL if all file receivers are in use.
|
* Returns NULL if all file receivers are in use.
|
||||||
*/
|
*/
|
||||||
static struct FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
static FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
||||||
uint8_t type)
|
uint8_t type)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
|
FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
|
||||||
|
|
||||||
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
if (ft->state == FILE_TRANSFER_INACTIVE) {
|
||||||
clear_file_transfer(ft);
|
clear_file_transfer(ft);
|
||||||
@ -242,7 +243,7 @@ static struct FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friend
|
|||||||
/* Initializes an unused file transfer and returns its pointer.
|
/* Initializes an unused file transfer and returns its pointer.
|
||||||
* Returns NULL on failure.
|
* Returns NULL on failure.
|
||||||
*/
|
*/
|
||||||
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
||||||
FILE_TRANSFER_DIRECTION direction, uint8_t type)
|
FILE_TRANSFER_DIRECTION direction, uint8_t type)
|
||||||
{
|
{
|
||||||
if (direction == FILE_TRANSFER_RECV) {
|
if (direction == FILE_TRANSFER_RECV) {
|
||||||
@ -256,13 +257,83 @@ struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length)
|
||||||
|
{
|
||||||
|
if (length == 0 || file_path == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > TOX_MAX_FILENAME_LENGTH) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
|
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
|
||||||
|
|
||||||
|
if (pending_slot->pending) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pending_slot->pending = true;
|
||||||
|
|
||||||
|
memcpy(pending_slot->file_path, file_path, length);
|
||||||
|
pending_slot->file_path[length] = 0;
|
||||||
|
pending_slot->length = length;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FILE_TRANSFER_SEND_CMD "/sendfile "
|
||||||
|
#define FILE_TRANSFER_SEND_LEN (sizeof(FILE_TRANSFER_SEND_CMD) - 1)
|
||||||
|
|
||||||
|
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
|
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
|
||||||
|
|
||||||
|
if (!pending_slot->pending) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char command[TOX_MAX_FILENAME_LENGTH + FILE_TRANSFER_SEND_LEN + 1];
|
||||||
|
snprintf(command, sizeof(command), "%s%s", FILE_TRANSFER_SEND_CMD, pending_slot->file_path);
|
||||||
|
|
||||||
|
execute(self->window, self, m, command, CHAT_COMMAND_MODE);
|
||||||
|
|
||||||
|
*pending_slot = (PendingFileTransfer) {
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int file_send_queue_remove(uint32_t friendnumber, size_t index)
|
||||||
|
{
|
||||||
|
if (index >= MAX_FILES) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[index];
|
||||||
|
|
||||||
|
if (!pending_slot->pending) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pending_slot = (PendingFileTransfer) {
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Closes file transfer ft.
|
/* Closes file transfer ft.
|
||||||
*
|
*
|
||||||
* 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 message or self to NULL if we don't want to display a message.
|
* Set message or self to NULL if we don't want to display a message.
|
||||||
*/
|
*/
|
||||||
void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int CTRL, const char *message,
|
void close_file_transfer(ToxWindow *self, Tox *m, FileTransfer *ft, int CTRL, const char *message,
|
||||||
Notification sound_type)
|
Notification sound_type)
|
||||||
{
|
{
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
@ -298,7 +369,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C
|
|||||||
void kill_avatar_file_transfers_friend(Tox *m, uint32_t friendnumber)
|
void kill_avatar_file_transfers_friend(Tox *m, uint32_t friendnumber)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
|
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
|
||||||
|
|
||||||
if (ft->file_type == TOX_FILE_KIND_AVATAR) {
|
if (ft->file_type == TOX_FILE_KIND_AVATAR) {
|
||||||
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
||||||
@ -312,6 +383,7 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber)
|
|||||||
for (size_t i = 0; i < MAX_FILES; ++i) {
|
for (size_t i = 0; i < MAX_FILES; ++i) {
|
||||||
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_sender[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_sender[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
||||||
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_receiver[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_receiver[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
||||||
|
file_send_queue_remove(friendnumber, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@
|
|||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|
||||||
#define KiB 1024
|
#define KiB (uint32_t) 1024
|
||||||
#define MiB 1048576 /* 1024^2 */
|
#define MiB (uint32_t) (1024 << 10) /* 1024^2 */
|
||||||
#define GiB 1073741824 /* 1024^3 */
|
#define GiB (uint32_t) (1024 << 20) /* 1024^3 */
|
||||||
|
|
||||||
#define MAX_FILES 32
|
#define MAX_FILES 32
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ typedef enum FILE_TRANSFER_DIRECTION {
|
|||||||
FILE_TRANSFER_RECV
|
FILE_TRANSFER_RECV
|
||||||
} FILE_TRANSFER_DIRECTION;
|
} FILE_TRANSFER_DIRECTION;
|
||||||
|
|
||||||
struct FileTransfer {
|
typedef struct FileTransfer {
|
||||||
ToxWindow *window;
|
ToxWindow *window;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
FILE_TRANSFER_STATE state;
|
FILE_TRANSFER_STATE state;
|
||||||
@ -63,7 +63,15 @@ struct FileTransfer {
|
|||||||
time_t last_line_progress; /* The last time we updated the progress bar */
|
time_t last_line_progress; /* The last time we updated the progress bar */
|
||||||
uint32_t line_id;
|
uint32_t line_id;
|
||||||
uint8_t file_id[TOX_FILE_ID_LENGTH];
|
uint8_t file_id[TOX_FILE_ID_LENGTH];
|
||||||
};
|
} FileTransfer;
|
||||||
|
|
||||||
|
typedef struct PendingFileTransfer {
|
||||||
|
char file_path[TOX_MAX_FILENAME_LENGTH + 1];
|
||||||
|
size_t length;
|
||||||
|
uint32_t friendnumber;
|
||||||
|
bool pending;
|
||||||
|
} PendingFileTransfer;
|
||||||
|
|
||||||
|
|
||||||
/* creates initial progress line that will be updated during file transfer.
|
/* creates initial progress line that will be updated during file transfer.
|
||||||
progline must be at lesat MAX_STR_SIZE bytes */
|
progline must be at lesat MAX_STR_SIZE bytes */
|
||||||
@ -96,6 +104,31 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
|
|||||||
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
|
||||||
FILE_TRANSFER_DIRECTION direction, uint8_t type);
|
FILE_TRANSFER_DIRECTION direction, uint8_t type);
|
||||||
|
|
||||||
|
/* Adds a file designated by `file_path` of length `length` to the file transfer queue.
|
||||||
|
*
|
||||||
|
* Items in this queue will be automatically sent to the contact designated by `friendnumber`
|
||||||
|
* as soon as they appear online. The item will then be removed from the queue whether
|
||||||
|
* or not the transfer successfully initiates.
|
||||||
|
*
|
||||||
|
* If the ToxWindow associated with this friend is closed, all queued items will be
|
||||||
|
* discarded.
|
||||||
|
*
|
||||||
|
* Return the queue index on success.
|
||||||
|
* Return -1 if the length is invalid.
|
||||||
|
* Return -2 if the send queue is full.
|
||||||
|
*/
|
||||||
|
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length);
|
||||||
|
|
||||||
|
/* Initiates all file transfers from the file send queue for friend designated by `friendnumber`. */
|
||||||
|
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber);
|
||||||
|
|
||||||
|
/* Removes the `index`-th item from the file send queue for `friendnumber`.
|
||||||
|
*
|
||||||
|
* Return 0 if a pending transfer was successfully removed
|
||||||
|
* Return -1 if index does not designate a pending file transfer.
|
||||||
|
*/
|
||||||
|
int file_send_queue_remove(uint32_t friendnumber, size_t index);
|
||||||
|
|
||||||
/* Closes file transfer ft.
|
/* Closes file transfer ft.
|
||||||
*
|
*
|
||||||
* 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.
|
||||||
|
@ -1107,14 +1107,14 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
|
|
||||||
/* Determine which portion of friendlist to draw based on current position */
|
/* Determine which portion of friendlist to draw based on current position */
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
int page = Friends.num_selected / (y2 - FLIST_OFST);
|
const int page = Friends.num_selected / (y2 - FLIST_OFST);
|
||||||
pthread_mutex_unlock(&Winthread.lock);
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
int start = (y2 - FLIST_OFST) * page;
|
const int start = (y2 - FLIST_OFST) * page;
|
||||||
int end = y2 - FLIST_OFST + start;
|
const int end = y2 - FLIST_OFST + start;
|
||||||
|
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
size_t num_friends = Friends.num_friends;
|
const size_t num_friends = Friends.num_friends;
|
||||||
pthread_mutex_unlock(&Winthread.lock);
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -79,8 +79,9 @@ typedef struct {
|
|||||||
struct GameInvite game_invite;
|
struct GameInvite game_invite;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct FileTransfer file_receiver[MAX_FILES];
|
FileTransfer file_receiver[MAX_FILES];
|
||||||
struct FileTransfer file_sender[MAX_FILES];
|
FileTransfer file_sender[MAX_FILES];
|
||||||
|
PendingFileTransfer file_send_queue[MAX_FILES];
|
||||||
} ToxicFriend;
|
} ToxicFriend;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -244,7 +244,7 @@ void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, u
|
|||||||
{
|
{
|
||||||
UNUSED_VAR(userdata);
|
UNUSED_VAR(userdata);
|
||||||
|
|
||||||
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
||||||
|
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
return;
|
return;
|
||||||
@ -267,7 +267,7 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint
|
|||||||
{
|
{
|
||||||
UNUSED_VAR(userdata);
|
UNUSED_VAR(userdata);
|
||||||
|
|
||||||
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
||||||
|
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
return;
|
return;
|
||||||
@ -285,7 +285,7 @@ void on_file_recv_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, To
|
|||||||
{
|
{
|
||||||
UNUSED_VAR(userdata);
|
UNUSED_VAR(userdata);
|
||||||
|
|
||||||
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
|
||||||
|
|
||||||
if (!ft) {
|
if (!ft) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user