added 'named' configs.
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 1 Mar 2005 21:16:15 +0000 (21:16 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 1 Mar 2005 21:16:15 +0000 (21:16 +0000)
log file and log levels are set by functions and not by direct config file reading.
added request framework to srfsh so we can make requests of any servers

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@134 9efc2488-bf62-4759-914b-345cdb29e865

12 files changed:
include/opensrf/generic_utils.h
include/opensrf/osrf_app_session.h
include/opensrf/osrf_system.h
src/libstack/Makefile
src/libstack/osrf_app_session.c
src/libstack/osrf_system.c
src/libtransport/generic_utils.c
src/router/Makefile
src/router/router.c
src/router/router.h
src/srfsh/Makefile
src/srfsh/srfsh.c

index f6e39ba..5144328 100644 (file)
 #ifndef GENERIC_UTILS_H
 #define GENERIC_UTILS_H
 
+#define LOG_ERROR 1
+#define LOG_WARNING 2
+#define LOG_INFO 3
+#define LOG_DEBUG 4
+
+
 #define equals(a,b) !strcmp(a,b) 
 
 /** Malloc's, checks for NULL, clears all memory bits and 
@@ -46,7 +52,7 @@ int buffer_free( growing_buffer* gb );
 void log_free(); 
 
 // Utility method
-void get_timestamp( char buf_25chars[]);
+void get_timestamp( char buf_36chars[]);
 
 // ---------------------------------------------------------------------------------
 // Error handling interface.
@@ -57,21 +63,31 @@ void warning_handler( char* message, ... );
 void info_handler( char* message, ... );
 void debug_handler( char* message, ... );
 
+/** If we return 0 either the log level is less than LOG_ERROR  
+  * or we could not open the log file
+  */
+int log_init( int log_level, char* log_file );
+
 // ---------------------------------------------------------------------------------
 // Config file module
 // ---------------------------------------------------------------------------------
 struct config_reader_struct {
        xmlDocPtr config_doc;
        xmlXPathContextPtr xpathCx;
+       char* name;
+       struct config_reader_struct* next;
 };
 typedef struct config_reader_struct config_reader;
 config_reader* conf_reader;
 
-void config_reader_init( char* config_file );
+//void config_reader_init( char* config_file );
+void config_reader_init( char* name, char* config_file );
 
 void config_reader_free();
 
 // allocastes a char*. FREE me.
-char* config_value( const char* xpath_query, ... );
+//char* config_value( const char* xpath_query, ... );
+char* config_value( const char* config_name, const char* xp_query, ... );
+//char* config_value( config_reader* reader, const char* xp_query, ... );
 
 #endif
index fe4d824..02cc2ab 100644 (file)
@@ -92,7 +92,7 @@ int osrf_app_session_make_request(
 void osrf_app_session_set_complete( osrf_app_session* session, int request_id );
 
 /** Returns true if the given request is complete */
-int osrf_app_session_complete( osrf_app_session* session, int request_id );
+int osrf_app_session_request_complete( osrf_app_session* session, int request_id );
 
 /** Does a recv call on the given request */
 osrf_message* osrf_app_session_request_recv( 
index 7023395..9a933b7 100644 (file)
@@ -5,20 +5,7 @@
 
 /** Connects to jabber.  Returns 1 on success, 0 on failure */
 int osrf_system_bootstrap_client(); 
-
-/** Useful for managing multiple connections.  Any clients added should
-  * live through the duration of the process so there are no cleanup procedures
-  * as of yet 
-  */
-struct transport_client_cache_struct {
-       transport_client* client;
-       char* service;
-       struct transport_client_cache_struct* next;
-};
-typedef struct transport_client_cache_struct transport_client_cache;
-
-void osrf_system_push_transport_client( transport_client* client, char* service );
-transport_client* osrf_system_get_transport_client( char* service );
+transport_client* osrf_system_get_transport_client();
 
 
 #endif
index 92970a0..93b6af0 100644 (file)
@@ -8,8 +8,8 @@ CC = gcc
 all: lib 
 #client sys_client
 
-#sys_client: sys_client.c lib 
-#      $(CC) $(CC_OPTS) $(EXE_LD_OPTS) *.o sys_client.c -o sys_client
+sys_client: sys_client.c lib 
+       $(CC) $(CC_OPTS) $(EXE_LD_OPTS) *.o sys_client.c -o sys_client
 
 #client: client.c lib 
 #      $(CC) $(CC_OPTS) $(EXE_LD_OPTS) *.o client.c -o client
index 956aac7..59b9015 100644 (file)
@@ -87,6 +87,21 @@ osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout ) {
        while( remaining >= 0 ) {
                /* tell the session to wait for stuff */
                debug_handler( "In app_request receive with remaining time [%d]", (int) remaining );
+
+               osrf_app_session_queue_wait( req->session, 0 );
+
+               if( req->result != NULL ) { /* if we received anything */
+                       /* pop off the first message in the list */
+                       debug_handler( "app_request_recv received a message, returning it");
+                       osrf_message* ret_msg = req->result;
+                       osrf_message* tmp_msg = ret_msg->next;
+                       req->result = tmp_msg;
+                       return ret_msg;
+               }
+
+               if( req->complete )
+                       return NULL;
+
                osrf_app_session_queue_wait( req->session, (int) remaining );
 
                if( req->result != NULL ) { /* if we received anything */
@@ -193,13 +208,22 @@ void _osrf_app_session_remove_session( char* session_id ) {
 osrf_app_session* osrf_app_client_session_init( char* remote_service ) {
        osrf_app_session* session = safe_malloc(sizeof(osrf_app_session));      
 
-       session->transport_handle = osrf_system_get_transport_client( "client" );
+       session->transport_handle = osrf_system_get_transport_client();
        if( session->transport_handle == NULL ) {
                warning_handler("No transport client for service 'client'");
                return NULL;
        }
+
+       char target_buf[512];
+       memset(target_buf,0,512);
+       char* domain    = config_value( "opensrf.bootstrap", "//bootstrap/domains/domain1" ); /* just the first for now */
+       char* router_name = config_value( "opensrf.bootstrap", "//bootstrap/router_name" );
+       sprintf( target_buf, "%s@%s/%s",  router_name, domain, remote_service );
+       free(domain);
+       free(router_name);
+
        session->request_queue = NULL;
-       session->remote_id = strdup("router@judy/math");  /*XXX config value */
+       session->remote_id = strdup(target_buf);
        session->orig_remote_id = strdup(session->remote_id);
 
        /* build a chunky, random session id */
@@ -229,7 +253,7 @@ osrf_app_session* osrf_app_server_session_init(
 
        session = safe_malloc(sizeof(osrf_app_session));        
 
-       session->transport_handle = osrf_system_get_transport_client( our_app  );
+       session->transport_handle = osrf_system_get_transport_client();
        if( session->transport_handle == NULL ) {
                warning_handler("No transport client for service '%s'", our_app );
                return NULL;
index 8a43804..6058b5e 100644 (file)
@@ -1,51 +1,56 @@
 #include "opensrf/osrf_system.h"
 
+transport_client* global_client;
+
+transport_client* osrf_system_get_transport_client() {
+       return global_client;
+}
+
+int osrf_system_bootstrap_client( char* config_file ) {
+       if( config_file == NULL )
+               fatal_handler("No Config File Specified\n" );
+
+       config_reader_init( "opensrf.bootstrap", config_file ); 
+       char* log_file          = config_value( "opensrf.bootstrap", "//logs/client" );
+       char* log_level = config_value( "opensrf.bootstrap", "//bootstrap/debug" );
+       char* domain            = config_value( "opensrf.bootstrap", "//bootstrap/domains/domain1" ); /* just the first for now */
+       char* username          = config_value( "opensrf.bootstrap", "//bootstrap/username" );
+       char* password          = config_value( "opensrf.bootstrap", "//bootstrap/passwd" );
+       char* port                      = config_value( "opensrf.bootstrap", "//bootstrap/port" );
+       int llevel = 0;
+       int iport = atoi(port);
+
+       if                      (!strcmp(log_level, "ERROR"))   llevel = LOG_ERROR;
+       else if (!strcmp(log_level, "WARN"))    llevel = LOG_WARNING;
+       else if (!strcmp(log_level, "INFO"))    llevel = LOG_INFO;
+       else if (!strcmp(log_level, "DEBUG"))   llevel = LOG_DEBUG;
+
+       log_init( llevel, log_file );
 
-int osrf_system_bootstrap_client() {
        // XXX config values 
-       transport_client* client = client_init( "judy", 5222, 0 );
+       transport_client* client = client_init( domain, iport, 0 );
        char buf[256];
        memset(buf,0,256);
        char* host = getenv("HOSTNAME");
        sprintf(buf, "client_%s_%d", host, getpid() );
 
-       if(client_connect( client, "who","hello_you", buf, 10, AUTH_DIGEST )) {
-               /* push ourselves into the client cache */
-               osrf_system_push_transport_client( client, "client" );
-               return 1;
+       if(client_connect( client, username, password, buf, 10, AUTH_DIGEST )) {
+               global_client = client;
        }
 
+       free(log_level);
+       free(log_file);
+       free(domain);
+       free(username);
+       free(password);
+       free(port);
+
+       if(global_client)
+               return 1;
+
        return 0;
 }
 
-// -----------------------------------------------------------------------------
-// Some client caching utility methods
-transport_client_cache* client_cache;
-
-void osrf_system_push_transport_client( transport_client* client, char* service ) {
-       if(client == NULL || service == NULL) return;
-       transport_client_cache* new = (transport_client_cache*) safe_malloc(sizeof(transport_client_cache));
-       new->service = strdup(service);
-       new->client = client;
-       if(client_cache == NULL) 
-               client_cache = new;
-       else {
-               transport_client_cache* tmp = client_cache->next;
-               client_cache = new;
-               new->next = tmp;
-       }
-}
 
-transport_client* osrf_system_get_transport_client( char* service ) {
-       if(service == NULL) return NULL;
-       transport_client_cache* cur = client_cache;
-       while(cur != NULL) {
-               if( !strcmp(cur->service, service)) 
-                       return cur->client;
-               cur = cur->next;
-       }
-       return NULL;
-}
-// -----------------------------------------------------------------------------
 
 
index cf67189..f83e19a 100644 (file)
@@ -3,20 +3,10 @@
 #include "pthread.h"
 #include <sys/timeb.h>
 
-int _init_log();
-
-int balance = 0;
-
-#define LOG_ERROR 1
-#define LOG_WARNING 2
-#define LOG_INFO 3
-#define LOG_DEBUG 4
-
 void get_timestamp( char buf_36chars[]) {
 
        struct timeb tb;
        ftime(&tb);
-       //time_t epoch = time(NULL);    
        char* localtime = strdup( ctime( &(tb.time) ) );
        char mil[4];
        memset(mil,0,4);
@@ -43,6 +33,7 @@ inline void* safe_malloc( int size ) {
 
 static FILE* log_file = NULL;
 static int log_level = -1;
+static int logging = 0;
 pthread_mutex_t mutex;
 
 void log_free() { if( log_file != NULL ) fclose(log_file ); }
@@ -55,7 +46,7 @@ void fatal_handler( char* msg, ... ) {
        pid_t  pid = getpid();
        va_list args;
 
-       if( _init_log() ) {
+       if( logging ) {
 
                if( log_level < LOG_ERROR )
                        return;
@@ -91,7 +82,7 @@ void warning_handler( char* msg, ... ) {
        pid_t  pid = getpid();
        va_list args;
        
-       if( _init_log() ) {
+       if(logging) {
 
                if( log_level < LOG_WARNING )
                        return;
@@ -126,7 +117,7 @@ void info_handler( char* msg, ... ) {
        pid_t  pid = getpid();
        va_list args;
 
-       if( _init_log() ) {
+       if(logging) {
 
                if( log_level < LOG_INFO )
                        return;
@@ -162,7 +153,7 @@ void debug_handler( char* msg, ... ) {
        pid_t  pid = getpid();
        va_list args;
        
-       if( _init_log() ) {
+       if(logging) {
 
                if( log_level < LOG_DEBUG )
                        return;
@@ -190,48 +181,24 @@ void debug_handler( char* msg, ... ) {
 }
 
 
+int log_init( int llevel, char* lfile ) {
 
-int _init_log() {
-
-       if( log_level != -1 )
-               return 1;
-
-
-       pthread_mutex_init( &(mutex), NULL );
-
-       /* load the log level setting if we haven't already */
-
-       if( conf_reader == NULL ) {
-               return 0;
-               //fprintf( stderr, "No config file specified" );
-       }
-
-       char* log_level_str = config_value( "//log/level");
-       if( log_level_str == NULL ) {
-       //      fprintf( stderr, "No log level specified" );
-               return 0;
-       }
-       log_level = atoi(log_level_str);
-       free(log_level_str);
 
-       /* see if we have a log file yet */
-       char* f = config_value("//log/file");
-
-       if( f == NULL ) {
-               // fprintf( stderr, "No log file specified" );
+       if( llevel < 1 ) {
+               logging = 0;
                return 0;
        }
 
-       log_file = fopen( f, "a" );
+       log_level = llevel;
+       log_file = fopen( lfile, "a" );
        if( log_file == NULL ) {
-               fprintf( stderr, "Unable to open log file %s for appending\n", f );
+               fprintf( stderr, "Unable to open log file %s for appending\n", lfile );
                return 0;
        }
-       free(f);
+       logging = 1;
        return 1;
-                               
-}
 
+}
 
 
 // ---------------------------------------------------------------------------------
@@ -320,6 +287,7 @@ char* buffer_data( growing_buffer *gb) {
 // Allocate and build the conf_reader.  This only has to happen once in a given
 // system.  Repeated calls are ignored.
 // ---------------------------------------------------------------------------------
+/*
 void config_reader_init( char* config_file ) {
        if( conf_reader == NULL ) {
 
@@ -339,14 +307,57 @@ void config_reader_init( char* config_file ) {
                }
        }
 }
+*/
+
+void config_reader_init( char* name, char* config_file ) {
+
+       if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) {
+               fatal_handler( "config_reader_init(): No config file specified" );
+               return;
+       }
+
+       config_reader* reader = 
+               (config_reader*) safe_malloc(sizeof(config_reader));
+
+       reader->config_doc = xmlParseFile( config_file ); 
+       reader->xpathCx = xmlXPathNewContext( reader->config_doc );
+       reader->name = strdup(name);
+       reader->next = NULL;
+
+       if( reader->xpathCx == NULL ) {
+               fprintf( stderr, "config_reader_init(): Unable to create xpath context\n");
+               return;
+       }
+
+       if( conf_reader == NULL ) {
+               conf_reader = reader;
+       } else {
+               config_reader* tmp = conf_reader;
+               conf_reader = reader;
+               reader->next = tmp;
+       }
+}
+
 
-char* config_value( const char* xp_query, ... ) {
+char* config_value( const char* config_name, const char* xp_query, ... ) {
 
        if( conf_reader == NULL || xp_query == NULL ) {
                fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" );
                return NULL;
        }
 
+       config_reader* reader = conf_reader;
+       while( reader != NULL ) {
+               if( !strcmp(reader->name, config_name)) 
+                       break;
+               reader = reader->next;
+       }
+
+       if( reader == NULL ) {
+               fprintf(stderr, "No Config file with name %s\n", config_name );
+               return NULL;
+       }
+
        int slen = strlen(xp_query) + 512;/* this is unsafe ... */
        char xpath_query[ slen ]; 
        memset( xpath_query, 0, slen );
@@ -362,7 +373,7 @@ char* config_value( const char* xp_query, ... ) {
        memset( alert_buffer, 0, len );
 
        // build the xpath object
-       xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, conf_reader->xpathCx );
+       xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx );
 
        if( xpathObj == NULL ) {
                sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
@@ -430,9 +441,12 @@ char* config_value( const char* xp_query, ... ) {
 
 
 void config_reader_free() {
-       if( conf_reader == NULL ) { return; }
-       xmlXPathFreeContext( conf_reader->xpathCx );
-       xmlFreeDoc( conf_reader->config_doc );
-       free( conf_reader );
-       conf_reader = NULL;
+       while( conf_reader != NULL ) {
+               xmlXPathFreeContext( conf_reader->xpathCx );
+               xmlFreeDoc( conf_reader->config_doc );
+               free(conf_reader->name );
+               config_reader* tmp = conf_reader->next;
+               free( conf_reader );
+               conf_reader = tmp;
+       }
 }
index cabf1f5..6d24c67 100644 (file)
@@ -7,17 +7,18 @@ LD_OPTS = -L ../../lib -lxml2 -lopensrf_stack -ljson
 LP=../libtransport
 LIB_SOURCES = $(LP)/generic_utils.c $(LP)/transport_socket.c $(LP)/transport_session.c $(LP)/transport_message.c $(LP)/transport_client.c $(LP)/sha.c
 
-all: router router_query router_register
+all: router 
+#router_query router_register
 
-router_register: router_register.c
-       $(CC) $(CC_OPTS) -L ../../lib -lopensrf_transport -lxml2 router_register.c -o router_register
+#router_register: router_register.c
+#      $(CC) $(CC_OPTS) -L ../../lib -lopensrf_transport -lxml2 router_register.c -o router_register
 
-router_query: router_query.c
-       $(CC) $(CC_OPTS) -L ../../lib -lopensrf_transport -lxml2 router_query.c -o router_query
+#router_query: router_query.c
+#      $(CC) $(CC_OPTS) -L ../../lib -lopensrf_transport -lxml2 router_query.c -o router_query
 
 # The router is compiled as a static binary because of some 
 # necessary #defines that would break the library
-router: 
+router:  router.c $(LIB_SOURCES)
        $(CC) $(LD_OPTS) -D_ROUTER $(CC_OPTS)   $(LIB_SOURCES) router.c -o $@ 
 
 clean:
index f5f8be5..497830d 100644 (file)
@@ -24,23 +24,32 @@ int main( int argc, char* argv[] ) {
                exit(0);
        }
 
-       char b[256];
-       memset(b,0,256);
-       jid_get_domain( "client@elroy/test", b );
-       fprintf(stderr, "Domain %s\n", b );
-
-       config_reader_init( argv[1] );  
+       config_reader_init( "opensrf.router", argv[1] );        
        if( conf_reader == NULL ) fatal_handler( "main(): Config is NULL" ); 
 
        /* laod the config options */
-       char* server                    = config_value("//router/transport/server");
-       char* port                              = config_value("//router/transport/port");
-       char* username                  = config_value("//router/transport/username");
-       char* password                  = config_value("//router/transport/password");
-       router_resource         = config_value("//router/transport/resource");
-       char* con_timeout               = config_value("//router/transport/connect_timeout" );
-       char* max_retries               = config_value("//router/transport/max_reconnect_attempts" );
-       char* component         = config_value("//router/component" );
+       char* server                    = config_value("opensrf.router", "//router/transport/server");
+       char* port                              = config_value("opensrf.router", "//router/transport/port");
+       char* username                  = config_value("opensrf.router", "//router/transport/username");
+       char* password                  = config_value("opensrf.router", "//router/transport/password");
+       router_resource         = config_value("opensrf.router", "//router/transport/resource");
+       char* con_timeout               = config_value("opensrf.router", "//router/transport/connect_timeout" );
+       char* max_retries               = config_value("opensrf.router", "//router/transport/max_reconnect_attempts" );
+       char* component         = config_value("opensrf.router", "//router/component" );
+
+
+       /* set up the logger */
+       char* level = config_value("opensrf.router","//log/level");
+       char* log_file = config_value("opensrf.router","//log/file");
+       int llevel = atoi(level);
+       fprintf(stderr, "Level %d; file %s\n", llevel, log_file );
+
+       if(!log_init( llevel, log_file )) 
+               fprintf(stderr, "Unable to init logging, going to stderr...\n" );
+
+
+       free(level);
+       free(log_file);
 
        fprintf(stderr, "Router connecting as \nserver: %s \nport: %s \nuser:%s \nresource:%s\n", 
                        server, port, username, router_resource );
@@ -129,7 +138,7 @@ void _build_trusted_sites( transport_router_registrar* router ) {
 
        int i = 0;
        while( ++i ) {
-               char* server = config_value("//router/trusted_domains/server%d", i );
+               char* server = config_value("opensrf.router","//router/trusted_domains/server%d", i );
                if(server == NULL)
                        break;
                
@@ -138,7 +147,7 @@ void _build_trusted_sites( transport_router_registrar* router ) {
 
        i = 0;
        while( ++i ) {
-               char* client = config_value( "//router/trusted_domains/client%d", i );
+               char* client = config_value( "opensrf.router","//router/trusted_domains/client%d", i );
                if(client == NULL)
                        break;
                router->trusted_clients[i-1] = client;
index fed3fd2..118832b 100644 (file)
@@ -1,6 +1,7 @@
 #include "opensrf/transport_client.h"
 #include "opensrf/transport_message.h"
 #include "opensrf/osrf_message.h"
+#include "opensrf/generic_utils.h"
 
 #include <time.h>
 #include <sys/select.h>
index a57863c..676736f 100644 (file)
@@ -1,7 +1,7 @@
 CC = gcc
 LIB_DIR=../../lib
 CC_OPTS = -Wall -O2 -I /usr/include/libxml2 -I /usr/include/libxml2/libxml -I ../../include 
-EXE_LD_OPTS = -L $(LIB_DIR) -lxml2 -lopensrf_transport 
+EXE_LD_OPTS = -L $(LIB_DIR) -lxml2 -lopensrf_transport -lopensrf_stack -ljson
 
 all: srfsh
 
index 8116742..e0ec1bc 100644 (file)
@@ -1,5 +1,7 @@
 #include "opensrf/transport_client.h"
 #include "opensrf/generic_utils.h"
+#include "opensrf/osrf_message.h"
+#include "opensrf/osrf_app_session.h"
 #include <time.h>
 
 #define SRFSH_PORT 5222
@@ -13,6 +15,8 @@ transport_client* client = NULL;
 int parse_request( char* request );
 int handle_router( char* words[] );
 int handle_time( char* words[] );
+int handle_request( char* words[] );
+int send_request( char* server, char* method, growing_buffer* buffer );
 int parse_error( char* words[] );
 int router_query_servers( char* server );
 int srfsh_client_connect();
@@ -21,9 +25,11 @@ void print_help();
 int main( int argc, char* argv[] ) {
 
 
-       if( argc < 4 ) 
-               fatal_handler( "usage: %s <jabbersever> <username> <password>", argv[0] );
+       if( argc < 5 ) 
+               fatal_handler( "usage: %s <jabbersever> <username> <password> <config_file>", argv[0] );
                
+       config_reader_init( "opensrf", argv[4] );       
+
        char request[256];
        memset(request, 0, 256);
        printf(prompt);
@@ -34,6 +40,9 @@ int main( int argc, char* argv[] ) {
                fprintf(stderr, "Most queries will be futile...\n" );
        }
 
+       if( ! osrf_system_bootstrap_client("srfsh.xml") ) 
+               fprintf( stderr, "Unable to bootstrap client for requests\n");
+
 
        while( fgets( request, 255, stdin) ) {
 
@@ -65,6 +74,10 @@ int main( int argc, char* argv[] ) {
        }
 
        fprintf(stderr, "Exiting...\n[Ignore Segfault]\n");
+
+       config_reader_free();   
+       log_free();
+
        return 0;
 }
 
@@ -122,9 +135,12 @@ int parse_request( char* request ) {
        if( !strcmp(words[0],"router") ) 
                ret_val = handle_router( words );
 
-       if( !strcmp(words[0],"time") ) 
+       else if( !strcmp(words[0],"time") ) 
                ret_val = handle_time( words );
 
+       else if (!strcmp(words[0],"request"))
+               ret_val = handle_request( words );
+
        if(!ret_val)
                return parse_error( words );
 
@@ -156,12 +172,66 @@ int handle_router( char* words[] ) {
        return 0;
 }
 
+int handle_request( char* words[] ) {
+
+       if(!client)
+               return 1;
+
+       if(words[1]) {
+               char* server = words[1];
+               char* method = words[2];
+               int i;
+               growing_buffer* buffer = buffer_init(128);
+
+               for(i = 3; words[i] != NULL; i++ ) {
+                       buffer_add( buffer, words[i] );
+                       buffer_add(buffer, " ");
+               }
+
+               return send_request( server, method, buffer );
+       } 
+
+       return 0;
+}
+
+int send_request( char* server, char* method, growing_buffer* buffer ) {
+       if( server == NULL || method == NULL )
+               return 0;
+
+       json* params = NULL;
+       if( buffer != NULL || buffer->n_used > 0 ) 
+               params = json_tokener_parse(buffer->buf);
+
+       osrf_app_session* session = osrf_app_client_session_init(server);
+       int req_id = osrf_app_session_make_request( session, params, method, 1 );
+
+       osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 5 );
+
+       if(!omsg) 
+               printf("Received no data from server\n");
+       
+       
+       while(omsg) {
+               if(omsg->result_content) 
+                       printf( "Received Data: %s\n",json_object_to_json_string(omsg->result_content) );
+               omsg = osrf_app_session_request_recv( session, req_id, 5 );
+       }
+
+
+       if( osrf_app_session_request_complete( session, req_id ))
+               printf("[Request Completed Successfully]\n");
+
+       return 1;
+
+
+}
+
 int handle_time( char* words[] ) {
 
        if( ! words[1] ) {
 
-               char buf[25];
-               memset(buf,0,25);
+               char buf[36];
+               memset(buf,0,36);
                get_timestamp(buf);
                printf( "%s\n", buf );
                return 1;