summaryrefslogtreecommitdiff
path: root/ndb/src/common/mgmcommon/LocalConfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/common/mgmcommon/LocalConfig.cpp')
-rw-r--r--ndb/src/common/mgmcommon/LocalConfig.cpp308
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;
+}