diff --git a/Makefile b/Makefile
index 07fa384..f6f4209 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
CFLAGS += $(USER_CFLAGS)
LDFLAGS = $(USER_LDFLAGS)
-OBJ = chat.o chat_commands.o configdir.o dns.o execute.o file_senders.o notify.o
+OBJ = chat.o chat_commands.o configdir.o dns.o execute.o file_transfers.o notify.o
OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o
OBJ += group_commands.o term_mplex.o
diff --git a/README.md b/README.md
index d3cc263..dd78dae 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Toxic is a [Tox](https://tox.im)-based instant messenging client which formerly
If you don't like installation methods listed above, you can still download precompiled binaries from [jenkins](https://jenkins.libtoxcore.so):
* [Linux 32 bit](https://jenkins.libtoxcore.so/job/toxic_linux_i386/lastSuccessfulBuild/artifact/toxic_linux_i386.tar.xz) [![Build Status](https://jenkins.libtoxcore.so/job/toxic_linux_i386/badge/icon)](https://jenkins.libtoxcore.so/job/toxic_linux_i386/lastSuccessfulBuild/artifact/toxic_linux_i386.tar.xz)
* [Linux 64 bit](https://jenkins.libtoxcore.so/job/toxic_linux_amd64/lastSuccessfulBuild/artifact/toxic_linux_amd64.tar.xz) [![Build Status](https://jenkins.libtoxcore.so/job/toxic_linux_amd64/badge/icon)](https://jenkins.libtoxcore.so/job/toxic_linux_amd64/lastSuccessfulBuild/artifact/toxic_linux_amd64.tar.xz)
-* [~~Linux ARMv6~~](https://jenkins.libtoxcore.so/job/toxic_linux_armv6/lastSuccessfulBuild/artifact/toxic_linux_armv6.tar.xz) **CURRENTLY DISABLED** [![Build Status](https://jenkins.libtoxcore.so/job/toxic_linux_amd64/badge/icon)](https://jenkins.libtoxcore.so/job/toxic_linux_armv6/lastSuccessfulBuild/artifact/toxic_linux_armv6.tar.xz)
+* [~~Linux ARMv6~~](https://jenkins.libtoxcore.so/job/toxic_linux_armv6/lastSuccessfulBuild/artifact/toxic_linux_armv6.tar.xz) **CURRENTLY DISABLED** [![Build Status](https://jenkins.libtoxcore.so/job/toxic_linux_armv6/badge/icon)](https://jenkins.libtoxcore.so/job/toxic_linux_armv6/lastSuccessfulBuild/artifact/toxic_linux_armv6.tar.xz)
#### DEBs packages
* [toxic-i386.deb](https://jenkins.libtoxcore.so/job/toxic-linux-pkg/lastSuccessfulBuild/artifact/toxic-i386.deb)
diff --git a/cfg/global_vars.mk b/cfg/global_vars.mk
index 52942fa..d5c7b57 100644
--- a/cfg/global_vars.mk
+++ b/cfg/global_vars.mk
@@ -1,5 +1,5 @@
# Version
-TOXIC_VERSION = 0.5.2
+TOXIC_VERSION = 0.6.0
REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error")
ifneq (, $(findstring error, $(REV)))
VERSION = $(TOXIC_VERSION)
diff --git a/doc/toxic.1 b/doc/toxic.1
index f7e21e4..242072c 100644
--- a/doc/toxic.1
+++ b/doc/toxic.1
@@ -2,12 +2,12 @@
.\" Title: toxic
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1
-.\" Date: 2014-09-19
+.\" Date: 2014-12-27
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
-.TH "TOXIC" "1" "2014\-09\-19" "toxic __VERSION__" "Toxic Manual"
+.TH "TOXIC" "1" "2014\-12\-27" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -115,11 +115,6 @@ Force TCP connection (use this with proxies)
.RS 4
Unencrypt a data file\&. A warning will appear if this option is used with a data file that is already unencrypted\&.
.RE
-.PP
-\-x, \-\-nodata
-.RS 4
-Ignore data file
-.RE
.SH "FILES"
.PP
__DATADIR__/DHTnodes
diff --git a/doc/toxic.1.asc b/doc/toxic.1.asc
index 93f3a86..0ee3c06 100644
--- a/doc/toxic.1.asc
+++ b/doc/toxic.1.asc
@@ -31,7 +31,7 @@ OPTIONS
Use default locale
-e, --encrypt-data::
- Encrypt an unencrypted data file. An error will occur if this option
+ Encrypt an unencrypted data file. An error will occur if this option
is used with an encrypted data file.
-f, --file data-file::
@@ -60,12 +60,9 @@ OPTIONS
Force TCP connection (use this with proxies)
-u, --unencrypt-data::
- Unencrypt a data file. A warning will appear if this option is used
+ Unencrypt a data file. A warning will appear if this option is used
with a data file that is already unencrypted.
--x, --nodata::
- Ignore data file
-
FILES
-----
{datadir}/DHTnodes::
diff --git a/doc/toxic.conf.5 b/doc/toxic.conf.5
index 6b4ad6b..0aaa841 100644
--- a/doc/toxic.conf.5
+++ b/doc/toxic.conf.5
@@ -202,7 +202,7 @@ Configuration related to notification sounds\&. Special value "silent" can be us
Each value is a string which corresponds to the absolute path of a wav sound file\&.
.PP
-\fBerror\fR
+\fBnotif_error\fR
.RS 4
Sound to play when an error occurs\&.
.RE
diff --git a/doc/toxic.conf.5.asc b/doc/toxic.conf.5.asc
index b276023..267918f 100644
--- a/doc/toxic.conf.5.asc
+++ b/doc/toxic.conf.5.asc
@@ -132,7 +132,7 @@ OPTIONS
Each value is a string which corresponds to the absolute path of a wav
sound file.
- *error*;;
+ *notif_error*;;
Sound to play when an error occurs.
*self_log_in*;;
diff --git a/src/audio_call.c b/src/audio_call.c
index ebe64eb..54b865b 100644
--- a/src/audio_call.c
+++ b/src/audio_call.c
@@ -59,7 +59,7 @@ static int set_call(Call* call, bool start)
{
call->in_idx = -1;
call->out_idx = -1;
-
+
if ( start ) {
call->ttas = true;
@@ -79,9 +79,9 @@ struct ASettings {
AudioError errors;
ToxAv *av;
-
+
ToxAvCSettings cs;
-
+
Call calls[MAX_CALLS];
} ASettins;
@@ -105,15 +105,15 @@ static void print_err (ToxWindow *self, const char *error_str)
}
ToxAv *init_audio(ToxWindow *self, Tox *tox)
-{
+{
ASettins.cs = av_DefaultSettings;
ASettins.cs.max_video_height = ASettins.cs.max_video_width = 0;
-
+
ASettins.errors = ae_None;
-
+
memset(ASettins.calls, 0, sizeof(ASettins.calls));
-
+
/* Streaming stuff from core */
ASettins.av = toxav_new(tox, MAX_CALLS);
@@ -122,7 +122,7 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox)
ASettins.errors |= ae_StartingCoreAudio;
return NULL;
}
-
+
if ( init_devices(ASettins.av) == de_InternalError ) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to init devices");
toxav_kill(ASettins.av);
@@ -142,7 +142,7 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox)
toxav_register_callstate_callback(ASettins.av, callback_requ_timeout, av_OnRequestTimeout, self);
toxav_register_callstate_callback(ASettins.av, callback_peer_timeout, av_OnPeerTimeout, self);
//toxav_register_callstate_callback(ASettins.av, callback_media_change, av_OnMediaChange, self);
-
+
toxav_register_audio_callback(ASettins.av, write_device_callback, NULL);
return ASettins.av;
@@ -156,14 +156,14 @@ void terminate_audio()
if ( ASettins.av )
toxav_kill(ASettins.av);
-
+
terminate_devices();
}
void read_device_callback (const int16_t* captured, uint32_t size, void* data)
{
int32_t call_index = *((int32_t*)data); /* TODO: Or pass an array of call_idx's */
-
+
uint8_t encoded_payload[RTP_PAYLOAD_SIZE];
int32_t payload_size = toxav_prepare_audio_frame(ASettins.av, call_index, encoded_payload, RTP_PAYLOAD_SIZE, captured, size);
if ( payload_size <= 0 || toxav_send_audio(ASettins.av, call_index, encoded_payload, payload_size) < 0 ) {
@@ -207,15 +207,15 @@ int start_transmission(ToxWindow *self, Call *call)
toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings);
if ( open_primary_device(input, &call->in_idx,
- csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None )
+ csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None )
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!");
- if ( register_device_callback(self->call_idx, call->in_idx,
- read_device_callback, &self->call_idx, true) != de_None)
+ if ( register_device_callback(self->call_idx, call->in_idx,
+ read_device_callback, &self->call_idx, true) != de_None)
/* Set VAD as true for all; TODO: Make it more dynamic */
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!");
- if ( open_primary_device(output, &call->out_idx,
+ if ( open_primary_device(output, &call->out_idx,
csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open output device!");
call->has_output = 0;
@@ -225,23 +225,23 @@ int start_transmission(ToxWindow *self, Call *call)
}
int stop_transmission(Call *call, int32_t call_index)
-{
+{
if ( call->ttas ) {
toxav_kill_transmission(ASettins.av, call_index);
call->ttas = false;
-
+
if ( call->in_idx != -1 )
close_device(input, call->in_idx);
-
+
if ( call->out_idx != -1 )
close_device(output, call->out_idx);
-
+
if (set_call(call, false) == -1)
return -1;
return 0;
}
-
+
return -1;
}
/*
@@ -269,10 +269,10 @@ void callback_recv_ringing ( void* av, int32_t call_index, void* arg )
}
void callback_recv_starting ( void* av, int32_t call_index, void* arg )
{
- ToxWindow* windows = arg;
+ ToxWindow* windows = arg;
int i;
- for (i = 0; i < MAX_WINDOWS_NUM; ++i)
- if (windows[i].onStarting != NULL && windows[i].call_idx == call_index) {
+ for (i = 0; i < MAX_WINDOWS_NUM; ++i)
+ if (windows[i].onStarting != NULL && windows[i].call_idx == call_index) {
windows[i].onStarting(&windows[i], ASettins.av, call_index);
if ( 0 != start_transmission(&windows[i], &ASettins.calls[call_index])) {/* YEAH! */
line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0 , "Error starting transmission!");
@@ -287,10 +287,10 @@ void callback_recv_ending ( void* av, int32_t call_index, void* arg )
}
void callback_call_started ( void* av, int32_t call_index, void* arg )
-{
- ToxWindow* windows = arg;
+{
+ ToxWindow* windows = arg;
int i;
- for (i = 0; i < MAX_WINDOWS_NUM; ++i)
+ for (i = 0; i < MAX_WINDOWS_NUM; ++i)
if (windows[i].onStart != NULL && windows[i].call_idx == call_index) {
windows[i].onStart(&windows[i], ASettins.av, call_index);
if ( 0 != start_transmission(&windows[i], &ASettins.calls[call_index]) ) {/* YEAH! */
@@ -357,7 +357,7 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
goto on_error;
}
- if (!self->stb->is_online) {
+ if (!self->stb->connection) {
error_str = "Friend is offline.";
goto on_error;
}
@@ -545,12 +545,12 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (
error_str = "Invalid input";
goto on_error;
}
-
+
if ( set_primary_device(type, selection) == de_InvalidSelection ) {
error_str="Invalid selection!";
goto on_error;
}
-
+
return;
on_error:
print_err (self, error_str);
@@ -559,71 +559,71 @@ on_error:
void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
const char *error_str;
-
+
if ( argc != 2 ) {
if ( argc < 1 ) error_str = "Type must be specified!";
else if ( argc < 2 ) error_str = "Must have id!";
else error_str = "Only two arguments allowed!";
-
+
goto on_error;
}
-
+
DeviceType type;
-
+
if ( strcmp(argv[1], "in") == 0 ) /* Input devices */
type = input;
-
+
else if ( strcmp(argv[1], "out") == 0 ) /* Output devices */
type = output;
-
+
else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]);
return;
}
-
-
+
+
char *end;
long int selection = strtol(argv[2], &end, 10);
-
+
if ( *end ) {
error_str = "Invalid input";
goto on_error;
}
-
+
if ( selection_valid(type, selection) == de_InvalidSelection ) {
error_str="Invalid selection!";
goto on_error;
}
-
+
/* If call is active, change device */
if ( self->call_idx > -1) {
Call* this_call = &ASettins.calls[self->call_idx];
if (this_call->ttas) {
-
+
ToxAvCSettings csettings;
toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings);
-
+
if (type == output) {
pthread_mutex_lock(&this_call->mutex);
close_device(output, this_call->out_idx);
- this_call->has_output = open_device(output, selection, &this_call->out_idx,
- csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels)
+ this_call->has_output = open_device(output, selection, &this_call->out_idx,
+ csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels)
== de_None ? 1 : 0;
pthread_mutex_unlock(&this_call->mutex);
}
else {
/* TODO: check for failure */
close_device(input, this_call->in_idx);
- open_device(input, selection, &this_call->in_idx, csettings.audio_sample_rate,
+ open_device(input, selection, &this_call->in_idx, csettings.audio_sample_rate,
csettings.audio_frame_duration, csettings.audio_channels);
/* Set VAD as true for all; TODO: Make it more dynamic */
register_device_callback(self->call_idx, this_call->in_idx, read_device_callback, &self->call_idx, true);
}
}
}
-
+
self->device_selection[type] = selection;
-
+
return;
on_error:
print_err (self, error_str);
@@ -632,33 +632,33 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
const char *error_str;
-
+
if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Type must be specified!";
else error_str = "Only two arguments allowed!";
-
+
goto on_error;
}
-
+
DeviceType type;
-
+
if ( strcasecmp(argv[1], "in") == 0 ) /* Input devices */
type = input;
-
+
else if ( strcasecmp(argv[1], "out") == 0 ) /* Output devices */
type = output;
-
+
else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]);
return;
}
-
-
+
+
/* If call is active, use this_call values */
if ( self->call_idx > -1) {
Call* this_call = &ASettins.calls[self->call_idx];
-
- pthread_mutex_lock(&this_call->mutex);
+
+ pthread_mutex_lock(&this_call->mutex);
if (type == input) {
device_mute(type, this_call->in_idx);
self->chatwin->infobox.in_is_muted ^= 1;
@@ -668,9 +668,9 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
}
pthread_mutex_unlock(&this_call->mutex);
}
-
+
return;
-
+
on_error:
print_err (self, error_str);
}
@@ -678,39 +678,39 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
const char *error_str;
-
+
if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Must have value!";
else error_str = "Only two arguments allowed!";
-
+
goto on_error;
}
-
+
char *end;
float value = strtof(argv[1], &end);
-
+
if ( *end ) {
error_str = "Invalid input";
goto on_error;
}
-
+
/* Call must be active */
if ( self->call_idx > -1) {
device_set_VAD_treshold(ASettins.calls[self->call_idx].in_idx, value);
self->chatwin->infobox.vad_lvl = value;
- }
-
+ }
+
return;
-
+
on_error:
print_err (self, error_str);
}
void stop_current_call(ToxWindow* self)
-{
+{
ToxAvCallState callstate;
- if ( ASettins.av != NULL && self->call_idx != -1 &&
+ if ( ASettins.av != NULL && self->call_idx != -1 &&
( callstate = toxav_get_call_state(ASettins.av, self->call_idx) ) != av_CallNonExistent) {
switch (callstate)
{
diff --git a/src/chat.c b/src/chat.c
index a5821a2..ed5dc60 100644
--- a/src/chat.c
+++ b/src/chat.c
@@ -29,11 +29,13 @@
#include
#include
#include
+#include
#include "toxic.h"
#include "windows.h"
#include "execute.h"
#include "misc_tools.h"
+#include "file_transfers.h"
#include "friendlist.h"
#include "toxic_strings.h"
#include "log.h"
@@ -49,10 +51,7 @@
#include "audio_call.h"
#endif /* AUDIO */
-
extern char *DATA_FILE;
-
-extern FileSender file_senders[MAX_FILES];
extern FriendsList Friends;
extern struct Winthread Winthread;
@@ -105,25 +104,23 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
#endif /* AUDIO */
};
-static void set_self_typingstatus(ToxWindow *self, Tox *m, uint8_t is_typing)
+static void set_self_typingstatus(ToxWindow *self, Tox *m, bool is_typing)
{
if (user_settings->show_typing_self == SHOW_TYPING_OFF)
return;
ChatContext *ctx = self->chatwin;
- tox_set_user_is_typing(m, self->num, is_typing);
+ tox_self_set_typing(m, self->num, is_typing, NULL);
ctx->self_is_typing = is_typing;
}
-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);
+ kill_all_file_transfers_friend(m, self->num);
log_disable(ctx->log);
line_info_cleanup(ctx->hst);
cqueue_cleanup(ctx->cqueue);
@@ -145,19 +142,11 @@ void kill_chat_window(ToxWindow *self, Tox *m)
del_window(self);
}
-static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *msg, uint16_t len)
+static void recv_message_helper(ToxWindow *self, Tox *m, uint32_t num, const char *msg, size_t len,
+ const char *nick, const char *timefrmt)
{
- if (self->num != num)
- return;
-
ChatContext *ctx = self->chatwin;
- char nick[TOX_MAX_NAME_LENGTH];
- get_nick_truncate(m, nick, num);
-
- char timefrmt[TIME_STR_SIZE];
- get_time_str(timefrmt, sizeof(timefrmt));
-
line_info_add(self, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", msg);
write_to_log(msg, nick, ctx->log, false);
@@ -165,13 +154,44 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *msg
box_notify2(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, self->active_box, "%s", msg);
else
box_notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, &self->active_box, nick, "%s", msg);
-
}
-static void chat_resume_file_transfers(Tox *m, int fnum);
-static void chat_stop_file_senders(int fnum);
+static void recv_action_helper(ToxWindow *self, Tox *m, uint32_t num, const char *action, size_t len,
+ const char *nick, const char *timefrmt)
+{
+ ChatContext *ctx = self->chatwin;
-static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
+ line_info_add(self, timefrmt, nick, NULL, IN_ACTION, 0, 0, "%s", action);
+ write_to_log(action, nick, ctx->log, true);
+
+ if (self->active_box != -1)
+ box_notify2(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, self->active_box, "* %s %s", nick, action );
+ else
+ box_notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, &self->active_box, self->name, "* %s %s", nick, action );
+}
+
+static void chat_onMessage(ToxWindow *self, Tox *m, uint32_t num, TOX_MESSAGE_TYPE type, const char *msg, size_t len)
+{
+ if (self->num != num)
+ return;
+
+ char nick[TOX_MAX_NAME_LENGTH];
+ get_nick_truncate(m, nick, num);
+
+ char timefrmt[TIME_STR_SIZE];
+ get_time_str(timefrmt, sizeof(timefrmt));
+
+ if (type == TOX_MESSAGE_TYPE_NORMAL)
+ return recv_message_helper(self, m, num, msg, len, nick, timefrmt);
+
+ if (type == TOX_MESSAGE_TYPE_ACTION)
+ return recv_action_helper(self, m, num, msg, len, nick, timefrmt);
+}
+
+static void chat_resume_file_transfers(Tox *m, uint32_t fnum);
+static void chat_stop_file_senders(Tox *m, uint32_t friendnum);
+
+static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_CONNECTION connection_status)
{
if (self->num != num)
return;
@@ -186,23 +206,23 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, num);
- if (status == 1) { /* Friend goes online */
- statusbar->is_online = true;
+ statusbar->connection = connection_status;
+
+ if (connection_status != TOX_CONNECTION_NONE) {
Friends.list[num].is_typing = user_settings->show_typing_other == SHOW_TYPING_ON
- ? tox_get_is_typing(m, num) : 0;
+ ? tox_friend_get_typing(m, num, NULL) : false;
chat_resume_file_transfers(m, num);
msg = "has come online";
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
write_to_log(msg, nick, ctx->log, true);
- } else { /* Friend goes offline */
- statusbar->is_online = false;
- Friends.list[num].is_typing = 0;
+ } else {
+ Friends.list[num].is_typing = false;
if (self->chatwin->self_is_typing)
set_self_typingstatus(self, m, 0);
- chat_stop_file_senders(num);
+ chat_stop_file_senders(m, num);
msg = "has gone offline";
line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg);
@@ -210,7 +230,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
}
}
-static void chat_onTypingChange(ToxWindow *self, Tox *m, int32_t num, uint8_t is_typing)
+static void chat_onTypingChange(ToxWindow *self, Tox *m, uint32_t num, bool is_typing)
{
if (self->num != num)
return;
@@ -218,29 +238,7 @@ static void chat_onTypingChange(ToxWindow *self, Tox *m, int32_t num, uint8_t is
Friends.list[num].is_typing = is_typing;
}
-static void chat_onAction(ToxWindow *self, Tox *m, int32_t num, const char *action, uint16_t len)
-{
- if (self->num != num)
- return;
-
- ChatContext *ctx = self->chatwin;
-
- char nick[TOX_MAX_NAME_LENGTH];
- get_nick_truncate(m, nick, num);
-
- char timefrmt[TIME_STR_SIZE];
- get_time_str(timefrmt, sizeof(timefrmt));
-
- line_info_add(self, timefrmt, nick, NULL, IN_ACTION, 0, 0, "%s", action);
- write_to_log(action, nick, ctx->log, true);
-
- if (self->active_box != -1)
- box_notify2(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, self->active_box, "* %s %s", nick, action );
- else
- box_notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS, &self->active_box, self->name, "* %s %s", nick, action );
-}
-
-static void chat_onNickChange(ToxWindow *self, Tox *m, int32_t num, const char *nick, uint16_t len)
+static void chat_onNickChange(ToxWindow *self, Tox *m, uint32_t num, const char *nick, size_t length)
{
if (self->num != num)
return;
@@ -248,13 +246,13 @@ static void chat_onNickChange(ToxWindow *self, Tox *m, int32_t num, const char *
StatusBar *statusbar = self->stb;
snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick);
- len = strlen(statusbar->nick);
- statusbar->nick_len = len;
+ length = strlen(statusbar->nick);
+ statusbar->nick_len = length;
- set_window_title(self, statusbar->nick, len);
+ set_window_title(self, statusbar->nick, length);
}
-static void chat_onStatusChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
+static void chat_onStatusChange(ToxWindow *self, Tox *m, uint32_t num, TOX_USER_STATUS status)
{
if (self->num != num)
return;
@@ -263,7 +261,7 @@ static void chat_onStatusChange(ToxWindow *self, Tox *m, int32_t num, uint8_t st
statusbar->status = status;
}
-static void chat_onStatusMessageChange(ToxWindow *self, int32_t num, const char *status, uint16_t len)
+static void chat_onStatusMessageChange(ToxWindow *self, uint32_t num, const char *status, size_t length)
{
if (self->num != num)
return;
@@ -274,83 +272,237 @@ static void chat_onStatusMessageChange(ToxWindow *self, int32_t num, const char
statusbar->statusmsg_len = strlen(statusbar->statusmsg);
}
-static void chat_onReadReceipt(ToxWindow *self, Tox *m, int32_t num, uint32_t receipt)
+static void chat_onReadReceipt(ToxWindow *self, Tox *m, uint32_t num, uint32_t receipt)
{
cqueue_remove(self, m, receipt);
}
-static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum,
- uint64_t filesize, const char *pathname, uint16_t path_len)
+/* Stops active file senders for this friend. Call when a friend goes offline */
+static void chat_stop_file_senders(Tox *m, uint32_t friendnum)
{
- if (self->num != num)
+ // TODO: core purges file transfers when a friend goes offline. Ideally we want to repair/resume
+ kill_all_file_transfers_friend(m, friendnum);
+}
+
+/* Tries to resume broken file transfers. Call when a friend comes online */
+static void chat_resume_file_transfers(Tox *m, uint32_t fnum)
+{
+ // TODO
+}
+
+static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_t filenum, uint64_t position,
+ size_t length)
+{
+ if (friendnum != self->num)
return;
- /* holds the filename appended to the user specified path */
- char filename_path[MAX_STR_SIZE] = {0};
+ struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum);
+
+ if (ft == NULL)
+ return;
+
+ if (ft->state != FILE_TRANSFER_STARTED)
+ return;
+
+ char msg[MAX_STR_SIZE];
+
+ if (length == 0) {
+ snprintf(msg, sizeof(msg), "File '%s' successfully sent.", ft->file_name);
+ print_progress_bar(self, ft->bps, 100.0, ft->line_id);
+ close_file_transfer(self, m, ft, -1, msg, transfer_completed);
+ return;
+ }
+
+ if (ft->file == NULL) {
+ snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Null file pointer.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ if (ft->position != position) {
+ if (fseek(ft->file, position, SEEK_SET) == -1) {
+ snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Seek fail.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ ft->position = position;
+ }
+
+ uint8_t send_data[length];
+ size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file);
+
+ if (send_length != length) {
+ snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Read fail.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ TOX_ERR_FILE_SEND_CHUNK err;
+ tox_file_send_chunk(m, friendnum, filenum, position, send_data, send_length, &err);
+
+ if (err != TOX_ERR_FILE_SEND_CHUNK_OK)
+ fprintf(stderr, "tox_file_send_chunk failed (error %d)\n", err);
+
+ ft->position += send_length;
+ ft->bps += send_length;
+}
+
+static void chat_onFileRecvChunk(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_t filenum, uint64_t position,
+ const char *data, size_t length)
+{
+ if (friendnum != self->num)
+ return;
+
+ struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum);
+
+ if (ft == NULL)
+ return;
+
+ if (ft->state != FILE_TRANSFER_STARTED)
+ return;
+
+ char msg[MAX_STR_SIZE];
+
+ if (length == 0) {
+ snprintf(msg, sizeof(msg), "File '%s' successfully received.", ft->file_name);
+ print_progress_bar(self, ft->bps, 100.0, ft->line_id);
+ close_file_transfer(self, m, ft, -1, msg, transfer_completed);
+ return;
+ }
+
+ if (ft->file == NULL) {
+ snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Invalid file pointer.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ if (fwrite(data, length, 1, ft->file) != 1) {
+ snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Write fail.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ ft->bps += length;
+ ft->position += length;
+}
+
+static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_t filenum, TOX_FILE_CONTROL control)
+{
+ if (self->num != friendnum)
+ return;
+
+ struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum);
+
+ if (ft == NULL)
+ return;
+
+ char msg[MAX_STR_SIZE];
+
+ switch (control) {
+ case TOX_FILE_CONTROL_RESUME:
+ /* transfer is accepted */
+ if (ft->state == FILE_TRANSFER_PENDING) {
+ ft->state = FILE_TRANSFER_STARTED;
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer [%d] for '%s' accepted.",
+ ft->index, ft->file_name);
+ char progline[MAX_STR_SIZE];
+ prep_prog_line(progline);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline);
+ sound_notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2, NULL);
+ ft->line_id = self->chatwin->hst->line_end->id + 2;
+
+ break;
+ }
+
+ /* transfer is resumed */
+ if (ft->state == FILE_TRANSFER_PAUSED) {
+ ft->state = FILE_TRANSFER_STARTED;
+ }
+
+ break;
+
+ case TOX_FILE_CONTROL_PAUSE:
+ break;
+
+ case TOX_FILE_CONTROL_CANCEL:
+ snprintf(msg, sizeof(msg), "File transfer for '%s' was aborted.", ft->file_name);
+ close_file_transfer(self, m, ft, -1, msg, notif_error);
+ break;
+ }
+}
+
+static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_t filenum, uint64_t file_size,
+ const char *filename, size_t name_length)
+{
+ if (self->num != friendnum)
+ return;
+
+ struct FileTransfer *ft = get_new_file_receiver(friendnum);
+
+ if (!ft) {
+ tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Too many concurrent file transfers.");
+ return;
+ }
- /* holds the lone filename */
- char filename_nopath[MAX_STR_SIZE];
- get_file_name(filename_nopath, sizeof(filename_nopath), pathname);
char sizestr[32];
- bytes_convert_str(sizestr, sizeof(sizestr), filesize);
- int len = strlen(filename_nopath);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer request for '%s' (%s)",
- filename_nopath, sizestr);
+ bytes_convert_str(sizestr, sizeof(sizestr), file_size);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer request for '%s' (%s)", filename, sizestr);
- if (filenum >= MAX_FILES) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Too many pending file requests; discarding.");
+ char file_path[MAX_STR_SIZE];
+ size_t path_len = name_length;
+
+ /* use specified download path in config if possible */
+ if (!string_is_empty(user_settings->download_path)) {
+ snprintf(file_path, sizeof(file_path), "%s%s", user_settings->download_path, filename);
+ path_len += strlen(user_settings->download_path);
+ } else {
+ snprintf(file_path, sizeof(file_path), "%s", filename);
+ }
+
+ if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
+ tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long.");
return;
}
- /* use specified path in config if possible */
- if (user_settings->download_path[0]) {
- snprintf(filename_path, sizeof(filename_path), "%s%s", user_settings->download_path, filename_nopath);
- len += strlen(user_settings->download_path);
- }
-
- if (len >= sizeof(Friends.list[num].file_receiver[filenum].filename)) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File name too long; discarding.");
- return;
- }
-
- char filename[MAX_STR_SIZE];
-
- if (filename_path[0])
- strcpy(filename, filename_path);
- else
- strcpy(filename, filename_nopath);
-
/* Append a number to duplicate file names */
FILE *filecheck = NULL;
int count = 1;
- while ((filecheck = fopen(filename, "r"))) {
+ while ((filecheck = fopen(file_path, "r"))) {
fclose(filecheck);
- filename[len] = '\0';
+ file_path[path_len] = '\0';
char d[9];
- sprintf(d, "(%d)", count++);
- int d_len = strlen(d);
+ sprintf(d, "(%d)", count);
+ ++count;
+ size_t d_len = strlen(d);
- if (len + d_len >= sizeof(filename)) {
- len -= d_len;
- filename[len] = '\0';
+ if (path_len + d_len >= sizeof(file_path)) {
+ path_len -= d_len;
+ file_path[path_len] = '\0';
}
- strcat(filename, d);
- filename[len + d_len] = '\0';
+ strcat(file_path, d);
+ file_path[path_len + d_len] = '\0';
if (count > 999) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error saving file to disk.");
+ tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: invalid file path.");
return;
}
}
- 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.", ft->index);
- Friends.list[num].file_receiver[filenum].pending = true;
- Friends.list[num].file_receiver[filenum].size = filesize;
- Friends.list[num].file_receiver[filenum].filenum = filenum;
- strcpy(Friends.list[num].file_receiver[filenum].filename, filename);
+ ft->state = FILE_TRANSFER_PENDING;
+ ft->direction = FILE_TRANSFER_RECV;
+ ft->file_size = file_size;
+ ft->friendnum = friendnum;
+ ft->filenum = filenum;
+ snprintf(ft->file_path, sizeof(ft->file_path), "%s", file_path);
+ snprintf(ft->file_name, sizeof(ft->file_name), "%s", filename);
if (self->active_box != -1)
box_notify2(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, self->active_box,
@@ -360,208 +512,6 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
"Incoming file: %s", filename );
}
-/* Stops active file senders for this friend. Call when a friend goes offline */
-static void chat_stop_file_senders(int fnum)
-{
- int i;
-
- for (i = 0; i < MAX_FILES; ++i) {
- if (file_senders[i].active && file_senders[i].friendnum == fnum)
- file_senders[i].noconnection = true;
- }
-}
-
-/* Tries to resume broken file transfers. Call when a friend comes online */
-static void chat_resume_file_transfers(Tox *m, int fnum)
-{
- if (Friends.list[fnum].active_file_receivers == 0)
- return;
-
- int i;
-
- for (i = 0; i < MAX_FILES; ++i) {
- if (Friends.list[fnum].file_receiver[i].active) {
- uint8_t bytes_recv[sizeof(uint64_t)];
- memcpy(bytes_recv, &Friends.list[fnum].file_receiver[i].bytes_recv, sizeof(uint64_t));
- net_to_host(bytes_recv, sizeof(uint64_t));
- int filenum = Friends.list[fnum].file_receiver[i].filenum;
- tox_file_send_control(m, fnum, 1, filenum, TOX_FILECONTROL_RESUME_BROKEN, bytes_recv, sizeof(uint64_t));
- }
- }
-}
-
-/* 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)
-{
- if (CTRL > 0)
- tox_file_send_control(m, friendnum, 1, filenum, CTRL, 0, 0);
-
- FILE *file = Friends.list[friendnum].file_receiver[filenum].file;
-
- if (file != NULL)
- fclose(file);
-
- memset(&Friends.list[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver));
- --Friends.list[friendnum].active_file_receivers;
-}
-
-static void close_all_file_receivers(Tox *m, int friendnum)
-{
- int i;
-
- for (i = 0; i < MAX_FILES; ++i) {
- if (Friends.list[friendnum].file_receiver[i].active)
- chat_close_file_receiver(m, i, friendnum, TOX_FILECONTROL_KILL);
- }
-}
-
-static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t receive_send,
- uint8_t filenum, uint8_t control_type, const char *data, uint16_t length)
-{
- if (self->num != num)
- return;
-
- const char *filename;
- char msg[MAX_STR_SIZE] = {0};
- int send_idx = 0; /* file sender index */
-
- if (receive_send == 0) {
- if (!Friends.list[num].file_receiver[filenum].active)
- return;
-
- filename = Friends.list[num].file_receiver[filenum].filename;
- } else {
- int i;
-
- for (i = 0; i < MAX_FILES; ++i) {
- send_idx = i;
-
- if (file_senders[i].active && file_senders[i].filenum == filenum)
- break;
- }
-
- if (!file_senders[send_idx].active)
- return;
-
- filename = file_senders[send_idx].filename;
- }
-
- switch (control_type) {
- case TOX_FILECONTROL_ACCEPT:
- if (receive_send != 1)
- break;
-
- /* transfer is accepted */
- if (!file_senders[send_idx].started) {
- file_senders[send_idx].started = true;
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer [%d] for '%s' accepted.",
- filenum, filename);
- char progline[MAX_STR_SIZE];
- prep_prog_line(progline);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline);
- file_senders[send_idx].line_id = self->chatwin->hst->line_end->id + 2;
- sound_notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2, NULL);
- } else { /* active transfer is unpaused by receiver */
- file_senders[send_idx].paused = false;
- file_senders[send_idx].timestamp = get_unix_time();
- }
-
- break;
-
- case TOX_FILECONTROL_PAUSE:
- if (receive_send == 1)
- file_senders[send_idx].paused = true;
-
- break;
-
- case TOX_FILECONTROL_KILL:
- snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename);
-
- if (self->active_box != -1)
- box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2,
- self->active_box, "File transfer for '%s' failed!", filename );
- else
- box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box,
- self->name, "File transfer for '%s' failed!", filename );
-
- if (receive_send == 0)
- chat_close_file_receiver(m, filenum, num, -1);
- else
- close_file_sender(self, m, send_idx, NULL, -1, filenum, num);
-
- break;
-
- case TOX_FILECONTROL_FINISHED:
- if (receive_send == 0) {
- print_progress_bar(self, filenum, num, 100.0);
-
- char filename_nopath[MAX_STR_SIZE];
- get_file_name(filename_nopath, sizeof(filename_nopath), filename);
- snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename_nopath);
- chat_close_file_receiver(m, filenum, num, TOX_FILECONTROL_FINISHED);
- } else {
- snprintf(msg, sizeof(msg), "File '%s' successfuly sent.", filename);
- close_file_sender(self, m, send_idx, NULL, TOX_FILECONTROL_FINISHED, filenum, num);
- }
-
- if (self->active_box != -1)
- box_notify2(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg);
- else
- box_notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box,
- self->name, "%s", msg);
-
- break;
-
- case TOX_FILECONTROL_RESUME_BROKEN:
- if (receive_send == 0)
- break;
-
- FILE *fp = file_senders[send_idx].file;
-
- if (fp == NULL)
- break;
-
- uint8_t tmp[sizeof(uint64_t)];
- memcpy(tmp, &data, sizeof(uint64_t));
- net_to_host(tmp, sizeof(uint64_t));
- uint64_t datapos;
- memcpy(&datapos, tmp, sizeof(uint64_t));
-
- if (fseek(fp, datapos, SEEK_SET) == -1) {
- snprintf(msg, sizeof(msg), "File transfer for '%s' failed to resume", filename);
- close_file_sender(self, m, send_idx, NULL, TOX_FILECONTROL_FINISHED, filenum, num);
- break;
- }
-
- tox_file_send_control(m, num, 0, filenum, TOX_FILECONTROL_ACCEPT, 0, 0);
- file_senders[send_idx].noconnection = false;
- break;
- }
-
- if (msg[0])
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
-}
-
-static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, const char *data,
- uint16_t length)
-{
- if (self->num != num)
- return;
-
- FILE *fp = Friends.list[num].file_receiver[filenum].file;
-
- if (fp) {
- if (fwrite(data, length, 1, fp) != 1) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Error writing to file.");
- chat_close_file_receiver(m, filenum, num, TOX_FILECONTROL_KILL);
- }
- }
-
- Friends.list[num].file_receiver[filenum].bps += length;
- Friends.list[num].file_receiver[filenum].bytes_recv += length;
-}
-
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, const char *invite_data,
uint16_t length)
{
@@ -838,7 +788,9 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
return;
char selfname[TOX_MAX_NAME_LENGTH];
- uint16_t len = tox_get_self_name(m, (uint8_t *) selfname);
+ tox_self_get_name(m, (uint8_t *) selfname);
+
+ size_t len = tox_self_get_name_size(m);
selfname[len] = '\0';
char timefrmt[TIME_STR_SIZE];
@@ -869,7 +821,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (ltr) { /* char is printable */
input_new_char(self, key, x, y, x2, y2);
- if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->is_online)
+ if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->connection != TOX_CONNECTION_NONE)
set_self_typingstatus(self, m, 1);
return;
@@ -905,7 +857,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
}
} else {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
} else if (key == '\n') {
@@ -930,7 +882,9 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
}
} else if (!string_is_empty(line)) {
char selfname[TOX_MAX_NAME_LENGTH];
- uint16_t len = tox_get_self_name(m, (uint8_t *) selfname);
+ tox_self_get_name(m, (uint8_t *) selfname);
+
+ size_t len = tox_self_get_name_size(m);
selfname[len] = '\0';
char timefrmt[TIME_STR_SIZE];
@@ -970,26 +924,20 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wmove(statusbar->topline, 0, 0);
/* Draw name, status and note in statusbar */
- if (statusbar->is_online) {
- int colour = WHITE;
- uint8_t status = statusbar->status;
+ if (statusbar->connection != TOX_CONNECTION_NONE) {
+ int colour = MAGENTA;
+ TOX_USER_STATUS status = statusbar->status;
switch (status) {
- case TOX_USERSTATUS_NONE:
+ case TOX_USER_STATUS_NONE:
colour = GREEN;
break;
-
- case TOX_USERSTATUS_AWAY:
+ case TOX_USER_STATUS_AWAY:
colour = YELLOW;
break;
-
- case TOX_USERSTATUS_BUSY:
+ case TOX_USER_STATUS_BUSY:
colour = RED;
break;
-
- case TOX_USERSTATUS_INVALID:
- colour = MAGENTA;
- break;
}
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@@ -1014,10 +962,11 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
/* Reset statusbar->statusmsg on window resize */
if (x2 != self->x) {
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'};
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH] = {'\0'};
pthread_mutex_lock(&Winthread.lock);
- int s_len = tox_get_status_message(m, self->num, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
+ tox_friend_get_status_message(m, self->num, (uint8_t *) statusmsg, NULL);
+ size_t s_len = tox_friend_get_status_message_size(m, self->num, NULL);
pthread_mutex_unlock(&Winthread.lock);
filter_str(statusmsg, s_len);
@@ -1028,7 +977,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
self->x = x2;
/* Truncate note if it doesn't fit in statusbar */
- uint16_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6;
+ size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6;
if (statusbar->statusmsg_len > maxlen) {
statusbar->statusmsg[maxlen - 3] = '\0';
@@ -1043,7 +992,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3);
wprintw(statusbar->topline, "{");
- int i;
+ size_t i;
for (i = 0; i < KEY_IDENT_DIGITS; ++i)
wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff);
@@ -1069,6 +1018,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
if (self->help->active)
help_onDraw(self);
+
+ pthread_mutex_lock(&Winthread.lock);
+ refresh_file_transfer_progress(self, m, self->num);
+ pthread_mutex_unlock(&Winthread.lock);
}
static void chat_onInit(ToxWindow *self, Tox *m)
@@ -1081,11 +1034,13 @@ static void chat_onInit(ToxWindow *self, Tox *m)
/* Init statusbar info */
StatusBar *statusbar = self->stb;
- statusbar->status = tox_get_user_status(m, self->num);
- statusbar->is_online = tox_get_friend_connection_status(m, self->num) == 1;
+ statusbar->status = tox_friend_get_status(m, self->num, NULL);
+ statusbar->connection = tox_friend_get_connection_status(m, self->num, NULL);
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'};
- uint16_t s_len = tox_get_status_message(m, self->num, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
+ tox_friend_get_status_message(m, self->num, (uint8_t *) statusmsg, NULL);
+
+ size_t s_len = tox_friend_get_status_message_size(m, self->num, NULL);
statusmsg[s_len] = '\0';
filter_str(statusmsg, s_len);
@@ -1093,7 +1048,7 @@ static void chat_onInit(ToxWindow *self, Tox *m)
statusbar->statusmsg_len = strlen(statusbar->statusmsg);
char nick[TOX_MAX_NAME_LENGTH + 1];
- int n_len = get_nick_truncate(m, nick, self->num);
+ size_t n_len = get_nick_truncate(m, nick, self->num);
snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick);
statusbar->nick_len = n_len;
@@ -1113,8 +1068,8 @@ static void chat_onInit(ToxWindow *self, Tox *m)
line_info_init(ctx->hst);
- char myid[TOX_FRIEND_ADDRESS_SIZE];
- tox_get_address(m, (uint8_t *) myid);
+ char myid[TOX_ADDRESS_SIZE];
+ tox_self_get_address(m, (uint8_t *) myid);
log_enable(nick, myid, Friends.list[self->num].pub_key, ctx->log, LOG_CHAT);
load_chat_history(self, ctx->log);
@@ -1128,7 +1083,7 @@ static void chat_onInit(ToxWindow *self, Tox *m)
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
}
-ToxWindow new_chat(Tox *m, int32_t friendnum)
+ToxWindow new_chat(Tox *m, uint32_t friendnum)
{
ToxWindow ret;
memset(&ret, 0, sizeof(ret));
@@ -1145,10 +1100,10 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
ret.onNickChange = &chat_onNickChange;
ret.onStatusChange = &chat_onStatusChange;
ret.onStatusMessageChange = &chat_onStatusMessageChange;
- ret.onAction = &chat_onAction;
- ret.onFileSendRequest = &chat_onFileSendRequest;
+ ret.onFileChunkRequest = &chat_onFileChunkRequest;
+ ret.onFileRecvChunk = &chat_onFileRecvChunk;
ret.onFileControl = &chat_onFileControl;
- ret.onFileData = &chat_onFileData;
+ ret.onFileRecv = &chat_onFileRecv;
ret.onReadReceipt = &chat_onReadReceipt;
ret.onGroupInvite = &chat_onGroupInvite;
@@ -1173,7 +1128,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
ret.active_box = -1;
char nick[TOX_MAX_NAME_LENGTH];
- int n_len = get_nick_truncate(m, nick, friendnum);
+ size_t n_len = get_nick_truncate(m, nick, friendnum);
set_window_title(&ret, nick, n_len);
ChatContext *chatwin = calloc(1, sizeof(ChatContext));
diff --git a/src/chat_commands.c b/src/chat_commands.c
index 9ca5109..54dadf8 100644
--- a/src/chat_commands.c
+++ b/src/chat_commands.c
@@ -31,15 +31,11 @@
#include "line_info.h"
#include "groupchat.h"
#include "chat.h"
-#include "file_senders.h"
+#include "file_transfers.h"
extern ToxWindow *prompt;
extern FriendsList Friends;
-extern FileSender file_senders[MAX_FILES];
-extern uint8_t max_file_senders_index;
-extern uint8_t num_active_file_senders;
-
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 2) {
@@ -47,52 +43,39 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
return;
}
+ char msg[MAX_STR_SIZE];
const char *inoutstr = argv[1];
- int filenum = atoi(argv[2]);
+ int idx = atoi(argv[2]);
- if (filenum >= MAX_FILES || filenum < 0) {
+ if (idx >= MAX_FILES || idx < 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
return;
}
- if (strcasecmp(inoutstr, "in") == 0) { /* cancel an incoming file transfer */
- if (!Friends.list[self->num].file_receiver[filenum].active) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
- return;
- }
+ struct FileTransfer *ft = NULL;
- const char *filepath = Friends.list[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);
- chat_close_file_receiver(m, filenum, self->num, TOX_FILECONTROL_KILL);
-
- return;
- } else if (strcasecmp(inoutstr, "out") == 0) { /* cancel an outgoing file transfer */
- int i;
- bool match = false;
-
- for (i = 0; i < MAX_FILES; ++i) {
- if (file_senders[i].active && file_senders[i].filenum == filenum) {
- match = true;
- break;
- }
- }
-
- if (!match) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
- return;
- }
-
- const char *filename = file_senders[i].filename;
- char msg[MAX_STR_SIZE];
- snprintf(msg, sizeof(msg), "File transfer for '%s' canceled.", filename);
- close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, self->num);
- return;
+ /* cancel an incoming file transfer */
+ if (strcasecmp(inoutstr, "in") == 0) {
+ ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
+ } else if (strcasecmp(inoutstr, "out") == 0) {
+ ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_SEND);
} else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type must be 'in' or 'out'.");
return;
}
+
+ if (!ft) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
+ return;
+ }
+
+ if (ft->state == FILE_TRANSFER_INACTIVE) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID.");
+ return;
+ }
+
+ snprintf(msg, sizeof(msg), "File transfer for '%s' aborted.", ft->file_name);
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent);
}
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@@ -124,50 +107,76 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
return;
}
- uint8_t filenum = atoi(argv[1]);
+ int idx = atoi(argv[1]);
- if ((filenum == 0 && strcmp(argv[1], "0")) || filenum >= MAX_FILES) {
+ if ((idx == 0 && strcmp(argv[1], "0")) || idx >= MAX_FILES) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
return;
}
- if (!Friends.list[self->num].file_receiver[filenum].pending) {
+ struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
+
+ if (!ft) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
return;
}
- const char *filename = Friends.list[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);
-
- /* prep progress bar line */
- char progline[MAX_STR_SIZE];
- prep_prog_line(progline);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline);
- Friends.list[self->num].file_receiver[filenum].line_id = self->chatwin->hst->line_end->id + 2;
-
- if ((Friends.list[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);
- } else {
- Friends.list[self->num].file_receiver[filenum].active = true;
- ++Friends.list[self->num].active_file_receivers;
- }
- } else {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed.");
+ if (ft->state != FILE_TRANSFER_PENDING) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
+ return;
}
- Friends.list[self->num].file_receiver[filenum].pending = false;
+ if ((ft->file = fopen(ft->file_path, "a")) == NULL) {
+ const char *msg = "File transfer failed: Invalid file path.";
+ close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
+ return;
+ }
+
+ TOX_ERR_FILE_CONTROL err;
+ tox_file_control(m, self->num, ft->filenum, TOX_FILE_CONTROL_RESUME, &err);
+
+ if (err != TOX_ERR_FILE_CONTROL_OK)
+ goto on_recv_error;
+
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%d] as: '%s'", idx, ft->file_path);
+
+ /* prep progress bar line */
+ char progline[MAX_STR_SIZE];
+ prep_prog_line(progline);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline);
+
+ ft->line_id = self->chatwin->hst->line_end->id + 2;
+ ft->state = FILE_TRANSFER_STARTED;
+
+ return;
+
+on_recv_error:
+ switch (err) {
+ case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend not found.");
+ return;
+
+ case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend is not online.");
+ return;
+
+ case TOX_ERR_FILE_CONTROL_NOT_FOUND:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Invalid filenumber.");
+ return;
+
+ case TOX_ERR_FILE_CONTROL_SENDQ:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Connection error.");
+ return;
+
+ default:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed (error %d)\n", err);
+ return;
+ }
}
void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
- if (max_file_senders_index >= (MAX_FILES - 1)) {
- const char *errmsg = "Please wait for some of your outgoing file transfers to complete.";
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
- return;
- }
+ const char *errmsg = NULL;
if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path required.");
@@ -199,51 +208,67 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
off_t filesize = file_size(path);
- if (filesize == -1) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File corrupt.");
+ if (filesize == 0) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file.");
fclose(file_to_send);
return;
}
- char filename[MAX_STR_SIZE] = {0};
- get_file_name(filename, sizeof(filename), path);
- int namelen = strlen(filename);
- int filenum = tox_new_file_sender(m, self->num, filesize, (const uint8_t *) filename, namelen);
+ char file_name[TOX_MAX_FILENAME_LENGTH];
+ size_t namelen = get_file_name(file_name, sizeof(file_name), path);
- if (filenum == -1) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error sending file.");
- fclose(file_to_send);
- return;
+ TOX_ERR_FILE_SEND err;
+ uint32_t filenum = tox_file_send(m, self->num, TOX_FILE_KIND_DATA, (uint64_t) filesize, NULL,
+ (uint8_t *) file_name, namelen, &err);
+
+ if (err != TOX_ERR_FILE_SEND_OK)
+ goto on_send_error;
+
+ struct FileTransfer *ft = get_new_file_sender(self->num);
+
+ if (!ft) {
+ err = TOX_ERR_FILE_SEND_TOO_MANY;
+ goto on_send_error;
}
- int i;
+ memcpy(ft->file_name, file_name, namelen + 1);
+ ft->state = FILE_TRANSFER_PENDING;
+ ft->file = file_to_send;
+ ft->file_size = filesize;
+ ft->filenum = filenum;
+ ft->friendnum = self->num;
+ ft->direction = FILE_TRANSFER_SEND;
- for (i = 0; i < MAX_FILES; ++i) {
- if (!file_senders[i].active) {
- memcpy(file_senders[i].filename, filename, namelen + 1);
- file_senders[i].active = true;
- file_senders[i].started = false;
- file_senders[i].toxwin = self;
- file_senders[i].file = file_to_send;
- file_senders[i].filenum = filenum;
- file_senders[i].friendnum = self->num;
- file_senders[i].timestamp = get_unix_time();
- 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);
+ char sizestr[32];
+ bytes_convert_str(sizestr, sizeof(sizestr), filesize);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Sending file [%d]: '%s' (%s)", filenum, file_name, sizestr);
- char sizestr[32];
- bytes_convert_str(sizestr, sizeof(sizestr), filesize);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0,
- "Sending file [%d]: '%s' (%s)", filenum, filename, sizestr);
+ return;
- ++num_active_file_senders;
+on_send_error:
+ switch (err) {
+ case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND:
+ errmsg = "File transfer failed: Invalid friend.";
+ break;
- if (i == max_file_senders_index)
- ++max_file_senders_index;
+ case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED:
+ errmsg = "File transfer failed: Friend is offline.";
+ break;
- reset_file_sender_queue();
- return;
- }
+ case TOX_ERR_FILE_SEND_NAME_TOO_LONG:
+ errmsg = "File transfer failed: Filename is too long.";
+ break;
+
+ case TOX_ERR_FILE_SEND_TOO_MANY:
+ errmsg = "File transfer failed: Too many concurrent file transfers.";
+ break;
+
+ default:
+ errmsg = "File transfer failed.";
+ break;
}
+
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", errmsg);
+ tox_file_control(m, self->num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
+ fclose(file_to_send);
}
diff --git a/src/dns.c b/src/dns.c
index aafb911..ade723c 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -75,7 +75,7 @@ static struct dns3_server_backup {
static struct thread_data {
ToxWindow *self;
- char id_bin[TOX_FRIEND_ADDRESS_SIZE];
+ char id_bin[TOX_ADDRESS_SIZE];
char addr[MAX_STR_SIZE];
char msg[MAX_STR_SIZE];
uint8_t busy;
@@ -168,39 +168,39 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
uint8_t *ans_pt = answer + sizeof(HEADER);
uint8_t *ans_end = answer + ans_len;
char exp_ans[PACKETSZ];
-
+
int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
if (len == -1)
- return dns_error(self, "dn_expand failed.");
+ return dns_error(self, "dn_expand failed.");
ans_pt += len;
if (ans_pt > ans_end - 4)
- return dns_error(self, "DNS reply was too short.");
+ return dns_error(self, "DNS reply was too short.");
int type;
GETSHORT(type, ans_pt);
if (type != T_TXT)
- return dns_error(self, "Broken DNS reply.");
-
+ return dns_error(self, "Broken DNS reply.");
+
ans_pt += INT16SZ; /* class */
uint32_t size = 0;
/* recurse through CNAME rr's */
- do {
+ do {
ans_pt += size;
len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
if (len == -1)
- return dns_error(self, "Second dn_expand failed.");
+ return dns_error(self, "Second dn_expand failed.");
ans_pt += len;
if (ans_pt > ans_end - 10)
- return dns_error(self, "DNS reply was too short.");
+ return dns_error(self, "DNS reply was too short.");
GETSHORT(type, ans_pt);
ans_pt += INT16SZ;
@@ -208,12 +208,12 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
GETSHORT(size, ans_pt);
if (ans_pt + size < answer || ans_pt + size > ans_end)
- return dns_error(self, "RR overflow.");
+ return dns_error(self, "RR overflow.");
} while (type == T_CNAME);
if (type != T_TXT)
- return dns_error(self, "DNS response failed.");
+ return dns_error(self, "DNS response failed.");
uint32_t txt_len = *ans_pt;
@@ -230,7 +230,7 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
return txt_len;
}
-/* Takes address addr in the form "username@domain", puts the username in namebuf,
+/* Takes address addr in the form "username@domain", puts the username in namebuf,
and the domain in dombuf.
return length of username on success, -1 on failure */
@@ -322,7 +322,7 @@ void *dns3_lookup_thread(void *data)
char string[MAX_DNS_REQST_SIZE + 1];
uint32_t request_id;
- int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id,
+ int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id,
(uint8_t *) name, namelen);
if (str_len == -1) {
@@ -361,7 +361,7 @@ void *dns3_lookup_thread(void *data)
memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len);
- if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id,
+ if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id,
strlen(encrypted_id), request_id) == -1) {
dns_error(self, "Core failed to decrypt DNS response.");
killdns_thread(dns_obj);
@@ -378,7 +378,7 @@ void *dns3_lookup_thread(void *data)
/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg)
{
- if (arg_opts.proxy_type != TOX_PROXY_NONE && arg_opts.force_tcp) {
+ if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "DNS lookups are disabled.");
return;
}
diff --git a/src/file_senders.c b/src/file_senders.c
deleted file mode 100644
index 267d92c..0000000
--- a/src/file_senders.c
+++ /dev/null
@@ -1,293 +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;
- int32_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, int32_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)
-{
- int 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, int i, int32_t friendnum, int filenum, const char *filename)
-{
- FILE *fp = file_senders[i].file;
-
- while (true) {
- if (tox_file_send_data(m, friendnum, filenum, (uint8_t *) file_senders[i].nextpiece,
- file_senders[i].piecelen) == -1)
- 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;
- int32_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 1581b4f..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;
- int32_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];
- uint16_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
new file mode 100644
index 0000000..4ac5c1b
--- /dev/null
+++ b/src/file_transfers.c
@@ -0,0 +1,236 @@
+/* file_transfers.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_transfers.h"
+#include "line_info.h"
+#include "misc_tools.h"
+#include "notify.h"
+
+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, double bps, double pct_done, uint32_t line_id)
+{
+ if (bps < 0 || pct_done < 0 || pct_done > 100)
+ return;
+
+ 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);
+}
+
+static void refresh_progress_helper(ToxWindow *self, struct FileTransfer *ft, uint64_t curtime)
+{
+ if (ft->state == FILE_TRANSFER_INACTIVE)
+ return;
+
+ /* Timeout must be set to 1 second to show correct bytes per second */
+ if (!timed_out(ft->last_progress, curtime, 1))
+ return;
+
+ double remain = ft->file_size - ft->position;
+ double pct_done = remain > 0 ? (1 - (remain / ft->file_size)) * 100 : 100;
+ print_progress_bar(self, ft->bps, pct_done, ft->line_id);
+
+ ft->bps = 0;
+ ft->last_progress = curtime;
+}
+
+/* refreshes active file receiver status bars for friendnum */
+void refresh_file_transfer_progress(ToxWindow *self, Tox *m, uint32_t friendnum)
+{
+ uint64_t curtime = get_unix_time();
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ refresh_progress_helper(self, &Friends.list[friendnum].file_receiver[i], curtime);
+ refresh_progress_helper(self, &Friends.list[friendnum].file_sender[i], curtime);
+ }
+}
+
+/* Returns a pointer to friendnum's FileTransfer struct associated with filenum.
+ * Returns NULL if filenum is invalid.
+ */
+struct FileTransfer *get_file_transfer_struct(uint32_t friendnum, uint32_t filenum)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ struct FileTransfer *ft_send = &Friends.list[friendnum].file_sender[i];
+
+ if (ft_send->state != FILE_TRANSFER_INACTIVE && ft_send->filenum == filenum)
+ return ft_send;
+
+ struct FileTransfer *ft_recv = &Friends.list[friendnum].file_receiver[i];
+
+ if (ft_recv->state != FILE_TRANSFER_INACTIVE && ft_recv->filenum == filenum)
+ return ft_recv;
+ }
+
+ return NULL;
+}
+
+/* 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,
+ FILE_TRANSFER_DIRECTION direction)
+{
+ if (direction != FILE_TRANSFER_RECV && direction != FILE_TRANSFER_SEND)
+ return NULL;
+
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ struct FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
+ &Friends.list[friendnum].file_sender[i] :
+ &Friends.list[friendnum].file_receiver[i];
+
+ if (ft->state != FILE_TRANSFER_INACTIVE && ft->index == index)
+ return ft;
+ }
+
+ return NULL;
+}
+
+/* Returns a pointer to an unused file sender.
+ * Returns NULL if all file senders are in use.
+ */
+struct FileTransfer *get_new_file_sender(uint32_t friendnum)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ struct FileTransfer *ft = &Friends.list[friendnum].file_sender[i];
+
+ if (ft->state == FILE_TRANSFER_INACTIVE) {
+ ft->index = i;
+ return ft;
+ }
+ }
+
+ return NULL;
+}
+
+/* Returns a pointer to an unused file receiver.
+ * Returns NULL if all file receivers are in use.
+ */
+struct FileTransfer *get_new_file_receiver(uint32_t friendnum)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ struct FileTransfer *ft = &Friends.list[friendnum].file_receiver[i];
+
+ if (ft->state == FILE_TRANSFER_INACTIVE) {
+ ft->index = i;
+ return ft;
+ }
+ }
+
+ return NULL;
+}
+
+/* Closes file transfer ft.
+ *
+ * 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.
+ */
+void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int CTRL, const char *message,
+ Notification sound_type)
+{
+ if (!ft)
+ return;
+
+ if (ft->state == FILE_TRANSFER_INACTIVE)
+ return;
+
+ if (ft->file)
+ fclose(ft->file);
+
+ memset(ft, 0, sizeof(struct FileTransfer));
+
+ if (CTRL >= 0)
+ tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL);
+
+ if (message && self) {
+ if (self->active_box != -1)
+ box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message);
+ else
+ box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message);
+
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", message);
+ }
+}
+
+/* Kills all active file transfers for friendnum */
+void kill_all_file_transfers_friend(Tox *m, uint32_t friendnum)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_FILES; ++i) {
+ close_file_transfer(NULL, m, &Friends.list[friendnum].file_sender[i], -1, NULL, silent);
+ close_file_transfer(NULL, m, &Friends.list[friendnum].file_receiver[i], -1, NULL, silent);
+ }
+}
diff --git a/src/file_transfers.h b/src/file_transfers.h
new file mode 100644
index 0000000..ba12886
--- /dev/null
+++ b/src/file_transfers.h
@@ -0,0 +1,110 @@
+/* file_transfers.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 FILE_TRANSFERS_H
+#define FILE_TRANSFERS_H
+
+#include
+
+#include "toxic.h"
+#include "windows.h"
+#include "notify.h"
+
+#define KiB 1024
+#define MiB 1048576 /* 1024 ^ 2 */
+#define GiB 1073741824 /* 1024 ^ 3 */
+
+#define MAX_FILES 32
+#define TIMEOUT_FILESENDER 120
+
+typedef enum FILE_TRANSFER_STATE {
+ FILE_TRANSFER_INACTIVE,
+ FILE_TRANSFER_PENDING,
+ FILE_TRANSFER_STARTED,
+ FILE_TRANSFER_PAUSED
+} FILE_TRANSFER_STATE;
+
+typedef enum FILE_TRANSFER_DIRECTION {
+ FILE_TRANSFER_SEND,
+ FILE_TRANSFER_RECV
+} FILE_TRANSFER_DIRECTION;
+
+struct FileTransfer {
+ FILE *file;
+ FILE_TRANSFER_STATE state;
+ FILE_TRANSFER_DIRECTION direction;
+ char file_name[TOX_MAX_FILENAME_LENGTH + 1];
+ char file_path[PATH_MAX + 1]; /* Not used by senders */
+ double bps;
+ uint32_t filenum;
+ uint32_t friendnum;
+ size_t index;
+ uint64_t file_size;
+ uint64_t last_progress;
+ uint64_t position;
+ uint32_t line_id;
+};
+
+/* creates initial progress line that will be updated during file transfer.
+ progline must be at lesat MAX_STR_SIZE bytes */
+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 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.
+ * Returns NULL if filenum is invalid.
+ */
+struct FileTransfer *get_file_transfer_struct(uint32_t friendnum, uint32_t filenum);
+
+
+/* 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,
+ FILE_TRANSFER_DIRECTION direction);
+
+/* Returns a pointer to an unused file sender.
+ * Returns NULL if all file senders are in use.
+ */
+struct FileTransfer *get_new_file_sender(uint32_t friendnum);
+
+/* Returns a pointer to an unused file receiver.
+ * Returns NULL if all file receivers are in use.
+ */
+struct FileTransfer *get_new_file_receiver(uint32_t friendnum);
+
+/* Closes file transfer ft.
+ *
+ * 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.
+ */
+void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int CTRL, const char *message,
+ Notification sound_type);
+
+/* Kills all active file transfers for friendnum */
+void kill_all_file_transfers_friend(Tox *m, uint32_t friendnum);
+
+#endif /* #define FILE_TRANSFERS_H */
diff --git a/src/friendlist.c b/src/friendlist.c
index 0fb475a..8f352b2 100644
--- a/src/friendlist.c
+++ b/src/friendlist.c
@@ -59,16 +59,15 @@ static struct Blocked {
int num_selected;
int max_idx;
int num_blocked;
-
- int *index;
+ uint32_t *index;
BlockedFriend *list;
} Blocked;
-static struct pendingDel {
- int num;
+static struct PendingDel {
+ uint32_t num;
bool active;
WINDOW *popup;
-} pendingdelete;
+} PendingDelete;
static void realloc_friends(int n)
{
@@ -81,7 +80,7 @@ static void realloc_friends(int n)
}
ToxicFriend *f = realloc(Friends.list, n * sizeof(ToxicFriend));
- int *f_idx = realloc(Friends.index, n * sizeof(int));
+ uint32_t *f_idx = realloc(Friends.index, n * sizeof(uint32_t));
if (f == NULL || f_idx == NULL)
exit_toxic_err("failed in realloc_friends", FATALERR_MEMORY);
@@ -101,7 +100,7 @@ static void realloc_blocklist(int n)
}
BlockedFriend *b = realloc(Blocked.list, n * sizeof(BlockedFriend));
- int *b_idx = realloc(Blocked.index, n * sizeof(int));
+ uint32_t *b_idx = realloc(Blocked.index, n * sizeof(uint32_t));
if (b == NULL || b_idx == NULL)
exit_toxic_err("failed in realloc_blocklist", FATALERR_MEMORY);
@@ -125,9 +124,6 @@ void kill_friendlist(void)
static int save_blocklist(char *path)
{
- if (arg_opts.ignore_data_file)
- return 0;
-
if (path == NULL)
return -1;
@@ -193,7 +189,7 @@ int load_blocklist(char *path)
off_t len = file_size(path);
- if (len == -1) {
+ if (len == 0) {
fclose(fp);
return -1;
}
@@ -255,8 +251,8 @@ static int index_name_cmp(const void *n1, const void *n2)
int res = qsort_strcasecmp_hlpr(Friends.list[*(int *) n1].name, Friends.list[*(int *) n2].name);
/* Use weight to make qsort always put online friends before offline */
- res = Friends.list[*(int *) n1].online ? (res - S_WEIGHT) : (res + S_WEIGHT);
- res = Friends.list[*(int *) n2].online ? (res + S_WEIGHT) : (res - S_WEIGHT);
+ res = Friends.list[*(int *) n1].connection_status ? (res - S_WEIGHT) : (res + S_WEIGHT);
+ res = Friends.list[*(int *) n2].connection_status ? (res + S_WEIGHT) : (res - S_WEIGHT);
return res;
}
@@ -264,15 +260,15 @@ static int index_name_cmp(const void *n1, const void *n2)
/* sorts Friends.index first by connection status then alphabetically */
void sort_friendlist_index(void)
{
- int i;
- int n = 0;
+ size_t i;
+ uint32_t n = 0;
for (i = 0; i < Friends.max_idx; ++i) {
if (Friends.list[i].active)
Friends.index[n++] = Friends.list[i].num;
}
- qsort(Friends.index, Friends.num_friends, sizeof(int), index_name_cmp);
+ qsort(Friends.index, Friends.num_friends, sizeof(uint32_t), index_name_cmp);
}
static int index_name_cmp_block(const void *n1, const void *n2)
@@ -282,18 +278,18 @@ static int index_name_cmp_block(const void *n1, const void *n2)
static void sort_blocklist_index(void)
{
- int i;
- int n = 0;
+ size_t i;
+ uint32_t n = 0;
for (i = 0; i < Blocked.max_idx; ++i) {
if (Blocked.list[i].active)
Blocked.index[n++] = Blocked.list[i].num;
}
- qsort(Blocked.index, Blocked.num_blocked, sizeof(int), index_name_cmp_block);
+ qsort(Blocked.index, Blocked.num_blocked, sizeof(uint32_t), index_name_cmp_block);
}
-static void update_friend_last_online(int32_t num, uint64_t timestamp)
+static void update_friend_last_online(uint32_t num, uint64_t timestamp)
{
Friends.list[num].last_online.last_on = timestamp;
Friends.list[num].last_online.tm = *localtime((const time_t*)×tamp);
@@ -304,42 +300,48 @@ static void update_friend_last_online(int32_t num, uint64_t timestamp)
&Friends.list[num].last_online.tm);
}
-static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *str, uint16_t len)
+static void friendlist_onMessage(ToxWindow *self, Tox *m, uint32_t num, TOX_MESSAGE_TYPE type, const char *str,
+ size_t length)
{
if (num >= Friends.max_idx)
return;
- if (Friends.list[num].chatwin == -1) {
- if (get_num_active_windows() < MAX_WINDOWS_NUM) {
- Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
- } else {
- char nick[TOX_MAX_NAME_LENGTH];
- get_nick_truncate(m, nick, num);
+ if (Friends.list[num].chatwin != -1)
+ return;
- char timefrmt[TIME_STR_SIZE];
- get_time_str(timefrmt, sizeof(timefrmt));
-
- line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str);
-
- const char *msg = "* Warning: Too many windows are open.";
- line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg);
- sound_notify(prompt, error, NT_WNDALERT_1, NULL);
- }
+ if (get_num_active_windows() < MAX_WINDOWS_NUM) {
+ Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
+ return;
}
+
+ char nick[TOX_MAX_NAME_LENGTH];
+ get_nick_truncate(m, nick, num);
+
+ char timefrmt[TIME_STR_SIZE];
+ get_time_str(timefrmt, sizeof(timefrmt));
+
+ line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str);
+ line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Warning: Too many windows are open.");
+ sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
-static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
+static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_CONNECTION connection_status)
{
if (num >= Friends.max_idx)
return;
- Friends.list[num].online = status;
+ if (connection_status == TOX_CONNECTION_NONE)
+ --Friends.num_online;
+ else
+ ++Friends.num_online;
+
+ Friends.list[num].connection_status = connection_status;
update_friend_last_online(num, get_unix_time());
store_data(m, DATA_FILE);
sort_friendlist_index();
}
-static void friendlist_onNickChange(ToxWindow *self, Tox *m, int32_t num, const char *nick, uint16_t len)
+static void friendlist_onNickChange(ToxWindow *self, Tox *m, uint32_t num, const char *nick, size_t length)
{
if (num >= Friends.max_idx)
return;
@@ -354,9 +356,9 @@ static void friendlist_onNickChange(ToxWindow *self, Tox *m, int32_t num, const
/* get data for chatlog renaming */
char newnamecpy[TOXIC_MAX_NAME_LENGTH + 1];
- char myid[TOX_FRIEND_ADDRESS_SIZE];
+ char myid[TOX_ADDRESS_SIZE];
strcpy(newnamecpy, Friends.list[num].name);
- tox_get_address(m, (uint8_t *) myid);
+ tox_self_get_address(m, (uint8_t *) myid);
if (strcmp(oldname, newnamecpy) != 0)
rename_logfile(oldname, newnamecpy, myid, Friends.list[num].pub_key, Friends.list[num].chatwin);
@@ -364,7 +366,7 @@ static void friendlist_onNickChange(ToxWindow *self, Tox *m, int32_t num, const
sort_friendlist_index();
}
-static void friendlist_onStatusChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
+static void friendlist_onStatusChange(ToxWindow *self, Tox *m, uint32_t num, TOX_USER_STATUS status)
{
if (num >= Friends.max_idx)
return;
@@ -372,50 +374,47 @@ static void friendlist_onStatusChange(ToxWindow *self, Tox *m, int32_t num, uint
Friends.list[num].status = status;
}
-static void friendlist_onStatusMessageChange(ToxWindow *self, int32_t num, const char *status, uint16_t len)
+static void friendlist_onStatusMessageChange(ToxWindow *self, uint32_t num, const char *note, size_t length)
{
- if (len > TOX_MAX_STATUSMESSAGE_LENGTH || num >= Friends.max_idx)
+ if (length > TOX_MAX_STATUS_MESSAGE_LENGTH || num >= Friends.max_idx)
return;
- snprintf(Friends.list[num].statusmsg, sizeof(Friends.list[num].statusmsg), "%s", status);
+ snprintf(Friends.list[num].statusmsg, sizeof(Friends.list[num].statusmsg), "%s", note);
Friends.list[num].statusmsg_len = strlen(Friends.list[num].statusmsg);
}
-void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort)
+void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort)
{
- if (Friends.max_idx < 0)
- return;
-
-
- Friends.num_friends = tox_count_friendlist(m);
realloc_friends(Friends.max_idx + 1);
memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend));
- int i;
+ uint32_t i;
for (i = 0; i <= Friends.max_idx; ++i) {
if (Friends.list[i].active)
continue;
+ ++Friends.num_friends;
+
Friends.list[i].num = num;
Friends.list[i].active = true;
Friends.list[i].chatwin = -1;
- Friends.list[i].online = false;
- Friends.list[i].status = TOX_USERSTATUS_NONE;
+ Friends.list[i].connection_status = TOX_CONNECTION_NONE;
+ Friends.list[i].status = TOX_USER_STATUS_NONE;
Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON;
- tox_get_client_id(m, num, (uint8_t *) Friends.list[i].pub_key);
- update_friend_last_online(i, tox_get_last_online(m, i));
+
+ TOX_ERR_FRIEND_GET_PUBLIC_KEY err;
+ tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &err);
+
+ if (err != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK)
+ fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", err);
+
+ // update_friend_last_online(i, 0);
char tempname[TOX_MAX_NAME_LENGTH] = {0};
- int len = get_nick_truncate(m, tempname, num);
-
- if (len == -1 || tempname[0] == '\0') {
- strcpy(Friends.list[i].name, UNKNOWN_NAME);
- Friends.list[i].namelength = strlen(UNKNOWN_NAME);
- } else { /* Enforce toxic's maximum name length */
- snprintf(Friends.list[i].name, sizeof(Friends.list[i].name), "%s", tempname);
- Friends.list[i].namelength = strlen(Friends.list[i].name);
- }
+ get_nick_truncate(m, tempname, num);
+ snprintf(Friends.list[i].name, sizeof(Friends.list[i].name), "%s", tempname);
+ Friends.list[i].namelength = strlen(Friends.list[i].name);
if (i == Friends.max_idx)
++Friends.max_idx;
@@ -428,9 +427,8 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort)
}
/* puts blocked friend back in friendlist. fnum is new friend number, bnum is blocked number */
-static void friendlist_add_blocked(Tox *m, int32_t fnum, int32_t bnum)
+static void friendlist_add_blocked(Tox *m, uint32_t fnum, uint32_t bnum)
{
- Friends.num_friends = tox_count_friendlist(m);
realloc_friends(Friends.max_idx + 1);
memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend));
@@ -440,10 +438,12 @@ static void friendlist_add_blocked(Tox *m, int32_t fnum, int32_t bnum)
if (Friends.list[i].active)
continue;
+ ++Friends.num_friends;
+
Friends.list[i].num = fnum;
Friends.list[i].active = true;
Friends.list[i].chatwin = -1;
- Friends.list[i].status = TOX_USERSTATUS_NONE;
+ Friends.list[i].status = TOX_USER_STATUS_NONE;
Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON;
Friends.list[i].namelength = Blocked.list[bnum].namelength;
update_friend_last_online(i, Blocked.list[bnum].last_on);
@@ -460,27 +460,29 @@ static void friendlist_add_blocked(Tox *m, int32_t fnum, int32_t bnum)
}
}
-static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum,
- uint64_t filesize, const char *filename, uint16_t filename_len)
+static void friendlist_onFileRecv(ToxWindow *self, Tox *m, uint32_t num, uint32_t filenum,
+ uint64_t file_size, const char *filename, size_t name_length)
{
if (num >= Friends.max_idx)
return;
- if (Friends.list[num].chatwin == -1) {
- if (get_num_active_windows() < MAX_WINDOWS_NUM) {
- Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
- } else {
- tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
+ if (Friends.list[num].chatwin != -1)
+ return;
- char nick[TOX_MAX_NAME_LENGTH];
- get_nick_truncate(m, nick, num);
-
- line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
- "* File transfer from %s failed: too many windows are open.", nick);
-
- sound_notify(prompt, error, NT_WNDALERT_1, NULL);
- }
+ if (get_num_active_windows() < MAX_WINDOWS_NUM) {
+ Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
+ return;
}
+
+ tox_file_control(m, num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
+
+ char nick[TOX_MAX_NAME_LENGTH];
+ get_nick_truncate(m, nick, num);
+
+ line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
+ "* File transfer from %s failed: too many windows are open.", nick);
+
+ sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const char *data,
@@ -489,17 +491,21 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const
if (num >= Friends.max_idx)
return;
- if (Friends.list[num].chatwin == -1) {
- if (get_num_active_windows() < MAX_WINDOWS_NUM) {
- Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
- } else {
- char nick[TOX_MAX_NAME_LENGTH];
- get_nick_truncate(m, nick, num);
- line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
- "* Group chat invite from %s failed: too many windows are open.", nick);
- sound_notify(prompt, error, NT_WNDALERT_1, NULL);
- }
+ if (Friends.list[num].chatwin != -1)
+ return;
+
+ if (get_num_active_windows() < MAX_WINDOWS_NUM) {
+ Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
+ return;
}
+
+ char nick[TOX_MAX_NAME_LENGTH];
+ get_nick_truncate(m, nick, num);
+
+ line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
+ "* Group chat invite from %s failed: too many windows are open.", nick);
+
+ sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
/* move friendlist/blocklist cursor up and down */
@@ -516,8 +522,20 @@ static void select_friend(ToxWindow *self, wint_t key, int *selected, int num)
}
}
-static void delete_friend(Tox *m, int32_t f_num)
+static void delete_friend(Tox *m, uint32_t f_num)
{
+ TOX_ERR_FRIEND_DELETE err;
+ if (tox_friend_delete(m, f_num, &err) != true) {
+ fprintf(stderr, "tox_friend_delete failed with error %d\n", err);
+ return;
+ }
+
+ --Friends.num_friends;
+
+ if (Friends.list[f_num].connection_status != TOX_CONNECTION_NONE)
+ --Friends.num_online;
+
+ /* close friend's chatwindow if it's currently open */
if (Friends.list[f_num].chatwin >= 0) {
ToxWindow *toxwin = get_window_ptr(Friends.list[f_num].chatwin);
@@ -527,7 +545,6 @@ static void delete_friend(Tox *m, int32_t f_num)
}
}
- tox_del_friend(m, f_num);
memset(&Friends.list[f_num], 0, sizeof(ToxicFriend));
int i;
@@ -538,7 +555,6 @@ static void delete_friend(Tox *m, int32_t f_num)
}
Friends.max_idx = i;
- Friends.num_friends = tox_count_friendlist(m);
realloc_friends(i);
/* make sure num_selected stays within Friends.num_friends range */
@@ -549,60 +565,60 @@ static void delete_friend(Tox *m, int32_t f_num)
}
/* activates delete friend popup */
-static void del_friend_activate(ToxWindow *self, Tox *m, int32_t f_num)
+static void del_friend_activate(ToxWindow *self, Tox *m, uint32_t f_num)
{
- pendingdelete.popup = newwin(3, 22 + TOXIC_MAX_NAME_LENGTH, 8, 8);
- pendingdelete.active = true;
- pendingdelete.num = f_num;
+ PendingDelete.popup = newwin(3, 22 + TOXIC_MAX_NAME_LENGTH, 8, 8);
+ PendingDelete.active = true;
+ PendingDelete.num = f_num;
}
-static void delete_blocked_friend(int32_t bnum);
+static void delete_blocked_friend(uint32_t bnum);
/* deactivates delete friend popup and deletes friend if instructed */
static void del_friend_deactivate(ToxWindow *self, Tox *m, wint_t key)
{
if (key == 'y') {
if (blocklist_view == 0) {
- delete_friend(m, pendingdelete.num);
+ delete_friend(m, PendingDelete.num);
sort_friendlist_index();
} else {
- delete_blocked_friend(pendingdelete.num);
+ delete_blocked_friend(PendingDelete.num);
sort_blocklist_index();
}
}
- delwin(pendingdelete.popup);
- memset(&pendingdelete, 0, sizeof(pendingdelete));
+ delwin(PendingDelete.popup);
+ memset(&PendingDelete, 0, sizeof(PendingDelete));
clear();
refresh();
}
static void draw_del_popup(void)
{
- if (!pendingdelete.active)
+ if (!PendingDelete.active)
return;
- wattron(pendingdelete.popup, A_BOLD);
- box(pendingdelete.popup, ACS_VLINE, ACS_HLINE);
- wattroff(pendingdelete.popup, A_BOLD);
+ wattron(PendingDelete.popup, A_BOLD);
+ box(PendingDelete.popup, ACS_VLINE, ACS_HLINE);
+ wattroff(PendingDelete.popup, A_BOLD);
- wmove(pendingdelete.popup, 1, 1);
- wprintw(pendingdelete.popup, "Delete contact ");
- wattron(pendingdelete.popup, A_BOLD);
+ wmove(PendingDelete.popup, 1, 1);
+ wprintw(PendingDelete.popup, "Delete contact ");
+ wattron(PendingDelete.popup, A_BOLD);
if (blocklist_view == 0)
- wprintw(pendingdelete.popup, "%s", Friends.list[pendingdelete.num].name);
+ wprintw(PendingDelete.popup, "%s", Friends.list[PendingDelete.num].name);
else
- wprintw(pendingdelete.popup, "%s", Blocked.list[pendingdelete.num].name);
+ wprintw(PendingDelete.popup, "%s", Blocked.list[PendingDelete.num].name);
- wattroff(pendingdelete.popup, A_BOLD);
- wprintw(pendingdelete.popup, "? y/n");
+ wattroff(PendingDelete.popup, A_BOLD);
+ wprintw(PendingDelete.popup, "? y/n");
- wrefresh(pendingdelete.popup);
+ wrefresh(PendingDelete.popup);
}
/* deletes contact from blocked list */
-static void delete_blocked_friend(int32_t bnum)
+static void delete_blocked_friend(uint32_t bnum)
{
memset(&Blocked.list[bnum], 0, sizeof(BlockedFriend));
@@ -623,7 +639,7 @@ static void delete_blocked_friend(int32_t bnum)
}
/* deletes contact from friendlist and puts in blocklist */
-void block_friend(Tox *m, int32_t fnum)
+void block_friend(Tox *m, uint32_t fnum)
{
if (Friends.num_friends <= 0)
return;
@@ -642,7 +658,7 @@ void block_friend(Tox *m, int32_t fnum)
Blocked.list[i].namelength = Friends.list[fnum].namelength;
Blocked.list[i].last_on = Friends.list[fnum].last_online.last_on;
memcpy(Blocked.list[i].pub_key, Friends.list[fnum].pub_key, TOX_PUBLIC_KEY_SIZE);
- memcpy(Blocked.list[i].name, Friends.list[fnum].name, Friends.list[fnum].namelength + 1);
+ memcpy(Blocked.list[i].name, Friends.list[fnum].name, Friends.list[fnum].namelength + 1);
++Blocked.num_blocked;
@@ -659,15 +675,16 @@ void block_friend(Tox *m, int32_t fnum)
}
/* removes friend from blocklist, puts back in friendlist */
-static void unblock_friend(Tox *m, int32_t bnum)
+static void unblock_friend(Tox *m, uint32_t bnum)
{
if (Blocked.num_blocked <= 0)
return;
- int32_t friendnum = tox_add_friend_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key);
+ TOX_ERR_FRIEND_ADD err;
+ uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err);
- if (friendnum == -1) {
- line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend");
+ if (err != TOX_ERR_FRIEND_ADD_OK) {
+ line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)\n", err);
return;
}
@@ -704,7 +721,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
f = Friends.index[Friends.num_selected];
/* lock screen and force decision on deletion popup */
- if (pendingdelete.active) {
+ if (PendingDelete.active) {
if (key == 'y' || key == 'n')
del_friend_deactivate(self, m, key);
@@ -728,7 +745,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} else {
const char *msg = "* Warning: Too many windows are open.";
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg);
- sound_notify(prompt, error, NT_WNDALERT_1, NULL);
+ sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
break;
@@ -770,7 +787,7 @@ static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2)
if ((y2 - FLIST_OFST) <= 0)
return;
- int selected_num = 0;
+ uint32_t selected_num = 0;
/* Determine which portion of friendlist to draw based on current position */
int page = Blocked.num_selected / (y2 - FLIST_OFST);
@@ -780,7 +797,7 @@ static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2)
int i;
for (i = start; i < Blocked.num_blocked && i < end; ++i) {
- int f = Blocked.index[i];
+ uint32_t f = Blocked.index[i];
bool f_selected = false;
if (i == Blocked.num_selected) {
@@ -853,22 +870,18 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
return;
}
- uint64_t cur_time = get_unix_time();
- struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
-
- pthread_mutex_lock(&Winthread.lock);
- int nf = tox_get_num_online_friends(m);
- pthread_mutex_unlock(&Winthread.lock);
+ // uint64_t cur_time = get_unix_time();
+ // struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
wattron(self->window, A_BOLD);
wprintw(self->window, " Online: ");
wattroff(self->window, A_BOLD);
- wprintw(self->window, "%d/%d \n\n", nf, Friends.num_friends);
+ wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends);
if ((y2 - FLIST_OFST) <= 0)
return;
- int selected_num = 0;
+ uint32_t selected_num = 0;
/* Determine which portion of friendlist to draw based on current position */
int page = Friends.num_selected / (y2 - FLIST_OFST);
@@ -878,7 +891,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
int i;
for (i = start; i < Friends.num_friends && i < end; ++i) {
- int f = Friends.index[i];
+ uint32_t f = Friends.index[i];
bool f_selected = false;
if (Friends.list[f].active) {
@@ -892,26 +905,20 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
wprintw(self->window, " ");
}
- if (Friends.list[f].online) {
- uint8_t status = Friends.list[f].status;
- int colour = WHITE;
+ if (Friends.list[f].connection_status != TOX_CONNECTION_NONE) {
+ TOX_USER_STATUS status = Friends.list[f].status;
+ int colour = MAGENTA;
switch (status) {
- case TOX_USERSTATUS_NONE:
+ case TOX_USER_STATUS_NONE:
colour = GREEN;
break;
-
- case TOX_USERSTATUS_AWAY:
+ case TOX_USER_STATUS_AWAY:
colour = YELLOW;
break;
-
- case TOX_USERSTATUS_BUSY:
+ case TOX_USER_STATUS_BUSY:
colour = RED;
break;
-
- case TOX_USERSTATUS_INVALID:
- colour = MAGENTA;
- break;
}
wattron(self->window, COLOR_PAIR(colour) | A_BOLD);
@@ -930,11 +937,11 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
/* Reset Friends.list[f].statusmsg on window resize */
if (fix_statuses) {
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH];
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
pthread_mutex_lock(&Winthread.lock);
- int s_len = tox_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg,
- TOX_MAX_STATUSMESSAGE_LENGTH);
+ tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL);
+ size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL);
pthread_mutex_unlock(&Winthread.lock);
filter_str(statusmsg, s_len);
@@ -943,7 +950,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
}
/* Truncate note if it doesn't fit on one line */
- uint16_t maxlen = x2 - getcurx(self->window) - 2;
+ size_t maxlen = x2 - getcurx(self->window) - 2;
if (Friends.list[f].statusmsg_len > maxlen) {
Friends.list[f].statusmsg[maxlen - 3] = '\0';
@@ -969,31 +976,34 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
if (f_selected)
wattroff(self->window, COLOR_PAIR(BLUE));
- uint64_t last_seen = Friends.list[f].last_online.last_on;
+ wprintw(self->window, "\n");
+ /* Last online is currently broken in core */
- if (last_seen != 0) {
- int day_dist = (
- cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday
- + ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365)
- );
- const char *hourmin = Friends.list[f].last_online.hour_min_str;
+ // uint64_t last_seen = Friends.list[f].last_online.last_on;
+ //
+ // if (last_seen != 0) {
+ // int day_dist = (
+ // cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday
+ // + ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365)
+ // );
+ // const char *hourmin = Friends.list[f].last_online.hour_min_str;
- switch (day_dist) {
- case 0:
- wprintw(self->window, " Last seen: Today %s\n", hourmin);
- break;
+ // switch (day_dist) {
+ // case 0:
+ // wprintw(self->window, " Last seen: Today %s\n", hourmin);
+ // break;
- case 1:
- wprintw(self->window, " Last seen: Yesterday %s\n", hourmin);
- break;
+ // case 1:
+ // wprintw(self->window, " Last seen: Yesterday %s\n", hourmin);
+ // break;
- default:
- wprintw(self->window, " Last seen: %d days ago\n", day_dist);
- break;
- }
- } else {
- wprintw(self->window, " Last seen: Never\n");
- }
+ // default:
+ // wprintw(self->window, " Last seen: %d days ago\n", day_dist);
+ // break;
+ // }
+ // } else {
+ // wprintw(self->window, " Last seen: Never\n");
+ // }
}
}
}
@@ -1020,7 +1030,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
help_onDraw(self);
}
-void disable_chatwin(int32_t f_num)
+void disable_chatwin(uint32_t f_num)
{
Friends.list[f_num].chatwin = -1;
}
@@ -1048,7 +1058,7 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
const char *errmsg = "* Warning: Too many windows are open.";
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
- sound_notify(prompt, error, NT_WNDALERT_1, NULL);
+ sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
}
}
@@ -1067,11 +1077,10 @@ ToxWindow new_friendlist(void)
ret.onFriendAdded = &friendlist_onFriendAdded;
ret.onMessage = &friendlist_onMessage;
ret.onConnectionChange = &friendlist_onConnectionChange;
- ret.onAction = &friendlist_onMessage; /* Action has identical behaviour to message */
ret.onNickChange = &friendlist_onNickChange;
ret.onStatusChange = &friendlist_onStatusChange;
ret.onStatusMessageChange = &friendlist_onStatusMessageChange;
- ret.onFileSendRequest = &friendlist_onFileSendRequest;
+ ret.onFileRecv = &friendlist_onFileRecv;
ret.onGroupInvite = &friendlist_onGroupInvite;
#ifdef AUDIO
diff --git a/src/friendlist.h b/src/friendlist.h
index 0969b47..b7c612b 100644
--- a/src/friendlist.h
+++ b/src/friendlist.h
@@ -27,20 +27,7 @@
#include "toxic.h"
#include "windows.h"
-#include "file_senders.h"
-
-struct FileReceiver {
- char filename[MAX_STR_SIZE];
- int filenum;
- FILE *file;
- bool pending;
- bool active;
- uint64_t size;
- uint64_t bytes_recv;
- double bps;
- uint64_t last_progress; /* unix-time when we last updated progress */
- uint32_t line_id;
-};
+#include "file_transfers.h"
struct LastOnline {
uint64_t last_on;
@@ -56,45 +43,47 @@ struct GroupInvite {
typedef struct {
char name[TOXIC_MAX_NAME_LENGTH + 1];
int namelength;
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH + 1];
- uint16_t statusmsg_len;
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH + 1];
+ size_t statusmsg_len;
char pub_key[TOX_PUBLIC_KEY_SIZE];
- int32_t num;
+ uint32_t num;
int chatwin;
bool active;
- bool online;
- uint8_t is_typing;
+ TOX_CONNECTION connection_status;
+ bool is_typing;
bool logging_on; /* saves preference for friend irrespective of global settings */
uint8_t status;
- struct GroupInvite group_invite;
+
struct LastOnline last_online;
- struct FileReceiver file_receiver[MAX_FILES];
- uint8_t active_file_receivers;
+ struct GroupInvite group_invite;
+ struct FileTransfer file_receiver[MAX_FILES];
+ struct FileTransfer file_sender[MAX_FILES];
} ToxicFriend;
typedef struct {
char name[TOXIC_MAX_NAME_LENGTH + 1];
int namelength;
char pub_key[TOX_PUBLIC_KEY_SIZE];
- int32_t num;
+ uint32_t num;
bool active;
uint64_t last_on;
} BlockedFriend;
typedef struct {
int num_selected;
- int max_idx; /* 1 + the index of the last friend in list */
- int num_friends;
- int *index;
+ size_t num_friends;
+ size_t num_online;
+ size_t max_idx; /* 1 + the index of the last friend in list */
+ uint32_t *index;
ToxicFriend *list;
} FriendsList;
ToxWindow new_friendlist(void);
-void disable_chatwin(int32_t f_num);
+void disable_chatwin(uint32_t f_num);
int get_friendnum(uint8_t *name);
int load_blocklist(char *data);
void kill_friendlist(void);
-void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort);
+void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort);
/* sorts friendlist_index first by connection status then alphabetically */
void sort_friendlist_index(void);
diff --git a/src/global_commands.c b/src/global_commands.c
index 6d762b9..ede6e5d 100644
--- a/src/global_commands.c
+++ b/src/global_commands.c
@@ -61,13 +61,14 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
return;
}
- const char *msg;
- int32_t friendnum = tox_add_friend_norequest(m, FrndRequests.request[req].key);
+ TOX_ERR_FRIEND_ADD err;
+ uint32_t friendnum = tox_friend_add_norequest(m, FrndRequests.request[req].key, &err);
- if (friendnum == -1)
- msg = "Failed to add friend.";
- else {
- msg = "Friend request accepted.";
+ if (err != TOX_ERR_FRIEND_ADD_OK) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to add friend (error %d\n)", err);
+ return;
+ } else {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Friend request accepted.");
on_friendadded(m, friendnum, true);
}
@@ -82,47 +83,55 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
FrndRequests.max_idx = i;
--FrndRequests.num_requests;
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
+
}
-void cmd_add_helper(ToxWindow *self, Tox *m, char *id_bin, char *msg)
+void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg)
{
const char *errmsg;
- int32_t f_num = tox_add_friend(m, (uint8_t *) id_bin, (uint8_t *) msg, (uint16_t) strlen(msg));
- switch (f_num) {
- case TOX_FAERR_TOOLONG:
+ TOX_ERR_FRIEND_ADD err;
+ uint32_t f_num = tox_friend_add(m, (uint8_t *) id_bin, (uint8_t *) msg, strlen(msg), &err);
+
+ switch (err) {
+ case TOX_ERR_FRIEND_ADD_TOO_LONG:
errmsg = "Message is too long.";
break;
- case TOX_FAERR_NOMESSAGE:
+ case TOX_ERR_FRIEND_ADD_NO_MESSAGE:
errmsg = "Please add a message to your request.";
break;
- case TOX_FAERR_OWNKEY:
+ case TOX_ERR_FRIEND_ADD_OWN_KEY:
errmsg = "That appears to be your own ID.";
break;
- case TOX_FAERR_ALREADYSENT:
+ case TOX_ERR_FRIEND_ADD_ALREADY_SENT:
errmsg = "Friend request has already been sent.";
break;
- case TOX_FAERR_UNKNOWN:
- errmsg = "Undefined error when adding friend.";
- break;
-
- case TOX_FAERR_BADCHECKSUM:
+ case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM:
errmsg = "Bad checksum in address.";
break;
- case TOX_FAERR_SETNEWNOSPAM:
+ case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM:
errmsg = "Nospam was different.";
break;
- default:
+ case TOX_ERR_FRIEND_ADD_MALLOC:
+ errmsg = "Core memory allocation failed.";
+ break;
+
+ case TOX_ERR_FRIEND_ADD_OK:
errmsg = "Friend request sent.";
on_friendadded(m, f_num, true);
break;
+
+ case TOX_ERR_FRIEND_ADD_NULL:
+ /* fallthrough */
+ default:
+ errmsg = "Faile to add friend: Unknown error.";
+ break;
}
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
@@ -152,21 +161,23 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
snprintf(msg, sizeof(msg), "%s", tmp);
} else {
char selfname[TOX_MAX_NAME_LENGTH];
- uint16_t n_len = tox_get_self_name(m, (uint8_t *) selfname);
+ tox_self_get_name(m, (uint8_t *) selfname);
+
+ size_t n_len = tox_self_get_name_size(m);
selfname[n_len] = '\0';
snprintf(msg, sizeof(msg), "Hello, my name is %s. Care to Tox?", selfname);
}
- char id_bin[TOX_FRIEND_ADDRESS_SIZE] = {0};
+ char id_bin[TOX_ADDRESS_SIZE] = {0};
uint16_t id_len = (uint16_t) strlen(id);
/* try to add tox ID */
- if (id_len == 2 * TOX_FRIEND_ADDRESS_SIZE) {
+ if (id_len == 2 * TOX_ADDRESS_SIZE) {
size_t i;
char xx[3];
uint32_t x;
- for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; ++i) {
+ for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
xx[2] = '\0';
@@ -187,77 +198,72 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
- if (argc < 2) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: No file path supplied.");
- return;
- }
+ // if (argc < 2) {
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: No file path supplied.");
+ // return;
+ // }
- /* turns the avatar off */
- if (strlen(argv[1]) < 3) {
- tox_unset_avatar(m);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No avatar set.");
- return;
- }
+ // /* turns the avatar off */
+ // if (strlen(argv[1]) < 3) {
+ // tox_unset_avatar(m);
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No avatar set.");
+ // return;
+ // }
- if (argv[1][0] != '\"') {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes.");
- return;
- }
+ // if (argv[1][0] != '\"') {
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes.");
+ // return;
+ // }
- /* remove opening and closing quotes */
- char path[MAX_STR_SIZE];
- snprintf(path, sizeof(path), "%s", &argv[1][1]);
- int len = strlen(path) - 1;
- path[len] = '\0';
+ // /* remove opening and closing quotes */
+ // char path[MAX_STR_SIZE];
+ // snprintf(path, sizeof(path), "%s", &argv[1][1]);
+ // int len = strlen(path) - 1;
+ // path[len] = '\0';
- off_t sz = file_size(path);
+ // off_t sz = file_size(path);
- if (sz <= 8) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Invalid file.");
- return;
- }
+ // if (sz <= 8) {
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Invalid file.");
+ // return;
+ // }
- if (sz > TOX_AVATAR_MAX_DATA_LENGTH) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File is too large.");
- return;
- }
+ // FILE *fp = fopen(path, "rb");
- FILE *fp = fopen(path, "rb");
+ // if (fp == NULL) {
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Could not open file.");
+ // return;
+ // }
- if (fp == NULL) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Could not open file.");
- return;
- }
+ // char PNG_signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
- char PNG_signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
+ // if (check_file_signature(PNG_signature, sizeof(PNG_signature), fp) != 0) {
+ // fclose(fp);
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File type not supported.");
+ // return;
+ // }
- if (check_file_signature(PNG_signature, sizeof(PNG_signature), fp) != 0) {
- fclose(fp);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File type not supported.");
- return;
- }
+ // char *avatar = malloc(sz);
- char *avatar = malloc(sz);
+ // if (avatar == NULL)
+ // exit_toxic_err("Failed in cmd_avatar", FATALERR_MEMORY);
- if (avatar == NULL)
- exit_toxic_err("Failed in set_avatar", FATALERR_MEMORY);
+ // if (fread(avatar, sz, 1, fp) != 1) {
+ // fclose(fp);
+ // free(avatar);
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Read fail.");
+ // return;
+ // }
- if (fread(avatar, sz, 1, fp) != 1) {
- fclose(fp);
- free(avatar);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Read fail.");
- return;
- }
+ // if (tox_set_avatar(m, TOX_AVATAR_FORMAT_PNG, (const uint8_t *) avatar, (uint32_t) sz) == -1)
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar");
- if (tox_set_avatar(m, TOX_AVATAR_FORMAT_PNG, (const uint8_t *) avatar, (uint32_t) sz) == -1)
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Core error.");
+ // char filename[MAX_STR_SIZE];
+ // get_file_name(filename, sizeof(filename), path);
+ // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename);
- char filename[MAX_STR_SIZE];
- get_file_name(filename, sizeof(filename), path);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename);
-
- fclose(fp);
- free(avatar);
+ // fclose(fp);
+ // free(avatar);
}
void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@@ -283,8 +289,26 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
}
char *binary_string = hex_string_to_bin(key);
- tox_bootstrap_from_address(m, ip, atoi(port), (uint8_t *) binary_string);
+
+ TOX_ERR_BOOTSTRAP err;
+ tox_bootstrap(m, ip, atoi(port), (uint8_t *) binary_string, &err);
free(binary_string);
+
+ switch (err) {
+ case TOX_ERR_BOOTSTRAP_BAD_HOST:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid IP.");
+ break;
+
+ case TOX_ERR_BOOTSTRAP_BAD_PORT:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid port.");
+ break;
+
+ case TOX_ERR_BOOTSTRAP_NULL:
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed.");
+ break;
+ default:
+ break;
+ }
}
void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@@ -456,8 +480,8 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
const char *swch = argv[1];
if (!strcmp(swch, "1") || !strcmp(swch, "on")) {
- char myid[TOX_FRIEND_ADDRESS_SIZE];
- tox_get_address(m, (uint8_t *) myid);
+ char myid[TOX_ADDRESS_SIZE];
+ tox_self_get_address(m, (uint8_t *) myid);
if (self->is_chat) {
Friends.list[self->num].logging_on = true;
@@ -488,13 +512,13 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
- char id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
- char address[TOX_FRIEND_ADDRESS_SIZE];
- tox_get_address(m, (uint8_t *) address);
+ char id[TOX_ADDRESS_SIZE * 2 + 1] = {0};
+ char address[TOX_ADDRESS_SIZE];
+ tox_self_get_address(m, (uint8_t *) address);
size_t i;
- for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; ++i) {
+ for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
char xx[3];
snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
strcat(id, xx);
@@ -511,7 +535,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
}
char nick[MAX_STR_SIZE];
- int len = 0;
+ size_t len = 0;
if (argv[1][0] == '\"') { /* remove opening and closing quotes */
snprintf(nick, sizeof(nick), "%s", &argv[1][1]);
@@ -530,11 +554,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
nick[len] = '\0';
- if (tox_set_name(m, (uint8_t *) nick, (uint16_t) len) == -1) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Core error setting nick.");
- return;
- }
-
+ tox_self_set_name(m, (uint8_t *) nick, len, NULL);
prompt_update_nick(prompt, nick);
set_nick_all_groups(m, nick, len);
@@ -606,31 +626,24 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
goto finish;
}
- char status[MAX_STR_SIZE];
- snprintf(status, sizeof(status), "%s", argv[1]);
- str_to_lower(status);
+ const char *status_str = argv[1];
+ TOX_USER_STATUS status;
- TOX_USERSTATUS status_kind;
-
- if (!strcmp(status, "online"))
- status_kind = TOX_USERSTATUS_NONE;
- else if (!strcmp(status, "away"))
- status_kind = TOX_USERSTATUS_AWAY;
- else if (!strcmp(status, "busy"))
- status_kind = TOX_USERSTATUS_BUSY;
+ if (!strcasecmp(status_str, "online"))
+ status = TOX_USER_STATUS_NONE;
+ else if (!strcasecmp(status_str, "away"))
+ status = TOX_USER_STATUS_AWAY;
+ else if (!strcasecmp(status_str, "busy"))
+ status = TOX_USER_STATUS_BUSY;
else {
errmsg = "Invalid status. Valid statuses are: online, busy and away.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
goto finish;
}
- if (tox_set_user_status(m, status_kind) == -1) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Core failed to set status\n");
- return;
- }
-
- set_status_all_groups(m, status_kind);
- prompt_update_status(prompt, status_kind);
+ tox_self_set_status(m, status);
+ prompt_update_status(prompt, status);
+ set_status_all_groups(m, status);
if (have_note) {
if (argv[2][0] != '\"') {
diff --git a/src/global_commands.h b/src/global_commands.h
index 6f2ff03..4615087 100644
--- a/src/global_commands.h
+++ b/src/global_commands.h
@@ -43,7 +43,7 @@ void cmd_quit(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]
void cmd_requests(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_status(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
-void cmd_add_helper(ToxWindow *self, Tox *m, char *id_bin, char *msg);
+void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg);
#ifdef AUDIO
void cmd_list_devices(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
diff --git a/src/groupchat.c b/src/groupchat.c
index f024b68..93b2c66 100644
--- a/src/groupchat.c
+++ b/src/groupchat.c
@@ -284,7 +284,9 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int
get_group_nick_truncate(m, nick, peernum, groupnum);
char selfnick[TOX_MAX_NAME_LENGTH];
- uint16_t sn_len = tox_group_get_self_name(m, groupnum, (uint8_t *) selfnick);
+ tox_self_get_name(m, (uint8_t *) selfnick);
+
+ size_t sn_len = tox_self_get_name_size(m);
selfnick[sn_len] = '\0';
int nick_clr = CYAN;
@@ -323,7 +325,9 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p
get_group_nick_truncate(m, nick, peernum, groupnum);
char selfnick[TOX_MAX_NAME_LENGTH];
- uint16_t n_len = tox_group_get_self_name(m, groupnum, (uint8_t *) selfnick);
+ tox_self_get_name(m, (uint8_t *) selfnick);
+
+ size_t n_len = tox_self_get_name_size(m);
selfnick[n_len] = '\0';
if (strcasestr(action, selfnick)) {
@@ -782,10 +786,10 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
}
} else {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
} else {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
} else if (key == user_settings->key_peer_list_down) { /* Scroll peerlist up and down one position */
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
@@ -931,8 +935,8 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
line_info_init(ctx->hst);
if (user_settings->autolog == AUTOLOG_ON) {
- char myid[TOX_FRIEND_ADDRESS_SIZE];
- tox_get_address(m, (uint8_t *) myid);
+ char myid[TOX_ADDRESS_SIZE];
+ tox_self_get_address(m, (uint8_t *) myid);
log_enable(self->name, myid, NULL, ctx->log, LOG_GROUP);
}
diff --git a/src/input.c b/src/input.c
index 0024455..86f94f1 100644
--- a/src/input.c
+++ b/src/input.c
@@ -46,12 +46,12 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_
/* this is the only place we need to do this check */
if (cur_len == -1) {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
return;
}
if (add_char_to_buf(ctx, key) == -1) {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
return;
}
@@ -67,7 +67,7 @@ static void input_backspace(ToxWindow *self, int x, int mx_x)
ChatContext *ctx = self->chatwin;
if (del_char_buf_bck(ctx) == -1) {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
return;
}
@@ -84,7 +84,7 @@ static void input_backspace(ToxWindow *self, int x, int mx_x)
static void input_delete(ToxWindow *self)
{
if (del_char_buf_frnt(self->chatwin) == -1)
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
/* delete last typed word */
@@ -93,7 +93,7 @@ static void input_del_word(ToxWindow *self, int x, int mx_x)
ChatContext *ctx = self->chatwin;
if (del_word_buf(ctx) == -1) {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
return;
}
}
@@ -102,14 +102,14 @@ static void input_del_word(ToxWindow *self, int x, int mx_x)
static void input_discard(ToxWindow *self)
{
if (discard_buf(self->chatwin) == -1)
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
/* deletes entire line after cursor from input field and buffer */
static void input_kill(ChatContext *ctx)
{
if (kill_buf(ctx) == -1)
- sound_notify(NULL, error, NT_ALWAYS, NULL);
+ sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
}
static void input_yank(ToxWindow *self, int x, int mx_x)
@@ -117,7 +117,7 @@ static void input_yank(ToxWindow *self, int x, int mx_x)
ChatContext *ctx = self->chatwin;
if (yank_buf(ctx) == -1) {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
return;
}
@@ -264,7 +264,7 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
break;
}
- /* TODO: this special case is ugly.
+ /* TODO: this special case is ugly.
maybe convert entire function to if/else and make them all customizable keys? */
if (!match && key == user_settings->key_toggle_peerlist) {
if (self->is_groupchat) {
diff --git a/src/line_info.c b/src/line_info.c
index 460ad78..1ea7b6e 100644
--- a/src/line_info.c
+++ b/src/line_info.c
@@ -155,11 +155,13 @@ void line_info_add(ToxWindow *self, const char *timestr, const char *name1, cons
/* for type-specific formatting in print function */
switch (type) {
case IN_ACTION:
+ /* fallthrough */
case OUT_ACTION:
len += strlen(user_settings->line_normal) + 2;
break;
case IN_MSG:
+ /* fallthrough */
case OUT_MSG:
len += strlen(user_settings->line_normal) + 3;
break;
@@ -304,7 +306,9 @@ void line_info_print(ToxWindow *self)
switch (type) {
case OUT_MSG:
+ /* fallthrough */
case OUT_MSG_READ:
+ /* fallthrough */
case IN_MSG:
case IN_PRVT_MSG:
case OUT_PRVT_MSG:
@@ -349,7 +353,9 @@ void line_info_print(ToxWindow *self)
break;
case OUT_ACTION_READ:
+ /* fallthrough */
case OUT_ACTION:
+ /* fallthrough */
case IN_ACTION:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
@@ -494,14 +500,14 @@ static void line_info_scroll_up(struct history *hst)
{
if (hst->line_start->prev)
hst->line_start = hst->line_start->prev;
- else sound_notify(NULL, error, NT_ALWAYS, NULL);
+ else sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
}
static void line_info_scroll_down(struct history *hst)
{
if (hst->line_start->next)
hst->line_start = hst->line_start->next;
- else sound_notify(NULL, error, NT_ALWAYS, NULL);
+ else sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
}
static void line_info_page_up(ToxWindow *self, struct history *hst)
diff --git a/src/message_queue.c b/src/message_queue.c
index 845b9da..70ccadb 100644
--- a/src/message_queue.c
+++ b/src/message_queue.c
@@ -42,7 +42,7 @@ void cqueue_cleanup(struct chat_queue *q)
free(q);
}
-void cqueue_add(struct chat_queue *q, const char *msg, int len, uint8_t type, uint32_t line_id)
+void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type, uint32_t line_id)
{
struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg));
@@ -103,7 +103,9 @@ void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt)
}
char selfname[TOX_MAX_NAME_LENGTH];
- uint16_t len = tox_get_self_name(m, (uint8_t *) selfname);
+ tox_self_get_name(m, (uint8_t *) selfname);
+
+ size_t len = tox_self_get_name_size(m);
selfname[len] = '\0';
write_to_log(msg->message, selfname, self->chatwin->log, msg->type == OUT_ACTION);
@@ -145,10 +147,8 @@ void cqueue_try_send(ToxWindow *self, Tox *m)
uint32_t receipt = 0;
- if (msg->type == OUT_MSG)
- receipt = tox_send_message(m, self->num, (uint8_t *) msg->message, msg->len);
- else
- receipt = tox_send_action(m, self->num, (uint8_t *) msg->message, msg->len);
+ TOX_MESSAGE_TYPE type = msg->type == OUT_MSG ? TOX_MESSAGE_TYPE_NORMAL : TOX_MESSAGE_TYPE_ACTION;
+ receipt = tox_friend_send_message(m, self->num, type, (uint8_t *) msg->message, msg->len, NULL);
msg->last_send_try = curtime;
msg->receipt = receipt;
diff --git a/src/message_queue.h b/src/message_queue.h
index b82cec3..df0317e 100644
--- a/src/message_queue.h
+++ b/src/message_queue.h
@@ -25,7 +25,7 @@
struct cqueue_msg {
char message[MAX_STR_SIZE];
- int len;
+ size_t len;
int line_id;
uint8_t type;
uint32_t receipt;
@@ -40,7 +40,7 @@ struct chat_queue {
};
void cqueue_cleanup(struct chat_queue *q);
-void cqueue_add(struct chat_queue *q, const char *msg, int len, uint8_t type, uint32_t line_id);
+void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type, uint32_t line_id);
/* Tries to send the oldest unsent message in queue. */
void cqueue_try_send(ToxWindow *self, Tox *m);
@@ -48,4 +48,4 @@ void cqueue_try_send(ToxWindow *self, Tox *m);
/* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */
void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt);
-#endif /* #define MESSAGE_QUEUE_H */
\ No newline at end of file
+#endif /* #define MESSAGE_QUEUE_H */
diff --git a/src/misc_tools.c b/src/misc_tools.c
index 736e495..3990327 100644
--- a/src/misc_tools.c
+++ b/src/misc_tools.c
@@ -32,7 +32,7 @@
#include "windows.h"
#include "misc_tools.h"
#include "settings.h"
-#include "file_senders.h"
+#include "file_transfers.h"
extern ToxWindow *prompt;
extern struct user_settings *user_settings;
@@ -212,9 +212,9 @@ int valid_nick(const char *nick)
}
/* Converts all newline/tab chars to spaces (use for strings that should be contained to a single line) */
-void filter_str(char *str, int len)
+void filter_str(char *str, size_t len)
{
- int i;
+ size_t i;
for (i = 0; i < len; ++i) {
if (str[i] == '\n' || str[i] == '\r' || str[i] == '\t' || str[i] == '\v')
@@ -222,17 +222,19 @@ void filter_str(char *str, int len)
}
}
-/* gets base file name from path or original file name if no path is supplied */
-void get_file_name(char *namebuf, int bufsize, const char *pathname)
+/* gets base file name from path or original file name if no path is supplied.
+ * Returns the file name length
+ */
+size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname)
{
- int idx = strlen(pathname) - 1;
+ int len = strlen(pathname) - 1;
char *path = strdup(pathname);
if (path == NULL)
exit_toxic_err("failed in get_file_name", FATALERR_MEMORY);
- while (idx >= 0 && pathname[idx] == '/')
- path[idx--] = '\0';
+ while (len >= 0 && pathname[len] == '/')
+ path[len--] = '\0';
char *finalname = strdup(path);
@@ -249,6 +251,8 @@ void get_file_name(char *namebuf, int bufsize, const char *pathname)
snprintf(namebuf, bufsize, "%s", finalname);
free(finalname);
free(path);
+
+ return strlen(namebuf);
}
/* converts str to all lowercase */
@@ -263,13 +267,15 @@ void str_to_lower(char *str)
/* puts friendnum's nick in buf, truncating at TOXIC_MAX_NAME_LENGTH if necessary.
if toxcore API call fails, put UNKNOWN_NAME in buf
Returns nick len */
-int get_nick_truncate(Tox *m, char *buf, int friendnum)
+size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum)
{
- int len = tox_get_name(m, friendnum, (uint8_t *) buf);
+ size_t len = tox_friend_get_name_size(m, friendnum, NULL);
- if (len == -1) {
+ if (len == 0) {
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
+ } else {
+ tox_friend_get_name(m, friendnum, (uint8_t *) buf, NULL);
}
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
@@ -297,7 +303,7 @@ int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum)
/* copies data to msg buffer.
returns length of msg.
returns 0 and nulls msg if length is too big for buffer size */
-uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length)
+size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length)
{
if (length > size - 1) {
msg[0] = '\0';
@@ -366,13 +372,13 @@ bool file_exists(const char *path)
return stat(path, &s) == 0;
}
-/* returns file size or -1 on error */
+/* returns file size. If file doesn't exist returns 0. */
off_t file_size(const char *path)
{
struct stat st;
if (stat(path, &st) == -1)
- return -1;
+ return 0;
return st.st_size;
}
diff --git a/src/misc_tools.h b/src/misc_tools.h
index 970faaa..3a5ca09 100644
--- a/src/misc_tools.h
+++ b/src/misc_tools.h
@@ -92,17 +92,17 @@ int qsort_strcasecmp_hlpr(const void *str1, const void *str2);
int valid_nick(const char *nick);
/* Converts all newline/tab chars to spaces (use for strings that should be contained to a single line) */
-void filter_str(char *str, int len);
+void filter_str(char *str, size_t len);
/* gets base file name from path or original file name if no path is supplied */
-void get_file_name(char *namebuf, int bufsize, const char *pathname);
+size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname);
/* converts str to all lowercase */
void str_to_lower(char *str);
/* puts friendnum's nick in buf, truncating at TOXIC_MAX_NAME_LENGTH if necessary.
Returns nick len on success, -1 on failure */
-int get_nick_truncate(Tox *m, char *buf, int friendnum);
+size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum);
/* same as get_nick_truncate but for groupchats */
int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum);
@@ -110,7 +110,7 @@ int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum);
/* copies data to msg buffer.
returns length of msg.
returns 0 and nulls msg if length is too big for buffer size */
-uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length);
+size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length);
/* returns index of the first instance of ch in s starting at idx.
returns length of s if char not found */
@@ -126,7 +126,7 @@ void bytes_convert_str(char *buf, int size, uint64_t bytes);
/* checks if a file exists. Returns true or false */
bool file_exists(const char *path);
-/* returns file size or -1 on error */
+/* returns file size. If file doesn't exist returns 0. */
off_t file_size(const char *path);
/* compares the first size bytes of fp and signature.
diff --git a/src/notify.c b/src/notify.c
index 2346991..8560659 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -1,5 +1,5 @@
/* notify.c
- *
+ *
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
@@ -67,12 +67,12 @@ extern struct user_settings *user_settings;
struct Control {
time_t cooldown;
time_t notif_timeout;
-
+
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
pthread_mutex_t poll_mutex[1];
bool poll_active;
#endif
-
+
#ifdef SOUND_NOTIFY
uint32_t device_idx; /* index of output device */
char* sounds[SOUNDS_SIZE];
@@ -107,11 +107,11 @@ static void tab_notify(ToxWindow *self, uint64_t flags)
if (self == NULL)
return;
- if (flags & NT_WNDALERT_0)
+ if (flags & NT_WNDALERT_0)
self->alert = WINDOW_ALERT_0;
- else if ( (flags & NT_WNDALERT_1) && (!self->alert || self->alert > WINDOW_ALERT_0) )
+ else if ( (flags & NT_WNDALERT_1) && (!self->alert || self->alert > WINDOW_ALERT_0) )
self->alert = WINDOW_ALERT_1;
- else if ( (flags & NT_WNDALERT_2) && (!self->alert || self->alert > WINDOW_ALERT_1) )
+ else if ( (flags & NT_WNDALERT_2) && (!self->alert || self->alert > WINDOW_ALERT_1) )
self->alert = WINDOW_ALERT_2;
}
@@ -154,14 +154,14 @@ static bool device_opened = false;
time_t last_opened_update = 0;
bool m_open_device()
-{
+{
last_opened_update = get_unix_time();
-
+
if (device_opened) return true;
-
+
/* Blah error check */
open_primary_device(output, &Control.device_idx, 48000, 20, 1);
-
+
return (device_opened = true);
}
@@ -194,9 +194,9 @@ void graceful_clear()
*actives[i].id_indicator = -1; /* reset indicator value */
if ( actives[i].looping ) {
- stop_sound(i);
+ stop_sound(i);
} else {
- if (!is_playing(actives[i].source))
+ if (!is_playing(actives[i].source))
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
else break;
}
@@ -217,17 +217,17 @@ void* do_playing(void* _p)
{
(void)_p;
int i;
-
+
bool has_looping = false;
-
+
while(Control.poll_active) {
control_lock();
-
-
+
+
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
-
+
if (actives[i].looping) has_looping = true;
-
+
if (actives[i].active && !actives[i].looping
#ifdef BOX_NOTIFY
&& !actives[i].box
@@ -237,7 +237,7 @@ void* do_playing(void* _p)
*actives[i].id_indicator = -1; /* reset indicator value */
if (!is_playing(actives[i].source)) {
- /* Close */
+ /* Close */
alSourceStop(actives[i].source);
alDeleteSources(1, &actives[i].source);
alDeleteBuffers(1, &actives[i].buffer);
@@ -263,14 +263,14 @@ void* do_playing(void* _p)
}
#endif
}
-
+
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
- if (device_opened && !has_looping &&
+ if (device_opened && !has_looping &&
(get_unix_time() - last_opened_update) > DEVICE_COOLDOWN) {
m_close_device();
}
has_looping = false;
-
+
control_unlock();
usleep(10000);
}
@@ -278,20 +278,20 @@ void* do_playing(void* _p)
}
int play_source(uint32_t source, uint32_t buffer, bool looping)
-{
+{
int i = 0;
for (; i < ACTIVE_NOTIFS_MAX && actives[i].active; i ++);
if ( i == ACTIVE_NOTIFS_MAX ) {
return -1; /* Full */
}
-
+
alSourcePlay(source);
-
+
actives[i].active = 1;
actives[i].source = source;
actives[i].buffer = buffer;
actives[i].looping = looping;
-
+
return i;
}
@@ -324,20 +324,20 @@ void graceful_clear()
{
int i;
control_lock();
-
+
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
if (actives[i].box) {
GError* ignore;
notify_notification_close(actives[i].box, &ignore);
actives[i].box = NULL;
}
-
+
if (actives[i].id_indicator)
*actives[i].id_indicator = -1; /* reset indicator value */
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
- }
-
+ }
+
control_unlock();
}
#endif
@@ -356,7 +356,7 @@ int init_notify(int login_cooldown, int notification_timeout)
#ifdef SOUND_NOTIFY
alutInitWithoutContext(NULL, NULL);
#endif /* SOUND_NOTIFY */
-
+
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
if (pthread_mutex_init(Control.poll_mutex, NULL) != 0)
return -1;
@@ -371,8 +371,8 @@ int init_notify(int login_cooldown, int notification_timeout)
Control.poll_active = 1;
#endif
Control.cooldown = get_unix_time() + login_cooldown;
-
-
+
+
#ifdef BOX_NOTIFY
notify_init("Toxic");
#endif
@@ -381,11 +381,11 @@ int init_notify(int login_cooldown, int notification_timeout)
}
void terminate_notify()
-{
-#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
- if ( !Control.poll_active ) return;
+{
+#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
+ if ( !Control.poll_active ) return;
Control.poll_active = 0;
-
+
graceful_clear();
#endif
@@ -394,7 +394,7 @@ void terminate_notify()
for (; i < SOUNDS_SIZE; i ++) free(Control.sounds[i]);
alutExit();
#endif /* SOUND_NOTIFY */
-
+
#ifdef BOX_NOTIFY
notify_uninit();
#endif
@@ -404,7 +404,7 @@ void terminate_notify()
int set_sound(Notification sound, const char* value)
{
if (sound == silent) return 0;
-
+
free(Control.sounds[sound]);
size_t len = strlen(value) + 1;
@@ -416,18 +416,18 @@ int set_sound(Notification sound, const char* value)
}
int play_sound_internal(Notification what, bool loop)
-{
+{
uint32_t source;
uint32_t buffer;
-
+
m_open_device();
-
+
alGenSources(1, &source);
alGenBuffers(1, &buffer);
buffer = alutCreateBufferFromFile(Control.sounds[what]);
alSourcei(source, AL_BUFFER, buffer);
alSourcei(source, AL_LOOPING, loop);
-
+
int rc = play_source(source, buffer, loop);
if (rc < 0) {
alSourceStop(source);
@@ -435,7 +435,7 @@ int play_sound_internal(Notification what, bool loop)
alDeleteBuffers(1,&buffer);
return -1;
}
-
+
return rc;
}
@@ -464,7 +464,7 @@ void stop_sound(int id)
notify_notification_close(actives[id].box, &ignore);
}
#endif
- if (actives[id].id_indicator)
+ if (actives[id].id_indicator)
*actives[id].id_indicator = -1;
// alSourcei(actives[id].source, AL_LOOPING, false);
alSourceStop(actives[id].source);
@@ -484,11 +484,11 @@ static int m_play_sound(Notification notif, uint64_t flags)
beep();
return -1;
-#endif /* SOUND_NOTIFY */
+#endif /* SOUND_NOTIFY */
}
#ifdef BOX_NOTIFY
-void m_notify_action(NotifyNotification *box, char *action, void* data)
+void m_notify_action(NotifyNotification *box, char *action, void* data)
{
}
#endif
@@ -503,7 +503,7 @@ int sound_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_in
int id = -1;
control_lock();
- if (self && (!self->stb || self->stb->status != TOX_USERSTATUS_BUSY) && user_settings->alerts == ALERTS_ENABLED)
+ if (self && (!self->stb || self->stb->status != TOX_USER_STATUS_BUSY) && user_settings->alerts == ALERTS_ENABLED)
id = m_play_sound(notif, flags);
else if (flags & NT_ALWAYS)
id = m_play_sound(notif, flags);
@@ -520,7 +520,7 @@ int sound_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_in
#endif
- if ( id_indicator && id != -1 ) {
+ if ( id_indicator && id != -1 ) {
actives[id].id_indicator = id_indicator;
*id_indicator = id;
}
@@ -533,46 +533,46 @@ int sound_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_in
int sound_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id)
{
tab_notify(self, flags);
-
+
if (notifications_are_disabled(flags))
return -1;
-
+
if (id < 0 || id >= ACTIVE_NOTIFS_MAX) return -1;
-#ifdef SOUND_NOTIFY
+#ifdef SOUND_NOTIFY
control_lock();
-
+
if (!actives[id].active || !Control.sounds[notif]) {
control_unlock();
return -1;
}
-
+
m_open_device();
-
+
alSourceStop(actives[id].source);
alDeleteSources(1, &actives[id].source);
alDeleteBuffers(1,&actives[id].buffer);
-
-
+
+
alGenSources(1, &actives[id].source);
alGenBuffers(1, &actives[id].buffer);
actives[id].buffer = alutCreateBufferFromFile(Control.sounds[notif]);
alSourcei(actives[id].source, AL_BUFFER, actives[id].buffer);
alSourcei(actives[id].source, AL_LOOPING, flags & NT_LOOP);
-
+
alSourcePlay(actives[id].source);
-
+
control_unlock();
-
+
return id;
#else
if (notif != silent)
beep();
-
+
return 0;
#endif /* SOUND_NOTIFY */
}
-int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, char* title, const char* format, ...)
+int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, const char* title, const char* format, ...)
{
if (notifications_are_disabled(flags)) {
tab_notify(self, flags);
@@ -594,7 +594,7 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi
return -1; /* Full */
}
- actives[id].active = 1;
+ actives[id].active = 1;
actives[id].id_indicator = id_indicator;
if (id_indicator) *id_indicator = id;
}
@@ -607,13 +607,13 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi
vsnprintf (actives[id].messages[0], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end (__ARGS__);
- if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3)
+ if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3)
strcpy(actives[id].messages[0] + MAX_BOX_MSG_LEN - 3, "...");
actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
actives[id].size++;
actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;
-
+
notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
notify_notification_set_app_name(actives[id].box, "toxic");
/*notify_notification_add_action(actives[id].box, "lel", "default", m_notify_action, self, NULL);*/
@@ -687,7 +687,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const
control_lock();
- int id;
+ int id;
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
if ( id == ACTIVE_NOTIFS_MAX ) {
control_unlock();
@@ -706,7 +706,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const
vsnprintf (actives[id].messages[0], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end (__ARGS__);
- if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3)
+ if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3)
strcpy(actives[id].messages[0] + MAX_BOX_MSG_LEN - 3, "...");
actives[id].active = 1;
diff --git a/src/notify.h b/src/notify.h
index d8a276c..6fd81f0 100644
--- a/src/notify.h
+++ b/src/notify.h
@@ -1,5 +1,5 @@
/* notify.h
- *
+ *
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
@@ -29,7 +29,7 @@
typedef enum _Notification
{
silent = -1,
- error,
+ notif_error,
self_log_in,
self_log_out,
user_log_in,
@@ -49,14 +49,14 @@ typedef enum _Flags {
NT_LOOP = 1 << 2, /* Loop sound. If this setting active, notify() will return id of the sound
* so it could be stopped. It will return 0 if error or NT_NATIVE flag is set and play \a instead
*/
- NT_RESTOL = 1 << 3, /* Respect tolerance. Usually used to stop flood at toxic startup
+ NT_RESTOL = 1 << 3, /* Respect tolerance. Usually used to stop flood at toxic startup
* Only works if login_cooldown is true when calling init_notify()
*/
NT_NOTIFWND = 1 << 4, /* Pop notify window. NOTE: only works(/WILL WORK) if libnotify is present */
NT_WNDALERT_0 = 1 << 5, /* Alert toxic */
NT_WNDALERT_1 = 1 << 6, /* Alert toxic */
NT_WNDALERT_2 = 1 << 7, /* Alert toxic */
-
+
NT_ALWAYS = 1 << 8, /* Force sound to play */
} Flags;
@@ -68,7 +68,7 @@ int sound_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id);
void stop_sound(int id);
-int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, char* title, const char* format, ...);
+int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, const char* title, const char* format, ...);
int box_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id, const char* format, ...);
int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const char* title, const char* format, ...);
int box_silent_notify2(ToxWindow* self, uint64_t flags, int id, const char* format, ...);
diff --git a/src/prompt.c b/src/prompt.c
index e007030..26e55b3 100644
--- a/src/prompt.c
+++ b/src/prompt.c
@@ -102,6 +102,13 @@ void kill_prompt_window(ToxWindow *self)
del_window(self);
}
+/* callback: Updates own connection status in prompt statusbar */
+void prompt_onSelfConnectionChange(Tox *m, TOX_CONNECTION connection_status, void *userdata)
+{
+ StatusBar *statusbar = prompt->stb;
+ statusbar->connection = connection_status;
+}
+
/* Updates own nick in prompt statusbar */
void prompt_update_nick(ToxWindow *prompt, const char *nick)
{
@@ -115,25 +122,23 @@ void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusms
{
StatusBar *statusbar = prompt->stb;
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
- int len = strlen(statusbar->statusmsg);
+ size_t len = strlen(statusbar->statusmsg);
statusbar->statusmsg_len = len;
- tox_set_status_message(m, (uint8_t *) statusmsg, (uint64_t) len);
+
+ TOX_ERR_SET_INFO err;
+ tox_self_set_status_message(m, (uint8_t *) statusmsg, len, &err);
+
+ if (err != TOX_ERR_SET_INFO_OK)
+ line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set note (error %d)\n", err);
}
/* Updates own status in prompt statusbar */
-void prompt_update_status(ToxWindow *prompt, uint8_t status)
+void prompt_update_status(ToxWindow *prompt, TOX_USER_STATUS status)
{
StatusBar *statusbar = prompt->stb;
statusbar->status = status;
}
-/* Updates own connection status in prompt statusbar */
-void prompt_update_connectionstatus(ToxWindow *prompt, bool is_connected)
-{
- StatusBar *statusbar = prompt->stb;
- statusbar->is_online = is_connected;
-}
-
/* Adds friend request to pending friend requests.
Returns request number on success, -1 if queue is full. */
static int add_friend_request(const char *public_key, const char *data)
@@ -210,10 +215,10 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
}
} else {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
} else {
- sound_notify(self, error, 0, NULL);
+ sound_notify(self, notif_error, 0, NULL);
}
} else if (key == '\n') {
rm_trailing_spaces_buf(ctx);
@@ -254,30 +259,23 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
wmove(statusbar->topline, 0, 0);
- if (statusbar->is_online) {
- int colour = WHITE;
- const char *status_text = "Unknown";
+ if (statusbar->connection != TOX_CONNECTION_NONE) {
+ int colour = MAGENTA;
+ const char *status_text = "ERROR";
switch (statusbar->status) {
- case TOX_USERSTATUS_NONE:
+ case TOX_USER_STATUS_NONE:
status_text = "Online";
colour = GREEN;
break;
-
- case TOX_USERSTATUS_AWAY:
+ case TOX_USER_STATUS_AWAY:
status_text = "Away";
colour = YELLOW;
break;
-
- case TOX_USERSTATUS_BUSY:
+ case TOX_USER_STATUS_BUSY:
status_text = "Busy";
colour = RED;
break;
-
- case TOX_USERSTATUS_INVALID:
- status_text = "ERROR";
- colour = MAGENTA;
- break;
}
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@@ -296,10 +294,10 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
/* Reset statusbar->statusmsg on window resize */
if (x2 != self->x) {
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {0};
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
pthread_mutex_lock(&Winthread.lock);
- tox_get_self_status_message(m, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
+ tox_self_get_status_message(m, (uint8_t *) statusmsg);
pthread_mutex_unlock(&Winthread.lock);
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
@@ -335,11 +333,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
help_onDraw(self);
}
-static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum , uint8_t status)
+static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnum , TOX_CONNECTION connection_status)
{
- if (friendnum < 0)
- return;
-
ChatContext *ctx = self->chatwin;
char nick[TOX_MAX_NAME_LENGTH] = {0}; /* stop removing this initiation */
@@ -352,7 +347,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
get_time_str(timefrmt, sizeof(timefrmt));
const char *msg;
- if (status == 1) {
+ if (connection_status != TOX_CONNECTION_NONE) {
msg = "has come online";
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
write_to_log(msg, nick, ctx->log, true);
@@ -377,7 +372,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
}
}
-static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, uint16_t length)
+static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
{
ChatContext *ctx = self->chatwin;
@@ -407,15 +402,19 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m)
/* Init statusbar info */
StatusBar *statusbar = self->stb;
- statusbar->status = TOX_USERSTATUS_NONE;
- statusbar->is_online = false;
+ statusbar->status = TOX_USER_STATUS_NONE;
+ statusbar->connection = TOX_CONNECTION_NONE;
char nick[TOX_MAX_NAME_LENGTH];
- char statusmsg[MAX_STR_SIZE];
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
- uint16_t n_len = tox_get_self_name(m, (uint8_t *) nick);
- uint16_t s_len = tox_get_self_status_message(m, (uint8_t *) statusmsg, MAX_STR_SIZE);
- uint8_t status = tox_get_self_user_status(m);
+ size_t n_len = tox_self_get_name_size(m);
+ tox_self_get_name(m, (uint8_t *) nick);
+
+ size_t s_len = tox_self_get_status_message_size(m);
+ tox_self_get_status_message(m, (uint8_t *) statusmsg);
+
+ TOX_USER_STATUS status = tox_self_get_status(m);
nick[n_len] = '\0';
statusmsg[s_len] = '\0';
@@ -469,8 +468,8 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
line_info_init(ctx->hst);
if (user_settings->autolog == AUTOLOG_ON) {
- char myid[TOX_FRIEND_ADDRESS_SIZE];
- tox_get_address(m, (uint8_t *) myid);
+ char myid[TOX_ADDRESS_SIZE];
+ tox_self_get_address(m, (uint8_t *) myid);
log_enable(self->name, myid, NULL, ctx->log, LOG_PROMPT);
}
diff --git a/src/prompt.h b/src/prompt.h
index e6eb0cc..4842f6c 100644
--- a/src/prompt.h
+++ b/src/prompt.h
@@ -45,8 +45,11 @@ void prep_prompt_win(void);
void prompt_init_statusbar(ToxWindow *self, Tox *m);
void prompt_update_nick(ToxWindow *prompt, const char *nick);
void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusmsg);
-void prompt_update_status(ToxWindow *prompt, uint8_t status);
+void prompt_update_status(ToxWindow *prompt, TOX_USER_STATUS status);
void prompt_update_connectionstatus(ToxWindow *prompt, bool is_connected);
void kill_prompt_window(ToxWindow *self);
+/* callback: Updates own connection status in prompt statusbar */
+void prompt_onSelfConnectionChange(Tox *m, TOX_CONNECTION connection_status, void *userdata);
+
#endif /* end of include guard: PROMPT_H */
diff --git a/src/settings.c b/src/settings.c
index 9df7c60..5c98d48 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -199,7 +199,7 @@ static void audio_defaults(struct user_settings* settings)
#ifdef SOUND_NOTIFY
static const struct sound_strings {
const char* self;
- const char* error;
+ const char* notif_error;
const char* self_log_in;
const char* self_log_out;
const char* user_log_in;
@@ -211,7 +211,7 @@ static const struct sound_strings {
const char* transfer_completed;
} sound_strings = {
"sounds",
- "error",
+ "notif_error",
"self_log_in",
"self_log_out",
"user_log_in",
@@ -406,10 +406,10 @@ int settings_load(struct user_settings *s, const char *patharg)
#ifdef SOUND_NOTIFY
if ((setting = config_lookup(cfg, sound_strings.self)) != NULL) {
- if ( (config_setting_lookup_string(setting, sound_strings.error, &str) != CONFIG_TRUE) ||
- !set_sound(error, str) ) {
+ if ( (config_setting_lookup_string(setting, sound_strings.notif_error, &str) != CONFIG_TRUE) ||
+ !set_sound(notif_error, str) ) {
if (str && strcasecmp(str, NO_SOUND) != 0)
- set_sound(error, PACKAGE_DATADIR "/sounds/ToxicError.wav");
+ set_sound(notif_error, PACKAGE_DATADIR "/sounds/ToxicError.wav");
}
if ( !config_setting_lookup_string(setting, sound_strings.user_log_in, &str) ||
@@ -455,7 +455,7 @@ int settings_load(struct user_settings *s, const char *patharg)
}
}
else {
- set_sound(error, PACKAGE_DATADIR "/sounds/ToxicError.wav");
+ set_sound(notif_error, PACKAGE_DATADIR "/sounds/ToxicError.wav");
set_sound(user_log_in, PACKAGE_DATADIR "/sounds/ToxicContactOnline.wav");
set_sound(user_log_out, PACKAGE_DATADIR "/sounds/ToxicContactOffline.wav");
set_sound(call_incoming, PACKAGE_DATADIR "/sounds/ToxicIncomingCall.wav");
diff --git a/src/settings.h b/src/settings.h
index 2e02a01..1e51c7b 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -67,7 +67,7 @@ struct user_settings {
int key_toggle_peerlist;
int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */
- char mplex_away_note [TOX_MAX_STATUSMESSAGE_LENGTH];
+ char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH];
#ifdef AUDIO
int audio_in_dev;
diff --git a/src/term_mplex.c b/src/term_mplex.c
index f150938..0036b73 100644
--- a/src/term_mplex.c
+++ b/src/term_mplex.c
@@ -70,8 +70,8 @@ static char buffer [BUFFER_SIZE];
static bool auto_away_active = false;
static mplex_status mplex = MPLEX_NONE;
-static TOX_USERSTATUS prev_status = TOX_USERSTATUS_NONE;
-static char prev_note [TOX_MAX_STATUSMESSAGE_LENGTH] = "";
+static TOX_USER_STATUS prev_status = TOX_USER_STATUS_NONE;
+static char prev_note [TOX_MAX_STATUS_MESSAGE_LENGTH] = "";
/* mutex for access to status data, for sync between:
- user command /status from ncurses thread
@@ -314,7 +314,7 @@ static int mplex_is_detached ()
static void mplex_timer_handler (Tox *m)
{
- TOX_USERSTATUS current_status, new_status;
+ TOX_USER_STATUS current_status, new_status;
const char *new_note;
if (mplex == MPLEX_NONE)
@@ -323,23 +323,23 @@ static void mplex_timer_handler (Tox *m)
int detached = mplex_is_detached ();
pthread_mutex_lock (&Winthread.lock);
- current_status = tox_get_self_user_status (m);
+ current_status = tox_self_get_status (m);
pthread_mutex_unlock (&Winthread.lock);
- if (auto_away_active && current_status == TOX_USERSTATUS_AWAY && !detached)
+ if (auto_away_active && current_status == TOX_USER_STATUS_AWAY && !detached)
{
auto_away_active = false;
new_status = prev_status;
new_note = prev_note;
}
else
- if (current_status == TOX_USERSTATUS_NONE && detached)
+ if (current_status == TOX_USER_STATUS_NONE && detached)
{
auto_away_active = true;
prev_status = current_status;
- new_status = TOX_USERSTATUS_AWAY;
+ new_status = TOX_USER_STATUS_AWAY;
pthread_mutex_lock (&Winthread.lock);
- tox_get_self_status_message (m, (uint8_t*) prev_note, sizeof (prev_note));
+ tox_self_get_status_message (m, (uint8_t*) prev_note);
pthread_mutex_unlock (&Winthread.lock);
new_note = user_settings->mplex_away_note;
}
@@ -348,8 +348,8 @@ static void mplex_timer_handler (Tox *m)
char argv[3][MAX_STR_SIZE];
strcpy (argv[0], "/status");
- strcpy (argv[1], (new_status == TOX_USERSTATUS_AWAY ? "away" :
- new_status == TOX_USERSTATUS_BUSY ? "busy" : "online"));
+ strcpy (argv[1], (new_status == TOX_USER_STATUS_AWAY ? "away" :
+ new_status == TOX_USER_STATUS_BUSY ? "busy" : "online"));
argv[2][0] = '\"';
strcpy (argv[2] + 1, new_note);
strcat (argv[2], "\"");
diff --git a/src/toxic.c b/src/toxic.c
index 44c282a..a6abfd6 100644
--- a/src/toxic.c
+++ b/src/toxic.c
@@ -50,7 +50,7 @@
#include "groupchat.h"
#include "prompt.h"
#include "misc_tools.h"
-#include "file_senders.h"
+#include "file_transfers.h"
#include "line_info.h"
#include "settings.h"
#include "log.h"
@@ -79,6 +79,8 @@ char *BLOCK_FILE = NULL;
ToxWindow *prompt = NULL;
#define AUTOSAVE_FREQ 60
+#define MIN_PASSWORD_LEN 6
+#define MAX_PASSWORD_LEN 64
struct Winthread Winthread;
struct cqueue_thread cqueue_thread;
@@ -86,8 +88,6 @@ struct audio_thread audio_thread;
struct arg_opts arg_opts;
struct user_settings *user_settings = NULL;
-#define MIN_PASSWORD_LEN 6
-#define MAX_PASSWORD_LEN 64
static struct user_password {
bool data_is_encrypted;
@@ -102,7 +102,7 @@ static void catch_SIGINT(int sig)
static void catch_SIGSEGV(int sig)
{
- freopen("/dev/tty", "w", stderr);
+ freopen("/dev/tty", "w", stderr); // make sure stderr is enabled since we may have disabled it
endwin();
fprintf(stderr, "Caught SIGSEGV: Aborting toxic session.\n");
exit(EXIT_FAILURE);
@@ -124,7 +124,6 @@ void exit_toxic_success(Tox *m)
{
store_data(m, DATA_FILE);
memset(&user_password, 0, sizeof(struct user_password));
- close_all_file_senders(m);
kill_all_windows(m);
terminate_notify();
@@ -151,9 +150,6 @@ void exit_toxic_success(Tox *m)
void exit_toxic_err(const char *errmsg, int errcode)
{
- if (errmsg == NULL)
- errmsg = "No error message";
-
freopen("/dev/tty", "w", stderr);
endwin();
fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg);
@@ -167,7 +163,7 @@ static void init_term(void)
if (!arg_opts.default_locale) {
if (setlocale(LC_ALL, "") == NULL)
exit_toxic_err("Could not set your locale, please check your locale settings or "
- "disable unicode support with the -d flag.", FATALERR_LOCALE_SET);
+ "disable unicode support with the -d flag.", FATALERR_LOCALE_NOT_SET);
}
#endif
@@ -255,82 +251,6 @@ static void print_init_messages(ToxWindow *toxwin)
line_info_add(toxwin, NULL, NULL, NULL, SYS_MSG, 0, 0, init_messages.msgs[i]);
}
-static Tox *init_tox(void)
-{
- Tox_Options tox_opts;
- tox_opts.ipv6enabled = !arg_opts.use_ipv4;
- tox_opts.udp_disabled = arg_opts.force_tcp;
- tox_opts.proxy_type = arg_opts.proxy_type;
-
- if (tox_opts.proxy_type != TOX_PROXY_NONE) {
- tox_opts.proxy_port = arg_opts.proxy_port;
- snprintf(tox_opts.proxy_address, sizeof(tox_opts.proxy_address), "%s", arg_opts.proxy_address);
- const char *ps = tox_opts.proxy_type == TOX_PROXY_SOCKS5 ? "SOCKS5" : "HTTP";
-
- char tmp[48];
- snprintf(tmp, sizeof(tmp), "Using %s proxy %s : %d", ps, arg_opts.proxy_address, arg_opts.proxy_port);
- queue_init_message("%s", tmp);
- }
-
- if (tox_opts.udp_disabled) {
- queue_init_message("UDP disabled");
- } else if (tox_opts.proxy_type != TOX_PROXY_NONE) {
- const char *msg = "WARNING: Using a proxy without disabling UDP may leak your real IP address.";
- queue_init_message("%s", msg);
- msg = "Use the -t option to disable UDP.";
- queue_init_message("%s", msg);
- }
-
- /* Init core */
- Tox *m = tox_new(&tox_opts);
-
- if (tox_opts.ipv6enabled && m == NULL) {
- queue_init_message("IPv6 failed to initialize");
- tox_opts.ipv6enabled = 0;
- m = tox_new(&tox_opts);
- }
-
- if (!tox_opts.ipv6enabled)
- queue_init_message("Forcing IPv4 connection");
-
- if (tox_opts.proxy_type != TOX_PROXY_NONE && m == NULL)
- exit_toxic_err("Proxy error", FATALERR_PROXY);
-
- if (m == NULL)
- return NULL;
-
- /* Callbacks */
- tox_callback_connection_status(m, on_connectionchange, NULL);
- tox_callback_typing_change(m, on_typing_change, NULL);
- tox_callback_friend_request(m, on_request, NULL);
- tox_callback_friend_message(m, on_message, NULL);
- tox_callback_name_change(m, on_nickchange, NULL);
- tox_callback_user_status(m, on_statuschange, NULL);
- tox_callback_status_message(m, on_statusmessagechange, NULL);
- tox_callback_friend_action(m, on_action, NULL);
- tox_callback_file_send_request(m, on_file_sendrequest, NULL);
- tox_callback_file_control(m, on_file_control, NULL);
- tox_callback_file_data(m, on_file_data, NULL);
- tox_callback_read_receipt(m, on_read_receipt, NULL);
- tox_callback_group_invite(m, on_group_invite, NULL);
- tox_callback_group_message(m, on_group_message, NULL);
- tox_callback_group_action(m, on_group_action, NULL);
- tox_callback_group_private_message(m, on_group_private_message, NULL);
- tox_callback_group_op_certificate(m, on_group_op_certificate, NULL);
- tox_callback_group_peerlist_update(m, on_group_namelistchange, NULL);
- tox_callback_group_peer_join(m, on_group_peer_join, NULL);
- tox_callback_group_peer_exit(m, on_group_peer_exit, NULL);
- tox_callback_group_nick_change(m, on_group_nick_change, NULL);
- tox_callback_group_topic_change(m, on_group_topic_change, NULL);
- tox_callback_group_self_join(m, on_group_self_join, NULL);
- tox_callback_group_self_timeout(m, on_group_self_timeout, NULL);
- tox_callback_group_rejected(m, on_group_rejected, NULL);
-
- tox_set_name(m, (uint8_t *) "Toxic User", strlen("Toxic User"));
-
- return m;
-}
-
#define MIN_NODE_LINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.im = 6) */
#define MAX_NODE_LINE 256 /* Approx max number of chars in a sever line (name + port + key) */
#define MAXNODES 50
@@ -387,7 +307,7 @@ static int load_nodelist(const char *filename)
int init_connection_helper(Tox *m, int line)
{
- return tox_bootstrap_from_address(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line]);
+ return tox_bootstrap(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], NULL);
}
/* Connects to a random DHT node listed in the DHTnodes file
@@ -439,43 +359,10 @@ int init_connection(Tox *m)
return 4;
}
-#define TRY_CONNECT 10 /* Seconds between connection attempts when DHT is not connected */
-
-static void do_connection(Tox *m, ToxWindow *prompt)
-{
- if (arg_opts.no_connect == 1)
- return;
-
- static int conn_err = 0;
- static bool was_connected = false;
- static uint64_t last_conn_try = 0;
- uint64_t curtime = get_unix_time();
- bool is_connected = tox_isconnected(m);
-
- if (was_connected && is_connected)
- return;
-
- if (!was_connected && is_connected) {
- was_connected = true;
- prompt_update_connectionstatus(prompt, was_connected);
- } else if (was_connected && !is_connected) {
- was_connected = false;
- prompt_update_connectionstatus(prompt, was_connected);
- } else if (!was_connected && !is_connected && timed_out(last_conn_try, curtime, TRY_CONNECT)) {
- /* if autoconnect has already failed there's no point in trying again */
- if (conn_err == 0) {
- last_conn_try = curtime;
-
- if ((conn_err = init_connection(m)) != 0)
- line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Auto-connect failed with error code %d", conn_err);
- }
- }
-}
-
static void load_friendlist(Tox *m)
{
- uint32_t i;
- uint32_t numfriends = tox_count_friendlist(m);
+ size_t i;
+ size_t numfriends = tox_self_get_friend_list_size(m);
for (i = 0; i < numfriends; ++i)
friendlist_onFriendAdded(NULL, m, i, false);
@@ -554,6 +441,7 @@ static void first_time_encrypt(const char *msg)
int len = 0;
bool valid_password = false;
char passconfirm[MAX_PASSWORD_LEN + 1] = {0};
+
printf("Enter a new password (must be at least %d characters) ", MIN_PASSWORD_LEN);
while (valid_password == false) {
@@ -584,7 +472,7 @@ static void first_time_encrypt(const char *msg)
valid_password = true;
}
- queue_init_message("Data file '%s' has been encrypted", DATA_FILE);
+ queue_init_message("Data file '%s' will be encrypted", DATA_FILE);
memset(passconfirm, 0, sizeof(passconfirm));
user_password.data_is_encrypted = true;
}
@@ -598,13 +486,10 @@ static void first_time_encrypt(const char *msg)
*/
int store_data(Tox *m, const char *path)
{
- if (arg_opts.ignore_data_file)
- return 0;
-
if (path == NULL)
return -1;
- int len = user_password.data_is_encrypted ? tox_encrypted_size(m) : tox_size(m);
+ size_t len = user_password.data_is_encrypted ? tox_encrypted_size(m) : tox_get_savedata_size(m);
char *buf = malloc(len);
if (buf == NULL)
@@ -616,72 +501,136 @@ int store_data(Tox *m, const char *path)
return -1;
}
} else {
- tox_save(m, (uint8_t *) buf);
+ tox_get_savedata(m, (uint8_t *) buf);
}
- FILE *fd = fopen(path, "wb");
+ FILE *fp = fopen(path, "wb");
- if (fd == NULL) {
+ if (fp == NULL) {
free(buf);
return -1;
}
- if (fwrite(buf, len, 1, fd) != 1) {
+ if (fwrite(buf, len, 1, fp) != 1) {
free(buf);
- fclose(fd);
+ fclose(fp);
return -1;
}
free(buf);
- fclose(fd);
+ fclose(fp);
return 0;
}
-static void load_data(Tox *m, char *path)
+static void init_tox_callbacks(Tox *m)
{
- if (arg_opts.ignore_data_file)
- return;
+ tox_callback_self_connection_status(m, prompt_onSelfConnectionChange, NULL);
- FILE *fd = fopen(path, "rb");
+ tox_callback_friend_connection_status(m, on_connectionchange, NULL);
+ tox_callback_friend_typing(m, on_typing_change, NULL);
+ tox_callback_friend_request(m, on_request, NULL);
+ tox_callback_friend_message(m, on_message, NULL);
+ tox_callback_friend_name(m, on_nickchange, NULL);
+ tox_callback_friend_status(m, on_statuschange, NULL);
+ tox_callback_friend_status_message(m, on_statusmessagechange, NULL);
+ tox_callback_friend_read_receipt(m, on_read_receipt, NULL);
- if (fd != NULL) {
- off_t len = file_size(path);
+ tox_callback_file_recv(m, on_file_recv, NULL);
+ tox_callback_file_chunk_request(m, on_file_chunk_request, NULL);
+ tox_callback_file_recv_control(m, on_file_control, NULL);
+ tox_callback_file_recv_chunk(m, on_file_recv_chunk, NULL);
- if (len == -1) {
- fclose(fd);
- exit_toxic_err("failed in load_data", FATALERR_FILEOP);
+ tox_callback_group_invite(m, on_group_invite, NULL);
+ tox_callback_group_message(m, on_group_message, NULL);
+ tox_callback_group_action(m, on_group_action, NULL);
+ tox_callback_group_private_message(m, on_group_private_message, NULL);
+ tox_callback_group_op_certificate(m, on_group_op_certificate, NULL);
+ tox_callback_group_peerlist_update(m, on_group_namelistchange, NULL);
+ tox_callback_group_peer_join(m, on_group_peer_join, NULL);
+ tox_callback_group_peer_exit(m, on_group_peer_exit, NULL);
+ tox_callback_group_nick_change(m, on_group_nick_change, NULL);
+ tox_callback_group_topic_change(m, on_group_topic_change, NULL);
+ tox_callback_group_self_join(m, on_group_self_join, NULL);
+ tox_callback_group_self_timeout(m, on_group_self_timeout, NULL);
+ tox_callback_group_rejected(m, on_group_rejected, NULL);
+}
+
+static void init_tox_options(struct Tox_Options *tox_opts)
+{
+ tox_opts->ipv6_enabled = !arg_opts.use_ipv4;
+ tox_opts->udp_enabled = !arg_opts.force_tcp;
+ tox_opts->proxy_type = arg_opts.proxy_type;
+
+ if (!tox_opts->ipv6_enabled)
+ queue_init_message("Forcing IPv4 connection");
+
+ if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) {
+ tox_opts->proxy_port = arg_opts.proxy_port;
+ tox_opts->proxy_host = arg_opts.proxy_address;
+ const char *ps = tox_opts->proxy_type == TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : "HTTP";
+
+ char tmp[48];
+ snprintf(tmp, sizeof(tmp), "Using %s proxy %s : %d", ps, arg_opts.proxy_address, arg_opts.proxy_port);
+ queue_init_message("%s", tmp);
+ }
+
+ if (!tox_opts->udp_enabled) {
+ queue_init_message("UDP disabled");
+ } else if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) {
+ const char *msg = "WARNING: Using a proxy without disabling UDP may leak your real IP address.";
+ queue_init_message("%s", msg);
+ msg = "Use the -t option to disable UDP.";
+ queue_init_message("%s", msg);
+ }
+}
+
+/* Returns a new Tox object on success.
+ * If object fails to initialize the toxic process will terminate.
+ */
+static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts)
+{
+ Tox *m = NULL;
+
+ FILE *fp = fopen(data_path, "rb");
+
+ if (fp != NULL) {
+ off_t len = file_size(data_path);
+
+ if (len == 0) {
+ fclose(fp);
+ exit_toxic_err("failed in load_toxic", FATALERR_FILEOP);
}
char *buf = malloc(len);
if (buf == NULL) {
- fclose(fd);
- exit_toxic_err("failed in load_data", FATALERR_MEMORY);
+ fclose(fp);
+ exit_toxic_err("failed in load_toxic", FATALERR_MEMORY);
}
- if (fread(buf, len, 1, fd) != 1) {
+ if (fread(buf, len, 1, fp) != 1) {
free(buf);
- fclose(fd);
- exit_toxic_err("failed in load_data", FATALERR_FILEOP);
+ fclose(fp);
+ exit_toxic_err("failed in load_toxic", FATALERR_FILEOP);
}
- bool is_encrypted = tox_is_save_encrypted((uint8_t *) buf);
+ bool is_encrypted = tox_is_data_encrypted((uint8_t *) buf);
/* attempt to encrypt an already encrypted data file */
if (arg_opts.encrypt_data && is_encrypted)
- exit_toxic_err("failed in load_data", FATALERR_ENCRYPT);
+ exit_toxic_err("failed in load_toxic", FATALERR_ENCRYPT);
if (arg_opts.unencrypt_data && is_encrypted)
- queue_init_message("Data file '%s' has been unencrypted", path);
+ queue_init_message("Data file '%s' has been unencrypted", data_path);
else if (arg_opts.unencrypt_data)
- queue_init_message("Warning: passed --unencrypt-data option with unencrypted data file '%s'", path);
+ queue_init_message("Warning: passed --unencrypt-data option with unencrypted data file '%s'", data_path);
if (is_encrypted) {
if (!arg_opts.unencrypt_data)
user_password.data_is_encrypted = true;
- int pwlen = 0;
- system("clear");
+ size_t pwlen = 0;
+ system("clear"); // TODO: is this portable?
printf("Enter password (q to quit) ");
while (true) {
@@ -698,44 +647,99 @@ static void load_data(Tox *m, char *path)
continue;
}
- if (tox_encrypted_load(m, (uint8_t *) buf, len, (uint8_t *) user_password.pass, pwlen) == 0) {
+ TOX_ERR_ENCRYPTED_NEW enc_err;
+ m = tox_encrypted_new(tox_opts, (uint8_t *) buf, len, (uint8_t *) user_password.pass, pwlen, &enc_err);
+
+ if (enc_err == TOX_ERR_ENCRYPTED_NEW_OK) {
break;
- } else {
+ } else if (enc_err == TOX_ERR_ENCRYPTED_NEW_LOAD_DECRYPTION_FAILED) {
system("clear");
sleep(1);
printf("Invalid password. Try again. ");
+ } else {
+ exit_toxic_err("tox_encrypted_new() failed", enc_err);
}
}
} else {
- /* tox_load errors are to be ignored until toxcore is fixed */
- tox_load(m, (uint8_t *) buf, len);
+ TOX_ERR_NEW err;
+ m = tox_new(tox_opts, (uint8_t *) buf, len, &err);
+
+ if (err != TOX_ERR_NEW_OK)
+ exit_toxic_err("tox_new() failed", err);
}
- load_friendlist(m);
- load_blocklist(BLOCK_FILE);
-
free(buf);
- fclose(fd);
+ fclose(fp);
} else {
/* if file exists then open() failing is fatal */
- if (file_exists(path))
- exit_toxic_err("failed in load_data", FATALERR_FILEOP);
+ if (file_exists(data_path))
+ exit_toxic_err("failed in load_toxic", FATALERR_FILEOP);
- if (store_data(m, path) != 0)
- exit_toxic_err("failed in load_data", FATALERR_STORE_DATA);
+ TOX_ERR_NEW err;
+ m = tox_new(tox_opts, NULL, 0, &err);
+
+ if (err != TOX_ERR_NEW_OK)
+ exit_toxic_err("tox_new() failed", err);
+
+ if (store_data(m, data_path) == -1)
+ exit_toxic_err("failed in load_toxic", FATALERR_FILEOP);
}
+
+ return m;
+}
+
+static Tox *load_toxic(char *data_path)
+{
+ struct Tox_Options tox_opts;
+ init_tox_options(&tox_opts);
+
+ Tox *m = load_tox(data_path, &tox_opts);
+
+ if (m == NULL)
+ exit_toxic_err("load_tox() failed", FATALERR_TOX_INIT);
+
+ init_tox_callbacks(m);
+ load_friendlist(m);
+ load_blocklist(BLOCK_FILE);
+
+ if (tox_self_get_name_size(m) == 0)
+ tox_self_set_name(m, (uint8_t *) "Toxic User", strlen("Toxic User"), NULL);
+
+ 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);
- do_connection(m, prompt);
- do_file_senders(m);
-
- if (arg_opts.no_connect == 0) {
- tox_do(m); /* main tox-core loop */
- }
-
+ tox_iterate(m);
+ do_bootstrap(m);
pthread_mutex_unlock(&Winthread.lock);
}
@@ -772,16 +776,19 @@ void *thread_cqueue(void *data)
while (true) {
pthread_mutex_lock(&Winthread.lock);
- int i;
+
+ size_t i;
for (i = 2; i < MAX_WINDOWS_NUM; ++i) {
ToxWindow *toxwin = get_window_ptr(i);
- if (toxwin != NULL && toxwin->is_chat && tox_get_friend_connection_status(m, toxwin->num) == 1)
+ if (toxwin != NULL && toxwin->is_chat
+ && tox_friend_get_connection_status(m, toxwin->num, NULL) != TOX_CONNECTION_NONE)
cqueue_try_send(toxwin, m);
}
pthread_mutex_unlock(&Winthread.lock);
+
usleep(4000);
}
}
@@ -795,6 +802,7 @@ void *thread_audio(void *data)
pthread_mutex_lock(&Winthread.lock);
toxav_do(av);
pthread_mutex_unlock(&Winthread.lock);
+
usleep(toxav_do_interval(av) * 1000);
}
}
@@ -817,7 +825,6 @@ static void print_usage(void)
fprintf(stderr, " -r, --dnslist Use specified DNSservers file\n");
fprintf(stderr, " -t, --force-tcp Force TCP connection (use this with proxies)\n");
fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n");
- fprintf(stderr, " -x, --nodata Ignore data file\n");
}
static void set_default_opts(void)
@@ -825,7 +832,7 @@ static void set_default_opts(void)
memset(&arg_opts, 0, sizeof(struct arg_opts));
/* set any non-zero defaults here*/
- arg_opts.proxy_type = TOX_PROXY_NONE;
+ arg_opts.proxy_type = TOX_PROXY_TYPE_NONE;
}
static void parse_args(int argc, char *argv[])
@@ -834,7 +841,6 @@ static void parse_args(int argc, char *argv[])
static struct option long_opts[] = {
{"file", required_argument, 0, 'f'},
- {"nodata", no_argument, 0, 'x'},
{"ipv4", no_argument, 0, '4'},
{"debug", no_argument, 0, 'b'},
{"default-locale", no_argument, 0, 'd'},
@@ -911,7 +917,7 @@ static void parse_args(int argc, char *argv[])
break;
case 'p':
- arg_opts.proxy_type = TOX_PROXY_SOCKS5;
+ arg_opts.proxy_type = TOX_PROXY_TYPE_SOCKS5;
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind-1][0] == '-')
@@ -921,7 +927,7 @@ static void parse_args(int argc, char *argv[])
break;
case 'P':
- arg_opts.proxy_type = TOX_PROXY_HTTP;
+ arg_opts.proxy_type = TOX_PROXY_TYPE_HTTP;
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind-1][0] == '-')
@@ -946,11 +952,6 @@ static void parse_args(int argc, char *argv[])
arg_opts.unencrypt_data = 1;
break;
- case 'x':
- arg_opts.ignore_data_file = 1;
- queue_init_message("Ignoring data file");
- break;
-
case 'h':
default:
print_usage();
@@ -1015,6 +1016,7 @@ static useconds_t optimal_msleepval(uint64_t *looptimer, uint64_t *loopcount, ui
}
#ifdef X11
+// FIXME
void DnD_callback(const char* asdv, DropType dt)
{
if (dt != DT_plain)
@@ -1026,31 +1028,32 @@ void DnD_callback(const char* asdv, DropType dt)
int main(int argc, char *argv[])
{
-
parse_args(argc, argv);
+ /* Use the -b flag to enable stderr */
+ if (!arg_opts.debug)
+ freopen("/dev/null", "w", stderr);
+
if (arg_opts.encrypt_data && arg_opts.unencrypt_data) {
arg_opts.encrypt_data = 0;
arg_opts.unencrypt_data = 0;
queue_init_message("Warning: Using --unencrypt-data and --encrypt-data simultaneously has no effect");
}
- /* Use the -b flag to enable stderr */
- if (!arg_opts.debug)
- freopen("/dev/null", "w", stderr);
-
/* Make sure all written files are read/writeable only by the current user. */
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
int config_err = init_default_data_files();
bool datafile_exists = file_exists(DATA_FILE);
- if (!arg_opts.ignore_data_file) {
- 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)
- first_time_encrypt("Encrypt existing data file? Y/n (q to quit)");
- }
+ 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)
+ first_time_encrypt("Encrypt existing data file? Y/n (q to quit)");
+
/* init user_settings struct and load settings from conf file */
user_settings = calloc(1, sizeof(struct user_settings));
@@ -1066,20 +1069,14 @@ int main(int argc, char *argv[])
queue_init_message("X failed to initialize");
#endif
- Tox *m = init_tox();
+ Tox *m = load_toxic(DATA_FILE);
- if (m == NULL)
- exit_toxic_err("failed in main", FATALERR_NETWORKINIT);
+ if (arg_opts.encrypt_data && !datafile_exists)
+ arg_opts.encrypt_data = 0;
- if (!arg_opts.ignore_data_file) {
- if (arg_opts.encrypt_data && !datafile_exists)
- arg_opts.encrypt_data = 0;
-
- load_data(m, DATA_FILE);
-
- }
init_term();
+
prompt = init_windows(m);
prompt_init_statusbar(prompt, m);
@@ -1124,7 +1121,7 @@ int main(int argc, char *argv[])
queue_init_message("Failed to load user settings");
/* screen/tmux auto-away timer */
- if (init_mplex_away_timer (m) == -1)
+ if (init_mplex_away_timer(m) == -1)
queue_init_message("Failed to init mplex auto-away.");
load_groups(m);
diff --git a/src/toxic.h b/src/toxic.h
index 0a1ef8f..4bcacd6 100644
--- a/src/toxic.h
+++ b/src/toxic.h
@@ -77,13 +77,13 @@ typedef enum _FATAL_ERRS {
FATALERR_THREAD_CREATE = -3, /* thread creation failed for critical thread */
FATALERR_MUTEX_INIT = -4, /* mutex init for critical thread failed */
FATALERR_THREAD_ATTR = -5, /* thread attr object init failed */
- FATALERR_LOCALE_SET = -6, /* system locale not set */
+ FATALERR_LOCALE_NOT_SET = -6, /* system locale not set */
FATALERR_STORE_DATA = -7, /* store_data failed in critical section */
- FATALERR_NETWORKINIT = -8, /* Tox network failed to init */
- FATALERR_INFLOOP = -9, /* infinite loop detected */
- FATALERR_WININIT = -10, /* window init failed */
- FATALERR_PROXY = -11, /* Tox network failed to init using a proxy */
- FATALERR_ENCRYPT = -12, /* Data file encryption failure */
+ FATALERR_INFLOOP = -8, /* infinite loop detected */
+ FATALERR_WININIT = -9, /* window init failed */
+ FATALERR_PROXY = -10, /* Tox network failed to init using a proxy */
+ FATALERR_ENCRYPT = -11, /* Data file encryption failure */
+ FATALERR_TOX_INIT = -12, /* Tox instance failed to initialize */
} FATAL_ERRS;
/* Fixes text color problem on some terminals.
@@ -98,21 +98,23 @@ void exit_toxic_err(const char *errmsg, int errcode);
int store_data(Tox *m, const char *path);
-void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata);
-void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata);
-void on_message(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata);
-void on_action(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata);
-void on_nickchange(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata);
-void on_statuschange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata);
-void on_statusmessagechange(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata);
-void on_friendadded(Tox *m, int32_t friendnumber, bool sort);
-void on_file_sendrequest(Tox *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *pathname,
- uint16_t pathname_length, void *userdata);
-void on_file_control(Tox *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type,
- const uint8_t *data, uint16_t length, void *userdata);
-void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata);
-void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata);
-void on_read_receipt(Tox *m, int32_t, uint32_t, void *userdata);
+/* callbacks */
+void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata);
+void on_connectionchange(Tox *m, uint32_t friendnumber, TOX_CONNECTION status, void *userdata);
+void on_message(Tox *m, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length, void *userdata);
+void on_action(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata);
+void on_nickchange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata);
+void on_statuschange(Tox *m, uint32_t friendnumber, TOX_USER_STATUS status, void *userdata);
+void on_statusmessagechange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata);
+void on_friendadded(Tox *m, uint32_t friendnumber, bool sort);
+void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata);
+void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
+ size_t length, void *userdata);
+void on_file_control (Tox *m, uint32_t friendnumber, uint32_t filenumber, TOX_FILE_CONTROL control, void *userdata);
+void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t kind, uint64_t file_size,
+ const uint8_t *filename, size_t filename_length, void *userdata);
+void on_typing_change(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata);
+void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata);
void on_group_invite(Tox *m, int32_t friendnumber, const uint8_t *invite_data, uint16_t length, void *userdata);
void on_group_message(Tox *m, int groupnumber, uint32_t peernumber, const uint8_t *message, uint16_t length, void *userdata);
diff --git a/src/toxic_strings.c b/src/toxic_strings.c
index 0709f13..e2417ba 100644
--- a/src/toxic_strings.c
+++ b/src/toxic_strings.c
@@ -125,7 +125,7 @@ int yank_buf(ChatContext *ctx)
return 0;
}
-/* Deletes all characters from line starting at pos and going backwards
+/* Deletes all characters from line starting at pos and going backwards
until we find a space or run out of characters.
Return 0 on success, -1 if nothing to delete */
int del_word_buf(ChatContext *ctx)
@@ -225,7 +225,7 @@ void fetch_hist_item(ChatContext *ctx, int key_dir)
if (key_dir == KEY_UP) {
if (--ctx->hst_pos < 0) {
ctx->hst_pos = 0;
- sound_notify(NULL, error, NT_ALWAYS, NULL);
+ sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
}
} else {
if (++ctx->hst_pos >= ctx->hst_tot) {
diff --git a/src/windows.c b/src/windows.c
index 4f03e75..899cd3b 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -46,12 +46,12 @@ extern struct user_settings *user_settings;
static int num_active_windows;
/* CALLBACKS START */
-void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
+void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) data, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onFriendRequest != NULL) {
@@ -60,22 +60,22 @@ void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t
}
}
-void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata)
+void on_connectionchange(Tox *m, uint32_t friendnumber, TOX_CONNECTION connection_status, void *userdata)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onConnectionChange != NULL)
- windows[i].onConnectionChange(&windows[i], m, friendnumber, status);
+ windows[i].onConnectionChange(&windows[i], m, friendnumber, connection_status);
}
}
-void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata)
+void on_typing_change(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata)
{
if (user_settings->show_typing_other == SHOW_TYPING_OFF)
return;
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onTypingChange != NULL)
@@ -83,39 +83,27 @@ void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *use
}
}
-void on_message(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata)
+void on_message(Tox *m, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length,
+ void *userdata)
{
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) string, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onMessage != NULL)
- windows[i].onMessage(&windows[i], m, friendnumber, msg, length);
+ windows[i].onMessage(&windows[i], m, friendnumber, type, msg, length);
}
}
-void on_action(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata)
-{
- char msg[MAX_STR_SIZE + 1];
- length = copy_tox_str(msg, sizeof(msg), (const char *) string, length);
-
- int i;
-
- for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
- if (windows[i].onAction != NULL)
- windows[i].onAction(&windows[i], m, friendnumber, msg, length);
- }
-}
-
-void on_nickchange(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata)
+void on_nickchange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
{
char nick[TOXIC_MAX_NAME_LENGTH + 1];
length = copy_tox_str(nick, sizeof(nick), (const char *) string, length);
filter_str(nick, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onNickChange != NULL)
@@ -125,13 +113,13 @@ void on_nickchange(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t
store_data(m, DATA_FILE);
}
-void on_statusmessagechange(Tox *m, int32_t friendnumber, const uint8_t *string, uint16_t length, void *userdata)
+void on_statusmessagechange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
{
- char msg[TOX_MAX_STATUSMESSAGE_LENGTH + 1];
+ char msg[TOX_MAX_STATUS_MESSAGE_LENGTH + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) string, length);
filter_str(msg, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onStatusMessageChange != NULL)
@@ -139,9 +127,9 @@ void on_statusmessagechange(Tox *m, int32_t friendnumber, const uint8_t *string,
}
}
-void on_statuschange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata)
+void on_statuschange(Tox *m, uint32_t friendnumber, TOX_USER_STATUS status, void *userdata)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onStatusChange != NULL)
@@ -149,9 +137,9 @@ void on_statuschange(Tox *m, int32_t friendnumber, uint8_t status, void *userdat
}
}
-void on_friendadded(Tox *m, int32_t friendnumber, bool sort)
+void on_friendadded(Tox *m, uint32_t friendnumber, bool sort)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onFriendAdded != NULL)
@@ -177,7 +165,7 @@ void on_group_message(Tox *m, int groupnumber, uint32_t peernumber, const uint8_
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupMessage != NULL)
@@ -191,7 +179,7 @@ void on_group_action(Tox *m, int groupnumber, uint32_t peernumber, const uint8_t
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) action, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupAction != NULL)
@@ -205,7 +193,7 @@ void on_group_private_message(Tox *m, int groupnumber, uint32_t peernumber, cons
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupPrivateMessage != NULL)
@@ -215,7 +203,7 @@ void on_group_private_message(Tox *m, int groupnumber, uint32_t peernumber, cons
void on_group_namelistchange(Tox *m, int groupnumber, void *userdata)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupNamelistChange != NULL)
@@ -259,7 +247,7 @@ void on_group_topic_change(Tox *m, int groupnumber, uint32_t peernumber, const u
char data[MAX_STR_SIZE + 1];
length = copy_tox_str(data, sizeof(data), (const char *) topic, length);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupTopicChange != NULL)
@@ -323,44 +311,60 @@ void on_group_rejected(Tox *m, int groupnumber, uint8_t type, void *userdata)
}
}
-void on_file_sendrequest(Tox *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize,
- const uint8_t *filename, uint16_t filename_length, void *userdata)
+void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position,
+ size_t length, void *userdata)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
- if (windows[i].onFileSendRequest != NULL)
- windows[i].onFileSendRequest(&windows[i], m, friendnumber, filenumber, filesize,
- (const char *) filename, filename_length);
+ if (windows[i].onFileChunkRequest != NULL)
+ windows[i].onFileChunkRequest(&windows[i], m, friendnumber, filenumber, position, length);
}
}
-void on_file_control (Tox *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber,
- uint8_t control_type, const uint8_t *data, uint16_t length, void *userdata)
+void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position,
+ const uint8_t *data, size_t length, void *user_data)
{
- int i;
+ size_t i;
+
+ for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
+ if (windows[i].onFileRecvChunk != NULL)
+ windows[i].onFileRecvChunk(&windows[i], m, friendnumber, filenumber, position, (char *) data, length);
+ }
+}
+
+void on_file_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, TOX_FILE_CONTROL control,
+ void *userdata)
+{
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onFileControl != NULL)
- windows[i].onFileControl(&windows[i], m, friendnumber, receive_send, filenumber,
- control_type, (const char *) data, length);
+ windows[i].onFileControl(&windows[i], m, friendnumber, filenumber, control);
}
}
-void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length,
- void *userdata)
+void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t kind, uint64_t file_size,
+ const uint8_t *filename, size_t filename_length, void *userdata)
{
- int i;
+ /* We don't care about receiving avatars */
+ if (kind != TOX_FILE_KIND_DATA) {
+ tox_file_control(m, friendnumber, filenumber, TOX_FILE_CONTROL_CANCEL, NULL);
+ return;
+ }
+
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
- if (windows[i].onFileData != NULL)
- windows[i].onFileData(&windows[i], m, friendnumber, filenumber, (const char *) data, length);
+ if (windows[i].onFileRecv != NULL)
+ windows[i].onFileRecv(&windows[i], m, friendnumber, filenumber, file_size, (char *) filename,
+ filename_length);
}
}
-void on_read_receipt(Tox *m, int32_t friendnumber, uint32_t receipt, void *userdata)
+void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onReadReceipt != NULL)
@@ -375,7 +379,7 @@ int add_window(Tox *m, ToxWindow w)
if (LINES < 2)
return -1;
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; i++) {
if (windows[i].active)
@@ -469,7 +473,7 @@ void on_window_resize(void)
getmaxyx(stdscr, y2, x2);
y2 -= 2;
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (!windows[i].active)
@@ -541,7 +545,7 @@ static void draw_bar(void)
printw(" TOXIC " TOXICVER " |");
attroff(COLOR_PAIR(BLUE) | A_BOLD);
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (!windows[i].active)
@@ -619,7 +623,7 @@ void draw_active_window(Tox *m)
call at least once per second */
void refresh_inactive_windows(void)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
ToxWindow *a = &windows[i];
@@ -655,7 +659,7 @@ int get_num_active_windows(void)
/* destroys all chat and groupchat windows (should only be called on shutdown) */
void kill_all_windows(Tox *m)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].is_chat)
diff --git a/src/windows.h b/src/windows.h
index 2e1394b..ace1259 100644
--- a/src/windows.h
+++ b/src/windows.h
@@ -81,21 +81,21 @@ struct audio_thread {
};
struct arg_opts {
- int ignore_data_file;
- int use_ipv4;
- int force_tcp;
- int debug;
- int default_locale;
- int use_custom_data;
- int no_connect;
- int encrypt_data;
- int unencrypt_data;
+ bool use_ipv4;
+ bool force_tcp;
+ bool debug;
+ bool default_locale;
+ bool use_custom_data;
+ bool no_connect;
+ bool encrypt_data;
+ bool unencrypt_data;
+
char dns_path[MAX_STR_SIZE];
char config_path[MAX_STR_SIZE];
char nodes_path[MAX_STR_SIZE];
- uint8_t proxy_type;
char proxy_address[256];
+ uint8_t proxy_type;
uint16_t proxy_port;
};
@@ -106,22 +106,25 @@ typedef struct ChatContext ChatContext;
typedef struct Help Help;
struct ToxWindow {
+ /* ncurses */
void(*onKey)(ToxWindow *, Tox *, wint_t, bool);
void(*onDraw)(ToxWindow *, Tox *);
void(*onInit)(ToxWindow *, Tox *);
- void(*onFriendRequest)(ToxWindow *, Tox *, const char *, const char *, uint16_t);
- void(*onFriendAdded)(ToxWindow *, Tox *, int32_t, bool);
- void(*onConnectionChange)(ToxWindow *, Tox *, int32_t, uint8_t);
- void(*onMessage)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
- void(*onNickChange)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
- void(*onStatusChange)(ToxWindow *, Tox *, int32_t, uint8_t);
- void(*onStatusMessageChange)(ToxWindow *, int32_t, const char *, uint16_t);
- void(*onAction)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
- void(*onFileSendRequest)(ToxWindow *, Tox *, int32_t, uint8_t, uint64_t, const char *, uint16_t);
- void(*onFileControl)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t, uint8_t, const char *, uint16_t);
- void(*onFileData)(ToxWindow *, Tox *, int32_t, uint8_t, const char *, uint16_t);
- void(*onTypingChange)(ToxWindow *, Tox *, int32_t, uint8_t);
- void(*onReadReceipt)(ToxWindow *, Tox *, int32_t, uint32_t);
+
+ /* toxcore */
+ void(*onFriendRequest)(ToxWindow *, Tox *, const char *, const char *, size_t);
+ void(*onFriendAdded)(ToxWindow *, Tox *, uint32_t, bool);
+ void(*onConnectionChange)(ToxWindow *, Tox *, uint32_t, TOX_CONNECTION);
+ void(*onMessage)(ToxWindow *, Tox *, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t);
+ void(*onNickChange)(ToxWindow *, Tox *, uint32_t, const char *, size_t);
+ void(*onStatusChange)(ToxWindow *, Tox *, uint32_t, TOX_USER_STATUS);
+ void(*onStatusMessageChange)(ToxWindow *, uint32_t, const char *, size_t);
+ void(*onFileChunkRequest)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, size_t);
+ void(*onFileRecvChunk)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, const char *, size_t);
+ void(*onFileControl)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_FILE_CONTROL);
+ void(*onFileRecv)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, const char *, size_t);
+ void(*onTypingChange)(ToxWindow *, Tox *, uint32_t, bool);
+ void(*onReadReceipt)(ToxWindow *, Tox *, uint32_t, uint32_t);
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
void(*onGroupMessage)(ToxWindow *, Tox *, int, int, const char *, uint16_t);
@@ -161,7 +164,7 @@ struct ToxWindow {
int active_box; /* For box notify */
char name[TOXIC_MAX_NAME_LENGTH + 1];
- int32_t num; /* corresponds to friendnumber in chat windows */
+ uint32_t num; /* corresponds to friendnumber in chat windows */
bool active;
int x;
@@ -183,19 +186,19 @@ struct ToxWindow {
/* statusbar info holder */
struct StatusBar {
WINDOW *topline;
- char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH + 1];
- uint16_t statusmsg_len;
+ char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH + 1];
+ size_t statusmsg_len;
char nick[TOXIC_MAX_NAME_LENGTH + 1];
- int nick_len;
- uint8_t status;
- bool is_online;
+ size_t nick_len;
+ TOX_USER_STATUS status;
+ TOX_CONNECTION connection;
};
#ifdef AUDIO
-
#define INFOBOX_HEIGHT 7
#define INFOBOX_WIDTH 21
+
/* holds display info for audio calls */
struct infobox {
float vad_lvl;