kike: implement DIE and KILL

This commit is contained in:
Přemysl Eric Janouch 2014-08-07 23:41:22 +02:00
parent c00ca0d29a
commit f53fa42ac3
1 changed files with 55 additions and 17 deletions

View File

@ -735,6 +735,26 @@ client_in_mask_list (const struct client *c, const struct str_vector *mask)
return result;
}
static void
irc_initiate_quit (struct server_context *ctx)
{
print_status ("shutting down");
for (struct client *iter = ctx->clients; iter; iter = iter->next)
if (!iter->closing_link)
irc_close_link (iter, "Shutting down");
ssize_t i = poller_find_by_fd (&ctx->poller, ctx->listen_fd);
if (soft_assert (i != -1))
poller_remove_at_index (&ctx->poller, i);
if (ctx->listen_fd != -1)
xclose (ctx->listen_fd);
ctx->listen_fd = -1;
ctx->quitting = true;
irc_try_finish_quit (ctx);
}
// --- Timers ------------------------------------------------------------------
static void
@ -864,6 +884,7 @@ enum
IRC_ERR_BANNEDFROMCHAN = 474,
IRC_ERR_BADCHANNELKEY = 475,
IRC_ERR_BADCHANMASK = 476,
IRC_ERR_NOPRIVILEGES = 481,
IRC_ERR_CHANOPRIVSNEEDED = 482,
IRC_ERR_USERSDONTMATCH = 502
@ -939,6 +960,7 @@ static const char *g_default_replies[] =
[IRC_ERR_BANNEDFROMCHAN] = "%s :Cannot join channel (+b)",
[IRC_ERR_BADCHANNELKEY] = "%s :Cannot join channel (+k)",
[IRC_ERR_BADCHANMASK] = "%s :Bad Channel Mask",
[IRC_ERR_NOPRIVILEGES] = ":Permission Denied- You're not an IRC operator",
[IRC_ERR_CHANOPRIVSNEEDED] = "%s :You're not channel operator",
[IRC_ERR_USERSDONTMATCH] = ":Cannot change mode for other users",
@ -1958,6 +1980,34 @@ irc_handle_ison (const struct irc_message *msg, struct client *c)
str_free (&result);
}
static void
irc_handle_kill (const struct irc_message *msg, struct client *c)
{
if (msg->params.len < 2)
RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
if (!(c->mode & IRC_USER_MODE_OPERATOR))
RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES);
struct client *target;
if (!(target = str_map_find (&c->ctx->users, msg->params.vector[0])))
RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHNICK, msg->params.vector[0]);
char *reason = xstrdup_printf ("Killed by %s: %s",
c->nickname, msg->params.vector[1]);
irc_close_link (target, reason);
free (reason);
}
static void
irc_handle_die (const struct irc_message *msg, struct client *c)
{
(void) msg;
if (!(c->mode & IRC_USER_MODE_OPERATOR))
RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES);
if (!c->ctx->quitting)
irc_initiate_quit (c->ctx);
}
// -----------------------------------------------------------------------------
struct irc_command
@ -1972,6 +2022,7 @@ irc_register_handlers (struct server_context *ctx)
{
// TODO: add an index for IRC_ERR_NOSUCHSERVER validation?
// TODO: add a minimal parameter count?
// TODO: add a field for oper-only commands?
static const struct irc_command message_handlers[] =
{
{ "PASS", false, irc_handle_pass },
@ -2002,6 +2053,9 @@ irc_register_handlers (struct server_context *ctx)
{ "WHO", true, irc_handle_who },
{ "WHOIS", true, irc_handle_whois },
{ "ISON", true, irc_handle_ison },
{ "KILL", true, irc_handle_kill },
{ "DIE", true, irc_handle_die },
};
for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
@ -2639,23 +2693,7 @@ on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx)
(void) read (fd->fd, &dummy, 1);
if (g_termination_requested && !ctx->quitting)
{
print_status ("shutting down");
for (struct client *iter = ctx->clients; iter; iter = iter->next)
if (!iter->closing_link)
irc_close_link (iter, "Shutting down");
ssize_t i = poller_find_by_fd (&ctx->poller, ctx->listen_fd);
if (soft_assert (i != -1))
poller_remove_at_index (&ctx->poller, i);
if (ctx->listen_fd != -1)
xclose (ctx->listen_fd);
ctx->listen_fd = -1;
ctx->quitting = true;
irc_try_finish_quit (ctx);
}
irc_initiate_quit (ctx);
}
static void