From f0275a67bb8d283ea9b20c8a51e1e5cd36ad9d87 Mon Sep 17 00:00:00 2001 From: thorium1256 Date: Tue, 12 May 2026 15:32:46 +0300 Subject: [PATCH] Finished IRC_ParseCapabilities() --- .gitignore | 3 +- include/IRC.h | 5 +-- src/IRC.c | 94 ++++++++++++++++++++------------------------------ test | Bin 0 -> 16176 bytes 4 files changed, 42 insertions(+), 60 deletions(-) create mode 100755 test diff --git a/.gitignore b/.gitignore index 5695706..0372fd3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build .vscode bbirc-debug -bbirc \ No newline at end of file +bbirc +tests \ No newline at end of file diff --git a/include/IRC.h b/include/IRC.h index 99d221d..2ac17bd 100644 --- a/include/IRC.h +++ b/include/IRC.h @@ -41,8 +41,9 @@ typedef struct typedef struct { - char name[32]; - char args[64]; + char capLine[96]; // A place for name and args to point to. + char *name; + char *args; } irc_capability_t; diff --git a/src/IRC.c b/src/IRC.c index 41cd83b..b47dd77 100644 --- a/src/IRC.c +++ b/src/IRC.c @@ -65,42 +65,59 @@ void IRC_ParseMessage(char *line, irc_message_t *msg) } } -// WIP +// Returns the number of capabilities found. int IRC_ParseCapabilities(char *caps, irc_capability_t *capabilities, int capsLength) { char capBak[512]; - strncpy(capBak, caps, sizeof(capBak) - 1); + strncpy(capBak, caps, sizeof(capBak) - 1); // copy the capline so we don't destroy our parameter capBak[sizeof(capBak) - 1] = 0; - memset(capabilities, 0, sizeof(irc_capability_t) * capsLength); - char *ptr = capBak; + char *tmp = ptr; int argc = 0; - - while(*ptr && argc <= capsLength) + + while(*ptr && argc < capsLength) { - // copy the cap name - strncpy(capabilities[argc].name, ptr, sizeof(capabilities[argc].name) - 1); - capabilities[argc].name[sizeof(capabilities[argc].name) - 1] = 0; - while(*ptr != ' ' && *ptr != '=') ptr++; + while(*ptr == ' ') ptr++; // skip any spaces before a capability + if(!*ptr) break; - if(*ptr == '=') + tmp = ptr; + + while(*tmp && *tmp != ' ') tmp++; + + *tmp++ = 0; + + // copy the cap line while it's untampered with + strncpy(capabilities[argc].capLine, ptr, sizeof(capabilities[argc].capLine) - 1); + capabilities[argc].capLine[sizeof(capabilities[argc].capLine) - 1] = 0; + + // ptr now points to the start of the next cap + ptr = tmp; + + // set the name pointer there + char* walker = capabilities[argc].capLine; + capabilities[argc].name = walker; + + while(*walker && *walker != '=') walker++; + + if(*walker == '=') { - *ptr++ = 0; + *walker++ = 0; + + // we don't need to move walker since it will be reinitialized in the next `while` iteration, and capLine already ends with a nullbyte + capabilities[argc].args = walker; + argc++; } - else if (*ptr == ' ') + else if (*walker == 0) { - if(strlen(capabilities[argc].name) > 0) - { - // the cap has no args - - } + // the cap has no args + capabilities[argc].args = NULL; argc++; } } - return 0; + return argc; } static void handlePing(irc_message_t *msg, irc_client_t *irc) @@ -115,45 +132,8 @@ static void handleCapabilities(irc_message_t *msg, irc_client_t *irc) // we are willing to tolerate some spaghetti... if(strncmp(msg->argv[1], "LS", 4) == 0) { - // add the supported capabilities to our client info - strncpy(irc->supportedCapabilities, msg->argv[2], sizeof irc->supportedCapabilities); - irc->supportedCapabilities[sizeof(irc->supportedCapabilities) - 1] = 0; - // try to find specific requested capabilities in there - - char* caps[64]; - int capCount = 0; + // parse the caps - char* ptr = irc->requestedCapabilities; - - // split the requested caps - while(*ptr && capCount < 64) - { - caps[capCount] = ptr; - - while(*ptr && *ptr != ' ') ptr++; - - if(*ptr) - { - *ptr++ = NUL; - while (*ptr == ' ') ptr++; - } - - capCount++; - } - - char buf[512]; - int bytesWritten = 0; - - for(int i = 0; i < capCount; i++) - { - if(strstr(irc->supportedCapabilities, caps[i]) != NULL) - { - // queue that up for one CAP REQ - bytesWritten += snprintf(buf + bytesWritten, sizeof(buf) - bytesWritten, "%s ", caps[i]); - } - } - - IRC_RequestCapabilities(buf, irc); } } diff --git a/test b/test new file mode 100755 index 0000000000000000000000000000000000000000..ca261703a37e0fc696abbc83393a1c181397e38f GIT binary patch literal 16176 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 iV@I(}L0ag6ZgW-6?b=qF%h$&5q