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

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ build
.vscode .vscode
bbirc-debug bbirc-debug
bbirc bbirc
tests

View File

@@ -41,8 +41,9 @@ typedef struct
typedef struct typedef struct
{ {
char name[32]; char capLine[96]; // A place for name and args to point to.
char args[64]; char *name;
char *args;
} irc_capability_t; } 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) int IRC_ParseCapabilities(char *caps, irc_capability_t *capabilities, int capsLength)
{ {
char capBak[512]; 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; capBak[sizeof(capBak) - 1] = 0;
memset(capabilities, 0, sizeof(irc_capability_t) * capsLength);
char *ptr = capBak; char *ptr = capBak;
char *tmp = ptr;
int argc = 0; int argc = 0;
while(*ptr && argc <= capsLength) while(*ptr && argc < capsLength)
{ {
// copy the cap name while(*ptr == ' ') ptr++; // skip any spaces before a capability
strncpy(capabilities[argc].name, ptr, sizeof(capabilities[argc].name) - 1); if(!*ptr) break;
capabilities[argc].name[sizeof(capabilities[argc].name) - 1] = 0;
while(*ptr != ' ' && *ptr != '=') ptr++;
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
{ capabilities[argc].args = NULL;
// the cap has no args
}
argc++; argc++;
} }
} }
return 0; return argc;
} }
static void handlePing(irc_message_t *msg, irc_client_t *irc) 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... // we are willing to tolerate some spaghetti...
if(strncmp(msg->argv[1], "LS", 4) == 0) if(strncmp(msg->argv[1], "LS", 4) == 0)
{ {
// add the supported capabilities to our client info // parse the caps
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;
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.