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 - "
00245 << "executed successfully" << endl ) ;
00246 }
00247 else
00248 {
00249
00250 BESDEBUG( "standalone", "BESServerHandler::execute - "
00251 "error occurred" << endl ) ;
00252
00253
00254 *_strm << flush ;
00255
00256
00257
00258 interface->finish_with_error( status ) ;
00259
00260 switch (status)
00261 {
00262 case BES_INTERNAL_FATAL_ERROR:
00263 {
00264 cerr << "BES server " << getpid()
00265 << ": Status not OK, dispatcher returned value "
00266 << status << endl ;
00267
00268
00269 exit( 1 ) ;
00270 }
00271 break;
00272 case BES_INTERNAL_ERROR:
00273 case BES_SYNTAX_USER_ERROR:
00274 case BES_FORBIDDEN_ERROR:
00275 case BES_NOT_FOUND_ERROR:
00276 default:
00277 break;
00278 }
00279 }
00280 delete interface ;
00281 interface = 0 ;
00282
00283 if( show_stream )
00284 {
00285 CmdPretty::make_pretty( show_stream->str(), *_strm ) ;
00286 delete show_stream ;
00287 show_stream = 0 ;
00288 }
00289
00290 _strm->flush() ;
00291 }
00292 }
00293 }
00294
00311 void
00312 StandAloneClient::executeCommands( const string &cmd_list, int repeat )
00313 {
00314 _isInteractive = true ;
00315 if( repeat < 1 ) repeat = 1 ;
00316
00317 CmdTranslation::set_show( false ) ;
00318 try
00319 {
00320 string doc = CmdTranslation::translate( cmd_list ) ;
00321 if( !doc.empty() )
00322 {
00323 executeCommand( doc, repeat ) ;
00324 }
00325 }
00326 catch( BESError &e )
00327 {
00328 CmdTranslation::set_show( false ) ;
00329 _isInteractive = false ;
00330 throw e ;
00331 }
00332 CmdTranslation::set_show( false ) ;
00333 _isInteractive = false ;
00334 }
00335
00354 void
00355 StandAloneClient::executeCommands(ifstream & istrm, int repeat)
00356 {
00357 _isInteractive = false ;
00358 if( repeat < 1 ) repeat = 1 ;
00359 for( int i = 0; i < repeat; i++ )
00360 {
00361 istrm.clear( ) ;
00362 istrm.seekg( 0, ios::beg ) ;
00363 string cmd ;
00364 while( !istrm.eof() )
00365 {
00366 char line[4096] ;
00367 line[0] = '\0' ;
00368 istrm.getline( line, 4096, '\n' ) ;
00369 cmd += line ;
00370 }
00371 this->executeCommand( cmd, 1 ) ;
00372 }
00373 }
00374
00390 void
00391 StandAloneClient::interact()
00392 {
00393 _isInteractive = true ;
00394
00395 cout << endl << endl
00396 << "Type 'exit' to exit the command line client and 'help' or '?' "
00397 << "to display the help screen" << endl << endl ;
00398
00399 bool done = false ;
00400 while( !done )
00401 {
00402 string message = "" ;
00403 size_t len = this->readLine( message ) ;
00404 if( len == -1 || message == "exit" || message == "exit;" )
00405 {
00406 done = true ;
00407 }
00408 else if( message == "help" || message == "help;" || message == "?" )
00409 {
00410 this->displayHelp() ;
00411 }
00412 else if( message.length() > 6 && message.substr( 0, 6 ) == "client" )
00413 {
00414 this->executeCommand( message, 1 ) ;
00415 }
00416 else if( len != 0 && message != "" )
00417 {
00418 CmdTranslation::set_show( false ) ;
00419 try
00420 {
00421 string doc = CmdTranslation::translate( message ) ;
00422 if( !doc.empty() )
00423 {
00424 this->executeCommand( doc, 1 ) ;
00425 }
00426 }
00427 catch( BESError &e )
00428 {
00429 CmdTranslation::set_show( false ) ;
00430 _isInteractive = false ;
00431 throw e ;
00432 }
00433 CmdTranslation::set_show( false ) ;
00434 }
00435 }
00436 _isInteractive = false ;
00437 }
00438
00444 size_t
00445 StandAloneClient::readLine(string & msg)
00446 {
00447 size_t len = 0;
00448 char *buf = (char *) NULL;
00449 buf =::readline("BESClient> ");
00450 if (buf && *buf) {
00451 len = strlen(buf);
00452 #ifdef HAVE_READLINE_HISTORY
00453 add_history(buf);
00454 #endif
00455 if (len > SIZE_COMMUNICATION_BUFFER) {
00456 cerr << __FILE__ << __LINE__
00457 <<
00458 ": incoming data buffer exceeds maximum capacity with lenght "
00459 << len << endl;
00460 exit(1);
00461 } else {
00462 msg = buf;
00463 }
00464 } else {
00465 if (!buf) {
00466
00467
00468
00469
00470
00471 len = -1;
00472 }
00473 }
00474 if (buf) {
00475 free(buf);
00476 buf = (char *) NULL;
00477 }
00478 return len;
00479 }
00480
00483 void
00484 StandAloneClient::displayHelp()
00485 {
00486 cout << endl;
00487 cout << endl;
00488 cout << "BES Command Line Client Help" << endl;
00489 cout << endl;
00490 cout << "Client commands available:" << endl;
00491 cout <<
00492 " exit - exit the command line interface" <<
00493 endl;
00494 cout << " help - display this help screen" <<
00495 endl;
00496 cout <<
00497 " client suppress; - suppress output from the server" <<
00498 endl;
00499 cout <<
00500 " client output to screen; - display server output to the screen"
00501 << endl;
00502 cout <<
00503 " client output to <file>; - display server output to specified file"
00504 << endl;
00505 cout << endl;
00506 cout <<
00507 "Any commands beginning with 'client' must end with a semicolon" <<
00508 endl;
00509 cout << endl;
00510 cout << "To display the list of commands available from the server "
00511 << "please type the command 'show help;'" << endl;
00512 cout << endl;
00513 cout << endl;
00514 }
00515
00522 void
00523 StandAloneClient::dump(ostream & strm) const
00524 {
00525 strm << BESIndent::LMarg << "StandAloneClient::dump - ("
00526 << (void *) this << ")" << endl;
00527 BESIndent::Indent();
00528 strm << BESIndent::LMarg << "stream: " << (void *) _strm << endl;
00529 strm << BESIndent::LMarg << "stream created? " << _strmCreated << endl;
00530 BESIndent::UnIndent();
00531 }