Fixed bugs with names containing spaces.

This commit is contained in:
Håvard Pettersson 2014-10-05 01:31:54 +02:00
parent 9a97a3fe0c
commit 0499f92ad7
2 changed files with 154 additions and 54 deletions

View File

@ -18,6 +18,7 @@
*/
#include <string.h>
#include <stdio.h>
#include <weechat/weechat-plugin.h>
#include <tox/tox.h>
@ -34,59 +35,138 @@
#include "twc-commands.h"
enum TWC_FRIEND_MATCH
{
TWC_FRIEND_MATCH_AMBIGUOUS = -1,
TWC_FRIEND_MATCH_NOMATCH = -2,
};
/**
* Make sure a command is executed on a Tox profile buffer. If not, warn user
* and abort.
*/
#define TWC_CHECK_PROFILE(profile) \
if (!profile) \
{ \
weechat_printf(NULL, \
"%s%s: command \"%s\" must be executed on a Tox buffer", \
weechat_prefix("error"), weechat_plugin->name, \
argv[0]); \
return WEECHAT_RC_OK; \
} \
#define TWC_CHECK_PROFILE(profile) \
if (!profile) \
{ \
weechat_printf(NULL, \
"%s%s: command \"%s\" must be executed on a Tox " \
"buffer", \
weechat_prefix("error"), weechat_plugin->name, \
argv[0]); \
return WEECHAT_RC_OK; \
} \
/**
* Make sure a command is executed in a chat buffer. If not, warn user and
* abort.
*/
#define TWC_CHECK_CHAT(chat) \
if (!chat) \
{ \
weechat_printf(NULL, \
"%s%s: command \"%s\" must be executed in a chat buffer", \
weechat_prefix("error"), weechat_plugin->name, argv[0]); \
return WEECHAT_RC_OK; \
#define TWC_CHECK_CHAT(chat) \
if (!chat) \
{ \
weechat_printf(NULL, \
"%s%s: command \"%s\" must be executed in a chat " \
"buffer", \
weechat_prefix("error"), \
weechat_plugin->name, \
argv[0]); \
return WEECHAT_RC_OK; \
}
/**
* Make sure a profile with the given name exists. If not, warn user and
* abort.
*/
#define TWC_CHECK_PROFILE_EXISTS(profile) \
if (!profile) \
{ \
weechat_printf(NULL, \
"%s%s: profile \"%s\" does not exist.", \
weechat_prefix("error"), weechat_plugin->name, \
name); \
return WEECHAT_RC_OK; \
#define TWC_CHECK_PROFILE_EXISTS(profile) \
if (!profile) \
{ \
weechat_printf(NULL, \
"%s%s: profile \"%s\" does not exist.", \
weechat_prefix("error"), weechat_plugin->name, \
name); \
return WEECHAT_RC_OK; \
}
/**
* Make sure a profile is loaded.
*/
#define TWC_CHECK_PROFILE_LOADED(profile) \
if (!(profile->tox)) \
{ \
weechat_printf(profile->buffer, \
"%sprofile must be loaded for command \"%s\"", \
weechat_prefix("error"), argv[0]); \
return WEECHAT_RC_OK; \
#define TWC_CHECK_PROFILE_LOADED(profile) \
if (!(profile->tox)) \
{ \
weechat_printf(profile->buffer, \
"%sprofile must be loaded for command \"%s\"", \
weechat_prefix("error"), argv[0]); \
return WEECHAT_RC_OK; \
}
/**
* Make sure friend exists.
*/
#define TWC_CHECK_FRIEND_NUMBER(number, string) \
if (number == TWC_FRIEND_MATCH_NOMATCH) \
{ \
weechat_printf(profile->buffer, \
"%sno friend number, name or Tox ID found matching " \
"\"%s\"", \
weechat_prefix("error"), string); \
return WEECHAT_RC_OK; \
} \
if (number == TWC_FRIEND_MATCH_AMBIGUOUS) \
{ \
weechat_printf(profile->buffer, \
"%smultiple friends with name \"%s\" found; please " \
"use Tox ID instead", \
weechat_prefix("error"), string); \
return WEECHAT_RC_OK; \
}
/**
* Get number of friend matching string. Tries to match number, name and
* Tox ID.
*/
enum TWC_FRIEND_MATCH
twc_match_friend(struct t_twc_profile *profile, const char *search_string)
{
uint32_t friend_count = tox_count_friendlist(profile->tox);
int32_t *friend_numbers = malloc(sizeof(int32_t) * friend_count);
tox_get_friendlist(profile->tox, friend_numbers, friend_count);
int32_t match = TWC_FRIEND_MATCH_NOMATCH;
char *endptr;
unsigned long friend_number = strtoul(search_string, &endptr, 10);
if (endptr == search_string + strlen(search_string)
&& tox_friend_exists(profile->tox, friend_number))
return friend_number;
size_t search_size = strlen(search_string);
for (uint32_t i = 0; i < friend_count; ++i)
{
if (search_size == TOX_CLIENT_ID_SIZE * 2)
{
uint8_t tox_id[TOX_CLIENT_ID_SIZE];
char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1];
tox_get_client_id(profile->tox, friend_numbers[i], tox_id);
twc_bin2hex(tox_id, TOX_CLIENT_ID_SIZE, hex_id);
if (weechat_strcasecmp(hex_id, search_string) == 0)
return friend_number;
}
char *name = twc_get_name_nt(profile->tox, friend_numbers[i]);
if (weechat_strcasecmp(name, search_string) == 0)
{
if (match == TWC_FRIEND_MATCH_NOMATCH)
match = friend_numbers[i];
else
return TWC_FRIEND_MATCH_AMBIGUOUS;
}
}
return match;
}
/**
* Command /bootstrap callback.
*/
@ -238,19 +318,11 @@ twc_cmd_friend(void *data, struct t_gui_buffer *buffer,
return WEECHAT_RC_OK;
}
// /friend remove <number>
else if (argc == 3 && (weechat_strcasecmp(argv[1], "remove") == 0))
// /friend remove
else if (argc >= 3 && (weechat_strcasecmp(argv[1], "remove") == 0))
{
char *endptr;
unsigned long friend_number = strtoul(argv[2], &endptr, 10);
if (endptr == argv[2] || !tox_friend_exists(profile->tox, friend_number))
{
weechat_printf(profile->buffer,
"%sInvalid friend number.",
weechat_prefix("error"));
return WEECHAT_RC_OK;
}
int32_t friend_number = twc_match_friend(profile, argv[2]);
TWC_CHECK_FRIEND_NUMBER(friend_number, argv[2]);
char *name = twc_get_name_nt(profile->tox, friend_number);
if (tox_del_friend(profile->tox, friend_number) == 0)
@ -483,23 +555,35 @@ twc_cmd_msg(void *data, struct t_gui_buffer *buffer,
TWC_CHECK_PROFILE(profile);
TWC_CHECK_PROFILE_LOADED(profile);
char *endptr;
unsigned long friend_number = strtoul(argv[1], &endptr, 10);
// do a shell split in case a friend has spaces in his name and we need
// quotes
int shell_argc;
char **shell_argv = weechat_string_split_shell(argv_eol[0], &shell_argc);
if (endptr == argv[1] || !tox_friend_exists(profile->tox, friend_number))
char recipient[TOX_MAX_NAME_LENGTH + 1];
snprintf(recipient, TOX_MAX_NAME_LENGTH, "%s", shell_argv[1]);
weechat_string_free_split(shell_argv);
char *message = NULL;
if (shell_argc >= 3)
{
weechat_printf(profile->buffer,
"%sInvalid friend number.",
weechat_prefix("error"));
return WEECHAT_RC_OK;
// extract message, add two if quotes are used
message = argv_eol[1] + strlen(recipient);
if (*argv[1] == '"' || *argv[1] == '\'')
message += 2;
}
int32_t friend_number = twc_match_friend(profile, recipient);
TWC_CHECK_FRIEND_NUMBER(friend_number, recipient);
// create chat buffer if it does not exist
struct t_twc_chat *chat = twc_chat_search_friend(profile, friend_number, true);
// send a message if provided
if (argc >= 3)
twc_chat_send_message(chat, argv_eol[2], TWC_MESSAGE_TYPE_MESSAGE);
if (message)
twc_chat_send_message(chat,
weechat_string_strip(message, 1, 1, " "),
TWC_MESSAGE_TYPE_MESSAGE);
return WEECHAT_RC_OK;
}
@ -851,8 +935,8 @@ twc_commands_init()
" || add"
" || remove %(tox_friend_name)|%(tox_friend_tox_id)"
" || requests"
" || accept %(tox_friend_name)|%(tox_friend_tox_id)"
" || decline %(tox_friend_name)|%(tox_friend_tox_id)",
" || accept"
" || decline",
twc_cmd_friend, NULL);
weechat_hook_command("group",

View File

@ -17,6 +17,9 @@
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdio.h>
#include <weechat/weechat-plugin.h>
#include "twc.h"
@ -78,10 +81,23 @@ twc_completion_friend(void *data,
{
char *name = twc_get_name_nt(profile->tox, friend_numbers[i]);
// add quotes if needed
if (strchr(name, ' '))
{
size_t length = strlen(name) + 3;
char *quoted_name = malloc(length);
snprintf(quoted_name, length, "\"%s\"", name);
free(name);
name = quoted_name;
}
weechat_hook_completion_list_add(completion,
name,
0,
WEECHAT_LIST_POS_SORT);
free(name);
}
}