]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/srfsh/srfsh.c
if no config file is specified on the command line, we check $HOME/.srfsh.xml
[OpenSRF.git] / src / srfsh / srfsh.c
1 #include "opensrf/transport_client.h"
2 #include "opensrf/generic_utils.h"
3 #include "opensrf/osrf_message.h"
4 #include "opensrf/osrf_app_session.h"
5 #include <time.h>
6
7 #include <stdio.h>
8 #include <readline/readline.h>
9 #include <readline/history.h>
10
11
12 #define SRFSH_PORT 5222
13 #define COMMAND_BUFSIZE 12
14
15
16 char* prompt = "srfsh# ";
17 char* last_request;
18 transport_client* client = NULL;
19
20 int parse_request( char* request );
21 int handle_router( char* words[] );
22 int handle_time( char* words[] );
23 int handle_request( char* words[] );
24 int send_request( char* server, char* method, growing_buffer* buffer );
25 int parse_error( char* words[] );
26 int router_query_servers( char* server );
27 int srfsh_client_connect();
28 int print_help();
29 char* json_printer( json* object );
30 char* tabs(int count);
31
32 int main( int argc, char* argv[] ) {
33
34         if( argc < 2 ) {
35
36                 /* see if they have a .srfsh.xml in their home directory */
37                 char* home = getenv("HOME");
38                 int l = strlen(home) + 36;
39                 char fbuf[l];
40                 memset(fbuf, 0, l);
41                 sprintf(fbuf,"%s/.srfsh.xml",home);
42                 if(!access(fbuf, F_OK))
43                         config_reader_init( "opensrf", fbuf );  
44                 else
45                         fatal_handler( "No Config file found at %s and none specified. "
46                                         "\nusage: %s <config_file>", fbuf, argv[0] );
47         } else {
48                 config_reader_init( "opensrf", argv[1] );       
49         }
50
51         if( ! osrf_system_bootstrap_client("srfsh.xml") ) 
52                 fprintf( stderr, "Unable to bootstrap client for requests\n");
53
54         client = osrf_system_get_transport_client();
55
56         char* request;
57         while((request=readline(prompt))) {
58
59                 if( !strcmp(request, "exit") || !strcmp(request,"quit")) 
60                         break; 
61
62                 char* req_copy = strdup(request);
63
64                 if(parse_request( req_copy ) ) 
65                         add_history(request);
66
67                 free(request);
68                 free(req_copy);
69         }
70
71         free(request);
72         client_disconnect( client );
73         client_free( client );  
74         config_reader_free();   
75         log_free();
76                 
77         return 0;
78 }
79
80
81 int parse_error( char* words[] ) {
82
83         if( ! words )
84                 return 0;
85
86         int i = 0;
87         char* current;
88         char buffer[256];
89         memset(buffer, 0, 256);
90         while( (current=words[i++]) ) {
91                 strcat(buffer, current);
92                 strcat(buffer, " ");
93         }
94         if( ! buffer || strlen(buffer) < 1 ) 
95                 printf("\n");
96
97         fprintf( stderr, "Command Incomplete or Not Recognized: %s\n", buffer );
98         return 0;
99
100 }
101
102
103 int parse_request( char* request ) {
104
105         if( request == NULL )
106                 return 0;
107
108         int ret_val = 0;
109         int i = 0;
110         char* words[COMMAND_BUFSIZE]; 
111         memset(words,0,COMMAND_BUFSIZE);
112         //char* req = strdup(request);
113         char* req = request;
114
115         char* cur_tok = strtok( req, " " );
116
117         if( cur_tok == NULL )
118                 return 0;
119
120         while(cur_tok != NULL) {
121                 words[i++] = cur_tok;
122                 cur_tok = strtok( NULL, " " );
123         }
124
125         //free(req);
126
127         // not sure why (strtok?), but this is necessary
128         memset( words + i, 0, COMMAND_BUFSIZE - i );
129
130         /* pass off to the top level command */
131         if( !strcmp(words[0],"router") ) 
132                 ret_val = handle_router( words );
133
134         else if( !strcmp(words[0],"time") ) 
135                 ret_val = handle_time( words );
136
137         else if (!strcmp(words[0],"request"))
138                 ret_val = handle_request( words );
139
140         else if (!strcmp(words[0],"help"))
141                 return print_help();
142
143         if(!ret_val)
144                 return parse_error( words );
145
146         return 1;
147
148 }
149
150
151 int handle_router( char* words[] ) {
152
153         if(!client)
154                 return 1;
155
156         int i;
157
158         if( words[1] ) { 
159                 if( !strcmp(words[1],"query") ) {
160                         
161                         if( words[2] && !strcmp(words[2],"servers") ) {
162                                 for(i=3; i < COMMAND_BUFSIZE - 3 && words[i]; i++ ) {   
163                                         router_query_servers( words[i] );
164                                 }
165                                 return 1;
166                         }
167                         return 0;
168                 }
169                 return 0;
170         }
171         return 0;
172 }
173
174 int handle_request( char* words[] ) {
175
176         if(!client)
177                 return 1;
178
179         if(words[1]) {
180                 char* server = words[1];
181                 char* method = words[2];
182                 int i;
183                 growing_buffer* buffer = buffer_init(128);
184
185                 buffer_add(buffer, "[");
186                 for(i = 3; words[i] != NULL; i++ ) {
187                         buffer_add( buffer, words[i] );
188                         buffer_add(buffer, " ");
189                 }
190                 buffer_add(buffer, "]");
191
192                 return send_request( server, method, buffer );
193         } 
194
195         return 0;
196 }
197
198 int send_request( char* server, char* method, growing_buffer* buffer ) {
199         if( server == NULL || method == NULL )
200                 return 0;
201
202         json* params = NULL;
203         if( buffer != NULL && buffer->n_used > 0 ) 
204                 params = json_tokener_parse(buffer->buf);
205
206         osrf_app_session* session = osrf_app_client_session_init(server);
207         double start = get_timestamp_millis();
208
209         if(!osrf_app_session_connect(session)) {
210                 warning_handler( "Unable to connect to remote service %s\n", server );
211                 return 1;
212         }
213
214         int req_id = osrf_app_session_make_request( session, params, method, 1 );
215
216         osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 8 );
217
218         if(!omsg) 
219                 printf("\nReceived no data from server\n");
220         
221         
222         while(omsg) {
223                 if(omsg->result_content) {
224                         char* content = json_printer( omsg->result_content );
225                         printf( "\nReceived Data: %s\n",content );
226                         free(content);
227                 }
228                 else
229                         printf( "\nReceived Message but no result data\n");
230
231                 osrf_message_free(omsg);
232                 omsg = osrf_app_session_request_recv( session, req_id, 5 );
233         }
234
235         double end = get_timestamp_millis();
236
237         printf("\n------------------------------------\n");
238         if( osrf_app_session_request_complete( session, req_id ))
239                 printf("Request Completed Successfully\n");
240
241
242         printf("Request Time in seconds: %f\n", end - start );
243         printf("------------------------------------\n");
244
245         osrf_app_session_request_finish( session, req_id );
246         osrf_app_session_disconnect( session );
247         osrf_app_session_destroy( session );
248
249         return 1;
250
251
252 }
253
254 int handle_time( char* words[] ) {
255
256         if( ! words[1] ) {
257
258                 char buf[36];
259                 memset(buf,0,36);
260                 get_timestamp(buf);
261                 printf( "%s\n", buf );
262                 return 1;
263         }
264
265         if( words[1] ) {
266                 time_t epoch = (time_t)atoi( words[1] );
267                 char* localtime = strdup( ctime( &epoch ) );
268                 printf( "%s => %s", words[1], localtime );
269                 free(localtime);
270                 return 1;
271         }
272
273         return 0;
274
275 }
276
277                 
278
279 int router_query_servers( char* router_server ) {
280
281         if( ! router_server || strlen(router_server) == 0 ) 
282                 return 0;
283
284         char rbuf[256];
285         memset(rbuf,0,256);
286         sprintf(rbuf,"router@%s/router", router_server );
287                 
288         transport_message* send = 
289                 message_init( "servers", NULL, NULL, rbuf, NULL );
290         message_set_router_info( send, NULL, NULL, NULL, "query", 0 );
291
292         client_send_message( client, send );
293         message_free( send );
294
295         transport_message* recv = client_recv( client, -1 );
296         if( recv == NULL )
297                 fprintf(stderr, "NULL message received from router\n");
298         
299         printf( 
300                         "---------------------------------------------------------------------------------\n"
301                         "Received from 'server' query on %s\n"
302                         "---------------------------------------------------------------------------------\n"
303                         "original reg time | latest reg time | last used time | class | server\n"
304                         "---------------------------------------------------------------------------------\n"
305                         "%s"
306                         "---------------------------------------------------------------------------------\n"
307                         , router_server, recv->body );
308
309         message_free( recv );
310         
311         return 1;
312 }
313                 
314 int print_help() {
315
316         printf(
317                         "---------------------------------------------------------------------------------\n"
318                         "Commands:\n"
319                         "---------------------------------------------------------------------------------\n"
320                         "help                   - Display this message\n"
321                         "last                   - Re-performs the last command\n"
322                         "time                   - Prints the current time\n"                                    
323                         "time <timestamp>       - Formats seconds since epoch into readable format\n"   
324                         "---------------------------------------------------------------------------------\n"
325                         "router query servers <server1 [, server2, ...]>\n"
326                         "       - Returns stats on connected services\n"
327                         "\n"
328                         "reqeust <service> <method> [ <json formatted string of params> ]\n"
329                         "       - Anything passed in will be wrapped in a json array,\n"
330                         "               so add commas if there is more than one param\n"
331                         "---------------------------------------------------------------------------------\n"
332                         );
333
334         return 1;
335 }
336
337
338
339 char* tabs(int count) {
340         growing_buffer* buf = buffer_init(24);
341         int i;
342         for(i=0;i!=count;i++)
343                 buffer_add(buf, "   ");
344
345         char* final = buffer_data( buf );
346         buffer_free( buf );
347         return final;
348 }
349
350 char* json_printer( json* object ) {
351
352         if(object == NULL)
353                 return NULL;
354         char* string = json_object_to_json_string(object);
355
356         growing_buffer* buf = buffer_init(64);
357         int i;
358         int tab_var = 0;
359         for(i=0; i!= strlen(string); i++) {
360
361                 if( string[i] == '{' ) {
362
363                         buffer_add(buf, "\n");
364                         char* tab = tabs(tab_var);
365                         buffer_add(buf, tab);
366                         free(tab);
367                         buffer_add( buf, "{");
368                         tab_var++;
369                         buffer_add( buf, "\n" );        
370                         tab = tabs(tab_var);
371                         buffer_add( buf, tab ); 
372                         free(tab);
373
374                 } else if( string[i] == '[' ) {
375
376                         buffer_add(buf, "\n");
377                         char* tab = tabs(tab_var);
378                         buffer_add(buf, tab);
379                         free(tab);
380                         buffer_add( buf, "[");
381                         tab_var++;
382                         buffer_add( buf, "\n" );        
383                         tab = tabs(tab_var);
384                         buffer_add( buf, tab ); 
385                         free(tab);
386
387                 } else if( string[i] == '}' ) {
388
389                         tab_var--;
390                         buffer_add(buf, "\n");
391                         char* tab = tabs(tab_var);
392                         buffer_add(buf, tab);
393                         free(tab);
394                         buffer_add( buf, "}");
395                         buffer_add( buf, "\n" );        
396                         tab = tabs(tab_var);
397                         buffer_add( buf, tab ); 
398                         free(tab);
399
400                 } else if( string[i] == ']' ) {
401
402                         tab_var--;
403                         buffer_add(buf, "\n");
404                         char* tab = tabs(tab_var);
405                         buffer_add(buf, tab);
406                         free(tab);
407                         buffer_add( buf, "]");
408                         buffer_add( buf, "\n" );        
409                         tab = tabs(tab_var);
410                         buffer_add( buf, tab ); 
411                         free(tab);
412
413                 } else {
414                         char b[2];
415                         b[0] = string[i];
416                         b[1] = '\0';
417                         buffer_add( buf, b ); 
418                 }
419
420         }
421
422         char* result = buffer_data(buf);
423         buffer_free(buf);
424         return result;
425
426 }