degesch: add support for IRCv3 chghost

This is somewhat similar to a nick change.
This commit is contained in:
Přemysl Eric Janouch 2021-05-30 08:06:38 +02:00
parent c75ef167f2
commit c1d69e3630
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 57 additions and 1 deletions

2
NEWS
View File

@ -7,6 +7,8 @@
* degesch: now supporting IRCv3.2 capability negotiation, including CAP DEL
* degesch: added support for IRCv3 chghost
1.1.0 (2020-10-31) "What Do You Mean By 'This Isn't Germany'?"

View File

@ -2341,7 +2341,7 @@ static struct config_schema g_config_server[] =
.type = CONFIG_ITEM_STRING_ARRAY,
.validate = config_validate_nonjunk_string,
.default_ = "\"multi-prefix,invite-notify,server-time,echo-message,"
"message-tags,away-notify,cap-notify\"" },
"message-tags,away-notify,cap-notify,chghost\"" },
{ .name = "tls",
.comment = "Whether to use TLS",
@ -4035,6 +4035,13 @@ log_full (struct app_context *ctx, struct server *s, struct buffer *buffer,
log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \
"#n is now known as #n", (old), (new_))
#define log_chghost_self(s, buffer, new_) \
log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \
"You are now #N", (new_))
#define log_chghost(s, buffer, old, new_) \
log_server ((s), (buffer), BUFFER_LINE_STATUS | BUFFER_LINE_UNIMPORTANT, \
"#N is now #N", (old), (new_))
#define log_outcoming_notice(s, buffer, who, text) \
log_server_status ((s), (buffer), "#s(#n): #m", "Notice", (who), (text))
#define log_outcoming_privmsg(s, buffer, prefixes, who, text) \
@ -6669,6 +6676,52 @@ irc_handle_cap (struct server *s, const struct irc_message *msg)
strv_free (&v);
}
static void
irc_handle_chghost (struct server *s, const struct irc_message *msg)
{
if (!msg->prefix || msg->params.len < 2)
return;
char *nickname = irc_cut_nickname (msg->prefix);
struct user *user = str_map_find (&s->irc_users, nickname);
free (nickname);
if (!user)
return;
// We don't remember the userhost part, we only log the change
char *new_prefix = xstrdup_printf ("%s!%s@%s", user->nickname,
msg->params.vector[0], msg->params.vector[1]);
if (irc_is_this_us (s, msg->prefix))
{
log_chghost_self (s, s->buffer, new_prefix);
// Log a message in all open buffers on this server
struct str_map_iter iter = str_map_iter_make (&s->irc_buffer_map);
struct buffer *buffer;
while ((buffer = str_map_iter_next (&iter)))
log_chghost_self (s, buffer, new_prefix);
}
else
{
// Log a message in any PM buffer
struct buffer *buffer =
str_map_find (&s->irc_buffer_map, user->nickname);
if (buffer)
log_chghost (s, buffer, msg->prefix, new_prefix);
// Log a message in all channels the user is in
LIST_FOR_EACH (struct user_channel, iter, user->channels)
{
buffer = str_map_find (&s->irc_buffer_map, iter->channel->name);
hard_assert (buffer != NULL);
log_chghost (s, buffer, msg->prefix, new_prefix);
}
}
free (new_prefix);
}
static void
irc_handle_error (struct server *s, const struct irc_message *msg)
{
@ -7310,6 +7363,7 @@ static struct irc_handler g_irc_handlers[] =
{ "AUTHENTICATE", irc_handle_authenticate },
{ "AWAY", irc_handle_away },
{ "CAP", irc_handle_cap },
{ "CHGHOST", irc_handle_chghost },
{ "ERROR", irc_handle_error },
{ "INVITE", irc_handle_invite },
{ "JOIN", irc_handle_join },