@ -9,6 +9,13 @@
# include <sipc.h>
# include <sipc.h>
# define _SIRH_CHECK 0xabad
struct si_response_header {
unsigned short check ;
int sd ;
int resp_sent ;
} ;
int si_bind ( const char * file )
int si_bind ( const char * file )
{
{
int sd , rc ;
int sd , rc ;
@ -45,6 +52,8 @@ static int _si_read_rest(int sd, si_message *message)
int read = 0 ;
int read = 0 ;
int rd = 0 ;
int rd = 0 ;
if ( message - > data_len < 1 ) return 0 ;
while ( ( read + = ( rd = recv ( sd , message - > data , message - > data_len , 0 ) ) ) < message - > data_len )
while ( ( read + = ( rd = recv ( sd , message - > data , message - > data_len , 0 ) ) ) < message - > data_len )
{
{
if ( rd < 0 ) return - 1 ;
if ( rd < 0 ) return - 1 ;
@ -95,10 +104,16 @@ int si_listen(int sd, si_error_callback on_error, si_callback on_message)
si_message * full ;
si_message * full ;
if ( _si_valid_header ( message ) )
if ( _si_valid_header ( message ) )
{
{
full = malloc ( sizeof ( si_message ) + message - > data_len + 1 ) ;
struct si_response_header * full0 = malloc ( sizeof ( si_message ) + message - > data_len + 1 + sizeof ( struct si_response_header ) ) ;
memset ( full , 0 , sizeof ( si_message ) + message - > data_len + 1 ) ; //always have null-term
memset ( full0 , 0 , sizeof ( si_message ) + message - > data_len + 1 + sizeof ( struct si_response_header ) ) ; //always have null-term
full0 - > check = _SIRH_CHECK ;
full0 - > sd = csd ;
full = ( si_message * ) ( ( ( unsigned char * ) full0 ) + sizeof ( struct si_response_header ) ) ;
memcpy ( full , message , sizeof ( si_message ) ) ;
memcpy ( full , message , sizeof ( si_message ) ) ;
rc = _si_read_rest ( csd , full ) ;
rc = _si_read_rest ( csd , full ) ;
if ( rc ! = 0 ) {
if ( rc ! = 0 ) {
if ( rc = = - 1 )
if ( rc = = - 1 )
rc = on_error ( SIE_READ ) ;
rc = on_error ( SIE_READ ) ;
@ -106,14 +121,32 @@ int si_listen(int sd, si_error_callback on_error, si_callback on_message)
rc = on_error ( SIE_PCONCLS ) ;
rc = on_error ( SIE_PCONCLS ) ;
if ( rc < 0 ) {
if ( rc < 0 ) {
close ( csd ) ;
close ( csd ) ;
free ( full0 ) ;
break ;
break ;
}
}
}
}
else {
else {
//Message has been read.
//Message has been read.
rc = on_message ( full ) ;
free ( full ) ;
rc = ( full - > flags & SI_DISCARD ) ? 0 : on_message ( full ) ;
if ( ! full0 - > resp_sent & & ! ( full - > flags & SI_NORESP ) )
{
//Send blank response. (Unless client asked for none.)
si_message * resp = malloc ( sizeof ( si_message ) ) ;
resp - > type = SI_BINARY ;
resp - > flags = SI_DISCARD | SI_NORESP ;
resp - > data_len = 0 ;
int rc2 = si_sendmsg ( csd , resp ) ;
if ( rc2 ! = SI_SEND_OKAY )
rc = on_error ( ( si_error ) rc2 ) ;
free ( resp ) ;
}
}
}
free ( full0 ) ;
}
}
else {
else {
rc = on_error ( SIE_INVALID ) ;
rc = on_error ( SIE_INVALID ) ;
@ -147,6 +180,16 @@ char *si_error_string(si_error err)
break ;
break ;
case SIE_INVALID :
case SIE_INVALID :
put ( " SIE_INVALID: Bad message " ) ;
put ( " SIE_INVALID: Bad message " ) ;
break ;
case SIE_R_INVALID :
puts ( " SIE_R_INVALID: Cannot respond to this " ) ;
break ;
case SIE_R_MULTI :
puts ( " SIE_R_MULTI: A response has already been sent " ) ;
break ;
case SIE_R_DISABLE :
puts ( " SIE_R_DISABLE: A response is not expected " ) ;
break ;
default :
default :
put ( " SIE_UNKNOWN: Unknown EC %d " , ( int ) err ) ;
put ( " SIE_UNKNOWN: Unknown EC %d " , ( int ) err ) ;
break ;
break ;
@ -202,7 +245,54 @@ int si_connect(const char *file)
return sd ;
return sd ;
}
}
int si_sendmsg ( int sd , const si_message * msg )
int si_read_response ( int sd , si_message * * resp )
{
unsigned char buffer [ sizeof ( si_message ) ] ;
si_message * head = ( si_message * ) buffer ;
int rc = 0 ;
int read , rd ;
read = rd = 0 ;
memset ( buffer , 0 , sizeof ( si_message ) ) ;
while ( ( read + = ( rd = recv ( sd , buffer , sizeof ( si_message ) , 0 ) ) ) < sizeof ( si_message ) )
{
if ( rd < 0 )
{
rc = ( int ) SIE_READ ;
break ;
} else if ( rd = = 0 )
{
rc = ( int ) SIE_PCONCLS ;
break ;
}
}
if ( rc = = 0 )
{
si_message * full = malloc ( sizeof ( si_message ) + head - > data_len + 1 ) ;
memset ( full , 0 , sizeof ( si_message ) + head - > data_len + 1 ) ;
memcpy ( full , head , sizeof ( si_message ) ) ;
rc = _si_read_rest ( sd , full ) ;
switch ( rc ) {
case 0 :
if ( full - > flags & SI_DISCARD )
free ( full ) ;
else
* resp = full ;
return 0 ;
case - 1 :
free ( full ) ;
return ( int ) SIE_READ ;
case - 2 :
free ( full ) ;
return ( int ) SIE_PCONCLS ;
}
}
return rc ;
}
static int _si_sendmsg ( int sd , const si_message * msg )
{
{
int rc = send ( sd , msg , sizeof ( si_message ) + msg - > data_len , 0 ) ;
int rc = send ( sd , msg , sizeof ( si_message ) + msg - > data_len , 0 ) ;
if ( rc < 0 )
if ( rc < 0 )
@ -215,40 +305,155 @@ int si_sendmsg(int sd, const si_message *msg)
return SI_SEND_OKAY ;
return SI_SEND_OKAY ;
}
}
int si_sendmsg_r ( int sd , const si_message * msg , si_message * * resp )
{
int rc = _si_sendmsg ( sd , msg ) ;
if ( ! ( msg - > flags & SI_NORESP ) )
{
si_message * _resp = NULL ;
rc = si_read_response ( sd , & _resp ) ;
if ( resp & & _resp & & ! ( _resp - > flags & SI_DISCARD ) & & rc = = 0 )
{
//printf("setting resp\n");
* resp = _resp ;
}
else {
//printf("not setting %d %d %d %d\n", !!resp, !!_resp, _resp && (_resp->flags & SI_DISCARD), rc);
if ( _resp )
free ( _resp ) ;
}
return rc = = 0 ? SI_SEND_OKAY : rc ;
}
return SI_SEND_OKAY ;
}
int si_sendmsg ( int sd , const si_message * msg )
{
return si_sendmsg_r ( sd , msg , NULL ) ;
}
int si_response ( const si_message * to , const si_message * msg )
{
struct si_response_header * rhead = ( struct si_response_header * ) ( ( ( intptr_t ) to ) - sizeof ( struct si_response_header ) ) ;
if ( rhead - > check ! = _SIRH_CHECK )
return ( int ) SIE_R_INVALID ;
if ( rhead - > resp_sent )
return ( int ) SIE_R_MULTI ;
if ( rhead - > resp_sent )
return ( int ) SIE_R_DISABLE ;
int rc = _si_sendmsg ( rhead - > sd , msg ) ;
rhead - > resp_sent = 1 ;
return rc ;
}
//Quick send functions
//Quick send functions
int siqs_string ( int sd , const char * string )
int siqs_string _r ( int sd , const char * string , unsigned int flags , si_message * * resp )
{
{
si_message * msg = malloc ( sizeof ( si_message ) + strlen ( string ) ) ;
si_message * msg = malloc ( sizeof ( si_message ) + strlen ( string ) + 1 ) ;
memset ( msg , 0 , sizeof ( si_message ) + strlen ( string ) ) ;
memset ( msg , 0 , sizeof ( si_message ) + strlen ( string ) + 1 ) ;
msg - > type = SI_STRING ;
msg - > type = SI_STRING ;
msg - > data_len = strlen ( string ) ;
msg - > data_len = strlen ( string ) + 1 ;
msg - > flags = flags ;
memcpy ( msg - > data , string , msg - > data_len ) ;
memcpy ( msg - > data , string , msg - > data_len ) ;
int rc = si_sendmsg ( sd , msg ) ;
int rc = si_sendmsg _r ( sd , msg , resp ) ;
free ( msg ) ;
free ( msg ) ;
return rc ;
return rc ;
}
}
int siqs_string ( int sd , const char * string )
{
return siqs_string_r ( sd , string , 0 , NULL ) ;
}
int siqs_close ( int sd )
int siqs_close _r( int sd , unsigned int flags , si_message * * resp )
{
{
si_message * msg = malloc ( sizeof ( si_message ) ) ;
si_message * msg = malloc ( sizeof ( si_message ) ) ;
memset ( msg , 0 , sizeof ( si_message ) ) ;
memset ( msg , 0 , sizeof ( si_message ) ) ;
msg - > type = SI_CLOSE ;
msg - > type = SI_CLOSE ;
msg - > data_len = 0 ;
msg - > data_len = 0 ;
msg - > flags = flags ;
int rc = si_sendmsg ( sd , msg ) ;
int rc = si_sendmsg _r ( sd , msg , resp ) ;
free ( msg ) ;
free ( msg ) ;
return rc ;
return rc ;
}
}
int siqs_close ( int sd )
{
return siqs_close_r ( sd , 0 , NULL ) ;
}
int siqs_binary_r ( int sd , const unsigned char * buffer , size_t size , unsigned int flags , si_message * * resp )
{
si_message * msg = malloc ( sizeof ( si_message ) + size ) ;
memset ( msg , 0 , sizeof ( si_message ) + size ) ;
msg - > type = SI_BINARY ;
msg - > data_len = size ;
msg - > flags = flags ;
memcpy ( msg - > data , buffer , msg - > data_len ) ;
int rc = si_sendmsg_r ( sd , msg , resp ) ;
free ( msg ) ;
return rc ;
}
int siqs_binary ( int sd , const unsigned char * buffer , size_t size )
int siqs_binary ( int sd , const unsigned char * buffer , size_t size )
{
return siqs_binary_r ( sd , buffer , size , 0 , NULL ) ;
}
// --
int siqs_printf_r ( int sd , unsigned int flags , si_message * * resp , const char * format , . . . )
{
char buffer [ SIQ_PRINTF_BUFFER_SIZE ] ;
va_list list ;
va_start ( list , format ) ;
memset ( buffer , 0 , SIQ_PRINTF_BUFFER_SIZE ) ;
vsnprintf ( buffer , SIQ_PRINTF_BUFFER_SIZE - 1 , format , list ) ;
int rc = siqs_string_r ( sd , buffer , flags , resp ) ;
va_end ( list ) ;
return rc ;
}
//Quick resp funcs
int siqr_string ( const si_message * sd , const char * string )
{
si_message * msg = malloc ( sizeof ( si_message ) + strlen ( string ) + 1 ) ;
memset ( msg , 0 , sizeof ( si_message ) + strlen ( string ) + 1 ) ;
msg - > type = SI_STRING ;
msg - > data_len = strlen ( string ) + 1 ;
memcpy ( msg - > data , string , msg - > data_len ) ;
int rc = si_response ( sd , msg ) ;
free ( msg ) ;
return rc ;
}
int siqr_binary ( const si_message * sd , const unsigned char * buffer , size_t size )
{
{
si_message * msg = malloc ( sizeof ( si_message ) + size ) ;
si_message * msg = malloc ( sizeof ( si_message ) + size ) ;
memset ( msg , 0 , sizeof ( si_message ) + size ) ;
memset ( msg , 0 , sizeof ( si_message ) + size ) ;
@ -258,13 +463,27 @@ int siqs_binary(int sd, const unsigned char* buffer, size_t size)
memcpy ( msg - > data , buffer , msg - > data_len ) ;
memcpy ( msg - > data , buffer , msg - > data_len ) ;
int rc = si_sendmsg ( sd , msg ) ;
int rc = si_response ( sd , msg ) ;
free ( msg ) ;
return rc ;
}
int siqr_close ( const si_message * sd )
{
si_message * msg = malloc ( sizeof ( si_message ) ) ;
memset ( msg , 0 , sizeof ( si_message ) ) ;
msg - > type = SI_CLOSE ;
msg - > data_len = 0 ;
int rc = si_response ( sd , msg ) ;
free ( msg ) ;
free ( msg ) ;
return rc ;
return rc ;
}
}
int siqs_printf ( int sd , const char * format , . . . )
int siq r_printf( const si_message * sd , const char * format , . . . )
{
{
char buffer [ SIQ_PRINTF_BUFFER_SIZE ] ;
char buffer [ SIQ_PRINTF_BUFFER_SIZE ] ;
va_list list ;
va_list list ;
@ -273,7 +492,7 @@ int siqs_printf(int sd, const char* format, ...)
vsnprintf ( buffer , SIQ_PRINTF_BUFFER_SIZE - 1 , format , list ) ;
vsnprintf ( buffer , SIQ_PRINTF_BUFFER_SIZE - 1 , format , list ) ;
int rc = siq s _string( sd , buffer ) ;
int rc = siq r _string( sd , buffer ) ;
va_end ( list ) ;
va_end ( list ) ;