diff options
Diffstat (limited to 'ndb/src/mgmapi/LocalConfig.cpp')
-rw-r--r-- | ndb/src/mgmapi/LocalConfig.cpp | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/ndb/src/mgmapi/LocalConfig.cpp b/ndb/src/mgmapi/LocalConfig.cpp new file mode 100644 index 00000000000..d0ff97cdedf --- /dev/null +++ b/ndb/src/mgmapi/LocalConfig.cpp @@ -0,0 +1,297 @@ +/* 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 <LocalConfig.hpp> +#include <NdbEnv.h> +#include <NdbConfig.h> +#include <NdbAutoPtr.hpp> +#include <NdbMem.h> + +LocalConfig::LocalConfig(){ + error_line = 0; error_msg[0] = 0; + _ownNodeId= 0; +} + +bool +LocalConfig::init(const char *connectString, + const char *fileName) { + /** + * Escalation: + * 1. Check connectString + * 2. Check given filename + * 3. Check environment variable NDB_CONNECTSTRING + * 4. Check Ndb.cfg in NDB_HOME + * 5. Check Ndb.cfg in cwd + * 6. Check defaultConnectString + */ + + //1. Check connectString + if(connectString != 0 && connectString[0] != 0){ + if(readConnectString(connectString, "connect string")){ + return true; + } + return false; + } + + //2. Check given filename + if (fileName && strlen(fileName) > 0) { + bool fopenError; + if(readFile(fileName, fopenError)){ + return true; + } + return false; + } + + //3. Check environment variable + char buf[255]; + if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) && + strlen(buf) != 0){ + if(readConnectString(buf, "NDB_CONNECTSTRING")){ + return true; + } + return false; + } + + //4. Check Ndb.cfg in NDB_HOME + { + bool fopenError; + char *buf= NdbConfig_NdbCfgName(1 /*true*/); + NdbAutoPtr<char> tmp_aptr(buf); + if(readFile(buf, fopenError)) + return true; + if (!fopenError) + return false; + } + + //5. Check Ndb.cfg in cwd + { + bool fopenError; + char *buf= NdbConfig_NdbCfgName(0 /*false*/); + NdbAutoPtr<char> tmp_aptr(buf); + if(readFile(buf, fopenError)) + return true; + if (!fopenError) + return false; + } + + //7. Check + { + char buf[256]; + BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_PORT); + if(readConnectString(buf, "default connect string")) + return true; + } + + setError(0, ""); + + return false; +} + +LocalConfig::~LocalConfig(){ +} + +void LocalConfig::setError(int lineNumber, const char * _msg) { + error_line = lineNumber; + strncpy(error_msg, _msg, sizeof(error_msg)); +} + +void LocalConfig::printError() const { + ndbout << "Configuration error" << endl; + if (error_line) + ndbout << "Line: "<< error_line << ", "; + ndbout << error_msg << endl << endl; +} + +void LocalConfig::printUsage() const { + ndbout << "This node needs information on how to connect"<<endl + << "to the NDB Management Server."<<endl + << "The information can be supplied in one of the following ways:" + << endl; + + ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl + << " the node. "<< endl + << " Ex: Ndb.cfg" << endl + << " | host=localhost:"<<NDB_PORT<<endl; + + ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl + << " provide this information." <<endl + << " Ex: " << endl + << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_PORT<<"\"" + <<endl<<endl; +} + +const char *nodeIdTokens[] = { + "OwnProcessId %i", + "nodeid=%i", + 0 +}; + +const char *hostNameTokens[] = { + "host://%[^:]:%i", + "host=%[^:]:%i", + "%[^:^=^ ]:%i", + "%s %i", + 0 +}; + +const char *fileNameTokens[] = { + "file://%s", + "file=%s", + 0 +}; + +bool +LocalConfig::parseNodeId(const char * buf){ + for(int i = 0; nodeIdTokens[i] != 0; i++) + if (sscanf(buf, nodeIdTokens[i], &_ownNodeId) == 1) + return true; + return false; +} + +bool +LocalConfig::parseHostName(const char * buf){ + char tempString[1024]; + char tempString2[1024]; + int port; + do { + for(int i = 0; hostNameTokens[i] != 0; i++) { + if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) { + MgmtSrvrId mgmtSrvrId; + mgmtSrvrId.type = MgmId_TCP; + mgmtSrvrId.name.assign(tempString); + mgmtSrvrId.port = port; + ids.push_back(mgmtSrvrId); + return true; + } + } + if (buf == tempString2) + break; + // try to add default port to see if it works + snprintf(tempString2, sizeof(tempString2),"%s:%s", buf, NDB_PORT); + buf= tempString2; + } while(1); + return false; +} + +bool +LocalConfig::parseFileName(const char * buf){ + char tempString[1024]; + for(int i = 0; fileNameTokens[i] != 0; i++) { + if (sscanf(buf, fileNameTokens[i], tempString) == 1) { + MgmtSrvrId mgmtSrvrId; + mgmtSrvrId.type = MgmId_File; + mgmtSrvrId.name.assign(tempString); + ids.push_back(mgmtSrvrId); + return true; + } + } + return false; +} + +bool +LocalConfig::parseString(const char * connectString, BaseString &err){ + char * for_strtok; + char * copy = strdup(connectString); + NdbAutoPtr<char> tmp_aptr(copy); + + bool b_nodeId = false; + bool found_other = false; + + for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0; + tok = strtok_r(NULL, ";,", &for_strtok)) { + if (tok[0] == '#') continue; + + if (!b_nodeId) // only one nodeid definition allowed + if (b_nodeId = parseNodeId(tok)) + continue; + if (found_other = parseHostName(tok)) + continue; + if (found_other = parseFileName(tok)) + continue; + + err.assfmt("Unexpected entry: \"%s\"", tok); + return false; + } + + if (!found_other) { + err.appfmt("Missing host/file name extry in \"%s\"", connectString); + return false; + } + + return true; +} + +bool LocalConfig::readFile(const char * filename, bool &fopenError) +{ + char line[1024]; + + fopenError = false; + + FILE * file = fopen(filename, "r"); + if(file == 0){ + BaseString::snprintf(line, sizeof(line), + "Unable to open local config file: %s", filename); + setError(0, line); + fopenError = true; + return false; + } + + BaseString theString; + + while(fgets(line, sizeof(line), file)){ + BaseString tmp(line); + tmp.trim(" \t\n\r"); + if(tmp.length() > 0 && tmp.c_str()[0] != '#'){ + theString.append(tmp); + break; + } + } + while (fgets(line, sizeof(line), file)) { + BaseString tmp(line); + tmp.trim(" \t\n\r"); + if(tmp.length() > 0 && tmp.c_str()[0] != '#'){ + theString.append(";"); + theString.append(tmp); + } + } + + BaseString err; + bool return_value = parseString(theString.c_str(), err); + + if (!return_value) { + BaseString tmp; + tmp.assfmt("Reading %s: %s", filename, err.c_str()); + setError(0, tmp.c_str()); + } + + fclose(file); + return return_value; +} + +bool +LocalConfig::readConnectString(const char * connectString, + const char * info){ + BaseString err; + bool return_value = parseString(connectString, err); + if (!return_value) { + BaseString err2; + err2.assfmt("Reading %d \"%s\": %s", info, connectString, err.c_str()); + setError(0,err2.c_str()); + } + return return_value; +} + +template class Vector<MgmtSrvrId>; |