2011-06-14 06:34:18 +04:00
# include "daemon-client.h"
# include "daemon-shared.h"
# include <sys/un.h>
# include <sys/socket.h>
# include <string.h>
# include <stdio.h>
2011-08-31 16:18:40 +04:00
# include <unistd.h>
2011-06-14 06:34:18 +04:00
# include <assert.h>
2011-06-27 17:14:53 +04:00
# include <errno.h> // ENOMEM
2011-06-14 06:34:18 +04:00
daemon_handle daemon_open ( daemon_info i ) {
2012-02-24 03:52:11 +04:00
daemon_handle h = { . protocol_version = 0 } ;
2011-06-14 06:34:18 +04:00
struct sockaddr_un sockaddr ;
2011-09-17 18:49:18 +04:00
2011-06-27 17:14:53 +04:00
if ( ( h . socket_fd = socket ( PF_UNIX , SOCK_STREAM /* | SOCK_NONBLOCK */ , 0 ) ) < 0 ) {
2011-06-14 06:34:18 +04:00
perror ( " socket " ) ;
goto error ;
}
memset ( & sockaddr , 0 , sizeof ( sockaddr ) ) ;
2011-06-27 17:46:45 +04:00
fprintf ( stderr , " [C] connecting to %s \n " , i . socket ) ;
2011-06-14 06:34:18 +04:00
strcpy ( sockaddr . sun_path , i . socket ) ;
sockaddr . sun_family = AF_UNIX ;
if ( connect ( h . socket_fd , ( struct sockaddr * ) & sockaddr , sizeof ( sockaddr ) ) ) {
perror ( " connect " ) ;
goto error ;
}
2012-02-24 03:52:11 +04:00
daemon_reply r = daemon_send_simple ( h , " hello " , NULL ) ;
if ( r . error | | strcmp ( daemon_reply_str ( r , " response " , " unknown " ) , " OK " ) )
goto error ;
h . protocol = daemon_reply_str ( r , " protocol " , NULL ) ;
if ( h . protocol )
h . protocol = dm_strdup ( h . protocol ) ; /* keep around */
h . protocol_version = daemon_reply_int ( r , " version " , 0 ) ;
if ( i . protocol & & ( ! h . protocol | | strcmp ( h . protocol , i . protocol ) ) )
goto error ;
if ( i . protocol_version & & h . protocol_version ! = i . protocol_version )
goto error ;
daemon_reply_destroy ( r ) ;
2011-06-14 06:34:18 +04:00
return h ;
error :
if ( h . socket_fd > = 0 )
close ( h . socket_fd ) ;
2012-02-24 03:52:11 +04:00
if ( r . cft )
daemon_reply_destroy ( r ) ;
2011-06-14 06:34:18 +04:00
h . socket_fd = - 1 ;
return h ;
}
daemon_reply daemon_send ( daemon_handle h , daemon_request rq )
{
2012-02-15 13:14:54 +04:00
daemon_reply reply = { . cft = NULL , . error = 0 } ;
2011-06-14 06:34:18 +04:00
assert ( h . socket_fd > = 0 ) ;
if ( ! rq . buffer ) {
/* TODO: build the buffer from rq.cft */
}
assert ( rq . buffer ) ;
write_buffer ( h . socket_fd , rq . buffer , strlen ( rq . buffer ) ) ;
2012-02-24 03:52:11 +04:00
dm_free ( rq . buffer ) ;
2011-06-14 06:34:18 +04:00
if ( read_buffer ( h . socket_fd , & reply . buffer ) ) {
2011-08-30 19:42:56 +04:00
reply . cft = dm_config_from_string ( reply . buffer ) ;
2011-06-14 06:34:18 +04:00
} else
reply . error = 1 ;
return reply ;
}
2011-06-27 17:58:11 +04:00
void daemon_reply_destroy ( daemon_reply r ) {
if ( r . cft )
2011-08-31 16:18:40 +04:00
dm_config_destroy ( r . cft ) ;
2012-02-24 03:52:11 +04:00
dm_free ( r . buffer ) ;
2011-06-27 17:58:11 +04:00
}
2012-01-15 19:16:50 +04:00
daemon_reply daemon_send_simple ( daemon_handle h , const char * id , . . . )
2011-06-27 17:14:53 +04:00
{
2011-09-17 18:49:18 +04:00
static const daemon_reply err = { . error = ENOMEM , . buffer = NULL , . cft = NULL } ;
2011-10-31 01:58:59 +04:00
daemon_request rq = { . cft = NULL } ;
2011-09-17 18:49:18 +04:00
daemon_reply repl ;
2011-06-27 17:14:53 +04:00
va_list ap ;
2011-09-17 18:49:18 +04:00
2011-06-27 17:14:53 +04:00
va_start ( ap , id ) ;
2011-09-17 18:49:18 +04:00
rq . buffer = format_buffer ( " request " , id , ap ) ;
va_end ( ap ) ;
2011-06-27 17:14:53 +04:00
2011-09-17 18:49:18 +04:00
if ( ! rq . buffer )
2011-06-27 17:14:53 +04:00
return err ;
2011-09-17 18:49:18 +04:00
repl = daemon_send ( h , rq ) ;
2011-06-27 17:14:53 +04:00
return repl ;
}
void daemon_close ( daemon_handle h )
{
2012-02-24 03:52:11 +04:00
dm_free ( ( char * ) h . protocol ) ;
2011-06-14 06:34:18 +04:00
}