2020-07-22 16:57:59 +00:00
/*
* 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 ;
}
2020-07-31 23:38:06 +00:00
if ( * progr ) {
out - > args [ i + + ] = ( * progr = = ' : ' ) ? progr + 1 : progr ;
out - > trailing = true ;
}
2020-07-22 16:57:59 +00:00
out - > args [ i ] = NULL ;
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 ;
}