1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-06-26 22:46:44 +02:00

Compare commits

...

25 Commits

Author SHA1 Message Date
0239509439 Bump version to 0.11.3 and update toxcore version in static build script 2021-12-24 14:21:26 -05:00
602d9d97c1 Send file control cancel when we block or delete a friend 2021-12-22 14:53:09 -05:00
6f8f6f0ac5 Implement file transfer queue for offline friends
File transfers initiated for offline friends are now
added to a queue and initiated all at once when the friend
appears online.
2021-12-22 14:27:28 -05:00
8d58e8f4d6 chore: Fix BUILD format (we check this on toktok-stack now). 2021-12-21 12:23:01 +00:00
b6f892edf5 Remove unnecessary define for keeping track of string array size 2021-12-15 13:39:11 -05:00
f91d10c831 Add missing ifdef 2021-12-13 12:37:51 -05:00
3f18c6f8de cleanup: fix some uninitialized memory warnings and clarify some logic 2021-12-13 12:33:58 -05:00
bf1e1b73fc Do proper error handling for a few malloc calls 2021-12-12 11:30:27 -05:00
3eac65036c Make infer print full error log 2021-12-11 20:13:31 -05:00
85f9ec6b9a chore: Add "infer" static analysis action on CI. 2021-12-11 23:55:29 +00:00
5230616a9d chore: Fix CI: don't install bootstrap daemon. 2021-12-11 23:01:47 +00:00
8e0e318df1 chore: Add github CI workflow. 2021-12-11 22:47:54 +00:00
701c0e1e94 cleanup: Reduce the amount of "extern" in .c files.
There is no check at all that the types of externs actually match the
type of the definition. This just accidentally was not a problem, but now
the compiler helps a bit in keeping it that way.
2021-12-11 22:35:51 +00:00
71f6a8d4d6 cleanup: Avoid casting away constness from pointers. 2021-12-11 22:22:25 +00:00
1cace1e81d Do exact length check for string passed to tox_pk_string_to_bytes 2021-12-11 17:13:30 -05:00
3030cda47e Fix possible null dereference
game invite info needs to be set after calloc in case it fails
2021-12-10 13:44:33 -05:00
2946e0dc56 Zero-init coordinates
Not strictly necessary, but makes static analysis happy
2021-12-10 13:09:47 -05:00
da90ca8b74 Fix bazel build for games. 2021-12-10 17:52:43 +00:00
17e5cc1147 Merge branch 'toktok' 2021-12-08 14:38:39 -05:00
d02ac24de8 Fix regression causing typing notifications to break
Also a small refactor so we use less duplicate code and reduce mutex usage
2021-12-07 22:14:32 -05:00
66e4c590dc Fix some lazy/incorrect code in cmd_add()
This fixes a rare but possible scenario where a name@domain lookup that's
longer than a tox id won't work. It also fixes custom messages for domain
lookups
2021-12-07 13:27:38 -05:00
8176b43880 Update static build script
Bump curl and toxcore versions
2021-12-06 11:42:53 -05:00
64794e14cd chore: Use toktok-stack 0.0.23 for cirrus builds. 2021-12-06 00:40:44 +00:00
f39da4d7f2 chore: Add a bazel test that calls toxic with --help.
This way we at least know it doesn't crash on load. Some code runs. We'll
want some real tests at some point, but this ensures *something* works.
2021-11-26 23:57:39 +00:00
af70c3d660 chore: Remove travis; add cirrus ci.
We still need a GitHub workflow to test the "make" build. For now, we only
test toktok-stack and the bazel build.
2021-11-26 23:52:39 +00:00
36 changed files with 509 additions and 296 deletions

13
.cirrus.yml Normal file
View File

@ -0,0 +1,13 @@
---
cirrus-ci_task:
container:
image: toxchat/toktok-stack:0.0.31-third_party
cpu: 2
memory: 2G
configure_script:
- /src/workspace/tools/inject-repo toxic
test_all_script:
- cd /src/workspace && bazel test -k
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
--config=release
//toxic/...

View File

@ -11,7 +11,8 @@ branches:
protection:
required_status_checks:
contexts:
- Codacy/PR Quality Review
- CodeFactor
- Travis CI - Pull Request
- build
- cirrus-ci
- Codacy Static Code Analysis
- code-review/reviewable
- infer

106
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,106 @@
name: ci
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run:
sudo apt-get update &&
sudo apt-get install -y --no-install-recommends
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libnotify-dev
libopenal-dev
libopus-dev
libqrencode-dev
libsodium-dev
libvpx-dev
libx11-dev
python3-dev
pkg-config &&
git clone --depth=1 https://github.com/TokTok/c-toxcore &&
cd c-toxcore &&
cmake . -B_build -DBOOTSTRAP_DAEMON=OFF &&
cd _build &&
make -j4 &&
sudo make install
- name: Build toxic
run: make -j4
infer:
runs-on: ubuntu-latest
container: toxchat/infer
steps:
- name: Install git
run:
apt-get update &&
DEBIAN_FRONTEND=noninteractive
apt-get install -y --no-install-recommends
git
- name: Install dependencies
run:
apt-get update &&
apt-get install -y --no-install-recommends
cmake
g++
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libncurses-dev
libnotify-dev
libopenal-dev
libopus-dev
libqrencode-dev
libsodium-dev
libvpx-dev
libx11-dev
make
python3-dev
pkg-config &&
git clone --depth=1 https://github.com/TokTok/c-toxcore &&
cd c-toxcore &&
cmake . -B_build -DBOOTSTRAP_DAEMON=OFF &&
cd _build &&
make -j4 &&
make install
- uses: actions/checkout@v2
- name: Run infer
run:
infer --no-progress-bar -- cc src/*.c
-fsyntax-only
$(python3-config --includes --ldflags)
$(pkg-config --cflags --libs
freealut
libconfig
libcurl
libnotify
libpng
libqrencode
ncurses
openal
python3
toxcore
vpx
x11)
-DAUDIO
-DBOX_NOTIFY
-DGAMES
-DPACKAGE_DATADIR='""'
-DPYTHON
-DQRCODE
-DSOUND_NOTIFY
-DVIDEO
- name: Print log
run:
cat /__w/toxic/toxic/infer-out/report.txt

View File

@ -1,60 +0,0 @@
---
language: python
python: nightly
dist: xenial
os: linux
jobs:
include:
- env: JOB=linux
addons:
apt:
packages:
- libalut-dev
- libconfig-dev
- libnotify-dev
- libopenal-dev
- libopus-dev
- libqrencode-dev
- libvpx-dev
cache:
directories:
- $HOME/cache
install:
# Where to find libraries.
- export LD_LIBRARY_PATH=$HOME/cache/usr/lib
- export PKG_CONFIG_PATH=$HOME/cache/usr/lib/pkgconfig
# c-sodium
- git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium ../libsodium
- test -f $HOME/cache/usr/lib/libsodium.so || (cd ../libsodium && ./configure --prefix=$HOME/cache/usr && make install -j$(nproc))
# c-toxcore
- git clone --depth=1 https://github.com/TokTok/c-toxcore ../c-toxcore
- test -f $HOME/cache/usr/lib/libtoxcore.so || (cd ../c-toxcore && cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/cache/usr && make -C_build install -j$(nproc))
script:
- make ENABLE_PYTHON=1 -j$(nproc)
- env: JOB=macos
os: macos
language: c
cache:
directories:
- $HOME/cache
install:
- brew install
freealut
libconfig
libqrencode
libsodium
openal-soft
- export LDFLAGS="-L/usr/local/Cellar/openal-soft/1.21.0/lib"
- git clone --depth=1 https://github.com/TokTok/c-toxcore ../c-toxcore
- test -f /usr/local/lib/libtoxcore.dylib || (cd ../c-toxcore && cmake -B_build -H. && make -C_build install -j$(nproc))
script:
- make ENABLE_PYTHON=1 DISABLE_DESKTOP_NOTIFY=1 DISABLE_X11=1 DISABLE_AV=1 DISABLE_SOUND_NOTIFY=1 -j$(nproc)

View File

@ -18,6 +18,7 @@ cc_binary(
copts = [
"-std=gnu99",
"-DAUDIO",
"-DGAMES",
"-DPACKAGE_DATADIR='\"data\"'",
"-DPYTHON",
"-DQRCODE",
@ -39,3 +40,10 @@ cc_binary(
"//tools/config:osx": [],
}),
)
sh_test(
name = "toxic_test",
size = "small",
srcs = [":toxic"],
args = ["--help"],
)

View File

@ -55,9 +55,9 @@ author = 'Jakob Kreuze'
# built documents.
#
# The short X.Y version.
version = '0.11.2'
version = '0.11.3'
# The full version, including alpha/beta/rc tags.
release = '0.11.2'
release = '0.11.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -151,4 +151,4 @@ texinfo_documents = [
(master_doc, 'toxic_api', 'toxic_api Documentation',
author, 'toxic_api', 'One line description of project.',
'Miscellaneous'),
]
]

View File

@ -1,5 +1,5 @@
# Version
TOXIC_VERSION = 0.11.2
TOXIC_VERSION = 0.11.3
REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error")
ifneq (, $(findstring error, $(REV)))
VERSION = $(TOXIC_VERSION)

View File

@ -132,10 +132,10 @@ mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="25a56c354937e9c8c4c50a64c3b4cfc099c34e29"
TOXCORE_VERSION="v0.2.13"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="8448752e6286c747130254571fde2db8e2fc073a8116f9fff489ed53af546c0a"
TOXCORE_HASH="67114fa57504c58b695f5dce8ef85124d555f2c3c353d0d2615e6d4845114ab8"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz"
@ -164,8 +164,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR"
CURL_VERSION="7.77.0"
CURL_HASH="b0a3428acb60fa59044c4d0baae4e4fc09ae9af1d8a3aa84b2e3fbcd99841f77"
CURL_VERSION="7.80.0"
CURL_HASH="dab997c9b08cb4a636a03f2f7f985eaba33279c1c52692430018fae4a4878dc7"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"

View File

@ -41,9 +41,6 @@ Tox *user_tox;
static WINDOW *cur_window;
static ToxWindow *self_window;
extern FriendsList Friends;
extern struct user_settings *user_settings;
void api_display(const char *const msg)
{
if (msg == NULL) {

View File

@ -60,14 +60,8 @@
#endif /* ALC_ALL_DEVICES_SPECIFIER */
#endif /* __APPLE__ */
extern FriendsList Friends;
extern ToxWindow *windows[MAX_WINDOWS_NUM];
struct CallControl CallControl;
extern struct user_settings *user_settings;
extern struct Winthread Winthread;
void on_call(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled,
void *user_data);
void on_call_state(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data);

View File

@ -530,7 +530,7 @@ static DeviceError open_device(DeviceType type, uint32_t *device_idx, DataHandle
device->cb_data = cb_data;
#ifdef AUDIO
if (user_settings->VAD_threshold >= 0.0f) {
if (user_settings->VAD_threshold >= 0.0) {
device->VAD_threshold = user_settings->VAD_threshold;
}

View File

@ -56,7 +56,7 @@ static void print_ac_matches(ToxWindow *self, Tox *m, char **list, size_t n_matc
*
* Returns the length of the match.
*/
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const char **matches, size_t n_items,
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const char *const *matches, size_t n_items,
size_t max_size)
{
UNUSED_VAR(self);
@ -96,7 +96,7 @@ static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const
*
* Note: This function should not be called directly. Use complete_line() and complete_path() instead.
*/
static int complete_line_helper(ToxWindow *self, const char **list, const size_t n_items, bool dir_search)
static int complete_line_helper(ToxWindow *self, const char *const *list, const size_t n_items, bool dir_search)
{
ChatContext *ctx = self->chatwin;
@ -181,7 +181,7 @@ static int complete_line_helper(ToxWindow *self, const char **list, const size_t
}
char match[MAX_STR_SIZE];
size_t match_len = get_str_match(self, match, sizeof(match), (const char **) matches, n_matches, MAX_STR_SIZE);
size_t match_len = get_str_match(self, match, sizeof(match), (const char *const *) matches, n_matches, MAX_STR_SIZE);
free_ptr_array((void **) matches);
@ -259,12 +259,12 @@ static int complete_line_helper(ToxWindow *self, const char **list, const size_t
return diff;
}
int complete_line(ToxWindow *self, const char **list, size_t n_items)
int complete_line(ToxWindow *self, const char *const *list, size_t n_items)
{
return complete_line_helper(self, list, n_items, false);
}
static int complete_path(ToxWindow *self, const char **list, const size_t n_items)
static int complete_path(ToxWindow *self, const char *const *list, const size_t n_items)
{
return complete_line_helper(self, list, n_items, true);
}
@ -385,7 +385,7 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
print_ac_matches(self, m, dirnames, dircount);
}
int ret = complete_path(self, (const char **) dirnames, dircount);
int ret = complete_path(self, (const char *const *) dirnames, dircount);
free_ptr_array((void **) dirnames);

View File

@ -39,9 +39,7 @@
#include "settings.h"
#include "windows.h"
extern struct arg_opts arg_opts;
extern struct user_settings *user_settings;
extern struct Winthread Winthread;
/* URL that we get the JSON encoded nodes list from. */
#define NODES_LIST_URL "https://nodes.tox.chat/json"
@ -59,7 +57,6 @@ extern struct Winthread Winthread;
#define IP_MAX_SIZE 45
#define IP_MIN_SIZE 7
#define PORT_MAX_SIZE 5
#define LAST_SCAN_JSON_KEY "\"last_scan\":"
#define LAST_SCAN_JSON_KEY_LEN (sizeof(LAST_SCAN_JSON_KEY) - 1)

View File

@ -58,12 +58,6 @@
#endif /* VIDEO */
#endif /* AUDIO */
extern char *DATA_FILE;
extern FriendsList Friends;
extern struct Winthread Winthread;
extern struct user_settings *user_settings;
#ifdef AUDIO
static void init_infobox(ToxWindow *self);
static void kill_infobox(ToxWindow *self);
@ -254,6 +248,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, Tox_C
if (prev_status == TOX_CONNECTION_NONE) {
chat_resume_file_senders(self, m, num);
file_send_queue_check(self, m, self->num);
msg = "has come online";
line_info_add(self, true, nick, NULL, CONNECTION, 0, GREEN, msg);
@ -798,12 +793,7 @@ void chat_onGameInvite(ToxWindow *self, Tox *m, uint32_t friend_number, const ui
return;
}
Friends.list[friend_number].game_invite.type = type;
Friends.list[friend_number].game_invite.id = id;
Friends.list[friend_number].game_invite.pending = true;
uint32_t data_length = length - GAME_PACKET_HEADER_SIZE;
Friends.list[friend_number].game_invite.data_length = data_length;
if (data_length > 0) {
free(Friends.list[friend_number].game_invite.data);
@ -818,6 +808,11 @@ void chat_onGameInvite(ToxWindow *self, Tox *m, uint32_t friend_number, const ui
Friends.list[friend_number].game_invite.data = buf;
}
Friends.list[friend_number].game_invite.type = type;
Friends.list[friend_number].game_invite.id = id;
Friends.list[friend_number].game_invite.pending = true;
Friends.list[friend_number].game_invite.data_length = data_length;
char name[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, name, friend_number);
@ -1270,9 +1265,16 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
}
ChatContext *ctx = self->chatwin;
StatusBar *statusbar = self->stb;
pthread_mutex_lock(&Winthread.lock);
line_info_print(self);
Tox_Connection connection = statusbar->connection;
Tox_User_Status status = statusbar->status;
const bool is_typing = Friends.list[self->num].is_typing;
pthread_mutex_unlock(&Winthread.lock);
wclear(ctx->linewin);
@ -1283,14 +1285,6 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
curs_set(1);
/* Draw status bar */
StatusBar *statusbar = self->stb;
pthread_mutex_lock(&Winthread.lock);
Tox_Connection connection = statusbar->connection;
Tox_User_Status status = statusbar->status;
pthread_mutex_unlock(&Winthread.lock);
wmove(statusbar->topline, 0, 0);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
@ -1318,13 +1312,13 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
}
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "]");
wprintw(statusbar->topline, "] ");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
if (status != TOX_USER_STATUS_NONE) {
const char *status_text = "ERROR";
int colour = MAGENTA;
const char *status_text = "ERROR";
int colour = BAR_TEXT;
if (connection != TOX_CONNECTION_NONE) {
switch (status) {
case TOX_USER_STATUS_AWAY:
colour = STATUS_AWAY;
@ -1339,9 +1333,11 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
default:
break;
}
}
if (colour != BAR_TEXT) {
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " [");
wprintw(statusbar->topline, "[");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@ -1351,30 +1347,23 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "] ");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
}
pthread_mutex_lock(&Winthread.lock);
const bool is_typing = Friends.list[self->num].is_typing;
pthread_mutex_unlock(&Winthread.lock);
if (is_typing) {
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
}
wprintw(statusbar->topline, "%s", statusbar->nick);
if (is_typing) {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_TEXT));
}
if (is_typing) {
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wprintw(statusbar->topline, " %s", statusbar->nick);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
}
wprintw(statusbar->topline, "%s", statusbar->nick);
if (is_typing) {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_TEXT));
}
/* Reset statusbar->statusmsg on window resize */
if (x2 != self->x) {
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH] = {'\0'};

View File

@ -54,7 +54,13 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
return;
}
struct FileTransfer *ft = NULL;
// first check transfer queue
if (file_send_queue_remove(self->num, idx) == 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Pending file transfer removed from queue");
return;
}
FileTransfer *ft = NULL;
/* cancel an incoming file transfer */
if (strcasecmp(inoutstr, "in") == 0) {
@ -239,7 +245,7 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
return;
}
struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
if (!ft) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
@ -324,7 +330,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
FILE *file_to_send = fopen(path, "r");
if (file_to_send == NULL) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File not found.");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File `%s` not found.", path);
return;
}
@ -347,7 +353,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
goto on_send_error;
}
struct FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
if (!ft) {
err = TOX_ERR_FILE_SEND_TOO_MANY;
@ -367,29 +373,62 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
on_send_error:
fclose(file_to_send);
switch (err) {
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND:
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: {
errmsg = "File transfer failed: Invalid friend.";
break;
}
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED:
errmsg = "File transfer failed: Friend is offline.";
break;
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: {
int queue_idx = file_send_queue_add(self->num, path, path_len);
case TOX_ERR_FILE_SEND_NAME_TOO_LONG:
char msg[MAX_STR_SIZE];
switch (queue_idx) {
case -1: {
snprintf(msg, sizeof(msg), "Invalid file name: path is null or length is zero.");
break;
}
case -2: {
snprintf(msg, sizeof(msg), "File name is too long.");
break;
}
case -3: {
snprintf(msg, sizeof(msg), "File send queue is full.");
break;
}
default: {
snprintf(msg, sizeof(msg), "File transfer queued. Type \"/cancel out %d\" to cancel.", queue_idx);
break;
}
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
return;
}
case TOX_ERR_FILE_SEND_NAME_TOO_LONG: {
errmsg = "File transfer failed: Filename is too long.";
break;
}
case TOX_ERR_FILE_SEND_TOO_MANY:
case TOX_ERR_FILE_SEND_TOO_MANY: {
errmsg = "File transfer failed: Too many concurrent file transfers.";
break;
}
default:
default: {
errmsg = "File transfer failed.";
break;
}
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", errmsg);
tox_file_control(m, self->num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
fclose(file_to_send);
}

View File

@ -63,8 +63,6 @@
#include "toxic_strings.h"
#include "windows.h"
extern char *DATA_FILE;
#define MAX_CONFERENCE_NUM (MAX_WINDOWS_NUM - 2)
#define CONFERENCE_EVENT_WAIT 30

View File

@ -117,15 +117,8 @@ static struct cmd_func conference_commands[] = {
{ NULL, NULL },
};
#ifdef PYTHON
#define SPECIAL_COMMANDS 8
#else
#define SPECIAL_COMMANDS 7
#endif /* PYTHON */
/* Special commands are commands that only take one argument even if it contains spaces */
static const char special_commands[SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = {
static const char special_commands[][MAX_CMDNAME_SIZE] = {
"/add",
"/avatar",
"/nick",
@ -136,6 +129,7 @@ static const char special_commands[SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = {
"/sendfile",
"/title",
"/mute",
"",
};
/* Returns true if input command is in the special_commands array. */
@ -143,7 +137,7 @@ static bool is_special_command(const char *input)
{
const int s = char_find(0, input, ' ');
for (int i = 0; i < SPECIAL_COMMANDS; ++i) {
for (int i = 0; special_commands[i][0] != '\0'; ++i) {
if (strncmp(input, special_commands[i], s) == 0) {
return true;
}

View File

@ -25,6 +25,7 @@
#include <time.h>
#include <unistd.h>
#include "execute.h"
#include "file_transfers.h"
#include "friendlist.h"
#include "line_info.h"
@ -98,7 +99,7 @@ void print_progress_bar(ToxWindow *self, double bps, double pct_done, uint32_t l
free(full_line);
}
static void refresh_progress_helper(ToxWindow *self, struct FileTransfer *ft)
static void refresh_progress_helper(ToxWindow *self, FileTransfer *ft)
{
if (ft->state == FILE_TRANSFER_INACTIVE) {
return;
@ -126,8 +127,8 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
bool active = false;
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
struct FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
refresh_progress_helper(self, ft_r);
refresh_progress_helper(self, ft_s);
@ -140,9 +141,9 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
return active;
}
static void clear_file_transfer(struct FileTransfer *ft)
static void clear_file_transfer(FileTransfer *ft)
{
*ft = (struct FileTransfer) {
*ft = (FileTransfer) {
0
};
}
@ -150,16 +151,16 @@ static void clear_file_transfer(struct FileTransfer *ft)
/* Returns a pointer to friendnumber's FileTransfer struct associated with filenumber.
* Returns NULL if filenumber is invalid.
*/
struct FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
if (ft_send->state != FILE_TRANSFER_INACTIVE && ft_send->filenumber == filenumber) {
return ft_send;
}
struct FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
if (ft_recv->state != FILE_TRANSFER_INACTIVE && ft_recv->filenumber == filenumber) {
return ft_recv;
@ -172,7 +173,7 @@ struct FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t fi
/* Returns a pointer to the FileTransfer struct associated with index with the direction specified.
* Returns NULL on failure.
*/
struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
FILE_TRANSFER_DIRECTION direction)
{
if (direction != FILE_TRANSFER_RECV && direction != FILE_TRANSFER_SEND) {
@ -180,9 +181,9 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
}
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
&Friends.list[friendnumber].file_sender[i] :
&Friends.list[friendnumber].file_receiver[i];
FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
&Friends.list[friendnumber].file_sender[i] :
&Friends.list[friendnumber].file_receiver[i];
if (ft->state != FILE_TRANSFER_INACTIVE && ft->index == index) {
return ft;
@ -195,10 +196,10 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
/* Returns a pointer to an unused file sender.
* Returns NULL if all file senders are in use.
*/
static struct FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
static FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
clear_file_transfer(ft);
@ -218,11 +219,11 @@ static struct FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnu
/* Returns a pointer to an unused file receiver.
* Returns NULL if all file receivers are in use.
*/
static struct FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
uint8_t type)
static FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
uint8_t type)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
clear_file_transfer(ft);
@ -242,8 +243,8 @@ static struct FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friend
/* Initializes an unused file transfer and returns its pointer.
* Returns NULL on failure.
*/
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type)
FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type)
{
if (direction == FILE_TRANSFER_RECV) {
return new_file_receiver(window, friendnumber, filenumber, type);
@ -256,13 +257,83 @@ struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber,
return NULL;
}
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length)
{
if (length == 0 || file_path == NULL) {
return -1;
}
if (length > TOX_MAX_FILENAME_LENGTH) {
return -2;
}
for (size_t i = 0; i < MAX_FILES; ++i) {
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
if (pending_slot->pending) {
continue;
}
pending_slot->pending = true;
memcpy(pending_slot->file_path, file_path, length);
pending_slot->file_path[length] = 0;
pending_slot->length = length;
return i;
}
return -3;
}
#define FILE_TRANSFER_SEND_CMD "/sendfile "
#define FILE_TRANSFER_SEND_LEN (sizeof(FILE_TRANSFER_SEND_CMD) - 1)
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
if (!pending_slot->pending) {
continue;
}
char command[TOX_MAX_FILENAME_LENGTH + FILE_TRANSFER_SEND_LEN + 1];
snprintf(command, sizeof(command), "%s%s", FILE_TRANSFER_SEND_CMD, pending_slot->file_path);
execute(self->window, self, m, command, CHAT_COMMAND_MODE);
*pending_slot = (PendingFileTransfer) {
0,
};
}
}
int file_send_queue_remove(uint32_t friendnumber, size_t index)
{
if (index >= MAX_FILES) {
return -1;
}
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[index];
if (!pending_slot->pending) {
return -1;
}
*pending_slot = (PendingFileTransfer) {
0,
};
return 0;
}
/* Closes file transfer ft.
*
* 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,
void close_file_transfer(ToxWindow *self, Tox *m, FileTransfer *ft, int CTRL, const char *message,
Notification sound_type)
{
if (!ft) {
@ -278,7 +349,11 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C
}
if (CTRL >= 0) {
tox_file_control(m, ft->friendnumber, ft->filenumber, (Tox_File_Control) CTRL, NULL);
Tox_Err_File_Control err;
if (!tox_file_control(m, ft->friendnumber, ft->filenumber, (Tox_File_Control) CTRL, &err)) {
fprintf(stderr, "Failed to cancel file transfer: %d\n", err);
}
}
if (message && self) {
@ -298,7 +373,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C
void kill_avatar_file_transfers_friend(Tox *m, uint32_t friendnumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
if (ft->file_type == TOX_FILE_KIND_AVATAR) {
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
@ -312,6 +387,7 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber)
for (size_t i = 0; i < MAX_FILES; ++i) {
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_sender[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_receiver[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
file_send_queue_remove(friendnumber, i);
}
}

View File

@ -29,9 +29,9 @@
#include "toxic.h"
#include "windows.h"
#define KiB 1024
#define MiB 1048576 /* 1024^2 */
#define GiB 1073741824 /* 1024^3 */
#define KiB (uint32_t) 1024
#define MiB (uint32_t) (1024 << 10) /* 1024^2 */
#define GiB (uint32_t) (1024 << 20) /* 1024^3 */
#define MAX_FILES 32
@ -47,7 +47,7 @@ typedef enum FILE_TRANSFER_DIRECTION {
FILE_TRANSFER_RECV
} FILE_TRANSFER_DIRECTION;
struct FileTransfer {
typedef struct FileTransfer {
ToxWindow *window;
FILE *file;
FILE_TRANSFER_STATE state;
@ -63,7 +63,15 @@ struct FileTransfer {
time_t last_line_progress; /* The last time we updated the progress bar */
uint32_t line_id;
uint8_t file_id[TOX_FILE_ID_LENGTH];
};
} FileTransfer;
typedef struct PendingFileTransfer {
char file_path[TOX_MAX_FILENAME_LENGTH + 1];
size_t length;
uint32_t friendnumber;
bool pending;
} PendingFileTransfer;
/* creates initial progress line that will be updated during file transfer.
progline must be at lesat MAX_STR_SIZE bytes */
@ -96,6 +104,31 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type);
/* Adds a file designated by `file_path` of length `length` to the file transfer queue.
*
* Items in this queue will be automatically sent to the contact designated by `friendnumber`
* as soon as they appear online. The item will then be removed from the queue whether
* or not the transfer successfully initiates.
*
* If the ToxWindow associated with this friend is closed, all queued items will be
* discarded.
*
* Return the queue index on success.
* Return -1 if the length is invalid.
* Return -2 if the send queue is full.
*/
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length);
/* Initiates all file transfers from the file send queue for friend designated by `friendnumber`. */
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber);
/* Removes the `index`-th item from the file send queue for `friendnumber`.
*
* Return 0 if a pending transfer was successfully removed
* Return -1 if index does not designate a pending file transfer.
*/
int file_send_queue_remove(uint32_t friendnumber, size_t index);
/* Closes file transfer ft.
*
* Set CTRL to -1 if we don't want to send a control signal.

View File

@ -37,6 +37,7 @@
#include "log.h"
#include "misc_tools.h"
#include "notify.h"
#include "prompt.h"
#include "settings.h"
#include "toxic.h"
#include "windows.h"
@ -46,13 +47,6 @@
#endif
extern char *DATA_FILE;
extern char *BLOCK_FILE;
extern ToxWindow *prompt;
extern struct Winthread Winthread;
extern struct user_settings *user_settings;
extern struct arg_opts arg_opts;
static uint8_t blocklist_view = 0; /* 0 if we're in friendlist view, 1 if we're in blocklist view */
FriendsList Friends;
@ -321,11 +315,11 @@ int load_blocklist(char *path)
#define S_WEIGHT 100000
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);
int res = qsort_strcasecmp_hlpr(Friends.list[*(const int *) n1].name, Friends.list[*(const int *) n2].name);
/* Use weight to make qsort always put online friends before offline */
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);
res = Friends.list[*(const int *) n1].connection_status ? (res - S_WEIGHT) : (res + S_WEIGHT);
res = Friends.list[*(const int *) n2].connection_status ? (res + S_WEIGHT) : (res - S_WEIGHT);
return res;
}
@ -349,7 +343,7 @@ void sort_friendlist_index(void)
static int index_name_cmp_block(const void *n1, const void *n2)
{
return qsort_strcasecmp_hlpr(Blocked.list[*(int *) n1].name, Blocked.list[*(int *) n2].name);
return qsort_strcasecmp_hlpr(Blocked.list[*(const int *) n1].name, Blocked.list[*(const int *) n2].name);
}
static void sort_blocklist_index(void)
@ -698,6 +692,9 @@ static void select_friend(wint_t key, int *selected, int num)
static void delete_friend(Tox *m, uint32_t f_num)
{
kill_all_file_transfers_friend(m, f_num);
kill_avatar_file_transfers_friend(m, f_num);
Tox_Err_Friend_Delete err;
if (tox_friend_delete(m, f_num, &err) != true) {
@ -846,9 +843,7 @@ void block_friend(Tox *m, uint32_t fnum)
realloc_blocklist(Blocked.max_idx + 1);
clear_blocklist_index(Blocked.max_idx);
int i;
for (i = 0; i <= Blocked.max_idx; ++i) {
for (int i = 0; i <= Blocked.max_idx; ++i) {
if (Blocked.list[i].active) {
continue;
}
@ -1113,14 +1108,14 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
/* Determine which portion of friendlist to draw based on current position */
pthread_mutex_lock(&Winthread.lock);
int page = Friends.num_selected / (y2 - FLIST_OFST);
const int page = Friends.num_selected / (y2 - FLIST_OFST);
pthread_mutex_unlock(&Winthread.lock);
int start = (y2 - FLIST_OFST) * page;
int end = y2 - FLIST_OFST + start;
const int start = (y2 - FLIST_OFST) * page;
const int end = y2 - FLIST_OFST + start;
pthread_mutex_lock(&Winthread.lock);
size_t num_friends = Friends.num_friends;
const size_t num_friends = Friends.num_friends;
pthread_mutex_unlock(&Winthread.lock);
int i;

View File

@ -79,8 +79,9 @@ typedef struct {
struct GameInvite game_invite;
#endif
struct FileTransfer file_receiver[MAX_FILES];
struct FileTransfer file_sender[MAX_FILES];
FileTransfer file_receiver[MAX_FILES];
FileTransfer file_sender[MAX_FILES];
PendingFileTransfer file_send_queue[MAX_FILES];
} ToxicFriend;
typedef struct {
@ -101,6 +102,8 @@ typedef struct {
ToxicFriend *list;
} FriendsList;
extern FriendsList Friends;
ToxWindow *new_friendlist(void);
void friendlist_onInit(ToxWindow *self, Tox *m);
void disable_chatwin(uint32_t f_num);

View File

@ -517,10 +517,10 @@ static void game_draw_help_bar(const GameData *game, WINDOW *win)
{
int max_x;
int max_y;
UNUSED_VAR(max_x);
getmaxyx(win, max_y, max_x);
UNUSED_VAR(max_x);
wmove(win, max_y - 1, 1);
if (!game->is_multiplayer) {
@ -937,10 +937,10 @@ int game_y_bottom_bound(const GameData *game)
{
int max_x;
int max_y;
UNUSED_VAR(max_x);
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_x);
return ((max_y + game->game_max_y) / 2) - 1;
}
@ -948,10 +948,10 @@ int game_y_top_bound(const GameData *game)
{
int max_x;
int max_y;
UNUSED_VAR(max_x);
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_x);
return ((max_y - game->game_max_y) / 2) + 1;
}
@ -959,10 +959,10 @@ int game_x_right_bound(const GameData *game)
{
int max_x;
int max_y;
UNUSED_VAR(max_y);
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_y);
return ((max_x + game->game_max_x) / 2) - 1;
}
@ -970,10 +970,10 @@ int game_x_left_bound(const GameData *game)
{
int max_x;
int max_y;
UNUSED_VAR(max_y);
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_y);
return ((max_x - game->game_max_x) / 2) + 1;
}

View File

@ -436,7 +436,11 @@ static bool chess_path_line_clear(Board *board, const Tile *from, const Tile *to
return false;
}
ChessCoords chess_coords;
ChessCoords chess_coords = (ChessCoords) {
0,
0
};
size_t start;
size_t end;
@ -800,11 +804,13 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
{
Board *board = &state->board;
const bool en_passant = player->en_passant_move_number == -1;
bool in_check = false;
Tile *ep_tile = NULL;
Piece ep_piece;
memset(&ep_piece, 0, sizeof(ep_piece));
if (player->en_passant_move_number == -1) { // remove piece that was captured via en passant
if (en_passant) { // remove piece that was captured via en passant
ChessCoords ep_coords;
ep_coords.N = player->colour == White ? to->chess_coords.N - 1 : to->chess_coords.N + 1;
ep_coords.L = to->chess_coords.L;
@ -815,7 +821,7 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
}
chess_copy_piece(&ep_piece, &ep_tile->piece);
ep_tile->piece.type = NoPiece;
ep_tile->piece.type = NoPiece; // temporarily remove piece
}
Piece from_piece;
@ -831,8 +837,8 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
from->piece.type = from_piece.type;
chess_copy_piece(&to->piece, &to_piece);
if (player->en_passant_move_number == -1) {
ep_tile->piece.type = ep_piece.type;
if (en_passant) {
ep_tile->piece.type = ep_piece.type; // reset piece to original state
}
return !in_check;

View File

@ -42,11 +42,6 @@
#include "game_base.h"
#endif
extern char *DATA_FILE;
extern ToxWindow *prompt;
extern FriendsList Friends;
extern FriendRequests FrndRequests;
/* command functions */
void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
@ -161,18 +156,12 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
const char *id = argv[1];
const size_t arg_length = strlen(id);
const bool is_tox_id = arg_length >= (2 * TOX_ADDRESS_SIZE);
const int space_idx = char_find(0, id, ' ');
if (is_tox_id) {
// we have to manually parse the message due to this command being a special case
int idx = char_find(0, id, ' ');
if (idx > 0 && idx < arg_length - 1) {
snprintf(msg, sizeof(msg), "%s", &id[idx + 1]);
}
}
if (!msg[0]) {
// we have to manually parse the message due to this command being a special case
if (space_idx > 0 && space_idx < arg_length - 1) {
snprintf(msg, sizeof(msg), "%s", &id[space_idx + 1]);
} else {
char selfname[TOX_MAX_NAME_LENGTH];
tox_self_get_name(m, (uint8_t *) selfname);
@ -183,34 +172,34 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
char id_bin[TOX_ADDRESS_SIZE] = {0};
/* try to add tox ID */
if (is_tox_id) {
size_t i;
char xx[3];
uint32_t x;
const bool is_tox_id = (char_find(0, id, '@') == arg_length) && (arg_length >= TOX_ADDRESS_SIZE * 2);
for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
xx[2] = 0;
if (!is_tox_id) {
name_lookup(self, m, id_bin, id, msg);
}
if (sscanf(xx, "%02x", &x) != 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
return;
}
char xx[3];
uint32_t x = 0;
id_bin[i] = x;
}
for (size_t i = 0; i < TOX_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
xx[2] = 0;
if (friend_is_blocked(id_bin)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Friend is in your block list.");
if (sscanf(xx, "%02x", &x) != 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
return;
}
cmd_add_helper(self, m, id_bin, msg);
} else { /* assume id is a username@domain address and do http name server lookup */
name_lookup(self, m, id_bin, id, msg);
id_bin[i] = x;
}
if (friend_is_blocked(id_bin)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Friend is in your block list.");
return;
}
cmd_add_helper(self, m, id_bin, msg);
}
void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])

View File

@ -148,9 +148,10 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
int x;
int y;
UNUSED_VAR(x);
getyx(win, y, x);
UNUSED_VAR(x);
// make sure cursor will wrap correctly after newline to prevent display bugs
if (y + 1 >= max_y) {
return -1;
@ -324,10 +325,10 @@ static void line_info_init_line(ToxWindow *self, struct line_info *line)
{
int y2;
int x2;
UNUSED_VAR(y2);
getmaxyx(self->window, y2, x2);
UNUSED_VAR(y2);
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
@ -522,10 +523,10 @@ void line_info_print(ToxWindow *self)
while (line && numlines++ <= max_y && print_ret == 0) {
int y;
int x;
UNUSED_VAR(y);
getyx(win, y, x);
UNUSED_VAR(y);
if (x > 0) { // Prevents us from printing off the screen
break;
}

View File

@ -148,7 +148,7 @@ void get_elapsed_time_str(char *buf, int bufsize, time_t secs)
*/
int tox_pk_string_to_bytes(const char *hex_string, size_t hex_len, char *output, size_t output_size)
{
if (output_size != TOX_PUBLIC_KEY_SIZE || hex_len > output_size * 2) {
if (output_size != TOX_PUBLIC_KEY_SIZE || hex_len != output_size * 2) {
return -1;
}
@ -288,7 +288,7 @@ int qsort_strcasecmp_hlpr(const void *str1, const void *str2)
/* case-insensitive string compare function for use with qsort */
int qsort_ptr_char_array_helper(const void *str1, const void *str2)
{
return strcasecmp(*(char **)str1, *(char **)str2);
return strcasecmp(*(const char *const *)str1, *(const char *const *)str2);
}
static const char invalid_chars[] = {'/', '\n', '\t', '\v', '\r', '\0'};

View File

@ -33,9 +33,6 @@
#include "toxic.h"
#include "windows.h"
extern struct arg_opts arg_opts;
extern struct Winthread Winthread;
#define NAMESERVER_API_PATH "api"
#define SERVER_KEY_SIZE 32
#define MAX_SERVERS 50
@ -111,14 +108,15 @@ static int load_nameserver_list(const char *path)
char line[MAX_SERVER_LINE];
while (fgets(line, sizeof(line), fp) && Nameservers.lines < MAX_SERVERS) {
int linelen = strlen(line);
size_t linelen = strlen(line);
if (linelen < SERVER_KEY_SIZE * 2 + 5) {
continue;
}
if (line[linelen - 1] == '\n') {
line[--linelen] = '\0';
--linelen;
line[linelen] = '\0';
}
const char *name = strtok(line, " ");

View File

@ -489,16 +489,27 @@ void terminate_notify(void)
}
#ifdef SOUND_NOTIFY
int set_sound(Notification sound, const char *value)
/*
* Sets notification sound designated by `sound` to file path `value`.
*
* Return true if the sound is successfully set.
*/
bool set_sound(Notification sound, const char *value)
{
if (sound == silent) {
return 0;
return false;
}
free(Control.sounds[sound]);
size_t len = strlen(value) + 1;
Control.sounds[sound] = calloc(len, 1);
if (Control.sounds[sound] == NULL) {
return false;
}
memcpy(Control.sounds[sound], value, len);
struct stat buf;

View File

@ -77,7 +77,7 @@ int box_silent_notify(ToxWindow *self, uint64_t flags, int *id_indicator, const
int box_silent_notify2(ToxWindow *self, uint64_t flags, int id, const char *format, ...);
#ifdef SOUND_NOTIFY
int set_sound(Notification sound, const char *value);
bool set_sound(Notification sound, const char *value);
#endif /* SOUND_NOTIFY */
#endif /* NOTIFY_H */

View File

@ -40,6 +40,9 @@ typedef struct FriendRequests {
struct friend_request request[MAX_FRIEND_REQUESTS];
} FriendRequests;
extern ToxWindow *prompt;
extern FriendRequests FrndRequests;
ToxWindow *new_prompt(void);
void prep_prompt_win(void);

View File

@ -96,6 +96,8 @@ struct user_settings {
#endif
};
extern struct user_settings *user_settings;
enum settings_values {
AUTOLOG_OFF = 0,
AUTOLOG_ON = 1,

View File

@ -74,7 +74,7 @@
#ifdef VIDEO
#include "video_call.h"
#endif /* VIDEO */
ToxAV *av;
static ToxAV *av;
#endif /* AUDIO */
#ifdef PYTHON
@ -98,10 +98,13 @@ ToxWindow *prompt = NULL;
#define MAX_PASSWORD_LEN 64
struct Winthread Winthread;
struct cqueue_thread cqueue_thread;
struct av_thread av_thread;
static struct cqueue_thread cqueue_thread;
struct arg_opts arg_opts;
#ifdef AUDIO
static struct av_thread av_thread;
#endif
// This struct is not thread safe. It should only ever be written to from the main thread
// before any other thread that uses it is initialized.
struct user_settings *user_settings = NULL;

View File

@ -145,5 +145,7 @@ void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userd
void on_friend_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata);
void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *data, size_t length, void *userdata);
extern char *DATA_FILE;
extern char *BLOCK_FILE;
#endif /* TOXIC_H */

View File

@ -92,21 +92,21 @@ typedef struct VideoDevice {
} VideoDevice;
const char *dvideo_device_names[2]; /* Default device */
const char *video_devices_names[2][MAX_DEVICES]; /* Container of available devices */
static int size[2]; /* Size of above containers */
VideoDevice *video_devices_running[2][MAX_DEVICES] = {{NULL}}; /* Running devices */
uint32_t primary_video_device[2]; /* Primary device */
static const char *dvideo_device_names[2]; /* Default device */
static char *video_devices_names[2][MAX_DEVICES]; /* Container of available devices */
static int size[2]; /* Size of above containers */
static VideoDevice *video_devices_running[2][MAX_DEVICES] = {{NULL}}; /* Running devices */
static uint32_t primary_video_device[2]; /* Primary device */
static ToxAV *av = NULL;
/* q_mutex */
#define lock pthread_mutex_lock(&video_mutex)
#define unlock pthread_mutex_unlock(&video_mutex)
pthread_mutex_t video_mutex;
static pthread_mutex_t video_mutex;
bool video_thread_running = true,
video_thread_paused = true; /* Thread control */
static bool video_thread_running = true;
static bool video_thread_paused = true; /* Thread control */
void *video_thread_poll(void *);
@ -187,7 +187,7 @@ VideoDeviceError init_video_devices(void)
#if defined(__OSX__) || defined(__APPLE__)
if (osx_video_init((char **)video_devices_names[vdt_input], &size[vdt_input]) != 0) {
if (osx_video_init(&video_devices_names[vdt_input][0], &size[vdt_input]) != 0) {
return vde_InternalError;
}
@ -209,12 +209,24 @@ VideoDeviceError init_video_devices(void)
/* Query V4L for capture capabilities */
if (-1 != ioctl(fd, VIDIOC_QUERYCAP, &cap)) {
video_input_name = (char *)malloc(strlen((const char *)cap.card) + strlen(device_address) + 4);
if (video_input_name == NULL) {
close(fd);
return vde_InternalError;
}
strcpy(video_input_name, (char *)cap.card);
strcat(video_input_name, " (");
strcat(video_input_name, (char *)device_address);
strcat(video_input_name, ")");
} else {
video_input_name = (char *)malloc(strlen(device_address) + 3);
if (video_input_name == NULL) {
close(fd);
return vde_InternalError;
}
strcpy(video_input_name, "(");
strcat(video_input_name, device_address);
strcat(video_input_name, ")");
@ -229,6 +241,9 @@ VideoDeviceError init_video_devices(void)
#endif
size[vdt_output] = 1;
// TODO(iphydf): String literals are const char *. This may need to be
// copied, or if we're not owning any output device names, it should be
// const and video_devices_names needs to be split.
char *video_output_name = "Toxic Video Receiver";
video_devices_names[vdt_output][0] = video_output_name;
@ -262,7 +277,7 @@ VideoDeviceError terminate_video_devices(void)
int i;
for (i = 0; i < size[vdt_input]; ++i) {
free((void *)video_devices_names[vdt_input][i]);
free(video_devices_names[vdt_input][i]);
}
if (pthread_mutex_destroy(&video_mutex) != 0) {

View File

@ -41,16 +41,10 @@
#include "game_base.h"
#endif
extern char *DATA_FILE;
extern struct Winthread Winthread;
ToxWindow *windows[MAX_WINDOWS_NUM];
static uint8_t active_window_index;
static int num_active_windows;
extern ToxWindow *prompt;
extern struct user_settings *user_settings;
/* CALLBACKS START */
void on_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{
@ -196,7 +190,7 @@ void on_conference_invite(Tox *m, uint32_t friendnumber, Tox_Conference_Type typ
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onConferenceInvite != NULL) {
windows[i]->onConferenceInvite(windows[i], m, friendnumber, type, (char *) conference_pub_key, length);
windows[i]->onConferenceInvite(windows[i], m, friendnumber, type, (const char *) conference_pub_key, length);
}
}
}
@ -250,7 +244,7 @@ void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, u
{
UNUSED_VAR(userdata);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -273,7 +267,7 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint
{
UNUSED_VAR(userdata);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -281,7 +275,7 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onFileRecvChunk != NULL) {
windows[i]->onFileRecvChunk(windows[i], m, friendnumber, filenumber, position, (char *) data, length);
windows[i]->onFileRecvChunk(windows[i], m, friendnumber, filenumber, position, (const char *) data, length);
}
}
}
@ -291,7 +285,7 @@ void on_file_recv_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, To
{
UNUSED_VAR(userdata);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -322,7 +316,7 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onFileRecv != NULL) {
windows[i]->onFileRecv(windows[i], m, friendnumber, filenumber, file_size, (char *) filename,
windows[i]->onFileRecv(windows[i], m, friendnumber, filenumber, file_size, (const char *) filename,
filename_length);
}
}
@ -691,10 +685,10 @@ void draw_window_bar(ToxWindow *self)
int cur_x;
int cur_y;
UNUSED_VAR(cur_y);
getyx(win, cur_y, cur_x);
UNUSED_VAR(cur_y);
wattron(win, COLOR_PAIR(BAR_TEXT));
mvwhline(win, 0, cur_x, ' ', COLS - cur_x);
wattroff(win, COLOR_PAIR(BAR_TEXT));

View File

@ -114,6 +114,8 @@ struct Winthread {
volatile sig_atomic_t last_refresh_flag;
};
extern struct Winthread Winthread;
struct cqueue_thread {
pthread_t tid;
};
@ -147,6 +149,8 @@ struct arg_opts {
uint16_t tcp_port;
};
extern struct arg_opts arg_opts;
typedef struct ToxWindow ToxWindow;
typedef struct StatusBar StatusBar;
typedef struct PromptBuf PromptBuf;
@ -233,6 +237,8 @@ struct ToxWindow {
WINDOW *window_bar;
};
extern ToxWindow *windows[MAX_WINDOWS_NUM];
/* statusbar info holder */
struct StatusBar {
WINDOW *topline;