diff --git a/ndb/src/Makefile.am b/ndb/src/Makefile.am index eb1cf1c6543133f23117ec63f1ee7920d5f32660..d35790a2e4365416d15f6925e6260e2290ac8854 100644 --- a/ndb/src/Makefile.am +++ b/ndb/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = common mgmapi ndbapi . kernel mgmsrv mgmclient cw +SUBDIRS = common mgmapi ndbapi . kernel mgmclient mgmsrv cw include $(top_srcdir)/ndb/config/common.mk.am diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp deleted file mode 100644 index 686155415d58c61aaa058062a7285920d03c3914..0000000000000000000000000000000000000000 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "CommandInterpreter.hpp" - -#include <string.h> -#include <ctype.h> - -#include "MgmtSrvr.hpp" -#include "MgmtErrorReporter.hpp" -#include <NdbOut.hpp> -#include "convertStrToInt.hpp" -#include <EventLogger.hpp> -#include <signaldata/SetLogLevelOrd.hpp> -#include "ConfigInfo.hpp" - -#include <version.h> -#include <m_string.h> - -//****************************************************************************** -//****************************************************************************** -CommandInterpreter::CommandInterpreter(MgmtSrvr& mgmtSrvr) : - _mgmtSrvr(mgmtSrvr) { -} - - -bool emptyString(const char* s) { - if (s == NULL) { - return true; - } - - for (unsigned int i = 0; i < strlen(s); ++i) { - if (! isspace(s[i])) { - return false; - } - } - - return true; -} - -class AutoPtr { -public: - AutoPtr(void * ptr) : m_ptr(ptr) {} - ~AutoPtr() { free(m_ptr);} -private: - void * m_ptr; -}; - -const char *CommandInterpreter::get_error_text(int err_no) -{ - return _mgmtSrvr.getErrorText(err_no, m_err_str, sizeof(m_err_str)); -} - -//***************************************************************************** -//***************************************************************************** -int CommandInterpreter::readAndExecute() { - - char* _line = readline_gets(); - char * line; - if(_line == NULL) { - ndbout << endl; - return true; - } - - line = strdup(_line); - - AutoPtr ptr(line); - - if (emptyString(line)) { - return true; - } - - for (unsigned int i = 0; i < strlen(line); ++i) { - line[i] = toupper(line[i]); - } - - // if there is anything in the line proceed - char* firstToken = strtok(line, " "); - char* allAfterFirstToken = strtok(NULL, "\0"); - - if (strcmp(firstToken, "ALL") == 0) { - analyseAfterFirstToken(-1, allAfterFirstToken); - } - else if(strcmp(firstToken, "QUIT") == 0 || - strcmp(firstToken, "EXIT") == 0 || - strcmp(firstToken, "BYE") == 0){ - return false; - } else { - // First token should be a digit, process ID - - int processId; - if (! convert(firstToken, processId)) { - ndbout << "Invalid command: " << _line << "." << endl; - return true; - } - if (processId < 0) { - ndbout << "Invalid process ID: " << firstToken << "." << endl; - return true; - } - - analyseAfterFirstToken(processId, allAfterFirstToken); - - } // else - return true; -} - - -static const CommandInterpreter::CommandFunctionPair commands[] = { - { "TRACE", &CommandInterpreter::executeTrace } - ,{ "LOGIN", &CommandInterpreter::executeLogIn } - ,{ "LOGOUT", &CommandInterpreter::executeLogOut } - ,{ "LOGOFF", &CommandInterpreter::executeLogOff } -}; - - -//***************************************************************************** -//***************************************************************************** -void -CommandInterpreter::analyseAfterFirstToken(int processId, - char* allAfterFirstToken) { - - if (emptyString(allAfterFirstToken)) { - if (processId == -1) { - ndbout << "Expected a command after ALL." << endl; - } - else { - ndbout << "Expected a command after process ID." << endl; - } - return; - } - - - char* secondToken = strtok(allAfterFirstToken, " "); - char* allAfterSecondToken = strtok(NULL, "\0"); - - const int tmpSize = sizeof(commands)/sizeof(CommandFunctionPair); - ExecuteFunction fun = 0; - const char * command = 0; - for(int i = 0; i<tmpSize; i++){ - if(strcmp(secondToken, commands[i].command) == 0){ - fun = commands[i].executeFunction; - command = commands[i].command; - break; - } - } - - if(fun == 0){ - ndbout << "Invalid command: " << secondToken << "." << endl; - return; - } - - if(processId == -1){ - executeForAll(command, fun, allAfterSecondToken); - } else { - ndbout << "Executing " << command << " on node: " - << processId << endl << endl; - (this->*fun)(processId, allAfterSecondToken, false); - ndbout << endl; - } -} - -void -CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, - const char * allAfterSecondToken){ - - NodeId nodeId = 0; - while(_mgmtSrvr.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - ndbout << "Executing " << cmd << " on node: " - << nodeId << endl << endl; - (this->*fun)(nodeId, allAfterSecondToken, true); - ndbout << endl; - } -} - -//***************************************************************************** -//***************************************************************************** -bool CommandInterpreter::parseBlockSpecification(const char* allAfterLog, - Vector<BaseString>& blocks) { - - // Parse: [BLOCK = {ALL|<blockName>+}] - - if (emptyString(allAfterLog)) { - return true; - } - - // Copy allAfterLog since strtok will modify it - char* newAllAfterLog = strdup(allAfterLog); - char* firstTokenAfterLog = strtok(newAllAfterLog, " "); - for (unsigned int i = 0; i < strlen(firstTokenAfterLog); ++i) { - firstTokenAfterLog[i] = toupper(firstTokenAfterLog[i]); - } - - if (strcmp(firstTokenAfterLog, "BLOCK") != 0) { - ndbout << "Unexpected value: " << firstTokenAfterLog - << ". Expected BLOCK." << endl; - free(newAllAfterLog); - return false; - } - - char* allAfterFirstToken = strtok(NULL, "\0"); - if (emptyString(allAfterFirstToken)) { - ndbout << "Expected =." << endl; - free(newAllAfterLog); - return false; - } - - char* secondTokenAfterLog = strtok(allAfterFirstToken, " "); - if (strcmp(secondTokenAfterLog, "=") != 0) { - ndbout << "Unexpected value: " << secondTokenAfterLog - << ". Expected =." << endl; - free(newAllAfterLog); - return false; - } - - char* blockName = strtok(NULL, " "); - bool all = false; - if (blockName != NULL && (strcmp(blockName, "ALL") == 0)) { - all = true; - } - while (blockName != NULL) { - blocks.push_back(BaseString(blockName)); - blockName = strtok(NULL, " "); - } - - if (blocks.size() == 0) { - ndbout << "No block specified." << endl; - free(newAllAfterLog); - return false; - } - if (blocks.size() > 1 && all) { - // More than "ALL" specified - ndbout << "Nothing expected after ALL." << endl; - free(newAllAfterLog); - return false; - } - - free(newAllAfterLog); - return true; -} - -void CommandInterpreter::executeLogIn(int processId, - const char* parameters, bool all) { - - (void)all; // Don't want compiler warning - - Vector<BaseString> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks); - if (result != 0) { - ndbout << get_error_text(result) << endl; - } -} - -//****************************************************************************** -//****************************************************************************** -void CommandInterpreter::executeLogOut(int processId, - const char* parameters, bool all) { - - (void)all; // Don't want compiler warning - - Vector<BaseString> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - - - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out, blocks); - if (result != 0) { - ndbout << get_error_text(result) << endl; - } - -} - - -//****************************************************************************** -//****************************************************************************** -void CommandInterpreter::executeLogOff(int processId, - const char* parameters, bool all) { - - (void)all; // Don't want compiler warning - - Vector<BaseString> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - - - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off, blocks); - if (result != 0) { - ndbout << get_error_text(result) << endl; - } - -} - -void CommandInterpreter::executeTrace(int processId, - const char* parameters, bool all) { - - (void)all; // Don't want compiler warning - - if (emptyString(parameters)) { - ndbout << "Missing trace number." << endl; - return; - } - - char* newpar = strdup(parameters); - char* firstParameter = strtok(newpar, " "); - - - int traceNo; - if (! convert(firstParameter, traceNo)) { - ndbout << "Expected an integer." << endl; - free(newpar); - return; - } - - char* allAfterFirstParameter = strtok(NULL, "\0"); - - if (! emptyString(allAfterFirstParameter)) { - ndbout << "Nothing expected after trace number." << endl; - free(newpar); - return; - } - - int result = _mgmtSrvr.setTraceNo(processId, traceNo); - if (result != 0) { - ndbout << get_error_text(result) << endl; - } - free(newpar); -} diff --git a/ndb/src/mgmsrv/CommandInterpreter.hpp b/ndb/src/mgmsrv/CommandInterpreter.hpp deleted file mode 100644 index 6b67d1a5a5f432d0a5c45e19d11d0af12a236b48..0000000000000000000000000000000000000000 --- a/ndb/src/mgmsrv/CommandInterpreter.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef CommandInterpreter_H -#define CommandInterpreter_H - -#include <ndb_global.h> -#include <Vector.hpp> -#include <BaseString.hpp> - -class MgmtSrvr; - -class CommandInterpreter { -public: - CommandInterpreter(MgmtSrvr& mgmtSrvr); - int readAndExecute(); - -private: - char m_err_str[1024]; - const char *get_error_text(int err_no); - - char *readline_gets () - { - static char linebuffer[254]; - static char *line_read = (char *)NULL; - - /* If the buffer has already been allocated, return the memory - to the free pool. */ - if (line_read) - { - free (line_read); - line_read = (char *)NULL; - } - - /* Get a line from the user. */ - fputs("ndb_mgmd> ", stdout); - linebuffer[sizeof(linebuffer)-1]=0; - line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); - if (line_read == linebuffer) { - char *q=linebuffer; - while (*q > 31) q++; - *q=0; - line_read= strdup(linebuffer); - } - return (line_read); - } - - void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr); - bool parseBlockSpecification(const char* allAfterLog, - Vector<BaseString>& blocks); - -public: - void executeTrace(int processId, const char* parameters, bool all); - void executeLogIn(int processId, const char* parameters, bool all); - void executeLogOut(int processId, const char* parameters, bool all); - void executeLogOff(int processId, const char* parameters, bool all); - -public: - typedef void (CommandInterpreter::* ExecuteFunction)(int processId, - const char * param, - bool all); - - struct CommandFunctionPair { - const char * command; - ExecuteFunction executeFunction; - }; -private: - /** - * - */ - void executeForAll(const char * cmd, ExecuteFunction fun, const char * param); - - /** - * Management server to use when executing commands - */ - MgmtSrvr& _mgmtSrvr; -}; - -#endif // CommandInterpreter_H diff --git a/ndb/src/mgmsrv/Makefile.am b/ndb/src/mgmsrv/Makefile.am index 50e0b6023adf2a629f48ef717ea66776b3c17e66..7fd3fa66b434738a7e7dd314cd0450605d23b346 100644 --- a/ndb/src/mgmsrv/Makefile.am +++ b/ndb/src/mgmsrv/Makefile.am @@ -16,17 +16,20 @@ ndb_mgmd_SOURCES = \ MgmtSrvrConfig.cpp \ ConfigInfo.cpp \ InitConfigFileParser.cpp \ - Config.cpp \ - CommandInterpreter.cpp + Config.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/src/ndbapi \ -I$(top_srcdir)/ndb/src/mgmapi \ - -I$(top_srcdir)/ndb/src/common/mgmcommon + -I$(top_srcdir)/ndb/src/common/mgmcommon \ + -I$(top_srcdir)/ndb/src/mgmclient -LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \ +LDADD_LOC = $(top_srcdir)/ndb/src/mgmclient/CommandInterpreter.o \ + $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ + $(top_builddir)/strings/libmystrings.a \ + @readline_link@ \ + @NDB_SCI_LIBS@ \ @TERMCAP_LIB@ DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index a638b85426e6ff5acf98402505dfce799e0af354..482bc2e89cc02f4bc76ba994c6a13ece915103ee 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -40,7 +40,7 @@ #if defined NDB_OSE || defined NDB_SOFTOSE #include <efs.h> #else -#include "CommandInterpreter.hpp" +#include <ndb_mgmclient.hpp> #endif #undef DEBUG @@ -48,11 +48,54 @@ const char progname[] = "mgmtsrvr"; +// copied from mysql.cc to get readline +extern "C" { +#if defined( __WIN__) || defined(OS2) +#include <conio.h> +#elif !defined(__NETWARE__) +#include <readline/readline.h> +extern "C" int add_history(const char *command); /* From readline directory */ +#define HAVE_READLINE +#endif +} + +static int +read_and_execute(Ndb_mgmclient* com, const char * prompt, int _try_reconnect) +{ + static char *line_read = (char *)NULL; + + /* If the buffer has already been allocated, return the memory + to the free pool. */ + if (line_read) + { + free (line_read); + line_read = (char *)NULL; + } +#ifdef HAVE_READLINE + /* Get a line from the user. */ + line_read = readline (prompt); + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) + add_history (line_read); +#else + static char linebuffer[254]; + fputs(prompt, stdout); + linebuffer[sizeof(linebuffer)-1]=0; + line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); + if (line_read == linebuffer) { + char *q=linebuffer; + while (*q > 31) q++; + *q=0; + line_read= strdup(linebuffer); + } +#endif + return com->execute(line_read,_try_reconnect); +} /** * @struct MgmGlobals * @brief Global Variables used in the management server - ******************************************************************************/ + *****************************************************************************/ struct MgmGlobals { MgmGlobals(); ~MgmGlobals(); @@ -297,14 +340,19 @@ int main(int argc, char** argv) #if ! defined NDB_OSE && ! defined NDB_SOFTOSE if(glob.interactive) { - CommandInterpreter com(* glob.mgmObject); - while(com.readAndExecute()); + BaseString con_str; + if(glob.interface_name) + con_str.appfmt("host=%s:%d", glob.interface_name, glob.port); + else + con_str.appfmt("localhost:%d", glob.port); + Ndb_mgmclient com(con_str.c_str(), 1); + while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1)); } else #endif - { - while(g_StopServer != true) - NdbSleep_MilliSleep(500); - } + { + while(g_StopServer != true) + NdbSleep_MilliSleep(500); + } g_eventLogger.info("Shutting down server..."); glob.socketServer->stopServer();