1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-06-26 20:47:45 +02:00

Lots of bug fixes and general code cleanup

This commit is contained in:
Jfreegman 2015-08-27 03:38:08 -04:00
parent 92d76c7f99
commit 11701d22a1
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
19 changed files with 247 additions and 173 deletions

View File

@ -93,7 +93,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE) if (ctx->pos <= 0 || ctx->len <= 0 || ctx->pos > ctx->len || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE)
return -1; return -1;
const char *L = (char *) list; const char *L = (char *) list;
@ -136,7 +136,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
} }
} }
if (string_is_empty(sub)) { if (!sub[0]) {
free(sub); free(sub);
return -1; return -1;
} }
@ -185,7 +185,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
return -1; return -1;
char tmpend[MAX_STR_SIZE]; char tmpend[MAX_STR_SIZE];
strcpy(tmpend, &ubuf[ctx->pos]); snprintf(tmpend, sizeof(tmpend), "%s", &ubuf[ctx->pos]);
strcpy(&ubuf[strt], match); strcpy(&ubuf[strt], match);
strcpy(&ubuf[strt + m_len], endchrs); strcpy(&ubuf[strt + m_len], endchrs);
strcpy(&ubuf[strt + m_len + n_endchrs], tmpend); strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
@ -193,7 +193,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
/* convert to widechar and copy back to original buf */ /* convert to widechar and copy back to original buf */
wchar_t newbuf[MAX_STR_SIZE]; wchar_t newbuf[MAX_STR_SIZE];
if (mbs_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1) if (mbs_to_wcs_buf(newbuf, ubuf, sizeof(newbuf) / sizeof(wchar_t)) == -1)
return -1; return -1;
wcscpy(ctx->line, newbuf); wcscpy(ctx->line, newbuf);
@ -218,7 +218,7 @@ static void complt_home_dir(ToxWindow *self, char *path, int pathsize, const cha
wchar_t wline[MAX_STR_SIZE]; wchar_t wline[MAX_STR_SIZE];
if (mbs_to_wcs_buf(wline, newline, sizeof(wline)) == -1) if (mbs_to_wcs_buf(wline, newline, sizeof(wline) / sizeof(wchar_t)) == -1)
return; return;
int newlen = wcslen(wline); int newlen = wcslen(wline);
@ -261,10 +261,10 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
} else if (!si && b_path[0] != '/') { /* look for matches in pwd */ } else if (!si && b_path[0] != '/') { /* look for matches in pwd */
char tmp[MAX_STR_SIZE]; char tmp[MAX_STR_SIZE];
snprintf(tmp, sizeof(tmp), ".%s", b_path); snprintf(tmp, sizeof(tmp), ".%s", b_path);
strcpy(b_path, tmp); snprintf(b_path, sizeof(b_path), "%s", tmp);
} }
strcpy(b_name, &b_path[si + 1]); snprintf(b_name, sizeof(b_name), "%s", &b_path[si + 1]);
b_path[si + 1] = '\0'; b_path[si + 1] = '\0';
int b_name_len = strlen(b_name); int b_name_len = strlen(b_name);
DIR *dp = opendir(b_path); DIR *dp = opendir(b_path);

View File

@ -541,7 +541,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
snprintf(file_path, sizeof(file_path), "%s", filename); snprintf(file_path, sizeof(file_path), "%s", filename);
} }
if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) { if (path_len >= sizeof(file_path) || path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); 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."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long.");
return; return;
@ -937,7 +937,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
int wlen = wcswidth(ctx->line, sizeof(ctx->line)); int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} }
} else { } else {
@ -1091,7 +1091,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
int y, x; int y, x;
getyx(self->window, y, x); getyx(self->window, y, x);
(void) x; (void) x;
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
wmove(self->window, y + 1, new_x); wmove(self->window, y + 1, new_x);
wrefresh(self->window); wrefresh(self->window);

View File

@ -234,12 +234,16 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
and the domain in dombuf. and the domain in dombuf.
return length of username on success, -1 on failure */ return length of username on success, -1 on failure */
static int parse_addr(const char *addr, char *namebuf, char *dombuf) static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
{ {
char tmpaddr[MAX_STR_SIZE]; if (strlen(addr) >= MAX_STR_SIZE)
char *tmpname, *tmpdom; return -1;
strcpy(tmpaddr, addr); char tmpaddr[MAX_STR_SIZE];
char *tmpname = NULL;
char *tmpdom = NULL;
snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
tmpname = strtok(tmpaddr, "@"); tmpname = strtok(tmpaddr, "@");
tmpdom = strtok(NULL, ""); tmpdom = strtok(NULL, "");
@ -247,8 +251,8 @@ static int parse_addr(const char *addr, char *namebuf, char *dombuf)
return -1; return -1;
str_to_lower(tmpdom); str_to_lower(tmpdom);
strcpy(namebuf, tmpname); snprintf(namebuf, namebuf_sz, "%s", tmpname);
strcpy(dombuf, tmpdom); snprintf(dombuf, dombuf_sz, "%s", tmpdom);
return strlen(namebuf); return strlen(namebuf);
} }
@ -295,7 +299,7 @@ void *dns3_lookup_thread(void *data)
char inputdomain[MAX_STR_SIZE]; char inputdomain[MAX_STR_SIZE];
char name[MAX_STR_SIZE]; char name[MAX_STR_SIZE];
int namelen = parse_addr(t_data.addr, name, inputdomain); int namelen = parse_addr(t_data.addr, name, sizeof(name), inputdomain, sizeof(inputdomain));
if (namelen == -1) { if (namelen == -1) {
dns_error(self, "Must be a Tox ID or an address in the form username@domain"); dns_error(self, "Must be a Tox ID or an address in the form username@domain");

View File

@ -285,7 +285,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C
tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL); tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL);
if (message && self) { if (message && self) {
if (self->active_box != -1) if (self->active_box != -1 && sound_type != silent)
box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message); box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message);
else else
box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message); box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message);

View File

@ -139,8 +139,10 @@ static int save_blocklist(char *path)
int count = 0; int count = 0;
for (i = 0; i < Blocked.max_idx; ++i) { for (i = 0; i < Blocked.max_idx; ++i) {
if (count > Blocked.num_blocked) if (count > Blocked.num_blocked) {
goto on_error; free(data);
return -1;
}
if (Blocked.list[i].active) { if (Blocked.list[i].active) {
BlockedFriend tmp; BlockedFriend tmp;
@ -161,19 +163,20 @@ static int save_blocklist(char *path)
FILE *fp = fopen(path, "wb"); FILE *fp = fopen(path, "wb");
if (fp == NULL) if (fp == NULL) {
goto on_error; free(data);
return -1;
}
if (fwrite(data, len, 1, fp) != 1) if (fwrite(data, len, 1, fp) != 1) {
goto on_error; fclose(fp);
free(data);
return -1;
}
fclose(fp); fclose(fp);
free(data); free(data);
return 0; return 0;
on_error:
free(data);
return -1;
} }
static void sort_blocklist_index(void); static void sort_blocklist_index(void);
@ -221,9 +224,10 @@ int load_blocklist(char *path)
int i; int i;
for (i = 0; i < num; ++i) { for (i = 0; i < num; ++i) {
BlockedFriend tmp;
memset(&tmp, 0, sizeof(BlockedFriend));
memset(&Blocked.list[i], 0, sizeof(BlockedFriend)); memset(&Blocked.list[i], 0, sizeof(BlockedFriend));
BlockedFriend tmp;
memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend)); memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend));
Blocked.list[i].active = true; Blocked.list[i].active = true;
Blocked.list[i].num = i; Blocked.list[i].num = i;

View File

@ -249,19 +249,22 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
const char *ip = argv[1]; const char *ip = argv[1];
const char *port = argv[2]; const char *port = argv[2];
const char *key = argv[3]; const char *ascii_key = argv[3];
if (atoi(port) == 0) { if (atoi(port) == 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port.");
return; return;
} }
char *binary_string = hex_string_to_bin(key); char key_binary[TOX_PUBLIC_KEY_SIZE * 2 + 1];
if (hex_string_to_bin(ascii_key, strlen(ascii_key), key_binary, TOX_PUBLIC_KEY_SIZE) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid key.");
return;
}
TOX_ERR_BOOTSTRAP err; TOX_ERR_BOOTSTRAP err;
tox_bootstrap(m, ip, atoi(port), (uint8_t *) binary_string, &err); tox_bootstrap(m, ip, atoi(port), (uint8_t *) key_binary, &err);
tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) binary_string, &err); tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) key_binary, &err);
free(binary_string);
switch (err) { switch (err) {
case TOX_ERR_BOOTSTRAP_BAD_HOST: case TOX_ERR_BOOTSTRAP_BAD_HOST:

View File

@ -593,7 +593,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
int wlen = wcswidth(ctx->line, sizeof(ctx->line)); int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} }
} else { } else {
@ -698,7 +698,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
int y, x; int y, x;
getyx(self->window, y, x); getyx(self->window, y, x);
(void) x; (void) x;
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
wmove(self->window, y + 1, new_x); wmove(self->window, y + 1, new_x);
wrefresh(self->window); wrefresh(self->window);
@ -795,66 +795,66 @@ static int group_audio_close_out_device(int groupnum)
return 0; return 0;
} }
static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels, // static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels,
unsigned int sample_rate) // unsigned int sample_rate)
{ // {
if (!pcm) // if (!pcm)
return -1; // return -1;
if (channels == 0 || channels > 2) // if (channels == 0 || channels > 2)
return -2; // return -2;
ALuint bufid; // ALuint bufid;
ALint processed = 0, queued = 0; // ALint processed = 0, queued = 0;
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed); // alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued); // alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued);
fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed); // fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed);
if (processed) { // if (processed) {
ALuint bufids[processed]; // ALuint bufids[processed];
alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids); // alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids);
alDeleteBuffers(processed - 1, bufids + 1); // alDeleteBuffers(processed - 1, bufids + 1);
bufid = bufids[0]; // bufid = bufids[0];
} else if (queued < 16) { // } else if (queued < 16) {
alGenBuffers(1, &bufid); // alGenBuffers(1, &bufid);
} else { // } else {
return -3; // return -3;
} // }
int length = samples * channels * sizeof(int16_t); // int length = samples * channels * sizeof(int16_t);
alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate); // alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate);
alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid); // alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid);
ALint state; // ALint state;
alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state); // alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) // if (state != AL_PLAYING)
alSourcePlay(groupchats[groupnum].audio.source); // alSourcePlay(groupchats[groupnum].audio.source);
return 0; // return 0;
} // }
static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm, static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm,
unsigned int samples, uint8_t channels, unsigned int sample_rate) unsigned int samples, uint8_t channels, unsigned int sample_rate)
{ {
return; return;
if (groupnum != self->num) // if (groupnum != self->num)
return; // return;
if (peernum < 0) // if (peernum < 0)
return; // return;
if (groupchats[groupnum].audio.dvhandle == NULL) // if (groupchats[groupnum].audio.dvhandle == NULL)
fprintf(stderr, "dvhandle is null)\n"); // fprintf(stderr, "dvhandle is null)\n");
if (groupchats[groupnum].audio.dvctx == NULL) // if (groupchats[groupnum].audio.dvctx == NULL)
fprintf(stderr, "ctx is null\n"); // fprintf(stderr, "ctx is null\n");
int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate); // int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate);
fprintf(stderr, "write: %d\n", ret); // fprintf(stderr, "write: %d\n", ret);
} }
#endif /* AUDIO */ #endif /* AUDIO */

View File

@ -125,7 +125,7 @@ static void input_yank(ToxWindow *self, int x, int mx_x)
if (x + yank_cols >= mx_x) { if (x + yank_cols >= mx_x) {
int rmdr = MAX(0, (x + yank_cols) - mx_x); int rmdr = MAX(0, (x + yank_cols) - mx_x);
int s_len = wcswidth(&ctx->line[ctx->start], rmdr); int s_len = MAX(0, wcswidth(&ctx->line[ctx->start], rmdr));
ctx->start += s_len + 1; ctx->start += s_len + 1;
} }
} }
@ -137,7 +137,7 @@ static void input_mv_end(ToxWindow *self, int y, int mx_x)
ctx->pos = ctx->len; ctx->pos = ctx->len;
int wlen = wcswidth(ctx->line, sizeof(ctx->line)); int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x)); ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x));
} }
@ -196,7 +196,7 @@ static void input_history(ToxWindow *self, wint_t key, int mx_x)
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
fetch_hist_item(ctx, key); fetch_hist_item(ctx, key);
int wlen = wcswidth(ctx->line, sizeof(ctx->line)); int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1; ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1;
} }

View File

@ -133,6 +133,9 @@ static struct line_info *line_info_ret_queue(struct history *hst)
void line_info_add(ToxWindow *self, const char *timestr, const char *name1, const char *name2, uint8_t type, void line_info_add(ToxWindow *self, const char *timestr, const char *name1, const char *name2, uint8_t type,
uint8_t bold, uint8_t colour, const char *msg, ...) uint8_t bold, uint8_t colour, const char *msg, ...)
{ {
if (!self)
return;
struct history *hst = self->chatwin->hst; struct history *hst = self->chatwin->hst;
if (hst->queue_sz >= MAX_LINE_INFO_QUEUE) if (hst->queue_sz >= MAX_LINE_INFO_QUEUE)

View File

@ -179,7 +179,7 @@ void load_chat_history(ToxWindow *self, struct chatlog *log)
if (sz <= 0) if (sz <= 0)
return; return;
char *hstbuf = malloc(sz); char *hstbuf = malloc(sz + 1);
if (hstbuf == NULL) if (hstbuf == NULL)
exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY); exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY);
@ -196,6 +196,8 @@ void load_chat_history(ToxWindow *self, struct chatlog *log)
return; return;
} }
hstbuf[sz] = '\0';
/* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */ /* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */
int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size); int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size);
int start, count = 0; int start, count = 0;

View File

@ -109,22 +109,27 @@ void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs)
snprintf(buf, bufsize, "%ld:%.2ld:%.2ld", hours, minutes, seconds); snprintf(buf, bufsize, "%ld:%.2ld:%.2ld", hours, minutes, seconds);
} }
char *hex_string_to_bin(const char *hex_string) /*
* Converts a hexidecimal string of length hex_len to binary format and puts the result in output.
* output_size must be exactly half of hex_len.
*
* Returns 0 on success.
* Returns -1 on failure.
*/
int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size)
{ {
size_t len = strlen(hex_string); if (output_size == 0 || hex_len != output_size * 2)
char *val = malloc(len); return -1;
if (val == NULL) for (size_t i = 0; i < output_size; ++i) {
exit_toxic_err("failed in hex_string_to_bin", FATALERR_MEMORY); sscanf(hex_string, "%2hhx", &output[i]);
hex_string += 2;
}
size_t i; return 0;
for (i = 0; i < len; ++i, hex_string += 2)
sscanf(hex_string, "%2hhx", &val[i]);
return val;
} }
int hex_string_to_bytes(char *buf, int size, const char *keystr) int hex_string_to_bytes(char *buf, int size, const char *keystr)
{ {
if (size % 2 != 0) if (size % 2 != 0)
@ -147,6 +152,9 @@ int hex_string_to_bytes(char *buf, int size, const char *keystr)
/* Returns 1 if the string is empty, 0 otherwise */ /* Returns 1 if the string is empty, 0 otherwise */
int string_is_empty(const char *string) int string_is_empty(const char *string)
{ {
if (!string)
return true;
return string[0] == '\0'; return string[0] == '\0';
} }

View File

@ -41,8 +41,14 @@
void hst_to_net(uint8_t *num, uint16_t numbytes); void hst_to_net(uint8_t *num, uint16_t numbytes);
/* convert a hex string to binary */ /*
char *hex_string_to_bin(const char *hex_string); * Converts a hexidecimal string of length hex_len to binary format and puts the result in output.
* output_size must be exactly half of hex_len.
*
* Returns 0 on success.
* Returns -1 on failure.
*/
int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size);
/* convert a hex string to bytes. returns 0 on success, -1 on failure */ /* convert a hex string to bytes. returns 0 on success, -1 on failure */
int hex_string_to_bytes(char *buf, int size, const char *keystr); int hex_string_to_bytes(char *buf, int size, const char *keystr);

View File

@ -90,7 +90,7 @@ struct _ActiveNotifications {
#ifdef BOX_NOTIFY #ifdef BOX_NOTIFY
NotifyNotification* box; NotifyNotification* box;
char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1]; char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1];
char title[24]; char title[64];
size_t size; size_t size;
time_t n_timeout; time_t n_timeout;
#endif #endif
@ -153,25 +153,26 @@ bool is_playing(int source)
static bool device_opened = false; static bool device_opened = false;
time_t last_opened_update = 0; time_t last_opened_update = 0;
bool m_open_device() /* Opens primary device. Returns true on succe*/
void m_open_device()
{ {
last_opened_update = get_unix_time(); last_opened_update = get_unix_time();
if (device_opened) return true; if (device_opened) return;
/* Blah error check */ /* Blah error check */
open_primary_device(output, &Control.device_idx, 48000, 20, 1); open_primary_device(output, &Control.device_idx, 48000, 20, 1);
return (device_opened = true); device_opened = true;
} }
bool m_close_device() void m_close_device()
{ {
if (!device_opened) return true; if (!device_opened) return;
close_device(output, Control.device_idx); close_device(output, Control.device_idx);
return !(device_opened = false); device_opened = false;
} }
/* Terminate all sounds but wait for them to finish first */ /* Terminate all sounds but wait for them to finish first */
@ -598,9 +599,12 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi
actives[id].id_indicator = id_indicator; actives[id].id_indicator = id_indicator;
if (id_indicator) *id_indicator = id; if (id_indicator) *id_indicator = id;
} }
#endif #else
if (id == -1)
return -1;
#endif /* SOUND_NOTIFY */
strncpy(actives[id].title, title, 24); snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
if (strlen(title) > 23) strcpy(actives[id].title + 20, "..."); if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
va_list __ARGS__; va_start (__ARGS__, format); va_list __ARGS__; va_start (__ARGS__, format);
@ -699,7 +703,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const
*id_indicator = id; *id_indicator = id;
} }
strncpy(actives[id].title, title, 24); snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
if (strlen(title) > 23) strcpy(actives[id].title + 20, "..."); if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
va_list __ARGS__; va_start (__ARGS__, format); va_list __ARGS__; va_start (__ARGS__, format);

View File

@ -212,7 +212,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
int wlen = wcswidth(ctx->line, sizeof(ctx->line)); int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} }
} else { } else {
@ -330,7 +330,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
getyx(self->window, y, x); getyx(self->window, y, x);
(void) x; (void) x;
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
wmove(self->window, y + 1, new_x); wmove(self->window, y + 1, new_x);
wrefresh(self->window); wrefresh(self->window);

View File

@ -41,6 +41,7 @@ typedef struct {
} FriendRequests; } FriendRequests;
ToxWindow new_prompt(void); ToxWindow new_prompt(void);
void prep_prompt_win(void); void prep_prompt_win(void);
void prompt_init_statusbar(ToxWindow *self, Tox *m); void prompt_init_statusbar(ToxWindow *self, Tox *m);
void prompt_update_nick(ToxWindow *prompt, const char *nick); void prompt_update_nick(ToxWindow *prompt, const char *nick);

View File

@ -167,6 +167,10 @@ static int detect_gnu_screen ()
free (dyn_buffer); free (dyn_buffer);
dyn_buffer = NULL; dyn_buffer = NULL;
if (strlen(socket_path) + strlen(PATH_SEP_S) + strlen(socket_name) >= sizeof(mplex_data))
goto nomplex;
strcpy (mplex_data, socket_path); strcpy (mplex_data, socket_path);
strcat (mplex_data, PATH_SEP_S); strcat (mplex_data, PATH_SEP_S);
strcat (mplex_data, socket_name); strcat (mplex_data, socket_name);
@ -181,6 +185,8 @@ nomplex:
pclose (session_info_stream); pclose (session_info_stream);
if (dyn_buffer) if (dyn_buffer)
free (dyn_buffer); free (dyn_buffer);
if (socket_path)
free(socket_path);
return 0; return 0;
} }
@ -196,7 +202,7 @@ static int detect_tmux ()
return 0; return 0;
/* store the session number string for later use */ /* store the session number string for later use */
strcpy (mplex_data, pos + 1); snprintf (mplex_data, sizeof(mplex_data), "%s", pos + 1);
mplex = MPLEX_TMUX; mplex = MPLEX_TMUX;
return 1; return 1;
} }

View File

@ -77,6 +77,9 @@ char *DATA_FILE = NULL;
char *BLOCK_FILE = NULL; char *BLOCK_FILE = NULL;
ToxWindow *prompt = NULL; ToxWindow *prompt = NULL;
#define DATANAME "data"
#define BLOCKNAME "data-blocklist"
#define AUTOSAVE_FREQ 60 #define AUTOSAVE_FREQ 60
#define MIN_PASSWORD_LEN 6 #define MIN_PASSWORD_LEN 6
#define MAX_PASSWORD_LEN 64 #define MAX_PASSWORD_LEN 64
@ -119,6 +122,24 @@ static void init_signal_catchers(void)
signal(SIGSEGV, catch_SIGSEGV); signal(SIGSEGV, catch_SIGSEGV);
} }
void free_global_data(void)
{
if (DATA_FILE) {
free(DATA_FILE);
DATA_FILE = NULL;
}
if (BLOCK_FILE) {
free(BLOCK_FILE);
BLOCK_FILE = NULL;
}
if (user_settings) {
free(user_settings);
user_settings = NULL;
}
}
void exit_toxic_success(Tox *m) void exit_toxic_success(Tox *m)
{ {
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
@ -131,10 +152,7 @@ void exit_toxic_success(Tox *m)
terminate_audio(); terminate_audio();
#endif /* AUDIO */ #endif /* AUDIO */
free(DATA_FILE); free_global_data();
free(BLOCK_FILE);
free(user_settings);
tox_kill(m); tox_kill(m);
endwin(); endwin();
@ -150,6 +168,7 @@ void exit_toxic_success(Tox *m)
void exit_toxic_err(const char *errmsg, int errcode) void exit_toxic_err(const char *errmsg, int errcode)
{ {
free_global_data();
freopen("/dev/tty", "w", stderr); freopen("/dev/tty", "w", stderr);
endwin(); endwin();
fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg); fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg);
@ -289,9 +308,11 @@ static int load_nodelist(const char *filename)
toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0; toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0;
toxNodes.ports[toxNodes.lines] = atoi(port); toxNodes.ports[toxNodes.lines] = atoi(port);
char *key_binary = hex_string_to_bin(key_ascii); char key_binary[TOX_PUBLIC_KEY_SIZE + 2 + 1];
if (hex_string_to_bin(key_ascii, strlen(key_ascii), key_binary, TOX_PUBLIC_KEY_SIZE) == -1)
continue;
memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE); memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE);
free(key_binary);
toxNodes.lines++; toxNodes.lines++;
} }
@ -933,10 +954,22 @@ static void parse_args(int argc, char *argv[])
case 'f': case 'f':
arg_opts.use_custom_data = 1; arg_opts.use_custom_data = 1;
DATA_FILE = strdup(optarg);
if (DATA_FILE)
free(DATA_FILE);
if (BLOCK_FILE)
free(BLOCK_FILE);
DATA_FILE = malloc(strlen(optarg) + 1);
strcpy(DATA_FILE, optarg);
if (DATA_FILE == NULL)
exit_toxic_err("failed in parse_args", FATALERR_MEMORY);
BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1); BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1);
if (DATA_FILE == NULL || BLOCK_FILE == NULL) if (BLOCK_FILE == NULL)
exit_toxic_err("failed in parse_args", FATALERR_MEMORY); exit_toxic_err("failed in parse_args", FATALERR_MEMORY);
strcpy(BLOCK_FILE, optarg); strcpy(BLOCK_FILE, optarg);
@ -1007,8 +1040,6 @@ static void parse_args(int argc, char *argv[])
} }
} }
#define DATANAME "data"
#define BLOCKNAME "data-blocklist"
static int init_default_data_files(void) static int init_default_data_files(void)
{ {
if (arg_opts.use_custom_data) if (arg_opts.use_custom_data)

View File

@ -568,7 +568,7 @@ ToxWindow *get_window_ptr(int i)
{ {
ToxWindow *toxwin = NULL; ToxWindow *toxwin = NULL;
if (i >= 0 && i <= MAX_WINDOWS_NUM && windows[i].active) if (i >= 0 && i < MAX_WINDOWS_NUM && windows[i].active)
toxwin = &windows[i]; toxwin = &windows[i];
return toxwin; return toxwin;
@ -595,7 +595,7 @@ void kill_all_windows(Tox *m)
if (windows[i].is_chat) if (windows[i].is_chat)
kill_chat_window(&windows[i], m); kill_chat_window(&windows[i], m);
else if (windows[i].is_groupchat) else if (windows[i].is_groupchat)
close_groupchat(&windows[i], m, i); close_groupchat(&windows[i], m, windows[i].num);
} }
kill_prompt_window(prompt); kill_prompt_window(prompt);

View File

@ -72,24 +72,24 @@ Property read_property(Window s, Atom p)
unsigned long read_num; unsigned long read_num;
unsigned long left_bytes; unsigned long left_bytes;
unsigned char *data = NULL; unsigned char *data = NULL;
int read_bytes = 1024; int read_bytes = 1024;
/* Keep trying to read the property until there are no bytes unread */ /* Keep trying to read the property until there are no bytes unread */
do { do {
if (data) XFree(data); if (data) XFree(data);
XGetWindowProperty(Xtra.display, s, XGetWindowProperty(Xtra.display, s,
p, 0, p, 0,
read_bytes, read_bytes,
False, AnyPropertyType, False, AnyPropertyType,
&read_type, &read_format, &read_type, &read_format,
&read_num, &left_bytes, &read_num, &left_bytes,
&data); &data);
read_bytes *= 2; read_bytes *= 2;
} while (left_bytes != 0); } while (left_bytes != 0);
Property property = {data, read_format, read_num, read_type}; Property property = {data, read_format, read_num, read_type};
return property; return property;
} }
@ -107,7 +107,7 @@ Atom get_dnd_type(long *a, int l)
static void handle_xdnd_enter(XClientMessageEvent* e) static void handle_xdnd_enter(XClientMessageEvent* e)
{ {
Xtra.handling_version = (e->data.l[1] >> 24); Xtra.handling_version = (e->data.l[1] >> 24);
if ((e->data.l[1] & 1)) { if ((e->data.l[1] & 1)) {
// Fetch the list of possible conversions // Fetch the list of possible conversions
Property p = read_property(e->data.l[0], XdndTypeList); Property p = read_property(e->data.l[0], XdndTypeList);
@ -120,7 +120,7 @@ static void handle_xdnd_enter(XClientMessageEvent* e)
} }
static void handle_xdnd_position(XClientMessageEvent* e) static void handle_xdnd_position(XClientMessageEvent* e)
{ {
XEvent ev = { XEvent ev = {
.xclient = { .xclient = {
.type = ClientMessage, .type = ClientMessage,
@ -130,15 +130,15 @@ static void handle_xdnd_position(XClientMessageEvent* e)
.format = 32, .format = 32,
.data = { .data = {
.l = { .l = {
Xtra.proxy_window, Xtra.proxy_window,
(Xtra.expecting_type != XtraNil), (Xtra.expecting_type != XtraNil),
0, 0, 0, 0,
XdndActionCopy XdndActionCopy
} }
} }
} }
}; };
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev); XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
XFlush(Xtra.display); XFlush(Xtra.display);
} }
@ -159,7 +159,7 @@ static void handle_xdnd_drop(XClientMessageEvent* e)
} }
} }
}; };
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev); XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
} else { } else {
Xtra.source_window = e->data.l[0]; Xtra.source_window = e->data.l[0];
@ -188,57 +188,57 @@ static void handle_xdnd_selection(XSelectionEvent* e)
} }
}; };
XSendEvent(Xtra.display, Xtra.source_window, False, NoEventMask, &ev); XSendEvent(Xtra.display, Xtra.source_window, False, NoEventMask, &ev);
Property p = read_property(Xtra.proxy_window, XdndSelection); Property p = read_property(Xtra.proxy_window, XdndSelection);
DropType dt; DropType dt;
if (strcmp(XGetAtomName(Xtra.display, p.read_type), "text/uri-list") == 0) if (strcmp(XGetAtomName(Xtra.display, p.read_type), "text/uri-list") == 0)
dt = DT_file_list; dt = DT_file_list;
else /* text/uri-list */ else /* text/uri-list */
dt = DT_plain; dt = DT_plain;
/* Call callback for every entry */ /* Call callback for every entry */
if (Xtra.on_drop && p.read_num) if (Xtra.on_drop && p.read_num)
{ {
char *sptr; char *sptr;
char *str = strtok_r((char *) p.data, "\n\r", &sptr); char *str = strtok_r((char *) p.data, "\n\r", &sptr);
if (str) Xtra.on_drop(str, dt); if (str) Xtra.on_drop(str, dt);
while ((str = strtok_r(NULL, "\n\r", &sptr))) while ((str = strtok_r(NULL, "\n\r", &sptr)))
Xtra.on_drop(str, dt); Xtra.on_drop(str, dt);
} }
if (p.data) XFree(p.data); if (p.data) XFree(p.data);
} }
void *event_loop(void* p) void *event_loop(void* p)
{ {
/* Handle events like a real nigga */ /* Handle events like a real nigga */
(void) p; /* DINDUNOTHIN */ (void) p; /* DINDUNOTHIN */
XEvent event; XEvent event;
int pending; int pending;
while (Xtra.display) while (Xtra.display)
{ {
/* NEEDMOEVENTSFODEMPROGRAMS */ /* NEEDMOEVENTSFODEMPROGRAMS */
XLockDisplay(Xtra.display); XLockDisplay(Xtra.display);
if((pending = XPending(Xtra.display))) XNextEvent(Xtra.display, &event); if((pending = XPending(Xtra.display))) XNextEvent(Xtra.display, &event);
if (!pending) if (!pending)
{ {
XUnlockDisplay(Xtra.display); XUnlockDisplay(Xtra.display);
usleep(10000); usleep(10000);
continue; continue;
} }
if (event.type == ClientMessage) if (event.type == ClientMessage)
{ {
Atom type = event.xclient.message_type; Atom type = event.xclient.message_type;
if (type == XdndEnter) handle_xdnd_enter(&event.xclient); if (type == XdndEnter) handle_xdnd_enter(&event.xclient);
else if (type == XdndPosition) handle_xdnd_position(&event.xclient); else if (type == XdndPosition) handle_xdnd_position(&event.xclient);
else if (type == XdndDrop) handle_xdnd_drop(&event.xclient); else if (type == XdndDrop) handle_xdnd_drop(&event.xclient);
@ -247,11 +247,11 @@ void *event_loop(void* p)
else if (event.type == SelectionNotify) handle_xdnd_selection(&event.xselection); else if (event.type == SelectionNotify) handle_xdnd_selection(&event.xselection);
/* AINNOBODYCANHANDLEDEMEVENTS*/ /* AINNOBODYCANHANDLEDEMEVENTS*/
else XSendEvent(Xtra.display, Xtra.terminal_window, 0, 0, &event); else XSendEvent(Xtra.display, Xtra.terminal_window, 0, 0, &event);
XUnlockDisplay(Xtra.display); XUnlockDisplay(Xtra.display);
} }
/* Actual XTRA termination /* Actual XTRA termination
* Please call xtra_terminate() at exit * Please call xtra_terminate() at exit
* otherwise HEWUSAGUDBOI happens * otherwise HEWUSAGUDBOI happens
*/ */
@ -262,23 +262,23 @@ void *event_loop(void* p)
int init_xtra(drop_callback d) int init_xtra(drop_callback d)
{ {
memset(&Xtra, 0, sizeof(Xtra)); memset(&Xtra, 0, sizeof(Xtra));
if (!d) return -1; if (!d) return -1;
else Xtra.on_drop = d; else Xtra.on_drop = d;
XInitThreads(); XInitThreads();
if ( !(Xtra.display = XOpenDisplay(NULL))) return -1; if ( !(Xtra.display = XOpenDisplay(NULL))) return -1;
Xtra.terminal_window = focused_window_id(); Xtra.terminal_window = focused_window_id();
{ {
/* Create an invisible window which will act as proxy for the DnD operation. */ /* Create an invisible window which will act as proxy for the DnD operation. */
XSetWindowAttributes attr = {0}; XSetWindowAttributes attr = {0};
attr.event_mask = EnterWindowMask | attr.event_mask = EnterWindowMask |
LeaveWindowMask | LeaveWindowMask |
ButtonMotionMask | ButtonMotionMask |
ButtonPressMask | ButtonPressMask |
ButtonReleaseMask | ButtonReleaseMask |
ResizeRedirectMask; ResizeRedirectMask;
attr.do_not_propagate_mask = NoEventMask; attr.do_not_propagate_mask = NoEventMask;
@ -286,14 +286,14 @@ int init_xtra(drop_callback d)
Window root; Window root;
int x, y; int x, y;
unsigned int wht, hht, b, d; unsigned int wht, hht, b, d;
/* Since we cannot capture resize events for parent window we will have to create /* Since we cannot capture resize events for parent window we will have to create
* this window to have maximum size as defined in root window * this window to have maximum size as defined in root window
*/ */
XGetGeometry(Xtra.display, XGetGeometry(Xtra.display,
XDefaultRootWindow(Xtra.display), XDefaultRootWindow(Xtra.display),
&root, &x, &y, &wht, &hht, &b, &d); &root, &x, &y, &wht, &hht, &b, &d);
if (! (Xtra.proxy_window = XCreateWindow if (! (Xtra.proxy_window = XCreateWindow
(Xtra.display, Xtra.terminal_window, /* Parent */ (Xtra.display, Xtra.terminal_window, /* Parent */
0, 0, /* Position */ 0, 0, /* Position */
@ -306,7 +306,7 @@ int init_xtra(drop_callback d)
&attr)) ) /* Attributes for value mask */ &attr)) ) /* Attributes for value mask */
return -1; return -1;
} }
XMapWindow(Xtra.display, Xtra.proxy_window); /* Show window (sandwich) */ XMapWindow(Xtra.display, Xtra.proxy_window); /* Show window (sandwich) */
XLowerWindow(Xtra.display, Xtra.proxy_window); /* Don't interfere with parent lmao */ XLowerWindow(Xtra.display, Xtra.proxy_window); /* Don't interfere with parent lmao */
@ -321,7 +321,7 @@ int init_xtra(drop_callback d)
XdndTypeList = XInternAtom(Xtra.display, "XdndTypeList", False); XdndTypeList = XInternAtom(Xtra.display, "XdndTypeList", False);
XdndActionCopy = XInternAtom(Xtra.display, "XdndActionCopy", False); XdndActionCopy = XInternAtom(Xtra.display, "XdndActionCopy", False);
XdndFinished = XInternAtom(Xtra.display, "XdndFinished", False); XdndFinished = XInternAtom(Xtra.display, "XdndFinished", False);
/* Inform my nigga windows that we are aware of dnd */ /* Inform my nigga windows that we are aware of dnd */
Atom XdndVersion = 3; Atom XdndVersion = 3;
XChangeProperty(Xtra.display, XChangeProperty(Xtra.display,
@ -331,18 +331,20 @@ int init_xtra(drop_callback d)
32, 32,
PropModeReplace, PropModeReplace,
(unsigned char*)&XdndVersion, 1); (unsigned char*)&XdndVersion, 1);
pthread_t id; pthread_t id;
pthread_create(&id, NULL, event_loop, NULL); if (pthread_create(&id, NULL, event_loop, NULL) != 0)
return -1;
pthread_detach(id); pthread_detach(id);
return 0; return 0;
} }
void terminate_xtra() void terminate_xtra()
{ {
if (!Xtra.display) return; if (!Xtra.display) return;
XEvent terminate = { XEvent terminate = {
.xclient = { .xclient = {
.type = ClientMessage, .type = ClientMessage,
@ -350,19 +352,19 @@ void terminate_xtra()
.message_type = XtraTerminate, .message_type = XtraTerminate,
} }
}; };
XLockDisplay(Xtra.display); XLockDisplay(Xtra.display);
XDeleteProperty(Xtra.display, Xtra.proxy_window, XdndAware); XDeleteProperty(Xtra.display, Xtra.proxy_window, XdndAware);
XSendEvent(Xtra.display, Xtra.proxy_window, 0, NoEventMask, &terminate); XSendEvent(Xtra.display, Xtra.proxy_window, 0, NoEventMask, &terminate);
XUnlockDisplay(Xtra.display); XUnlockDisplay(Xtra.display);
while (Xtra.display); /* Wait for termination */ while (Xtra.display); /* Wait for termination */
} }
long unsigned int focused_window_id() long unsigned int focused_window_id()
{ {
if (!Xtra.display) return 0; if (!Xtra.display) return 0;
Window focus; Window focus;
int revert; int revert;
XLockDisplay(Xtra.display); XLockDisplay(Xtra.display);