57#include "CmdTranslation.h"
61#define BES_CMDLN_DEFAULT_TIMEOUT 5
64#define DEFAULT_PORT 10022
65#define DEFAULT_HOST "localhost"
68 BESApp(), _client(0), _hostStr(DEFAULT_HOST), _unixStr(
""), _portVal(DEFAULT_PORT), _outputStrm(0), _inputStrm(
69 0), _createdInputStrm(false), _timeout(0), _repeat(0)
81void CmdApp::showVersion()
83 cout <<
appName() <<
": version 2.0" << endl;
86void CmdApp::showUsage()
89 cout <<
appName() <<
": the following flags are available:" << endl;
90 cout <<
" -h <host> - specifies a host for TCP/IP connection" << endl;
91 cout <<
" -p <port> - specifies a port for TCP/IP connection" << endl;
92 cout <<
" -u <unixSocket> - specifies a unix socket for connection. " << endl;
93 cout <<
" -x <command> - specifies a command for the server to execute" << endl;
94 cout <<
" -i <inputFile> - specifies a file name for a sequence of input commands" << endl;
95 cout <<
" -f <outputFile> - specifies a file name to output the results of the input" << endl;
96 cout <<
" -t <timeoutVal> - specifies an optional timeout value in seconds" << endl;
97 cout <<
" -d - sets the optional debug flag for the client session" << endl;
98 cout <<
" -r <num> - repeat the command(s) num times" << endl;
99 cout <<
" -? - display this list of flags" << endl;
104void CmdApp::signalCannotConnect(
int sig)
106 if (sig == SIGCONT) {
112 <<
"busy with another incoming connection. exiting!\n";
119void CmdApp::signalInterrupt(
int sig)
124 if (signal(SIGINT, CmdApp::signalInterrupt) == SIG_ERR) {
129void CmdApp::signalTerminate(
int sig)
131 if (sig == SIGTERM) {
134 if (signal(SIGTERM, CmdApp::signalTerminate) == SIG_ERR) {
139void CmdApp::signalBrokenPipe(
int sig)
141 if (sig == SIGPIPE) {
143 << endl <<
"Please check parameters and try again" << endl;
158void CmdApp::registerSignals()
161 BESDEBUG(
"cmdln",
"CmdApp: Registering signal SIGCONT ... " << endl);
162 if (signal( SIGCONT, signalCannotConnect) == SIG_ERR) {
163 BESDEBUG(
"cmdln",
"FAILED" << endl);
164 cerr <<
appName() <<
"Failed to register signal SIGCONT" << endl;
167 BESDEBUG(
"cmdln",
"OK" << endl);
171 BESDEBUG(
"cmdln",
"CmdApp: Registering signal SIGINT ... " << endl);
172 if (signal( SIGINT, signalInterrupt) == SIG_ERR) {
173 BESDEBUG(
"cmdln",
"FAILED" << endl);
174 cerr <<
appName() <<
"Failed to register signal SIGINT" << endl;
177 BESDEBUG(
"cmdln",
"OK" << endl);
181 BESDEBUG(
"cmdln",
"CmdApp: Registering signal SIGTERM ... " << endl);
182 if (signal( SIGTERM, signalTerminate) == SIG_ERR) {
183 BESDEBUG(
"cmdln",
"FAILED" << endl);
184 cerr <<
appName() <<
"Failed to register signal SIGTERM" << endl;
187 BESDEBUG(
"cmdln",
"OK" << endl);
190 BESDEBUG(
"cmdln",
"CmdApp: Registering signal SIGPIPE ... " << endl);
191 if (signal( SIGPIPE, CmdApp::signalBrokenPipe) == SIG_ERR) {
192 BESDEBUG(
"cmdln",
"FAILED" << endl);
193 cerr <<
appName() <<
"Failed to register signal SIGPIPE" << endl;
196 BESDEBUG(
"cmdln",
"OK" << endl);
202 if (retVal != 0)
return retVal;
204 CmdTranslation::initialize(argc, argv);
207 string outputStr =
"";
208 string inputStr =
"";
209 string timeoutStr =
"";
210 string repeatStr =
"";
212 bool badUsage =
false;
216 while ((c = getopt(argc, argv,
"?vd:h:p:t:u:x:f:i:r:")) != -1) {
258 if (!portStr.empty() && !_unixStr.empty()) {
259 cerr <<
"cannot use both a port number and a unix socket" << endl;
263 if (!portStr.empty()) {
264 _portVal = atoi(portStr.c_str());
267 if (!timeoutStr.empty()) {
268 _timeout = atoi(timeoutStr.c_str());
271 _timeout = BES_CMDLN_DEFAULT_TIMEOUT;
274 if (outputStr !=
"") {
275 if (_cmd ==
"" && inputStr ==
"") {
276 cerr <<
"When specifying an output file you must either " <<
"specify a command or an input file" << endl;
279 else if (_cmd !=
"" && inputStr !=
"") {
280 cerr <<
"You must specify either a command or an input file on " <<
"the command line, not both" << endl;
285 if (badUsage ==
true) {
290 if (outputStr !=
"") {
291 _outputStrm =
new ofstream(outputStr.c_str());
292 if (!(*_outputStrm)) {
293 cerr <<
"could not open the output file " << outputStr << endl;
298 if (inputStr !=
"") {
299 _inputStrm =
new ifstream(inputStr.c_str());
300 if (!(*_inputStrm)) {
301 cerr <<
"could not open the input file " << inputStr << endl;
304 _createdInputStrm =
true;
307 if (!repeatStr.empty()) {
308 _repeat = atoi(repeatStr.c_str());
309 if (!_repeat && repeatStr !=
"0") {
310 cerr <<
"repeat number invalid: " << repeatStr << endl;
318 if (badUsage ==
true) {
325 BESDEBUG(
"cmdln",
"CmdApp: initialized settings:" << endl << *
this);
336 if (!_unixStr.empty()) {
337 BESDEBUG(
"cmdln",
"CmdApp: Connecting to unix socket: " << _unixStr <<
" ... " << endl);
342 "CmdApp: Connecting to host: " << _hostStr <<
" at port: " << _portVal <<
" ... " << endl);
343 _client->
startClient(_hostStr, _portVal, _timeout);
352 BESDEBUG(
"cmdln",
"OK" << endl);
360 BESDEBUG(
"cmdln",
"FAILED" << endl);
361 cerr <<
"error starting the client" << endl;
366 bool do_exit =
false;
371 else if (_inputStrm) {
379 cerr <<
"error processing commands" << endl;
384 BESDEBUG(
"cmdln",
"CmdApp: shutting down client ... " << endl);
391 BESDEBUG(
"cmdln",
"OK" << endl);
393 BESDEBUG(
"cmdln",
"CmdApp: closing input stream ... " << endl);
394 if (_createdInputStrm && _inputStrm) {
399 BESDEBUG(
"cmdln",
"OK" << endl);
402 BESDEBUG(
"cmdln",
"FAILED" << endl);
403 cerr <<
"error closing the client" << endl;
419 strm << BESIndent::LMarg <<
"CmdApp::dump - (" << (
void *)
this <<
")" << endl;
422 strm << BESIndent::LMarg <<
"client: " << endl;
425 BESIndent::UnIndent();
428 strm << BESIndent::LMarg <<
"client: null" << endl;
430 strm << BESIndent::LMarg <<
"host: " << _hostStr << endl;
431 strm << BESIndent::LMarg <<
"unix socket: " << _unixStr << endl;
432 strm << BESIndent::LMarg <<
"port: " << _portVal << endl;
433 strm << BESIndent::LMarg <<
"command: " << _cmd << endl;
434 strm << BESIndent::LMarg <<
"output stream: " << (
void *) _outputStrm << endl;
435 strm << BESIndent::LMarg <<
"input stream: " << (
void *) _inputStrm << endl;
436 strm << BESIndent::LMarg <<
"created input stream? " << _createdInputStrm << endl;
437 strm << BESIndent::LMarg <<
"timeout: " << _timeout << endl;
439 BESIndent::UnIndent();
442int main(
int argc,
char **argv)
445 return app.
main(argc, argv);
Application class for BES applications.
virtual int initialize(int argC, char **argV)
Initialize the application using the passed argc and argv values.
std::string appName() const
Returns the name of the application.
void dump(std::ostream &strm) const override=0
dumps information about this object
static BESApp * TheApplication()
Returns the BESApp application object for this application.
virtual int main(int argC, char **argV)
main routine, the main entry point for any BES applications.
static void SetUp(const std::string &values)
Sets up debugging for the bes.
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Base exception class for the BES with basic string message.
std::string get_message() const
get the error message for this exception
virtual int initialize(int argC, char **argV)
Initialize the application using the passed argc and argv values.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual int run()
The body of the application, implementing the primary functionality of the BES application.
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 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.