Implement TIME, VERSION, MOTD, LUSERS
This commit is contained in:
parent
86e3ae951e
commit
b2a4d38e8c
|
@ -43,6 +43,7 @@
|
|||
#include <regex.h>
|
||||
#include <libgen.h>
|
||||
#include <syslog.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
|
76
src/kike.c
76
src/kike.c
|
@ -514,10 +514,13 @@ enum
|
|||
IRC_RPL_LUSERCHANNELS = 254,
|
||||
IRC_RPL_LUSERME = 255,
|
||||
|
||||
IRC_RPL_VERSION = 351,
|
||||
IRC_RPL_MOTD = 372,
|
||||
IRC_RPL_MOTDSTART = 375,
|
||||
IRC_RPL_ENDOFMOTD = 376,
|
||||
IRC_RPL_TIME = 391,
|
||||
|
||||
IRC_ERR_NOSUCHSERVER = 402,
|
||||
IRC_ERR_NOORIGIN = 409,
|
||||
IRC_ERR_UNKNOWNCOMMAND = 421,
|
||||
IRC_ERR_NOMOTD = 422,
|
||||
|
@ -542,10 +545,13 @@ static const char *g_default_replies[] =
|
|||
[IRC_RPL_LUSERCHANNELS] = "%d :channels formed",
|
||||
[IRC_RPL_LUSERME] = ":I have %d clients and %d servers",
|
||||
|
||||
[IRC_RPL_VERSION] = "%s.%d %s :%s",
|
||||
[IRC_RPL_MOTD] = ":- %s",
|
||||
[IRC_RPL_MOTDSTART] = ":- %s Message of the day - ",
|
||||
[IRC_RPL_ENDOFMOTD] = ":End of MOTD command",
|
||||
[IRC_RPL_TIME] = "%s :%s",
|
||||
|
||||
[IRC_ERR_NOSUCHSERVER] = "%s :No such server",
|
||||
[IRC_ERR_NOORIGIN] = ":No origin specified",
|
||||
[IRC_ERR_UNKNOWNCOMMAND] = "%s: Unknown command",
|
||||
[IRC_ERR_NOMOTD] = ":MOTD File is missing",
|
||||
|
@ -625,6 +631,12 @@ irc_send_lusers (struct client *c)
|
|||
}
|
||||
|
||||
static bool
|
||||
irc_is_this_me (struct server_context *ctx, const char *target)
|
||||
{
|
||||
return !fnmatch (target, ctx->server_name, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_try_finish_registration (struct client *c)
|
||||
{
|
||||
struct server_context *ctx = c->ctx;
|
||||
|
@ -737,17 +749,66 @@ irc_handle_user (const struct irc_message *msg, struct client *c)
|
|||
irc_try_finish_registration (c);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_lusers (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
|
||||
{
|
||||
irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
irc_send_lusers (c);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_motd (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
|
||||
irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
|
||||
else
|
||||
irc_send_motd (c);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_ping (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
// XXX: the RFC is pretty incomprehensible about the exact usage
|
||||
if (msg->params.len < 1)
|
||||
if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
|
||||
irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
|
||||
else if (msg->params.len < 1)
|
||||
irc_send_reply (c, IRC_ERR_NOORIGIN);
|
||||
else
|
||||
irc_send (c, ":%s PONG :%s",
|
||||
c->ctx->server_name, msg->params.vector[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_time (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
|
||||
irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
|
||||
else
|
||||
{
|
||||
char buf[32];
|
||||
time_t now = time (NULL);
|
||||
struct tm tm;
|
||||
strftime (buf, sizeof buf, "%a %b %d %Y %T", localtime_r (&now, &tm));
|
||||
irc_send_reply (c, IRC_RPL_TIME, c->ctx->server_name, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_version (const struct irc_message *msg, struct client *c)
|
||||
{
|
||||
if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
|
||||
irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
|
||||
else
|
||||
irc_send_reply (c, IRC_RPL_VERSION, PROGRAM_VERSION, g_debug_mode,
|
||||
c->ctx->server_name, PROGRAM_NAME " " PROGRAM_VERSION);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct irc_command
|
||||
|
@ -760,13 +821,18 @@ struct irc_command
|
|||
static void
|
||||
irc_register_handlers (struct server_context *ctx)
|
||||
{
|
||||
// TODO: add an index for IRC_ERR_NOSUCHSERVER validation?
|
||||
static const struct irc_command message_handlers[] =
|
||||
{
|
||||
{ "PASS", false, irc_handle_pass },
|
||||
{ "NICK", false, irc_handle_nick },
|
||||
{ "USER", false, irc_handle_user },
|
||||
{ "PASS", false, irc_handle_pass },
|
||||
{ "NICK", false, irc_handle_nick },
|
||||
{ "USER", false, irc_handle_user },
|
||||
|
||||
{ "PING", true, irc_handle_ping }
|
||||
{ "LUSERS", true, irc_handle_lusers },
|
||||
{ "MOTD", true, irc_handle_motd },
|
||||
{ "PING", true, irc_handle_ping },
|
||||
{ "TIME", true, irc_handle_time },
|
||||
{ "VERSION", true, irc_handle_version },
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
|
||||
|
|
Loading…
Reference in New Issue