New API cleanup.

This commit is contained in:
Håvard Pettersson 2015-04-10 00:08:40 +02:00
parent cacd200a5c
commit ed96d36711
7 changed files with 219 additions and 171 deletions

View File

@ -60,42 +60,6 @@ twc_profile_expanded_data_path(struct t_twc_profile *profile)
return full_path; return full_path;
} }
/**
* Try loading a Tox save file for a profile.
*
* Returns 0 on success, -1 on failure.
*
* TODO: support encrypted save files
*/
int
twc_profile_load_data(struct t_twc_profile *profile)
{
char *full_path = twc_profile_expanded_data_path(profile);
FILE *file = fopen(full_path, "r");
free(full_path);
if (file)
{
// get file size
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
// allocate a buffer and read file into it
uint8_t *data = malloc(sizeof(*data) * size);
fread(data, sizeof(uint8_t), size, file);
fclose(file);
// try loading the data
int status = tox_load(profile->tox, data, size);
free(data);
return status;
}
return -1;
}
/** /**
* Save a profile's Tox data to disk. * Save a profile's Tox data to disk.
* *
@ -118,9 +82,9 @@ twc_profile_save_data_file(struct t_twc_profile *profile)
free(dir_path); free(dir_path);
// save Tox data to a buffer // save Tox data to a buffer
uint32_t size = tox_size(profile->tox); uint32_t size = tox_get_savedata_size(profile->tox);
uint8_t *data = malloc(size); uint8_t *data = malloc(size);
tox_save(profile->tox, data); tox_get_savedata(profile->tox, data);
// save buffer to a file // save buffer to a file
FILE *file = fopen(full_path, "w"); FILE *file = fopen(full_path, "w");
@ -191,15 +155,107 @@ twc_profile_new(const char *name)
return profile; return profile;
} }
/**
* Load Tox options from WeeChat configuration files into a Tox_Options struct.
*/
void
twc_profile_set_options(struct Tox_Options *options,
struct t_twc_profile *profile)
{
tox_options_default(options);
const char *proxy_host =
TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_PROXY_ADDRESS);
if (proxy_host)
options->proxy_host = proxy_host;
switch (TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_TYPE))
{
case TWC_PROXY_NONE:
options->proxy_type = TOX_PROXY_TYPE_NONE;
break;
case TWC_PROXY_SOCKS5:
options->proxy_type = TOX_PROXY_TYPE_SOCKS5;
break;
case TWC_PROXY_HTTP:
options->proxy_type = TOX_PROXY_TYPE_HTTP;
break;
}
options->proxy_port =
TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_PORT);
options->udp_enabled =
TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_UDP);
options->ipv6_enabled =
TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_IPV6);
}
void
twc_tox_new_print_error(struct t_twc_profile *profile,
struct Tox_Options *options,
TOX_ERR_NEW error)
{
switch (error)
{
case TOX_ERR_NEW_MALLOC:
weechat_printf(profile->buffer,
"%scould not load Tox (malloc error)",
weechat_prefix("error"));
break;
case TOX_ERR_NEW_PORT_ALLOC:
weechat_printf(profile->buffer,
"%scould not load Tox (failed to allocate a port)",
weechat_prefix("error"));
break;
case TOX_ERR_NEW_PROXY_BAD_TYPE:
weechat_printf(profile->buffer,
"%scould not load Tox (internal error; bad proxy type)",
weechat_prefix("error"));
break;
case TOX_ERR_NEW_PROXY_BAD_HOST:
weechat_printf(profile->buffer,
"%scould not load Tox (invalid proxy host: \"%s\")",
weechat_prefix("error"), options->proxy_host);
break;
case TOX_ERR_NEW_PROXY_BAD_PORT:
weechat_printf(profile->buffer,
"%scould not load Tox (invalid proxy port: \"%d\")",
weechat_prefix("error"), options->proxy_port);
break;
case TOX_ERR_NEW_PROXY_NOT_FOUND:
weechat_printf(profile->buffer,
"%scould not load Tox (proxy host not found: \"%s\")",
weechat_prefix("error"), options->proxy_host);
break;
case TOX_ERR_NEW_LOAD_ENCRYPTED:
weechat_printf(profile->buffer,
"%scould not load Tox (encrypted data files are not yet supported)",
weechat_prefix("error"));
break;
case TOX_ERR_NEW_LOAD_BAD_FORMAT:
weechat_printf(profile->buffer,
"%scould not load Tox (invalid data file, some data "
"may have been loaded; use -force to try using it)",
weechat_prefix("error"));
break;
default:
weechat_printf(profile->buffer,
"%scould not load Tox (unknown error %d)",
weechat_prefix("error"), error);
break;
}
}
/** /**
* Load a profile's Tox object, creating a new one if it can't be loaded from * Load a profile's Tox object, creating a new one if it can't be loaded from
* disk, and bootstraps the Tox DHT. * disk, and bootstraps the Tox DHT.
*/ */
void enum t_twc_rc
twc_profile_load(struct t_twc_profile *profile) twc_profile_load(struct t_twc_profile *profile)
{ {
if (profile->tox) if (profile->tox)
return; return TWC_RC_ERROR;
if (!(profile->buffer)) if (!(profile->buffer))
{ {
@ -208,90 +264,73 @@ twc_profile_load(struct t_twc_profile *profile)
NULL, NULL, NULL, NULL,
twc_profile_buffer_close_callback, profile); twc_profile_buffer_close_callback, profile);
if (!(profile->buffer)) if (!(profile->buffer))
return; return TWC_RC_ERROR;
} }
weechat_printf(profile->buffer, weechat_printf(profile->buffer,
"%s%s: profile %s connecting", "%s profile %s connecting",
weechat_prefix("network"), weechat_plugin->name, weechat_prefix("network"), profile->name);
profile->name);
// create Tox options object // create Tox options object
struct Tox_Options options; struct Tox_Options options;
tox_options_default(&options); twc_profile_set_options(&options, profile);
char *proxy_type;
switch (TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_TYPE))
{
case TWC_PROXY_NONE:
options.proxy_type = TOX_PROXY_TYPE_NONE;
break;
case TWC_PROXY_SOCKS5:
options.proxy_type = TOX_PROXY_TYPE_SOCKS5;
proxy_type = "SOCKS5";
break;
case TWC_PROXY_HTTP:
options.proxy_type = TOX_PROXY_TYPE_HTTP;
proxy_type = "HTTP";
break;
}
const char *proxy_host =
TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_PROXY_ADDRESS);
if (proxy_host)
options.proxy_host = proxy_host;
options.proxy_port =
TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_PORT);
options.udp_enabled =
TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_UDP);
options.ipv6_enabled =
TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_IPV6);
// print a proxy message
if (options.proxy_type != TOX_PROXY_TYPE_NONE) if (options.proxy_type != TOX_PROXY_TYPE_NONE)
{ {
if (!options.proxy_host || !options.proxy_port) weechat_printf(profile->buffer,
{ "%susing %s proxy %s:%d",
weechat_printf(profile->buffer, weechat_prefix("network"),
"%sproxy is enabled, but proxy information is " options.proxy_type == TOX_PROXY_TYPE_HTTP ? "HTTP" :
"incomplete; aborting", TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" :
weechat_prefix("error")); NULL,
return; options.proxy_host, options.proxy_port);
} }
else
{ // try loading data file
weechat_printf(profile->buffer, char *path = twc_profile_expanded_data_path(profile);
"%susing %s proxy %s:%d", uint8_t *data;
weechat_prefix("network"), size_t data_size = 0;
proxy_type, enum t_twc_rc data_rc = twc_read_file(path, &data, &data_size);
options.proxy_host, options.proxy_port);
} if (data_rc == TWC_RC_ERROR_MALLOC)
{
weechat_printf(profile->buffer,
"%scould not load Tox data file, aborting (malloc error)",
weechat_prefix("error"));
return TWC_RC_ERROR_MALLOC;
} }
// create Tox // create Tox
profile->tox = tox_new(&options); TOX_ERR_NEW rc;
if (!(profile->tox)) profile->tox = tox_new(&options, data, data_size, &rc);
if (rc != TOX_ERR_NEW_OK)
{ {
weechat_printf(profile->buffer, twc_tox_new_print_error(profile, &options, rc);
"%scould not create Tox instance", return rc == TOX_ERR_NEW_MALLOC ? TWC_RC_ERROR_MALLOC : TWC_RC_ERROR;
weechat_prefix("error"));
return;
} }
// try loading Tox saved data if (data_size == 0)
// TODO: this can return -1 even if it does not fail
if (twc_profile_load_data(profile) == -1)
{ {
// we failed to load - set some defaults // no data file loaded, set default name
char *name; const char *default_name = "Tox-WeeChat User";
const char *name;
struct passwd *user_pwd; struct passwd *user_pwd;
if ((user_pwd = getpwuid(geteuid()))) if ((user_pwd = getpwuid(geteuid())))
name = user_pwd->pw_name; name = user_pwd->pw_name;
else else
name = "Tox-WeeChat User"; name = default_name;
tox_set_name(profile->tox, TOX_ERR_SET_INFO rc;
(uint8_t *)name, strlen(name)); tox_self_set_name(profile->tox,
(uint8_t *)name, strlen(name),
&rc);
if (rc == TOX_ERR_SET_INFO_TOO_LONG)
tox_self_set_name(profile->tox,
(uint8_t *)default_name, strlen(default_name),
NULL);
} }
// bootstrap DHT // bootstrap DHT
@ -300,16 +339,15 @@ twc_profile_load(struct t_twc_profile *profile)
for (int i = 0; i < bootstrap_node_count; ++i) for (int i = 0; i < bootstrap_node_count; ++i)
twc_bootstrap_random_node(profile->tox); twc_bootstrap_random_node(profile->tox);
// start Tox_do loop // start tox_iterate loop
twc_do_timer_cb(profile, 0); twc_do_timer_cb(profile, 0);
// register Tox callbacks // register Tox callbacks
tox_callback_friend_message(profile->tox, twc_friend_message_callback, profile); tox_callback_friend_message(profile->tox, twc_friend_message_callback, profile);
tox_callback_friend_action(profile->tox, twc_friend_action_callback, profile); tox_callback_friend_connection_status(profile->tox, twc_connection_status_callback, profile);
tox_callback_connection_status(profile->tox, twc_connection_status_callback, profile); tox_callback_friend_name(profile->tox, twc_name_change_callback, profile);
tox_callback_name_change(profile->tox, twc_name_change_callback, profile); tox_callback_friend_status(profile->tox, twc_user_status_callback, profile);
tox_callback_user_status(profile->tox, twc_user_status_callback, profile); tox_callback_friend_status_message(profile->tox, twc_status_message_callback, profile);
tox_callback_status_message(profile->tox, twc_status_message_callback, profile);
tox_callback_friend_request(profile->tox, twc_friend_request_callback, profile); tox_callback_friend_request(profile->tox, twc_friend_request_callback, profile);
tox_callback_group_invite(profile->tox, twc_group_invite_callback, profile); tox_callback_group_invite(profile->tox, twc_group_invite_callback, profile);
tox_callback_group_message(profile->tox, twc_group_message_callback, profile); tox_callback_group_message(profile->tox, twc_group_message_callback, profile);

View File

@ -93,7 +93,7 @@ twc_profile_init();
struct t_twc_profile * struct t_twc_profile *
twc_profile_new(const char *name); twc_profile_new(const char *name);
void enum t_twc_rc
twc_profile_load(struct t_twc_profile *profile); twc_profile_load(struct t_twc_profile *profile);
void void

View File

@ -38,24 +38,25 @@ twc_do_timer_cb(void *data,
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
tox_do(profile->tox); tox_iterate(profile->tox);
struct t_hook *hook = weechat_hook_timer(tox_do_interval(profile->tox), 0, 1, struct t_hook *hook = weechat_hook_timer(tox_iteration_interval(profile->tox),
twc_do_timer_cb, profile); 0, 1, twc_do_timer_cb, profile);
profile->tox_do_timer = hook; profile->tox_do_timer = hook;
// check connection status // check connection status
int connected = tox_isconnected(profile->tox); TOX_CONNECTION connection = tox_self_get_connection_status(profile->tox);
twc_profile_set_online_status(profile, connected); bool is_connected = connection == TOX_CONNECTION_TCP
|| connection == TOX_CONNECTION_UDP;
twc_profile_set_online_status(profile, is_connected);
return WEECHAT_RC_OK; return WEECHAT_RC_OK;
} }
void void
twc_handle_friend_message(Tox *tox, int32_t friend_number, twc_friend_message_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, TOX_MESSAGE_TYPE type,
void *data, const uint8_t *message, size_t length,
enum TWC_MESSAGE_TYPE message_type) void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
struct t_twc_chat *chat = twc_chat_search_friend(profile, struct t_twc_chat *chat = twc_chat_search_friend(profile,
@ -66,36 +67,15 @@ twc_handle_friend_message(Tox *tox, int32_t friend_number,
char *message_nt = twc_null_terminate(message, length); char *message_nt = twc_null_terminate(message, length);
twc_chat_print_message(chat, "", name, twc_chat_print_message(chat, "", name,
message_nt, message_type); message_nt, type);
free(name); free(name);
free(message_nt); free(message_nt);
} }
void void
twc_friend_message_callback(Tox *tox, int32_t friend_number, twc_connection_status_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, TOX_CONNECTION status, void *data)
void *data)
{
twc_handle_friend_message(tox, friend_number,
message, length,
data, TWC_MESSAGE_TYPE_MESSAGE);
}
void
twc_friend_action_callback(Tox *tox, int32_t friend_number,
const uint8_t *message, uint16_t length,
void *data)
{
twc_handle_friend_message(tox, friend_number,
message, length,
data, TWC_MESSAGE_TYPE_ACTION);
}
void
twc_connection_status_callback(Tox *tox,
int32_t friend_number, uint8_t status,
void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
char *name = twc_get_name_nt(profile->tox, friend_number); char *name = twc_get_name_nt(profile->tox, friend_number);
@ -120,8 +100,8 @@ twc_connection_status_callback(Tox *tox,
} }
void void
twc_name_change_callback(Tox *tox, int32_t friend_number, twc_name_change_callback(Tox *tox, uint32_t friend_number,
const uint8_t *name, uint16_t length, const uint8_t *name, size_t length,
void *data) void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
@ -155,9 +135,8 @@ twc_name_change_callback(Tox *tox, int32_t friend_number,
} }
void void
twc_user_status_callback(Tox *tox, twc_user_status_callback(Tox *tox, uint32_t friend_number,
int32_t friend_number, uint8_t status, TOX_USER_STATUS status, void *data)
void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
struct t_twc_chat *chat = twc_chat_search_friend(profile, struct t_twc_chat *chat = twc_chat_search_friend(profile,
@ -168,8 +147,8 @@ twc_user_status_callback(Tox *tox,
} }
void void
twc_status_message_callback(Tox *tox, int32_t friend_number, twc_status_message_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, const uint8_t *message, size_t length,
void *data) void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;
@ -182,7 +161,7 @@ twc_status_message_callback(Tox *tox, int32_t friend_number,
void void
twc_friend_request_callback(Tox *tox, const uint8_t *public_key, twc_friend_request_callback(Tox *tox, const uint8_t *public_key,
const uint8_t *message, uint16_t length, const uint8_t *message, size_t length,
void *data) void *data)
{ {
struct t_twc_profile *profile = data; struct t_twc_profile *profile = data;

View File

@ -27,38 +27,32 @@ twc_do_timer_cb(void *data,
int remaining_calls); int remaining_calls);
void void
twc_friend_message_callback(Tox *tox, int32_t friend_number, twc_friend_message_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length,
void *data); void *data);
void void
twc_friend_action_callback(Tox *tox, int32_t friend_number, twc_connection_status_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, TOX_CONNECTION status, void *data);
void *data);
void void
twc_connection_status_callback(Tox *tox, twc_name_change_callback(Tox *tox, uint32_t friend_number,
int32_t friend_number, uint8_t status, const uint8_t *name, size_t length,
void *data);
void
twc_name_change_callback(Tox *tox, int32_t friend_number,
const uint8_t *name, uint16_t length,
void *data); void *data);
void void
twc_user_status_callback(Tox *tox, twc_user_status_callback(Tox *tox, uint32_t friend_number,
int32_t friend_number, uint8_t status, TOX_USER_STATUS status, void *data);
void *data);
void void
twc_status_message_callback(Tox *tox, int32_t friend_number, twc_status_message_callback(Tox *tox, uint32_t friend_number,
const uint8_t *message, uint16_t length, const uint8_t *message, size_t length,
void *data); void *data);
void void
twc_friend_request_callback(Tox *tox, const uint8_t *public_key, twc_friend_request_callback(Tox *tox, const uint8_t *public_key,
const uint8_t *message, uint16_t length, const uint8_t *message, size_t length,
void *data); void *data);
void void

View File

@ -183,3 +183,36 @@ twc_hash_tox_id(const uint8_t *tox_id)
return hash; return hash;
} }
/**
* Read an entire file into memory.
*
* @return TWC_RC_OK on success, TWC_RC_ERROR if file can not be opened, and
* TWC_RC_ERROR_MALLOC if an appropriate buffer can not be allocated.
*/
enum t_twc_rc
twc_read_file(const char *path, uint8_t **data, size_t *size)
{
FILE *file;
if (file = fopen(path, "r"))
{
// get file size
fseek(file, 0, SEEK_END);
*size = ftell(file);
rewind(file);
if (data = malloc(sizeof(*data) * *size))
{
fread(data, sizeof(uint8_t), *size, file);
fclose(file);
return TWC_RC_OK;
}
else
{
fclose(file);
return TWC_RC_ERROR_MALLOC;
}
}
return TWC_RC_ERROR;
}

View File

@ -54,5 +54,8 @@ twc_uint32_reverse_bytes(uint32_t num);
unsigned long long unsigned long long
twc_hash_tox_id(const uint8_t *tox_id); twc_hash_tox_id(const uint8_t *tox_id);
enum t_twc_rc
twc_read_file(const char *path, uint8_t **data, size_t *size);
#endif // TOX_WEECHAT_UTILS_H #endif // TOX_WEECHAT_UTILS_H

View File

@ -23,7 +23,8 @@
extern struct t_weechat_plugin *weechat_plugin; extern struct t_weechat_plugin *weechat_plugin;
/// Return codes used throughout Tox-WeeChat. /// Return codes used throughout Tox-WeeChat.
enum t_twc_rc { enum t_twc_rc
{
TWC_RC_OK, TWC_RC_OK,
/// Generic error return code. /// Generic error return code.
TWC_RC_ERROR, TWC_RC_ERROR,