Add mode bits and some helper functions, rename some functions, fix a few bugs, separate tag functions

This commit is contained in:
Alex 2020-07-01 21:52:45 +02:00
parent 2fbcadfaf3
commit 313dba4e0f
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
3 changed files with 102 additions and 54 deletions

View File

@ -19,6 +19,10 @@
#ifndef UIRC_INCLUDED
#define UIRC_INCLUDED
/* Mode bitmask values */
#define MBMASK_WALLOPS 2 /* 010 */
#define MBMASK_INVIS 4 /* 100 */
typedef struct uirc_tag {
char* value;
bool clientbound;
@ -54,6 +58,10 @@ int uirc_tokenize_message(IRC_Message* irc_msg, char** line);
int uirc_assm_mesg(char* buf, IRC_Message* mesg);
unsigned int uirc_ircmd_stoi(char* str);
/* Here begin the helper functions */
IRC_Message* create_nick(char* nick);
IRC_Message* create_user(char* user, char* realname, int modes);
enum {
PASS = 10,
NICK,

View File

@ -63,15 +63,15 @@ struct tagmapping {
char* name;
IRC_Tag* assg;
};
int uirc_tokenize_message(IRC_Message* irc_msg, char** line)
{
if (*line == NULL)
return -2;
char *progr = *line, *command;
if (*progr == '@') {
char* tags;
if ((tags = strtok_r(progr, " ", &progr)) != NULL) {
if (!tagmgr(&tags, irc_msg, true))
if (!tok_tags(tags, irc_msg))
return -1;
} else
return 0;
@ -120,12 +120,12 @@ unsigned int uirc_ircmd_stoi(char* str)
}
int uirc_assm_mesg(char* buf, IRC_Message* mesg)
{
if (buf == NULL)
if (buf == NULL || mesg == NULL)
return -2;
char* pos = buf;
int cnt;
if (!tagmgr(&pos, mesg, false))
if (!assm_tags(&pos, mesg))
return -1;
if (mesg->name.nick || mesg->name.host) {
if (!assm_prefix(&pos, &mesg->name))
@ -151,11 +151,54 @@ int uirc_assm_mesg(char* buf, IRC_Message* mesg)
return -1;
return 1;
}
bool tagmgr(char** pos, IRC_Message* mesg, bool tagged)
int assm_tags(char** pos, IRC_Message* mesg)
{
const char* origpos = *pos;
char *cval, *cpos = *pos, *ctag = NULL;
char* cpos = *pos;
int cnt;
const struct tagmapping tags[] = {
{.name = "time", .assg = &mesg->tags.time},
{.name = "account", .assg = &mesg->tags.account},
{.name = "batch", .assg = &mesg->tags.batch},
{.name = "label", .assg = &mesg->tags.label},
{.name = "msgid", .assg = &mesg->tags.msgid},
{.name = "multiline-concat", .assg = &mesg->tags.multiline_concat},
{.name = "typing", .assg = &mesg->tags.typing},
{.name = "react", .assg = &mesg->tags.react},
{.name = "reply", .assg = &mesg->tags.reply}};
for (unsigned int i = 0; i < sizeof(tags) / sizeof(struct tagmapping); i++) {
if ((*tags[i].assg).present) {
if (cpos == origpos) {
if (sprintf(cpos++, "@") != 1)
return false;
} else {
if (sprintf(cpos++, ";") != 1)
return false;
}
if ((*tags[i].assg).clientbound) {
if (sprintf(cpos++, "+") != 1)
return false;
}
if ((*tags[i].assg).value != NULL)
cnt = sprintf(cpos, "%s=%s", tags[i].name, (*tags[i].assg).value);
else
cnt = sprintf(cpos, "%s", tags[i].name);
if (cnt > 0)
cpos += cnt;
else
return false;
}
}
if (*origpos == '@') {
if (sprintf(cpos++, " ") != 1)
return false;
}
*pos = cpos;
return true;
}
int tok_tags(char* msg, IRC_Message* mesg)
{
char *cval, *cpos = msg, *ctag = NULL;
bool clientbound;
const struct tagmapping tags[] = {
{.name = "time", .assg = &mesg->tags.time},
@ -167,56 +210,29 @@ bool tagmgr(char** pos, IRC_Message* mesg, bool tagged)
{.name = "typing", .assg = &mesg->tags.typing},
{.name = "react", .assg = &mesg->tags.react},
{.name = "reply", .assg = &mesg->tags.reply}};
if (tagged) {
if (*cpos == '@')
cpos++;
while ((ctag = strtok_r(NULL, "; ", &cpos)) != NULL) {
clientbound = false;
if (*ctag == '+') {
ctag++;
clientbound = true;
}
cval = strchr(ctag, '=');
if (cval != NULL)
*(cval++) = '\0';
for (unsigned int i = 0; i < sizeof(tags) / sizeof(struct tagmapping); i++) {
if (!strcmp(ctag, tags[i].name)) {
if (cval != NULL)
(*tags[i].assg).value = cval;
(*tags[i].assg).clientbound = clientbound;
(*tags[i].assg).present = true;
}
}
if (*cpos == '@')
cpos++;
while ((ctag = strtok_r(NULL, "; ", &cpos)) != NULL) {
clientbound = false;
if (*ctag == '+') {
ctag++;
clientbound = true;
}
} else {
cval = strchr(ctag, '=');
if (cval != NULL)
*(cval++) = '\0';
for (unsigned int i = 0; i < sizeof(tags) / sizeof(struct tagmapping); i++) {
if ((*tags[i].assg).value != NULL) {
if (cpos == origpos) {
if (sprintf(cpos++, "@") != 1)
return false;
} else {
if (sprintf(cpos++, ";") != 1)
return false;
}
if ((*tags[i].assg).clientbound) {
if (sprintf(cpos++, "+") != 1)
return false;
}
if ((cnt = sprintf(cpos, "%s=%s", tags[i].name, (*tags[i].assg).value)) > 0)
cpos += cnt;
else
return false;
if (!strcmp(ctag, tags[i].name)) {
if (cval != NULL)
(*tags[i].assg).value = cval;
(*tags[i].assg).clientbound = clientbound;
(*tags[i].assg).present = true;
}
}
if (*origpos == '@') {
if (sprintf(cpos++, " ") != 1)
return false;
}
*pos = cpos;
}
return true;
}
bool assm_prefix(char** str, IRC_User* usr)
int assm_prefix(char** str, IRC_User* usr)
{
int cnt;
char* pos = *str;
@ -248,7 +264,7 @@ bool assm_prefix(char** str, IRC_User* usr)
*str = pos;
return true;
}
bool tok_prefix(char* prefix, IRC_User* user)
int tok_prefix(char* prefix, IRC_User* user)
{
char* pos = (*prefix == ':') ? prefix + 1 : prefix;
if ((user->host = strchr(pos, '@')) != NULL)
@ -259,3 +275,26 @@ bool tok_prefix(char* prefix, IRC_User* user)
return false;
return true;
}
static IRC_Message imassm_mesg;
IRC_Message* create_nick(char* nick)
{
memset((void*)&imassm_mesg, '\0', sizeof(IRC_Message));
imassm_mesg.args[0] = nick;
imassm_mesg.cmd = NICK;
return &imassm_mesg;
}
IRC_Message* create_user(char* user, char* realname, int modes)
{
if (modes < 0 || modes > (MBMASK_INVIS | MBMASK_WALLOPS))
return NULL;
memset((void*)&imassm_mesg, '\0', sizeof(IRC_Message));
char local_mode[2];
sprintf(local_mode, "%i", modes);
imassm_mesg.args[0] = user;
imassm_mesg.args[1] = local_mode;
imassm_mesg.args[2] = "*";
imassm_mesg.trailing = realname;
imassm_mesg.cmd = USER;
return &imassm_mesg;
}

View File

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
bool tagmgr(char** pos, IRC_Message* mesg, bool tagged);
bool tok_prefix(char* prefix, IRC_User* user);
bool assm_prefix(char** str, IRC_User* usr);
int assm_tags(char** pos, IRC_Message* mesg);
int tok_tags(char* msg, IRC_Message* mesg);
int tok_prefix(char* prefix, IRC_User* user);
int assm_prefix(char** str, IRC_User* usr);