diff options
Diffstat (limited to 'ndb/src/common/mgmcommon/LocalConfig.cpp')
-rw-r--r-- | ndb/src/common/mgmcommon/LocalConfig.cpp | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/ndb/src/common/mgmcommon/LocalConfig.cpp b/ndb/src/common/mgmcommon/LocalConfig.cpp new file mode 100644 index 00000000000..12e685ced34 --- /dev/null +++ b/ndb/src/common/mgmcommon/LocalConfig.cpp @@ -0,0 +1,308 @@ +/* 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> + +LocalConfig::LocalConfig(){ + ids = 0; size = 0; items = 0; + error_line = 0; error_msg[0] = 0; +} + +bool +LocalConfig::init(bool onlyNodeId, + const char *connectString, + const char *fileName, + const char *defaultConnectString) { + /** + * 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) { + if(readConnectString(connectString, onlyNodeId)){ + return true; + } + return false; + } + + //2. Check given filename + if (fileName && strlen(fileName) > 0) { + bool fopenError; + if(readFile(fileName, fopenError, onlyNodeId)){ + 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, onlyNodeId)){ + return true; + } + return false; + } + + //4. Check Ndb.cfg in NDB_HOME + { + bool fopenError; + char buf[256]; + if(readFile(NdbConfig_NdbCfgName(buf, sizeof(buf), 1 /*true*/), fopenError, onlyNodeId)){ + return true; + } + if (!fopenError) + return false; + } + + //5. Check Ndb.cfg in cwd + { + bool fopenError; + char buf[256]; + if(readFile(NdbConfig_NdbCfgName(buf, sizeof(buf), 0 /*false*/), fopenError, onlyNodeId)){ + return true; + } + if (!fopenError) + return false; + } + + //6. Check defaultConnectString + if(defaultConnectString != 0) { + if(readConnectString(defaultConnectString, onlyNodeId)){ + return true; + } + return false; + } + + setError(0, ""); + + return false; +} + +LocalConfig::~LocalConfig(){ + for(int i = 0; i<items; i++){ + if(ids[i]->type == MgmId_TCP) + free(ids[i]->data.tcp.remoteHost); + else if(ids[i]->type == MgmId_File) + free(ids[i]->data.file.filename); + delete ids[i]; + } + if(ids != 0) + delete[] ids; +} + +void LocalConfig::add(MgmtSrvrId * i){ + if(items == size){ + MgmtSrvrId ** tmp = new MgmtSrvrId * [size+10]; + if(ids != 0){ + memcpy(tmp, ids, items*sizeof(MgmtSrvrId *)); + delete []ids; + } + ids = tmp; + } + ids[items] = i; + items++; +} + +void LocalConfig::setError(int lineNumber, const char * _msg) { + error_line = lineNumber; + strncpy(error_msg, _msg, sizeof(error_msg)); +} + +void LocalConfig::printError() const { + ndbout << "Local configuration error"<< endl + << "Line: "<< error_line << ", " << 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 + << " | nodeid=11;host=localhost:2200"<<endl<<endl; + + ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl + << " provide this information." <<endl + << " Ex: " << endl + << " >export NDB_CONNECTSTRING=\"nodeid=11;host=localhost:2200\"" + <<endl<<endl; +} + +char *nodeIdTokens[] = { + "OwnProcessId %i", + "nodeid=%i", + 0 +}; + +char *hostNameTokens[] = { + "host://%[^:]:%i", + "host=%[^:]:%i", + "%[^:]:%i", + "%s %i", + 0 +}; + +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[100]; + int port; + for(int i = 0; hostNameTokens[i] != 0; i++) { + if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) { + MgmtSrvrId* mgmtSrvrId = new MgmtSrvrId(); + mgmtSrvrId->type = MgmId_TCP; + mgmtSrvrId->data.tcp.remoteHost = strdup(tempString); + mgmtSrvrId->data.tcp.port = port; + add(mgmtSrvrId); + return true; + } + } + return false; +} + +bool +LocalConfig::parseFileName(const char * buf){ + char tempString[100]; + for(int i = 0; fileNameTokens[i] != 0; i++) { + if (sscanf(buf, fileNameTokens[i], tempString) == 1) { + MgmtSrvrId* mgmtSrvrId = new MgmtSrvrId(); + mgmtSrvrId->type = MgmId_File; + mgmtSrvrId->data.file.filename = strdup(tempString); + add(mgmtSrvrId); + return true; + } + } + return false; +} + +bool +LocalConfig::parseString(const char * connectString, bool onlyNodeId, char *line){ + bool return_value = true; + + char * for_strtok; + char * copy = strdup(connectString); + + bool b_nodeId = false; + bool found_other = false; + + for (char *tok = strtok_r(copy,";",&for_strtok); + tok != 0 && !(onlyNodeId && b_nodeId); + 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 (onlyNodeId) + continue; + if (found_other = parseHostName(tok)) + continue; + if (found_other = parseFileName(tok)) + continue; + + snprintf(line, 150, "Unexpected entry: \"%s\"", tok); + return_value = false; + break; + } + + if (return_value && !onlyNodeId && !found_other) { + return_value = false; + snprintf(line, 150, "Missing host/file name extry in \"%s\"", connectString); + } + + free(copy); + return return_value; +} + +bool LocalConfig::readFile(const char * filename, bool &fopenError, bool onlyNodeId) +{ + char line[150], line2[150]; + + fopenError = false; + + FILE * file = fopen(filename, "r"); + if(file == 0){ + snprintf(line, 150, "Unable to open local config file: %s", filename); + setError(0, line); + fopenError = true; + return false; + } + + int sz = 1024; + char* theString = (char*)malloc(sz); + theString[0] = 0; + + fgets(theString, sz, file); + while (fgets(line+1, 100, file)) { + line[0] = ';'; + while (strlen(theString) + strlen(line) >= sz) { + sz = sz*2; + char *newString = (char*)malloc(sz); + strcpy(newString, theString); + free(theString); + theString = newString; + } + strcat(theString, line); + } + + bool return_value = parseString(theString, onlyNodeId, line); + + if (!return_value) { + snprintf(line2, 150, "Reading %s: %s", filename, line); + setError(0,line2); + } + + free(theString); + fclose(file); + return return_value; +} + +bool +LocalConfig::readConnectString(const char * connectString, bool onlyNodeId){ + char line[150], line2[150]; + bool return_value = parseString(connectString, onlyNodeId, line); + if (!return_value) { + snprintf(line2, 150, "Reading NDB_CONNECTSTRING \"%s\": %s", connectString, line); + setError(0,line2); + } + return return_value; +} |