diff --git a/NEWS b/NEWS index d0ac5aa..0d126ec 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Unreleased + + * xC: made it show WALLOPS messages, as PRIVMSG for the server buffer + + * xD: implemented WALLOPS, choosing to make it target even non-operators + + 1.5.0 (2021-12-21) "The Show Must Go On" * xC: made it possible to pass the cursor position to external editors, diff --git a/xC.c b/xC.c index a5a8070..909675d 100644 --- a/xC.c +++ b/xC.c @@ -7488,6 +7488,16 @@ irc_handle_topic (struct server *s, const struct irc_message *msg) } } +static void +irc_handle_wallops (struct server *s, const struct irc_message *msg) +{ + if (!msg->prefix || msg->params.len < 1) + return; + + const char *message = msg->params.vector[0]; + log_server (s, s->buffer, 0, "<#n> #m", msg->prefix, message); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static struct irc_handler g_irc_handlers[] = @@ -7511,6 +7521,7 @@ static struct irc_handler g_irc_handlers[] = { "QUIT", irc_handle_quit }, { "TAGMSG", irc_handle_tagmsg }, { "TOPIC", irc_handle_topic }, + { "WALLOPS", irc_handle_wallops }, }; static bool diff --git a/xD.c b/xD.c index 8d24cef..4ec365a 100644 --- a/xD.c +++ b/xD.c @@ -2932,6 +2932,29 @@ irc_handle_links (const struct irc_message *msg, struct client *c) irc_send_reply (c, IRC_RPL_ENDOFLINKS, mask); } +static void +irc_handle_wallops (const struct irc_message *msg, struct client *c) +{ + if (msg->params.len < 1) + RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command); + if (!(c->mode & IRC_USER_MODE_OPERATOR)) + RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES); + + const char *message = msg->params.vector[0]; + + // Our interpretation: anonymize the sender, + // and target all users who want to receive these messages + struct str_map_iter iter = str_map_iter_make (&c->ctx->users); + struct client *target; + while ((target = str_map_iter_next (&iter))) + { + if (target != c && !(target->mode & IRC_USER_MODE_RX_WALLOPS)) + continue; + + client_send (target, ":%s WALLOPS :%s", c->ctx->server_name, message); + } +} + static void irc_handle_kill (const struct irc_message *msg, struct client *c) { @@ -2994,6 +3017,7 @@ irc_register_handlers (struct server_context *ctx) { "ADMIN", true, irc_handle_admin, 0, 0 }, { "STATS", true, irc_handle_stats, 0, 0 }, { "LINKS", true, irc_handle_links, 0, 0 }, + { "WALLOPS", true, irc_handle_wallops, 0, 0 }, { "MODE", true, irc_handle_mode, 0, 0 }, { "PRIVMSG", true, irc_handle_privmsg, 0, 0 },