45 using std::ostringstream;
49 #ifdef HAVE_LIBREADLINE 50 # if defined(HAVE_READLINE_READLINE_H) 51 # include <readline/readline.h> 52 # elif defined(HAVE_READLINE_H) 53 # include <readline.h> 57 char *readline(
const char * );
65 #ifdef HAVE_READLINE_HISTORY 66 # if defined(HAVE_READLINE_HISTORY_H) 67 # include <readline/history.h> 68 # elif defined(HAVE_HISTORY_H) 73 int add_history(
const char * );
74 int write_history(
const char * );
75 int read_history(
const char * );
81 #include <libxml/encoding.h> 83 #define SIZE_COMMUNICATION_BUFFER 4096*4096 84 #include "CmdClient.h" 85 #include "CmdTranslation.h" 86 #include "PPTClient.h" 88 #include "BESStopWatch.h" 91 CmdClient::~CmdClient()
93 if (_strmCreated && _strm) {
123 _client =
new PPTClient(host, portVal, timeout);
124 _client->initConnection();
138 _client =
new PPTClient(unixStr, timeout);
139 _client->initConnection();
152 if (_client) _client->closeConnection();
173 if (_strmCreated && _strm) {
181 _strmCreated = created;
197 bool do_exit =
false;
198 string suppress =
"suppress";
199 if (cmd.compare(0, suppress.length(), suppress) == 0) {
204 string output =
"output to";
205 if (cmd.compare(0, output.length(), output) == 0) {
206 string subcmd = cmd.substr(output.length() + 1);
207 string screen =
"screen";
208 if (subcmd.compare(0, screen.length(), screen) == 0) {
213 string file = subcmd.substr(0, subcmd.length() - 1);
214 ofstream *fstrm =
new ofstream(file.c_str(), ios::app);
215 if (fstrm && !(*fstrm)) {
217 cerr <<
"Unable to set client output to file " << file << endl;
227 string load =
"load";
228 if (cmd.compare(0, load.length(), load) == 0) {
229 string file = cmd.substr(load.length() + 1, cmd.length() - load.length() - 2);
230 ifstream fstrm(file.c_str());
232 cerr <<
"Unable to load commands from file " << file <<
": file does not exist or failed to open file" 242 cerr <<
"Improper client command " << cmd << endl;
259 bool CmdClient::executeCommand(
const string &cmd,
int repeat)
261 bool do_exit =
false;
262 const string client =
"client";
263 if (cmd.compare(0, client.length(), client) == 0) {
267 if (repeat < 1) repeat = 1;
268 for (
int i = 0; i < repeat && !do_exit; i++) {
269 BESDEBUG(
"cmdln",
"cmdclient sending " << cmd << endl);
272 if( BESISDEBUG( TIMING_LOG ) )
273 sw.
start(
"CmdClient::executeCommand",
"command_line_client");
275 map<string, string> extensions;
276 _client->
send(cmd, extensions);
278 BESDEBUG(
"cmdln",
"cmdclient receiving " << endl);
281 ostringstream *show_stream = 0;
283 if (CmdTranslation::is_show()) {
285 show_stream =
new ostringstream;
289 done = _client->
receive(extensions, show_stream);
292 done = _client->
receive(extensions, _strm);
294 if (extensions[
"status"] ==
"error") {
301 if (_isInteractive) {
302 CmdTranslation::set_show(
true);
305 if (extensions[
"exit"] ==
"true") {
310 *(_strm) << show_stream->str() << endl;
315 BESDEBUG(
"cmdln",
"extensions:" << endl);
316 map<string, string>::const_iterator i = extensions.begin();
317 map<string, string>::const_iterator e = extensions.end();
318 for (; i != e; i++) {
319 BESDEBUG(
"cmdln",
" " << (*i).first <<
" = " << (*i).second << endl);
321 BESDEBUG(
"cmdln",
"cmdclient done receiving " << endl);
349 bool do_exit =
false;
350 _isInteractive =
true;
351 if (repeat < 1) repeat = 1;
353 CmdTranslation::set_show(
false);
355 string doc = CmdTranslation::translate(cmd_list);
357 do_exit = this->executeCommand(doc, repeat);
361 CmdTranslation::set_show(
false);
362 _isInteractive =
false;
365 CmdTranslation::set_show(
false);
366 _isInteractive =
false;
390 bool do_exit =
false;
391 _isInteractive =
false;
392 if (repeat < 1) repeat = 1;
393 for (
int i = 0; i < repeat; i++) {
395 istrm.seekg(0, ios::beg);
397 while (!istrm.eof()) {
400 istrm.getline(line, 4096,
'\n');
403 do_exit = this->executeCommand(cmd, 1);
429 bool do_exit =
false;
430 _isInteractive =
true;
432 cout << endl << endl <<
"Type 'exit' to exit the command line client and 'help' or '?' " 433 <<
"to display the help screen" << endl << endl;
436 while (!done && !do_exit) {
438 size_t len = this->readLine(message);
440 if (message ==
"exit" || message ==
"exit;") {
443 else if (message ==
"help" || message ==
"help;" || message ==
"?") {
446 else if (message.length() > 6 && message.substr(0, 6) ==
"client") {
447 do_exit = this->executeCommand(message, 1);
449 else if (len != 0 && message !=
"") {
450 CmdTranslation::set_show(
false);
452 string doc = CmdTranslation::translate(message);
454 do_exit = this->executeCommand(doc, 1);
458 CmdTranslation::set_show(
false);
459 _isInteractive =
false;
462 CmdTranslation::set_show(
false);
465 _isInteractive =
false;
477 size_t CmdClient::readLine(
string &msg)
480 char *buf = (
char *) NULL;
481 buf = ::readline(
"BESClient> ");
484 #ifdef HAVE_READLINE_HISTORY 487 if (len > SIZE_COMMUNICATION_BUFFER) {
488 cerr << __FILE__ << __LINE__ <<
489 ": incoming data buffer exceeds maximum capacity with lenght " << len << endl;
516 void CmdClient::displayHelp()
520 cout <<
"BES Command Line Client Help" << endl;
522 cout <<
"Client commands available:" << endl;
523 cout <<
" exit - exit the command line interface" << endl;
524 cout <<
" help - display this help screen" << endl;
525 cout <<
" client suppress; - suppress output from the server" << endl;
526 cout <<
" client output to screen; - display server output to the screen" << endl;
527 cout <<
" client output to <file>; - display server output to specified file" << endl;
528 cout <<
" client load <file>; - load xml document from file" << endl;
530 cout <<
"Any commands beginning with 'client' must end with a semicolon" << endl;
532 cout <<
"To display the list of commands available from the server " <<
"please type the command 'show help;'" 544 if (_client)
return _client->isConnected();
552 if (_client) _client->brokenPipe();
563 strm << BESIndent::LMarg <<
"CmdClient::dump - (" << (
void *)
this <<
")" << endl;
566 strm << BESIndent::LMarg <<
"client:" << endl;
569 BESIndent::UnIndent();
572 strm << BESIndent::LMarg <<
"client: null" << endl;
574 strm << BESIndent::LMarg <<
"stream: " << (
void *) _strm << endl;
575 strm << BESIndent::LMarg <<
"stream created? " << _strmCreated << endl;
576 BESIndent::UnIndent();
void shutdownClient()
Closes the connection to the OpeNDAP server and closes the output stream.
virtual bool receive(map< string, string > &extensions, ostream *strm=0)
receive a chunk of either extensions into the specified map or data into the specified stream ...
bool executeClientCommand(const string &cmd)
Executes a client side command.
void brokenPipe()
inform the server that there has been a borken pipe
virtual bool start(string name)
Abstract exception class for the BES with basic string message.
bool isConnected()
return whether the client is connected to the BES
static bool IsSet(const string &flagName)
see if the debug context flagName is set to true
virtual void dump(ostream &strm) const
dumps information about this object
virtual void dump(ostream &strm) const
dumps information about this object
void startClient(const string &host, int portVal, int timeout)
Connect the BES client to the BES server.
void setOutput(ostream *strm, bool created)
Set the output stream for responses from the BES server.
bool executeCommands(const string &cmd, int repeat)
Send the command(s) specified to the BES server after wrapping in request document.
bool interact()
An interactive BES client that takes BES requests on the command line.
virtual void send(const string &buffer)
sends the buffer to the socket