Finish server message parser and some work on the client message assembler, change few types and make some public as well
This commit is contained in:
parent
ca4b783af4
commit
b7a12816e8
|
@ -19,26 +19,34 @@
|
|||
#ifndef UIRC_INCLUDED
|
||||
#define UIRC_INCLUDED
|
||||
|
||||
struct irc_message {
|
||||
struct tags {
|
||||
typedef struct uirc_tag {
|
||||
char* value;
|
||||
bool clientbound;
|
||||
} IRC_Tag;
|
||||
typedef struct name {
|
||||
char* nick;
|
||||
char* user;
|
||||
char* host;
|
||||
char* realname;
|
||||
} IRC_User;
|
||||
typedef struct uirc_message {
|
||||
struct uirc_tags {
|
||||
/* See https://ircv3.net/registry#tags for more information */
|
||||
char* account;
|
||||
char* batch;
|
||||
char* label;
|
||||
char* msgid;
|
||||
char* multiline_concat; /* NOTE: Still a draft */
|
||||
char* time;
|
||||
IRC_Tag account;
|
||||
IRC_Tag batch;
|
||||
IRC_Tag label;
|
||||
IRC_Tag msgid;
|
||||
IRC_Tag multiline_concat;
|
||||
IRC_Tag time;
|
||||
IRC_Tag typing;
|
||||
IRC_Tag react;
|
||||
IRC_Tag reply;
|
||||
} tags;
|
||||
struct source {
|
||||
char* nick;
|
||||
char* user;
|
||||
char* host;
|
||||
} source;
|
||||
IRC_User name;
|
||||
signed short cmd;
|
||||
char* args[14];
|
||||
unsigned int argc;
|
||||
char* args[15]; /* 0-13 + NULL */
|
||||
char* msg;
|
||||
};
|
||||
} IRC_Message;
|
||||
|
||||
enum {
|
||||
PASS = 10,
|
||||
|
@ -209,7 +217,7 @@ enum {
|
|||
};
|
||||
extern const char* uirc_ircmd[];
|
||||
|
||||
int uirc_tokenize_message(struct irc_message* irc_msg, char* line);
|
||||
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);
|
||||
int uirc_assm_mesg(char* buf, int comm, char* dest, char* msg);
|
||||
#endif
|
||||
|
|
86
src/uirc.c
86
src/uirc.c
|
@ -58,7 +58,9 @@ const char* uirc_ircmd[] = {
|
|||
[WALLOPS] = "WALLOPS",
|
||||
[USERHOST] = "USERHOST",
|
||||
[ISON] = "ISON"};
|
||||
int uirc_tokenize_message(struct irc_message* irc_msg, char* line)
|
||||
|
||||
/* TODO: Parse client messages aswell */
|
||||
int uirc_tokenize_message(IRC_Message* irc_msg, char* line)
|
||||
{
|
||||
char *progr, *command;
|
||||
progr = line;
|
||||
|
@ -67,21 +69,33 @@ int uirc_tokenize_message(struct irc_message* irc_msg, char* line)
|
|||
char* tags;
|
||||
if ((tags = strtok_r(progr + 1, " ", &progr)) != NULL) {
|
||||
char *ctag = tags, *cval;
|
||||
bool clientbound;
|
||||
do {
|
||||
clientbound = false;
|
||||
if (*ctag == '+') {
|
||||
ctag++;
|
||||
clientbound = true;
|
||||
}
|
||||
if ((cval = strchr(ctag, '=')) != NULL) {
|
||||
*(cval++) = '\0';
|
||||
if (!strcmp(ctag, "time")) {
|
||||
irc_msg->tags.time = cval;
|
||||
} else if (!strcmp(ctag, "account")) {
|
||||
irc_msg->tags.account = cval;
|
||||
} else if (!strcmp(ctag, "batch")) {
|
||||
irc_msg->tags.batch = cval;
|
||||
} else if (!strcmp(ctag, "label")) {
|
||||
irc_msg->tags.label = cval;
|
||||
} else if (!strcmp(ctag, "msgid")) {
|
||||
irc_msg->tags.msgid = cval;
|
||||
} else if (!strcmp(ctag, "multiline-concat")) {
|
||||
irc_msg->tags.multiline_concat = cval;
|
||||
struct tagmapping {
|
||||
char* name;
|
||||
IRC_Tag* assg;
|
||||
} tags[] = {
|
||||
{.name = "time", .assg = &irc_msg->tags.time},
|
||||
{.name = "account", .assg = &irc_msg->tags.account},
|
||||
{.name = "batch", .assg = &irc_msg->tags.batch},
|
||||
{.name = "label", .assg = &irc_msg->tags.label},
|
||||
{.name = "msgid", .assg = &irc_msg->tags.msgid},
|
||||
{.name = "multiline-concat", .assg = &irc_msg->tags.multiline_concat},
|
||||
{.name = "typing", .assg = &irc_msg->tags.typing},
|
||||
{.name = "react", .assg = &irc_msg->tags.react},
|
||||
{.name = "reply", .assg = &irc_msg->tags.reply}};
|
||||
for (unsigned int i = 0; i < sizeof(tags) / sizeof(struct tagmapping); i++) {
|
||||
if (!strcmp(ctag, tags[i].name)) {
|
||||
(*tags[i].assg).value = cval;
|
||||
(*tags[i].assg).clientbound = clientbound;
|
||||
}
|
||||
}
|
||||
if ((ctag = strchr(cval, ';')) != NULL)
|
||||
*(ctag++) = '\0';
|
||||
|
@ -93,12 +107,12 @@ int uirc_tokenize_message(struct irc_message* irc_msg, char* line)
|
|||
if (*progr == ':') {
|
||||
char* prefix;
|
||||
if ((prefix = strtok_r(progr + 1, " ", &progr)) != NULL) {
|
||||
if ((irc_msg->source.host = strchr(prefix, '@')) != NULL) {
|
||||
*(irc_msg->source.host++) = '\0';
|
||||
if ((irc_msg->source.user = strchr(prefix, '!')) != NULL)
|
||||
*(irc_msg->source.user++) = '\0';
|
||||
if ((irc_msg->name.host = strchr(prefix, '@')) != NULL) {
|
||||
*(irc_msg->name.host++) = '\0';
|
||||
if ((irc_msg->name.user = strchr(prefix, '!')) != NULL)
|
||||
*(irc_msg->name.user++) = '\0';
|
||||
}
|
||||
irc_msg->source.nick = prefix; /* NOTE: This may be the server instead of a nick according to RFC2812, it is left to the library user to decide how to interpret this based on the context. */
|
||||
irc_msg->name.nick = prefix; /* NOTE: This may be the server instead of a nick according to RFC2812, it is left to the library user to decide how to interpret this based on the context. */
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
@ -119,7 +133,7 @@ int uirc_tokenize_message(struct irc_message* irc_msg, char* line)
|
|||
if ((irc_msg->args[i] = strtok_r(NULL, " ", &progr)) == NULL)
|
||||
return 0;
|
||||
}
|
||||
irc_msg->argc = i;
|
||||
irc_msg->args[i] = NULL;
|
||||
if (*progr == ':')
|
||||
++progr;
|
||||
irc_msg->msg = progr;
|
||||
|
@ -133,16 +147,38 @@ unsigned int uirc_ircmd_stoi(char* str)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
int uirc_assm_mesg(char* buf, int comm, char* dest, char* msg)
|
||||
int uirc_assm_mesg(char* buf, IRC_Message* mesg)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return -2;
|
||||
if (dest == NULL) {
|
||||
if (sprintf(buf, "%s %s\r\n", uirc_ircmd[comm], msg) < 0)
|
||||
char* pos = buf;
|
||||
int cnt;
|
||||
char* arg;
|
||||
/* TODO: Finish this
|
||||
if (mesg->tags.typing.value || mesg->tags.react.value || mesg->tags.reply.value) {
|
||||
if (sprintf(pos++, "@") != 1)
|
||||
return -1;
|
||||
} else {
|
||||
if (sprintf(buf, "%s %s %s\r\n", uirc_ircmd[comm], dest, msg) < 0)
|
||||
if (sprintf(pos++, " ") != 1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
*/
|
||||
if ((uirc_ircmd[mesg->cmd] != NULL) && ((cnt = sprintf(pos, "%s", uirc_ircmd[mesg->cmd])) > 0))
|
||||
pos += cnt;
|
||||
else
|
||||
return -1;
|
||||
for (unsigned int i = 0; i < 14 && mesg->args[i] != NULL; i++) {
|
||||
if ((cnt = sprintf(pos, " %s", mesg->args[i])) > 0)
|
||||
pos += cnt;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (mesg->cmd == PART || mesg->cmd == NOTICE) {
|
||||
if ((cnt = sprintf(pos, " %s", mesg->msg)) > 0)
|
||||
pos += cnt;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if ((cnt = sprintf(pos, "\r\n")) != 2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
|
Reference in New Issue