Reformat code, add if preprocessor comments, shorten structrs, remove analyzer

This commit is contained in:
Alex D. 2020-12-16 14:22:25 +00:00
parent 124da1eb77
commit 0d019b02dc
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
19 changed files with 502 additions and 446 deletions

View File

@ -1,20 +1,41 @@
--- ---
Language: Cpp BasedOnStyle: LLVM
Standard: Cpp11 AlignConsecutiveMacros: 'true'
BasedOnStyle: LLVM AlignConsecutiveAssignments: 'true'
TabWidth: 8 AlignConsecutiveDeclarations: 'true'
IndentWidth: 8 AlignEscapedNewlines: Left
UseTab: ForIndentation AllowShortBlocksOnASingleLine: 'true'
AllowShortBlocksOnASingleLine: true AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: All
AllowShortFunctionsOnASingleLine: true AllowShortIfStatementsOnASingleLine: Always
AllowShortIfStatementsOnASingleLine: true AllowShortLoopsOnASingleLine: 'true'
AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: TopLevel
AllowAllParametersOfDeclarationOnNextLine: true AlwaysBreakAfterReturnType: AllDefinitions
BreakBeforeBinaryOperators: NonAssignment AlwaysBreakBeforeMultilineStrings: 'false'
BreakBeforeBraces: Linux BinPackArguments: 'false'
IndentCaseLabels: true BinPackParameters: 'false'
PointerAlignment: Left BreakBeforeBinaryOperators: NonAssignment
ColumnLimit: 150 BreakBeforeBraces: Linux
... BreakStringLiterals: 'false'
ColumnLimit: '150'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
Cpp11BracedListStyle: 'false'
IncludeBlocks: Regroup
IndentCaseLabels: 'true'
IndentPPDirectives: None
IndentWidth: '8'
Language: Cpp
PointerAlignment: Left
ReflowComments: 'true'
SortIncludes: 'true'
SpaceAfterCStyleCast: 'true'
SpaceAfterLogicalNot: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'true'
SpaceBeforeParens: ControlStatements
SpacesInCStyleCastParentheses: 'false'
Standard: Cpp11
TabWidth: '8'
UseTab: ForIndentation
...

View File

@ -1,9 +1,9 @@
--- ---
Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements' Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements,-readability-magic-numbers'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '' HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
FormatStyle: none FormatStyle: file
User: caskd User: caskd
CheckOptions: CheckOptions:
- key: bugprone-argument-comment.CommentBoolLiterals - key: bugprone-argument-comment.CommentBoolLiterals
@ -158,10 +158,6 @@ CheckOptions:
value: '1' value: '1'
- key: readability-inconsistent-declaration-parameter-name.Strict - key: readability-inconsistent-declaration-parameter-name.Strict
value: '0' value: '0'
- key: readability-magic-numbers.IgnoredFloatingPointValues
value: '1.0;100.0;'
- key: readability-magic-numbers.IgnoredIntegerValues
value: '1;2;3;4;'
- key: readability-redundant-member-init.IgnoreBaseInCopyConstructors - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors
value: '0' value: '0'
- key: readability-redundant-smartptr-get.IgnoreMacros - key: readability-redundant-smartptr-get.IgnoreMacros

View File

@ -1,19 +1,26 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(microirc LANGUAGES C) project(microirc LANGUAGES C)
# NOTE: Do these seem too annoying? Try writing good code then.
# Code that triggers these warnings will not be accepted unless it has a good reason to trigger them.
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall -Wextra -Werror -Wformat-overflow=2 -Wformat-security -Winit-self -Wstrict-overflow=2 -Wstringop-overflow=2 -Walloc-zero -Wduplicated-branches -Wduplicated-cond -Wtrampolines -Wfloat-equal -Wshadow -Wunsafe-loop-optimizations -Wparentheses -pedantic -fanalyzer -fstack-check)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Weverything -Wno-padded -Wno-disabled-macro-expansion -pedantic)
endif()
OPTION(CMAKE_BUILD_TYPE "Debug")
OPTION(BUILD_TESTS "Build tests for ctest" OFF) OPTION(BUILD_TESTS "Build tests for ctest" OFF)
OPTION(BUILD_IRCV3 "Build IRCv3 components" ON) OPTION(BUILD_IRCV3 "Build IRCv3 components" ON)
OPTION(BUILD_HELPERS "Build message helpers" ON) OPTION(BUILD_HELPERS "Build message helpers" ON)
OPTION(BUILD_VALIDATORS "Build message validators" ON) OPTION(BUILD_VALIDATORS "Build message validators" ON)
OPTION(CODE_ANALYZER "Analyze the code statically" ON)
OPTION(CODE_COVERAGE "Build with coverage tools" OFF)
# NOTE: Do these seem too annoying? Try writing good code then.
# Code that triggers these warnings will not be accepted unless it has a good reason to trigger them.
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall -Wextra -Werror -Wformat-overflow=2 -Wformat-security -Winit-self -Wstrict-overflow=2 -Wstringop-overflow=2 -Walloc-zero -Wduplicated-branches -Wduplicated-cond -Wtrampolines -Wfloat-equal -Wshadow -Wunsafe-loop-optimizations -Wparentheses -pedantic -fstack-check)
if ( CODE_ANALYZER )
add_compile_options(-fanalyzer)
endif()
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Weverything -Wno-padded -Wno-disabled-macro-expansion -pedantic)
if ( CODE_COVERAGE )
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
endif()
endif()
if ( BUILD_IRCV3 ) if ( BUILD_IRCV3 )
message(STATUS "IRCv3 capabilities are going to be built.") message(STATUS "IRCv3 capabilities are going to be built.")

View File

@ -15,25 +15,27 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>. * along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "types.h" #include "types.h"
#include <stdbool.h> #include <stdbool.h>
#include <sys/types.h> #include <sys/types.h>
#ifndef UIRC_INCLUDED_FUNCT #ifndef UIRC_GUARD_FUNCTIONS
#define UIRC_INCLUDED_FUNCT #define UIRC_GUARD_FUNCTIONS
/* Tokenizers: They take a string in and point their struct element pointers at tokens and end tokens with '\0' */ /* 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_mesg(char* str, IRC_Message* out);
extern signed int Tok_user(char* str, IRC_User* out, bool useorig); extern signed int Tok_user(char* str, IRC_User* out, bool useorig);
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
extern signed int Tok_tags(char* str, IRC_Tags* out); extern signed int Tok_tags(char* str, IRC_Tags* out);
#endif #endif /* UIRC_IRCV3 */
/* Assemblers: They return the amount of bytes written and write directly at buf */ /* Assemblers: They return the amount of bytes written and write directly at buf */
extern signed long Assm_mesg(char* buf, IRC_Message* in, size_t len); extern signed long Assm_mesg(char* buf, IRC_Message* in, size_t len);
extern signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig); extern signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
extern signed long Assm_tags(char* buf, IRC_Tags* in, size_t len); extern signed long Assm_tags(char* buf, IRC_Tags* in, size_t len);
#endif #endif /* UIRC_IRCV3 */
/* Validators: They check that the parsed message is valid and follows the standard */ /* Validators: They check that the parsed message is valid and follows the standard */
#ifdef UIRC_VALIDATORS #ifdef UIRC_VALIDATORS
@ -42,9 +44,9 @@ extern signed int Val_channame(char* chan);
extern signed int Val_type_nocrlf(char* str); extern signed int Val_type_nocrlf(char* str);
extern signed int Val_type_nospcl(char* str); extern signed int Val_type_nospcl(char* str);
extern signed int Val_type_noblcm(char* str); extern signed int Val_type_noblcm(char* str);
#endif #endif /* UIRC_VALIDATORS */
/* Converters: They convert from one format to another */ /* Converters: They convert from one format to another */
extern signed int Ircmd_stoi(char* str); extern signed int Ircmd_stoi(char* str);
#endif #endif /* UIRC_GUARD_FUNCTIONS */

View File

@ -15,63 +15,66 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>. * along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "types.h" #include "types.h"
#include <stdbool.h> #include <stdbool.h>
#include <time.h> #include <time.h>
#ifdef UIRC_HELPERS #ifdef UIRC_HELPERS
#ifndef UIRC_INCLUDED_HELPERS #ifndef UIRC_GUARD_HELPERS
#define UIRC_INCLUDED_HELPERS #define UIRC_GUARD_HELPERS
extern IRC_Message* Assm_AUTO(int cmd, bool trailing, char** args, int req); extern IRC_Message* Assm_AUTO(int cmd, bool trailing, char** args, int req);
#define Assm_cmd_REHASH() Assm_AUTO(REHASH, false, (char*[]){NULL}, 0) #define Assm_cmd_REHASH() Assm_AUTO(REHASH, false, (char*[]) { NULL }, 0)
#define Assm_cmd_DIE() Assm_AUTO(DIE, false, (char*[]){NULL}, 0) #define Assm_cmd_DIE() Assm_AUTO(DIE, false, (char*[]) { NULL }, 0)
#define Assm_cmd_RESTART() Assm_AUTO(RESTART, false, (char*[]){NULL}, 0) #define Assm_cmd_RESTART() Assm_AUTO(RESTART, false, (char*[]) { NULL }, 0)
#define Assm_cmd_QUIT(message) Assm_AUTO(QUIT, true, (char*[]){message, NULL}, 0) #define Assm_cmd_QUIT(message) Assm_AUTO(QUIT, true, (char*[]) { message, NULL }, 0)
#define Assm_cmd_MOTD(target) Assm_AUTO(MOTD, false, (char*[]){target, NULL}, 0) #define Assm_cmd_MOTD(target) Assm_AUTO(MOTD, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_VERSION(target) Assm_AUTO(VERSION, false, (char*[]){target, NULL}, 0) #define Assm_cmd_VERSION(target) Assm_AUTO(VERSION, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_TIME(target) Assm_AUTO(TIME, false, (char*[]){target, NULL}, 0) #define Assm_cmd_TIME(target) Assm_AUTO(TIME, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_TRACE(target) Assm_AUTO(TRACE, false, (char*[]){target, NULL}, 0) #define Assm_cmd_TRACE(target) Assm_AUTO(TRACE, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_ADMIN(target) Assm_AUTO(ADMIN, false, (char*[]){target, NULL}, 0) #define Assm_cmd_ADMIN(target) Assm_AUTO(ADMIN, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_INFO(target) Assm_AUTO(INFO, false, (char*[]){target, NULL}, 0) #define Assm_cmd_INFO(target) Assm_AUTO(INFO, false, (char*[]) { target, NULL }, 0)
#define Assm_cmd_AWAY(message) Assm_AUTO(AWAY, false, (char*[]){message, NULL}, 0) #define Assm_cmd_AWAY(message) Assm_AUTO(AWAY, false, (char*[]) { message, NULL }, 0)
#define Assm_cmd_PASS(password) Assm_AUTO(PASS, true, (char*[]){password, NULL}, 1) #define Assm_cmd_PASS(password) Assm_AUTO(PASS, true, (char*[]) { password, NULL }, 1)
#define Assm_cmd_ERROR(message) Assm_AUTO(ERROR, true, (char*[]){message, NULL}, 1) #define Assm_cmd_ERROR(message) Assm_AUTO(ERROR, true, (char*[]) { message, NULL }, 1)
#define Assm_cmd_WALLOPS(text) Assm_AUTO(WALLOPS, true, (char*[]){text, NULL}, 1) #define Assm_cmd_WALLOPS(text) Assm_AUTO(WALLOPS, true, (char*[]) { text, NULL }, 1)
#define Assm_cmd_NICK(nickname) Assm_AUTO(NICK, false, (char*[]){nickname, NULL}, 1) #define Assm_cmd_NICK(nickname) Assm_AUTO(NICK, false, (char*[]) { nickname, NULL }, 1)
#define Assm_cmd_USERS(target) Assm_AUTO(USERS, false, (char*[]){target, NULL}, 1) #define Assm_cmd_USERS(target) Assm_AUTO(USERS, false, (char*[]) { target, NULL }, 1)
#define Assm_cmd_NAMES(channels, target) Assm_AUTO(NAMES, false, (char*[]){channels, target, NULL}, 0) #define Assm_cmd_NAMES(channels, target) Assm_AUTO(NAMES, false, (char*[]) { channels, target, NULL }, 0)
#define Assm_cmd_LIST(channels, target) Assm_AUTO(LIST, false, (char*[]){channels, target, NULL}, 0) #define Assm_cmd_LIST(channels, target) Assm_AUTO(LIST, false, (char*[]) { channels, target, NULL }, 0)
#define Assm_cmd_LUSERS(mask, target) Assm_AUTO(LUSERS, false, (char*[]){mask, target, NULL}, 0) #define Assm_cmd_LUSERS(mask, target) Assm_AUTO(LUSERS, false, (char*[]) { mask, target, NULL }, 0)
#define Assm_cmd_STATS(query, target) Assm_AUTO(STATS, false, (char*[]){query, target, NULL}, 0) #define Assm_cmd_STATS(query, target) Assm_AUTO(STATS, false, (char*[]) { query, target, NULL }, 0)
#define Assm_cmd_SERVLIST(mask, type) Assm_AUTO(SERVLIST, false, (char*[]){mask, type, NULL}, 0) #define Assm_cmd_SERVLIST(mask, type) Assm_AUTO(SERVLIST, false, (char*[]) { mask, type, NULL }, 0)
#define Assm_cmd_JOIN(channels, keys) Assm_AUTO(JOIN, false, (char*[]){channels, keys, NULL}, 1) #define Assm_cmd_JOIN(channels, keys) Assm_AUTO(JOIN, false, (char*[]) { channels, keys, NULL }, 1)
#define Assm_cmd_PART(channel, message) Assm_AUTO(PART, false, (char*[]){channel, message, NULL}, 1) #define Assm_cmd_PART(channel, message) Assm_AUTO(PART, false, (char*[]) { channel, message, NULL }, 1)
/* NOTE: Use a non-NULL address (pointing at a "\0") as the topic to clear it and use a NULL address to check it /* 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 */ * Blame the protocol, not this >:C */
#define Assm_cmd_TOPIC(channel, topic) Assm_AUTO(TOPIC, true, (char*[]){channel, topic, NULL}, 1) #define Assm_cmd_TOPIC(channel, topic) Assm_AUTO(TOPIC, true, (char*[]) { channel, topic, NULL }, 1)
#define Assm_cmd_PONG(source, target) Assm_AUTO(PONG, true, (char*[]){source, target, NULL}, 1) #define Assm_cmd_PONG(source, target) Assm_AUTO(PONG, true, (char*[]) { source, target, NULL }, 1)
#define Assm_cmd_OPER(name, password) Assm_AUTO(OPER, true, (char*[]){name, password, NULL}, 2) #define Assm_cmd_OPER(name, password) Assm_AUTO(OPER, true, (char*[]) { name, password, NULL }, 2)
#define Assm_cmd_SQUIT(server, comment) Assm_AUTO(SQUIT, true, (char*[]){server, comment, NULL}, 2) #define Assm_cmd_SQUIT(server, comment) Assm_AUTO(SQUIT, true, (char*[]) { server, comment, NULL }, 2)
#define Assm_cmd_PRIVMSG(target, message) Assm_AUTO(PRIVMSG, true, (char*[]){target, message, NULL}, 2) #define Assm_cmd_PRIVMSG(target, message) Assm_AUTO(PRIVMSG, true, (char*[]) { target, message, NULL }, 2)
#define Assm_cmd_NOTICE(target, text) Assm_AUTO(NOTICE, true, (char*[]){target, text, NULL}, 2) #define Assm_cmd_NOTICE(target, text) Assm_AUTO(NOTICE, true, (char*[]) { target, text, NULL }, 2)
#define Assm_cmd_SQUERY(servicename, text) Assm_AUTO(SQUERY, true, (char*[]){servicename, text, NULL}, 2) #define Assm_cmd_SQUERY(servicename, text) Assm_AUTO(SQUERY, true, (char*[]) { servicename, text, NULL }, 2)
#define Assm_cmd_KILL(nick, comment) Assm_AUTO(KILL, true, (char*[]){nick, comment, NULL}, 2) #define Assm_cmd_KILL(nick, comment) Assm_AUTO(KILL, true, (char*[]) { nick, comment, NULL }, 2)
#define Assm_cmd_INVITE(nick, channel) Assm_AUTO(INVITE, false, (char*[]){nick, channel, NULL}, 2) #define Assm_cmd_INVITE(nick, channel) Assm_AUTO(INVITE, false, (char*[]) { nick, channel, NULL }, 2)
#define Assm_cmd_MODE(nickname, modes, modeparams) Assm_AUTO(MODE, false, (char*[]){nickname, modes, modeparams, NULL}, 1) #define Assm_cmd_MODE(nickname, modes, modeparams) Assm_AUTO(MODE, false, (char*[]) { nickname, modes, modeparams, NULL }, 1)
#define Assm_cmd_KICK(channels, users, comment) Assm_AUTO(KICK, true, (char*[]){channels, users, comment, NULL}, 2) #define Assm_cmd_KICK(channels, users, comment) Assm_AUTO(KICK, true, (char*[]) { channels, users, comment, NULL }, 2)
#define Assm_cmd_CONNECT(target, port, remote) Assm_AUTO(CONNECT, false, (char*[]){target, port, remote, NULL}, 2) #define Assm_cmd_CONNECT(target, port, remote) Assm_AUTO(CONNECT, false, (char*[]) { target, port, remote, NULL }, 2)
#define Assm_cmd_SERVICE(nickname, distribution, type, info) \ #define Assm_cmd_SERVICE(nickname, distribution, type, info) \
Assm_AUTO(SERVICE, true, (char*[]){nickname, RESERVED, distribution, "0", RESERVED, info, NULL}, 6) Assm_AUTO(SERVICE, true, (char*[]) { nickname, RESERVED, distribution, "0", RESERVED, info, NULL }, 6)
extern IRC_Message* Assm_cmd_USER(char* user, char* realname, int modes); extern IRC_Message* Assm_cmd_USER(char* user, char* realname, int modes);
extern IRC_Message* Assm_cmd_LINKS(char* remoteserv, char* servmask); extern IRC_Message* Assm_cmd_LINKS(char* remoteserv, char* servmask);
@ -85,20 +88,21 @@ extern IRC_Message* Assm_cmd_ISON(char* users[]);
extern void Tok_cmd_PING(IRC_Message* mesg, char* source, char* target); extern void Tok_cmd_PING(IRC_Message* mesg, char* source, char* target);
extern void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg); extern void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg);
extern int Tok_CAPS(char* caps); extern int Tok_CAPS(char* caps);
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
#define Assm_cmd_CAP_END() Assm_AUTO(CAP, false, (char*[]){"END", NULL}, 0) #define Assm_cmd_CAP_END() Assm_AUTO(CAP, false, (char*[]) { "END", NULL }, 0)
#define Assm_cmd_CAP_LIST() Assm_AUTO(CAP, false, (char*[]){"LIST", NULL}, 0) #define Assm_cmd_CAP_LIST() Assm_AUTO(CAP, false, (char*[]) { "LIST", NULL }, 0)
#define Assm_cmd_CAP_LS(version) Assm_AUTO(CAP, false, (char*[]){"LS", version, NULL}, 0) #define Assm_cmd_CAP_LS(version) Assm_AUTO(CAP, false, (char*[]) { "LS", version, NULL }, 0)
#define Assm_cmd_CAP_REQ(caps) Assm_AUTO(CAP, true, (char*[]){"REQ", caps, NULL}, 1) #define Assm_cmd_CAP_REQ(caps) Assm_AUTO(CAP, true, (char*[]) { "REQ", caps, NULL }, 1)
#define Assm_cmd_CAP_NEW(nick, caps) Assm_AUTO(CAP, true, (char*[]){"NEW", nick, caps, NULL}, 2) #define Assm_cmd_CAP_NEW(nick, caps) Assm_AUTO(CAP, true, (char*[]) { "NEW", nick, caps, NULL }, 2)
#define Assm_cmd_CAP_DEL(nick, caps) Assm_AUTO(CAP, true, (char*[]){"DEL", nick, caps, NULL}, 2) #define Assm_cmd_CAP_DEL(nick, caps) Assm_AUTO(CAP, true, (char*[]) { "DEL", nick, caps, NULL }, 2)
#endif #endif /* UIRC_IRCV3 */
extern size_t Assm_tag_timestamp(char* buf, size_t len, time_t time); extern size_t Assm_tag_timestamp(char* buf, size_t len, time_t time);
#endif
#endif #endif /* UIRC_GUARD_HELPERS */
#endif /* UIRC_HELPERS */

View File

@ -16,44 +16,44 @@
* along with uIRC. If not, see <https://www.gnu.org/licenses/>. * along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef UIRC_INCLUDED_MAPS #ifndef UIRC_GUARD_MAPS
#define UIRC_INCLUDED_MAPS #define UIRC_GUARD_MAPS
#define ERR_UIRC_GENERIC -1 #define ERR_UIRC_GENERIC -1
#define ERR_UIRC_NULL_ARGS -2 #define ERR_UIRC_NULL_ARGS -2
#define ERR_UIRC_INVALID_FORMAT -3 #define ERR_UIRC_INVALID_FORMAT -3
#define ERR_UIRC_BUFFER_ERR -4 #define ERR_UIRC_BUFFER_ERR -4
#define ERR_UIRC_UNKNOWN_TOKEN -5 #define ERR_UIRC_UNKNOWN_TOKEN -5
#define ERR_UIRC_VAL_FAILED -10 #define ERR_UIRC_VAL_FAILED -10
/* Mode bitmask values */ /* Mode bitmask values */
#define MBMASK_WALLOPS 1 << 1 /* 010 */ #define MBMASK_WALLOPS 1 << 1 /* 010 */
#define MBMASK_INVIS 1 << 2 /* 100 */ #define MBMASK_INVIS 1 << 2 /* 100 */
/* IRCv3 Supported features bits */ /* IRCv3 Supported features bits */
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
#define CAP_ACCOUNT_NOTIFY 1 #define CAP_ACCOUNT_NOTIFY 1
#define CAP_ACCOUNT_TAG 2 #define CAP_ACCOUNT_TAG 2
#define CAP_AWAY_NOTIFY 3 #define CAP_AWAY_NOTIFY 3
#define CAP_BATCH 4 #define CAP_BATCH 4
#define CAP_CAP_NOTIFY 5 #define CAP_CAP_NOTIFY 5
#define CAP_CHANNEL_RENAME 6 #define CAP_CHANNEL_RENAME 6
#define CAP_CHGHOST 7 #define CAP_CHGHOST 7
#define CAP_ECHO_MESSAGE 8 #define CAP_ECHO_MESSAGE 8
#define CAP_EXTENDED_JOIN 9 #define CAP_EXTENDED_JOIN 9
#define CAP_INVITE_NOTIFY 10 #define CAP_INVITE_NOTIFY 10
#define CAP_LABELED_RESPONSE 11 #define CAP_LABELED_RESPONSE 11
#define CAP_MESSAGE_TAGS 12 #define CAP_MESSAGE_TAGS 12
#define CAP_MONITOR 13 #define CAP_MONITOR 13
#define CAP_MULTI_PREFIX 14 #define CAP_MULTI_PREFIX 14
#define CAP_MULTILINE 15 #define CAP_MULTILINE 15
#define CAP_SASL 16 #define CAP_SASL 16
#define CAP_SERVER_TIME 17 #define CAP_SERVER_TIME 17
#define CAP_SETNAME 18 #define CAP_SETNAME 18
#define CAP_TLS 19 #define CAP_TLS 19
#define CAP_USERHOST_IN_NAMES 20 #define CAP_USERHOST_IN_NAMES 20
#define CAPBIT(cap) (1 << cap) #define CAPBIT(cap) (1 << cap)
#endif #endif /* UIRC_IRCV3 */
#define UIRC_FCMD ADMIN #define UIRC_FCMD ADMIN
enum commands { enum commands {
@ -121,16 +121,16 @@ enum commands {
WEBIRC, /* https://ircv3.net/specs/extensions/webirc */ WEBIRC, /* https://ircv3.net/specs/extensions/webirc */
#define UIRC_LCMD WEBIRC #define UIRC_LCMD WEBIRC
#else #else /* UIRC_IRCV3 */
#define UIRC_LCMD WHOWAS #define UIRC_LCMD WHOWAS
#endif #endif /* UIRC_IRCV3 */
}; };
#define RPL_WELCOME 1 #define RPL_WELCOME 1
#define RPL_YOURHOST 2 #define RPL_YOURHOST 2
#define RPL_CREATED 3 #define RPL_CREATED 3
#define RPL_MYINFO 4 #define RPL_MYINFO 4
#define RPL_BOUNCE 5 #define RPL_BOUNCE 5
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
/* TO IRCv3 WG: /* TO IRCv3 WG:
@ -141,154 +141,154 @@ enum commands {
* Read the above and go speak with them, or just don't use IRCv3 :) * Read the above and go speak with them, or just don't use IRCv3 :)
*/ */
#define RPL_ISUPPORT 5 #define RPL_ISUPPORT 5
#endif #endif /* UIRC_IRCV3 */
#define RPL_TRACELINK 200 #define RPL_TRACELINK 200
#define RPL_TRACECONNECTING 201 #define RPL_TRACECONNECTING 201
#define RPL_TRACEHANDSHAKE 202 #define RPL_TRACEHANDSHAKE 202
#define RPL_TRACEUNKNOWN 203 #define RPL_TRACEUNKNOWN 203
#define RPL_TRACEOPERATOR 204 #define RPL_TRACEOPERATOR 204
#define RPL_TRACEUSER 205 #define RPL_TRACEUSER 205
#define RPL_TRACESERVER 206 #define RPL_TRACESERVER 206
#define RPL_TRACENEWTYPE 208 #define RPL_TRACENEWTYPE 208
#define RPL_STATSLINKINFO 211 #define RPL_STATSLINKINFO 211
#define RPL_STATSCOMMANDS 212 #define RPL_STATSCOMMANDS 212
#define RPL_STATSCLINE 213 #define RPL_STATSCLINE 213
#define RPL_STATSNLINE 214 #define RPL_STATSNLINE 214
#define RPL_STATSILINE 215 #define RPL_STATSILINE 215
#define RPL_STATSKLINE 216 #define RPL_STATSKLINE 216
#define RPL_STATSYLINE 218 #define RPL_STATSYLINE 218
#define RPL_ENDOFSTATS 219 #define RPL_ENDOFSTATS 219
#define RPL_UMODEIS 221 #define RPL_UMODEIS 221
#define RPL_STATSLLINE 241 #define RPL_STATSLLINE 241
#define RPL_STATSUPTIME 242 #define RPL_STATSUPTIME 242
#define RPL_STATSOLINE 243 #define RPL_STATSOLINE 243
#define RPL_STATSHLINE 244 #define RPL_STATSHLINE 244
#define RPL_LUSERCLIENT 251 #define RPL_LUSERCLIENT 251
#define RPL_LUSEROP 252 #define RPL_LUSEROP 252
#define RPL_LUSERUNKNOWN 253 #define RPL_LUSERUNKNOWN 253
#define RPL_LUSERCHANNELS 254 #define RPL_LUSERCHANNELS 254
#define RPL_LUSERME 255 #define RPL_LUSERME 255
#define RPL_ADMINME 256 #define RPL_ADMINME 256
#define RPL_ADMINLOC1 257 #define RPL_ADMINLOC1 257
#define RPL_ADMINLOC2 258 #define RPL_ADMINLOC2 258
#define RPL_ADMINEMAIL 259 #define RPL_ADMINEMAIL 259
#define RPL_TRACELOG 261 #define RPL_TRACELOG 261
#define RPL_NONE 300 #define RPL_NONE 300
#define RPL_AWAY 301 #define RPL_AWAY 301
#define RPL_USERHOST 302 #define RPL_USERHOST 302
#define RPL_ISON 303 #define RPL_ISON 303
#define RPL_UNAWAY 305 #define RPL_UNAWAY 305
#define RPL_NOWAWAY 306 #define RPL_NOWAWAY 306
#define RPL_WHOISUSER 311 #define RPL_WHOISUSER 311
#define RPL_WHOISSERVER 312 #define RPL_WHOISSERVER 312
#define RPL_WHOISOPERATOR 313 #define RPL_WHOISOPERATOR 313
#define RPL_WHOWASUSER 314 #define RPL_WHOWASUSER 314
#define RPL_ENDOFWHO 315 #define RPL_ENDOFWHO 315
#define RPL_WHOISIDLE 317 #define RPL_WHOISIDLE 317
#define RPL_ENDOFWHOIS 318 #define RPL_ENDOFWHOIS 318
#define RPL_WHOISCHANNELS 319 #define RPL_WHOISCHANNELS 319
#define RPL_LISTSTART 321 #define RPL_LISTSTART 321
#define RPL_LIST 322 #define RPL_LIST 322
#define RPL_LISTEND 323 #define RPL_LISTEND 323
#define RPL_CHANNELMODEIS 324 #define RPL_CHANNELMODEIS 324
#define RPL_NOTOPIC 331 #define RPL_NOTOPIC 331
#define RPL_TOPIC 332 #define RPL_TOPIC 332
#define RPL_INVITING 341 #define RPL_INVITING 341
#define RPL_SUMMONING 342 #define RPL_SUMMONING 342
#define RPL_VERSION 351 #define RPL_VERSION 351
#define RPL_WHOREPLY 352 #define RPL_WHOREPLY 352
#define RPL_NAMREPLY 353 #define RPL_NAMREPLY 353
#define RPL_LINKS 364 #define RPL_LINKS 364
#define RPL_ENDOFLINKS 365 #define RPL_ENDOFLINKS 365
#define RPL_ENDOFNAMES 366 #define RPL_ENDOFNAMES 366
#define RPL_BANLIST 367 #define RPL_BANLIST 367
#define RPL_ENDOFBANLIST 368 #define RPL_ENDOFBANLIST 368
#define RPL_ENDOFWHOWAS 369 #define RPL_ENDOFWHOWAS 369
#define RPL_INFO 371 #define RPL_INFO 371
#define RPL_MOTD 372 #define RPL_MOTD 372
#define RPL_ENDOFINFO 374 #define RPL_ENDOFINFO 374
#define RPL_MOTDSTART 375 #define RPL_MOTDSTART 375
#define RPL_ENDOFMOTD 376 #define RPL_ENDOFMOTD 376
#define RPL_YOUREOPER 381 #define RPL_YOUREOPER 381
#define RPL_REHASHING 382 #define RPL_REHASHING 382
#define RPL_TIME 391 #define RPL_TIME 391
#define RPL_USERSSTART 392 #define RPL_USERSSTART 392
#define RPL_USERS 393 #define RPL_USERS 393
#define RPL_ENDOFUSERS 394 #define RPL_ENDOFUSERS 394
#define RPL_NOUSERS 395 #define RPL_NOUSERS 395
#define ERR_NOSUCHNICK 401 #define ERR_NOSUCHNICK 401
#define ERR_NOSUCHSERVER 402 #define ERR_NOSUCHSERVER 402
#define ERR_NOSUCHCHANNEL 403 #define ERR_NOSUCHCHANNEL 403
#define ERR_CANNOTSENDTOCHAN 404 #define ERR_CANNOTSENDTOCHAN 404
#define ERR_TOOMANYCHANNELS 405 #define ERR_TOOMANYCHANNELS 405
#define ERR_WASNOSUCHNICK 406 #define ERR_WASNOSUCHNICK 406
#define ERR_TOOMANYTARGETS 407 #define ERR_TOOMANYTARGETS 407
#define ERR_NOORIGIN 409 #define ERR_NOORIGIN 409
#define ERR_NORECIPIENT 411 #define ERR_NORECIPIENT 411
#define ERR_NOTEXTTOSEND 412 #define ERR_NOTEXTTOSEND 412
#define ERR_NOTOPLEVEL 413 #define ERR_NOTOPLEVEL 413
#define ERR_WILDTOPLEVEL 414 #define ERR_WILDTOPLEVEL 414
#define ERR_UNKNOWNCOMMAND 421 #define ERR_UNKNOWNCOMMAND 421
#define ERR_NOMOTD 422 #define ERR_NOMOTD 422
#define ERR_NOADMININFO 423 #define ERR_NOADMININFO 423
#define ERR_FILEERROR 424 #define ERR_FILEERROR 424
#define ERR_NONICKNAMEGIVEN 431 #define ERR_NONICKNAMEGIVEN 431
#define ERR_ERRONEUSNICKNAME 432 #define ERR_ERRONEUSNICKNAME 432
#define ERR_NICKNAMEINUSE 433 #define ERR_NICKNAMEINUSE 433
#define ERR_NICKCOLLISION 436 #define ERR_NICKCOLLISION 436
#define ERR_USERNOTINCHANNEL 441 #define ERR_USERNOTINCHANNEL 441
#define ERR_NOTONCHANNEL 442 #define ERR_NOTONCHANNEL 442
#define ERR_USERONCHANNEL 443 #define ERR_USERONCHANNEL 443
#define ERR_NOLOGIN 444 #define ERR_NOLOGIN 444
#define ERR_SUMMONDISABLED 445 #define ERR_SUMMONDISABLED 445
#define ERR_USERSDISABLED 446 #define ERR_USERSDISABLED 446
#define ERR_NOTREGISTERED 451 #define ERR_NOTREGISTERED 451
#define ERR_NEEDMOREPARAMS 461 #define ERR_NEEDMOREPARAMS 461
#define ERR_ALREADYREGISTRED 462 #define ERR_ALREADYREGISTRED 462
#define ERR_NOPERMFORHOST 463 #define ERR_NOPERMFORHOST 463
#define ERR_PASSWDMISMATCH 464 #define ERR_PASSWDMISMATCH 464
#define ERR_YOUREBANNEDCREEP 465 #define ERR_YOUREBANNEDCREEP 465
#define ERR_KEYSET 467 #define ERR_KEYSET 467
#define ERR_CHANNELISFULL 471 #define ERR_CHANNELISFULL 471
#define ERR_UNKNOWNMODE 472 #define ERR_UNKNOWNMODE 472
#define ERR_INVITEONLYCHAN 473 #define ERR_INVITEONLYCHAN 473
#define ERR_BANNEDFROMCHAN 474 #define ERR_BANNEDFROMCHAN 474
#define ERR_BADCHANNELKEY 475 #define ERR_BADCHANNELKEY 475
#define ERR_NOPRIVILEGES 481 #define ERR_NOPRIVILEGES 481
#define ERR_CHANOPRIVSNEEDED 482 #define ERR_CHANOPRIVSNEEDED 482
#define ERR_CANTKILLSERVER 483 #define ERR_CANTKILLSERVER 483
#define ERR_NOOPERHOST 491 #define ERR_NOOPERHOST 491
#define ERR_UMODEUNKNOWNFLAG 501 #define ERR_UMODEUNKNOWNFLAG 501
#define ERR_USERSDONTMATCH 502 #define ERR_USERSDONTMATCH 502
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
/* https://ircv3.net/registry */ /* https://ircv3.net/registry */
#define RPL_STARTTLS 670 #define RPL_STARTTLS 670
#define ERR_STARTTLS 691 #define ERR_STARTTLS 691
#define RPL_MONONLINE 730 #define RPL_MONONLINE 730
#define RPL_MONOFFLINE 731 #define RPL_MONOFFLINE 731
#define RPL_MONLIST 732 #define RPL_MONLIST 732
#define RPL_ENDOFMONLIST 733 #define RPL_ENDOFMONLIST 733
#define ERR_MOLISTFULL 734 #define ERR_MOLISTFULL 734
#define RPL_LOGGEDIN 900 #define RPL_LOGGEDIN 900
#define RPL_LOGGEDOUT 901 #define RPL_LOGGEDOUT 901
#define ERR_NICKLOCKED 902 #define ERR_NICKLOCKED 902
#define RPL_SASLSUCCESS 903 #define RPL_SASLSUCCESS 903
#define ERR_SASLFAIL 904 #define ERR_SASLFAIL 904
#define ERR_SASLTOOLONG 905 #define ERR_SASLTOOLONG 905
#define ERR_SASLABORTED 906 #define ERR_SASLABORTED 906
#define ERR_SASLALREADY 907 #define ERR_SASLALREADY 907
#define ERR_SASLMECHS 908 #define ERR_SASLMECHS 908
#endif #endif /* UIRC_IRCV3 */
#endif
extern const char* const IRC_Cmds[UIRC_LCMD + UIRC_FCMD]; extern const char* const IRC_Cmds[UIRC_LCMD + UIRC_FCMD];
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
extern const char* const IRC_v3_Caps[CAP_USERHOST_IN_NAMES + 1]; extern const char* const IRC_v3_Caps[CAP_USERHOST_IN_NAMES + 1];
#endif #endif /* UIRC_IRCV3 */
#endif /* UIRC_GUARD_MAPS */

View File

@ -17,35 +17,23 @@
*/ */
#include <stdbool.h> #include <stdbool.h>
#ifndef UIRC_INCLUDED_TYPES #ifndef UIRC_GUARD_TYPES
#define UIRC_INCLUDED_TYPES #define UIRC_GUARD_TYPES
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
typedef struct { typedef struct {
char* value; /* if present, it isn't NULL and if it has no value, it is "" (aka '\0') */ char* value; /* if present, it isn't NULL and if it has no value, it is "" (aka '\0') */
bool clientbound; bool clientbound;
} IRC_Tag; } IRC_Tag;
typedef struct { typedef struct {
/* See https://ircv3.net/registry#tags for more information */ /* See https://ircv3.net/registry#tags for more information */
IRC_Tag account; IRC_Tag account, batch, label, msgid, multiline_concat, time, typing, react, reply;
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; } IRC_Tags;
#endif #endif /* UIRC_IRCV3 */
typedef struct { typedef struct {
char* nick; char* nick, *user, *host, *orig, *real;
char* user;
char* host;
char* orig;
char* real;
} IRC_User; } IRC_User;
/* This is how a full user source would look like /* This is how a full user source would look like
* NOTE: 'real (Real name)' may only be used in special contexts other than communication. * NOTE: 'real (Real name)' may only be used in special contexts other than communication.
@ -56,11 +44,12 @@ typedef unsigned short IRC_Command;
typedef struct { typedef struct {
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
IRC_Tags tags; IRC_Tags tags;
#endif #endif /* UIRC_IRCV3 */
IRC_User name; IRC_User name;
char* args[16]; /* 0-13 + trailing + NULL */ char* args[16]; /* 0-13 + trailing + NULL */
bool trailing; /* Tells if the last argument is trailing */ bool trailing; /* Tells if the last argument is trailing */
IRC_Command cmd; IRC_Command cmd;
} IRC_Message; } IRC_Message;
#endif
#endif /* UIRC_GUARD_TYPES */

View File

@ -20,9 +20,11 @@
#include "helpers.h" #include "helpers.h"
#include "mappings.h" #include "mappings.h"
#include "types.h" #include "types.h"
#ifndef UIRC_INCLUDED
#define UIRC_INCLUDED
#define UIRC_VERSION 20203110 #ifndef UIRC_GUARD_UIRC
#endif #define UIRC_GUARD_UIRC
#define UIRC_VERSION 20201216
#endif /* UIRC_GUARD_UIRC */

View File

@ -17,104 +17,103 @@
*/ */
#include "assemblers.h" #include "assemblers.h"
signed long Assm_mesg(char* buf, IRC_Message* in, size_t len) signed long
Assm_mesg(char* buf, IRC_Message* in, size_t len)
{ {
if (buf == NULL || in == NULL) return ERR_UIRC_BUFFER_ERR; if (buf == NULL || in == NULL) return ERR_UIRC_BUFFER_ERR;
char* pos = buf; char* pos = buf;
signed long cnt, ret; signed long cnt, ret;
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
if ((ret = Assm_tags(pos, &in->tags, len - (unsigned long)(pos - buf))) < 0) if ((ret = Assm_tags(pos, &in->tags, len - (unsigned long) (pos - buf))) < 0) return ret;
return ret;
else if (ret != 0) { else if (ret != 0) {
pos += ret; pos += ret;
if (!safe_charcpy(&pos, ' ', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, ' ', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
#endif #endif /* UIRC_IRCV3 */
if (in->name.nick != NULL || in->name.host != NULL) { if (in->name.nick != NULL || in->name.host != NULL) {
if (!safe_charcpy(&pos, ':', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, ':', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if ((ret = Assm_user(pos, &in->name, len - (unsigned long)(pos - buf), false)) <= 0) if ((ret = Assm_user(pos, &in->name, len - (unsigned long) (pos - buf), false)) <= 0) return ret;
return ret;
else else
pos += ret; pos += ret;
if (!safe_charcpy(&pos, ' ', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, ' ', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
if (in->cmd < UIRC_FCMD || in->cmd > UIRC_LCMD) { if (in->cmd < UIRC_FCMD || in->cmd > UIRC_LCMD) {
if ((cnt = snprintf(pos, 4, "%.3i", in->cmd)) == 3) if ((cnt = snprintf(pos, 4, "%.3i", in->cmd)) == 3) pos += cnt;
pos += cnt;
else else
return ERR_UIRC_UNKNOWN_TOKEN; return ERR_UIRC_UNKNOWN_TOKEN;
} else { } else {
if (IRC_Cmds[in->cmd] != NULL) { if (IRC_Cmds[in->cmd] != NULL) {
size_t cmdlen = strlen(IRC_Cmds[in->cmd]); size_t cmdlen = strlen(IRC_Cmds[in->cmd]);
if (len - (unsigned long)(pos - buf) > cmdlen && strcpy(pos, IRC_Cmds[in->cmd]) != NULL) if (len - (unsigned long) (pos - buf) > cmdlen && strcpy(pos, IRC_Cmds[in->cmd]) != NULL) pos += cmdlen;
pos += cmdlen;
else else
return ERR_UIRC_UNKNOWN_TOKEN; return ERR_UIRC_UNKNOWN_TOKEN;
} }
} }
for (unsigned int i = 0; in->args[i] != NULL; i++) { for (unsigned int i = 0; in->args[i] != NULL; i++) {
if (len - (unsigned long)(pos - buf) > strlen(in->args[i]) + 2 if (len - (unsigned long) (pos - buf) > strlen(in->args[i]) + 2
&& (cnt = && (cnt =
snprintf(pos, len - (unsigned long)(pos - buf), (in->args[i + 1] == NULL && in->trailing) ? " :%s" : " %s", in->args[i])) snprintf(pos, len - (unsigned long) (pos - buf), (in->args[i + 1] == NULL && in->trailing) ? " :%s" : " %s", in->args[i]))
> 0) > 0)
pos += cnt; pos += cnt;
else else
return ERR_UIRC_BUFFER_ERR; return ERR_UIRC_BUFFER_ERR;
} }
if (!safe_strcpy(&pos, "\r\n", len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, "\r\n", len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
return pos - buf; return pos - buf;
} }
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
signed long Assm_tags(char* buf, IRC_Tags* in, size_t len) signed long
Assm_tags(char* buf, IRC_Tags* in, size_t len)
{ {
if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS;
char* pos = buf; char* pos = buf;
struct tagmapping tagmps[] = {{.name = "time", .assg = &in->time}, {.name = "account", .assg = &in->account}, struct tagmapping tagmps[] = { { .name = "time", .assg = &in->time }, { .name = "account", .assg = &in->account },
{.name = "batch", .assg = &in->batch}, {.name = "label", .assg = &in->label}, { .name = "batch", .assg = &in->batch }, { .name = "label", .assg = &in->label },
{.name = "msgid", .assg = &in->msgid}, {.name = "multiline-concat", .assg = &in->multiline_concat}, { .name = "msgid", .assg = &in->msgid }, { .name = "multiline-concat", .assg = &in->multiline_concat },
{.name = "typing", .assg = &in->typing}, {.name = "react", .assg = &in->react}, { .name = "typing", .assg = &in->typing }, { .name = "react", .assg = &in->react },
{.name = "reply", .assg = &in->reply}}; { .name = "reply", .assg = &in->reply } };
for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) {
if ((*tagmps[i].assg).value != NULL) { if ((*tagmps[i].assg).value != NULL) {
if (pos == buf) { if (pos == buf) {
if (!safe_charcpy(&pos, '@', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '@', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} else { } else {
if (!safe_charcpy(&pos, ';', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, ';', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
if ((*tagmps[i].assg).clientbound) { if ((*tagmps[i].assg).clientbound) {
if (!safe_charcpy(&pos, '+', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '+', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
if (!safe_strcpy(&pos, tagmps[i].name, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, tagmps[i].name, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (*(*tagmps[i].assg).value != '\0') { if (*(*tagmps[i].assg).value != '\0') {
if (!safe_charcpy(&pos, '=', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '=', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
} }
} }
return pos - buf; return pos - buf;
} }
#endif #endif /* UIRC_IRCV3*/
signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig) signed long
Assm_user(char* buf, IRC_User* in, size_t len, bool useorig)
{ {
if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS;
char* pos = buf; char* pos = buf;
if (in->nick == NULL && in->host != NULL) { if (in->nick == NULL && in->host != NULL) {
if (!safe_strcpy(&pos, in->host, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, in->host, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} else if (in->nick != NULL) { } else if (in->nick != NULL) {
if (!safe_strcpy(&pos, in->nick, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, in->nick, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (in->user != NULL) { if (in->user != NULL) {
if (!safe_charcpy(&pos, '!', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '!', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (!safe_strcpy(&pos, in->user, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, in->user, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
if (useorig && in->orig != NULL) { if (useorig && in->orig != NULL) {
if (!safe_charcpy(&pos, '%', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '%', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (!safe_strcpy(&pos, in->orig, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, in->orig, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
if (in->host != NULL) { if (in->host != NULL) {
if (!safe_charcpy(&pos, '@', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_charcpy(&pos, '@', len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
if (!safe_strcpy(&pos, in->host, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (!safe_strcpy(&pos, in->host, len - (unsigned long) (pos - buf))) return ERR_UIRC_BUFFER_ERR;
} }
} else } else
return ERR_UIRC_NULL_ARGS; return ERR_UIRC_NULL_ARGS;

View File

@ -19,18 +19,19 @@
#include "../include/mappings.h" #include "../include/mappings.h"
#include "../include/types.h" #include "../include/types.h"
#include "misc.h" #include "misc.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#ifndef UIRC_INCLUDED_PRIVATE_ASSM #ifndef UIRC_GUARD_PRIVATE_ASSEMBLERS
#define UIRC_INCLUDED_PRIVATE_ASSM #define UIRC_GUARD_PRIVATE_ASSEMBLERS
signed long Assm_mesg(char* buf, IRC_Message* in, size_t len); signed long Assm_mesg(char* buf, IRC_Message* in, size_t len);
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
signed long Assm_tags(char* buf, IRC_Tags* in, size_t len); signed long Assm_tags(char* buf, IRC_Tags* in, size_t len);
#endif #endif /* UIRC_IRCV3 */
signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig); signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
#endif #endif /* UIRC_GUARD_PRIVATE_ASSEMBLERS */

View File

@ -19,101 +19,114 @@
#include "helpers.h" #include "helpers.h"
static IRC_Message imassm_mesg; static IRC_Message imassm_mesg;
char* RESERVED = "*"; char* RESERVED = "*";
void clear_assm(void) { memset((void*)&imassm_mesg, '\0', sizeof(IRC_Message)); } void
IRC_Message* Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req) clear_assm(void)
{
memset((void*) &imassm_mesg, '\0', sizeof(IRC_Message));
}
IRC_Message*
Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req)
{ {
clear_assm(); clear_assm();
int i; int i;
for (i = 0; args[i] != NULL && i < 15; i++) { imassm_mesg.args[i] = args[i]; } for (i = 0; args[i] != NULL && i < 15; i++) { imassm_mesg.args[i] = args[i]; }
if (i < req) return NULL; if (i < req) return NULL;
imassm_mesg.trailing = trailing; imassm_mesg.trailing = trailing;
imassm_mesg.cmd = cmd; imassm_mesg.cmd = cmd;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_USER(char* user, char* realname, int modes) IRC_Message*
Assm_cmd_USER(char* user, char* realname, int modes)
{ {
if (user == NULL || modes < 0 || modes > (MBMASK_INVIS | MBMASK_WALLOPS)) return NULL; if (user == NULL || modes < 0 || modes > (MBMASK_INVIS | MBMASK_WALLOPS)) return NULL;
clear_assm(); clear_assm();
static char local_mode[2]; static char local_mode[2];
snprintf(local_mode, 2, "%i", modes); snprintf(local_mode, 2, "%i", modes);
imassm_mesg.args[0] = user; imassm_mesg.args[0] = user;
imassm_mesg.args[1] = local_mode; imassm_mesg.args[1] = local_mode;
imassm_mesg.args[2] = RESERVED; imassm_mesg.args[2] = RESERVED;
imassm_mesg.args[3] = realname; imassm_mesg.args[3] = realname;
imassm_mesg.trailing = true; imassm_mesg.trailing = true;
imassm_mesg.cmd = USER; imassm_mesg.cmd = USER;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_LINKS(char* remoteserv, char* servmask) IRC_Message*
Assm_cmd_LINKS(char* remoteserv, char* servmask)
{ {
if (remoteserv != NULL && servmask == NULL) return NULL; if (remoteserv != NULL && servmask == NULL) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = (remoteserv == NULL) ? servmask : remoteserv; imassm_mesg.args[0] = (remoteserv == NULL) ? servmask : remoteserv;
imassm_mesg.args[1] = (remoteserv == NULL) ? NULL : servmask; imassm_mesg.args[1] = (remoteserv == NULL) ? NULL : servmask;
imassm_mesg.cmd = LINKS; imassm_mesg.cmd = LINKS;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_WHO(char* mask, bool oper) IRC_Message*
Assm_cmd_WHO(char* mask, bool oper)
{ {
static char* operator= "o"; static char* operator= "o";
if (oper && mask == NULL) return NULL; if (oper && mask == NULL) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = mask; imassm_mesg.args[0] = mask;
imassm_mesg.args[1] = (oper) ? operator: NULL; imassm_mesg.args[1] = (oper) ? operator: NULL;
imassm_mesg.cmd = WHO; imassm_mesg.cmd = WHO;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_WHOIS(char* target, char* mask) IRC_Message*
Assm_cmd_WHOIS(char* target, char* mask)
{ {
if (mask == NULL) return NULL; if (mask == NULL) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = (target == NULL) ? mask : target; imassm_mesg.args[0] = (target == NULL) ? mask : target;
imassm_mesg.args[1] = (target == NULL) ? NULL : mask; imassm_mesg.args[1] = (target == NULL) ? NULL : mask;
imassm_mesg.cmd = WHOIS; imassm_mesg.cmd = WHOIS;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_WHOWAS(char* nick, char* count, char* target) IRC_Message*
Assm_cmd_WHOWAS(char* nick, char* count, char* target)
{ {
if (nick == NULL || (target != NULL && count == NULL)) return NULL; if (nick == NULL || (target != NULL && count == NULL)) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = nick; imassm_mesg.args[0] = nick;
imassm_mesg.args[1] = count; imassm_mesg.args[1] = count;
imassm_mesg.args[2] = target; imassm_mesg.args[2] = target;
imassm_mesg.cmd = WHOWAS; imassm_mesg.cmd = WHOWAS;
return &imassm_mesg; return &imassm_mesg;
} }
/* NOTE: This is what implementation you have to live with /* NOTE: This is what implementation you have to live with
* I would've just used the prefix to set the source but whatever * I would've just used the prefix to set the source but whatever
*/ */
IRC_Message* Assm_cmd_PING(char* source, char* target) IRC_Message*
Assm_cmd_PING(char* source, char* target)
{ {
if (source == NULL && target == NULL) return NULL; if (source == NULL && target == NULL) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = (source != NULL) ? source : target; imassm_mesg.args[0] = (source != NULL) ? source : target;
imassm_mesg.args[1] = (source != NULL && target != NULL) ? target : NULL; imassm_mesg.args[1] = (source != NULL && target != NULL) ? target : NULL;
imassm_mesg.trailing = (source != NULL && target == NULL) ? true : false; imassm_mesg.trailing = (source != NULL && target == NULL) ? true : false;
imassm_mesg.cmd = PING; imassm_mesg.cmd = PING;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_SUMMON(char* user, char* target, char* channel) IRC_Message*
Assm_cmd_SUMMON(char* user, char* target, char* channel)
{ {
if (user == NULL || (channel != NULL && target == NULL)) return NULL; if (user == NULL || (channel != NULL && target == NULL)) return NULL;
clear_assm(); clear_assm();
imassm_mesg.args[0] = user; imassm_mesg.args[0] = user;
imassm_mesg.args[1] = target; imassm_mesg.args[1] = target;
imassm_mesg.args[2] = channel; imassm_mesg.args[2] = channel;
imassm_mesg.cmd = SUMMON; imassm_mesg.cmd = SUMMON;
return &imassm_mesg; return &imassm_mesg;
} }
IRC_Message* Assm_cmd_USERHOST(char* users[]) IRC_Message*
Assm_cmd_USERHOST(char* users[])
{ {
if (users[0] == NULL) return NULL; if (users[0] == NULL) return NULL;
clear_assm(); clear_assm();
@ -122,7 +135,8 @@ IRC_Message* Assm_cmd_USERHOST(char* users[])
return &imassm_mesg; return &imassm_mesg;
} }
/* NOTE: Limited to 14 nicks per command */ /* NOTE: Limited to 14 nicks per command */
IRC_Message* Assm_cmd_ISON(char* users[]) IRC_Message*
Assm_cmd_ISON(char* users[])
{ {
if (users[0] == NULL) return NULL; if (users[0] == NULL) return NULL;
clear_assm(); clear_assm();
@ -131,7 +145,8 @@ IRC_Message* Assm_cmd_ISON(char* users[])
return &imassm_mesg; return &imassm_mesg;
} }
void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target) void
Tok_cmd_PING(IRC_Message* mesg, char** source, char** target)
{ {
*source = (mesg->args[0] == NULL && mesg->trailing) ? mesg->args[2] : (mesg->args[1] != NULL) ? mesg->args[0] : NULL; *source = (mesg->args[0] == NULL && mesg->trailing) ? mesg->args[2] : (mesg->args[1] != NULL) ? mesg->args[0] : NULL;
*target = (mesg->args[1] == NULL) ? mesg->args[0] : mesg->args[1]; *target = (mesg->args[1] == NULL) ? mesg->args[0] : mesg->args[1];
@ -140,19 +155,21 @@ void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target)
* (stands for first argument optional) * (stands for first argument optional)
* [ <optarg> ] <reqarg> * [ <optarg> ] <reqarg>
*/ */
void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg) void
Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg)
{ {
*optarg = (mesg->args[1] != NULL) ? mesg->args[0] : NULL; *optarg = (mesg->args[1] != NULL) ? mesg->args[0] : NULL;
*reqarg = (mesg->args[1] != NULL) ? mesg->args[1] : mesg->args[0]; *reqarg = (mesg->args[1] != NULL) ? mesg->args[1] : mesg->args[0];
} }
int Tok_CAPS(char* caps) int
Tok_CAPS(char* caps)
{ {
int temp = 0; int temp = 0;
char* cur = NULL; char* cur = NULL;
if ((cur = strtok(caps, " ")) != NULL) { if ((cur = strtok(caps, " ")) != NULL) {
do { do {
for (int i = 1; (unsigned long)i < (sizeof(IRC_v3_Caps) / sizeof(*IRC_v3_Caps)); i++) { for (int i = 1; (unsigned long) i < (sizeof(IRC_v3_Caps) / sizeof(*IRC_v3_Caps)); i++) {
if (strcmp(IRC_v3_Caps[i], cur) == 0) { if (strcmp(IRC_v3_Caps[i], cur) == 0) {
temp |= CAPBIT(i); temp |= CAPBIT(i);
break; break;

View File

@ -18,16 +18,17 @@
#include "../include/mappings.h" #include "../include/mappings.h"
#include "../include/types.h" #include "../include/types.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#ifndef UIRC_INCLUDED_PRIVATE_HELPERS #ifndef UIRC_GUARD_PRIVATE_HELPERS
#define UIRC_INCLUDED_PRIVATE_HELPERS #define UIRC_GUARD_PRIVATE_HELPERS
extern char* RESERVED; extern char* RESERVED;
void clear_assm(void); void clear_assm(void);
IRC_Message* Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req); IRC_Message* Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req);
@ -43,6 +44,6 @@ IRC_Message* Assm_cmd_ISON(char* users[]);
void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target); void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target);
void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg); void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg);
int Tok_CAPS(char* caps); int Tok_CAPS(char* caps);
#endif #endif /* UIRC_GUARD_PRIVATE_HELPERS */

View File

@ -17,61 +17,63 @@
*/ */
#include "misc.h" #include "misc.h"
const char* const IRC_Cmds[] = {[ADMIN] = "ADMIN", [AWAY] = "AWAY", [CONNECT] = "CONNECT", [DIE] = "DIE", const char* const IRC_Cmds[] = { [ADMIN] = "ADMIN", [AWAY] = "AWAY", [CONNECT] = "CONNECT", [DIE] = "DIE",
[ERROR] = "ERROR", [INFO] = "INFO", [INVITE] = "INVITE", [ISON] = "ISON", [ERROR] = "ERROR", [INFO] = "INFO", [INVITE] = "INVITE", [ISON] = "ISON",
[JOIN] = "JOIN", [KICK] = "KICK", [KILL] = "KILL", [LINKS] = "LINKS", [JOIN] = "JOIN", [KICK] = "KICK", [KILL] = "KILL", [LINKS] = "LINKS",
[LIST] = "LIST", [LUSERS] = "LUSERS", [MODE] = "MODE", [MOTD] = "MOTD", [LIST] = "LIST", [LUSERS] = "LUSERS", [MODE] = "MODE", [MOTD] = "MOTD",
[NAMES] = "NAMES", [NICK] = "NICK", [NOTICE] = "NOTICE", [OPER] = "OPER", [NAMES] = "NAMES", [NICK] = "NICK", [NOTICE] = "NOTICE", [OPER] = "OPER",
[PART] = "PART", [PASS] = "PASS", [PING] = "PING", [PONG] = "PONG", [PART] = "PART", [PASS] = "PASS", [PING] = "PING", [PONG] = "PONG",
[PRIVMSG] = "PRIVMSG", [QUIT] = "QUIT", [REHASH] = "REHASH", [RESTART] = "RESTART", [PRIVMSG] = "PRIVMSG", [QUIT] = "QUIT", [REHASH] = "REHASH", [RESTART] = "RESTART",
[SERVER] = "SERVER", [SERVICE] = "SERVICE", [SERVLIST] = "SERVLIST", [SQUERY] = "SQUERY", [SERVER] = "SERVER", [SERVICE] = "SERVICE", [SERVLIST] = "SERVLIST", [SQUERY] = "SQUERY",
[SQUIT] = "SQUIT", [STATS] = "STATS", [SUMMON] = "SUMMON", [TIME] = "TIME", [SQUIT] = "SQUIT", [STATS] = "STATS", [SUMMON] = "SUMMON", [TIME] = "TIME",
[TOPIC] = "TOPIC", [TRACE] = "TRACE", [USERHOST] = "USERHOST", [USERS] = "USERS", [TOPIC] = "TOPIC", [TRACE] = "TRACE", [USERHOST] = "USERHOST", [USERS] = "USERS",
[USER] = "USER", [VERSION] = "VERSION", [WALLOPS] = "WALLOPS", [WHOIS] = "WHOIS", [USER] = "USER", [VERSION] = "VERSION", [WALLOPS] = "WALLOPS", [WHOIS] = "WHOIS",
[WHOWAS] = "WHOWAS", [WHO] = "WHO", [WHOWAS] = "WHOWAS", [WHO] = "WHO",
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
[ACCOUNT] = "ACCOUNT", [ACC] = "ACC", [ACK] = "ACK", [AUTHENTICATE] = "AUTHENTICATE", [ACCOUNT] = "ACCOUNT", [ACC] = "ACC", [ACK] = "ACK", [AUTHENTICATE] = "AUTHENTICATE",
[BATCH] = "BATCH", [CAP] = "CAP", [CHGHOST] = "CHGHOST", [FAIL] = "FAIL", [BATCH] = "BATCH", [CAP] = "CAP", [CHGHOST] = "CHGHOST", [FAIL] = "FAIL",
[MONITOR] = "MONITOR", [NOTE] = "NOTE", [RENAME] = "RENAME", [RESUME] = "RESUME", [MONITOR] = "MONITOR", [NOTE] = "NOTE", [RENAME] = "RENAME", [RESUME] = "RESUME",
[SETNAME] = "SETNAME", [WARN] = "WARN", [WEBIRC] = "WEBIRC" [SETNAME] = "SETNAME", [WARN] = "WARN", [WEBIRC] = "WEBIRC"
#endif #endif /* UIRC_IRCV3 */
}; };
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
const char* const IRC_v3_Caps[] = { const char* const IRC_v3_Caps[] = {
[CAP_ACCOUNT_NOTIFY] = "account-notify", [CAP_ACCOUNT_NOTIFY] = "account-notify",
[CAP_ACCOUNT_TAG] = "account-tag", [CAP_ACCOUNT_TAG] = "account-tag",
[CAP_AWAY_NOTIFY] = "away-notify", [CAP_AWAY_NOTIFY] = "away-notify",
[CAP_BATCH] = "batch", [CAP_BATCH] = "batch",
[CAP_CAP_NOTIFY] = "cap-notify", [CAP_CAP_NOTIFY] = "cap-notify",
[CAP_CHANNEL_RENAME] = "channel-rename", [CAP_CHANNEL_RENAME] = "channel-rename",
[CAP_CHGHOST] = "chghost", [CAP_CHGHOST] = "chghost",
[CAP_ECHO_MESSAGE] = "echo-message", [CAP_ECHO_MESSAGE] = "echo-message",
[CAP_EXTENDED_JOIN] = "extended-join", [CAP_EXTENDED_JOIN] = "extended-join",
[CAP_INVITE_NOTIFY] = "invite-notify", [CAP_INVITE_NOTIFY] = "invite-notify",
[CAP_LABELED_RESPONSE] = "labeled-response", [CAP_LABELED_RESPONSE] = "labeled-response",
[CAP_MESSAGE_TAGS] = "message-tags", [CAP_MESSAGE_TAGS] = "message-tags",
[CAP_MONITOR] = "monitor", [CAP_MONITOR] = "monitor",
[CAP_MULTI_PREFIX] = "multi-prefix", [CAP_MULTI_PREFIX] = "multi-prefix",
[CAP_MULTILINE] = "multiline", [CAP_MULTILINE] = "multiline",
[CAP_SASL] = "sasl", [CAP_SASL] = "sasl",
[CAP_SERVER_TIME] = "server-time", [CAP_SERVER_TIME] = "server-time",
[CAP_SETNAME] = "setname", [CAP_SETNAME] = "setname",
[CAP_TLS] = "tls", [CAP_TLS] = "tls",
[CAP_USERHOST_IN_NAMES] = "userhost-in-names", [CAP_USERHOST_IN_NAMES] = "userhost-in-names",
}; };
#endif #endif /* UIRC_IRCV3 */
signed short Ircmd_stoi(char* str) signed short
Ircmd_stoi(char* str)
{ {
if (str == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL) return ERR_UIRC_NULL_ARGS;
for (signed short i = UIRC_FCMD; i <= (signed short)UIRC_LCMD; i++) { for (signed short i = UIRC_FCMD; i <= (signed short) UIRC_LCMD; i++) {
if (IRC_Cmds[i] != NULL && strcmp(IRC_Cmds[i], str) == 0) return i; if (IRC_Cmds[i] != NULL && strcmp(IRC_Cmds[i], str) == 0) return i;
} }
return ERR_UIRC_UNKNOWN_TOKEN; return ERR_UIRC_UNKNOWN_TOKEN;
} }
size_t safe_strcpy(char** dest, const char* src, size_t lef) size_t
safe_strcpy(char** dest, const char* src, size_t lef)
{ {
size_t cnt; size_t cnt;
if (lef > (cnt = strlen(src)) + 1) { if (lef > (cnt = strlen(src)) + 1) {
@ -82,27 +84,30 @@ size_t safe_strcpy(char** dest, const char* src, size_t lef)
return 0; return 0;
} }
bool safe_charcpy(char** dest, const char c, size_t lef) bool
safe_charcpy(char** dest, const char c, size_t lef)
{ {
if (lef > 1) { if (lef > 1) {
*(*dest)++ = c; *(*dest)++ = c;
**dest = '\0'; **dest = '\0';
return 1; return 1;
} else } else
return 0; return 0;
} }
void skip_spaces(char** addr) void
skip_spaces(char** addr)
{ {
for (; **addr == ' '; (*addr)++) for (; **addr == ' '; (*addr)++)
; ;
} }
char* strtok_mr(char** addr, const char* tokens) char*
strtok_mr(char** addr, const char* tokens)
{ {
if (addr == NULL || *addr == NULL || !**addr || tokens == NULL) return NULL; if (addr == NULL || *addr == NULL || !**addr || tokens == NULL) return NULL;
char* save = *addr; char* save = *addr;
const char* tok = NULL; const char* tok = NULL;
do { do {
if (!**addr) return save; if (!**addr) return save;
for (tok = tokens; *tok; tok++) { for (tok = tokens; *tok; tok++) {

View File

@ -18,23 +18,24 @@
#include "../include/mappings.h" #include "../include/mappings.h"
#include "../include/types.h" #include "../include/types.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifndef UIRC_INCLUDED_PRIVATE_MISC #ifndef UIRC_GUARD_PRIVATE_MISC
#define UIRC_INCLUDED_PRIVATE_MISC #define UIRC_GUARD_PRIVATE_MISC
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
struct tagmapping { struct tagmapping {
const char* const name; const char* const name;
IRC_Tag* assg; IRC_Tag* assg;
}; };
#endif #endif /* UIRC_IRCV3 */
signed short Ircmd_stoi(char* str); signed short Ircmd_stoi(char* str);
size_t safe_strcpy(char** dest, const char* src, size_t lef); size_t safe_strcpy(char** dest, const char* src, size_t lef);
bool safe_charcpy(char** dest, char c, size_t lef); bool safe_charcpy(char** dest, char c, size_t lef);
void skip_spaces(char** addr); void skip_spaces(char** addr);
char* strtok_mr(char** addr, const char* tokens); char* strtok_mr(char** addr, const char* tokens);
#endif #endif /* UIRC_GUARD_PRIVATE_MISC */

View File

@ -22,8 +22,8 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#ifndef UIRC_INCLUDED_PRIVATE_TAGHELPERS #ifndef UIRC_GUARD_PRIVATE_TAGHELPERS
#define UIRC_INCLUDED_PRIVATE_TAGHELPERS #define UIRC_GUARD_PRIVATE_TAGHELPERS
size_t Assm_tag_timestamp(char* buf, size_t len, time_t time); size_t Assm_tag_timestamp(char* buf, size_t len, time_t time);
#endif #endif /* UIRC_GUARD_PRIVATE_TAGHELPERS */

View File

@ -17,10 +17,11 @@
*/ */
#include "tokenizers.h" #include "tokenizers.h"
signed int Tok_mesg(char* str, IRC_Message* out) signed int
Tok_mesg(char* str, IRC_Message* out)
{ {
if (str == NULL || out == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL || out == NULL) return ERR_UIRC_NULL_ARGS;
int ret; int ret;
char *progr = str, *command; char *progr = str, *command;
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
if (*progr == '@') { if (*progr == '@') {
@ -31,7 +32,7 @@ signed int Tok_mesg(char* str, IRC_Message* out)
return ERR_UIRC_INVALID_FORMAT; return ERR_UIRC_INVALID_FORMAT;
} }
skip_spaces(&progr); skip_spaces(&progr);
#endif #endif /* UIRC_IRCV3 */
if (*progr == ':') { if (*progr == ':') {
char* prefix; char* prefix;
if ((prefix = strtok_mr(&progr, " ")) != NULL) { if ((prefix = strtok_mr(&progr, " ")) != NULL) {
@ -46,9 +47,9 @@ signed int Tok_mesg(char* str, IRC_Message* out)
signed short temp; signed short temp;
if (isalpha(*command)) { if (isalpha(*command)) {
if ((temp = Ircmd_stoi(command)) < UIRC_FCMD || temp > UIRC_LCMD) return ERR_UIRC_UNKNOWN_TOKEN; if ((temp = Ircmd_stoi(command)) < UIRC_FCMD || temp > UIRC_LCMD) return ERR_UIRC_UNKNOWN_TOKEN;
out->cmd = (IRC_Command)temp; out->cmd = (IRC_Command) temp;
} else { } else {
out->cmd = (IRC_Command)atoi(command); out->cmd = (IRC_Command) atoi(command);
} }
} else } else
return ERR_UIRC_INVALID_FORMAT; return ERR_UIRC_INVALID_FORMAT;
@ -59,7 +60,7 @@ signed int Tok_mesg(char* str, IRC_Message* out)
for (i = 0; i < 15 && *progr;) { for (i = 0; i < 15 && *progr;) {
if (i == 14 || *progr == ':') { if (i == 14 || *progr == ':') {
out->args[i++] = (*progr == ':') ? progr + 1 : progr; out->args[i++] = (*progr == ':') ? progr + 1 : progr;
out->trailing = true; out->trailing = true;
break; break;
} else { } else {
if ((out->args[i++] = strtok_mr(&progr, " ")) == NULL) return ERR_UIRC_INVALID_FORMAT; if ((out->args[i++] = strtok_mr(&progr, " ")) == NULL) return ERR_UIRC_INVALID_FORMAT;
@ -71,16 +72,19 @@ signed int Tok_mesg(char* str, IRC_Message* out)
} }
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
signed int Tok_tags(char* str, IRC_Tags* out) signed int
Tok_tags(char* str, IRC_Tags* out)
{ {
if (str == NULL || out == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL || out == NULL) return ERR_UIRC_NULL_ARGS;
char *cval, *cpos = str, *ctag = NULL; char * cval, *cpos = str, *ctag = NULL;
bool clientbound; bool clientbound;
const struct tagmapping tagmps[] = {{.name = "time", .assg = &out->time}, {.name = "account", .assg = &out->account}, const struct tagmapping tagmps[] = {
{.name = "batch", .assg = &out->batch}, {.name = "label", .assg = &out->label}, { .name = "time", .assg = &out->time }, { .name = "account", .assg = &out->account },
{.name = "msgid", .assg = &out->msgid}, {.name = "multiline-concat", .assg = &out->multiline_concat}, { .name = "batch", .assg = &out->batch }, { .name = "label", .assg = &out->label },
{.name = "typing", .assg = &out->typing}, {.name = "react", .assg = &out->react}, { .name = "msgid", .assg = &out->msgid }, { .name = "multiline-concat", .assg = &out->multiline_concat },
{.name = "reply", .assg = &out->reply}}; { .name = "typing", .assg = &out->typing }, { .name = "react", .assg = &out->react },
{ .name = "reply", .assg = &out->reply }
};
if (*cpos == '@') cpos++; if (*cpos == '@') cpos++;
while ((ctag = strtok_mr(&cpos, "; ")) != NULL) { while ((ctag = strtok_mr(&cpos, "; ")) != NULL) {
clientbound = false; clientbound = false;
@ -95,23 +99,24 @@ signed int Tok_tags(char* str, IRC_Tags* out)
* This is done for a few reasons. First, we have a non-null address so we show that * This is done for a few reasons. First, we have a non-null address so we show that
* the tag is present and second, we have no value that way * the tag is present and second, we have no value that way
*/ */
(*tagmps[i].assg).value = (cval != NULL) ? cval : ctag + strlen(ctag); (*tagmps[i].assg).value = (cval != NULL) ? cval : ctag + strlen(ctag);
(*tagmps[i].assg).clientbound = clientbound; (*tagmps[i].assg).clientbound = clientbound;
} }
} }
} }
return 1; return 1;
} }
#endif #endif /* UIRC_IRCV3 */
signed int Tok_user(char* str, IRC_User* out, bool useorig) signed int
Tok_user(char* str, IRC_User* out, bool useorig)
{ {
char* pos = (*str == ':') ? str + 1 : str; char* pos = (*str == ':') ? str + 1 : str;
if ((out->host = strchr(pos, '@')) != NULL) *(out->host++) = '\0'; if ((out->host = strchr(pos, '@')) != NULL) *(out->host++) = '\0';
if (useorig && (out->orig = strchr(pos, '%')) != NULL) *(out->orig++) = '\0'; if (useorig && (out->orig = strchr(pos, '%')) != NULL) *(out->orig++) = '\0';
if ((out->user = strchr(pos, '!')) if ((out->user = strchr(pos, '!'))
!= NULL) /* RFC2812 says this cannot be here without the host but RFC1459 says it can, we accept both options */ != NULL) /* RFC2812 says this cannot be here without the host but RFC1459 says it can, we accept both options */
*((char*)out->user++) = '\0'; *((char*) out->user++) = '\0';
if (!*(out->nick = pos)) return ERR_UIRC_INVALID_FORMAT; if (!*(out->nick = pos)) return ERR_UIRC_INVALID_FORMAT;
/* NOTE: De-facto standard below /* NOTE: De-facto standard below
* This assumes that every prefix without a '@host' and '!user' is itself a host prefix only * This assumes that every prefix without a '@host' and '!user' is itself a host prefix only

View File

@ -19,19 +19,20 @@
#include "../include/mappings.h" #include "../include/mappings.h"
#include "../include/types.h" #include "../include/types.h"
#include "misc.h" #include "misc.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef UIRC_INCLUDED_PRIVATE_TKNIZ #ifndef UIRC_GUARD_PRIVATE_TOKENIZERS
#define UIRC_INCLUDED_PRIVATE_TKNIZ #define UIRC_GUARD_PRIVATE_TOKENIZERS
signed int Tok_mesg(char* str, IRC_Message* out); signed int Tok_mesg(char* str, IRC_Message* out);
#ifdef UIRC_IRCV3 #ifdef UIRC_IRCV3
signed int Tok_tags(char* str, IRC_Tags* out); signed int Tok_tags(char* str, IRC_Tags* out);
#endif #endif /* UIRC_IRCV3 */
signed int Tok_user(char* str, IRC_User* out, bool useorig); signed int Tok_user(char* str, IRC_User* out, bool useorig);
#endif #endif /* UIRC_GUARD_PRIVATE_TOKENIZERS */

View File

@ -1,4 +1,3 @@
/* /*
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC) * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
* Copyright (c) 2019, 2020 Alex-David Denes * Copyright (c) 2019, 2020 Alex-David Denes
@ -18,7 +17,8 @@
*/ */
#include "validators.h" #include "validators.h"
signed int Val_mesg(IRC_Message* mesg) signed int
Val_mesg(IRC_Message* mesg)
{ {
if (mesg == NULL) return ERR_UIRC_NULL_ARGS; if (mesg == NULL) return ERR_UIRC_NULL_ARGS;
for (unsigned int i = 0; mesg->args[i] != NULL; i++) { for (unsigned int i = 0; mesg->args[i] != NULL; i++) {
@ -30,7 +30,8 @@ signed int Val_mesg(IRC_Message* mesg)
return 1; return 1;
} }
signed int Val_type_nocrlf(char* str) signed int
Val_type_nocrlf(char* str)
{ {
if (str == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL) return ERR_UIRC_NULL_ARGS;
for (; *str; str++) { for (; *str; str++) {
@ -39,7 +40,8 @@ signed int Val_type_nocrlf(char* str)
return 1; return 1;
} }
signed int Val_type_nospcl(char* str) signed int
Val_type_nospcl(char* str)
{ {
if (str == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL) return ERR_UIRC_NULL_ARGS;
for (; *str; str++) { for (; *str; str++) {
@ -48,7 +50,8 @@ signed int Val_type_nospcl(char* str)
return 1; return 1;
} }
signed int Val_type_noblcm(char* str) signed int
Val_type_noblcm(char* str)
{ {
if (str == NULL) return ERR_UIRC_NULL_ARGS; if (str == NULL) return ERR_UIRC_NULL_ARGS;
for (; *str; str++) { for (; *str; str++) {
@ -57,7 +60,8 @@ signed int Val_type_noblcm(char* str)
return 1; return 1;
} }
signed int Val_channame(char* chan) signed int
Val_channame(char* chan)
{ {
if (chan == NULL) return ERR_UIRC_NULL_ARGS; if (chan == NULL) return ERR_UIRC_NULL_ARGS;
if (*chan != '#' && *chan != '+' && *chan != '!' && *chan != '&') return 0; if (*chan != '#' && *chan != '+' && *chan != '!' && *chan != '&') return 0;
@ -69,7 +73,7 @@ signed int Val_channame(char* chan)
return 0; return 0;
} }
*clps = ':'; *clps = ':';
chan = ++clps; chan = ++clps;
} }
if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) return 0; if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) return 0;
return 1; return 1;

View File

@ -18,15 +18,16 @@
#include "../include/mappings.h" #include "../include/mappings.h"
#include "../include/types.h" #include "../include/types.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifndef UIRC_INCLUDED_PRIVATE_VALIDATORS #ifndef UIRC_GUARD_PRIVATE_VALIDATORS
#define UIRC_INCLUDED_PRIVATE_VALIDATORS #define UIRC_GUARD_PRIVATE_VALIDATORS
signed int Val_mesg(IRC_Message* mesg); signed int Val_mesg(IRC_Message* mesg);
signed int Val_type_nocrlf(char* str); signed int Val_type_nocrlf(char* str);
signed int Val_type_nospcl(char* str); signed int Val_type_nospcl(char* str);
signed int Val_type_noblcm(char* str); signed int Val_type_noblcm(char* str);
signed int Val_channame(char* chan); signed int Val_channame(char* chan);
#endif #endif /* UIRC_GUARD_PRIVATE_VALIDATORS */