LocalConfig.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "LocalConfig.hpp"
  14. #include <NdbEnv.h>
  15. #include <NdbConfig.h>
  16. #include <NdbAutoPtr.hpp>
  17. #include <NdbMem.h>
  18. LocalConfig::LocalConfig(){
  19.   error_line = 0; error_msg[0] = 0;
  20.   _ownNodeId= 0;
  21. }
  22. bool
  23. LocalConfig::init(const char *connectString,
  24.   const char *fileName) {
  25.   /** 
  26.    * Escalation:
  27.    *  1. Check connectString
  28.    *  2. Check given filename
  29.    *  3. Check environment variable NDB_CONNECTSTRING
  30.    *  4. Check Ndb.cfg in NDB_HOME
  31.    *  5. Check Ndb.cfg in cwd
  32.    *  6. Check defaultConnectString
  33.    */
  34.   
  35.   //1. Check connectString
  36.   if(connectString != 0 && connectString[0] != 0){
  37.     if(readConnectString(connectString, "connect string")){
  38.       return true;
  39.     }
  40.     return false;
  41.   }
  42.   //2. Check given filename
  43.   if (fileName && strlen(fileName) > 0) {
  44.     bool fopenError;
  45.     if(readFile(fileName, fopenError)){
  46.       return true;
  47.     }
  48.     return false;
  49.   }
  50.   //3. Check environment variable
  51.   char buf[255];  
  52.   if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) &&
  53.      strlen(buf) != 0){
  54.     if(readConnectString(buf, "NDB_CONNECTSTRING")){
  55.       return true;
  56.     }
  57.     return false;
  58.   }
  59.   
  60.   //4. Check Ndb.cfg in NDB_HOME
  61.   {
  62.     bool fopenError;
  63.     char *buf= NdbConfig_NdbCfgName(1 /*true*/);
  64.     NdbAutoPtr<char> tmp_aptr(buf);
  65.     if(readFile(buf, fopenError))
  66.       return true;
  67.     if (!fopenError)
  68.       return false;
  69.   }
  70.   //5. Check Ndb.cfg in cwd
  71.   {
  72.     bool fopenError;
  73.     char *buf= NdbConfig_NdbCfgName(0 /*false*/);
  74.     NdbAutoPtr<char> tmp_aptr(buf);
  75.     if(readFile(buf, fopenError))
  76.       return true;
  77.     if (!fopenError)
  78.       return false;
  79.   }
  80.   //7. Check
  81.   {
  82.     char buf[256];
  83.     BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_PORT);
  84.     if(readConnectString(buf, "default connect string"))
  85.       return true;
  86.   }
  87.   setError(0, "");
  88.   return false;
  89. }
  90. LocalConfig::~LocalConfig(){
  91. }
  92.   
  93. void LocalConfig::setError(int lineNumber, const char * _msg) {
  94.   error_line = lineNumber;
  95.   strncpy(error_msg, _msg, sizeof(error_msg));
  96. }
  97. void LocalConfig::printError() const {
  98.   ndbout << "Configuration error" << endl;
  99.   if (error_line)
  100.     ndbout << "Line: "<< error_line << ", ";
  101.   ndbout << error_msg << endl << endl;
  102. }
  103. void LocalConfig::printUsage() const {
  104.   ndbout << "This node needs information on how to connect"<<endl
  105.  << "to the NDB Management Server."<<endl
  106.  << "The information can be supplied in one of the following ways:"
  107.  << endl;
  108.     
  109.   ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl 
  110.  << "   the node. "<< endl
  111.  << "   Ex: Ndb.cfg" << endl
  112.  << "   | host=localhost:"<<NDB_PORT<<endl;
  113.     
  114.   ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl
  115.  << "   provide this information." <<endl
  116.  << "   Ex: " << endl
  117.  << "   >export NDB_CONNECTSTRING="host=localhost:"<<NDB_PORT<<"""
  118.  <<endl<<endl;
  119. }
  120.   
  121. const char *nodeIdTokens[] = {
  122.   "OwnProcessId %i",
  123.   "nodeid=%i",
  124.   0
  125. };
  126. const char *hostNameTokens[] = {
  127.   "host://%[^:]:%i",
  128.   "host=%[^:]:%i",
  129.   "%[^:^=^ ]:%i",
  130.   "%s %i",
  131.   0
  132. };
  133. const char *fileNameTokens[] = {
  134.   "file://%s",
  135.   "file=%s",
  136.   0
  137. };
  138. bool
  139. LocalConfig::parseNodeId(const char * buf){
  140.   for(int i = 0; nodeIdTokens[i] != 0; i++)
  141.     if (sscanf(buf, nodeIdTokens[i], &_ownNodeId) == 1)
  142.       return true;
  143.   return false;
  144. }
  145. bool
  146. LocalConfig::parseHostName(const char * buf){
  147.   char tempString[1024];
  148.   char tempString2[1024];
  149.   int port;
  150.   do {
  151.     for(int i = 0; hostNameTokens[i] != 0; i++) {
  152.       if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) {
  153. MgmtSrvrId mgmtSrvrId;
  154. mgmtSrvrId.type = MgmId_TCP;
  155. mgmtSrvrId.name.assign(tempString);
  156. mgmtSrvrId.port = port;
  157. ids.push_back(mgmtSrvrId);
  158. return true;
  159.       }
  160.     }
  161.     if (buf == tempString2)
  162.       break;
  163.     // try to add default port to see if it works
  164.     snprintf(tempString2, sizeof(tempString2),"%s:%s", buf, NDB_PORT);
  165.     buf= tempString2;
  166.   } while(1);
  167.   return false;
  168. }
  169. bool
  170. LocalConfig::parseFileName(const char * buf){
  171.   char tempString[1024];
  172.   for(int i = 0; fileNameTokens[i] != 0; i++) {
  173.     if (sscanf(buf, fileNameTokens[i], tempString) == 1) {
  174.       MgmtSrvrId mgmtSrvrId;
  175.       mgmtSrvrId.type = MgmId_File;
  176.       mgmtSrvrId.name.assign(tempString);
  177.       ids.push_back(mgmtSrvrId);
  178.       return true;
  179.     }
  180.   }
  181.   return false;
  182. }
  183. bool
  184. LocalConfig::parseString(const char * connectString, BaseString &err){
  185.   char * for_strtok;
  186.   char * copy = strdup(connectString);
  187.   NdbAutoPtr<char> tmp_aptr(copy);
  188.   bool b_nodeId = false;
  189.   bool found_other = false;
  190.   for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0;
  191.        tok = strtok_r(NULL, ";,", &for_strtok)) {
  192.     if (tok[0] == '#') continue;
  193.     if (!b_nodeId) // only one nodeid definition allowed
  194.       if (b_nodeId = parseNodeId(tok))
  195. continue;
  196.     if (found_other = parseHostName(tok))
  197.       continue;
  198.     if (found_other = parseFileName(tok))
  199.       continue;
  200.     
  201.     err.assfmt("Unexpected entry: "%s"", tok);
  202.     return false;
  203.   }
  204.   if (b_nodeId && !found_other) 
  205.   {
  206.     BaseString tmp;
  207.     tmp.assfmt("host=localhost:%s", NDB_PORT);
  208.     if(parseHostName(tmp.c_str()))
  209.       return true;
  210.     
  211.     err.appfmt("Missing host/file name extry in "%s"", connectString);
  212.     return false;
  213.   }
  214.   return true;
  215. }
  216. bool LocalConfig::readFile(const char * filename, bool &fopenError)
  217. {
  218.   char line[1024];
  219.   
  220.   fopenError = false;
  221.   
  222.   FILE * file = fopen(filename, "r");
  223.   if(file == 0){
  224.     BaseString::snprintf(line, sizeof(line),
  225.      "Unable to open local config file: %s", filename);
  226.     setError(0, line);
  227.     fopenError = true;
  228.     return false;
  229.   }
  230.   BaseString theString;
  231.   while(fgets(line, sizeof(line), file)){
  232.     BaseString tmp(line);
  233.     tmp.trim(" tnr");
  234.     if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
  235.       theString.append(tmp);
  236.       break;
  237.     }
  238.   }
  239.   while (fgets(line, sizeof(line), file)) {
  240.     BaseString tmp(line);
  241.     tmp.trim(" tnr");
  242.     if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
  243.       theString.append(";");
  244.       theString.append(tmp);
  245.     }
  246.   }
  247.   
  248.   BaseString err;
  249.   bool return_value = parseString(theString.c_str(), err);
  250.   if (!return_value) {
  251.     BaseString tmp;
  252.     tmp.assfmt("Reading %s: %s", filename, err.c_str());
  253.     setError(0, tmp.c_str());
  254.   }
  255.   fclose(file);
  256.   return return_value;
  257. }
  258. bool
  259. LocalConfig::readConnectString(const char * connectString,
  260.        const char * info){
  261.   BaseString err;
  262.   bool return_value = parseString(connectString, err);
  263.   if (!return_value) {
  264.     BaseString err2;
  265.     err2.assfmt("Reading %d "%s": %s", info, connectString, err.c_str());
  266.     setError(0,err2.c_str());
  267.   }
  268.   return return_value;
  269. }
  270. char *
  271. LocalConfig::makeConnectString(char *buf, int sz)
  272. {
  273.   int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
  274.   if (p < sz)
  275.     for (unsigned i = 0; i < ids.size(); i++)
  276.     {
  277.       if (ids[i].type != MgmId_TCP)
  278. continue;
  279.       int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d",
  280. ids[i].name.c_str(), ids[i].port);
  281.       if (new_p < sz)
  282. p= new_p;
  283.       else 
  284.       {
  285. buf[p]= 0;
  286. break;
  287.       }
  288.     }
  289.   buf[sz-1]=0;
  290.   return buf;
  291. }
  292. template class Vector<MgmtSrvrId>;