From eb8263e0f5c4daaf51dde4b091a261b0502145c9 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 7 Jul 2020 23:17:28 +0200 Subject: [PATCH] Uniform function namespace, add includes where needed, add IRC_Tags struct, shorten msg tokenizer, return assembled lenghts --- include/helpers.h | 92 ++++++++-------- include/structs.h | 30 +++--- include/uirc.h | 21 ++-- src/helpers.c | 93 ++++++++-------- src/uirc.c | 264 +++++++++++++++++++++++----------------------- src/uirc.h | 4 - 6 files changed, 259 insertions(+), 245 deletions(-) diff --git a/include/helpers.h b/include/helpers.h index 315783f..159f0ba 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -1,50 +1,52 @@ +#include "structs.h" +#include #ifdef UIRC_HELPERS #ifndef _UIRC_HELPERS_INCLUDED #define _UIRC_HELPERS_INCLUDED -extern IRC_Message* Assemble_NICK(const char* nick); -extern IRC_Message* Assemble_USER(const char* user, const char* realname, const int modes); -extern IRC_Message* Assemble_PASS(const char* password); -extern IRC_Message* Assemble_OPER(const char* name, const char* password); -extern IRC_Message* Assemble_MODE(const char* nick, const char* modes, const char* modeparams); -extern IRC_Message* Assemble_SERVICE(const char* nickname, const char* distribution, const char* type, const char* info); -extern IRC_Message* Assemble_QUIT(const char* mesg, const IRC_User* user); -extern IRC_Message* Assemble_SQUIT(const char* server, const char* comment, const IRC_User* user); -extern IRC_Message* Assemble_JOIN(const char* channels, const char* keys, const IRC_User* user); -extern IRC_Message* Assemble_PART(const char* channel, const char* message, const IRC_User* user); -extern IRC_Message* Assemble_TOPIC(const char* channel, const char* topic, const IRC_User* user); -extern IRC_Message* Assemble_NAMES(const char* channels, const char* target); -extern IRC_Message* Assemble_LIST(const char* channels, const char* target); -extern IRC_Message* Assemble_INVITE(const char* nick, const char* channel, const IRC_User* user); -extern IRC_Message* Assemble_KICK(const char* channels, const char* users, const char* comment, const IRC_User* user); -extern IRC_Message* Assemble_PRIVMSG(const char* target, const char* message, const IRC_User* source); -extern IRC_Message* Assemble_NOTICE(const char* target, const char* text, const IRC_User* user); -extern IRC_Message* Assemble_MOTD(const char* target); -extern IRC_Message* Assemble_LUSERS(const char* mask, const char* target); -extern IRC_Message* Assemble_VERSION(const char* target); -extern IRC_Message* Assemble_STATS(const char* query, const char* target); -extern IRC_Message* Assemble_LINKS(const char* remoteserv, const char* servmask); -extern IRC_Message* Assemble_TIME(const char* target); -extern IRC_Message* Assemble_CONNECT(const char* target, const char* port, const char* remote); -extern IRC_Message* Assemble_TRACE(const char* target); -extern IRC_Message* Assemble_ADMIN(const char* target); -extern IRC_Message* Assemble_INFO(const char* target); -extern IRC_Message* Assemble_SERVLIST(const char* mask, const char* type); -extern IRC_Message* Assemble_SQUERY(const char* servicename, const char* text); -extern IRC_Message* Assemble_WHO(const char* mask, const bool oper); -extern IRC_Message* Assemble_WHOIS(const char* target, const char* mask); -extern IRC_Message* Assemble_WHOWAS(const char* nick, const char* count, const char* target); -extern IRC_Message* Assemble_KILL(const char* nick, const char* comment); -extern IRC_Message* Assemble_PING(const char* source, const char* target); -extern IRC_Message* Assemble_PONG(const char* source, const char* target); -extern IRC_Message* Assemble_ERROR(const char* message); -extern IRC_Message* Assemble_AWAY(const char* mesg); -extern IRC_Message* Assemble_REHASH(void); -extern IRC_Message* Assemble_DIE(void); -extern IRC_Message* Assemble_RESTART(void); -extern IRC_Message* Assemble_SUMMON(const char* user, const char* target, const char* channel); -extern IRC_Message* Assemble_USERS(const char* target); -extern IRC_Message* Assemble_WALLOPS(const char* text, const IRC_User* source); -extern IRC_Message* Assemble_USERHOST(const char* users[], const IRC_User* source); -extern IRC_Message* Assemble_ISON(const char* users[]); +extern IRC_Message* Assm_cmd_NICK(const char* nick); +extern IRC_Message* Assm_cmd_USER(const char* user, const char* realname, const int modes); +extern IRC_Message* Assm_cmd_PASS(const char* password); +extern IRC_Message* Assm_cmd_OPER(const char* name, const char* password); +extern IRC_Message* Assm_cmd_MODE(const char* nick, const char* modes, const char* modeparams); +extern IRC_Message* Assm_cmd_SERVICE(const char* nickname, const char* distribution, const char* type, const char* info); +extern IRC_Message* Assm_cmd_QUIT(const char* mesg, const IRC_User* user); +extern IRC_Message* Assm_cmd_SQUIT(const char* server, const char* comment, const IRC_User* user); +extern IRC_Message* Assm_cmd_JOIN(const char* channels, const char* keys, const IRC_User* user); +extern IRC_Message* Assm_cmd_PART(const char* channel, const char* message, const IRC_User* user); +extern IRC_Message* Assm_cmd_TOPIC(const char* channel, const char* topic, const IRC_User* user); +extern IRC_Message* Assm_cmd_NAMES(const char* channels, const char* target); +extern IRC_Message* Assm_cmd_LIST(const char* channels, const char* target); +extern IRC_Message* Assm_cmd_INVITE(const char* nick, const char* channel, const IRC_User* user); +extern IRC_Message* Assm_cmd_KICK(const char* channels, const char* users, const char* comment, const IRC_User* user); +extern IRC_Message* Assm_cmd_PRIVMSG(const char* target, const char* message, const IRC_User* source); +extern IRC_Message* Assm_cmd_NOTICE(const char* target, const char* text, const IRC_User* user); +extern IRC_Message* Assm_cmd_MOTD(const char* target); +extern IRC_Message* Assm_cmd_LUSERS(const char* mask, const char* target); +extern IRC_Message* Assm_cmd_VERSION(const char* target); +extern IRC_Message* Assm_cmd_STATS(const char* query, const char* target); +extern IRC_Message* Assm_cmd_LINKS(const char* remoteserv, const char* servmask); +extern IRC_Message* Assm_cmd_TIME(const char* target); +extern IRC_Message* Assm_cmd_CONNECT(const char* target, const char* port, const char* remote); +extern IRC_Message* Assm_cmd_TRACE(const char* target); +extern IRC_Message* Assm_cmd_ADMIN(const char* target); +extern IRC_Message* Assm_cmd_INFO(const char* target); +extern IRC_Message* Assm_cmd_SERVLIST(const char* mask, const char* type); +extern IRC_Message* Assm_cmd_SQUERY(const char* servicename, const char* text); +extern IRC_Message* Assm_cmd_WHO(const char* mask, const bool oper); +extern IRC_Message* Assm_cmd_WHOIS(const char* target, const char* mask); +extern IRC_Message* Assm_cmd_WHOWAS(const char* nick, const char* count, const char* target); +extern IRC_Message* Assm_cmd_KILL(const char* nick, const char* comment); +extern IRC_Message* Assm_cmd_PING(const char* source, const char* target); +extern IRC_Message* Assm_cmd_PONG(const char* source, const char* target); +extern IRC_Message* Assm_cmd_ERROR(const char* message); +extern IRC_Message* Assm_cmd_AWAY(const char* mesg); +extern IRC_Message* Assm_cmd_REHASH(void); +extern IRC_Message* Assm_cmd_DIE(void); +extern IRC_Message* Assm_cmd_RESTART(void); +extern IRC_Message* Assm_cmd_SUMMON(const char* user, const char* target, const char* channel); +extern IRC_Message* Assm_cmd_USERS(const char* target); +extern IRC_Message* Assm_cmd_WALLOPS(const char* text, const IRC_User* source); +extern IRC_Message* Assm_cmd_USERHOST(const char* users[], const IRC_User* source); +extern IRC_Message* Assm_cmd_ISON(const char* users[]); #endif #endif diff --git a/include/structs.h b/include/structs.h index f2565a5..282f526 100644 --- a/include/structs.h +++ b/include/structs.h @@ -1,3 +1,4 @@ +#include #ifndef _UIRC_STRUCTS_INCLUDED #define _UIRC_STRUCTS_INCLUDED typedef struct uirc_tag { @@ -9,21 +10,26 @@ typedef struct name { const char* nick; const char* user; const char* host; + const char* orig; const char* real; } IRC_User; +/* This is how a full user source would look like + * NOTE: 'real (Real name)' may only be used in special contexts other than communication. + * nick!user%orig@host */ +typedef struct uirc_tags { + /* See https://ircv3.net/registry#tags for more information */ + 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; +} IRC_Tags; typedef struct uirc_message { - struct uirc_tags { - /* See https://ircv3.net/registry#tags for more information */ - 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; + IRC_Tags tags; IRC_User name; signed short cmd; const char* args[15]; /* 0-13 + NULL */ diff --git a/include/uirc.h b/include/uirc.h index b8f36b2..6ae6c08 100644 --- a/include/uirc.h +++ b/include/uirc.h @@ -15,14 +15,23 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ -#include -#include "structs.h" -#include "mappings.h" #include "helpers.h" +#include "mappings.h" +#include "structs.h" +#include #ifndef UIRC_INCLUDED #define UIRC_INCLUDED extern const char* const uirc_ircmd[]; -extern int uirc_tokenize_message(IRC_Message* irc_msg, char** line); -extern int uirc_assm_mesg(char* buf, IRC_Message* mesg); -extern unsigned int uirc_ircmd_stoi(char* str); + +/* Tokenizers: They take a string in and point their struct element pointers at tokens and end tokens with '\0' */ +extern signed int Tok_mesg(char* str, IRC_Message* out); +extern signed int Tok_tags(char* str, IRC_Tags* out); +extern signed int Tok_user(char* str, IRC_User* out, bool useorig); + +/* Assemblers: They return the amount of bytes written and write directly at buf */ +extern signed int Assm_mesg(char* buf, IRC_Message* in); +extern signed int Assm_tags(char* buf, IRC_Tags* in); +extern signed int Assm_user(char* buf, IRC_User* in, bool useorig); + +extern signed int Ircmd_stoi(char* str); #endif diff --git a/src/helpers.c b/src/helpers.c index 7e6d5bf..1f9f8bb 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -1,6 +1,7 @@ #include "../include/uirc.h" -#include +#include #include +#include #include static IRC_Message imassm_mesg; const char* const RESERVED = "*"; @@ -8,7 +9,7 @@ void clear_assm(void) { memset((void*)&imassm_mesg, '\0', sizeof(IRC_Message)); } -IRC_Message* Assemble_NICK(const char* nick) +IRC_Message* Assm_cmd_NICK(const char* nick) { if (nick == NULL) return NULL; @@ -17,7 +18,7 @@ IRC_Message* Assemble_NICK(const char* nick) imassm_mesg.cmd = NICK; return &imassm_mesg; } -IRC_Message* Assemble_USER(const char* user, const char* realname, const int modes) +IRC_Message* Assm_cmd_USER(const char* user, const char* realname, const int modes) { if (user == NULL || modes < 0 || modes > (MBMASK_INVIS | MBMASK_WALLOPS)) return NULL; @@ -31,7 +32,7 @@ IRC_Message* Assemble_USER(const char* user, const char* realname, const int mod imassm_mesg.cmd = USER; return &imassm_mesg; } -IRC_Message* Assemble_PASS(const char* password) +IRC_Message* Assm_cmd_PASS(const char* password) { if (password == NULL) return NULL; @@ -40,7 +41,7 @@ IRC_Message* Assemble_PASS(const char* password) imassm_mesg.cmd = PASS; return &imassm_mesg; } -IRC_Message* Assemble_OPER(const char* name, const char* password) +IRC_Message* Assm_cmd_OPER(const char* name, const char* password) { if (name == NULL || password == NULL) return NULL; @@ -50,7 +51,7 @@ IRC_Message* Assemble_OPER(const char* name, const char* password) imassm_mesg.cmd = OPER; return &imassm_mesg; } -IRC_Message* Assemble_MODE(const char* nick, const char* modes, const char* modeparams) +IRC_Message* Assm_cmd_MODE(const char* nick, const char* modes, const char* modeparams) { if (nick == NULL) return NULL; @@ -61,7 +62,7 @@ IRC_Message* Assemble_MODE(const char* nick, const char* modes, const char* mode imassm_mesg.cmd = MODE; return &imassm_mesg; } -IRC_Message* Assemble_SERVICE(const char* nickname, const char* distribution, const char* type, const char* info) +IRC_Message* Assm_cmd_SERVICE(const char* nickname, const char* distribution, const char* type, const char* info) { if (nickname == NULL || distribution == NULL || type == NULL || info == NULL) return NULL; @@ -75,7 +76,7 @@ IRC_Message* Assemble_SERVICE(const char* nickname, const char* distribution, co imassm_mesg.cmd = SERVICE; return &imassm_mesg; } -IRC_Message* Assemble_QUIT(const char* mesg, const IRC_User* user) +IRC_Message* Assm_cmd_QUIT(const char* mesg, const IRC_User* user) { clear_assm(); imassm_mesg.trailing = mesg; @@ -84,7 +85,7 @@ IRC_Message* Assemble_QUIT(const char* mesg, const IRC_User* user) imassm_mesg.cmd = QUIT; return &imassm_mesg; } -IRC_Message* Assemble_SQUIT(const char* server, const char* comment, const IRC_User* user) +IRC_Message* Assm_cmd_SQUIT(const char* server, const char* comment, const IRC_User* user) { if (server == NULL || comment == NULL) return NULL; @@ -96,7 +97,7 @@ IRC_Message* Assemble_SQUIT(const char* server, const char* comment, const IRC_U imassm_mesg.cmd = SQUIT; return &imassm_mesg; } -IRC_Message* Assemble_JOIN(const char* channels, const char* keys, const IRC_User* user) +IRC_Message* Assm_cmd_JOIN(const char* channels, const char* keys, const IRC_User* user) { if (channels == NULL) return NULL; @@ -108,7 +109,7 @@ IRC_Message* Assemble_JOIN(const char* channels, const char* keys, const IRC_Use imassm_mesg.cmd = JOIN; return &imassm_mesg; } -IRC_Message* Assemble_PART(const char* channel, const char* message, const IRC_User* user) +IRC_Message* Assm_cmd_PART(const char* channel, const char* message, const IRC_User* user) { if (channel == NULL) return NULL; @@ -123,7 +124,7 @@ IRC_Message* Assemble_PART(const char* channel, const char* message, const IRC_U /* NOTE: Use a non-NULL address (pointing at a "\0") as the topic to clear it and use a NULL address to check it * Blame the protocol, not this >:C */ -IRC_Message* Assemble_TOPIC(const char* channel, const char* topic, const IRC_User* user) +IRC_Message* Assm_cmd_TOPIC(const char* channel, const char* topic, const IRC_User* user) { if (channel == NULL) return NULL; @@ -135,7 +136,7 @@ IRC_Message* Assemble_TOPIC(const char* channel, const char* topic, const IRC_Us imassm_mesg.cmd = TOPIC; return &imassm_mesg; } -IRC_Message* Assemble_NAMES(const char* channels, const char* target) +IRC_Message* Assm_cmd_NAMES(const char* channels, const char* target) { if (channels == NULL && target != NULL) return NULL; @@ -145,7 +146,7 @@ IRC_Message* Assemble_NAMES(const char* channels, const char* target) imassm_mesg.cmd = NAMES; return &imassm_mesg; } -IRC_Message* Assemble_LIST(const char* channels, const char* target) +IRC_Message* Assm_cmd_LIST(const char* channels, const char* target) { if (channels == NULL && target != NULL) return NULL; @@ -155,7 +156,7 @@ IRC_Message* Assemble_LIST(const char* channels, const char* target) imassm_mesg.cmd = LIST; return &imassm_mesg; } -IRC_Message* Assemble_INVITE(const char* nick, const char* channel, const IRC_User* user) +IRC_Message* Assm_cmd_INVITE(const char* nick, const char* channel, const IRC_User* user) { if (nick == NULL || channel == NULL) return NULL; @@ -167,7 +168,7 @@ IRC_Message* Assemble_INVITE(const char* nick, const char* channel, const IRC_Us imassm_mesg.cmd = INVITE; return &imassm_mesg; } -IRC_Message* Assemble_KICK(const char* channels, const char* users, const char* comment, const IRC_User* user) +IRC_Message* Assm_cmd_KICK(const char* channels, const char* users, const char* comment, const IRC_User* user) { if (channels == NULL || users == NULL) return NULL; @@ -180,7 +181,7 @@ IRC_Message* Assemble_KICK(const char* channels, const char* users, const char* imassm_mesg.cmd = KICK; return &imassm_mesg; } -IRC_Message* Assemble_PRIVMSG(const char* target, const char* message, const IRC_User* source) +IRC_Message* Assm_cmd_PRIVMSG(const char* target, const char* message, const IRC_User* source) { if (target == NULL || message == NULL) return NULL; @@ -192,7 +193,7 @@ IRC_Message* Assemble_PRIVMSG(const char* target, const char* message, const IRC imassm_mesg.cmd = PRIVMSG; return &imassm_mesg; } -IRC_Message* Assemble_NOTICE(const char* target, const char* text, const IRC_User* user) +IRC_Message* Assm_cmd_NOTICE(const char* target, const char* text, const IRC_User* user) { if (target == NULL || text == NULL) return NULL; @@ -204,14 +205,14 @@ IRC_Message* Assemble_NOTICE(const char* target, const char* text, const IRC_Use imassm_mesg.cmd = NOTICE; return &imassm_mesg; } -IRC_Message* Assemble_MOTD(const char* target) +IRC_Message* Assm_cmd_MOTD(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = MOTD; return &imassm_mesg; } -IRC_Message* Assemble_LUSERS(const char* mask, const char* target) +IRC_Message* Assm_cmd_LUSERS(const char* mask, const char* target) { if (mask == NULL && target != NULL) return NULL; @@ -221,14 +222,14 @@ IRC_Message* Assemble_LUSERS(const char* mask, const char* target) imassm_mesg.cmd = LUSERS; return &imassm_mesg; } -IRC_Message* Assemble_VERSION(const char* target) +IRC_Message* Assm_cmd_VERSION(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = VERSION; return &imassm_mesg; } -IRC_Message* Assemble_STATS(const char* query, const char* target) +IRC_Message* Assm_cmd_STATS(const char* query, const char* target) { if (query == NULL && target != NULL) return NULL; @@ -238,7 +239,7 @@ IRC_Message* Assemble_STATS(const char* query, const char* target) imassm_mesg.cmd = STATS; return &imassm_mesg; } -IRC_Message* Assemble_LINKS(const char* remoteserv, const char* servmask) +IRC_Message* Assm_cmd_LINKS(const char* remoteserv, const char* servmask) { if (remoteserv != NULL && servmask == NULL) return NULL; @@ -248,14 +249,14 @@ IRC_Message* Assemble_LINKS(const char* remoteserv, const char* servmask) imassm_mesg.cmd = LINKS; return &imassm_mesg; } -IRC_Message* Assemble_TIME(const char* target) +IRC_Message* Assm_cmd_TIME(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = TIME; return &imassm_mesg; } -IRC_Message* Assemble_CONNECT(const char* target, const char* port, const char* remote) +IRC_Message* Assm_cmd_CONNECT(const char* target, const char* port, const char* remote) { if (target == NULL || port == NULL) return NULL; @@ -266,28 +267,28 @@ IRC_Message* Assemble_CONNECT(const char* target, const char* port, const char* imassm_mesg.cmd = CONNECT; return &imassm_mesg; } -IRC_Message* Assemble_TRACE(const char* target) +IRC_Message* Assm_cmd_TRACE(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = TRACE; return &imassm_mesg; } -IRC_Message* Assemble_ADMIN(const char* target) +IRC_Message* Assm_cmd_ADMIN(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = ADMIN; return &imassm_mesg; } -IRC_Message* Assemble_INFO(const char* target) +IRC_Message* Assm_cmd_INFO(const char* target) { clear_assm(); imassm_mesg.args[0] = target; imassm_mesg.cmd = INFO; return &imassm_mesg; } -IRC_Message* Assemble_SERVLIST(const char* mask, const char* type) +IRC_Message* Assm_cmd_SERVLIST(const char* mask, const char* type) { if (type != NULL && mask == NULL) return NULL; @@ -297,7 +298,7 @@ IRC_Message* Assemble_SERVLIST(const char* mask, const char* type) imassm_mesg.cmd = SERVLIST; return &imassm_mesg; } -IRC_Message* Assemble_SQUERY(const char* servicename, const char* text) +IRC_Message* Assm_cmd_SQUERY(const char* servicename, const char* text) { if (servicename == NULL || text == NULL) return NULL; @@ -307,7 +308,7 @@ IRC_Message* Assemble_SQUERY(const char* servicename, const char* text) imassm_mesg.cmd = SQUERY; return &imassm_mesg; } -IRC_Message* Assemble_WHO(const char* mask, const bool oper) +IRC_Message* Assm_cmd_WHO(const char* mask, const bool oper) { static const char* const operator= "o"; if (oper && mask == NULL) @@ -318,7 +319,7 @@ IRC_Message* Assemble_WHO(const char* mask, const bool oper) imassm_mesg.cmd = WHO; return &imassm_mesg; } -IRC_Message* Assemble_WHOIS(const char* target, const char* mask) +IRC_Message* Assm_cmd_WHOIS(const char* target, const char* mask) { if (mask == NULL) return NULL; @@ -328,7 +329,7 @@ IRC_Message* Assemble_WHOIS(const char* target, const char* mask) imassm_mesg.cmd = WHOIS; return &imassm_mesg; } -IRC_Message* Assemble_WHOWAS(const char* nick, const char* count, const char* target) +IRC_Message* Assm_cmd_WHOWAS(const char* nick, const char* count, const char* target) { if (nick == NULL || (target != NULL && count == NULL)) return NULL; @@ -339,7 +340,7 @@ IRC_Message* Assemble_WHOWAS(const char* nick, const char* count, const char* ta imassm_mesg.cmd = WHOWAS; return &imassm_mesg; } -IRC_Message* Assemble_KILL(const char* nick, const char* comment) +IRC_Message* Assm_cmd_KILL(const char* nick, const char* comment) { if (nick == NULL || comment == NULL) return NULL; @@ -352,7 +353,7 @@ IRC_Message* Assemble_KILL(const char* nick, const char* comment) /* NOTE: This is what implementation you have to live with * I would've just used the prefix to set the source but whatever */ -IRC_Message* Assemble_PING(const char* source, const char* target) +IRC_Message* Assm_cmd_PING(const char* source, const char* target) { if (source == NULL && target == NULL) return NULL; @@ -363,7 +364,7 @@ IRC_Message* Assemble_PING(const char* source, const char* target) imassm_mesg.cmd = PING; return &imassm_mesg; } -IRC_Message* Assemble_PONG(const char* source, const char* target) +IRC_Message* Assm_cmd_PONG(const char* source, const char* target) { if (source == NULL) return NULL; @@ -373,7 +374,7 @@ IRC_Message* Assemble_PONG(const char* source, const char* target) imassm_mesg.cmd = PONG; return &imassm_mesg; } -IRC_Message* Assemble_ERROR(const char* message) +IRC_Message* Assm_cmd_ERROR(const char* message) { if (message == NULL) return NULL; @@ -382,32 +383,32 @@ IRC_Message* Assemble_ERROR(const char* message) imassm_mesg.cmd = ERROR; return &imassm_mesg; } -IRC_Message* Assemble_AWAY(const char* mesg) +IRC_Message* Assm_cmd_AWAY(const char* mesg) { clear_assm(); imassm_mesg.trailing = mesg; imassm_mesg.cmd = AWAY; return &imassm_mesg; } -IRC_Message* Assemble_REHASH(void) +IRC_Message* Assm_cmd_REHASH(void) { clear_assm(); imassm_mesg.cmd = REHASH; return &imassm_mesg; } -IRC_Message* Assemble_DIE(void) +IRC_Message* Assm_cmd_DIE(void) { clear_assm(); imassm_mesg.cmd = DIE; return &imassm_mesg; } -IRC_Message* Assemble_RESTART(void) +IRC_Message* Assm_cmd_RESTART(void) { clear_assm(); imassm_mesg.cmd = RESTART; return &imassm_mesg; } -IRC_Message* Assemble_SUMMON(const char* user, const char* target, const char* channel) +IRC_Message* Assm_cmd_SUMMON(const char* user, const char* target, const char* channel) { if (user == NULL || (channel != NULL && target == NULL)) return NULL; @@ -418,7 +419,7 @@ IRC_Message* Assemble_SUMMON(const char* user, const char* target, const char* c imassm_mesg.cmd = SUMMON; return &imassm_mesg; } -IRC_Message* Assemble_USERS(const char* target) +IRC_Message* Assm_cmd_USERS(const char* target) { if (target == NULL) return NULL; @@ -427,7 +428,7 @@ IRC_Message* Assemble_USERS(const char* target) imassm_mesg.cmd = USERS; return &imassm_mesg; } -IRC_Message* Assemble_WALLOPS(const char* text, const IRC_User* source) +IRC_Message* Assm_cmd_WALLOPS(const char* text, const IRC_User* source) { if (text == NULL) return NULL; @@ -438,7 +439,7 @@ IRC_Message* Assemble_WALLOPS(const char* text, const IRC_User* source) imassm_mesg.cmd = WALLOPS; return &imassm_mesg; } -IRC_Message* Assemble_USERHOST(const char* users[], const IRC_User* source) +IRC_Message* Assm_cmd_USERHOST(const char* users[], const IRC_User* source) { if (users[0] == NULL) return NULL; @@ -452,7 +453,7 @@ IRC_Message* Assemble_USERHOST(const char* users[], const IRC_User* source) return &imassm_mesg; } /* NOTE: Limited to 14 nicks per command */ -IRC_Message* Assemble_ISON(const char* users[]) +IRC_Message* Assm_cmd_ISON(const char* users[]) { if (users[0] == NULL) return NULL; diff --git a/src/uirc.c b/src/uirc.c index abbd596..7628a34 100644 --- a/src/uirc.c +++ b/src/uirc.c @@ -69,55 +69,7 @@ struct tagmapping { const char* name; IRC_Tag* assg; }; -int uirc_tokenize_message(IRC_Message* irc_msg, char** line) -{ - if (*line == NULL || irc_msg == NULL) - return ERR_UIRC_NULL_ARGS; - int ret; - char *progr = *line, *command; - if (*progr == '@') { - char* tags; - if ((tags = strtok_r(progr, " ", &progr)) != NULL) { - if ((ret = tok_tags(tags, irc_msg)) < 0) - return ret; - } else - return ERR_UIRC_INVALID_FORMAT; - } - if (*progr == ':') { - char* prefix; - if ((prefix = strtok_r(progr, " ", &progr)) != NULL) { - if ((ret = tok_prefix(prefix, &irc_msg->name)) < 0) - return ret; - } else - return ERR_UIRC_INVALID_FORMAT; - } - - if ((command = strtok_r(NULL, " ", &progr)) != NULL) { - if (isalpha(*command)) { - if (!(irc_msg->cmd = uirc_ircmd_stoi(command))) - return ERR_UIRC_UNKNOWN_TOKEN; - } else if (isdigit(*command)) { - if ((irc_msg->cmd = atoi(command)) == 0) - return ERR_UIRC_UNKNOWN_TOKEN; - } else { - return ERR_UIRC_UNKNOWN_TOKEN; - } - } else { - return ERR_UIRC_INVALID_FORMAT; - } - - int i; - for (i = 0; *progr != ':' && i < 14; i++) { - if ((irc_msg->args[i] = strtok_r(NULL, " ", &progr)) == NULL) - return ERR_UIRC_INVALID_FORMAT; - } - irc_msg->args[i] = NULL; - if (*progr == ':') - ++progr; - irc_msg->trailing = progr; - return 1; -} -unsigned int uirc_ircmd_stoi(char* str) +signed int Ircmd_stoi(char* str) { if (str == NULL) return ERR_UIRC_NULL_ARGS; @@ -127,102 +79,145 @@ unsigned int uirc_ircmd_stoi(char* str) } return ERR_UIRC_UNKNOWN_TOKEN; } -int uirc_assm_mesg(char* buf, IRC_Message* mesg) +signed int Tok_mesg(char* str, IRC_Message* out) { - if (buf == NULL || mesg == NULL) + if (str == NULL || out == NULL) + return ERR_UIRC_NULL_ARGS; + int ret; + char *progr = str, *command; + if (*progr == '@') { + char* tags; + if ((tags = strtok_r(progr, " ", &progr)) != NULL) { + if ((ret = Tok_tags(tags, &out->tags)) < 0) + return ret; + } else + return ERR_UIRC_INVALID_FORMAT; + } + if (*progr == ':') { + char* prefix; + if ((prefix = strtok_r(progr, " ", &progr)) != NULL) { + if ((ret = Tok_user(prefix, &out->name, false)) < 0) + return ret; + } else + return ERR_UIRC_INVALID_FORMAT; + } + + if ((command = strtok_r(NULL, " ", &progr)) != NULL) { + if (!(out->cmd = (isalpha(*command)) ? Ircmd_stoi(command) : atoi(command))) + return ERR_UIRC_UNKNOWN_TOKEN; + } else { + return ERR_UIRC_INVALID_FORMAT; + } + + int i; + for (i = 0; *progr != ':' && i < 14; i++) { + if ((out->args[i] = strtok_r(NULL, " ", &progr)) == NULL) + return ERR_UIRC_INVALID_FORMAT; + } + out->args[i] = NULL; + if (*progr == ':') + ++progr; + out->trailing = progr; + return 1; +} +signed int Assm_mesg(char* buf, IRC_Message* in) +{ + if (buf == NULL || in == NULL) return ERR_UIRC_BUFFER_ERR; char* pos = buf; int cnt, ret; - if ((ret = assm_tags(&pos, mesg)) < 0) + if ((ret = Assm_tags(pos, &in->tags)) < 0) return ret; - if (mesg->name.nick != NULL || mesg->name.host != NULL) { - if ((ret = assm_prefix(&pos, &mesg->name)) < 0) + else + pos += ret; + if (in->name.nick != NULL || in->name.host != NULL) { + *(pos++) = ':'; + if ((ret = Assm_user(pos, &in->name, false)) <= 0) return ret; + else + pos += ret; + *(pos++) = ' '; } - if ((uirc_ircmd[mesg->cmd] != NULL) && ((cnt = sprintf(pos, "%s", uirc_ircmd[mesg->cmd])) > 0)) + if ((uirc_ircmd[in->cmd] != NULL) && ((cnt = sprintf(pos, "%s", uirc_ircmd[in->cmd])) > 0)) pos += cnt; else return ERR_UIRC_GENERIC; - for (unsigned int i = 0; i < 14 && mesg->args[i] != NULL; i++) { - if ((cnt = sprintf(pos, " %s", mesg->args[i])) > 0) + for (unsigned int i = 0; i < 14 && in->args[i] != NULL; i++) { + if ((cnt = sprintf(pos, " %s", in->args[i])) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; } - if (mesg->trailing != NULL) { - if ((cnt = sprintf(pos, " :%s", mesg->trailing)) > 0) + if (in->trailing != NULL) { + if ((cnt = sprintf(pos, " :%s", in->trailing)) > 0) pos += cnt; else return ERR_UIRC_GENERIC; } - if ((cnt = sprintf(pos, "\r\n")) != 2) + if ((cnt = sprintf(pos, "\r\n")) == 2) + pos += cnt; + else return ERR_UIRC_BUFFER_ERR; - return 1; + return pos - buf; } -int assm_tags(char** pos, IRC_Message* mesg) +signed int Assm_tags(char* buf, IRC_Tags* in) { - if (*pos == NULL || mesg == NULL) + if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; - const char* origpos = *pos; - char* cpos = *pos; + char* pos = buf; 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) + struct tagmapping tagmps[] = { + {.name = "time", .assg = &in->time}, + {.name = "account", .assg = &in->account}, + {.name = "batch", .assg = &in->batch}, + {.name = "label", .assg = &in->label}, + {.name = "msgid", .assg = &in->msgid}, + {.name = "multiline-concat", .assg = &in->multiline_concat}, + {.name = "typing", .assg = &in->typing}, + {.name = "react", .assg = &in->react}, + {.name = "reply", .assg = &in->reply}}; + for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { + if ((*tagmps[i].assg).present) { + if (pos == buf) { + if (sprintf(pos++, "@") != 1) return ERR_UIRC_BUFFER_ERR; } else { - if (sprintf(cpos++, ";") != 1) + if (sprintf(pos++, ";") != 1) return ERR_UIRC_BUFFER_ERR; } - if ((*tags[i].assg).clientbound) { - if (sprintf(cpos++, "+") != 1) + if ((*tagmps[i].assg).clientbound) { + if (sprintf(pos++, "+") != 1) return ERR_UIRC_BUFFER_ERR; } - if ((*tags[i].assg).value != NULL) - cnt = sprintf(cpos, "%s=%s", tags[i].name, (*tags[i].assg).value); + if ((*tagmps[i].assg).value != NULL) + cnt = sprintf(pos, "%s=%s", tagmps[i].name, (*tagmps[i].assg).value); else - cnt = sprintf(cpos, "%s", tags[i].name); + cnt = sprintf(pos, "%s", tagmps[i].name); if (cnt > 0) - cpos += cnt; + pos += cnt; else return ERR_UIRC_BUFFER_ERR; } } - if (*origpos == '@') { - if (sprintf(cpos++, " ") != 1) - return ERR_UIRC_BUFFER_ERR; - } - *pos = cpos; - return 1; + return pos - buf; } -int tok_tags(char* msg, IRC_Message* mesg) +signed int Tok_tags(char* str, IRC_Tags* out) { - if (msg == NULL || mesg == NULL) + if (str == NULL || out == NULL) return ERR_UIRC_NULL_ARGS; - char *cval, *cpos = msg, *ctag = NULL; + char *cval, *cpos = str, *ctag = NULL; bool clientbound; - 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}}; + const struct tagmapping tagmps[] = { + {.name = "time", .assg = &out->time}, + {.name = "account", .assg = &out->account}, + {.name = "batch", .assg = &out->batch}, + {.name = "label", .assg = &out->label}, + {.name = "msgid", .assg = &out->msgid}, + {.name = "multiline-concat", .assg = &out->multiline_concat}, + {.name = "typing", .assg = &out->typing}, + {.name = "react", .assg = &out->react}, + {.name = "reply", .assg = &out->reply}}; if (*cpos == '@') cpos++; while ((ctag = strtok_r(NULL, "; ", &cpos)) != NULL) { @@ -233,60 +228,65 @@ int tok_tags(char* msg, IRC_Message* mesg) } if ((cval = strchr(ctag, '=')) != NULL) *(cval++) = '\0'; - for (unsigned int i = 0; i < sizeof(tags) / sizeof(struct tagmapping); i++) { - if (!strcmp(ctag, tags[i].name)) { + for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { + if (!strcmp(ctag, tagmps[i].name)) { if (cval != NULL) - (*tags[i].assg).value = cval; - (*tags[i].assg).clientbound = clientbound; - (*tags[i].assg).present = true; + (*tagmps[i].assg).value = cval; + (*tagmps[i].assg).clientbound = clientbound; + (*tagmps[i].assg).present = true; } } } return 1; } -int assm_prefix(char** str, IRC_User* usr) +signed int Assm_user(char* buf, IRC_User* in, bool useorig) { - if (*str == NULL || usr == NULL) + if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; int cnt; - char* pos = *str; - *(pos++) = ':'; - if (usr->nick == NULL && usr->user == NULL && usr->host != NULL) { - if ((cnt = sprintf(pos, "%s", usr->host)) > 0) + char* pos = buf; + if (in->nick == NULL && in->host != NULL) { + if ((cnt = sprintf(pos, "%s", in->host)) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; - } else if (usr->nick != NULL) { - if ((cnt = sprintf(pos, "%s", usr->nick)) > 0) + } else if (in->nick != NULL) { + if ((cnt = sprintf(pos, "%s", in->nick)) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; - if (usr->user != NULL) { - if ((cnt = sprintf(pos, "!%s", usr->user)) > 0) + if (in->user != NULL) { + if ((cnt = sprintf(pos, "!%s", in->user)) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; } - if (usr->host != NULL) { - if ((cnt = sprintf(pos, "@%s", usr->host)) > 0) + if (in->orig != NULL) { + if ((cnt = sprintf(pos, "%%%s", in->orig)) > 0) + pos += cnt; + else + return ERR_UIRC_BUFFER_ERR; + } + if (in->host != NULL) { + if ((cnt = sprintf(pos, "@%s", in->host)) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; } } else return ERR_UIRC_NULL_ARGS; - *(pos++) = ' '; - *str = pos; - return 1; + return pos - buf; } -int tok_prefix(char* prefix, IRC_User* user) +signed int Tok_user(char* str, IRC_User* out, bool useorig) { - char* pos = (*prefix == ':') ? prefix + 1 : prefix; - if ((user->host = strchr(pos, '@')) != NULL) - *((char*)user->host++) = '\0'; - if ((user->user = strchr(pos, '!')) != NULL) /* RFC2812 says this cannot be here without the host but RFC1459 says it can, we accept both options */ - *((char*)user->user++) = '\0'; - if (*(user->nick = pos) == '\0') /* 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. */ + char* pos = (*str == ':') ? str + 1 : str; + if ((out->host = strchr(pos, '@')) != NULL) + *((char*)out->host++) = '\0'; + if ((out->orig = strchr(pos, '%')) != NULL) + *((char*)out->orig++) = '\0'; + if ((out->user = strchr(pos, '!')) != NULL) /* RFC2812 says this cannot be here without the host but RFC1459 says it can, we accept both options */ + *((char*)out->user++) = '\0'; + if (*(out->nick = pos) == '\0') /* NOTE: This may be the server instead of a nick according to RFC2812, it is left to the library out to decide how to interpret this based on the context. */ return ERR_UIRC_INVALID_FORMAT; return 1; } diff --git a/src/uirc.h b/src/uirc.h index c9ea298..d16f6a5 100644 --- a/src/uirc.h +++ b/src/uirc.h @@ -21,7 +21,3 @@ #include #include #include -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);