diff options
author | dequis <dx@dxzone.com.ar> | 2015-07-28 01:48:49 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-09-10 23:31:10 -0300 |
commit | dc96e6e002f5f1cc415ff5fb5b073f4e4cd35bb0 (patch) | |
tree | 77b0344e037393cd57b34bdfdb02847737c2be6d /irc_commands.c | |
parent | 0ef1c9293b2055807e14e404cdf96cf7d8843170 (diff) |
CAP REQ
Diffstat (limited to 'irc_commands.c')
-rw-r--r-- | irc_commands.c | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/irc_commands.c b/irc_commands.c index 078a59ff..32fea023 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -28,6 +28,87 @@ #include "help.h" #include "ipc.h" +typedef guint32 cap_flag; /* 32 bits ought to be enough for anybody */ + +typedef struct _cap_info { + char *name; + cap_flag flag; +} cap_info_t; + +#define CAP_FOO (1 << 0) +#define CAP_BAR (1 << 1) + +static const cap_info_t supported_caps[] = { + {"foo", CAP_FOO}, + {"bar", CAP_BAR}, + {NULL}, +}; + +static cap_flag cap_flag_from_string(char *cap_name) { + int i; + + if (!cap_name && !cap_name[0]) { + return 0; + } + + if (cap_name[0] == '-') { + cap_name++; + } + + for (i = 0; supported_caps[i].name; i++) { + if (strcmp(supported_caps[i].name, cap_name) == 0) { + return supported_caps[i].flag; + } + } + return 0; +} + +static gboolean irc_cmd_cap_req(irc_t *irc, char *caps) +{ + int i; + char *lower = NULL; + char **split = NULL; + cap_flag new_caps = irc->caps; + + if (!caps || !caps[0]) { + return FALSE; + } + + lower = g_ascii_strdown(caps, -1); + split = g_strsplit(lower, " ", -1); + g_free(lower); + + for (i = 0; split[i]; i++) { + gboolean remove; + cap_flag flag; + + if (!split[i][0]) { + continue; /* skip empty items (consecutive spaces) */ + } + + remove = (split[i][0] == '-'); + flag = cap_flag_from_string(split[i]); + + if (!flag || (remove && !(irc->caps & flag))) { + /* unsupported cap, or removing something that isn't there */ + g_strfreev(split); + return FALSE; + } + + if (remove) { + new_caps &= ~flag; + } else { + new_caps |= flag; + } + } + + /* if we got here, set the new caps and ack */ + irc->caps = new_caps; + + g_strfreev(split); + return TRUE; +} + static void irc_cmd_cap(irc_t *irc, char **cmd) { if (!(irc->status & USTATUS_LOGGED_IN)) { @@ -37,13 +118,19 @@ static void irc_cmd_cap(irc_t *irc, char **cmd) if (g_strcasecmp(cmd[1], "LS") == 0) { /* gboolean irc302 = (g_strcmp0(cmd[2], "302") == 0); */ - irc_send_cap(irc, "LS", ""); + //char *ls = g_strjoinv(" ", (char **) supported_caps); + + irc_send_cap(irc, "LS", "foo bar"); + + //g_free(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] ? : ""); + gboolean ack = irc_cmd_cap_req(irc, cmd[2]); + + irc_send_cap(irc, ack ? "ACK" : "NAK", cmd[2] ? : ""); } else if (g_strcasecmp(cmd[1], "END") == 0) { irc->status &= ~USTATUS_CAP_PENDING; |