Uniform function namespace, add includes where needed, add IRC_Tags struct, shorten msg tokenizer, return assembled lenghts

This commit is contained in:
Alex 2020-07-07 23:17:28 +02:00
parent 96fce4fe49
commit eb8263e0f5
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
6 changed files with 259 additions and 245 deletions

View File

@ -1,50 +1,52 @@
#include "structs.h"
#include <stdbool.h>
#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

View File

@ -1,3 +1,4 @@
#include <stdbool.h>
#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 */

View File

@ -15,14 +15,23 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include "structs.h"
#include "mappings.h"
#include "helpers.h"
#include "mappings.h"
#include "structs.h"
#include <stdbool.h>
#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

View File

@ -1,6 +1,7 @@
#include "../include/uirc.h"
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;

View File

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

View File

@ -21,7 +21,3 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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);