Various changes to nTox including a potential crash (also possible from remote!), and a tiny change to toxcore.

Crash stuff:

nTox.c:
- do_refresh(): avoid crashes (input a "%" and the client goes "boom!", send someone a string with embedded "%" and see him blow up...)

Other stuff:

toxcore: tox.h (doc.)/network.c (code):
- networking_wait_prepare(): return -1 if lenptr was NULL and therefore not settable

nTox.c:
- fraddr_to_str(): function to convert a TOX_FRIEND_ADDRESS into a segmented (and therefore line-breakable) string
- print_friendlist(): print index of friend on name line, print id on 2nd line
- command /f: skip spaces (and +) inside a friend id
- command /r (new): "/r #" to remove a friend
- main(): reduce cpu consumption if we're not currently sending files
This commit is contained in:
Coren[m] 2013-11-27 20:59:00 +01:00
parent 3fe7e08791
commit 26fef7cf9a
No known key found for this signature in database
GPG Key ID: AFA6943800F5DC6D
3 changed files with 126 additions and 30 deletions

View File

@ -64,7 +64,7 @@ const char wrap_cont_str[] = "\n+ ";
/* documented: fdmnlsahxgiztq(c[rfg]) */ /* documented: fdmnlsahxgiztq(c[rfg]) */
/* undocumented: d (tox_do()) */ /* undocumented: d (tox_do()) */
/* 249 characters */ /* 251+1 characters */
char *help_main = char *help_main =
"[i] Available main commands:\n+ " "[i] Available main commands:\n+ "
"/x (to print one's own id)|" "/x (to print one's own id)|"
@ -75,21 +75,22 @@ char *help_main =
"/h friend (for friend related commands)|" "/h friend (for friend related commands)|"
"/h group (for group related commands)"; "/h group (for group related commands)";
/* 141 characters */ /* 190+1 characters */
char *help_friend1 = char *help_friend1 =
"[i] Available friend commands (1/2):\n+ " "[i] Available friend commands (1/2):\n+ "
"/l list (to list friends)|" "/l list (to list friends)|"
"/r friend no. (to remove from the friend list)|"
"/f ID (to send a friend request)|" "/f ID (to send a friend request)|"
"/a request no. (to accept a friend request)"; "/a request no. (to accept a friend request)";
/* 184 characters */ /* 187+1 characters */
char *help_friend2 = char *help_friend2 =
"[i] Available friend commands (2/2):\n+ " "[i] Available friend commands (2/2):\n+ "
"/m friend no. message (to send a message)|" "/m friend no. message (to send a message)|"
"/t friend no. filename (to send a file to a friend)|" "/t friend no. filename (to send a file to a friend)|"
"/cf friend no. (to talk to that friend per default)"; "/cf friend no. (to talk to that friend per default)";
/* 216 characters */ /* 253+1 characters */
char *help_group = char *help_group =
"[i] Available group commands:\n+ " "[i] Available group commands:\n+ "
"/g (to create a group)|" "/g (to create a group)|"
@ -236,18 +237,41 @@ uint32_t resolve_addr(const char *address)
return addr; return addr;
} }
#define FRADDR_TOSTR_CHUNK_LEN 8
#define FRADDR_TOSTR_BUFSIZE (TOX_FRIEND_ADDRESS_SIZE * 2 + TOX_FRIEND_ADDRESS_SIZE / FRADDR_TOSTR_CHUNK_LEN + 1)
static void fraddr_to_str(uint8_t *id_bin, char *id_str)
{
uint i, delta = 0, pos_extra, sum_extra = 0;
for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
sprintf(&id_str[2 * i + delta], "%02hhX", id_bin[i]);
if ((i + 1) == TOX_CLIENT_ID_SIZE)
pos_extra = 2 * (i + 1) + delta;
if (i >= TOX_CLIENT_ID_SIZE)
sum_extra |= id_bin[i];
if (!((i + 1) % FRADDR_TOSTR_CHUNK_LEN)) {
id_str[2 * (i + 1) + delta] = ' ';
delta++;
}
}
id_str[2 * i + delta] = 0;
if (!sum_extra)
id_str[pos_extra] = 0;
}
void get_id(Tox *m, char *data) void get_id(Tox *m, char *data)
{ {
sprintf(data, "[i] ID: "); sprintf(data, "[i] ID: ");
int offset = strlen(data); int offset = strlen(data);
uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
tox_getaddress(m, address); tox_getaddress(m, address);
fraddr_to_str(address, data + offset);
uint32_t i = 0;
for (; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
sprintf(data + 2 * i + offset, "%02X ", address[i]);
}
} }
int getfriendname_terminated(Tox *m, int friendnum, char *namebuf) int getfriendname_terminated(Tox *m, int friendnum, char *namebuf)
@ -283,21 +307,31 @@ void new_lines(char *line)
} }
const char ptrn_friend[] = "[i] Friend: %s\n+ id: %i"; const char ptrn_friend[] = "[i] Friend %i: %s\n+ id: %s";
const int id_str_len = TOX_FRIEND_ADDRESS_SIZE * 2 + 3;
void print_friendlist(Tox *m) void print_friendlist(Tox *m)
{ {
char name[TOX_MAX_NAME_LENGTH + 1];
int i = 0;
new_lines("[i] Friend List:"); new_lines("[i] Friend List:");
char name[TOX_MAX_NAME_LENGTH + 1];
uint8_t fraddr_bin[TOX_FRIEND_ADDRESS_SIZE];
char fraddr_str[FRADDR_TOSTR_BUFSIZE];
/* account for the longest name and the longest "base" string and number (int) and id_str */
char fstring[TOX_MAX_NAME_LENGTH + strlen(ptrn_friend) + 21 + id_str_len];
uint i = 0;
while (getfriendname_terminated(m, i, name) != -1) { while (getfriendname_terminated(m, i, name) != -1) {
/* account for the longest name and the longest "base" string and number (int) */ if (!tox_getclient_id(m, i, fraddr_bin))
char fstring[TOX_MAX_NAME_LENGTH + strlen(ptrn_friend) + 21]; fraddr_to_str(fraddr_bin, fraddr_str);
else
sprintf(fraddr_str, "???");
if (strlen(name) <= 0) { if (strlen(name) <= 0) {
sprintf(fstring, ptrn_friend, "No name?", i); sprintf(fstring, ptrn_friend, i, "No name?", fraddr_str);
} else { } else {
sprintf(fstring, ptrn_friend, (uint8_t *)name, i); sprintf(fstring, ptrn_friend, i, (uint8_t *)name, fraddr_str);
} }
i++; i++;
@ -361,11 +395,15 @@ void line_eval(Tox *m, char *line)
new_lines(prompt); new_lines(prompt);
if (inpt_command == 'f') { // add friend command: /f ID if (inpt_command == 'f') { // add friend command: /f ID
int i; int i, delta = 0;
char temp_id[128]; char temp_id[128];
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++) {
temp_id[i] = line[i + prompt_offset]; temp_id[i - delta] = line[i + prompt_offset];
if ((temp_id[i - delta] == ' ') || (temp_id[i - delta] == '+'))
delta++;
}
unsigned char *bin_string = hex_string_to_bin(temp_id); unsigned char *bin_string = hex_string_to_bin(temp_id);
int num = tox_addfriend(m, bin_string, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); int num = tox_addfriend(m, bin_string, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
@ -452,7 +490,7 @@ void line_eval(Tox *m, char *line)
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] changed status to %s", (char *)status); sprintf(numstring, "[i] changed status to %s", (char *)status);
new_lines(numstring); new_lines(numstring);
} else if (inpt_command == 'a') { } else if (inpt_command == 'a') { // /a #: accept
uint8_t numf = atoi(line + 3); uint8_t numf = atoi(line + 3);
char numchar[100]; char numchar[100];
@ -472,6 +510,39 @@ void line_eval(Tox *m, char *line)
new_lines(numchar); new_lines(numchar);
} }
} }
} else if (inpt_command == 'r') { // /r #: remove friend
uint8_t numf = atoi(line + 3);
if (!tox_friend_exists(m, numf)) {
char err[64];
sprintf(err, "You don't have a friend %i.", numf);
new_lines(err);
return;
}
char msg[128 + TOX_MAX_NAME_LENGTH];
char fname[TOX_MAX_NAME_LENGTH ];
getfriendname_terminated(m, numf, fname);
sprintf(msg, "Are you sure you want to delete friend %i: %s? (y/n)", numf, fname);
input_line[0] = 0;
new_lines(msg);
int c;
do {
c = getchar();
} while ((c != 'y') && (c != 'n') && (c != EOF));
if (c == 'y') {
int res = tox_delfriend(m, numf);
if (res == 0)
sprintf(msg, "[i] [%i: %s] is no longer your friend", numf, fname);
else
sprintf(msg, "[i] failed to remove friend");
new_lines(msg);
}
} else if (inpt_command == 'h') { //help } else if (inpt_command == 'h') { //help
if (line[2] == ' ') { if (line[2] == ' ') {
if (line[3] == 'f') { if (line[3] == 'f') {
@ -838,7 +909,7 @@ void do_refresh()
if (count < y) { if (count < y) {
move(y - 1 - count, 0); move(y - 1 - count, 0);
printw(wrap_output); printw("%s", wrap_output);
clrtoeol(); clrtoeol();
} }
} }
@ -846,7 +917,7 @@ void do_refresh()
move(y - 1, 0); move(y - 1, 0);
clrtoeol(); clrtoeol();
printw(">> "); printw(">> ");
printw(input_line); printw("%s", input_line);
clrtoeol(); clrtoeol();
refresh(); refresh();
} }
@ -1243,6 +1314,16 @@ int main(int argc, char *argv[])
time_t timestamp0 = time(NULL); time_t timestamp0 = time(NULL);
uint8_t pollok = 0;
uint16_t len = 0;
if (!tox_wait_prepare(m, NULL, &len))
pollok = 1;
else
new_lines("[i] failed to setup for low cpu consumption");
uint8_t data[len];
while (1) { while (1) {
if (on == 0) { if (on == 0) {
if (tox_isconnected(m)) { if (tox_isconnected(m)) {
@ -1258,9 +1339,20 @@ int main(int argc, char *argv[])
} }
} }
if (numfilesenders > 0)
// during file transfer wasting cpu cycles is almost unavoidable
c_sleep(1);
else {
if (pollok && (tox_wait_prepare(m, data, &len) == 1)) {
/* 250ms is more than fast enough in "regular" mode */
tox_wait_execute(m, data, len, 100);
tox_wait_cleanup(m, data, len);
} else
c_sleep(25);
}
send_filesenders(m); send_filesenders(m);
tox_do(m); tox_do(m);
c_sleep(1);
do_refresh(); do_refresh();
c = getch(); c = getch();

View File

@ -310,9 +310,12 @@ typedef struct {
int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr) int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr)
{ {
if ((data == NULL) || (*lenptr < sizeof(select_info))) { if ((data == NULL) || !lenptr || (*lenptr < sizeof(select_info))) {
*lenptr = sizeof(select_info); if (lenptr) {
return 0; *lenptr = sizeof(select_info);
return 0;
} else
return -1;
} }
*lenptr = sizeof(select_info); *lenptr = sizeof(select_info);

View File

@ -606,10 +606,11 @@ void tox_do(Tox *tox);
* Prepares the data required to call tox_wait_execute() asynchronously * Prepares the data required to call tox_wait_execute() asynchronously
* *
* data[] is reserved and kept by the caller * data[] is reserved and kept by the caller
* len is in/out: in = reserved data[], out = required data[] * *lenptr is in/out: in = reserved data[], out = required data[]
* *
* returns 1 on success * returns 1 on success
* returns 0 on failure (length is insufficient) * returns 0 if *lenptr is insufficient
* returns -1 if lenptr is NULL
* *
* *
* tox_wait_execute(): function can be called asynchronously * tox_wait_execute(): function can be called asynchronously