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 <iostream>
00036 #include <fstream>
00037
00038 using std::cout;
00039 using std::endl;
00040 using std::cerr;
00041 using std::ofstream;
00042 using std::ios;
00043
00044 #ifdef HAVE_LIBREADLINE
00045 # if defined(HAVE_READLINE_READLINE_H)
00046 # include <readline/readline.h>
00047 # elif defined(HAVE_READLINE_H)
00048 # include <readline.h>
00049 # else
00050 extern "C" {
00051 char *readline(const char *);
00052 }
00053 # endif
00054 char *cmdline = NULL;
00055 #else
00056
00057 #endif
00058
00059 #ifdef HAVE_READLINE_HISTORY
00060 # if defined(HAVE_READLINE_HISTORY_H)
00061 # include <readline/history.h>
00062 # elif defined(HAVE_HISTORY_H)
00063 # include <history.h>
00064 # else
00065 extern "C" {
00066 int add_history(const char *);
00067 int write_history(const char *);
00068 int read_history(const char *);
00069 }
00070 # endif
00071
00072 #endif
00073 #define SIZE_COMMUNICATION_BUFFER 4096*4096
00074 #include "CmdClient.h"
00075 #include "PPTClient.h"
00076 CmdClient::~CmdClient()
00077 {
00078 if (_strmCreated && _strm) {
00079 _strm->flush();
00080 delete _strm;
00081 _strm = 0;
00082 } else if (_strm) {
00083 _strm->flush();
00084 }
00085 if (_client) {
00086 delete _client;
00087 _client = 0;
00088 }
00089 }
00090
00105 void
00106 CmdClient::startClient(const string & host, int portVal, int timeout)
00107 {
00108 _client = new PPTClient(host, portVal, timeout);
00109 _client->initConnection();
00110 }
00111
00121 void CmdClient::startClient(const string & unixStr, int timeout)
00122 {
00123 _client = new PPTClient(unixStr, timeout);
00124 _client->initConnection();
00125 }
00126
00136 void CmdClient::shutdownClient()
00137 {
00138 if( _client )
00139 _client->closeConnection();
00140 }
00141
00157 void CmdClient::setOutput(ostream * strm, bool created)
00158 {
00159 if (_strmCreated && _strm) {
00160 _strm->flush();
00161 delete _strm;
00162 } else if (_strm) {
00163 _strm->flush();
00164 }
00165 _strm = strm;
00166 _strmCreated = created;
00167 }
00168
00180 void CmdClient::executeClientCommand(const string & cmd)
00181 {
00182 string suppress = "suppress";
00183 if (cmd.compare(0, suppress.length(), suppress) == 0) {
00184 setOutput(NULL, false);
00185 } else {
00186 string output = "output to";
00187 if (cmd.compare(0, output.length(), output) == 0) {
00188 string subcmd = cmd.substr(output.length() + 1);
00189 string screen = "screen";
00190 if (subcmd.compare(0, screen.length(), screen) == 0) {
00191 setOutput(&cout, false);
00192 } else {
00193
00194 string file = subcmd.substr(0, subcmd.length() - 1);
00195 ofstream *fstrm = new ofstream(file.c_str(), ios::app);
00196 if (!(*fstrm)) {
00197 cerr << "Unable to set client output to file " << file
00198 << endl;
00199 } else {
00200 setOutput(fstrm, true);
00201 }
00202 }
00203 } else {
00204 cerr << "Improper client command " << cmd << endl;
00205 }
00206 }
00207 }
00208
00223 void CmdClient::executeCommand(const string & cmd, int repeat )
00224 {
00225 string client = "client";
00226 if (cmd.compare(0, client.length(), client) == 0) {
00227 executeClientCommand(cmd.substr(client.length() + 1));
00228 } else {
00229 if( repeat < 1 ) repeat = 1 ;
00230 for( int i = 0; i < repeat; i++ )
00231 {
00232 _client->send(cmd);
00233 _client->receive(_strm);
00234 _strm->flush();
00235 }
00236 }
00237 }
00238
00253 void CmdClient::executeCommands(const string & cmd_list, int repeat)
00254 {
00255 if( repeat < 1 ) repeat = 1 ;
00256 for( int i = 0; i < repeat; i++ )
00257 {
00258 std::string::size_type start = 0;
00259 std::string::size_type end = 0;
00260 while ((end = cmd_list.find(';', start)) != string::npos) {
00261 string cmd = cmd_list.substr(start, end - start + 1);
00262 executeCommand(cmd, 1);
00263 start = end + 1;
00264 }
00265 }
00266 }
00267
00288 void CmdClient::executeCommands(ifstream & istrm, int repeat)
00289 {
00290 if( repeat < 1 ) repeat = 1 ;
00291 for( int i = 0; i < repeat; i++ )
00292 {
00293 istrm.clear( ) ;
00294 istrm.seekg( 0, ios::beg ) ;
00295 string cmd;
00296 bool done = false;
00297 while (!done) {
00298 char line[4096];
00299 line[0] = '\0';
00300 istrm.getline(line, 4096, '\n');
00301 string nextLine = line;
00302 if (nextLine == "") {
00303 if (cmd != "") {
00304 this->executeCommands(cmd, 1);
00305 }
00306 done = true;
00307 } else {
00308 std::string::size_type i = nextLine.find_last_of(';');
00309 if (i == string::npos) {
00310 if (cmd == "") {
00311 cmd = nextLine;
00312 } else {
00313 cmd += " " + nextLine;
00314 }
00315 } else {
00316 string sub = nextLine.substr(0, i + 1);
00317 if (cmd == "") {
00318 cmd = sub;
00319 } else {
00320 cmd += " " + sub;
00321 }
00322 this->executeCommands(cmd, 1);
00323 if (i == nextLine.length() || i == nextLine.length() - 1) {
00324 cmd = "";
00325 } else {
00326 cmd = nextLine.substr(i + 1, nextLine.length());
00327 }
00328 }
00329 }
00330 }
00331 }
00332 }
00333
00351 void CmdClient::interact()
00352 {
00353 cout << endl << endl
00354 << "Type 'exit' to exit the command line client and 'help' or '?' "
00355 << "to display the help screen" << endl << endl;
00356
00357 bool done = false;
00358 while (!done) {
00359 string message = "";
00360 size_t len = this->readLine(message);
00361 if (len == -1 || message == "exit" || message == "exit;") {
00362 done = true;
00363 } else if (message == "help" || message == "help;"
00364 || message == "?") {
00365 this->displayHelp();
00366 } else if (len != 0 && message != "") {
00367 if (message[message.length() - 1] != ';') {
00368 cerr << "Commands must end with a semicolon" << endl;
00369 } else {
00370 this->executeCommands(message, 1);
00371 message = "";
00372 len = 0;
00373 }
00374 }
00375 }
00376 }
00377
00378 size_t CmdClient::readLine(string & msg)
00379 {
00380 size_t len = 0;
00381 char *buf = (char *) NULL;
00382 buf =::readline("BESClient> ");
00383 if (buf && *buf) {
00384 len = strlen(buf);
00385 #ifdef HAVE_READLINE_HISTORY
00386 add_history(buf);
00387 #endif
00388 if (len > SIZE_COMMUNICATION_BUFFER) {
00389 cerr << __FILE__ << __LINE__
00390 <<
00391 ": incoming data buffer exceeds maximum capacity with lenght "
00392 << len << endl;
00393 exit(1);
00394 } else {
00395 msg = buf;
00396 }
00397 } else {
00398 if (!buf) {
00399
00400
00401
00402
00403
00404 len = -1;
00405 }
00406 }
00407 if (buf) {
00408 free(buf);
00409 buf = (char *) NULL;
00410 }
00411 return len;
00412 }
00413
00414 void CmdClient::displayHelp()
00415 {
00416 cout << endl;
00417 cout << endl;
00418 cout << "BES Command Line Client Help" << endl;
00419 cout << endl;
00420 cout << "Client commands available:" << endl;
00421 cout <<
00422 " exit - exit the command line interface" <<
00423 endl;
00424 cout << " help - display this help screen" <<
00425 endl;
00426 cout <<
00427 " client suppress; - suppress output from the server" <<
00428 endl;
00429 cout <<
00430 " client output to screen; - display server output to the screen"
00431 << endl;
00432 cout <<
00433 " client output to <file>; - display server output to specified file"
00434 << endl;
00435 cout << endl;
00436 cout <<
00437 "Any commands beginning with 'client' must end with a semicolon" <<
00438 endl;
00439 cout << endl;
00440 cout << "To display the list of commands available from the server "
00441 << "please type the command 'show help;'" << endl;
00442 cout << endl;
00443 cout << endl;
00444 }
00445
00446 bool CmdClient::isConnected()
00447 {
00448 if (_client)
00449 return _client->isConnected();
00450 return false;
00451 }
00452
00453 void CmdClient::brokenPipe()
00454 {
00455 if (_client)
00456 _client->brokenPipe();
00457 }
00458
00465 void CmdClient::dump(ostream & strm) const
00466 {
00467 strm << BESIndent::LMarg << "CmdClient::dump - ("
00468 << (void *) this << ")" << endl;
00469 BESIndent::Indent();
00470 if (_client) {
00471 strm << BESIndent::LMarg << "client:" << endl;
00472 BESIndent::Indent();
00473 _client->dump(strm);
00474 BESIndent::UnIndent();
00475 } else {
00476 strm << BESIndent::LMarg << "client: null" << endl;
00477 }
00478 strm << BESIndent::LMarg << "stream: " << (void *) _strm << endl;
00479 strm << BESIndent::LMarg << "stream created? " << _strmCreated << endl;
00480 BESIndent::UnIndent();
00481 }