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