From fe2f9c773e09827055859cc5ceb4893f0381a8a2 Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 15 Apr 1998 09:47:51 +0000 Subject: Rename des fichiers socket en bussocket, et modifs des sources et du Makefile en consequence --- src/Makefile | 8 +- src/bus.c | 2 +- src/bussocket.c | 667 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bussocket.h | 87 ++++++++ src/socket.c | 667 -------------------------------------------------------- src/socket.h | 87 -------- src/testbus.c | 2 +- 7 files changed, 760 insertions(+), 760 deletions(-) create mode 100644 src/bussocket.c create mode 100644 src/bussocket.h delete mode 100644 src/socket.c delete mode 100644 src/socket.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index c4e6a73..e9d704f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ XTINC = CC=gcc -OBJ = timer.o socket.o bus.o -GOBJ = timer.o socket.o gbus.o +OBJ = timer.o bussocket.o bus.o +GOBJ = timer.o bussocket.o gbus.o XTOBJ = timer.o xtsocket.o bus.o all: libbus.a libgbus.a libxtbus.a testbus @@ -9,8 +9,8 @@ all: libbus.a libgbus.a libxtbus.a testbus gbus.o: bus.c $(CC) -DGNU_REGEXP -c $(CFLAGS) -o gbus.o bus.c -xtsocket.o: socket.c - $(CC) -DXTMAINLOOP $(XTINC) -c $(CFLAGS) -o xtsocket.o socket.c +xtsocket.o: bussocket.c + $(CC) -DXTMAINLOOP $(XTINC) -c $(CFLAGS) -o xtsocket.o bussocket.c testbus: testbus.o $(OBJ) $(CC) -o testbus testbus.o $(OBJ) diff --git a/src/bus.c b/src/bus.c index 18a5a67..e1d9a50 100644 --- a/src/bus.c +++ b/src/bus.c @@ -13,7 +13,7 @@ #include -#include "socket.h" +#include "bussocket.h" #include "list.h" #include "bus.h" diff --git a/src/bussocket.c b/src/bussocket.c new file mode 100644 index 0000000..0d75e61 --- /dev/null +++ b/src/bussocket.c @@ -0,0 +1,667 @@ +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#define close closesocket +#define perror( a ) printf(a" error=%d\n",WSAGetLastError()); +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#ifdef XTMAINLOOP +#include +#endif +#include "list.h" +#include "bussocket.h" +#include "timer.h" + +#define MAX_BUFFER 2048 + +struct _channel { + Channel next; + HANDLE fd; +#ifdef XTMAINLOOP + XtInputId id; +#endif + void *data; + int tobedeleted; + void (*handle_delete)( void *data ); + void (*handle_read)( Channel channel, HANDLE fd, void *data); + }; + +typedef struct _server *Server; + +struct _server { + Server next; + Channel channel; + void *(*create)(Client client); + void (*handle_delete)(Client client, void *data); + SocketInterpretation interpretation; + }; + +struct _client { + Client next; + Channel channel; + unsigned short port; + struct sockaddr_in from; + SocketInterpretation interpretation; + void (*handle_delete)(Client client, void *data); + char buffer[MAX_BUFFER+2]; + char *ptr; + void *data; + }; + +static Channel channels_list = NULL; +static Server servers_list = NULL; +static Client clients_list = NULL; +static int channel_initialized = 0; + +#ifdef XTMAINLOOP +static XtAppContext app; +#else +static fd_set open_fds; +static int MainLoop = 1; +#endif + + + +#ifdef WIN32 +WSADATA WsaData; +#endif + +void ChannelClose( Channel channel ) +{ +#ifdef XTMAINLOOP + if ( channel->handle_delete ) + (*channel->handle_delete)( channel->data ); + close(channel->fd); + XtRemoveInput( channel->id ); + LIST_REMOVE( channels_list, channel ); +#else + channel->tobedeleted = 1; +#endif +} +#ifdef XTMAINLOOP +static void HandleChannel( XtPointer closure, int* source, XtInputId* id ) +{ + Channel channel = (Channel)closure; +#ifdef DEBUG + printf("Handle Channel read %d\n",*source ); +#endif + (*channel->handle_read)(channel,channel->fd,channel->data); +} +#else +static void ChannelDelete( Channel channel ) +{ + if ( channel->handle_delete ) + (*channel->handle_delete)( channel->data ); + close(channel->fd); + + FD_CLR(channel->fd, &open_fds); + LIST_REMOVE( channels_list, channel ); +} +static void ChannelDefferedDelete() +{ + Channel channel,next; + LIST_EACH_SAFE( channels_list, channel,next) + { + if ( channel->tobedeleted ) + { + ChannelDelete( channel ); + } + } +} +#endif +Channel ChannelSetUp(HANDLE fd, void *data, + void (*handle_delete)( void *data ), + void (*handle_read)( Channel channel, HANDLE fd, void *data) + ) +{ + Channel channel; + + LIST_ADD( channels_list, channel ); + if ( !channel ) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + close( fd ); + exit(0); + } + channel->fd = fd; + channel->tobedeleted = 0; + channel->handle_delete = handle_delete; + channel->handle_read = handle_read; + channel->data = data; +#ifdef XTMAINLOOP + channel->id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask, HandleChannel, channel); +#else + FD_SET( channel->fd, &open_fds ); +#endif + return channel; +} +#ifndef XTMAINLOOP +static void ChannelHandleRead(fd_set *current) +{ + Channel channel,next; + + LIST_EACH_SAFE( channels_list, channel, next ) + { + if ( FD_ISSET( channel->fd, current ) ) + { + (*channel->handle_read)(channel,channel->fd,channel->data); + } + } +} +static void ChannelHandleExcpt(fd_set *current) +{ + Channel channel,next; + LIST_EACH_SAFE( channels_list, channel, next ) + { + if (FD_ISSET( channel->fd, current ) ) + { + ChannelClose( channel ); + } + } +} +#endif +static void DeleteSocket(void *data) +{ + Client client = ( Client )data; + if ( client->handle_delete ) + (*client->handle_delete)( client, client->data ); + shutdown( client->channel->fd, 2 ); + LIST_REMOVE( clients_list, client ); +} +static void HandleSocket( Channel channel, HANDLE fd, void *data) +{ + Client client = (Client)data; + char *ptr; + char *ptr_nl; + long nb_to_read = 0; + long nb; + int len; + + /* limitation taille buffer */ + nb_to_read = MAX_BUFFER - ( client->ptr - client->buffer ); + if( nb_to_read == 0 ) { + fprintf(stderr, "Erreur message trop long sans LF\n"); + client->ptr = client->buffer; + return; + }; + len = sizeof( client->from ); + nb = recvfrom( fd, client->ptr, nb_to_read,0,(struct sockaddr *)&client->from,&len); + if (nb < 0) { + perror(" Read Socket "); + ChannelClose( client->channel ); + return; + }; + if ( nb == 0 ) + { + ChannelClose( client->channel ); + return; + } + + client->ptr += nb; + *(client->ptr) = '\0'; + ptr = client->buffer; + while( (ptr_nl = strchr( ptr, '\n' ))) + { + *ptr_nl = '\0'; + if ( client->interpretation ) + (*client->interpretation)( client, client->data, ptr ); + else fprintf( stderr,"Socket No interpretation function ???!\n"); + ptr = ++ptr_nl; + } + if ( *ptr != '\0' ) + { /* recopie ligne incomplete au debut du buffer */ + strcpy( client->buffer, ptr ); + client->ptr = client->buffer + strlen(client->buffer); + } + else + { + client->ptr = client->buffer; + } +} +static void HandleServer(Channel channel, HANDLE fd, void *data) +{ + Server server = ( Server ) data; + Client client; + HANDLE ns; + int addrlen; + struct sockaddr_in remote2; + + addrlen = sizeof( remote2 ); + if ((ns = accept( fd, (struct sockaddr *)&remote2, &addrlen)) <0) + { + perror ( "*** accept ***"); + return; + }; + LIST_ADD( clients_list, client ); + if ( !client ) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + close( fd ); + exit(0); + } + client->from = remote2; + client->channel = ChannelSetUp( ns, client, DeleteSocket, HandleSocket ); + client->interpretation = server->interpretation; + client->ptr = client->buffer; + client->handle_delete = server->handle_delete; + client->data = (*server->create)( client ); + +} +int SocketServer(unsigned short port, + void*(*create)(Client client), + void(*handle_delete)(Client client, void *data), + void(*interpretation)( Client client, void *data, char *ligne)) +{ + Server server; + HANDLE fd; + int one=1; + struct sockaddr_in local; + int addrlen; + + + if ((fd = socket( AF_INET, SOCK_STREAM, 0)) < 0){ + perror( "***open socket ***"); + exit(0); + }; + + + local.sin_family = AF_INET; + local.sin_addr.s_addr = INADDR_ANY; + local.sin_port = htons (port); + + if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&one,sizeof(one)) < 0) + { + perror( "*** set socket option SO_REUSEADDR ***"); + exit(0); + } + +#ifdef SO_REUSEPORT + + if (setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, (char *)&one, sizeof( one)) < 0) + { + perror( "*** set socket option REUSEPORT ***"); + exit(0); + } +#endif + + if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) + { + perror( "*** bind ***"); + exit(0); + } + + addrlen = sizeof( local ); + if (getsockname(fd,(struct sockaddr *)&local, &addrlen) < 0) + { + perror( "***get socket name ***"); + exit(0); + } + + if (listen( fd, 128) < 0){ + perror( "*** listen ***"); + exit(0); + }; + + + LIST_ADD( servers_list, server ); + if ( !server ) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + exit(0); + } + server->channel = ChannelSetUp( fd, server, DeleteSocket, HandleServer ); + server->create = create; + server->handle_delete = handle_delete; + server->interpretation = interpretation; + return ntohs(local.sin_port); +} +char *SocketGetPeerHost( Client client ) +{ + int err; + struct sockaddr_in name; + struct hostent *host; + int len = sizeof(name); + err = getpeername( client->channel->fd, (struct sockaddr *)&name, &len ); + if ( err < 0 ) return "can't get peer"; + host = gethostbyaddr( (char *)&name.sin_addr.s_addr,sizeof(name.sin_addr.s_addr),name.sin_family); + if ( host == NULL ) return "can't translate addr"; + return host->h_name; +} +struct in_addr * SocketGetRemoteAddr( Client client ) +{ + return &client->from.sin_addr; +} +void SocketGetRemote( Client client, char **host, unsigned short *port ) +{ + struct hostent *hostp; + /* extract hostname and port from last message received */ + hostp = gethostbyaddr( (char *)&client->from.sin_addr.s_addr, + sizeof(client->from.sin_addr.s_addr),client->from.sin_family); + if ( hostp == NULL ) *host = "unknown"; + else *host = hostp->h_name; + *port = ntohs( client->from.sin_port ); +} +void SocketClose( Client client ) +{ + ChannelClose( client->channel ); +} + +void SocketSendRaw( Client client, char *buffer, int len ) +{ + int err; + err = send( client->channel->fd, buffer, len, 0 ); + if ( err != len ) + perror( "*** send ***"); +} +void SocketSetData( Client client, void *data ) +{ + client->data = data; +} +void SocketSend( Client client, char *fmt, ... ) +{ + char buffer[4096]; + va_list ap; + int len; + va_start( ap, fmt ); + len = vsprintf( buffer, fmt, ap ); + SocketSendRaw( client, buffer, len ); + va_end ( ap ); +} +void *SocketGetData( Client client ) +{ + return client->data; +} +void SocketBroadcast( char *fmt, ... ) +{ + Client client; + char buffer[4096]; + va_list ap; + int len; + + va_start( ap, fmt ); + len = vsprintf( buffer, fmt, ap ); + va_end ( ap ); + LIST_EACH( clients_list, client ) + { + SocketSendRaw( client, buffer, len ); + } +} +/* +Ouverture d'un canal TCP/IP en mode client +*/ +Client SocketConnect( char * host, unsigned short port, + void *data, + SocketInterpretation interpretation, + void (*handle_delete)(Client client, void *data) + ) +{ +struct hostent *rhost; + + +if ((rhost = gethostbyname( host )) == NULL){ + fprintf(stderr, "Erreur %s Calculateur inconnu !\n",host); + return NULL; + }; +return SocketConnectAddr( (struct in_addr*)(rhost->h_addr), port, data, interpretation, handle_delete); +} +Client SocketConnectAddr( struct in_addr * addr, unsigned short port, + void *data, + SocketInterpretation interpretation, + void (*handle_delete)(Client client, void *data) + ) +{ +HANDLE handle; +Client client; +struct sockaddr_in remote; + +remote.sin_family = AF_INET; +remote.sin_addr = *addr; +remote.sin_port = htons (port); + +if ((handle = socket( AF_INET, SOCK_STREAM, 0)) < 0){ + perror( "*** client socket ***"); + return NULL; + }; + +if ( connect( handle, (struct sockaddr *)&remote, sizeof(remote) ) < 0){ + perror( "*** client connect ***"); + return NULL; + }; + +LIST_ADD( clients_list, client ); +if ( !client ) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + close( handle ); + exit(0); + } + + +client->channel = ChannelSetUp( handle, client, DeleteSocket, HandleSocket ); +client->interpretation = interpretation; +client->ptr = client->buffer; +client->data = data; +client->handle_delete = handle_delete; +client->from.sin_family = AF_INET; +client->from.sin_addr = *addr; +client->from.sin_port = htons (port); + +return client; +} +int SocketWaitForReply( Client client, char *buffer, int size, int delai) +{ + fd_set rdset; + struct timeval timeout; + struct timeval *timeoutptr = &timeout; + int ready; + char *ptr; + char *ptr_nl; + long nb_to_read = 0; + long nb; + HANDLE fd; + + fd = client->channel->fd; + ptr = buffer; + timeout.tv_sec = delai; + timeout.tv_usec = 0; + do { + /* limitation taille buffer */ + nb_to_read = size - ( ptr - buffer ); + if( nb_to_read == 0 ) + { + fprintf(stderr, "Erreur message trop long sans LF\n"); + ptr = buffer; + return -1; + } + FD_ZERO( &rdset ); + FD_SET( fd, &rdset ); + ready = select(fd+1, &rdset, 0, 0, timeoutptr); + if ( ready < 0 ) + { + perror("select"); + return -1; + } + if ( ready == 0 ) + { + return -2; + } + if ((nb = recv( fd , ptr, nb_to_read, 0 )) < 0) + { + perror(" Read Socket "); + return -1; + } + if ( nb == 0 ) + return 0; + + ptr += nb; + *ptr = '\0'; + ptr_nl = strchr( buffer, '\n' ); + } while ( !ptr_nl ); + *ptr_nl = '\0'; + return (ptr_nl - buffer); +} +void ChannelInit(void) +{ +#ifdef WIN32 + int error; +#else + signal( SIGPIPE, SIG_IGN); +#endif + if ( channel_initialized ) return; +#ifndef XTMAINLOOP + FD_ZERO( &open_fds ); +#endif +#ifdef WIN32 + error = WSAStartup( 0x0101, &WsaData ); + if ( error == SOCKET_ERROR ) { + printf( "WSAStartup failed.\n" ); + } +#endif + channel_initialized = 1; +} + +#ifdef XTMAINLOOP + +void SetSocketAppContext( XtAppContext cntx ) +{ + app = cntx; +} + +void ChannelMainLoop(void(*hook)(void)) +{ + printf("Compiled for Use of XtMainLoop not ChannelMainLoop\n"); + exit(-1); +} +#else +void ChannelStop(void) +{ + MainLoop = 0; +} +void ChannelMainLoop(void(*hook)(void)) +{ + +fd_set rdset; +fd_set exset; +int ready; + + + + while (MainLoop) { + ChannelDefferedDelete(); + if ( hook ) (*hook)(); + rdset = open_fds; + exset = open_fds; + ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout()); + if ( ready < 0 && ( errno != EINTR )) + { + perror("select"); + return; + } + TimerScan(); + if ( ready > 0 ) + { + ChannelHandleExcpt(&exset); + ChannelHandleRead(&rdset); + continue; + } + } +} +#endif +/* Socket UDP */ + +Client SocketBroadcastCreate( unsigned short port, + void *data, + SocketInterpretation interpretation + ) +{ +HANDLE handle; +Client client; +struct sockaddr_in local; +int on = 1; + +local.sin_family = AF_INET; +local.sin_addr.s_addr = INADDR_ANY; +local.sin_port = htons (port); + +if ((handle = socket( AF_INET, SOCK_DGRAM, 0)) < 0){ + perror( "*** dgram socket ***"); + return NULL; + }; + +/* wee need to used multiple client on the same host */ +if (setsockopt( handle, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof( on)) < 0) + { + perror( "*** set socket option REUSEADDR ***"); + return NULL; + }; +#ifdef SO_REUSEPORT + +if (setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof( on)) < 0) + { + perror( "*** set socket option REUSEPORT ***"); + return NULL; + } +#endif +/* wee need to broadcast */ +if (setsockopt( handle, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof( on)) < 0) + { + perror( "*** BROADCAST ***"); + return NULL; + }; + +if (bind(handle, (struct sockaddr *)&local, sizeof(local)) < 0) + { + perror( "*** test BIND ***"); + return NULL; + }; + +LIST_ADD( clients_list, client ); +if ( !client ) + { + fprintf(stderr,"NOK Memory Alloc Error\n"); + close( handle ); + exit(0); + } + + +client->channel = ChannelSetUp( handle, client, DeleteSocket, HandleSocket ); +client->interpretation = interpretation; +client->ptr = client->buffer; +client->data = data; + +return client; +} + +void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *fmt, ... ) +{ + struct sockaddr_in remote; + char buffer[4096]; + va_list ap; + int err,len; + + va_start( ap, fmt ); + len = vsprintf( buffer, fmt, ap ); + /* Send UDP packet to the dest */ + remote.sin_family = AF_INET; + remote.sin_addr.s_addr = htonl( host ); + remote.sin_port = htons(port); + err = sendto( client->channel->fd, + buffer, len,0, + (struct sockaddr *)&remote,sizeof(remote)); + if ( err != len ) + { + perror( "*** send ***"); + } va_end ( ap ); +} diff --git a/src/bussocket.h b/src/bussocket.h new file mode 100644 index 0000000..99b9abd --- /dev/null +++ b/src/bussocket.h @@ -0,0 +1,87 @@ +#ifndef _SOCKET_H +#define _SOCKET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* general Handle */ + +#define ANYPORT 0 + +#ifdef WIN32 +#include +#define HANDLE SOCKET +#else +#define HANDLE int +#include +#endif + +typedef struct _channel *Channel; + +extern void ChannelInit(void); +extern void ChannelStop(void); +extern void ChannelMainLoop(void(*hook)(void) ); +extern Channel ChannelSetUp( + HANDLE fd, + void *data, + void (*handle_delete)( void *data ), + void (*handle_read)( Channel channel, HANDLE fd, void *data) + ); + +extern void ChannelClose( Channel channel ); + +/* Server Part */ +typedef struct _client *Client; +typedef void (*SocketInterpretation)( Client client, void *data, char *ligne); + +extern void SocketClose( Client client ); +extern void SocketSend( Client client, char *fmt, ... ); +extern void SocketSendRaw( Client client, char *buffer, int len ); +extern char *SocketGetPeerHost( Client client ); +extern void SocketSetData( Client client, void *data ); +extern void *SocketGetData( Client client ); +extern void SocketBroadcast( char *fmt, ... ); + +extern int SocketServer(unsigned short port, + void*(*create)(Client client), + void(*handle_delete)(Client client, void *data), + SocketInterpretation interpretation); + +/* Client Part */ + +extern Client SocketConnect( char * host, unsigned short port, + void *data, + SocketInterpretation interpretation, + void (*handle_delete)(Client client, void *data) + ); +extern Client SocketConnectAddr( struct in_addr * addr, unsigned short port, + void *data, + SocketInterpretation interpretation, + void (*handle_delete)(Client client, void *data) + ); +extern int SocketWaitForReply( Client client, char *buffer, int size, int delai); + +/* Socket UDP */ +/* Creation d'une socket en mode non connecte */ +/* et ecoute des messages */ +extern Client SocketBroadcastCreate( + unsigned short port, + void *data, + SocketInterpretation interpretation + ); +/* recuperation de l'emetteur du message */ +extern struct in_addr * SocketGetRemoteAddr( Client client ); +extern void SocketGetRemote( Client client, char **host, unsigned short *port ); +/* emmission d'un broadcast UDP */ +extern void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *fmt, ... ); + +#ifdef XTMAINLOOP +extern void SetSocketAppContext( XtAppContext cntx ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/socket.c b/src/socket.c deleted file mode 100644 index 17d0fe1..0000000 --- a/src/socket.c +++ /dev/null @@ -1,667 +0,0 @@ -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#define close closesocket -#define perror( a ) printf(a" error=%d\n",WSAGetLastError()); -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#ifdef XTMAINLOOP -#include -#endif -#include "list.h" -#include "socket.h" -#include "timer.h" - -#define MAX_BUFFER 2048 - -struct _channel { - Channel next; - HANDLE fd; -#ifdef XTMAINLOOP - XtInputId id; -#endif - void *data; - int tobedeleted; - void (*handle_delete)( void *data ); - void (*handle_read)( Channel channel, HANDLE fd, void *data); - }; - -typedef struct _server *Server; - -struct _server { - Server next; - Channel channel; - void *(*create)(Client client); - void (*handle_delete)(Client client, void *data); - SocketInterpretation interpretation; - }; - -struct _client { - Client next; - Channel channel; - unsigned short port; - struct sockaddr_in from; - SocketInterpretation interpretation; - void (*handle_delete)(Client client, void *data); - char buffer[MAX_BUFFER+2]; - char *ptr; - void *data; - }; - -static Channel channels_list = NULL; -static Server servers_list = NULL; -static Client clients_list = NULL; -static int channel_initialized = 0; - -#ifdef XTMAINLOOP -static XtAppContext app; -#else -static fd_set open_fds; -static int MainLoop = 1; -#endif - - - -#ifdef WIN32 -WSADATA WsaData; -#endif - -void ChannelClose( Channel channel ) -{ -#ifdef XTMAINLOOP - if ( channel->handle_delete ) - (*channel->handle_delete)( channel->data ); - close(channel->fd); - XtRemoveInput( channel->id ); - LIST_REMOVE( channels_list, channel ); -#else - channel->tobedeleted = 1; -#endif -} -#ifdef XTMAINLOOP -static void HandleChannel( XtPointer closure, int* source, XtInputId* id ) -{ - Channel channel = (Channel)closure; -#ifdef DEBUG - printf("Handle Channel read %d\n",*source ); -#endif - (*channel->handle_read)(channel,channel->fd,channel->data); -} -#else -static void ChannelDelete( Channel channel ) -{ - if ( channel->handle_delete ) - (*channel->handle_delete)( channel->data ); - close(channel->fd); - - FD_CLR(channel->fd, &open_fds); - LIST_REMOVE( channels_list, channel ); -} -static void ChannelDefferedDelete() -{ - Channel channel,next; - LIST_EACH_SAFE( channels_list, channel,next) - { - if ( channel->tobedeleted ) - { - ChannelDelete( channel ); - } - } -} -#endif -Channel ChannelSetUp(HANDLE fd, void *data, - void (*handle_delete)( void *data ), - void (*handle_read)( Channel channel, HANDLE fd, void *data) - ) -{ - Channel channel; - - LIST_ADD( channels_list, channel ); - if ( !channel ) - { - fprintf(stderr,"NOK Memory Alloc Error\n"); - close( fd ); - exit(0); - } - channel->fd = fd; - channel->tobedeleted = 0; - channel->handle_delete = handle_delete; - channel->handle_read = handle_read; - channel->data = data; -#ifdef XTMAINLOOP - channel->id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask, HandleChannel, channel); -#else - FD_SET( channel->fd, &open_fds ); -#endif - return channel; -} -#ifndef XTMAINLOOP -static void ChannelHandleRead(fd_set *current) -{ - Channel channel,next; - - LIST_EACH_SAFE( channels_list, channel, next ) - { - if ( FD_ISSET( channel->fd, current ) ) - { - (*channel->handle_read)(channel,channel->fd,channel->data); - } - } -} -static void ChannelHandleExcpt(fd_set *current) -{ - Channel channel,next; - LIST_EACH_SAFE( channels_list, channel, next ) - { - if (FD_ISSET( channel->fd, current ) ) - { - ChannelClose( channel ); - } - } -} -#endif -static void DeleteSocket(void *data) -{ - Client client = ( Client )data; - if ( client->handle_delete ) - (*client->handle_delete)( client, client->data ); - shutdown( client->channel->fd, 2 ); - LIST_REMOVE( clients_list, client ); -} -static void HandleSocket( Channel channel, HANDLE fd, void *data) -{ - Client client = (Client)data; - char *ptr; - char *ptr_nl; - long nb_to_read = 0; - long nb; - int len; - - /* limitation taille buffer */ - nb_to_read = MAX_BUFFER - ( client->ptr - client->buffer ); - if( nb_to_read == 0 ) { - fprintf(stderr, "Erreur message trop long sans LF\n"); - client->ptr = client->buffer; - return; - }; - len = sizeof( client->from ); - nb = recvfrom( fd, client->ptr, nb_to_read,0,(struct sockaddr *)&client->from,&len); - if (nb < 0) { - perror(" Read Socket "); - ChannelClose( client->channel ); - return; - }; - if ( nb == 0 ) - { - ChannelClose( client->channel ); - return; - } - - client->ptr += nb; - *(client->ptr) = '\0'; - ptr = client->buffer; - while( (ptr_nl = strchr( ptr, '\n' ))) - { - *ptr_nl = '\0'; - if ( client->interpretation ) - (*client->interpretation)( client, client->data, ptr ); - else fprintf( stderr,"Socket No interpretation function ???!\n"); - ptr = ++ptr_nl; - } - if ( *ptr != '\0' ) - { /* recopie ligne incomplete au debut du buffer */ - strcpy( client->buffer, ptr ); - client->ptr = client->buffer + strlen(client->buffer); - } - else - { - client->ptr = client->buffer; - } -} -static void HandleServer(Channel channel, HANDLE fd, void *data) -{ - Server server = ( Server ) data; - Client client; - HANDLE ns; - int addrlen; - struct sockaddr_in remote2; - - addrlen = sizeof( remote2 ); - if ((ns = accept( fd, (struct sockaddr *)&remote2, &addrlen)) <0) - { - perror ( "*** accept ***"); - return; - }; - LIST_ADD( clients_list, client ); - if ( !client ) - { - fprintf(stderr,"NOK Memory Alloc Error\n"); - close( fd ); - exit(0); - } - client->from = remote2; - client->channel = ChannelSetUp( ns, client, DeleteSocket, HandleSocket ); - client->interpretation = server->interpretation; - client->ptr = client->buffer; - client->handle_delete = server->handle_delete; - client->data = (*server->create)( client ); - -} -int SocketServer(unsigned short port, - void*(*create)(Client client), - void(*handle_delete)(Client client, void *data), - void(*interpretation)( Client client, void *data, char *ligne)) -{ - Server server; - HANDLE fd; - int one=1; - struct sockaddr_in local; - int addrlen; - - - if ((fd = socket( AF_INET, SOCK_STREAM, 0)) < 0){ - perror( "***open socket ***"); - exit(0); - }; - - - local.sin_family = AF_INET; - local.sin_addr.s_addr = INADDR_ANY; - local.sin_port = htons (port); - - if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&one,sizeof(one)) < 0) - { - perror( "*** set socket option SO_REUSEADDR ***"); - exit(0); - } - -#ifdef SO_REUSEPORT - - if (setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, (char *)&one, sizeof( one)) < 0) - { - perror( "*** set socket option REUSEPORT ***"); - exit(0); - } -#endif - - if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) - { - perror( "*** bind ***"); - exit(0); - } - - addrlen = sizeof( local ); - if (getsockname(fd,(struct sockaddr *)&local, &addrlen) < 0) - { - perror( "***get socket name ***"); - exit(0); - } - - if (listen( fd, 128) < 0){ - perror( "*** listen ***"); - exit(0); - }; - - - LIST_ADD( servers_list, server ); - if ( !server ) - { - fprintf(stderr,"NOK Memory Alloc Error\n"); - exit(0); - } - server->channel = ChannelSetUp( fd, server, DeleteSocket, HandleServer ); - server->create = create; - server->handle_delete = handle_delete; - server->interpretation = interpretation; - return ntohs(local.sin_port); -} -char *SocketGetPeerHost( Client client ) -{ - int err; - struct sockaddr_in name; - struct hostent *host; - int len = sizeof(name); - err = getpeername( client->channel->fd, (struct sockaddr *)&name, &len ); - if ( err < 0 ) return "can't get peer"; - host = gethostbyaddr( (char *)&name.sin_addr.s_addr,sizeof(name.sin_addr.s_addr),name.sin_family); - if ( host == NULL ) return "can't translate addr"; - return host->h_name; -} -struct in_addr * SocketGetRemoteAddr( Client client ) -{ - return &client->from.sin_addr; -} -void SocketGetRemote( Client client, char **host, unsigned short *port ) -{ - struct hostent *hostp; - /* extract hostname and port from last message received */ - hostp = gethostbyaddr( (char *)&client->from.sin_addr.s_addr, - sizeof(client->from.sin_addr.s_addr),client->from.sin_family); - if ( hostp == NULL ) *host = "unknown"; - else *host = hostp->h_name; - *port = ntohs( client->from.sin_port ); -} -void SocketClose( Client client ) -{ - ChannelClose( client->channel ); -} - -void SocketSendRaw( Client client, char *buffer, int len ) -{ - int err; - err = send( client->channel->fd, buffer, len, 0 ); - if ( err != len ) - perror( "*** send ***"); -} -void SocketSetData( Client client, void *data ) -{ - client->data = data; -} -void SocketSend( Client client, char *fmt, ... ) -{ - char buffer[4096]; - va_list ap; - int len; - va_start( ap, fmt ); - len = vsprintf( buffer, fmt, ap ); - SocketSendRaw( client, buffer, len ); - va_end ( ap ); -} -void *SocketGetData( Client client ) -{ - return client->data; -} -void SocketBroadcast( char *fmt, ... ) -{ - Client client; - char buffer[4096]; - va_list ap; - int len; - - va_start( ap, fmt ); - len = vsprintf( buffer, fmt, ap ); - va_end ( ap ); - LIST_EACH( clients_list, client ) - { - SocketSendRaw( client, buffer, len ); - } -} -/* -Ouverture d'un canal TCP/IP en mode client -*/ -Client SocketConnect( char * host, unsigned short port, - void *data, - SocketInterpretation interpretation, - void (*handle_delete)(Client client, void *data) - ) -{ -struct hostent *rhost; - - -if ((rhost = gethostbyname( host )) == NULL){ - fprintf(stderr, "Erreur %s Calculateur inconnu !\n",host); - return NULL; - }; -return SocketConnectAddr( (struct in_addr*)(rhost->h_addr), port, data, interpretation, handle_delete); -} -Client SocketConnectAddr( struct in_addr * addr, unsigned short port, - void *data, - SocketInterpretation interpretation, - void (*handle_delete)(Client client, void *data) - ) -{ -HANDLE handle; -Client client; -struct sockaddr_in remote; - -remote.sin_family = AF_INET; -remote.sin_addr = *addr; -remote.sin_port = htons (port); - -if ((handle = socket( AF_INET, SOCK_STREAM, 0)) < 0){ - perror( "*** client socket ***"); - return NULL; - }; - -if ( connect( handle, (struct sockaddr *)&remote, sizeof(remote) ) < 0){ - perror( "*** client connect ***"); - return NULL; - }; - -LIST_ADD( clients_list, client ); -if ( !client ) - { - fprintf(stderr,"NOK Memory Alloc Error\n"); - close( handle ); - exit(0); - } - - -client->channel = ChannelSetUp( handle, client, DeleteSocket, HandleSocket ); -client->interpretation = interpretation; -client->ptr = client->buffer; -client->data = data; -client->handle_delete = handle_delete; -client->from.sin_family = AF_INET; -client->from.sin_addr = *addr; -client->from.sin_port = htons (port); - -return client; -} -int SocketWaitForReply( Client client, char *buffer, int size, int delai) -{ - fd_set rdset; - struct timeval timeout; - struct timeval *timeoutptr = &timeout; - int ready; - char *ptr; - char *ptr_nl; - long nb_to_read = 0; - long nb; - HANDLE fd; - - fd = client->channel->fd; - ptr = buffer; - timeout.tv_sec = delai; - timeout.tv_usec = 0; - do { - /* limitation taille buffer */ - nb_to_read = size - ( ptr - buffer ); - if( nb_to_read == 0 ) - { - fprintf(stderr, "Erreur message trop long sans LF\n"); - ptr = buffer; - return -1; - } - FD_ZERO( &rdset ); - FD_SET( fd, &rdset ); - ready = select(fd+1, &rdset, 0, 0, timeoutptr); - if ( ready < 0 ) - { - perror("select"); - return -1; - } - if ( ready == 0 ) - { - return -2; - } - if ((nb = recv( fd , ptr, nb_to_read, 0 )) < 0) - { - perror(" Read Socket "); - return -1; - } - if ( nb == 0 ) - return 0; - - ptr += nb; - *ptr = '\0'; - ptr_nl = strchr( buffer, '\n' ); - } while ( !ptr_nl ); - *ptr_nl = '\0'; - return (ptr_nl - buffer); -} -void ChannelInit(void) -{ -#ifdef WIN32 - int error; -#else - signal( SIGPIPE, SIG_IGN); -#endif - if ( channel_initialized ) return; -#ifndef XTMAINLOOP - FD_ZERO( &open_fds ); -#endif -#ifdef WIN32 - error = WSAStartup( 0x0101, &WsaData ); - if ( error == SOCKET_ERROR ) { - printf( "WSAStartup failed.\n" ); - } -#endif - channel_initialized = 1; -} - -#ifdef XTMAINLOOP - -void SetSocketAppContext( XtAppContext cntx ) -{ - app = cntx; -} - -void ChannelMainLoop(void(*hook)(void)) -{ - printf("Compiled for Use of XtMainLoop not ChannelMainLoop\n"); - exit(-1); -} -#else -void ChannelStop(void) -{ - MainLoop = 0; -} -void ChannelMainLoop(void(*hook)(void)) -{ - -fd_set rdset; -fd_set exset; -int ready; - - - - while (MainLoop) { - ChannelDefferedDelete(); - if ( hook ) (*hook)(); - rdset = open_fds; - exset = open_fds; - ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout()); - if ( ready < 0 && ( errno != EINTR )) - { - perror("select"); - return; - } - TimerScan(); - if ( ready > 0 ) - { - ChannelHandleExcpt(&exset); - ChannelHandleRead(&rdset); - continue; - } - } -} -#endif -/* Socket UDP */ - -Client SocketBroadcastCreate( unsigned short port, - void *data, - SocketInterpretation interpretation - ) -{ -HANDLE handle; -Client client; -struct sockaddr_in local; -int on = 1; - -local.sin_family = AF_INET; -local.sin_addr.s_addr = INADDR_ANY; -local.sin_port = htons (port); - -if ((handle = socket( AF_INET, SOCK_DGRAM, 0)) < 0){ - perror( "*** dgram socket ***"); - return NULL; - }; - -/* wee need to used multiple client on the same host */ -if (setsockopt( handle, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof( on)) < 0) - { - perror( "*** set socket option REUSEADDR ***"); - return NULL; - }; -#ifdef SO_REUSEPORT - -if (setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof( on)) < 0) - { - perror( "*** set socket option REUSEPORT ***"); - return NULL; - } -#endif -/* wee need to broadcast */ -if (setsockopt( handle, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof( on)) < 0) - { - perror( "*** BROADCAST ***"); - return NULL; - }; - -if (bind(handle, (struct sockaddr *)&local, sizeof(local)) < 0) - { - perror( "*** test BIND ***"); - return NULL; - }; - -LIST_ADD( clients_list, client ); -if ( !client ) - { - fprintf(stderr,"NOK Memory Alloc Error\n"); - close( handle ); - exit(0); - } - - -client->channel = ChannelSetUp( handle, client, DeleteSocket, HandleSocket ); -client->interpretation = interpretation; -client->ptr = client->buffer; -client->data = data; - -return client; -} - -void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *fmt, ... ) -{ - struct sockaddr_in remote; - char buffer[4096]; - va_list ap; - int err,len; - - va_start( ap, fmt ); - len = vsprintf( buffer, fmt, ap ); - /* Send UDP packet to the dest */ - remote.sin_family = AF_INET; - remote.sin_addr.s_addr = htonl( host ); - remote.sin_port = htons(port); - err = sendto( client->channel->fd, - buffer, len,0, - (struct sockaddr *)&remote,sizeof(remote)); - if ( err != len ) - { - perror( "*** send ***"); - } va_end ( ap ); -} diff --git a/src/socket.h b/src/socket.h deleted file mode 100644 index 99b9abd..0000000 --- a/src/socket.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _SOCKET_H -#define _SOCKET_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* general Handle */ - -#define ANYPORT 0 - -#ifdef WIN32 -#include -#define HANDLE SOCKET -#else -#define HANDLE int -#include -#endif - -typedef struct _channel *Channel; - -extern void ChannelInit(void); -extern void ChannelStop(void); -extern void ChannelMainLoop(void(*hook)(void) ); -extern Channel ChannelSetUp( - HANDLE fd, - void *data, - void (*handle_delete)( void *data ), - void (*handle_read)( Channel channel, HANDLE fd, void *data) - ); - -extern void ChannelClose( Channel channel ); - -/* Server Part */ -typedef struct _client *Client; -typedef void (*SocketInterpretation)( Client client, void *data, char *ligne); - -extern void SocketClose( Client client ); -extern void SocketSend( Client client, char *fmt, ... ); -extern void SocketSendRaw( Client client, char *buffer, int len ); -extern char *SocketGetPeerHost( Client client ); -extern void SocketSetData( Client client, void *data ); -extern void *SocketGetData( Client client ); -extern void SocketBroadcast( char *fmt, ... ); - -extern int SocketServer(unsigned short port, - void*(*create)(Client client), - void(*handle_delete)(Client client, void *data), - SocketInterpretation interpretation); - -/* Client Part */ - -extern Client SocketConnect( char * host, unsigned short port, - void *data, - SocketInterpretation interpretation, - void (*handle_delete)(Client client, void *data) - ); -extern Client SocketConnectAddr( struct in_addr * addr, unsigned short port, - void *data, - SocketInterpretation interpretation, - void (*handle_delete)(Client client, void *data) - ); -extern int SocketWaitForReply( Client client, char *buffer, int size, int delai); - -/* Socket UDP */ -/* Creation d'une socket en mode non connecte */ -/* et ecoute des messages */ -extern Client SocketBroadcastCreate( - unsigned short port, - void *data, - SocketInterpretation interpretation - ); -/* recuperation de l'emetteur du message */ -extern struct in_addr * SocketGetRemoteAddr( Client client ); -extern void SocketGetRemote( Client client, char **host, unsigned short *port ); -/* emmission d'un broadcast UDP */ -extern void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *fmt, ... ); - -#ifdef XTMAINLOOP -extern void SetSocketAppContext( XtAppContext cntx ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/testbus.c b/src/testbus.c index 39d55b5..e42094d 100644 --- a/src/testbus.c +++ b/src/testbus.c @@ -1,7 +1,7 @@ #include #include #include -#include "socket.h" +#include "bussocket.h" #include "bus.h" #include "timer.h" #ifdef XTMAINLOOP -- cgit v1.1