diff options
-rw-r--r-- | src/ivy.c | 26 | ||||
-rw-r--r-- | src/ivy.h | 2 | ||||
-rw-r--r-- | src/ivybind.c | 74 | ||||
-rw-r--r-- | src/ivybind.h | 1 | ||||
-rw-r--r-- | src/ivyprobe.c | 32 | ||||
-rw-r--r-- | src/libIvy.def | 1 |
6 files changed, 107 insertions, 29 deletions
@@ -329,6 +329,8 @@ static int ClientCall (IvyClientPtr clnt, const char *message) { MsgSndPtr msg; int match_count = 0; + /* for simple binding message syntax msg arg1=val1 arg2=val2 ... argn=valn */ + IvyBindingParseMessage( message ); /* recherche dans la liste des requetes recues de ce client */ IVY_LIST_EACH (clnt->msg_send, msg) { match_count+= MsgSendCallTo (clnt->client, message, msg ); @@ -343,9 +345,12 @@ static int CheckConnected( IvyClientPtr clnt ) struct in_addr *addr1; struct in_addr *addr2; + /* TODO check multiple instance of the same application name */ + if ( clnt->app_port == 0 ) /* Old Ivy Protocol Dont check */ return 0; /* recherche dans la liste des clients de la presence de clnt */ + /* TODO check based on appid not on the copule host:port */ IVY_LIST_EACH( clients, client ) { /* client different mais port identique */ @@ -407,7 +412,8 @@ static char* Receive( Client client, void *data, char *message, unsigned int len SocketClose( client ); break; case Error: - printf ("Received error %d %.*s\n", id, len_args, (char*)args); + /*TODO Callback */ + fprintf (stderr, "Received error %d %.*s from %s\n", id, len_args, (char*)args, clnt->app_name); break; case AddRegexp: @@ -619,7 +625,7 @@ BOOL SendRegexp(HASHKEYTYPE key, void *data, va_list args) { Client client = va_arg( args, Client); MsgRcvPtr msg = (MsgRcvPtr)data; - MsgSendTo( client, AddRegexp,msg->id,strlen(msg->regexp), msg->regexp); + MsgSendTo( client, msg->type == IvyBindRegexp ? AddRegexp : AddBinding, msg->id, strlen(msg->regexp), msg->regexp); return FALSE; /* iter throught all hash table */ } static IvyClientPtr SendService( Client client ) @@ -759,6 +765,12 @@ static char* BroadcastReceive( Client client, void *data, char *message, unsigne SocketGetRemoteHost (client, &remotehost, &remoteport ); printf(" Broadcast de %s:%hu port %hu %s %s\n", remotehost, remoteport, serviceport, appname, appid ); #endif //DEBUG + /* check if already the same name on the bus */ + if ( strcmp( appname,ApplicationName )== 0) + { + /* TODO rize some callback ? */ + fprintf(stderr,"!!! Warning a another instance of %s is arriving on the Bus !!!\n", ApplicationName ); + } /* connect to the service and send the regexp */ app = SocketConnectAddr(SocketGetRemoteAddr(client), serviceport, 0, Receive, ClientDelete ); @@ -1142,15 +1154,15 @@ IvyClientPtr IvyGetApplication( char *name ) return app; } -char *IvyGetApplicationList() +char **IvyGetApplicationList() { - static char applist[4096]; + static char* applist[500]; IvyClientPtr app; - applist[0] = '\0'; + int appCount= 0; + memset( applist, 0 , sizeof( applist )); IVY_LIST_EACH( clients, app ) { - strcat( applist, app->app_name ); - strcat( applist, " " ); + applist[appCount++]= app->app_name; } return applist; } @@ -101,7 +101,7 @@ char *IvyGetApplicationName( IvyClientPtr app ); char *IvyGetApplicationHost( IvyClientPtr app ); char *IvyGetApplicationId( IvyClientPtr app ); IvyClientPtr IvyGetApplication( char *name ); -char *IvyGetApplicationList(); +char ** IvyGetApplicationList(); char **IvyGetApplicationMessages( IvyClientPtr app); /* demande de reception d'un message */ MsgRcvPtr IvyBindMsg( MsgCallback callback, void *user_data, const char *fmt_regexp, ... ); /* avec sprintf prealable */ diff --git a/src/ivybind.c b/src/ivybind.c index 9aae16d..656be62 100644 --- a/src/ivybind.c +++ b/src/ivybind.c @@ -21,6 +21,8 @@ #include <time.h> #include <stdlib.h> #include <memory.h> +#include <string.h> +#include <stdarg.h> #ifdef USE_PCRE_REGEX #define OVECSIZE 60 /* must be multiple of 3, for regexp return */ @@ -31,6 +33,7 @@ #endif #include "list.h" +#include "hash.h" #include "ivybind.h" static int err_offset; @@ -44,6 +47,9 @@ static int err_offset; struct _binding { struct _binding *next; IvyBindingType type; + const char *msgname; /* msg tag name first word of message */ + char **msgargs; /* list of msg argument name */ + IvyArgument args; /* result */ #ifdef USE_PCRE_REGEX pcre *regexp; pcre_extra *inspect; @@ -60,16 +66,36 @@ struct _binding { static int messages_classes_count = 0; static const char **messages_classes = 0; + +/* stokage du message parse avant l'execution des regles de binding simple */ +static char *current_msg = NULL; +static char *msgtag; +static HASHTABLE msg_args_values = NULL; + static IvyBinding IvyBindingCompileSimple( IvyBindingType typ, const char * expression ) { - //TODO return NULL - err_offset = 0; -#ifdef USE_PCRE_REGEX - err_buf = "Not Yiet Implemented"; -#else - strcpy( err_buf, "Not Yiet Implemented" ); -#endif - return NULL; + int nb_arg= 0; + char *argname; + char **argv; + char *expr; + IvyBinding bind=0; + + expr = strdup( expression ); //Allocate a new buffer of separated token + /* count nb args */ + argname = expr; + while ( *argname ) + { + if ( *argname++ == ' ' ) nb_arg++; + } + + bind = (IvyBinding)malloc( sizeof( struct _binding )); + bind->msgname = strtok( expr, " "); + bind->msgargs = malloc ( sizeof( char* ) * ( nb_arg + 1) ); + argv = bind->msgargs; + while ( (argname = strtok( NULL, " ")) ) + *argv++ = argname; + *argv++ = argname; /* end with NULL */ + return bind; } static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expression ) { @@ -166,7 +192,19 @@ int IvyBindingExecRegexp( IvyBinding bind, const char * message ) } int IvyBindingExecSimple( IvyBinding bind, const char * message ) { - return 0; + char **msg_args; + if ( strcmp( bind->msgname, msgtag ) != 0 ) + return 0; + msg_args = bind->msgargs; + bind->args = IvyArgumentNew( 0,NULL ); + while( *msg_args ) + { + char *value; + value = hash_lookup(msg_args_values, (HASHKEYTYPE)*msg_args++); + if ( !value ) value = ""; /* TODO should we report matching ??? */ + IvyAddChildValue( bind->args, strlen( value ), value); + } + return 1; } int IvyBindingExec( IvyBinding bind, const char * message ) { @@ -177,8 +215,7 @@ int IvyBindingExec( IvyBinding bind, const char * message ) } static IvyArgument IvyBindingMatchSimple( IvyBinding bind, const char *message) { - //TODO - return NULL; + return bind->args; } static IvyArgument IvyBindingMatchRegexp( IvyBinding bind, const char *message) { @@ -225,6 +262,21 @@ void IvyBindingSetFilter( int argc, const char **argv) messages_classes_count = argc; messages_classes = argv; } +void IvyBindingParseMessage( const char *msg ) +{ + char *arg; + if ( current_msg ) free( current_msg ); + if ( msg_args_values ) hash_destroy( msg_args_values ); + current_msg = strdup( msg ); + msg_args_values = hash_create( 256, TRUE ); + msgtag = strtok( current_msg, " " ); + while( (arg = strtok( NULL, " =" )) ) + { + char *val = strtok( NULL, " ="); + if ( arg && val ) + hash_add( msg_args_values, (HASHKEYTYPE)arg, val ); + } +} int IvyBindingFilter(IvyBindingType typ, int len, const char *exp) { /* TODO check args limits !!!*/ diff --git a/src/ivybind.h b/src/ivybind.h index 830079b..8c3166e 100644 --- a/src/ivybind.h +++ b/src/ivybind.h @@ -21,6 +21,7 @@ typedef struct _binding *IvyBinding; typedef enum { IvyBindRegexp, IvyBindSimple } IvyBindingType; +void IvyBindingParseMessage( const char *msg ); void IvyBindingSetFilter( int argc, const char ** argv ); int IvyBindingFilter( IvyBindingType typ, int len, const char *exp ); IvyBinding IvyBindingCompile( IvyBindingType typ, const char * expression ); diff --git a/src/ivyprobe.c b/src/ivyprobe.c index c163577..bea1625 100644 --- a/src/ivyprobe.c +++ b/src/ivyprobe.c @@ -118,6 +118,7 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) char *cmd; char *arg; char *choparg; + char **applist; int id; IvyClientPtr app; int err; @@ -135,7 +136,7 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) cmd = strtok (line, ".: \n"); if (strcmp (cmd, "die") == 0) { - arg = strtok (NULL, " \n"); + arg = strtok (NULL, "\n"); /* no space separator appname can containt space*/ if (arg) { app = IvyGetApplication (arg); if (app) @@ -144,15 +145,14 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) } } else if (strcmp(cmd, "dieall-yes-i-am-sure") == 0) { - arg = IvyGetApplicationList(); - arg = strtok (arg, " \n"); - while (arg) { - app = IvyGetApplication (arg); + applist = IvyGetApplicationList(); + while (*applist) { + app = IvyGetApplication (*applist); if (app) IvySendDieMsg (app); else - printf ("No Application %s!!!\n",arg); - arg = strtok (NULL, " "); + printf ("No Application %s!!!\n",*applist); + applist++; } } else if (strcmp(cmd, "bind") == 0) { @@ -181,7 +181,14 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) } } - } else if (strcmp(cmd, "where") == 0) { + } + else if (strcmp(cmd, "bindsimple") == 0) { + arg = strtok (NULL, "'"); + if (arg) { + IvyBindSimpleMsg (Callback, NULL, Chop(arg)); + } + } + else if (strcmp(cmd, "where") == 0) { arg = strtok (NULL, " \n"); if (arg) { app = IvyGetApplication (arg); @@ -204,7 +211,11 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) } } else if (strcmp(cmd, "who") == 0) { - printf("Apps: %s\n", IvyGetApplicationList()); + applist = IvyGetApplicationList(); + while (*applist) { + printf ("Application '%s'\n",*applist); + applist++; + } } else if (strcmp(cmd, "help") == 0) { fprintf(stderr,"Commands list:\n"); @@ -214,7 +225,8 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) printf(" .dieall-yes-i-am-sure - send die msg to all applis\n"); printf(" .direct appname id 'arg' - send direct msg to appname\n"); printf(" .where appname - on which host is appname\n"); - printf(" .bind 'regexp' - add a msg to receive\n"); + printf(" .bind 'regexp' - add a msg to receive using regexp\n"); + printf(" .bindsimple 'expr' - add a msg to receive using simple msg format tag param param\n"); printf(" .bindcall - toogle callback to binding\n"); printf(" .who - who is on the bus\n"); } else if (strcmp(cmd, "bindcall") == 0) { diff --git a/src/libIvy.def b/src/libIvy.def index acf1786..4f7e3ba 100644 --- a/src/libIvy.def +++ b/src/libIvy.def @@ -15,6 +15,7 @@ IvyGetApplication IvyGetApplicationList IvyGetApplicationMessages IvyBindMsg +IvyBindSimpleMsg IvyUnbindMsg IvySendError IvySendDieMsg |