45using std::ostringstream;
52#ifdef HAVE_LIBREADLINE
53# if defined(HAVE_READLINE_READLINE_H)
54# include <readline/readline.h>
55# elif defined(HAVE_READLINE_H)
60 char *readline(
const char * );
68#ifdef HAVE_READLINE_HISTORY
69# if defined(HAVE_READLINE_HISTORY_H)
70# include <readline/history.h>
71# elif defined(HAVE_HISTORY_H)
76 int add_history(
const char * );
77 int write_history(
const char * );
78 int read_history(
const char * );
84#include <libxml/encoding.h>
86#define SIZE_COMMUNICATION_BUFFER 4096*4096
88#include "CmdTranslation.h"
91#include "BESStopWatch.h"
94CmdClient::~CmdClient()
96 if (_strmCreated && _strm) {
126 _client =
new PPTClient(host, portVal, timeout);
127 _client->initConnection();
141 _client =
new PPTClient(unixStr, timeout);
142 _client->initConnection();
155 if (_client) _client->closeConnection();
176 if (_strmCreated && _strm) {
184 _strmCreated = created;
200 bool do_exit =
false;
201 string suppress =
"suppress";
202 if (cmd.compare(0, suppress.length(), suppress) == 0) {
207 string output =
"output to";
208 if (cmd.compare(0, output.length(), output) == 0) {
209 string subcmd = cmd.substr(output.length() + 1);
210 string screen =
"screen";
211 if (subcmd.compare(0, screen.length(), screen) == 0) {
216 string file = subcmd.substr(0, subcmd.length() - 1);
217 ofstream *fstrm =
new ofstream(file.c_str(), ios::app);
218 if (fstrm && !(*fstrm)) {
220 cerr <<
"Unable to set client output to file " << file << endl;
230 string load =
"load";
231 if (cmd.compare(0, load.length(), load) == 0) {
232 string file = cmd.substr(load.length() + 1, cmd.length() - load.length() - 2);
233 ifstream fstrm(file.c_str());
235 cerr <<
"Unable to load commands from file " << file <<
": file does not exist or failed to open file"
245 cerr <<
"Improper client command " << cmd << endl;
262bool CmdClient::executeCommand(
const string &cmd,
int repeat)
264 bool do_exit =
false;
265 const string client =
"client";
266 if (cmd.compare(0, client.length(), client) == 0) {
270 if (repeat < 1) repeat = 1;
271 for (
int i = 0; i < repeat && !do_exit; i++) {
272 BESDEBUG(
"cmdln",
"cmdclient sending " << cmd << endl);
276 sw.
start(
"CmdClient::executeCommand",
"command_line_client");
278 map<string, string> extensions;
279 _client->
send(cmd, extensions);
281 BESDEBUG(
"cmdln",
"cmdclient receiving " << endl);
284 ostringstream *show_stream = 0;
286 if (CmdTranslation::is_show()) {
288 show_stream =
new ostringstream;
292 done = _client->
receive(extensions, show_stream);
295 done = _client->
receive(extensions, _strm);
297 if (extensions[
"status"] ==
"error") {
304 if (_isInteractive) {
305 CmdTranslation::set_show(
true);
308 if (extensions[
"exit"] ==
"true") {
313 *(_strm) << show_stream->str() << endl;
318 BESDEBUG(
"cmdln",
"extensions:" << endl);
319 map<string, string>::const_iterator i = extensions.begin();
320 map<string, string>::const_iterator e = extensions.end();
321 for (; i != e; i++) {
322 BESDEBUG(
"cmdln",
" " << (*i).first <<
" = " << (*i).second << endl);
324 BESDEBUG(
"cmdln",
"cmdclient done receiving " << endl);
352 bool do_exit =
false;
353 _isInteractive =
true;
354 if (repeat < 1) repeat = 1;
356 CmdTranslation::set_show(
false);
358 string doc = CmdTranslation::translate(cmd_list);
360 do_exit = this->executeCommand(doc, repeat);
364 CmdTranslation::set_show(
false);
365 _isInteractive =
false;
368 CmdTranslation::set_show(
false);
369 _isInteractive =
false;
393 bool do_exit =
false;
394 _isInteractive =
false;
395 if (repeat < 1) repeat = 1;
396 for (
int i = 0; i < repeat; i++) {
398 istrm.seekg(0, ios::beg);
400 while (!istrm.eof()) {
403 istrm.getline(line, 4096,
'\n');
406 do_exit = this->executeCommand(cmd, 1);
432 bool do_exit =
false;
433 _isInteractive =
true;
435 cout << endl << endl <<
"Type 'exit' to exit the command line client and 'help' or '?' "
436 <<
"to display the help screen" << endl << endl;
439 while (!done && !do_exit) {
441 size_t len = this->readLine(message);
443 if (message ==
"exit" || message ==
"exit;") {
446 else if (message ==
"help" || message ==
"help;" || message ==
"?") {
449 else if (message.length() > 6 && message.substr(0, 6) ==
"client") {
450 do_exit = this->executeCommand(message, 1);
452 else if (len != 0 && message !=
"") {
453 CmdTranslation::set_show(
false);
455 string doc = CmdTranslation::translate(message);
457 do_exit = this->executeCommand(doc, 1);
461 CmdTranslation::set_show(
false);
462 _isInteractive =
false;
465 CmdTranslation::set_show(
false);
468 _isInteractive =
false;
480size_t CmdClient::readLine(
string &msg)
483 char *buf = (
char *) NULL;
484 buf = ::readline(
"BESClient> ");
487#ifdef HAVE_READLINE_HISTORY
490 if (len > SIZE_COMMUNICATION_BUFFER) {
491 cerr << __FILE__ << __LINE__ <<
492 ": incoming data buffer exceeds maximum capacity with lenght " << len << endl;
519void CmdClient::displayHelp()
523 cout <<
"BES Command Line Client Help" << endl;
525 cout <<
"Client commands available:" << endl;
526 cout <<
" exit - exit the command line interface" << endl;
527 cout <<
" help - display this help screen" << endl;
528 cout <<
" client suppress; - suppress output from the server" << endl;
529 cout <<
" client output to screen; - display server output to the screen" << endl;
530 cout <<
" client output to <file>; - display server output to specified file" << endl;
531 cout <<
" client load <file>; - load xml document from file" << endl;
533 cout <<
"Any commands beginning with 'client' must end with a semicolon" << endl;
535 cout <<
"To display the list of commands available from the server " <<
"please type the command 'show help;'"
547 if (_client)
return _client->isConnected();
555 if (_client) _client->brokenPipe();
566 strm << BESIndent::LMarg <<
"CmdClient::dump - (" << (
void *)
this <<
")" << endl;
569 strm << BESIndent::LMarg <<
"client:" << endl;
572 BESIndent::UnIndent();
575 strm << BESIndent::LMarg <<
"client: null" << endl;
577 strm << BESIndent::LMarg <<
"stream: " << (
void *) _strm << endl;
578 strm << BESIndent::LMarg <<
"stream created? " << _strmCreated << endl;
579 BESIndent::UnIndent();
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
Base exception class for the BES with basic string message.
virtual bool start(std::string name)
void brokenPipe()
inform the server that there has been a borken pipe
bool executeCommands(const std::string &cmd, int repeat)
Send the command(s) specified to the BES server after wrapping in request document.
void startClient(const std::string &host, int portVal, int timeout)
Connect the BES client to the BES server.
bool executeClientCommand(const std::string &cmd)
Executes a client side command.
bool interact()
An interactive BES client that takes BES requests on the command line.
bool isConnected()
return whether the client is connected to the BES
void shutdownClient()
Closes the connection to the OpeNDAP server and closes the output stream.
virtual void dump(std::ostream &strm) const
dumps information about this object
void setOutput(std::ostream *strm, bool created)
Set the output stream for responses from the BES server.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void send(const std::string &buffer)
sends the buffer to the socket
virtual bool receive(std::map< std::string, std::string > &extensions, std::ostream *strm=0)
receive a chunk of either extensions into the specified map or data into the specified stream