Finished IRC_ParseCapabilities()

This commit is contained in:
thorium1256
2026-05-12 15:32:46 +03:00
parent 1b896f3dd7
commit f0275a67bb
4 changed files with 42 additions and 60 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
build
.vscode
bbirc-debug
bbirc
bbirc
tests

View File

@@ -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;

View File

@@ -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);
}
}

BIN
test Executable file

Binary file not shown.