mirror of
https://github.com/weechat/weechat.git
synced 2026-06-26 04:46:37 +02:00
irc: add support of UTF8MAPPING, add support of optional server in info "irc_is_nick" (closes #1528)
This commit is contained in:
@@ -108,6 +108,10 @@ irc_info_info_irc_is_nick_cb (const void *pointer, void *data,
|
||||
const char *info_name,
|
||||
const char *arguments)
|
||||
{
|
||||
char *pos_comma, *server;
|
||||
const char *pos_nick;
|
||||
struct t_irc_server *ptr_server;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
@@ -116,7 +120,21 @@ irc_info_info_irc_is_nick_cb (const void *pointer, void *data,
|
||||
if (!arguments || !arguments[0])
|
||||
return NULL;
|
||||
|
||||
return (irc_nick_is_nick (arguments)) ? strdup ("1") : NULL;
|
||||
ptr_server = NULL;
|
||||
pos_nick = arguments;
|
||||
pos_comma = strchr (arguments, ',');
|
||||
if (pos_comma)
|
||||
{
|
||||
pos_nick = pos_comma + 1;
|
||||
server = weechat_strndup (arguments, pos_comma - arguments);
|
||||
if (server)
|
||||
{
|
||||
ptr_server = irc_server_search (server);
|
||||
free (server);
|
||||
}
|
||||
}
|
||||
|
||||
return (irc_nick_is_nick (ptr_server, pos_nick)) ? strdup ("1") : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1072,7 +1090,7 @@ irc_info_init ()
|
||||
weechat_hook_info (
|
||||
"irc_is_nick",
|
||||
N_("1 if string is a valid IRC nick name"),
|
||||
N_("nickname"),
|
||||
N_("server,nickname (server is optional)"),
|
||||
&irc_info_info_irc_is_nick_cb, NULL, NULL);
|
||||
weechat_hook_info (
|
||||
"irc_nick",
|
||||
|
||||
+44
-12
@@ -62,31 +62,63 @@ irc_nick_valid (struct t_irc_channel *channel, struct t_irc_nick *nick)
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if string is a valid nick string (RFC 1459).
|
||||
* Checks if string is a valid nick string, using server UTF8MAPPING.
|
||||
*
|
||||
* Returns:
|
||||
* 1: string is a valid nick
|
||||
* 0: string is not a valid nick
|
||||
* 1: string is a valid nick on this server
|
||||
* 0: string is not a valid nick on this server
|
||||
*/
|
||||
|
||||
int
|
||||
irc_nick_is_nick (const char *string)
|
||||
irc_nick_is_nick (struct t_irc_server *server, const char *string)
|
||||
{
|
||||
const char *ptr;
|
||||
const char *ptr_string;
|
||||
int utf8mapping;
|
||||
|
||||
if (!string || !string[0])
|
||||
return 0;
|
||||
|
||||
/* first char must not be a number or hyphen */
|
||||
ptr = string;
|
||||
if (strchr ("0123456789-", *ptr))
|
||||
return 0;
|
||||
utf8mapping = (server) ? server->utf8mapping : IRC_SERVER_UTF8MAPPING_NONE;
|
||||
|
||||
while (ptr && ptr[0])
|
||||
/* check length of nick in bytes (if we have a limit in the server) */
|
||||
if (server && (server->nick_max_length > 0)
|
||||
&& (int)strlen (string) > server->nick_max_length)
|
||||
{
|
||||
if (!strchr (IRC_NICK_VALID_CHARS, *ptr))
|
||||
/* nick is too long */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if nick is UTF-8 valid */
|
||||
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_RFC8265)
|
||||
&& !weechat_utf8_is_valid (string, -1, NULL))
|
||||
{
|
||||
/* invalid UTF-8 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check the first char in the nick */
|
||||
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_NONE)
|
||||
&& strchr ("0123456789-", string[0]))
|
||||
{
|
||||
/* first char is invalid */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if there are forbidden chars in nick */
|
||||
ptr_string = string;
|
||||
while (ptr_string && ptr_string[0])
|
||||
{
|
||||
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_NONE)
|
||||
&& !strchr (IRC_NICK_VALID_CHARS, ptr_string[0]))
|
||||
{
|
||||
return 0;
|
||||
ptr++;
|
||||
}
|
||||
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_RFC8265)
|
||||
&& strchr (IRC_NICK_INVALID_CHARS, ptr_string[0]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ptr_string = weechat_utf8_next_char (ptr_string);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define IRC_NICK_VALID_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHI" \
|
||||
"JKLMNOPQRSTUVWXYZ0123456789-[]\\`_^{|}"
|
||||
#define IRC_NICK_INVALID_CHARS " ,:\n\r*?.!@"
|
||||
|
||||
/* nicklist group for nicks without prefix is "999|..." */
|
||||
#define IRC_NICK_GROUP_OTHER_NUMBER 999
|
||||
@@ -47,7 +48,7 @@ struct t_irc_nick
|
||||
|
||||
extern int irc_nick_valid (struct t_irc_channel *channel,
|
||||
struct t_irc_nick *nick);
|
||||
extern int irc_nick_is_nick (const char *string);
|
||||
extern int irc_nick_is_nick (struct t_irc_server *server, const char *string);
|
||||
extern char *irc_nick_find_color (const char *nickname);
|
||||
extern char *irc_nick_find_color_name (const char *nickname);
|
||||
extern void irc_nick_set_host (struct t_irc_nick *nick, const char *host);
|
||||
|
||||
@@ -3096,7 +3096,7 @@ IRC_PROTOCOL_CALLBACK(001)
|
||||
IRC_PROTOCOL_CALLBACK(005)
|
||||
{
|
||||
char *pos, *pos2, *pos_start, *error, *isupport2;
|
||||
int length_isupport, length, casemapping;
|
||||
int length_isupport, length, casemapping, utf8mapping;
|
||||
long value;
|
||||
|
||||
IRC_PROTOCOL_MIN_ARGS(4);
|
||||
@@ -3181,6 +3181,21 @@ IRC_PROTOCOL_CALLBACK(005)
|
||||
pos2[0] = ' ';
|
||||
}
|
||||
|
||||
/* save utf8mapping */
|
||||
pos = strstr (argv_eol[3], "UTF8MAPPING=");
|
||||
if (pos)
|
||||
{
|
||||
pos += 12;
|
||||
pos2 = strchr (pos, ' ');
|
||||
if (pos2)
|
||||
pos2[0] = '\0';
|
||||
utf8mapping = irc_server_search_utf8mapping (pos);
|
||||
if (utf8mapping >= 0)
|
||||
server->utf8mapping = utf8mapping;
|
||||
if (pos2)
|
||||
pos2[0] = ' ';
|
||||
}
|
||||
|
||||
/* save chantypes */
|
||||
pos = strstr (argv_eol[3], "CHANTYPES=");
|
||||
if (pos)
|
||||
|
||||
@@ -124,6 +124,9 @@ char *irc_server_options[IRC_SERVER_NUM_OPTIONS][2] =
|
||||
char *irc_server_casemapping_string[IRC_SERVER_NUM_CASEMAPPING] =
|
||||
{ "rfc1459", "strict-rfc1459", "ascii" };
|
||||
|
||||
char *irc_server_utf8mapping_string[IRC_SERVER_NUM_UTF8MAPPING] =
|
||||
{ "none", "rfc8265" };
|
||||
|
||||
char *irc_server_prefix_modes_default = "ov";
|
||||
char *irc_server_prefix_chars_default = "@+";
|
||||
char *irc_server_chanmodes_default = "beI,k,l";
|
||||
@@ -248,8 +251,8 @@ irc_server_search_option (const char *option_name)
|
||||
/*
|
||||
* Searches for a casemapping.
|
||||
*
|
||||
* Returns index of casemapping in array "irc_server_casemapping_string", -1 if
|
||||
* not found.
|
||||
* Returns index of casemapping in array "irc_server_casemapping_string",
|
||||
* -1 if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -267,6 +270,28 @@ irc_server_search_casemapping (const char *casemapping)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for a utf8mapping.
|
||||
*
|
||||
* Returns index of utf8mapping in array "irc_server_utf8mapping_string",
|
||||
* -1 if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
irc_server_search_utf8mapping (const char *utf8mapping)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IRC_SERVER_NUM_UTF8MAPPING; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (irc_server_utf8mapping_string[i], utf8mapping) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* utf8mapping not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares two strings on server (case insensitive, depends on casemapping).
|
||||
*
|
||||
@@ -302,8 +327,8 @@ irc_server_strcasecmp (struct t_irc_server *server,
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares two strings on server (case insensitive, depends on casemapping) for
|
||||
* max chars.
|
||||
* Compares two strings on server (case insensitive, depends on casemapping)
|
||||
* for max chars.
|
||||
*
|
||||
* Returns:
|
||||
* < 0: string1 < string2
|
||||
@@ -1415,6 +1440,7 @@ irc_server_alloc (const char *name)
|
||||
new_server->user_max_length = 0;
|
||||
new_server->host_max_length = 0;
|
||||
new_server->casemapping = IRC_SERVER_CASEMAPPING_RFC1459;
|
||||
new_server->utf8mapping = IRC_SERVER_UTF8MAPPING_NONE;
|
||||
new_server->chantypes = NULL;
|
||||
new_server->chanmodes = NULL;
|
||||
new_server->monitor = 0;
|
||||
@@ -5743,6 +5769,7 @@ irc_server_hdata_server_cb (const void *pointer, void *data,
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, user_max_length, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, host_max_length, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, casemapping, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, utf8mapping, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, chantypes, STRING, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, chanmodes, STRING, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, monitor, INTEGER, 0, NULL, NULL);
|
||||
@@ -5990,6 +6017,10 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "casemapping_string", irc_server_casemapping_string[server->casemapping]))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "utf8mapping", server->utf8mapping))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "utf8mapping_string", irc_server_utf8mapping_string[server->utf8mapping]))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "chantypes", server->chantypes))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "chanmodes", server->chanmodes))
|
||||
@@ -6378,6 +6409,9 @@ irc_server_print_log ()
|
||||
weechat_log_printf (" casemapping. . . . . : %d (%s)",
|
||||
ptr_server->casemapping,
|
||||
irc_server_casemapping_string[ptr_server->casemapping]);
|
||||
weechat_log_printf (" utf8mapping. . . . . : %d (%s)",
|
||||
ptr_server->utf8mapping,
|
||||
irc_server_utf8mapping_string[ptr_server->utf8mapping]);
|
||||
weechat_log_printf (" chantypes. . . . . . : '%s'", ptr_server->chantypes);
|
||||
weechat_log_printf (" chanmodes. . . . . . : '%s'", ptr_server->chanmodes);
|
||||
weechat_log_printf (" monitor. . . . . . . : %d", ptr_server->monitor);
|
||||
|
||||
@@ -142,6 +142,15 @@ enum t_irc_server_casemapping
|
||||
IRC_SERVER_NUM_CASEMAPPING,
|
||||
};
|
||||
|
||||
/* utf8mapping (string comparisons for nicks/channels) */
|
||||
enum t_irc_server_utf8mapping
|
||||
{
|
||||
IRC_SERVER_UTF8MAPPING_NONE = 0,
|
||||
IRC_SERVER_UTF8MAPPING_RFC8265,
|
||||
/* number of utf8mapping */
|
||||
IRC_SERVER_NUM_UTF8MAPPING,
|
||||
};
|
||||
|
||||
/* output queue of messages to server (for sending slowly to server) */
|
||||
|
||||
struct t_irc_outqueue
|
||||
@@ -210,6 +219,7 @@ struct t_irc_server
|
||||
int user_max_length; /* max length of user (from msg 005) */
|
||||
int host_max_length; /* max length of host (from msg 005) */
|
||||
int casemapping; /* casemapping from msg 005 */
|
||||
int utf8mapping; /* utf8mapping from msg 005 */
|
||||
char *chantypes; /* chantypes from msg 005 (eg "&#") */
|
||||
char *chanmodes; /* chanmodes from msg 005 */
|
||||
/* (eg "beI,k,l,imnpstaqr") */
|
||||
@@ -284,6 +294,7 @@ extern struct t_irc_server *irc_server_search (const char *server_name);
|
||||
extern struct t_irc_server *irc_server_casesearch (const char *server_name);
|
||||
extern int irc_server_search_option (const char *option_name);
|
||||
extern int irc_server_search_casemapping (const char *casemapping);
|
||||
extern int irc_server_search_utf8mapping (const char *utf8mapping);
|
||||
extern int irc_server_strcasecmp (struct t_irc_server *server,
|
||||
const char *string1, const char *string2);
|
||||
extern int irc_server_strncasecmp (struct t_irc_server *server,
|
||||
|
||||
@@ -339,7 +339,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
|
||||
int object_id,
|
||||
struct t_infolist *infolist)
|
||||
{
|
||||
int flags, sock, size, i, index, nicks_count, num_items;
|
||||
int flags, sock, size, i, index, nicks_count, num_items, utf8mapping;
|
||||
long number;
|
||||
time_t join_time;
|
||||
char *buf, option_name[64], **nicks, *nick_join, *pos, *error;
|
||||
@@ -479,7 +479,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
|
||||
irc_upgrade_current_server->prefix_chars = strdup (str);
|
||||
}
|
||||
irc_upgrade_current_server->nick_max_length = weechat_infolist_integer (infolist, "nick_max_length");
|
||||
/* "user_max_length" is new in WeeChat 2.6 */
|
||||
/* "user_max_length" is new in WeeChat 2.6 */
|
||||
if (weechat_infolist_search_var (infolist, "user_max_length"))
|
||||
{
|
||||
irc_upgrade_current_server->user_max_length = weechat_infolist_integer (infolist, "user_max_length");
|
||||
@@ -497,7 +497,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
|
||||
irc_upgrade_current_server->user_max_length = (int)number;
|
||||
}
|
||||
}
|
||||
/* "host_max_length" is new in WeeChat 2.6 */
|
||||
/* "host_max_length" is new in WeeChat 2.6 */
|
||||
if (weechat_infolist_search_var (infolist, "host_max_length"))
|
||||
{
|
||||
irc_upgrade_current_server->host_max_length = weechat_infolist_integer (infolist, "host_max_length");
|
||||
@@ -516,6 +516,23 @@ irc_upgrade_read_cb (const void *pointer, void *data,
|
||||
}
|
||||
}
|
||||
irc_upgrade_current_server->casemapping = weechat_infolist_integer (infolist, "casemapping");
|
||||
/* "utf8mapping" is new in WeeChat 2.9 */
|
||||
if (weechat_infolist_search_var (infolist, "utf8mapping"))
|
||||
{
|
||||
irc_upgrade_current_server->utf8mapping = weechat_infolist_integer (infolist, "utf8mapping");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* WeeChat <= 2.8 */
|
||||
str = irc_server_get_isupport_value (irc_upgrade_current_server,
|
||||
"UTF8MAPPING");
|
||||
if (str)
|
||||
{
|
||||
utf8mapping = irc_server_search_utf8mapping (str);
|
||||
if (utf8mapping >= 0)
|
||||
irc_upgrade_current_server->utf8mapping = utf8mapping;
|
||||
}
|
||||
}
|
||||
str = weechat_infolist_string (infolist, "chantypes");
|
||||
if (str)
|
||||
irc_upgrade_current_server->chantypes = strdup (str);
|
||||
|
||||
Reference in New Issue
Block a user