Implement TIME, VERSION, MOTD, LUSERS
This commit is contained in:
		@@ -43,6 +43,7 @@
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								src/kike.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								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    },
 | 
			
		||||
 | 
			
		||||
		{ "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++)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user