From 37118a4d2b70c11a76c732346975c2745d3cc4c6 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 24 May 2021 02:53:28 +0100 Subject: Implement support for the IRCv3 account-tag specification. (#2572) Co-authored-by: Patrick --- src/common/hexchat.h | 1 + src/common/inbound.c | 3 +++ src/common/proto-irc.c | 19 +++++++++++++++++++ src/common/proto-irc.h | 4 ++++ src/common/server.c | 1 + src/common/userlist.c | 12 +++++++----- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index f7cacfcc..f9ca006b 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -569,6 +569,7 @@ typedef struct server unsigned int have_idmsg:1; /* freenode's IDENTIFY-MSG */ unsigned int have_accnotify:1; /* cap account-notify */ unsigned int have_extjoin:1; /* cap extended-join */ + unsigned int have_account_tag:1; /* cap account-tag */ unsigned int have_server_time:1; /* cap server-time */ unsigned int have_sasl:1; /* SASL capability */ unsigned int have_except:1; /* ban exemptions +e */ diff --git a/src/common/inbound.c b/src/common/inbound.c index 3a26dce9..7175b2ae 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1671,6 +1671,8 @@ inbound_toggle_caps (server *serv, const char *extensions_str, gboolean enable) serv->have_server_time = enable; else if (!strcmp (extension, "away-notify")) serv->have_awaynotify = enable; + else if (!strcmp (extension, "account-tag")) + serv->have_account_tag = enable; else if (!strcmp (extension, "sasl")) { serv->have_sasl = enable; @@ -1726,6 +1728,7 @@ static const char * const supported_caps[] = { "chghost", "setname", "invite-notify", + "account-tag", /* ZNC */ "znc.in/server-time-iso", diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 57eda88a..cfe76361 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -1010,6 +1010,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], const message_tags_data *tags_data) { server *serv = sess->server; + char *account; char ip[128], nick[NICKLEN]; char *text, *ex; int len = strlen (type); @@ -1028,6 +1029,14 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], ex[0] = '!'; } + + /** Update the account for this message's source. */ + if (serv->have_account_tag) + { + account = tags_data->account && *tags_data->account ? tags_data->account : "*"; + inbound_account (serv, nick, account, tags_data); + } + if (len == 4) { guint32 t; @@ -1522,6 +1531,9 @@ handle_message_tags (server *serv, const char *tags_str, *value = '\0'; value++; + if (serv->have_account_tag && !strcmp (key, "account")) + tags_data->account = g_strdup (value); + if (serv->have_server_time && !strcmp (key, "time")) handle_message_tag_time (value, tags_data); } @@ -1619,9 +1631,16 @@ irc_inline (server *serv, char *buf, int len) } xit: + message_tags_data_free (&tags_data); g_free (pdibuf); } +void +message_tags_data_free (message_tags_data *tags_data) +{ + g_clear_pointer (&tags_data->account, g_free); +} + void proto_fill_her_up (server *serv) { diff --git a/src/common/proto-irc.h b/src/common/proto-irc.h index 6c075795..0f72c644 100644 --- a/src/common/proto-irc.h +++ b/src/common/proto-irc.h @@ -25,6 +25,7 @@ #define MESSAGE_TAGS_DATA_INIT \ { \ + NULL, /* account name */ \ (time_t)0, /* timestamp */ \ } @@ -36,9 +37,12 @@ */ typedef struct { + char *account; time_t timestamp; } message_tags_data; +void message_tags_data_free (message_tags_data *tags_data); + void proto_fill_her_up (server *serv); #endif diff --git a/src/common/server.c b/src/common/server.c index c6fa1ced..5c645eb5 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1784,6 +1784,7 @@ server_set_defaults (server *serv) serv->have_idmsg = FALSE; serv->have_accnotify = FALSE; serv->have_extjoin = FALSE; + serv->have_account_tag = FALSE; serv->have_server_time = FALSE; serv->have_sasl = FALSE; serv->have_except = FALSE; diff --git a/src/common/userlist.c b/src/common/userlist.c index 17719ff6..5f2d67f2 100644 --- a/src/common/userlist.c +++ b/src/common/userlist.c @@ -101,13 +101,15 @@ userlist_set_account (struct session *sess, char *nick, char *account) user = userlist_find (sess, nick); if (user) { - g_free (user->account); - if (strcmp (account, "*") == 0) - user->account = NULL; - else + { + g_clear_pointer (&user->account, g_free); + } else if (g_strcmp0 (user->account, account)) + { + g_free (user->account); user->account = g_strdup (account); - + } + /* gui doesnt currently reflect login status, maybe later fe_userlist_rehash (sess, user); */ } -- cgit 1.4.1