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 0000000..ca26170 Binary files /dev/null and b/test differ