aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--degesch.c56
2 files changed, 57 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 1c1a528..cbc1807 100644
--- a/NEWS
+++ b/NEWS
@@ -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'?"
diff --git a/degesch.c b/degesch.c
index 2033497..0c4310b 100644
--- a/degesch.c
+++ b/degesch.c
@@ -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) \
@@ -6670,6 +6677,52 @@ irc_handle_cap (struct server *s, const struct irc_message *msg)
}
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)
{
if (msg->params.len < 1)
@@ -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 },