From 27ef5c2ea38231a5997039f7aa197366af902bae Mon Sep 17 00:00:00 2001 From: PÅ™emysl Janouch Date: Thu, 18 Jun 2015 21:21:49 +0200 Subject: degesch: fix /ban, add /unban --- degesch.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 28 deletions(-) diff --git a/degesch.c b/degesch.c index 5ad27fb..0f5eb5c 100644 --- a/degesch.c +++ b/degesch.c @@ -6253,41 +6253,22 @@ handle_command_cycle (struct app_context *ctx, char *arguments) return true; } -static bool -handle_command_channel_mode (struct app_context *ctx, char *arguments, - const char *command_name, bool adding, char mode_char) +static void +mass_channel_mode (struct server *s, const char *channel_name, + bool adding, char mode_char, struct str_vector *v) { - if (!server_command_check (ctx, command_name, true)) - return true; - - struct server *s = ctx->current_buffer->server; - char *channel_name = try_get_channel (ctx, &arguments); - if (!channel_name) - { - buffer_send_error (ctx, ctx->current_buffer, - "%s: %s", "Can't set mode", - "no channel name given and this buffer is not a channel"); - return true; - } - if (!*arguments) - return false; - - struct str_vector v; - str_vector_init (&v); - split_str_ignore_empty (arguments, ' ', &v); - size_t n; - for (size_t i = 0; i < v.len; i += n) + for (size_t i = 0; i < v->len; i += n) { struct str modes; str_init (&modes); struct str params; str_init (¶ms); - n = MIN (v.len - i, s->irc_max_modes); + n = MIN (v->len - i, s->irc_max_modes); str_append_printf (&modes, "MODE %s %c", channel_name, "-+"[adding]); for (size_t k = 0; k < n; k++) { str_append_c (&modes, mode_char); - str_append_printf (¶ms, " %s", v.vector[i + k]); + str_append_printf (¶ms, " %s", v->vector[i + k]); } irc_send (s, "%s%s", modes.str, params.str); @@ -6295,7 +6276,31 @@ handle_command_channel_mode (struct app_context *ctx, char *arguments, str_free (&modes); str_free (¶ms); } - str_vector_free (&v); +} + +static bool +handle_command_channel_mode (struct app_context *ctx, char *arguments, + const char *command_name, bool adding, char mode_char) +{ + if (!server_command_check (ctx, command_name, true)) + return true; + + struct server *s = ctx->current_buffer->server; + char *channel_name = try_get_channel (ctx, &arguments); + if (!channel_name) + buffer_send_error (ctx, ctx->current_buffer, + "%s: %s", "Can't set mode", + "no channel name given and this buffer is not a channel"); + else if (*arguments) + { + struct str_vector v; + str_vector_init (&v); + split_str_ignore_empty (arguments, ' ', &v); + mass_channel_mode (s, channel_name, adding, mode_char, &v); + str_vector_free (&v); + } + else + return false; return true; } @@ -6421,6 +6426,22 @@ handle_command_kickban (struct app_context *ctx, char *arguments) return true; } +static void +complete_user_masks (struct str_vector *v) +{ + // XXX: this may be a bit too trivial; we could map also nicknames + // to information from WHO polling or userhost-in-names + for (size_t i = 0; i < v->len; i++) + { + char *target = v->vector[i]; + if (strpbrk (target, "!@*?")) + continue; + + v->vector[i] = xstrdup_printf ("%s!*@*", target); + free (target); + } +} + static bool handle_command_ban (struct app_context *ctx, char *arguments) { @@ -6434,7 +6455,40 @@ handle_command_ban (struct app_context *ctx, char *arguments) "%s: %s", "Can't ban", "no channel name given and this buffer is not a channel"); else if (*arguments) - irc_send (s, "MODE %s +b %s", channel_name, arguments); + { + struct str_vector v; + str_vector_init (&v); + split_str_ignore_empty (arguments, ' ', &v); + complete_user_masks (&v); + mass_channel_mode (s, channel_name, true, 'b', &v); + str_vector_free (&v); + } + else + irc_send (s, "MODE %s +b", channel_name); + return true; +} + +static bool +handle_command_unban (struct app_context *ctx, char *arguments) +{ + if (!server_command_check (ctx, "unban", true)) + return true; + + struct server *s = ctx->current_buffer->server; + char *channel_name = try_get_channel (ctx, &arguments); + if (!channel_name) + buffer_send_error (ctx, ctx->current_buffer, + "%s: %s", "Can't unban", + "no channel name given and this buffer is not a channel"); + else if (*arguments) + { + struct str_vector v; + str_vector_init (&v); + split_str_ignore_empty (arguments, ' ', &v); + complete_user_masks (&v); + mass_channel_mode (s, channel_name, false, 'b', &v); + str_vector_free (&v); + } else return false; return true; @@ -6735,8 +6789,11 @@ g_command_handlers[] = "[] []", handle_command_kickban }, { "ban", "Ban user from channel", - "[] ", + "[] [...]", handle_command_ban }, + { "unban", "Unban user from channel", + "[] ...", + handle_command_unban }, { "invite", "Invite user to channel", "[] ", handle_command_invite }, -- cgit v1.2.3-70-g09d2