StandAloneClient.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "config.h"
00034
00035 #include <cstdlib>
00036 #include <iostream>
00037 #include <fstream>
00038 #include <sstream>
00039
00040 #ifdef HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043
00044 using std::cout;
00045 using std::endl;
00046 using std::cerr;
00047 using std::ofstream;
00048 using std::ios;
00049 using std::flush;
00050 using std::ostringstream;
00051
00052 #ifdef HAVE_LIBREADLINE
00053 # if defined(HAVE_READLINE_READLINE_H)
00054 # include <readline/readline.h>
00055 # elif defined(HAVE_READLINE_H)
00056 # include <readline.h>
00057 # else
00058 extern "C" {
00059 char *readline(const char *);
00060 }
00061 # endif
00062 char *cmdline = NULL;
00063 #else
00064
00065 #endif
00066
00067 #ifdef HAVE_READLINE_HISTORY
00068 # if defined(HAVE_READLINE_HISTORY_H)
00069 # include <readline/history.h>
00070 # elif defined(HAVE_HISTORY_H)
00071 # include <history.h>
00072 # else
00073 extern "C" {
00074 int add_history(const char *);
00075 int write_history(const char *);
00076 int read_history(const char *);
00077 }
00078 # endif
00079
00080 #endif
00081 #define SIZE_COMMUNICATION_BUFFER 4096*4096
00082 #include "StandAloneClient.h"
00083 #include "BESDebug.h"
00084 #include "BESXMLInterface.h"
00085 #include "CmdTranslation.h"
00086 #include "CmdPretty.h"
00087
00088 StandAloneClient::~StandAloneClient()
00089 {
00090 if (_strmCreated && _strm) {
00091 _strm->flush();
00092 delete _strm;
00093 _strm = 0;
00094 } else if (_strm) {
00095 _strm->flush();
00096 }
00097 }
00098
00115 void
00116 StandAloneClient::setOutput(ostream * strm, bool created)
00117 {
00118 if (_strmCreated && _strm) {
00119 _strm->flush();
00120 delete _strm;
00121 } else if (_strm) {
00122 _strm->flush();
00123 }
00124 _strm = strm;
00125 _strmCreated = created;
00126 }
00127
00139 void
00140 StandAloneClient::executeClientCommand( const string &cmd )
00141 {
00142 string suppress = "suppress" ;
00143 if( cmd.compare( 0, suppress.length(), suppress ) == 0 )
00144 {
00145 setOutput( NULL, false ) ;
00146 return ;
00147 }
00148
00149 string output = "output to" ;
00150 if( cmd.compare( 0, output.length(), output ) == 0 )
00151 {
00152 string subcmd = cmd.substr( output.length() + 1 ) ;
00153 string screen = "screen" ;
00154 if( subcmd.compare( 0, screen.length(), screen ) == 0 )
00155 {
00156 setOutput( &cout, false ) ;
00157 }
00158 else
00159 {
00160
00161 string file = subcmd.substr( 0, subcmd.length() - 1 ) ;
00162 ofstream *fstrm = new ofstream( file.c_str(), ios::app ) ;
00163 if( fstrm && !(*fstrm) )
00164 {
00165 delete fstrm ;
00166 cerr << "Unable to set client output to file " << file
00167 << endl ;
00168 }
00169 else
00170 {
00171 setOutput( fstrm, true ) ;
00172 }
00173 }
00174 return ;
00175 }
00176
00177
00178 string load = "load" ;
00179 if( cmd.compare( 0, load.length(), load ) == 0 )
00180 {
00181 string file = cmd.substr( load.length() + 1,
00182 cmd.length() - load.length() - 2 ) ;
00183 ifstream fstrm( file.c_str() ) ;
00184 if( !fstrm )
00185 {
00186 cerr << "Unable to load commands from file " << file
00187 << ": file does not exist or failed to open file" << endl ;
00188 }
00189 else
00190 {
00191 executeCommands( fstrm, 1 ) ;
00192 }
00193
00194 return ;
00195 }
00196
00197 cerr << "Improper client command " << cmd << endl ;
00198 }
00199
00212 void
00213 StandAloneClient::executeCommand( const string & cmd, int repeat )
00214 {
00215 string client = "client" ;
00216 if( cmd.compare( 0, client.length(), client ) == 0 )
00217 {
00218 executeClientCommand( cmd.substr( client.length() + 1 ) ) ;
00219 }
00220 else
00221 {
00222 if( repeat < 1 ) repeat = 1 ;
00223 for( int i = 0; i < repeat; i++ )
00224 {
00225 ostringstream *show_stream = 0 ;
00226 if( CmdTranslation::is_show() )
00227 {
00228 show_stream = new ostringstream ;
00229 }
00230 BESDEBUG( "standalone", "cmdclient sending " << cmd << endl )
00231 BESXMLInterface *interface = 0 ;
00232 if( show_stream )
00233 {
00234 interface = new BESXMLInterface( cmd, show_stream ) ;
00235 }
00236 else
00237 {
00238 interface = new BESXMLInterface( cmd, _strm ) ;
00239 }
00240 int status = interface->execute_request( "standalone" ) ;
00241
00242 if( status == 0 )
00243 {
00244 BESDEBUG( "standalone", "BESServerHandler::execute - executed successfully" << endl )
00245 }
00246 else
00247 {
00248
00249 BESDEBUG( "standalone", "BESServerHandler::execute - error occurred" << endl )
00250
00251
00252 *_strm << flush ;
00253
00254
00255
00256 interface->finish_with_error( status ) ;
00257
00258 switch (status)
00259 {
00260 case BES_INTERNAL_FATAL_ERROR:
00261 {
00262 cerr << "BES server " << getpid()
00263 << ": Status not OK, dispatcher returned value "
00264 << status << endl ;
00265
00266
00267 exit( 1 ) ;
00268 }
00269 break;
00270 case BES_INTERNAL_ERROR:
00271 case BES_SYNTAX_USER_ERROR:
00272 case BES_FORBIDDEN_ERROR:
00273 case BES_NOT_FOUND_ERROR:
00274 default:
00275 break;
00276 }
00277 }
00278 delete interface ;
00279 interface = 0 ;
00280
00281 if( show_stream )
00282 {
00283 CmdPretty::make_pretty( show_stream->str(), *_strm ) ;
00284 delete show_stream ;
00285 show_stream = 0 ;
00286 }
00287
00288 _strm->flush() ;
00289 }
00290 }
00291 }
00292
00309 void
00310 StandAloneClient::executeCommands( const string &cmd_list, int repeat )
00311 {
00312 _isInteractive = true ;
00313 if( repeat < 1 ) repeat = 1 ;
00314
00315 CmdTranslation::set_show( false ) ;
00316 try
00317 {
00318 string doc = CmdTranslation::translate( cmd_list ) ;
00319 if( !doc.empty() )
00320 {
00321 executeCommand( doc, repeat ) ;
00322 }
00323 }
00324 catch( BESError &e )
00325 {
00326 CmdTranslation::set_show( false ) ;
00327 _isInteractive = false ;
00328 throw e ;
00329 }
00330 CmdTranslation::set_show( false ) ;
00331 _isInteractive = false ;
00332 }
00333
00352 void
00353 StandAloneClient::executeCommands(ifstream & istrm, int repeat)
00354 {
00355 _isInteractive = false ;
00356 if( repeat < 1 ) repeat = 1 ;
00357 for( int i = 0; i < repeat; i++ )
00358 {
00359 istrm.clear( ) ;
00360 istrm.seekg( 0, ios::beg ) ;
00361 string cmd ;
00362 while( !istrm.eof() )
00363 {
00364 char line[4096] ;
00365 line[0] = '\0' ;
00366 istrm.getline( line, 4096, '\n' ) ;
00367 cmd += line ;
00368 }
00369 this->executeCommand( cmd, 1 ) ;
00370 }
00371 }
00372
00388 void
00389 StandAloneClient::interact()
00390 {
00391 _isInteractive = true ;
00392
00393 cout << endl << endl
00394 << "Type 'exit' to exit the command line client and 'help' or '?' "
00395 << "to display the help screen" << endl << endl ;
00396
00397 bool done = false ;
00398 while( !done )
00399 {
00400 string message = "" ;
00401 size_t len = this->readLine( message ) ;
00402 if( len == -1 || message == "exit" || message == "exit;" )
00403 {
00404 done = true ;
00405 }
00406 else if( message == "help" || message == "help;" || message == "?" )
00407 {
00408 this->displayHelp() ;
00409 }
00410 else if( message.length() > 6 && message.substr( 0, 6 ) == "client" )
00411 {
00412 this->executeCommand( message, 1 ) ;
00413 }
00414 else if( len != 0 && message != "" )
00415 {
00416 CmdTranslation::set_show( false ) ;
00417 try
00418 {
00419 string doc = CmdTranslation::translate( message ) ;
00420 if( !doc.empty() )
00421 {
00422 this->executeCommand( doc, 1 ) ;
00423 }
00424 }
00425 catch( BESError &e )
00426 {
00427 CmdTranslation::set_show( false ) ;
00428 _isInteractive = false ;
00429 throw e ;
00430 }
00431 CmdTranslation::set_show( false ) ;
00432 }
00433 }
00434 _isInteractive = false ;
00435 }
00436
00442 size_t
00443 StandAloneClient::readLine(string & msg)
00444 {
00445 size_t len = 0;
00446 char *buf = (char *) NULL;
00447 buf =::readline("BESClient> ");
00448 if (buf && *buf) {
00449 len = strlen(buf);
00450 #ifdef HAVE_READLINE_HISTORY
00451 add_history(buf);
00452 #endif
00453 if (len > SIZE_COMMUNICATION_BUFFER) {
00454 cerr << __FILE__ << __LINE__
00455 <<
00456 ": incoming data buffer exceeds maximum capacity with lenght "
00457 << len << endl;
00458 exit(1);
00459 } else {
00460 msg = buf;
00461 }
00462 } else {
00463 if (!buf) {
00464
00465
00466
00467
00468
00469 len = -1;
00470 }
00471 }
00472 if (buf) {
00473 free(buf);
00474 buf = (char *) NULL;
00475 }
00476 return len;
00477 }
00478
00481 void
00482 StandAloneClient::displayHelp()
00483 {
00484 cout << endl;
00485 cout << endl;
00486 cout << "BES Command Line Client Help" << endl;
00487 cout << endl;
00488 cout << "Client commands available:" << endl;
00489 cout <<
00490 " exit - exit the command line interface" <<
00491 endl;
00492 cout << " help - display this help screen" <<
00493 endl;
00494 cout <<
00495 " client suppress; - suppress output from the server" <<
00496 endl;
00497 cout <<
00498 " client output to screen; - display server output to the screen"
00499 << endl;
00500 cout <<
00501 " client output to <file>; - display server output to specified file"
00502 << endl;
00503 cout << endl;
00504 cout <<
00505 "Any commands beginning with 'client' must end with a semicolon" <<
00506 endl;
00507 cout << endl;
00508 cout << "To display the list of commands available from the server "
00509 << "please type the command 'show help;'" << endl;
00510 cout << endl;
00511 cout << endl;
00512 }
00513
00520 void
00521 StandAloneClient::dump(ostream & strm) const
00522 {
00523 strm << BESIndent::LMarg << "StandAloneClient::dump - ("
00524 << (void *) this << ")" << endl;
00525 BESIndent::Indent();
00526 strm << BESIndent::LMarg << "stream: " << (void *) _strm << endl;
00527 strm << BESIndent::LMarg << "stream created? " << _strmCreated << endl;
00528 BESIndent::UnIndent();
00529 }