diff options
Diffstat (limited to 'src/ivyprobe.c')
-rw-r--r-- | src/ivyprobe.c | 333 |
1 files changed, 176 insertions, 157 deletions
diff --git a/src/ivyprobe.c b/src/ivyprobe.c index dc134a0..b6d9607 100644 --- a/src/ivyprobe.c +++ b/src/ivyprobe.c @@ -34,109 +34,96 @@ #include <string.h> #ifdef WIN32 #include <windows.h> +#include "getopt.h" #ifdef __MINGW32__ +#include <regex.h> #include <getopt.h> +#endif #else -#include "getopt.h" -#endif // __MINGW32__ -#else // WIN32 #include <sys/time.h> #include <unistd.h> #ifdef __INTERIX extern char *optarg; extern int optind; -#endif // __INTERIX -#endif // WIN32 - -#ifdef USE_PCRE_REGEX -#define OVECSIZE 60 /* must be multiple of 3, for regexp return */ -#include <pcre.h> -#else -#include <regex.h> #endif -#include "ivychannel.h" +#endif +#ifdef XTMAINLOOP +#include "ivyxtloop.h" +#endif +#ifdef GLIBMAINLOOP +#include <glib.h> +#include "ivyglibloop.h" +#endif +#ifdef GLUTMAINLOOP +#include "ivyglutloop.h" +#endif +#ifdef IVYMAINLOOP +#include "ivyloop.h" +#endif #include "ivysocket.h" +#include "ivychannel.h" +#include "ivybind.h" /* to test regexp before passing to BinMsg */ #include "ivy.h" #include "timer.h" #ifdef XTMAINLOOP -#include "ivyxtloop.h" #include <X11/Intrinsic.h> XtAppContext cntx; - #endif int app_count = 0; int wait_count = 0; int fbindcallback = 0; +int filter_count = 0; +const char *filter[4096]; +char *classes; -void DirectCallback(IvyClientPtr app, void *user_data, int id, int len, void *msg ) +void DirectCallback(IvyClientPtr app, void *user_data, int id, char *msg ) { - printf("%s sent a direct message, id=%d, message=%.*s\n", - IvyGetApplicationName(app),id,len,(char*)msg); + printf("%s sent a direct message, id=%d, message=%s\n", + IvyGetApplicationName(app),id,msg); } -void BindCallback(IvyClientPtr app, void *user_data, IvyBindEvent event, char *regexp ) -{ - char *sevent; - sevent= event==IvyAddBind ? "added" :"removed"; - - printf("%s has modified his binding, regexp=%s is %s\n", - IvyGetApplicationName(app),regexp,sevent); -} -void Callback (IvyClientPtr app, void *user_data, IvyArgument args) +void Callback (IvyClientPtr app, void *user_data, int argc, char *argv[]) { - IvyArgument arg; - int len; - const void* value; - printf ("%s sent:",IvyGetApplicationName(app)); - arg = IvyArgumentGetChildrens ( args ) ; - while( arg ) - { - IvyArgumentGetValue( arg, &len, &value ); - printf(" '%.*s'",len, (char*)value ); - arg = IvyArgumentGetNextChild( arg ); - } + int i; + printf ("%s sent ",IvyGetApplicationName(app)); + for (i = 0; i < argc; i++) + printf(" '%s'",argv[i]); printf("\n"); } char * Chop(char *arg) { - int len; + size_t len; if (arg==NULL) return arg; len=strlen(arg)-1; if ((*(arg+len))=='\n') *(arg+len)=0; return arg; } -void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) - +void HandleStdin (Channel channel, HANDLE fd, void *data) { char buf[4096]; char *line; char *cmd; char *arg; - char *choparg; - char **applist; int id; IvyClientPtr app; int err; line = fgets(buf, 4096, stdin); if (!line) { -#ifdef WIN32 -#else + IvyChannelRemove (channel); -#endif IvyStop(); return; - } if (*line == '.') { cmd = strtok (line, ".: \n"); if (strcmp (cmd, "die") == 0) { - arg = strtok (NULL, "\n"); /* no space separator appname can containt space*/ + arg = strtok (NULL, " \n"); if (arg) { app = IvyGetApplication (arg); if (app) @@ -145,50 +132,34 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) } } else if (strcmp(cmd, "dieall-yes-i-am-sure") == 0) { - applist = IvyGetApplicationList(); - while (*applist) { - app = IvyGetApplication (*applist); + arg = IvyGetApplicationList("#"); + arg = strtok (arg, "#"); + while (arg) { + app = IvyGetApplication (arg); if (app) IvySendDieMsg (app); else - printf ("No Application %s!!!\n",*applist); - applist++; + printf ("No Application %s!!!\n",arg); + arg = strtok (NULL, " "); } } else if (strcmp(cmd, "bind") == 0) { arg = strtok (NULL, "'"); + Chop(arg); if (arg) { -#ifdef USE_PCRE_REGEX - pcre *regexp; + IvyBinding bind; const char *errbuf; int erroffset; - Chop(arg); - regexp = pcre_compile(arg, 0,&errbuf,&erroffset,NULL); - if (regexp==NULL) { - printf("Error compiling '%s', %s, not bound\n", arg, errbuf); -#else - regex_t reg; - int err; - Chop(arg); - if (err=regcomp(®,arg,REG_ICASE|REG_EXTENDED)!=0) { - char errbuf[4096]; - regerror (err, ®, errbuf, 4096); - printf("Error compiling '%s', %s, not bound\n", arg, errbuf); - -#endif + bind = IvyBindingCompile(arg, & erroffset, & errbuf); + if (bind==NULL) { + printf("Error compiling '%s', %s, not bound\n", arg, errbuf); } else { - IvyBindMsg (Callback, NULL, Chop(arg)); + IvyBindingFree( bind ); + IvyBindMsg (Callback, NULL, arg); } } - } - else if (strcmp(cmd, "bindsimple") == 0) { - arg = strtok (NULL, "'"); - if (arg) { - IvyBindSimpleMsg (Callback, NULL, Chop(arg)); - } - } - else if (strcmp(cmd, "where") == 0) { + } else if (strcmp(cmd, "where") == 0) { arg = strtok (NULL, " \n"); if (arg) { app = IvyGetApplication (arg); @@ -199,103 +170,54 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data) } else if (strcmp(cmd, "direct") == 0) { arg = strtok (NULL, " \n"); if (arg) { - choparg = Chop(arg); app = IvyGetApplication (arg); if (app) { arg = strtok (NULL, " "); id = atoi (arg) ; arg = strtok (NULL, "'"); - IvySendDirectMsg (app, id, strlen(choparg), choparg); + IvySendDirectMsg (app, id, Chop(arg)); } else printf ("No Application %s!!!\n",arg); } } else if (strcmp(cmd, "who") == 0) { - applist = IvyGetApplicationList(); - while (*applist) { - printf ("Application '%s'\n",*applist); - applist++; - } + printf("Apps: %s\n", IvyGetApplicationList(",")); } else if (strcmp(cmd, "help") == 0) { fprintf(stderr,"Commands list:\n"); - printf(" .help - this help\n"); - printf(" .quit - terminate this application\n"); - printf(" .die appname - send die msg to appname\n"); - 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 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) { + printf(" .help - this help\n"); + printf(" .quit - terminate this application\n"); + printf(" .die appname - send die msg to appname\n"); + 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(" .showbind - show bindings \n"); + + printf(" .who - who is on the bus\n"); + } else if (strcmp(cmd, "showbind") == 0) { if (!fbindcallback) { - IvySetBindCallback(BindCallback, NULL); + IvySetBindCallback(IvyDefaultBindCallback, NULL); fbindcallback=1; } else { - IvySetBindCallback(NULL, NULL); + IvySetBindCallback(NULL, NULL); fbindcallback=0; } } else if (strcmp(cmd, "quit") == 0) { - IvyStop(); /* this wil exit MainLoop */ - //exit(0); -#ifdef WIN32 - ExitThread( 0 ); /* exit STDin handle thread */ -#endif + exit(0); } } else { cmd = strtok (buf, "\n"); - if ( cmd ) - { err = IvySendMsg (cmd); printf("-> Sent to %d peer%s\n", err, err == 1 ? "" : "s"); - } } } -#ifdef WIN32 -DWORD WINAPI HandleStdinThread( LPVOID lpParam ) -{ - while( 1 ) - HandleStdin( 0,0,0); -} -void CreateStdinThread() -{ - DWORD dwThreadId, dwThrdParam = 1; - HANDLE hThread; - - hThread = CreateThread( - NULL, // default security attributes - 0, // use default stack size - HandleStdinThread, // thread function - &dwThrdParam, // argument to thread function - 0, // use default creation flags - &dwThreadId); // returns the thread identifier - - // Check the return value for success. - - if (hThread == NULL) - { - printf( "CreateThread failed (%d)\n", GetLastError() ); - } -} -#endif -void StartHandleStdin() -{ -#ifdef WIN32 - /* Stdin not compatible with select , select only accept socket */ - /* use Thread to Read StdIn */ - CreateStdinThread(); -#else - IvyChannelAdd (0, NULL, NULL, HandleStdin); -#endif -} void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent event) { char *appname; char *host; - char **msgList; +/* char **msgList;*/ appname = IvyGetApplicationName (app); host = IvyGetApplicationHost (app); switch (event) { @@ -304,12 +226,17 @@ void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent app_count++; printf("%s connected from %s\n", appname, host); /* printf("Application(%s): Begin Messages\n", appname);*/ +/* double usage with -s flag remove it msgList = IvyGetApplicationMessages (app); while (*msgList ) printf("%s subscribes to '%s'\n",appname,*msgList++); +*/ /* printf("Application(%s): End Messages\n",appname);*/ +#ifndef WIN32 +/* Stdin not compatible with select , select only accept socket */ if (app_count == wait_count) - StartHandleStdin(); + IvyChannelAdd (0, NULL, NULL, HandleStdin); +#endif break; case IvyApplicationDisconnected: @@ -322,13 +249,40 @@ void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent break; } } +void IvyPrintBindCallback( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event) +{ + switch ( event ) { + case IvyAddBind: + if ( fbindcallback ) + printf("Application: %s on %s add regexp %d : %s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyRemoveBind: + if ( fbindcallback ) + printf("Application: %s on %s remove regexp %d :%s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyFilterBind: + printf("Application: %s on %s as been filtred regexp %d :%s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyChangeBind: + if ( fbindcallback ) + printf("Application: %s on %s change regexp %d : %s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + default: + printf("Application: %s unkown event %d\n",IvyGetApplicationName( app ), event); + break; + } +} -#ifndef XTMAINLOOP +#ifdef IVYMAINLOOP void TimerCall(TimerId id, void *user_data, unsigned long delta) { - printf("Timer callback: %d delta %lu ms\n", (int)user_data, delta); - IvySendMsg ("TEST TIMER %d", (int)user_data); + printf("Timer callback: %ld delta %lu ms\n", (long)user_data, delta); + IvySendMsg ("TEST TIMER %d", (long)user_data); /*if ((int)user_data == 5) TimerModify (id, 2000);*/ } #endif @@ -341,18 +295,62 @@ display(void) } #endif +void BindMsgOfFile( const char * regex_file ) +{ + char line[4096]; + size_t size; + FILE* file; + file = fopen( regex_file, "r" ); + if ( !file ) { + perror( "Regexp file open "); + return; + } + while( !feof( file ) ) + { + if ( fgets( line, sizeof(line), file ) ) + { + size = strlen(line); + if ( size > 1 ) + { + line[size-1] = '\0'; /* supress \n */ + IvyBindMsg (Callback, NULL, line); + } + } + } +} +void BuildFilterRegexp() +{ + char *word=strtok( classes, "," ); + while ( word != NULL && (filter_count < 4096 )) + { + filter[filter_count++] = word; + word = strtok( NULL, ","); + } + if ( filter_count ) + IvySetFilter( filter_count, filter ); +} int main(int argc, char *argv[]) { int c; int timer_test = 0; char busbuf [1024] = ""; const char* bus = 0; + const char* regex_file = 0; char agentnamebuf [1024] = ""; const char* agentname = DEFAULT_IVYPROBE_NAME; char agentready [1024] = ""; const char* helpmsg = - "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n\t-t\ttriggers the timer test\n\t-n name\tchanges the name of the agent, defaults to IVYPROBE\n\t-v\tprints the ivy relase number\n\nregexp is a Perl5 compatible regular expression (see ivyprobe(1) and pcrepattern(3) for more info\nuse .help within ivyprobe\n\t-s bindcall\tactive the interception of regexp's subscribing or unscribing\n"; - while ((c = getopt(argc, argv, "vn:d:b:w:t:s")) != EOF) + "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n" + "\t-t\ttriggers the timer test\n" + "\t-n name\tchanges the name of the agent, defaults to IVYPROBE\n" + "\t-v\tprints the ivy relase number\n\n" + "regexp is a Perl5 compatible regular expression (see ivyprobe(1) and pcrepattern(3) for more info\n" + "use .help within ivyprobe\n" + "\t-s bindcall\tactive the interception of regexp's subscribing or unscribing\n" + "\t-f regexfile\tread list of regexp's from file one by line\n" + "\t-c msg1,msg2,msg3,...\tfilter the regexp's not beginning with words\n" + ; + while ((c = getopt(argc, argv, "vn:d:b:w:t:sf:c:")) != EOF) switch (c) { case 'b': strcpy (busbuf, optarg); @@ -361,6 +359,9 @@ int main(int argc, char *argv[]) case 'w': wait_count = atoi(optarg) ; break; + case 'f': + regex_file = optarg ; + break; case 'n': strcpy(agentnamebuf, optarg); agentname=agentnamebuf; @@ -371,9 +372,11 @@ int main(int argc, char *argv[]) timer_test = 1; break; case 's': - IvySetBindCallback(BindCallback, NULL); fbindcallback=1; break; + case 'c': + classes= strdup(optarg); + break; default: printf("usage: %s %s",argv[0],helpmsg); exit(1); @@ -393,13 +396,21 @@ int main(int argc, char *argv[]) glutDisplayFunc(display); #endif IvyInit (agentname, agentready, ApplicationCallback,NULL,NULL,NULL); - IvySetApplicationPriority( 0 ); /* lower priority */ + IvySetBindCallback(IvyPrintBindCallback, NULL); + IvyBindDirectMsg( DirectCallback,NULL); + if ( classes ) + BuildFilterRegexp(); + if ( regex_file ) + BindMsgOfFile( regex_file ); for (; optind < argc; optind++) IvyBindMsg (Callback, NULL, argv[optind]); if (wait_count == 0) - StartHandleStdin(); +#ifndef WIN32 +/* Stdin not compatible with select , select only accept socket */ + IvyChannelAdd (0, NULL, NULL, HandleStdin); +#endif IvyStart (bus); @@ -413,11 +424,19 @@ int main(int argc, char *argv[]) #ifdef XTMAINLOOP XtAppMainLoop (cntx); #endif +#ifdef GLIBMAINLOOP + { + GMainLoop *ml = g_main_loop_new(NULL, FALSE); + g_main_loop_run(ml); + } +#endif +#ifdef GLUTMAINLOOP + glutMainLoop(); +#endif - IvyMainLoop (0); - #ifdef _CRTDBG_MAP_ALLOC - _CrtDumpMemoryLeaks(); - #endif - +#ifdef IVYMAINLOOP + IvyMainLoop (); +#endif return 0; } + |