Skip to content

Commit

Permalink
irc: build dynamically the list of CTCPs supported in reply to "CTCP …
Browse files Browse the repository at this point in the history
…CLIENTINFO" (issue #1974)
  • Loading branch information
flashcode committed Jul 12, 2023
1 parent f46f759 commit 9237852
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 10 deletions.
1 change: 1 addition & 0 deletions ChangeLog.adoc
Expand Up @@ -24,6 +24,7 @@ New features::
* irc: display commands 716/717 in private buffer (if present) (issue #146)
* irc: create default options irc.ctcp.* when file irc.conf is created (issue #1974)
* irc: evaluate options irc.ctcp.* (issue #1974)
* irc: build dynamically the list of CTCPs supported in reply to "CTCP CLIENTINFO" (issue #1974)
* irc: remove Git revision and compilation date from CTCP VERSION/FINGER reply (issue #1974)
* trigger: add options `-o`, `-ol`, `-i` and `-il` in command `/trigger list` (issue #1953)

Expand Down
126 changes: 123 additions & 3 deletions src/plugins/irc/irc-ctcp.c
Expand Up @@ -427,6 +427,123 @@ irc_ctcp_reply_to_nick (struct t_irc_server *server,
weechat_arraylist_free (list_messages);
}

/*
* Compares two CTCPs in arraylist.
*/

int
irc_ctcp_list_ctcp_cmp_cb (void *data, struct t_arraylist *arraylist,
void *pointer1, void *pointer2)
{
/* make C compiler happy */
(void) data;
(void) arraylist;

return weechat_strcasecmp ((const char *)pointer1, (const char *)pointer2);
}

/*
* Frees a CTCP in arraylist.
*/

void
irc_ctcp_list_ctcp_free_cb (void *data, struct t_arraylist *arraylist,
void *pointer)
{
/* make C compiler happy */
(void) data;
(void) arraylist;

free (pointer);
}

/*
* Returns list of supported/configured CTCP replies, aggregation of these
* lists:
*
* - list of default CTCP replies (if not blocked)
* - list of CTCP replies defined in options irc.ctcp.* (if not blocked)
* - other CTCP: ACTION, DCC, PING.
*
* The list returned is a string with multiple CTCP (upper case) separated by
* spaces.
*
* Note: result must be freed after use.
*/

char *
irc_ctcp_get_supported_ctcp (struct t_irc_server *server)
{
struct t_arraylist *list_ctcp;
struct t_hdata *hdata_config_section, *hdata_config_option;
struct t_config_option *ptr_option;
const char *reply, *ptr_name;
char *ctcp_upper, **result;
int i, list_size;

list_ctcp = weechat_arraylist_new (16, 1, 0,
&irc_ctcp_list_ctcp_cmp_cb, NULL,
&irc_ctcp_list_ctcp_free_cb, NULL);
if (!list_ctcp)
return NULL;

/* add default CTCPs */
for (i = 0; irc_ctcp_default_reply[i].name; i++)
{
reply = irc_ctcp_get_reply (server, irc_ctcp_default_reply[i].name);
if (reply && reply[0])
{
weechat_arraylist_add (list_ctcp,
strdup (irc_ctcp_default_reply[i].name));
}
}

/* add customized CTCPs */
hdata_config_section = weechat_hdata_get ("config_section");
hdata_config_option = weechat_hdata_get ("config_option");
ptr_option = weechat_hdata_pointer (hdata_config_section,
irc_config_section_ctcp,
"options");
while (ptr_option)
{
ptr_name = weechat_hdata_string (hdata_config_option, ptr_option, "name");
if (ptr_name)
{
reply = irc_ctcp_get_reply (server, ptr_name);
if (reply && reply[0])
weechat_arraylist_add (list_ctcp, strdup (ptr_name));
}
ptr_option = weechat_hdata_move (hdata_config_option, ptr_option, 1);
}

/* add other CTCPs */
weechat_arraylist_add (list_ctcp, strdup ("action"));
weechat_arraylist_add (list_ctcp, strdup ("dcc"));
weechat_arraylist_add (list_ctcp, strdup ("ping"));

result = weechat_string_dyn_alloc (128);
if (result)
{
list_size = weechat_arraylist_size (list_ctcp);
for (i = 0; i < list_size; i++)
{
ctcp_upper = weechat_string_toupper (
(const char *)weechat_arraylist_get (list_ctcp, i));
if (ctcp_upper)
{
if (*result[0])
weechat_string_dyn_concat (result, " ", -1);
weechat_string_dyn_concat (result, ctcp_upper, -1);
free (ctcp_upper);
}
}
}

weechat_arraylist_free (list_ctcp);

return (result) ? weechat_string_dyn_free (result, 0) : NULL;
}

/*
* Evaluates CTCP reply format.
*
Expand Down Expand Up @@ -458,9 +575,12 @@ irc_ctcp_eval_reply (struct t_irc_server *server, const char *format)
* $clientinfo: supported CTCP, example:
* ACTION DCC CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION
*/
weechat_hashtable_set (extra_vars, "clientinfo",
"ACTION DCC CLIENTINFO FINGER PING SOURCE TIME "
"USERINFO VERSION");
info = irc_ctcp_get_supported_ctcp (server);
if (info)
{
weechat_hashtable_set (extra_vars, "clientinfo", info);
free (info);
}

info_version = weechat_info_get ("version", "");
info_version_git = weechat_info_get ("version_git", "");
Expand Down
42 changes: 41 additions & 1 deletion tests/unit/plugins/irc/test-irc-ctcp.cpp
Expand Up @@ -31,6 +31,8 @@ extern "C"
#include "src/plugins/irc/irc-config.h"
#include "src/plugins/irc/irc-ctcp.h"
#include "src/plugins/irc/irc-server.h"

extern char *irc_ctcp_get_supported_ctcp (struct t_irc_server *server);
}

TEST_GROUP(IrcCtcp)
Expand Down Expand Up @@ -109,6 +111,44 @@ TEST(IrcCtcp, IrcCtcpReplyToNick)
/* TODO: write tests */
}

/*
* Tests functions:
* irc_ctcp_get_supported_ctcp
*/

TEST(IrcCtcp, IrcCtcpGetSupportedCtcp)
{
struct t_irc_server *server;
struct t_config_option *ptr_option;
char *str;

server = irc_server_alloc ("server");
CHECK(server);

WEE_TEST_STR("ACTION CLIENTINFO DCC FINGER PING SOURCE TIME USERINFO VERSION",
irc_ctcp_get_supported_ctcp (server));

config_file_option_set_with_string ("irc.ctcp.version", "");
WEE_TEST_STR("ACTION CLIENTINFO DCC FINGER PING SOURCE TIME USERINFO",
irc_ctcp_get_supported_ctcp (server));

config_file_option_set_with_string ("irc.ctcp.time", "");
WEE_TEST_STR("ACTION CLIENTINFO DCC FINGER PING SOURCE USERINFO",
irc_ctcp_get_supported_ctcp (server));

config_file_option_set_with_string ("irc.ctcp.version", "test");
WEE_TEST_STR("ACTION CLIENTINFO DCC FINGER PING SOURCE USERINFO VERSION",
irc_ctcp_get_supported_ctcp (server));

config_file_search_with_string ("irc.ctcp.version", NULL, NULL, &ptr_option, NULL);
config_file_option_unset (ptr_option);

config_file_search_with_string ("irc.ctcp.time", NULL, NULL, &ptr_option, NULL);
config_file_option_unset (ptr_option);

irc_server_free (server);
}

/*
* Tests functions:
* irc_ctcp_eval_reply
Expand Down Expand Up @@ -139,7 +179,7 @@ TEST(IrcCtcp, IrcCtcpEvalReply)
WEE_TEST_STR("abc", irc_ctcp_eval_reply (server, "abc"));

/* ${clientinfo} */
WEE_TEST_STR("ACTION DCC CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION",
WEE_TEST_STR("ACTION CLIENTINFO DCC FINGER PING SOURCE TIME USERINFO VERSION",
irc_ctcp_eval_reply (server, "${clientinfo}"));

/* ${version} */
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/plugins/irc/test-irc-protocol.cpp
Expand Up @@ -2953,9 +2953,9 @@ TEST(IrcProtocolWithServer, privmsg)
{
CHECK_SRV("--", "CTCP requested by alice: CLIENTINFO",
"irc_privmsg,irc_ctcp,host_user@host,log1");
CHECK_SRV("--", "CTCP reply to alice: CLIENTINFO ACTION DCC "
"CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION",
"irc_privmsg,irc_ctcp,irc_ctcp_reply,self_msg,notify_none,"
CHECK_SRV("--", "CTCP reply to alice: CLIENTINFO ACTION CLIENTINFO "
"DCC FINGER PING SOURCE TIME USERINFO VERSION",
"irc_privmsg,irc_ctcp,irc_ctcp_reply,self_msg,notify_none,"
"no_highlight,log1");
}
else
Expand All @@ -2970,9 +2970,9 @@ TEST(IrcProtocolWithServer, privmsg)
RECV(":alice!user@host PRIVMSG alice :\01CLIENTINFO\01");
CHECK_SRV("--", "CTCP requested by alice: CLIENTINFO",
"irc_privmsg,irc_ctcp,host_user@host,log1");
CHECK_SRV("--", "CTCP reply to alice: CLIENTINFO ACTION DCC "
"CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION",
"irc_privmsg,irc_ctcp,irc_ctcp_reply,self_msg,notify_none,"
CHECK_SRV("--", "CTCP reply to alice: CLIENTINFO ACTION CLIENTINFO "
"DCC FINGER PING SOURCE TIME USERINFO VERSION",
"irc_privmsg,irc_ctcp,irc_ctcp_reply,self_msg,notify_none,"
"no_highlight,log1");
}

Expand Down

0 comments on commit 9237852

Please sign in to comment.