aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-07-27 02:14:09 -0300
committerdequis <dx@dxzone.com.ar>2015-09-10 23:31:10 -0300
commit0ef1c9293b2055807e14e404cdf96cf7d8843170 (patch)
treebfa51613f2ea1b72dd54c99dd4b26fd466f5ecdd
parent34d16d5b4b5265990125894572a90493284358cd (diff)
Initial implementation of ircv3 capability negotiation
Mostly no-op for now. Puts registration on hold, supports the basic commands, and NAKs everything
-rw-r--r--irc.c2
-rw-r--r--irc.h2
-rw-r--r--irc_commands.c28
-rw-r--r--irc_send.c7
4 files changed, 38 insertions, 1 deletions
diff --git a/irc.c b/irc.c
index 802b2b37..74e185a8 100644
--- a/irc.c
+++ b/irc.c
@@ -726,7 +726,7 @@ void irc_desync(irc_t *irc)
int irc_check_login(irc_t *irc)
{
- if (irc->user->user && irc->user->nick) {
+ if (irc->user->user && irc->user->nick && !(irc->status & USTATUS_CAP_PENDING)) {
if (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED)) {
irc_send_num(irc, 464, ":This server is password-protected.");
return 0;
diff --git a/irc.h b/irc.h
index 8b2e4947..549f400c 100644
--- a/irc.h
+++ b/irc.h
@@ -48,6 +48,7 @@ typedef enum {
USTATUS_IDENTIFIED = 4, /* To NickServ (root). */
USTATUS_SHUTDOWN = 8, /* Now used to indicate we're shutting down.
Currently just blocks irc_vawrite(). */
+ USTATUS_CAP_PENDING = 16,
/* Not really status stuff, but other kinds of flags: For slightly
better password security, since the only way to send passwords
@@ -330,6 +331,7 @@ void irc_send_nick(irc_user_t *iu, const char *new_nick);
void irc_send_channel_user_mode_diff(irc_channel_t *ic, irc_user_t *iu,
irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags);
void irc_send_invite(irc_user_t *iu, irc_channel_t *ic);
+void irc_send_cap(irc_t *irc, char *subcommand, char *body);
/* irc_user.c */
irc_user_t *irc_user_new(irc_t *irc, const char *nick);
diff --git a/irc_commands.c b/irc_commands.c
index 98579d99..078a59ff 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -28,6 +28,33 @@
#include "help.h"
#include "ipc.h"
+static void irc_cmd_cap(irc_t *irc, char **cmd)
+{
+ if (!(irc->status & USTATUS_LOGGED_IN)) {
+ /* Put registration on hold until CAP END */
+ irc->status |= USTATUS_CAP_PENDING;
+ }
+
+ if (g_strcasecmp(cmd[1], "LS") == 0) {
+ /* gboolean irc302 = (g_strcmp0(cmd[2], "302") == 0); */
+ irc_send_cap(irc, "LS", "");
+
+ } else if (g_strcasecmp(cmd[1], "LIST") == 0) {
+ irc_send_cap(irc, "LIST", "");
+
+ } else if (g_strcasecmp(cmd[1], "REQ") == 0) {
+ irc_send_cap(irc, "NAK", cmd[2] ? : "");
+
+ } else if (g_strcasecmp(cmd[1], "END") == 0) {
+ irc->status &= ~USTATUS_CAP_PENDING;
+ irc_check_login(irc);
+
+ } else {
+ irc_send_num(irc, 410, "%s :Invalid CAP command", cmd[1]);
+ }
+
+}
+
static void irc_cmd_pass(irc_t *irc, char **cmd)
{
if (irc->status & USTATUS_LOGGED_IN) {
@@ -684,6 +711,7 @@ static void irc_cmd_rehash(irc_t *irc, char **cmd)
}
static const command_t irc_commands[] = {
+ { "cap", 1, irc_cmd_cap, 0 },
{ "pass", 1, irc_cmd_pass, 0 },
{ "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN },
{ "nick", 1, irc_cmd_nick, 0 },
diff --git a/irc_send.c b/irc_send.c
index 3da725a4..a76b5bb1 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -427,3 +427,10 @@ void irc_send_invite(irc_user_t *iu, irc_channel_t *ic)
irc_write(iu->irc, ":%s!%s@%s INVITE %s :%s",
iu->nick, iu->user, iu->host, irc->user->nick, ic->name);
}
+
+void irc_send_cap(irc_t *irc, char *subcommand, char *body)
+{
+ char *nick = irc->user->nick ? : "*";
+
+ irc_write(irc, ":%s CAP %s %s :%s", irc->root->host, nick, subcommand, body);
+}