diff --git a/degesch.c b/degesch.c index 80a0512..989a95f 100644 --- a/degesch.c +++ b/degesch.c @@ -6316,25 +6316,52 @@ handle_command_mode (struct app_context *ctx, char *arguments) if (!server_command_check (ctx, "mode", true)) return true; - // FIXME: allow usernames as well, not only channels struct server *s = ctx->current_buffer->server; // Channel names prefixed by "+" collide with mode strings, // so we just disallow specifying these channels char *channel_name = NULL; + char *nickname = NULL; + if (*arguments != '+') channel_name = maybe_cut_word (&arguments, validate_channel_name, s); - if (!channel_name && ctx->current_buffer->type == BUFFER_CHANNEL) - channel_name = ctx->current_buffer->channel->name; + if (!channel_name + && !strchr ("+-\0", *arguments)) + nickname = cut_word (&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) - irc_send (s, "MODE %s %s", channel_name, arguments); - else - irc_send (s, "MODE %s", channel_name); + if (!channel_name + && !nickname) + { + if (ctx->current_buffer->type == BUFFER_CHANNEL) + channel_name = ctx->current_buffer->channel->name; + if (ctx->current_buffer->type == BUFFER_PM) + nickname = ctx->current_buffer->user->nickname; + if (ctx->current_buffer->type == BUFFER_SERVER) + nickname = ctx->current_buffer->server->irc_user->nickname; + } + + if (channel_name) + { + if (*arguments) + // XXX: split as necessary using irc_max_modes? + irc_send (s, "MODE %s %s", channel_name, arguments); + else + irc_send (s, "MODE %s", channel_name); + return true; + } + + if (nickname) + { + if (*arguments) + irc_send (s, "MODE %s %s", nickname, arguments); + else + irc_send (s, "MODE %s", nickname); + return true; + } + + buffer_send_error (ctx, ctx->current_buffer, + "%s: %s", "Can't change mode", + "no target given and this buffer is neither a PM nor a channel"); return true; }