1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Parse multiline responses to CAP LS

The parsing logic isn't too elegant because of the optional parameter
used for signaling if a response has a continuation one.
This commit is contained in:
LemonBoy 2017-10-21 11:23:44 +02:00
parent 57827ca743
commit 8c87766132

View File

@ -110,13 +110,31 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add
{ {
GSList *tmp; GSList *tmp;
GString *cmd; GString *cmd;
char *params, *evt, *list, **caps; char *params, *evt, *list, *star, **caps;
int i, caps_length, disable, avail_caps; int i, caps_length, disable, avail_caps, multiline;
params = event_get_params(args, 3, NULL, &evt, &list); params = event_get_params(args, 4, NULL, &evt, &star, &list);
if (params == NULL) if (params == NULL)
return; return;
/* Multiline responses have an additional parameter and we have to do
* this stupid dance to parse them */
if (evt[0] == 'L' && !strcmp(star, "*")) {
multiline = TRUE;
}
/* This branch covers the '*' parameter isn't present, adjust the
* parameter pointer to compensate for this */
else if (list[0] == '\0') {
multiline = FALSE;
list = star;
}
/* Malformed request, terminate the negotiation */
else {
cap_finish_negotiation(server);
g_warn_if_reached();
return;
}
/* Strip the trailing whitespaces before splitting the string, some servers send responses with /* Strip the trailing whitespaces before splitting the string, some servers send responses with
* superfluous whitespaces that g_strsplit the interprets as tokens */ * superfluous whitespaces that g_strsplit the interprets as tokens */
caps = g_strsplit(g_strchomp(list), " ", -1); caps = g_strsplit(g_strchomp(list), " ", -1);
@ -149,7 +167,10 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add
} }
/* Request the required caps, if any */ /* A multiline response is always terminated by a normal one,
* wait until we receive that one to require any CAP */
if (multiline == FALSE) {
/* No CAP has been requested */
if (server->cap_queue == NULL) { if (server->cap_queue == NULL) {
cap_finish_negotiation(server); cap_finish_negotiation(server);
} }
@ -182,6 +203,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add
g_string_free(cmd, TRUE); g_string_free(cmd, TRUE);
} }
} }
}
else if (!g_strcmp0(evt, "ACK")) { else if (!g_strcmp0(evt, "ACK")) {
int got_sasl = FALSE; int got_sasl = FALSE;
@ -214,6 +236,9 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add
for (i = 0; i < caps_length; i++) for (i = 0; i < caps_length; i++)
cap_emit_signal(server, "nak", caps[i]); cap_emit_signal(server, "nak", caps[i]);
} }
else {
g_warning("Unhandled CAP subcommand %s", evt);
}
g_strfreev(caps); g_strfreev(caps);
g_free(params); g_free(params);