diff options
author | Lubos Lunak <l.lunak@ suse.cz> | 2006-03-02 00:40:23 +0000 |
---|---|---|
committer | Lubos Lunak <l.lunak@ suse.cz> | 2006-03-02 00:40:23 +0000 |
commit | 1429fedeb44aca08d5b0307ef3574a0af34055c4 (patch) | |
tree | 3a8b5dceb48c681975fe2f4ce26d36bc87c094fb /lib |
Initial dapi commit.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 7 | ||||
-rw-r--r-- | lib/calls.c | 14 | ||||
-rw-r--r-- | lib/calls.h | 20 | ||||
-rw-r--r-- | lib/comm.c | 299 | ||||
-rw-r--r-- | lib/comm.h | 23 | ||||
-rw-r--r-- | lib/comm_internal.h | 13 | ||||
-rw-r--r-- | lib/utils.c | 15 | ||||
-rw-r--r-- | lib/utils.h | 5 |
8 files changed, 396 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..11730b0 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,7 @@ +lib_LTLIBRARIES = libdapi.la + +libdapi_la_SOURCES = comm.c utils.c calls.c +libdapi_la_LIBADD = +libdapi_la_LDFLAGS = $(all_libraries) -no-undefined + +INCLUDES = $(all_includes) diff --git a/lib/calls.c b/lib/calls.c new file mode 100644 index 0000000..cea41b2 --- /dev/null +++ b/lib/calls.c @@ -0,0 +1,14 @@ +#include "calls.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "comm.h" +#include "comm_internal.h" + +#include "../kde/gen/calls_generated.c" + +void dapi_setSyncCallback( DapiConnection* conn, DapiSyncCallback callback ) + { + conn->sync_callback = callback; + } diff --git a/lib/calls.h b/lib/calls.h new file mode 100644 index 0000000..f2d4606 --- /dev/null +++ b/lib/calls.h @@ -0,0 +1,20 @@ +#ifndef DAPI_CALLS_H +#define DAPI_CALLS_H + +#include "comm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../kde/gen/calls_generated.h" + +typedef void (*DapiSyncCallback)( DapiConnection* conn, int command, int seq ); + +void dapi_setSyncCallback( DapiConnection* conn, DapiSyncCallback callback ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/comm.c b/lib/comm.c new file mode 100644 index 0000000..0ddc349 --- /dev/null +++ b/lib/comm.c @@ -0,0 +1,299 @@ +#include "comm.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/un.h> +#include <unistd.h> + +#include "comm_internal.h" + +static void getDisplay( char* ret, int max ) + { + char hostname[ 256 ]; + const char* disp = getenv( "DISPLAY" ); + char* pos; + *ret = '\0'; + if( disp == NULL ) + disp = ":0"; + if( *disp == ':' ) + { + gethostname( ret, max ); + hostname[ max - 1 ] = '\0'; + } + strncat( ret, disp, max - 1 ); + pos = strrchr( ret, '.' ); /* strip head */ + if( pos != NULL && pos > strrchr( ret, ':' )) + *pos = '\0'; + } + +static void socketName( char* name, int max ) + { + const char* home; + char display[ 256 ]; + home = getenv( "HOME" ); + getDisplay( display, 255 ); + snprintf( name, max - 1, "%s/.dapi-%s", home, display ); + } + +DapiConnection* dapi_connect() + { + char sock_file[ 256 ]; + int sock; + struct sockaddr_un addr; + DapiConnection* ret; + socketName( sock_file, 255 ); + sock = socket( PF_UNIX, SOCK_STREAM, 0 ); + if( sock < 0 ) + { + perror( "socket" ); + return NULL; + } + addr.sun_family = AF_UNIX; + strcpy( addr.sun_path, sock_file ); + if( connect( sock, ( struct sockaddr* ) &addr, sizeof( addr )) < 0 ) + { + perror( "connect" ); + close( sock ); + return NULL; + } + ret = malloc( sizeof( DapiConnection )); + if( ret != NULL ) + { + ret->sock = sock; + ret->sync_callback = NULL; + ret->in_server = 0; + ret->last_seq = 0; + } + return ret; + } + +int dapi_bindSocket() + { + char sock_file[ 256 ]; + int sock; + struct sockaddr_un addr; + socketName( sock_file, 255 ); + sock = socket( PF_UNIX, SOCK_STREAM, 0 ); + if( sock < 0 ) + { + perror( "socket" ); + return -1; + } + int opt = fcntl( sock, F_GETFL ); + if( opt < 0 ) + { + perror( "fcntl" ); + close( sock ); + return -1; + } + if( fcntl( sock, F_SETFL, opt | O_NONBLOCK ) < 0 ) + { + perror( "nonblock" ); + close( sock ); + return -1; + } + unlink( sock_file ); + addr.sun_family = AF_UNIX; + strcpy( addr.sun_path, sock_file ); + if( bind( sock, ( struct sockaddr* ) &addr, sizeof( addr )) < 0 ) + { + perror( "bind" ); + close( sock ); + return -1; + } + if( chmod( sock_file, 0600 ) != 0 ) + { + perror( "chmod" ); + close( sock ); + return -1; + } + if( listen( sock, SOMAXCONN ) < 0 ) + { + perror( "listen" ); + close( sock ); + return -1; + } + return sock; + } + +int dapi_socket( DapiConnection* conn ) + { + return conn->sock; + } + +static int writeSocket( DapiConnection* conn, const char* data, int size ) + { + int written = 0; + for(;;) + { + int len = write( conn->sock, data + written, size - written ); + if( len < 0 && errno != EINTR && errno != EAGAIN ) + return -1; + if( len > 0 ) + written += len; + if( written == size ) + return 1; + } + } + +static int readSocket( DapiConnection* conn, char* data, int size ) + { + int rd = 0; + for(;;) + { + int len = read( conn->sock, data + rd, size - rd ); + if( len < 0 && errno != EINTR && errno != EAGAIN ) + return -1; + if( len == 0 ) + return 0; + if( len > 0 ) + rd += len; + if( rd == size ) + return 1; + } + } + +DapiConnection* dapi_acceptSocket( int sock ) + { + struct sockaddr_un addr; + DapiConnection* ret = NULL; + socklen_t addr_len = sizeof( addr ); + int sock2 = accept( sock, ( struct sockaddr* ) &addr, &addr_len ); + if( sock2 > 0 ) + { + ret = malloc( sizeof( DapiConnection )); + if( ret != NULL ) + { + ret->sock = sock2; + ret->sync_callback = NULL; + ret->in_server = 1; + ret->last_seq = 0; + } + else + close( sock2 ); + } + return ret; + } + +void dapi_close( DapiConnection* conn ) + { + close( conn->sock ); + } + +static int getNextSeq( DapiConnection* conn ) + { + return ++conn->last_seq; + } + +static char* readString( DapiConnection* conn, int len ) + { + char* ret = malloc( len + 1 ); + if( ret == NULL ) + return NULL; + if( readSocket( conn, ret, len + 1 ) > 0 ) + { + ret[ len ] = '\0'; + return ret; + } + free( ret ); + return NULL; + } + +static void writeString( DapiConnection* conn, const char* str ) + { + if( str == NULL ) + { + char c = '\0'; + writeSocket( conn, &c, 1 ); + return; + } + writeSocket( conn, str, strlen( str ) + 1 ); + } + +static int stringSize( const char** strs ) + { + int cnt = 0; + if( strs == NULL || *strs == NULL ) + return 0; + for(; + *strs != NULL; + ++strs ) + cnt += strlen( *strs ) + 1; + return cnt; + } + +static char** readStringList( DapiConnection* conn, int len ) + { + char* buf; + char** ret; + int cnt; + int i; + int pos; + int set; + if( len == 0 ) + { + ret = malloc( sizeof( char* )); + if( ret == NULL ) + return NULL; + *ret = NULL; + return ret; + } + buf = malloc( len ); + if( buf == NULL ) + return NULL; + if( readSocket( conn, buf, len ) <= 0 ) + { + free( buf ); + return NULL; + } + cnt = 1; /* extra for terminating NULL */ + for( i = 0; + i < len; + ++i ) + if( buf[ i ] == '\0' ) + ++cnt; + if( cnt == 0 ) + { + free( buf ); + return NULL; + } + ret = malloc( sizeof( char* ) * cnt + len ); + if( ret == NULL ) + { + free( buf ); + return NULL; + } + memcpy( ret + cnt, buf, len ); /* place string data right after the pointers */ + free( buf ); + buf = ( char* )( ret + cnt ); + pos = 0; + set = 1; + for( i = 0; + i < len; + ++i ) + { + if( set ) + ret[ pos++ ] = buf + i; + set = buf[ i ] == '\0'; + } + ret[ pos ] = NULL; /* terminating NULL */ + return ret; + } + +static void writeStringList( DapiConnection* conn, const char** strs ) + { + if( strs == NULL || *strs == NULL ) + return; + for(; + *strs != NULL; + ++strs ) + writeSocket( conn, *strs, strlen( *strs ) + 1 ); + } + +#include "../kde/gen/comm_generated.c" diff --git a/lib/comm.h b/lib/comm.h new file mode 100644 index 0000000..e20f090 --- /dev/null +++ b/lib/comm.h @@ -0,0 +1,23 @@ +#ifndef DAPI_COMM_H +#define DAPI_COMM_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DapiConnection DapiConnection; + +DapiConnection* dapi_connect( void ); +void dapi_close( DapiConnection* conn ); +int dapi_socket( DapiConnection* conn ); + +int dapi_bindSocket( void ); +DapiConnection* dapi_acceptSocket( int sock ); + +#include "../kde/gen/comm_generated.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/comm_internal.h b/lib/comm_internal.h new file mode 100644 index 0000000..a321d5e --- /dev/null +++ b/lib/comm_internal.h @@ -0,0 +1,13 @@ +enum { MAGIC = 0x152355 }; + +#include "../kde/gen/comm_internal_generated.h" + +#include "calls.h" + +struct DapiConnection + { + int sock; + DapiSyncCallback sync_callback; + int in_server; + int last_seq; + }; diff --git a/lib/utils.c b/lib/utils.c new file mode 100644 index 0000000..7764e50 --- /dev/null +++ b/lib/utils.c @@ -0,0 +1,15 @@ +#include <config.h> + +#include "utils.h" + +#include <stdarg.h> +#include <stdio.h> + +void debug( const char* fmt, ... ) + { + va_list va; + va_start( va, fmt ); + vfprintf( stderr, fmt, va ); + va_end( va ); + fprintf( stderr, "\n" ); + } diff --git a/lib/utils.h b/lib/utils.h new file mode 100644 index 0000000..721ff84 --- /dev/null +++ b/lib/utils.h @@ -0,0 +1,5 @@ +void debug( const char* fmt, ... ) +#ifdef __GNUC__ + __attribute (( format( printf, 1, 2 ))) +#endif + ; |