summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-06-18 21:21:49 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2015-06-18 21:21:49 +0200
commit27ef5c2ea38231a5997039f7aa197366af902bae (patch)
tree0b8e14e842b4ee93e1cca3e3d0207a235daa958e
parent782bc8533666b93f373ad95f81692531470bfc6c (diff)
downloadxK-27ef5c2ea38231a5997039f7aa197366af902bae.tar.gz
xK-27ef5c2ea38231a5997039f7aa197366af902bae.tar.xz
xK-27ef5c2ea38231a5997039f7aa197366af902bae.zip
degesch: fix /ban, add /unban
-rw-r--r--degesch.c113
1 files 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 (&params);
- 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 (&params, " %s", v.vector[i + k]);
+ str_append_printf (&params, " %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 (&params);
}
- 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[] =
"[<channel>] <user> [<reason>]",
handle_command_kickban },
{ "ban", "Ban user from channel",
- "[<channel>] <mask>",
+ "[<channel>] [<mask>...]",
handle_command_ban },
+ { "unban", "Unban user from channel",
+ "[<channel>] <mask>...",
+ handle_command_unban },
{ "invite", "Invite user to channel",
"[<channel>] <user>",
handle_command_invite },