Split files better
This commit is contained in:
parent
5dde15f3b6
commit
edd9790cdf
|
@ -18,10 +18,15 @@ if ( BUILD_TESTS )
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
set(build_FILES src/uirc.c)
|
set(build_FILES
|
||||||
|
src/assemblers.c
|
||||||
|
src/misc.c
|
||||||
|
src/tokenizers.c
|
||||||
|
src/validators.c
|
||||||
|
)
|
||||||
if ( USE_HELPERS )
|
if ( USE_HELPERS )
|
||||||
message("Helper functions are going to be built.")
|
message("Helper functions are going to be built.")
|
||||||
set(build_FILES src/uirc.c src/helpers.c)
|
set(build_FILES ${build_FILES} src/helpers.c)
|
||||||
endif()
|
endif()
|
||||||
add_library(uirc SHARED ${build_FILES})
|
add_library(uirc SHARED ${build_FILES})
|
||||||
set_property(TARGET uirc PROPERTY C_STANDARD 99)
|
set_property(TARGET uirc PROPERTY C_STANDARD 99)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "types.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifndef _UIRC_INCLUDED_FUNCT
|
||||||
|
#define _UIRC_INCLUDED_FUNCT
|
||||||
|
/* 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_user(char* str, IRC_User* out, bool useorig);
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
extern signed int Tok_tags(char* str, IRC_Tags* out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Assemblers: They return the amount of bytes written and write directly at buf */
|
||||||
|
extern signed int Assm_mesg(char* buf, IRC_Message* in, size_t len);
|
||||||
|
extern signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
extern signed int Assm_tags(char* buf, IRC_Tags* in, size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Validators: They check that the parsed message is valid and follows the standard */
|
||||||
|
extern signed int Val_mesg(IRC_Message* mesg);
|
||||||
|
extern signed int Val_channame(char* chan);
|
||||||
|
extern signed int Val_type_nocrlf(char* str);
|
||||||
|
extern signed int Val_type_nospcl(char* str);
|
||||||
|
extern signed int Val_type_noblcm(char* str);
|
||||||
|
|
||||||
|
/* Converters: They convert from one format to another */
|
||||||
|
extern signed int Ircmd_stoi(char* str);
|
||||||
|
#endif
|
|
@ -15,11 +15,12 @@
|
||||||
* 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 "structs.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "types.h"
|
||||||
#ifdef UIRC_HELPERS
|
#ifdef UIRC_HELPERS
|
||||||
#ifndef _UIRC_HELPERS_INCLUDED
|
|
||||||
#define _UIRC_HELPERS_INCLUDED
|
#ifndef _UIRC_INCLUDED_HELPERS
|
||||||
|
#define _UIRC_INCLUDED_HELPERS
|
||||||
extern IRC_Message* Assm_cmd_NICK(char* nick);
|
extern IRC_Message* Assm_cmd_NICK(char* nick);
|
||||||
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_PASS(char* password);
|
extern IRC_Message* Assm_cmd_PASS(char* password);
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
* 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/>.
|
||||||
*/
|
*/
|
||||||
#ifndef _UIRC_ENUMS_INCLUDED
|
#ifndef _UIRC_INCLUDED_ENUMS
|
||||||
#define _UIRC_ENUMS_INCLUDED
|
#define _UIRC_INCLUDED_ENUMS
|
||||||
|
|
||||||
#define ERR_UIRC_GENERIC -1
|
#define ERR_UIRC_GENERIC -1
|
||||||
#define ERR_UIRC_NULL_ARGS -2
|
#define ERR_UIRC_NULL_ARGS -2
|
||||||
|
@ -29,9 +29,11 @@
|
||||||
#define MBMASK_WALLOPS 2 /* 010 */
|
#define MBMASK_WALLOPS 2 /* 010 */
|
||||||
#define MBMASK_INVIS 4 /* 100 */
|
#define MBMASK_INVIS 4 /* 100 */
|
||||||
|
|
||||||
|
extern const char* const IRC_Cmds[];
|
||||||
|
|
||||||
#define UIRC_FCMD ADMIN
|
#define UIRC_FCMD ADMIN
|
||||||
enum commands {
|
enum commands {
|
||||||
ADMIN,
|
ADMIN = 10,
|
||||||
AWAY,
|
AWAY,
|
||||||
CONNECT,
|
CONNECT,
|
||||||
DIE,
|
DIE,
|
||||||
|
@ -94,7 +96,9 @@ enum commands {
|
||||||
WARN, /* https://ircv3.net/specs/extensions/standard-replies */
|
WARN, /* https://ircv3.net/specs/extensions/standard-replies */
|
||||||
WEBIRC, /* https://ircv3.net/specs/extensions/webirc */
|
WEBIRC, /* https://ircv3.net/specs/extensions/webirc */
|
||||||
#define UIRC_LCMD WEBIRC
|
#define UIRC_LCMD WEBIRC
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define UIRC_LCMD WHOWAS
|
#define UIRC_LCMD WHOWAS
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,16 +16,17 @@
|
||||||
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#ifndef _UIRC_STRUCTS_INCLUDED
|
#ifndef _UIRC_INCLUDED_TYPES
|
||||||
#define _UIRC_STRUCTS_INCLUDED
|
#define _UIRC_INCLUDED_TYPES
|
||||||
|
|
||||||
#ifdef UIRC_IRCV3
|
#ifdef UIRC_IRCV3
|
||||||
typedef struct uirc_tag {
|
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;
|
||||||
#endif
|
#endif
|
||||||
typedef struct name {
|
|
||||||
|
typedef struct {
|
||||||
char* nick;
|
char* nick;
|
||||||
char* user;
|
char* user;
|
||||||
char* host;
|
char* host;
|
||||||
|
@ -35,8 +36,9 @@ typedef struct name {
|
||||||
/* 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.
|
||||||
* nick!user%orig@host */
|
* nick!user%orig@host */
|
||||||
|
|
||||||
#ifdef UIRC_IRCV3
|
#ifdef UIRC_IRCV3
|
||||||
typedef struct uirc_tags {
|
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;
|
||||||
IRC_Tag batch;
|
IRC_Tag batch;
|
||||||
|
@ -49,7 +51,8 @@ typedef struct uirc_tags {
|
||||||
IRC_Tag reply;
|
IRC_Tag reply;
|
||||||
} IRC_Tags;
|
} IRC_Tags;
|
||||||
#endif
|
#endif
|
||||||
typedef struct uirc_message {
|
|
||||||
|
typedef struct {
|
||||||
#ifdef UIRC_IRCV3
|
#ifdef UIRC_IRCV3
|
||||||
IRC_Tags tags;
|
IRC_Tags tags;
|
||||||
#endif
|
#endif
|
|
@ -15,35 +15,13 @@
|
||||||
* 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 "helpers.h"
|
#include "helpers.h"
|
||||||
|
#include "types.h"
|
||||||
#include "mappings.h"
|
#include "mappings.h"
|
||||||
#include "structs.h"
|
#include "functions.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifndef UIRC_INCLUDED
|
#ifndef UIRC_INCLUDED
|
||||||
#define UIRC_INCLUDED
|
#define UIRC_INCLUDED
|
||||||
extern const char* const uirc_ircmd[];
|
|
||||||
|
|
||||||
/* Tokenizers: They take a string in and point their struct element pointers at tokens and end tokens with '\0' */
|
#define UIRC_VERSION 0.6
|
||||||
extern signed int Tok_mesg(char* str, IRC_Message* out);
|
|
||||||
extern signed int Tok_user(char* str, IRC_User* out, bool useorig);
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
extern signed int Tok_tags(char* str, IRC_Tags* out);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Assemblers: They return the amount of bytes written and write directly at buf */
|
|
||||||
extern signed int Assm_mesg(char* buf, IRC_Message* in, size_t len);
|
|
||||||
extern signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
extern signed int Assm_tags(char* buf, IRC_Tags* in, size_t len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Validators: They check that the parsed message is valid and follows the standard */
|
|
||||||
extern signed int Val_mesg(IRC_Message* mesg);
|
|
||||||
extern signed int Val_channame(char* chan);
|
|
||||||
extern signed int Val_type_nocrlf(char* str);
|
|
||||||
extern signed int Val_type_nospcl(char* str);
|
|
||||||
extern signed int Val_type_noblcm(char* str);
|
|
||||||
|
|
||||||
extern signed int Ircmd_stoi(char* str);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "assemblers.h"
|
||||||
|
|
||||||
|
signed int Assm_mesg(char* buf, IRC_Message* in, size_t len)
|
||||||
|
{
|
||||||
|
if (buf == NULL || in == NULL)
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
char* pos = buf;
|
||||||
|
unsigned int cnt;
|
||||||
|
signed int ret;
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
if ((ret = Assm_tags(pos, &in->tags, len - (pos - buf))) >= 0)
|
||||||
|
pos += ret;
|
||||||
|
else
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
if (in->name.nick != NULL || in->name.host != NULL) {
|
||||||
|
if (!safe_charcpy(&pos, ':', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if ((ret = Assm_user(pos, &in->name, len - (pos - buf), false)) <= 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
pos += ret;
|
||||||
|
if (!safe_charcpy(&pos, ' ', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if ((IRC_Cmds[in->cmd] != NULL) && len - (pos - buf) > (cnt = strlen(IRC_Cmds[in->cmd])) + 1 && strcpy(pos, IRC_Cmds[in->cmd]) != NULL)
|
||||||
|
pos += cnt;
|
||||||
|
else
|
||||||
|
return ERR_UIRC_GENERIC;
|
||||||
|
for (unsigned int i = 0; i < 14 && in->args[i] != NULL; i++) {
|
||||||
|
if (len - (pos - buf) > strlen(in->args[i]) + 2 && (cnt = snprintf(pos, len - (pos - buf), " %s", in->args[i])) > 0)
|
||||||
|
pos += cnt;
|
||||||
|
else
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if (in->trailing != NULL) {
|
||||||
|
if (len - (pos - buf) > strlen(in->trailing) + 3 && (cnt = snprintf(pos, len - (pos - buf), " :%s", in->trailing)) > 0)
|
||||||
|
pos += cnt;
|
||||||
|
else
|
||||||
|
return ERR_UIRC_GENERIC;
|
||||||
|
}
|
||||||
|
if (!safe_strcpy(&pos, "\r\n", len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
return pos - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
signed int Assm_tags(char* buf, IRC_Tags* in, size_t len)
|
||||||
|
{
|
||||||
|
if (buf == NULL || in == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
char* pos = buf;
|
||||||
|
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).value != NULL) {
|
||||||
|
if (pos == buf) {
|
||||||
|
if (!safe_charcpy(&pos, '@', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
} else {
|
||||||
|
if (!safe_charcpy(&pos, ';', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if ((*tagmps[i].assg).clientbound) {
|
||||||
|
if (!safe_charcpy(&pos, '+', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if (!safe_strcpy(&pos, tagmps[i].name, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (*(*tagmps[i].assg).value != '\0') {
|
||||||
|
if (!safe_charcpy(&pos, '=', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pos - buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig)
|
||||||
|
{
|
||||||
|
if (buf == NULL || in == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
char* pos = buf;
|
||||||
|
if (in->nick == NULL && in->host != NULL) {
|
||||||
|
if (!safe_strcpy(&pos, in->host, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
} else if (in->nick != NULL) {
|
||||||
|
if (!safe_strcpy(&pos, in->nick, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (in->user != NULL) {
|
||||||
|
if (!safe_charcpy(&pos, '!', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (!safe_strcpy(&pos, in->user, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if (useorig && in->orig != NULL) {
|
||||||
|
if (!safe_charcpy(&pos, '%', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (!safe_strcpy(&pos, in->orig, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
if (in->host != NULL) {
|
||||||
|
if (!safe_charcpy(&pos, '@', len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
if (!safe_strcpy(&pos, in->host, len - (pos - buf)))
|
||||||
|
return ERR_UIRC_BUFFER_ERR;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
return pos - buf;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "../include/types.h"
|
||||||
|
#include "../include/mappings.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _UIRC_INCLUDED_ASSM
|
||||||
|
#define _UIRC_INCLUDED_ASSM
|
||||||
|
signed int Assm_mesg(char* buf, IRC_Message* in, size_t len);
|
||||||
|
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
signed int Assm_tags(char* buf, IRC_Tags* in, size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
|
||||||
|
#endif
|
|
@ -15,11 +15,9 @@
|
||||||
* 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 "../include/uirc.h"
|
|
||||||
#include <stdbool.h>
|
#include "helpers.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
static IRC_Message imassm_mesg;
|
static IRC_Message imassm_mesg;
|
||||||
char* RESERVED = "*";
|
char* RESERVED = "*";
|
||||||
void clear_assm(void)
|
void clear_assm(void)
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/types.h"
|
||||||
|
#include "../include/mappings.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _UIRC_INCLUDED_ASSM
|
||||||
|
#define _UIRC_INCLUDED_ASSM
|
||||||
|
void clear_assm(void);
|
||||||
|
IRC_Message* Assm_cmd_NICK(char* nick);
|
||||||
|
IRC_Message* Assm_cmd_USER(char* user, char* realname, int modes);
|
||||||
|
IRC_Message* Assm_cmd_PASS(char* password);
|
||||||
|
IRC_Message* Assm_cmd_OPER(char* name, char* password);
|
||||||
|
IRC_Message* Assm_cmd_MODE(char* nick, char* modes, char* modeparams);
|
||||||
|
IRC_Message* Assm_cmd_SERVICE(char* nickname, char* distribution, char* type, char* info);
|
||||||
|
IRC_Message* Assm_cmd_QUIT(char* mesg);
|
||||||
|
IRC_Message* Assm_cmd_SQUIT(char* server, char* comment);
|
||||||
|
IRC_Message* Assm_cmd_JOIN(char* channels, char* keys);
|
||||||
|
IRC_Message* Assm_cmd_PART(char* channel, char* message);
|
||||||
|
IRC_Message* Assm_cmd_TOPIC(char* channel, char* topic);
|
||||||
|
IRC_Message* Assm_cmd_NAMES(char* channels, char* target);
|
||||||
|
IRC_Message* Assm_cmd_LIST(char* channels, char* target);
|
||||||
|
IRC_Message* Assm_cmd_INVITE(char* nick, char* channel);
|
||||||
|
IRC_Message* Assm_cmd_KICK(char* channels, char* users, char* comment);
|
||||||
|
IRC_Message* Assm_cmd_PRIVMSG(char* target, char* message);
|
||||||
|
IRC_Message* Assm_cmd_NOTICE(char* target, char* text);
|
||||||
|
IRC_Message* Assm_cmd_MOTD(char* target);
|
||||||
|
IRC_Message* Assm_cmd_LUSERS(char* mask, char* target);
|
||||||
|
IRC_Message* Assm_cmd_VERSION(char* target);
|
||||||
|
IRC_Message* Assm_cmd_STATS(char* query, char* target);
|
||||||
|
IRC_Message* Assm_cmd_LINKS(char* remoteserv, char* servmask);
|
||||||
|
IRC_Message* Assm_cmd_TIME(char* target);
|
||||||
|
IRC_Message* Assm_cmd_CONNECT(char* target, char* port, char* remote);
|
||||||
|
IRC_Message* Assm_cmd_TRACE(char* target);
|
||||||
|
IRC_Message* Assm_cmd_ADMIN(char* target);
|
||||||
|
IRC_Message* Assm_cmd_INFO(char* target);
|
||||||
|
IRC_Message* Assm_cmd_SERVLIST(char* mask, char* type);
|
||||||
|
IRC_Message* Assm_cmd_SQUERY(char* servicename, char* text);
|
||||||
|
IRC_Message* Assm_cmd_WHO(char* mask, bool oper);
|
||||||
|
IRC_Message* Assm_cmd_WHOIS(char* target, char* mask);
|
||||||
|
IRC_Message* Assm_cmd_WHOWAS(char* nick, char* count, char* target);
|
||||||
|
IRC_Message* Assm_cmd_KILL(char* nick, char* comment);
|
||||||
|
IRC_Message* Assm_cmd_PING(char* source, char* target);
|
||||||
|
IRC_Message* Assm_cmd_PONG(char* source, char* target);
|
||||||
|
IRC_Message* Assm_cmd_ERROR(char* message);
|
||||||
|
IRC_Message* Assm_cmd_AWAY(char* mesg);
|
||||||
|
IRC_Message* Assm_cmd_REHASH(void);
|
||||||
|
IRC_Message* Assm_cmd_DIE(void);
|
||||||
|
IRC_Message* Assm_cmd_RESTART(void);
|
||||||
|
IRC_Message* Assm_cmd_SUMMON(char* user, char* target, char* channel);
|
||||||
|
IRC_Message* Assm_cmd_USERS(char* target);
|
||||||
|
IRC_Message* Assm_cmd_WALLOPS(char* text);
|
||||||
|
IRC_Message* Assm_cmd_USERHOST(char* users[]);
|
||||||
|
IRC_Message* Assm_cmd_ISON(char* users[]);
|
||||||
|
|
||||||
|
void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target);
|
||||||
|
void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg);
|
||||||
|
#endif
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
const char* const IRC_Cmds[] = {
|
||||||
|
[ADMIN] = "ADMIN",
|
||||||
|
[AWAY] = "AWAY",
|
||||||
|
[CONNECT] = "CONNECT",
|
||||||
|
[DIE] = "DIE",
|
||||||
|
[ERROR] = "ERROR",
|
||||||
|
[INFO] = "INFO",
|
||||||
|
[INVITE] = "INVITE",
|
||||||
|
[ISON] = "ISON",
|
||||||
|
[JOIN] = "JOIN",
|
||||||
|
[KICK] = "KICK",
|
||||||
|
[KILL] = "KILL",
|
||||||
|
[LINKS] = "LINKS",
|
||||||
|
[LIST] = "LIST",
|
||||||
|
[LUSERS] = "LUSERS",
|
||||||
|
[MODE] = "MODE",
|
||||||
|
[MOTD] = "MOTD",
|
||||||
|
[NAMES] = "NAMES",
|
||||||
|
[NICK] = "NICK",
|
||||||
|
[NOTICE] = "NOTICE",
|
||||||
|
[OPER] = "OPER",
|
||||||
|
[PART] = "PART",
|
||||||
|
[PASS] = "PASS",
|
||||||
|
[PING] = "PING",
|
||||||
|
[PONG] = "PONG",
|
||||||
|
[PRIVMSG] = "PRIVMSG",
|
||||||
|
[QUIT] = "QUIT",
|
||||||
|
[REHASH] = "REHASH",
|
||||||
|
[RESTART] = "RESTART",
|
||||||
|
[SERVER] = "SERVER",
|
||||||
|
[SERVICE] = "SERVICE",
|
||||||
|
[SERVLIST] = "SERVLIST",
|
||||||
|
[SQUERY] = "SQUERY",
|
||||||
|
[SQUIT] = "SQUIT",
|
||||||
|
[STATS] = "STATS",
|
||||||
|
[SUMMON] = "SUMMON",
|
||||||
|
[TIME] = "TIME",
|
||||||
|
[TOPIC] = "TOPIC",
|
||||||
|
[TRACE] = "TRACE",
|
||||||
|
[USERHOST] = "USERHOST",
|
||||||
|
[USERS] = "USERS",
|
||||||
|
[USER] = "USER",
|
||||||
|
[VERSION] = "VERSION",
|
||||||
|
[WALLOPS] = "WALLOPS",
|
||||||
|
[WHOIS] = "WHOIS",
|
||||||
|
[WHOWAS] = "WHOWAS",
|
||||||
|
[WHO] = "WHO",
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
[ACCOUNT] = "ACCOUNT",
|
||||||
|
[ACC] = "ACC",
|
||||||
|
[ACK] = "ACK",
|
||||||
|
[AUTHENTICATE] = "AUTHENTICATE",
|
||||||
|
[BATCH] = "BATCH",
|
||||||
|
[CAP] = "CAP",
|
||||||
|
[CHGHOST] = "CHGHOST",
|
||||||
|
[FAIL] = "FAIL",
|
||||||
|
[MONITOR] = "MONITOR",
|
||||||
|
[NOTE] = "NOTE",
|
||||||
|
[RENAME] = "RENAME",
|
||||||
|
[RESUME] = "RESUME",
|
||||||
|
[SETNAME] = "SETNAME",
|
||||||
|
[WARN] = "WARN",
|
||||||
|
[WEBIRC] = "WEBIRC"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
signed int Ircmd_stoi(char* str)
|
||||||
|
{
|
||||||
|
if (str == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
for (unsigned short i = UIRC_FCMD; i <= UIRC_LCMD; i++) {
|
||||||
|
if (IRC_Cmds[i] != NULL && strcmp(IRC_Cmds[i], str) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return ERR_UIRC_UNKNOWN_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int safe_strcpy(char** dest, const char* src, size_t lef)
|
||||||
|
{
|
||||||
|
size_t cnt;
|
||||||
|
if (lef > (cnt = strlen(src)) + 1) {
|
||||||
|
strcpy(*dest, src);
|
||||||
|
*dest += cnt;
|
||||||
|
return cnt;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int safe_charcpy(char** dest, const char c, size_t lef)
|
||||||
|
{
|
||||||
|
if (lef > 1) {
|
||||||
|
*(*dest)++ = c;
|
||||||
|
**dest = '\0';
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "../include/mappings.h"
|
||||||
|
#include "../include/types.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _UIRC_INCLUDED_MISC
|
||||||
|
#define _UIRC_INCLUDED_MISC
|
||||||
|
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
struct tagmapping {
|
||||||
|
const char* const name;
|
||||||
|
IRC_Tag* assg;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signed int Ircmd_stoi(char* str);
|
||||||
|
int safe_strcpy(char** dest, const char* src, size_t lef);
|
||||||
|
int safe_charcpy(char** dest, const char c, size_t lef);
|
||||||
|
#endif
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "tokenizers.h"
|
||||||
|
|
||||||
|
signed int Tok_mesg(char* str, IRC_Message* out)
|
||||||
|
{
|
||||||
|
if (str == NULL || out == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
int ret;
|
||||||
|
char *progr = str, *command;
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
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 && *progr; i++) {
|
||||||
|
if ((out->args[i] = strtok_r(NULL, " ", &progr)) == NULL)
|
||||||
|
return ERR_UIRC_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
out->args[i] = NULL;
|
||||||
|
if (*progr)
|
||||||
|
out->trailing = (*progr == ':') ? progr + 1 : progr;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
signed int Tok_tags(char* str, IRC_Tags* out)
|
||||||
|
{
|
||||||
|
if (str == NULL || out == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
char *cval, *cpos = str, *ctag = NULL;
|
||||||
|
bool clientbound;
|
||||||
|
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) {
|
||||||
|
clientbound = false;
|
||||||
|
if (*ctag == '+') {
|
||||||
|
ctag++;
|
||||||
|
clientbound = true;
|
||||||
|
}
|
||||||
|
if ((cval = strchr(ctag, '=')) != NULL)
|
||||||
|
*(cval++) = '\0';
|
||||||
|
for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) {
|
||||||
|
if (!strcmp(ctag, tagmps[i].name)) {
|
||||||
|
/* If the tag is present we point it to the value if given, or to the delimiter ('\0')
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
(*tagmps[i].assg).value = (cval != NULL) ? cval : ctag + strlen(ctag);
|
||||||
|
(*tagmps[i].assg).clientbound = clientbound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signed int Tok_user(char* str, IRC_User* out, bool useorig)
|
||||||
|
{
|
||||||
|
char* pos = (*str == ':') ? str + 1 : str;
|
||||||
|
if ((out->host = strchr(pos, '@')) != NULL)
|
||||||
|
*(out->host++) = '\0';
|
||||||
|
if (useorig && (out->orig = strchr(pos, '%')) != NULL)
|
||||||
|
*(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)) /* 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;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "../include/types.h"
|
||||||
|
#include "../include/mappings.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifndef _UIRC_INCLUDED_TKNIZ
|
||||||
|
#define _UIRC_INCLUDED_TKNIZ
|
||||||
|
signed int Tok_mesg(char* str, IRC_Message* out);
|
||||||
|
|
||||||
|
#ifdef UIRC_IRCV3
|
||||||
|
signed int Tok_tags(char* str, IRC_Tags* out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signed int Tok_user(char* str, IRC_User* out, bool useorig);
|
||||||
|
#endif
|
401
src/uirc.c
401
src/uirc.c
|
@ -1,401 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
|
||||||
* Copyright (c) 2019, 2020 Alex-David Denes
|
|
||||||
*
|
|
||||||
* uIRC is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* uIRC is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "uirc.h"
|
|
||||||
|
|
||||||
const char* const uirc_ircmd[] = {
|
|
||||||
[ADMIN] = "ADMIN",
|
|
||||||
[AWAY] = "AWAY",
|
|
||||||
[CONNECT] = "CONNECT",
|
|
||||||
[DIE] = "DIE",
|
|
||||||
[ERROR] = "ERROR",
|
|
||||||
[INFO] = "INFO",
|
|
||||||
[INVITE] = "INVITE",
|
|
||||||
[ISON] = "ISON",
|
|
||||||
[JOIN] = "JOIN",
|
|
||||||
[KICK] = "KICK",
|
|
||||||
[KILL] = "KILL",
|
|
||||||
[LINKS] = "LINKS",
|
|
||||||
[LIST] = "LIST",
|
|
||||||
[LUSERS] = "LUSERS",
|
|
||||||
[MODE] = "MODE",
|
|
||||||
[MOTD] = "MOTD",
|
|
||||||
[NAMES] = "NAMES",
|
|
||||||
[NICK] = "NICK",
|
|
||||||
[NOTICE] = "NOTICE",
|
|
||||||
[OPER] = "OPER",
|
|
||||||
[PART] = "PART",
|
|
||||||
[PASS] = "PASS",
|
|
||||||
[PING] = "PING",
|
|
||||||
[PONG] = "PONG",
|
|
||||||
[PRIVMSG] = "PRIVMSG",
|
|
||||||
[QUIT] = "QUIT",
|
|
||||||
[REHASH] = "REHASH",
|
|
||||||
[RESTART] = "RESTART",
|
|
||||||
[SERVER] = "SERVER",
|
|
||||||
[SERVICE] = "SERVICE",
|
|
||||||
[SERVLIST] = "SERVLIST",
|
|
||||||
[SQUERY] = "SQUERY",
|
|
||||||
[SQUIT] = "SQUIT",
|
|
||||||
[STATS] = "STATS",
|
|
||||||
[SUMMON] = "SUMMON",
|
|
||||||
[TIME] = "TIME",
|
|
||||||
[TOPIC] = "TOPIC",
|
|
||||||
[TRACE] = "TRACE",
|
|
||||||
[USERHOST] = "USERHOST",
|
|
||||||
[USERS] = "USERS",
|
|
||||||
[USER] = "USER",
|
|
||||||
[VERSION] = "VERSION",
|
|
||||||
[WALLOPS] = "WALLOPS",
|
|
||||||
[WHOIS] = "WHOIS",
|
|
||||||
[WHOWAS] = "WHOWAS",
|
|
||||||
[WHO] = "WHO",
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
[ACCOUNT] = "ACCOUNT",
|
|
||||||
[ACC] = "ACC",
|
|
||||||
[ACK] = "ACK",
|
|
||||||
[AUTHENTICATE] = "AUTHENTICATE",
|
|
||||||
[BATCH] = "BATCH",
|
|
||||||
[CAP] = "CAP",
|
|
||||||
[CHGHOST] = "CHGHOST",
|
|
||||||
[FAIL] = "FAIL",
|
|
||||||
[MONITOR] = "MONITOR",
|
|
||||||
[NOTE] = "NOTE",
|
|
||||||
[RENAME] = "RENAME",
|
|
||||||
[RESUME] = "RESUME",
|
|
||||||
[SETNAME] = "SETNAME",
|
|
||||||
[WARN] = "WARN",
|
|
||||||
[WEBIRC] = "WEBIRC"
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
struct tagmapping {
|
|
||||||
const char* const name;
|
|
||||||
IRC_Tag* assg;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
signed int Ircmd_stoi(char* str)
|
|
||||||
{
|
|
||||||
if (str == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
for (unsigned short i = UIRC_FCMD; i <= UIRC_LCMD; i++) {
|
|
||||||
if (uirc_ircmd[i] != NULL && strcmp(uirc_ircmd[i], str) == 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return ERR_UIRC_UNKNOWN_TOKEN;
|
|
||||||
}
|
|
||||||
signed int Assm_mesg(char* buf, IRC_Message* in, size_t len)
|
|
||||||
{
|
|
||||||
if (buf == NULL || in == NULL)
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
char* pos = buf;
|
|
||||||
unsigned int cnt;
|
|
||||||
signed int ret;
|
|
||||||
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
if ((ret = Assm_tags(pos, &in->tags, len - (pos - buf))) >= 0)
|
|
||||||
pos += ret;
|
|
||||||
else
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
if (in->name.nick != NULL || in->name.host != NULL) {
|
|
||||||
if (!safe_charcpy(&pos, ':', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if ((ret = Assm_user(pos, &in->name, len - (pos - buf), false)) <= 0)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
pos += ret;
|
|
||||||
if (!safe_charcpy(&pos, ' ', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if ((uirc_ircmd[in->cmd] != NULL) && len - (pos - buf) > (cnt = strlen(uirc_ircmd[in->cmd])) + 1 && strcpy(pos, uirc_ircmd[in->cmd]) != NULL)
|
|
||||||
pos += cnt;
|
|
||||||
else
|
|
||||||
return ERR_UIRC_GENERIC;
|
|
||||||
for (unsigned int i = 0; i < 14 && in->args[i] != NULL; i++) {
|
|
||||||
if (len - (pos - buf) > strlen(in->args[i]) + 2 && (cnt = snprintf(pos, len - (pos - buf), " %s", in->args[i])) > 0)
|
|
||||||
pos += cnt;
|
|
||||||
else
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if (in->trailing != NULL) {
|
|
||||||
if (len - (pos - buf) > strlen(in->trailing) + 3 && (cnt = snprintf(pos, len - (pos - buf), " :%s", in->trailing)) > 0)
|
|
||||||
pos += cnt;
|
|
||||||
else
|
|
||||||
return ERR_UIRC_GENERIC;
|
|
||||||
}
|
|
||||||
if (!safe_strcpy(&pos, "\r\n", len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
return pos - buf;
|
|
||||||
}
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
signed int Assm_tags(char* buf, IRC_Tags* in, size_t len)
|
|
||||||
{
|
|
||||||
if (buf == NULL || in == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
char* pos = buf;
|
|
||||||
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).value != NULL) {
|
|
||||||
if (pos == buf) {
|
|
||||||
if (!safe_charcpy(&pos, '@', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
} else {
|
|
||||||
if (!safe_charcpy(&pos, ';', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if ((*tagmps[i].assg).clientbound) {
|
|
||||||
if (!safe_charcpy(&pos, '+', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if (!safe_strcpy(&pos, tagmps[i].name, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (*(*tagmps[i].assg).value != '\0') {
|
|
||||||
if (!safe_charcpy(&pos, '=', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pos - buf;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig)
|
|
||||||
{
|
|
||||||
if (buf == NULL || in == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
char* pos = buf;
|
|
||||||
if (in->nick == NULL && in->host != NULL) {
|
|
||||||
if (!safe_strcpy(&pos, in->host, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
} else if (in->nick != NULL) {
|
|
||||||
if (!safe_strcpy(&pos, in->nick, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (in->user != NULL) {
|
|
||||||
if (!safe_charcpy(&pos, '!', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (!safe_strcpy(&pos, in->user, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if (useorig && in->orig != NULL) {
|
|
||||||
if (!safe_charcpy(&pos, '%', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (!safe_strcpy(&pos, in->orig, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
if (in->host != NULL) {
|
|
||||||
if (!safe_charcpy(&pos, '@', len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
if (!safe_strcpy(&pos, in->host, len - (pos - buf)))
|
|
||||||
return ERR_UIRC_BUFFER_ERR;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
return pos - buf;
|
|
||||||
}
|
|
||||||
signed int Tok_mesg(char* str, IRC_Message* out)
|
|
||||||
{
|
|
||||||
if (str == NULL || out == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
int ret;
|
|
||||||
char *progr = str, *command;
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
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 && *progr; i++) {
|
|
||||||
if ((out->args[i] = strtok_r(NULL, " ", &progr)) == NULL)
|
|
||||||
return ERR_UIRC_INVALID_FORMAT;
|
|
||||||
}
|
|
||||||
out->args[i] = NULL;
|
|
||||||
if (*progr)
|
|
||||||
out->trailing = (*progr == ':') ? progr + 1 : progr;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#ifdef UIRC_IRCV3
|
|
||||||
signed int Tok_tags(char* str, IRC_Tags* out)
|
|
||||||
{
|
|
||||||
if (str == NULL || out == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
char *cval, *cpos = str, *ctag = NULL;
|
|
||||||
bool clientbound;
|
|
||||||
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) {
|
|
||||||
clientbound = false;
|
|
||||||
if (*ctag == '+') {
|
|
||||||
ctag++;
|
|
||||||
clientbound = true;
|
|
||||||
}
|
|
||||||
if ((cval = strchr(ctag, '=')) != NULL)
|
|
||||||
*(cval++) = '\0';
|
|
||||||
for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) {
|
|
||||||
if (!strcmp(ctag, tagmps[i].name)) {
|
|
||||||
/* If the tag is present we point it to the value if given, or to the delimiter ('\0')
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
(*tagmps[i].assg).value = (cval != NULL) ? cval : ctag + strlen(ctag);
|
|
||||||
(*tagmps[i].assg).clientbound = clientbound;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
signed int Tok_user(char* str, IRC_User* out, bool useorig)
|
|
||||||
{
|
|
||||||
char* pos = (*str == ':') ? str + 1 : str;
|
|
||||||
if ((out->host = strchr(pos, '@')) != NULL)
|
|
||||||
*(out->host++) = '\0';
|
|
||||||
if (useorig && (out->orig = strchr(pos, '%')) != NULL)
|
|
||||||
*(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)) /* 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;
|
|
||||||
}
|
|
||||||
signed int Val_mesg(IRC_Message* mesg)
|
|
||||||
{
|
|
||||||
if (mesg == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
for (unsigned int i = 0; i < 14 && mesg->args[i] != NULL; i++) {
|
|
||||||
if (Val_type_nocrlf(mesg->args[i]) != 1)
|
|
||||||
return ERR_UIRC_VAL_FAILED;
|
|
||||||
if (Val_type_nospcl(mesg->args[i]) != 1)
|
|
||||||
return ERR_UIRC_VAL_FAILED;
|
|
||||||
}
|
|
||||||
if (mesg->trailing != NULL) {
|
|
||||||
if (Val_type_nocrlf(mesg->trailing) != 1)
|
|
||||||
return ERR_UIRC_VAL_FAILED;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
signed int Val_type_nocrlf(char* str)
|
|
||||||
{
|
|
||||||
if (str == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
for (; *str; str++) {
|
|
||||||
if (*str == '\r' || *str == '\n')
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
signed int Val_type_nospcl(char* str)
|
|
||||||
{
|
|
||||||
if (str == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
for (; *str; str++) {
|
|
||||||
if (*str == ' ' || *str == ':')
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
signed int Val_type_noblcm(char* str)
|
|
||||||
{
|
|
||||||
if (str == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
for (; *str; str++) {
|
|
||||||
if (*str == '\a' || *str == ',')
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
signed int Val_channame(char* chan)
|
|
||||||
{
|
|
||||||
if (chan == NULL)
|
|
||||||
return ERR_UIRC_NULL_ARGS;
|
|
||||||
if (*chan != '#' || *chan != '+' || *chan != '!' || *chan != '&')
|
|
||||||
return 0;
|
|
||||||
char* clps = ++chan;
|
|
||||||
if ((clps = strchr(chan, ':')) != NULL) {
|
|
||||||
*clps = '\0';
|
|
||||||
if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) {
|
|
||||||
*clps = ':';
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*clps = ':';
|
|
||||||
chan = ++clps;
|
|
||||||
}
|
|
||||||
if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int safe_strcpy(char** dest, const char* src, size_t lef)
|
|
||||||
{
|
|
||||||
size_t cnt;
|
|
||||||
if (lef > (cnt = strlen(src)) + 1) {
|
|
||||||
strcpy(*dest, src);
|
|
||||||
*dest += cnt;
|
|
||||||
return cnt;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int safe_charcpy(char** dest, const char c, size_t lef)
|
|
||||||
{
|
|
||||||
if (lef > 1) {
|
|
||||||
*(*dest)++ = c;
|
|
||||||
**dest = '\0';
|
|
||||||
return 1;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -21,5 +21,3 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
int safe_strcpy(char** dest, const char* src, size_t lef);
|
|
||||||
int safe_charcpy(char** dest, const char c, size_t lef);
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "validators.h"
|
||||||
|
|
||||||
|
signed int Val_mesg(IRC_Message* mesg)
|
||||||
|
{
|
||||||
|
if (mesg == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
for (unsigned int i = 0; i < 14 && mesg->args[i] != NULL; i++) {
|
||||||
|
if (Val_type_nocrlf(mesg->args[i]) != 1)
|
||||||
|
return ERR_UIRC_VAL_FAILED;
|
||||||
|
if (Val_type_nospcl(mesg->args[i]) != 1)
|
||||||
|
return ERR_UIRC_VAL_FAILED;
|
||||||
|
}
|
||||||
|
if (mesg->trailing != NULL) {
|
||||||
|
if (Val_type_nocrlf(mesg->trailing) != 1)
|
||||||
|
return ERR_UIRC_VAL_FAILED;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed int Val_type_nocrlf(char* str)
|
||||||
|
{
|
||||||
|
if (str == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
for (; *str; str++) {
|
||||||
|
if (*str == '\r' || *str == '\n')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed int Val_type_nospcl(char* str)
|
||||||
|
{
|
||||||
|
if (str == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
for (; *str; str++) {
|
||||||
|
if (*str == ' ' || *str == ':')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed int Val_type_noblcm(char* str)
|
||||||
|
{
|
||||||
|
if (str == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
for (; *str; str++) {
|
||||||
|
if (*str == '\a' || *str == ',')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed int Val_channame(char* chan)
|
||||||
|
{
|
||||||
|
if (chan == NULL)
|
||||||
|
return ERR_UIRC_NULL_ARGS;
|
||||||
|
if (*chan != '#' || *chan != '+' || *chan != '!' || *chan != '&')
|
||||||
|
return 0;
|
||||||
|
char* clps = ++chan;
|
||||||
|
if ((clps = strchr(chan, ':')) != NULL) {
|
||||||
|
*clps = '\0';
|
||||||
|
if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) {
|
||||||
|
*clps = ':';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*clps = ':';
|
||||||
|
chan = ++clps;
|
||||||
|
}
|
||||||
|
if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
|
||||||
|
* Copyright (c) 2019, 2020 Alex-David Denes
|
||||||
|
*
|
||||||
|
* uIRC is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* uIRC is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "../include/types.h"
|
||||||
|
#include "../include/mappings.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
signed int Val_mesg(IRC_Message* mesg);
|
||||||
|
signed int Val_type_nocrlf(char* str);
|
||||||
|
signed int Val_type_nospcl(char* str);
|
||||||
|
signed int Val_type_noblcm(char* str);
|
||||||
|
signed int Val_channame(char* chan);
|
Reference in New Issue