]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/srfsh/srfsh.c
changing back to an array, from calloc. more straight-forward, and avoids memset...
[OpenSRF.git] / src / srfsh / srfsh.c
1 #include <opensrf/transport_client.h>
2 #include <opensrf/osrf_message.h>
3 #include <opensrf/osrf_app_session.h>
4 #include <time.h>
5 #include <sys/timeb.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8
9 #include <opensrf/utils.h>
10 #include <opensrf/log.h>
11
12 #include <signal.h>
13
14 #include <stdio.h>
15 #include <readline/readline.h>
16 #include <readline/history.h>
17
18 #define SRFSH_PORT 5222
19 #define COMMAND_BUFSIZE 4096
20
21
22 /* shell prompt */
23 static const char* prompt = "srfsh# ";
24
25 static char* history_file = NULL;
26
27 //static int child_dead = 0;
28
29 static char* login_session = NULL;
30
31 /* true if we're pretty printing json results */
32 static int pretty_print = 1;
33 /* true if we're bypassing 'less' */
34 static int raw_print = 0;
35
36 /* our jabber connection */
37 static transport_client* client = NULL; 
38
39 /* the last result we received */
40 static osrf_message* last_result = NULL;
41
42 /* functions */
43 static int parse_request( char* request );
44
45 /* handles router requests */
46 static int handle_router( char* words[] );
47
48 /* utility method for print time data */
49 /* static int handle_time( char* words[] ); */
50
51 /* handles app level requests */
52 static int handle_request( char* words[], int relay );
53 static int handle_set( char* words[]);
54 static int handle_print( char* words[]);
55 static int send_request( char* server, 
56                                   char* method, growing_buffer* buffer, int relay );
57 static int parse_error( char* words[] );
58 static int router_query_servers( const char* server );
59 static int print_help( void );
60
61 //static int srfsh_client_connect();
62 //static char* tabs(int count);
63 //static void sig_child_handler( int s );
64 //static void sig_int_handler( int s );
65
66 static int load_history( void );
67 static int handle_math( char* words[] );
68 static int do_math( int count, int style );
69 static int handle_introspect(char* words[]);
70 static int handle_login( char* words[]);
71
72 static int recv_timeout = 120;
73 static int is_from_script = 0;
74
75 int main( int argc, char* argv[] ) {
76
77         /* --------------------------------------------- */
78         /* see if they have a .srfsh.xml in their home directory */
79         char* home = getenv("HOME");
80         int l = strlen(home) + 36;
81         char fbuf[l];
82         memset(fbuf, 0, l);
83         sprintf(fbuf,"%s/.srfsh.xml",home);
84         
85         if(!access(fbuf, R_OK)) {
86                 if( ! osrf_system_bootstrap_client(fbuf, "srfsh") ) {
87                         fprintf(stderr,"Unable to bootstrap client for requests\n");
88                         osrfLogError( OSRF_LOG_MARK,  "Unable to bootstrap client for requests");
89                         return -1;
90                 }
91
92         } else {
93                 fprintf(stderr,"No Config file found at %s\n", fbuf ); 
94                 return -1;
95         }
96
97         if(argc > 1) {
98                 /* for now.. the first arg is used as a script file for processing */
99                 int f;
100                 if( (f = open(argv[1], O_RDONLY)) == -1 ) {
101                         osrfLogError( OSRF_LOG_MARK, "Unable to open file %s for reading, exiting...", argv[1]);
102                         return -1;
103                 }
104
105                 if(dup2(f, STDIN_FILENO) == -1) {
106                         osrfLogError( OSRF_LOG_MARK, "Unable to duplicate STDIN, exiting...");
107                         return -1;
108                 }
109
110                 close(f);
111                 is_from_script = 1;
112         }
113                 
114         /* --------------------------------------------- */
115         load_history();
116
117
118         client = osrf_system_get_transport_client();
119
120         /* main process loop */
121         char* request;
122         while((request=readline(prompt))) {
123
124                 if( !strcasecmp(request, "exit") || !strcasecmp(request,"quit")) 
125                         break; 
126
127                 char* req_copy = strdup(request);
128
129                 parse_request( req_copy ); 
130                 if( request && strlen(request) > 1 ) {
131                         add_history(request);
132                 }
133
134                 free(request);
135                 free(req_copy);
136
137                 fflush(stderr);
138                 fflush(stdout);
139         }
140
141         if(history_file != NULL )
142                 write_history(history_file);
143
144         free(request);
145
146         osrf_system_shutdown();
147         return 0;
148 }
149
150 /*
151 static void sig_child_handler( int s ) {
152         child_dead = 1;
153 }
154 */
155
156 /*
157 void sig_int_handler( int s ) {
158         printf("\n");
159         caught_sigint = 1;
160         signal(SIGINT,sig_int_handler);
161 }
162 */
163
164 static int load_history( void ) {
165
166         char* home = getenv("HOME");
167         int l = strlen(home) + 24;
168         char fbuf[l];
169
170         memset(fbuf, 0, l);
171         sprintf(fbuf,"%s/.srfsh_history",home);
172         history_file = strdup(fbuf);
173
174         if(!access(history_file, W_OK | R_OK )) {
175                 history_length = 5000;
176                 read_history(history_file);
177         }
178         return 1;
179 }
180
181
182 static int parse_error( char* words[] ) {
183
184         if( ! words )
185                 return 0;
186
187         growing_buffer * gbuf = buffer_init( 64 );
188         buffer_add( gbuf, *words );
189         while( *++words ) {
190                 buffer_add( gbuf, " " );
191                 buffer_add( gbuf, *words );
192         }
193         fprintf( stderr, "???: %s\n", gbuf->buf );
194         buffer_free( gbuf );
195         
196         return 0;
197
198 }
199
200
201 static int parse_request( char* request ) {
202
203         if( request == NULL )
204                 return 0;
205
206         char* original_request = strdup( request );
207         char* words[COMMAND_BUFSIZE]; 
208         
209         int ret_val = 0;
210         int i = 0;
211
212
213         char* req = request;
214         char* cur_tok = strtok( req, " " );
215
216         if( cur_tok == NULL )
217         {
218                 free( original_request );
219                 return 0;
220         }
221
222         /* Load an array with pointers to    */
223         /* the tokens as defined by strtok() */
224         
225         while(cur_tok != NULL) {
226                 if( i < COMMAND_BUFSIZE - 1 ) {
227                         words[i++] = cur_tok;
228                         cur_tok = strtok( NULL, " " );
229                 } else {
230                         fprintf( stderr, "Too many tokens in command\n" );
231                         free( original_request );
232                         return 1;
233                 }
234         }
235
236         words[i] = NULL;
237         
238         /* pass off to the top level command */
239         if( !strcmp(words[0],"router") ) 
240                 ret_val = handle_router( words );
241
242         /*
243         else if( !strcmp(words[0],"time") ) 
244                 ret_val = handle_time( words );
245                 */
246
247         else if (!strcmp(words[0],"request"))
248                 ret_val = handle_request( words, 0 );
249
250         else if (!strcmp(words[0],"relay"))
251                 ret_val = handle_request( words, 1 );
252
253         else if (!strcmp(words[0],"help"))
254                 ret_val = print_help();
255
256         else if (!strcmp(words[0],"set"))
257                 ret_val = handle_set(words);
258
259         else if (!strcmp(words[0],"print"))
260                 ret_val = handle_print(words);
261
262         else if (!strcmp(words[0],"math_bench"))
263                 ret_val = handle_math(words);
264
265         else if (!strcmp(words[0],"introspect"))
266                 ret_val = handle_introspect(words);
267
268         else if (!strcmp(words[0],"login"))
269                 ret_val = handle_login(words);
270
271         else if (words[0][0] == '!') {
272                 system( original_request + 1 );
273                 ret_val = 1;
274         }
275         
276         free( original_request );
277         
278         if(!ret_val)
279                 return parse_error( words );
280         else
281                 return 1;
282 }
283
284
285 static int handle_introspect(char* words[]) {
286
287         if(words[1] && words[2]) {
288                 fprintf(stderr, "--> %s\n", words[1]);
289                 char buf[256];
290                 memset(buf,0,256);
291                 sprintf( buf, "request %s opensrf.system.method %s", words[1], words[2] );
292                 return parse_request( buf );
293
294         } else {
295         
296                 if(words[1]) {
297                         fprintf(stderr, "--> %s\n", words[1]);
298                         char buf[256];
299                         memset(buf,0,256);
300                         sprintf( buf, "request %s opensrf.system.method.all", words[1] );
301                         return parse_request( buf );
302                 }
303         }
304
305         return 0;
306 }
307
308
309 static int handle_login( char* words[]) {
310
311         if( words[1] && words[2]) {
312
313                 char* username          = words[1];
314                 char* password          = words[2];
315                 char* type                      = words[3];
316                 char* orgloc            = words[4];
317                 char* workstation       = words[5];
318                 int orgloci = (orgloc) ? atoi(orgloc) : 0;
319                 if(!type) type = "opac";
320
321                 char buf[256];
322                 memset(buf,0,256);
323
324                 char buf2[256];
325                 memset(buf2,0,256);
326
327                 sprintf( buf, 
328                                 "request open-ils.auth open-ils.auth.authenticate.init \"%s\"", username );
329                 parse_request(buf); 
330
331                 char* hash;
332                 if(last_result && last_result->_result_content) {
333                         jsonObject* r = last_result->_result_content;
334                         hash = jsonObjectGetString(r);
335                 } else return 0;
336
337
338                 char* pass_buf = md5sum(password);
339
340                 char both_buf[256];
341                 memset(both_buf,0,256);
342                 sprintf(both_buf,"%s%s",hash, pass_buf);
343
344                 char* mess_buf = md5sum(both_buf);
345
346                 /*
347                 sprintf( buf2, "request open-ils.auth open-ils.auth.authenticate.complete "
348                                 "{ \"username\" : \"%s\", \"password\" : \"%s\", "
349                                 "\"type\" : \"%s\", \"org\" : %d, \"workstation\": \"%s\"}", 
350                                 username, mess_buf, type, orgloci, workstation );
351                                 */
352
353                 growing_buffer* argbuf = buffer_init(64);
354                 buffer_fadd(argbuf, 
355                                 "request open-ils.auth open-ils.auth.authenticate.complete "
356                                 "{ \"username\" : \"%s\", \"password\" : \"%s\"", username, mess_buf );
357
358                 if(type) buffer_fadd( argbuf, ", \"type\" : \"%s\"", type );
359                 if(orgloci) buffer_fadd( argbuf, ", \"org\" : %d", orgloci );
360                 if(workstation) buffer_fadd( argbuf, ", \"workstation\" : \"%s\"", workstation);
361                 buffer_add(argbuf, "}");
362
363                 free(pass_buf);
364                 free(mess_buf);
365
366                 parse_request( argbuf->buf );
367                 buffer_free(argbuf);
368
369                 jsonObject* x = last_result->_result_content;
370                 double authtime = 0;
371                 if(x) {
372                         char* authtoken = jsonObjectGetString(
373                                         jsonObjectGetKey(jsonObjectGetKey(x,"payload"), "authtoken"));
374                         authtime  = jsonObjectGetNumber(
375                                         jsonObjectGetKey(jsonObjectGetKey(x,"payload"), "authtime"));
376                         if(authtoken) login_session = strdup(authtoken);
377                         else login_session = NULL;
378                 }
379                 else login_session = NULL;
380
381                 printf("Login Session: %s.  Session timeout: %f\n", login_session, authtime );
382                 
383                 return 1;
384
385         }
386
387         return 0;
388 }
389
390 static int handle_set( char* words[]) {
391
392         char* variable;
393         if( (variable=words[1]) ) {
394
395                 char* val;
396                 if( (val=words[2]) ) {
397
398                         if(!strcmp(variable,"pretty_print")) {
399                                 if(!strcmp(val,"true")) {
400                                         pretty_print = 1;
401                                         printf("pretty_print = true\n");
402                                         return 1;
403                                 } 
404                                 if(!strcmp(val,"false")) {
405                                         pretty_print = 0;
406                                         printf("pretty_print = false\n");
407                                         return 1;
408                                 } 
409                         }
410
411                         if(!strcmp(variable,"raw_print")) {
412                                 if(!strcmp(val,"true")) {
413                                         raw_print = 1;
414                                         printf("raw_print = true\n");
415                                         return 1;
416                                 } 
417                                 if(!strcmp(val,"false")) {
418                                         raw_print = 0;
419                                         printf("raw_print = false\n");
420                                         return 1;
421                                 } 
422                         }
423
424                 }
425         }
426
427         return 0;
428 }
429
430
431 static int handle_print( char* words[]) {
432
433         char* variable;
434         if( (variable=words[1]) ) {
435                 if(!strcmp(variable,"pretty_print")) {
436                         if(pretty_print) {
437                                 printf("pretty_print = true\n");
438                                 return 1;
439                         } else {
440                                 printf("pretty_print = false\n");
441                                 return 1;
442                         }
443                 }
444
445                 if(!strcmp(variable,"login")) {
446                         printf("login session = %s\n", login_session );
447                         return 1;
448                 }
449
450         }
451         return 0;
452 }
453
454 static int handle_router( char* words[] ) {
455
456         if(!client)
457                 return 1;
458
459         int i;
460
461         if( words[1] ) { 
462                 if( !strcmp(words[1],"query") ) {
463                         
464                         if( words[2] && !strcmp(words[2],"servers") ) {
465                                 for(i=3; i < COMMAND_BUFSIZE - 3 && words[i]; i++ ) {   
466                                         router_query_servers( words[i] );
467                                 }
468                                 return 1;
469                         }
470                         return 0;
471                 }
472                 return 0;
473         }
474         return 0;
475 }
476
477
478
479 static int handle_request( char* words[], int relay ) {
480
481         if(!client)
482                 return 1;
483
484         if(words[1]) {
485                 char* server = words[1];
486                 char* method = words[2];
487                 int i;
488                 growing_buffer* buffer = NULL;
489                 if(!relay) {
490                         buffer = buffer_init(128);
491                         buffer_add(buffer, "[");
492                         for(i = 3; words[i] != NULL; i++ ) {
493                                 /* removes trailing semicolon if user accidentally enters it */
494                                 if( words[i][strlen(words[i])-1] == ';' )
495                                         words[i][strlen(words[i])-1] = '\0';
496                                 buffer_add( buffer, words[i] );
497                                 buffer_add(buffer, " ");
498                         }
499                         buffer_add(buffer, "]");
500                 }
501
502                 return send_request( server, method, buffer, relay );
503         } 
504
505         return 0;
506 }
507
508 int send_request( char* server, 
509                 char* method, growing_buffer* buffer, int relay ) {
510         if( server == NULL || method == NULL )
511                 return 0;
512
513         jsonObject* params = NULL;
514         if( !relay ) {
515                 if( buffer != NULL && buffer->n_used > 0 ) 
516                         params = json_parse_string(buffer->buf);
517         } else {
518                 if(!last_result || ! last_result->_result_content) { 
519                         printf("We're not going to call 'relay' with no result params\n");
520                         return 1;
521                 }
522                 else {
523                         jsonObject* o = jsonNewObject(NULL);
524                         jsonObjectPush(o, last_result->_result_content );
525                         params = o;
526                 }
527         }
528
529
530         if(buffer->n_used > 0 && params == NULL) {
531                 fprintf(stderr, "JSON error detected, not executing\n");
532                 return 1;
533         }
534
535         osrf_app_session* session = osrf_app_client_session_init(server);
536
537         if(!osrf_app_session_connect(session)) {
538                 osrfLogWarning( OSRF_LOG_MARK,  "Unable to connect to remote service %s\n", server );
539                 return 1;
540         }
541
542         double start = get_timestamp_millis();
543         //int req_id = osrf_app_session_make_request( session, params, method, 1, NULL );
544         int req_id = osrf_app_session_make_req( session, params, method, 1, NULL );
545
546
547         osrf_message* omsg = osrf_app_session_request_recv( session, req_id, recv_timeout );
548
549         if(!omsg) 
550                 printf("\nReceived no data from server\n");
551         
552         
553         signal(SIGPIPE, SIG_IGN);
554
555         FILE* less; 
556         if(!is_from_script) less = popen( "less -EX", "w");
557         else less = stdout;
558
559         if( less == NULL ) { less = stdout; }
560
561         growing_buffer* resp_buffer = buffer_init(4096);
562
563         while(omsg) {
564
565                 if(raw_print) {
566
567                         if(omsg->_result_content) {
568         
569                                 osrf_message_free(last_result);
570                                 last_result = omsg;
571         
572                                 char* content;
573         
574                                 if( pretty_print && omsg->_result_content ) {
575                                         char* j = jsonObjectToJSON(omsg->_result_content);
576                                         //content = json_printer(j); 
577                                         content = jsonFormatString(j);
578                                         free(j);
579                                 } else
580                                         content = jsonObjectGetString(omsg->_result_content);
581         
582                                 printf( "\nReceived Data: %s\n", content ); 
583                                 free(content);
584         
585                         } else {
586
587                                 char code[16];
588                                 memset(code, 0, 16);
589                                 sprintf( code, "%d", omsg->status_code );
590                                 buffer_add( resp_buffer, code );
591
592                                 printf( "\nReceived Exception:\nName: %s\nStatus: %s\nStatus: %s\n", 
593                                                 omsg->status_name, omsg->status_text, code );
594
595                                 fflush(stdout);
596                         }
597
598                 } else {
599
600                         if(omsg->_result_content) {
601         
602                                 osrf_message_free(last_result);
603                                 last_result = omsg;
604         
605                                 char* content;
606         
607                                 if( pretty_print && omsg->_result_content ) {
608                                         char* j = jsonObjectToJSON(omsg->_result_content);
609                                         //content = json_printer(j); 
610                                         content = jsonFormatString(j);
611                                         free(j);
612                                 } else
613                                         content = jsonObjectGetString(omsg->_result_content);
614         
615                                 buffer_add( resp_buffer, "\nReceived Data: " ); 
616                                 buffer_add( resp_buffer, content );
617                                 buffer_add( resp_buffer, "\n" );
618                                 free(content);
619         
620                         } else {
621         
622                                 buffer_add( resp_buffer, "\nReceived Exception:\nName: " );
623                                 buffer_add( resp_buffer, omsg->status_name );
624                                 buffer_add( resp_buffer, "\nStatus: " );
625                                 buffer_add( resp_buffer, omsg->status_text );
626                                 buffer_add( resp_buffer, "\nStatus: " );
627                                 char code[16];
628                                 memset(code, 0, 16);
629                                 sprintf( code, "%d", omsg->status_code );
630                                 buffer_add( resp_buffer, code );
631                         }
632                 }
633
634
635                 omsg = osrf_app_session_request_recv( session, req_id, recv_timeout );
636
637         }
638
639         double end = get_timestamp_millis();
640
641         fprintf( less, resp_buffer->buf );
642         buffer_free( resp_buffer );
643         fprintf( less, "\n------------------------------------\n");
644         if( osrf_app_session_request_complete( session, req_id ))
645                 fprintf(less, "Request Completed Successfully\n");
646
647
648         fprintf(less, "Request Time in seconds: %.6f\n", end - start );
649         fprintf(less, "------------------------------------\n");
650
651         pclose(less); 
652
653         osrf_app_session_request_finish( session, req_id );
654         osrf_app_session_disconnect( session );
655         osrf_app_session_destroy( session );
656
657
658         return 1;
659
660
661 }
662
663 /*
664 static int handle_time( char* words[] ) {
665
666         if( ! words[1] ) {
667
668                 char buf[36];
669                 memset(buf,0,36);
670                 get_timestamp(buf);
671                 printf( "%s\n", buf );
672                 return 1;
673         }
674
675         if( words[1] ) {
676                 time_t epoch = (time_t)atoi( words[1] );
677                 char* localtime = strdup( ctime( &epoch ) );
678                 printf( "%s => %s", words[1], localtime );
679                 free(localtime);
680                 return 1;
681         }
682
683         return 0;
684
685 }
686 */
687
688                 
689
690 static int router_query_servers( const char* router_server ) {
691
692         if( ! router_server || strlen(router_server) == 0 ) 
693                 return 0;
694
695         char rbuf[256];
696         memset(rbuf,0,256);
697         sprintf(rbuf,"router@%s/router", router_server );
698                 
699         transport_message* send = 
700                 message_init( "servers", NULL, NULL, rbuf, NULL );
701         message_set_router_info( send, NULL, NULL, NULL, "query", 0 );
702
703         client_send_message( client, send );
704         message_free( send );
705
706         transport_message* recv = client_recv( client, -1 );
707         if( recv == NULL ) {
708                 fprintf(stderr, "NULL message received from router\n");
709                 return 1;
710         }
711         
712         printf( 
713                         "---------------------------------------------------------------------------------\n"
714                         "Received from 'server' query on %s\n"
715                         "---------------------------------------------------------------------------------\n"
716                         "original reg time | latest reg time | last used time | class | server\n"
717                         "---------------------------------------------------------------------------------\n"
718                         "%s"
719                         "---------------------------------------------------------------------------------\n"
720                         , router_server, recv->body );
721
722         message_free( recv );
723         
724         return 1;
725 }
726
727 static int print_help( void ) {
728
729         printf(
730                         "---------------------------------------------------------------------------------\n"
731                         "Commands:\n"
732                         "---------------------------------------------------------------------------------\n"
733                         "help                   - Display this message\n"
734                         "!<command> [args] - Forks and runs the given command in the shell\n"
735                 /*
736                         "time                   - Prints the current time\n"
737                         "time <timestamp>       - Formats seconds since epoch into readable format\n"   
738                 */
739                         "set <variable> <value> - set a srfsh variable (e.g. set pretty_print true )\n"
740                         "print <variable>               - Displays the value of a srfsh variable\n"
741                         "---------------------------------------------------------------------------------\n"
742
743                         "router query servers <server1 [, server2, ...]>\n"
744                         "       - Returns stats on connected services\n"
745                         "\n"
746                         "\n"
747                         "request <service> <method> [ <json formatted string of params> ]\n"
748                         "       - Anything passed in will be wrapped in a json array,\n"
749                         "               so add commas if there is more than one param\n"
750                         "\n"
751                         "\n"
752                         "relay <service> <method>\n"
753                         "       - Performs the requested query using the last received result as the param\n"
754                         "\n"
755                         "\n"
756                         "math_bench <num_batches> [0|1|2]\n"
757                         "       - 0 means don't reconnect, 1 means reconnect after each batch of 4, and\n"
758                         "                2 means reconnect after every request\n"
759                         "\n"
760                         "introspect <service>\n"
761                         "       - prints the API for the service\n"
762                         "\n"
763                         "\n"
764                         "---------------------------------------------------------------------------------\n"
765                         " Commands for Open-ILS\n"
766                         "---------------------------------------------------------------------------------\n"
767                         "login <username> <password>\n"
768                         "       -       Logs into the 'server' and displays the session id\n"
769                         "       - To view the session id later, enter: print login\n"
770                         "---------------------------------------------------------------------------------\n"
771                         "\n"
772                         "\n"
773                         "Note: long output is piped through 'less'.  To search in 'less', type: /<search>\n"
774                         "---------------------------------------------------------------------------------\n"
775                         "\n"
776                         );
777
778         return 1;
779 }
780
781
782 /*
783 static char* tabs(int count) {
784         growing_buffer* buf = buffer_init(24);
785         int i;
786         for(i=0;i!=count;i++)
787                 buffer_add(buf, "  ");
788
789         char* final = buffer_data( buf );
790         buffer_free( buf );
791         return final;
792 }
793 */
794
795
796 static int handle_math( char* words[] ) {
797         if( words[1] )
798                 return do_math( atoi(words[1]), 0 );
799         return 0;
800 }
801
802
803 static int do_math( int count, int style ) {
804
805         osrf_app_session* session = osrf_app_client_session_init(  "opensrf.math" );
806         osrf_app_session_connect(session);
807
808         jsonObject* params = json_parse_string("[]");
809         jsonObjectPush(params,jsonNewObject("1"));
810         jsonObjectPush(params,jsonNewObject("2"));
811
812         char* methods[] = { "add", "sub", "mult", "div" };
813         char* answers[] = { "3", "-1", "2", "0.500000" };
814
815         float times[ count * 4 ];
816         memset(times,0,count*4);
817
818         int k;
819         for(k=0;k!=100;k++) {
820                 if(!(k%10)) 
821                         fprintf(stderr,"|");
822                 else
823                         fprintf(stderr,".");
824         }
825
826         fprintf(stderr,"\n\n");
827
828         int running = 0;
829         int i;
830         for(i=0; i!= count; i++) {
831
832                 int j;
833                 for(j=0; j != 4; j++) {
834
835                         ++running;
836
837                         double start = get_timestamp_millis();
838                         int req_id = osrf_app_session_make_req( session, params, methods[j], 1, NULL );
839                         osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 5 );
840                         double end = get_timestamp_millis();
841
842                         times[(4*i) + j] = end - start;
843
844                         if(omsg) {
845         
846                                 if(omsg->_result_content) {
847                                         char* jsn = jsonObjectToJSON(omsg->_result_content);
848                                         if(!strcmp(jsn, answers[j]))
849                                                 fprintf(stderr, "+");
850                                         else
851                                                 fprintf(stderr, "\n![%s] - should be %s\n", jsn, answers[j] );
852                                         free(jsn);
853                                 }
854
855
856                                 osrf_message_free(omsg);
857                 
858                         } else { fprintf( stderr, "\nempty message for tt: %d\n", req_id ); }
859
860                         osrf_app_session_request_finish( session, req_id );
861
862                         if(style == 2)
863                                 osrf_app_session_disconnect( session );
864
865                         if(!(running%100))
866                                 fprintf(stderr,"\n");
867                 }
868
869                 if(style==1)
870                         osrf_app_session_disconnect( session );
871         }
872
873         osrf_app_session_destroy( session );
874         jsonObjectFree(params);
875
876         int c;
877         float total = 0;
878         for(c=0; c!= count*4; c++) 
879                 total += times[c];
880
881         float avg = total / (count*4); 
882         fprintf(stderr, "\n      Average round trip time: %f\n", avg );
883
884         return 1;
885 }