00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "LocalConfig.hpp"
00018 #include <NdbEnv.h>
00019 #include <NdbConfig.h>
00020 #include <NdbAutoPtr.hpp>
00021 #include <NdbMem.h>
00022
00023 LocalConfig::LocalConfig(){
00024 error_line = 0; error_msg[0] = 0;
00025 _ownNodeId= 0;
00026 }
00027
00028 bool
00029 LocalConfig::init(const char *connectString,
00030 const char *fileName)
00031 {
00032 DBUG_ENTER("LocalConfig::init");
00043 _ownNodeId= 0;
00044
00045
00046 if(connectString != 0 && connectString[0] != 0){
00047 if(readConnectString(connectString, "connect string")){
00048 if (ids.size())
00049 DBUG_RETURN(true);
00050
00051 } else
00052 DBUG_RETURN(false);
00053 }
00054
00055
00056 if (fileName && strlen(fileName) > 0) {
00057 bool fopenError;
00058 if(readFile(fileName, fopenError)){
00059 DBUG_RETURN(true);
00060 }
00061 DBUG_RETURN(false);
00062 }
00063
00064
00065 char buf[255];
00066 if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) &&
00067 strlen(buf) != 0){
00068 if(readConnectString(buf, "NDB_CONNECTSTRING")){
00069 DBUG_RETURN(true);
00070 }
00071 DBUG_RETURN(false);
00072 }
00073
00074
00075 {
00076 bool fopenError;
00077 char *buf= NdbConfig_NdbCfgName(1 );
00078 NdbAutoPtr<char> tmp_aptr(buf);
00079 if(readFile(buf, fopenError))
00080 DBUG_RETURN(true);
00081 if (!fopenError)
00082 DBUG_RETURN(false);
00083 }
00084
00085
00086 {
00087 bool fopenError;
00088 char *buf= NdbConfig_NdbCfgName(0 );
00089 NdbAutoPtr<char> tmp_aptr(buf);
00090 if(readFile(buf, fopenError))
00091 DBUG_RETURN(true);
00092 if (!fopenError)
00093 DBUG_RETURN(false);
00094 }
00095
00096
00097 {
00098 char buf[256];
00099 BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_PORT);
00100 if(readConnectString(buf, "default connect string"))
00101 DBUG_RETURN(true);
00102 }
00103
00104 setError(0, "");
00105
00106 DBUG_RETURN(false);
00107 }
00108
00109 LocalConfig::~LocalConfig(){
00110 }
00111
00112 void LocalConfig::setError(int lineNumber, const char * _msg) {
00113 error_line = lineNumber;
00114 strncpy(error_msg, _msg, sizeof(error_msg));
00115 }
00116
00117 void LocalConfig::printError() const {
00118 ndbout << "Configuration error" << endl;
00119 if (error_line)
00120 ndbout << "Line: "<< error_line << ", ";
00121 ndbout << error_msg << endl << endl;
00122 }
00123
00124 void LocalConfig::printUsage() const {
00125 ndbout << "This node needs information on how to connect"<<endl
00126 << "to the NDB Management Server."<<endl
00127 << "The information can be supplied in one of the following ways:"
00128 << endl;
00129
00130 ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl
00131 << " the node. "<< endl
00132 << " Ex: Ndb.cfg" << endl
00133 << " | host=localhost:"<<NDB_PORT<<endl;
00134
00135 ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl
00136 << " provide this information." <<endl
00137 << " Ex: " << endl
00138 << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_PORT<<"\""
00139 <<endl<<endl;
00140 }
00141
00142 const char *nodeIdTokens[] = {
00143 "OwnProcessId %i",
00144 "nodeid=%i",
00145 0
00146 };
00147
00148 const char *hostNameTokens[] = {
00149 "host://%[^:]:%i",
00150 "host=%[^:]:%i",
00151 "mgmd=%[^:]:%i",
00152 "%[^:^=^ ]:%i",
00153 "%s %i",
00154 0
00155 };
00156
00157 const char *fileNameTokens[] = {
00158 "file://%s",
00159 "file=%s",
00160 0
00161 };
00162
00163 bool
00164 LocalConfig::parseNodeId(const char * buf){
00165 for(int i = 0; nodeIdTokens[i] != 0; i++)
00166 if (sscanf(buf, nodeIdTokens[i], &_ownNodeId) == 1)
00167 return true;
00168 return false;
00169 }
00170
00171 bool
00172 LocalConfig::parseHostName(const char * buf){
00173 char tempString[1024];
00174 char tempString2[1024];
00175 int port;
00176 do {
00177 for(int i = 0; hostNameTokens[i] != 0; i++) {
00178 if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) {
00179 MgmtSrvrId mgmtSrvrId;
00180 mgmtSrvrId.type = MgmId_TCP;
00181 mgmtSrvrId.name.assign(tempString);
00182 mgmtSrvrId.port = port;
00183 ids.push_back(mgmtSrvrId);
00184 return true;
00185 }
00186 }
00187 if (buf == tempString2)
00188 break;
00189
00190 snprintf(tempString2, sizeof(tempString2),"%s:%s", buf, NDB_PORT);
00191 buf= tempString2;
00192 } while(1);
00193 return false;
00194 }
00195
00196 bool
00197 LocalConfig::parseFileName(const char * buf){
00198 char tempString[1024];
00199 for(int i = 0; fileNameTokens[i] != 0; i++) {
00200 if (sscanf(buf, fileNameTokens[i], tempString) == 1) {
00201 MgmtSrvrId mgmtSrvrId;
00202 mgmtSrvrId.type = MgmId_File;
00203 mgmtSrvrId.name.assign(tempString);
00204 ids.push_back(mgmtSrvrId);
00205 return true;
00206 }
00207 }
00208 return false;
00209 }
00210
00211 bool
00212 LocalConfig::parseString(const char * connectString, BaseString &err){
00213 char * for_strtok;
00214 char * copy = strdup(connectString);
00215 NdbAutoPtr<char> tmp_aptr(copy);
00216
00217 for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0;
00218 tok = strtok_r(NULL, ";,", &for_strtok)) {
00219 if (tok[0] == '#') continue;
00220
00221 if (!_ownNodeId)
00222 if (parseNodeId(tok))
00223 continue;
00224 if (parseHostName(tok))
00225 continue;
00226 if (parseFileName(tok))
00227 continue;
00228
00229 err.assfmt("Unexpected entry: \"%s\"", tok);
00230 return false;
00231 }
00232
00233 return true;
00234 }
00235
00236 bool LocalConfig::readFile(const char * filename, bool &fopenError)
00237 {
00238 char line[1024];
00239
00240 fopenError = false;
00241
00242 FILE * file = fopen(filename, "r");
00243 if(file == 0){
00244 BaseString::snprintf(line, sizeof(line),
00245 "Unable to open local config file: %s", filename);
00246 setError(0, line);
00247 fopenError = true;
00248 return false;
00249 }
00250
00251 BaseString theString;
00252
00253 while(fgets(line, sizeof(line), file)){
00254 BaseString tmp(line);
00255 tmp.trim(" \t\n\r");
00256 if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
00257 theString.append(tmp);
00258 break;
00259 }
00260 }
00261 while (fgets(line, sizeof(line), file)) {
00262 BaseString tmp(line);
00263 tmp.trim(" \t\n\r");
00264 if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
00265 theString.append(";");
00266 theString.append(tmp);
00267 }
00268 }
00269
00270 BaseString err;
00271 bool return_value = parseString(theString.c_str(), err);
00272
00273 if (!return_value) {
00274 BaseString tmp;
00275 tmp.assfmt("Reading %s: %s", filename, err.c_str());
00276 setError(0, tmp.c_str());
00277 }
00278
00279 fclose(file);
00280 return return_value;
00281 }
00282
00283 bool
00284 LocalConfig::readConnectString(const char * connectString,
00285 const char * info){
00286 BaseString err;
00287 bool return_value = parseString(connectString, err);
00288 if (!return_value) {
00289 BaseString err2;
00290 err2.assfmt("Reading %d \"%s\": %s", info, connectString, err.c_str());
00291 setError(0,err2.c_str());
00292 }
00293 return return_value;
00294 }
00295
00296 char *
00297 LocalConfig::makeConnectString(char *buf, int sz)
00298 {
00299 int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
00300 if (p < sz)
00301 for (unsigned i = 0; i < ids.size(); i++)
00302 {
00303 if (ids[i].type != MgmId_TCP)
00304 continue;
00305 int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d",
00306 ids[i].name.c_str(), ids[i].port);
00307 if (new_p < sz)
00308 p= new_p;
00309 else
00310 {
00311 buf[p]= 0;
00312 break;
00313 }
00314 }
00315 buf[sz-1]=0;
00316 return buf;
00317 }
00318
00319 template class Vector<MgmtSrvrId>;