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.
 
   7  *    This program is distributed in the hope that it will be useful,
 
   8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  10  *    GNU General Public License for more details.
 
  12  *    You should have received a copy of the GNU General Public License
 
  13  *    along with this program; if not, write to the Free Software
 
  14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
  22  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
 
  27 $Date: 2010/08/19 13:42:30 $
 
  35 #include "settings_impl.h"
 
  36 #include "stg_logger.h"
 
  37 #include "dotconfpp.h"
 
  41 //-----------------------------------------------------------------------------
 
  42 SETTINGS_IMPL::SETTINGS_IMPL()
 
  43     : confDir("/etc/stargazer"),
 
  44       scriptsDir("/etc/stargazer"),
 
  45       pidFile("/var/run/stargazer.pid"),
 
  47       detailStatWritePeriod(dsPeriod_1_6),
 
  55       freeMbAllowInet(false),
 
  56       dayFeeIsLastDay(false),
 
  57       writeFreeMbTraffCost(false),
 
  60       logger(GetStgLogger())
 
  63 //-----------------------------------------------------------------------------
 
  64 SETTINGS_IMPL::SETTINGS_IMPL(const std::string & cd)
 
  68       detailStatWritePeriod(dsPeriod_1_6),
 
  76       freeMbAllowInet(false),
 
  77       dayFeeIsLastDay(false),
 
  78       writeFreeMbTraffCost(false),
 
  81       logger(GetStgLogger())
 
  84 //-----------------------------------------------------------------------------
 
  85 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
 
  86     : confDir(rval.confDir),
 
  87       scriptsDir(rval.scriptsDir),
 
  88       pidFile(rval.pidFile),
 
  89       monitoring(rval.monitoring),
 
  90       detailStatWritePeriod(dsPeriod_1_6),
 
  92       stgExecMsgKey(rval.stgExecMsgKey),
 
  93       executersNum(rval.executersNum),
 
  94       fullFee(rval.fullFee),
 
  97       spreadFee(rval.spreadFee),
 
  98       freeMbAllowInet(false),
 
  99       dayFeeIsLastDay(false),
 
 100       writeFreeMbTraffCost(false),
 
 101       showFeeInCash(rval.showFeeInCash),
 
 102       messageTimeout(rval.messageTimeout),
 
 103       logger(GetStgLogger())
 
 106 //-----------------------------------------------------------------------------
 
 107 int SETTINGS_IMPL::ParseYesNo(const string & value, bool * val)
 
 109 if (0 == strcasecmp(value.c_str(), "yes"))
 
 114 if (0 == strcasecmp(value.c_str(), "no"))
 
 120 strError = "Incorrect value \'" + value + "\'.";
 
 123 //-----------------------------------------------------------------------------
 
 124 int SETTINGS_IMPL::ParseInt(const string & value, int * val)
 
 126 if (str2x<int>(value, *val))
 
 128     strError = "Cannot convert \'" + value + "\' to integer.";
 
 133 //-----------------------------------------------------------------------------
 
 134 int SETTINGS_IMPL::ParseUnsigned(const string & value, unsigned * val)
 
 136 if (str2x<unsigned>(value, *val))
 
 138     strError = "Cannot convert \'" + value + "\' to unsigned integer.";
 
 143 //-----------------------------------------------------------------------------
 
 144 int SETTINGS_IMPL::ParseIntInRange(const string & value, int min, int max, int * val)
 
 146 if (ParseInt(value, val) != 0)
 
 149 if (*val < min || *val > max)
 
 151     strError = "Value \'" + value + "\' out of range.";
 
 157 //-----------------------------------------------------------------------------
 
 158 int SETTINGS_IMPL::ParseUnsignedInRange(const string & value, unsigned min, unsigned max, unsigned * val)
 
 160 if (ParseUnsigned(value, val) != 0)
 
 163 if (*val < min || *val > max)
 
 165     strError = "Value \'" + value + "\' out of range.";
 
 171 //-----------------------------------------------------------------------------
 
 172 int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, vector<PARAM_VALUE> * params)
 
 174 const DOTCONFDocumentNode * childNode;
 
 178 pv.param = node->getName();
 
 180 if (node->getValue(1))
 
 182     strError = "Unexpected value \'" + string(node->getValue(1)) + "\'.";
 
 186 value = node->getValue(0);
 
 190     strError = "Module name expected.";
 
 194 childNode = node->getChildNode();
 
 197     pv.param = childNode->getName();
 
 199     while ((value = childNode->getValue(i++)) != NULL)
 
 201         pv.value.push_back(value);
 
 203     params->push_back(pv);
 
 205     childNode = childNode->getNextNode();
 
 210 //-----------------------------------------------------------------------------
 
 211 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
 
 213     printfd(__FILE__, buf);
 
 214     SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
 
 215     settings->logger(buf);
 
 217 //-----------------------------------------------------------------------------
 
 218 int SETTINGS_IMPL::ReadSettings()
 
 220 const char * requiredOptions[] = {
 
 226     "DetailStatWritePeriod",
 
 232     "WriteFreeMbTraffCost",
 
 235 int storeModulesCount = 0;
 
 236 modulesSettings.clear();
 
 238 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
 
 239 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
 
 240 conf.setRequiredOptionNames(requiredOptions);
 
 241 string confFile = confDir + "/stargazer.conf";
 
 243 if(conf.setContent(confFile.c_str()) != 0)
 
 245     strError = "Cannot read file " + confFile;
 
 249 const DOTCONFDocumentNode * node = conf.getFirstNode();
 
 253     if (strcasecmp(node->getName(), "ScriptDir") == 0)
 
 255         scriptsDir = node->getValue(0);
 
 258     if (strcasecmp(node->getName(), "LogFile") == 0)
 
 260         logFile = node->getValue(0);
 
 263     if (strcasecmp(node->getName(), "PIDFile") == 0)
 
 265         pidFile = node->getValue(0);
 
 268     if (strcasecmp(node->getName(), "ModulesPath") == 0)
 
 270         modulesPath = node->getValue(0);
 
 273     if (strcasecmp(node->getName(), "Rules") == 0)
 
 275         rules = node->getValue(0);
 
 278     if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
 
 280         if (ParseDetailStatWritePeriod(node->getValue(0)) != 0)
 
 282             strError = "Incorrect DetailStatWritePeriod value: \'" + string(node->getValue(0)) + "\'";
 
 287     if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
 
 289         if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
 
 291             strError = "Incorrect StatWritePeriod value: \'" + string(node->getValue(0)) + "\'";
 
 296     if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
 
 298         if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
 
 300             strError = "Incorrect ExecMsgKey value: \'" + string(node->getValue(0)) + "\'";
 
 305     if (strcasecmp(node->getName(), "ExecutersNum") == 0)
 
 307         if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
 
 309             strError = "Incorrect ExecutersNum value: \'" + string(node->getValue(0)) + "\'";
 
 314     if (strcasecmp(node->getName(), "DayFee") == 0)
 
 316         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
 
 318             strError = "Incorrect DayFee value: \'" + string(node->getValue(0)) + "\'";
 
 323     if (strcasecmp(node->getName(), "FullFee") == 0)
 
 325         if (ParseYesNo(node->getValue(0), &fullFee) != 0)
 
 327             strError = "Incorrect FullFee value: \'" + string(node->getValue(0)) + "\'";
 
 332     if (strcasecmp(node->getName(), "DayResetTraff") == 0)
 
 334         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
 
 336             strError = "Incorrect DayResetTraff value: \'" + string(node->getValue(0)) + "\'";
 
 341     if (strcasecmp(node->getName(), "SpreadFee") == 0)
 
 343         if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
 
 345             strError = "Incorrect SpreadFee value: \'" + string(node->getValue(0)) + "\'";
 
 350     if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
 
 352         if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
 
 354             strError = "Incorrect FreeMbAllowInet value: \'" + string(node->getValue(0)) + "\'";
 
 359     if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
 
 361         if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
 
 363             strError = "Incorrect DayFeeIsLastDay value: \'" + string(node->getValue(0)) + "\'";
 
 368     if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
 
 370         if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
 
 372             strError = "Incorrect WriteFreeMbTraffCost value: \'" + string(node->getValue(0)) + "\'";
 
 377     if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
 
 379         if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
 
 381             strError = "Incorrect ShowFeeInCash value: \'" + string(node->getValue(0)) + "\'";
 
 386     if (strcasecmp(node->getName(), "MonitorDir") == 0)
 
 388         monitorDir = node->getValue(0);
 
 392         if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
 
 398     if (strcasecmp(node->getName(), "MessageTimeout") == 0)
 
 400         if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
 
 402             strError = "Incorrect MessageTimeout value: \'" + string(node->getValue(0)) + "\'";
 
 407     if (strcasecmp(node->getName(), "DirNames") == 0)
 
 409         const DOTCONFDocumentNode * child = node->getChildNode();
 
 412             const DOTCONFDocumentNode * dirNameNode;
 
 413             for (int i = 0; i < DIR_NUM; i++)
 
 416                 sprintf(strDirName, "DirName%d", i);
 
 417                 dirNameNode = conf.findNode(strDirName, node);
 
 418                 if (dirNameNode && dirNameNode->getValue(0))
 
 420                     dirName[i] = dirNameNode->getValue(0);
 
 426     if (strcasecmp(node->getName(), "StoreModule") == 0)
 
 428         if (node->getValue(1))
 
 430             strError = "Unexpected \'" + string(node->getValue(1)) + "\'.";
 
 434         if (storeModulesCount)
 
 436             strError = "Should be only one StoreModule.";
 
 441         storeModuleSettings.moduleName = node->getValue(0);
 
 442         ParseModuleSettings(node, &storeModuleSettings.moduleParams);
 
 445     if (strcasecmp(node->getName(), "Modules") == 0)
 
 447         if (node->getValue(0))
 
 449             strError = "Unexpected \'" + string(node->getValue(0)) + "\'.";
 
 452         const DOTCONFDocumentNode * child = node->getChildNode();
 
 455             if (strcasecmp(child->getName(), "Module") != 0)
 
 457                 child = child->getNextNode();
 
 460             MODULE_SETTINGS modSettings;
 
 461             modSettings.moduleParams.clear();
 
 462             modSettings.moduleName = child->getValue();
 
 464             ParseModuleSettings(child, &modSettings.moduleParams);
 
 466             modulesSettings.push_back(modSettings);
 
 468             child = child->getNextNode();
 
 472     node = node->getNextNode();
 
 477 //-----------------------------------------------------------------------------
 
 478 int SETTINGS_IMPL::ParseDetailStatWritePeriod(const string & detailStatPeriodStr)
 
 480 if (detailStatPeriodStr == "1")
 
 482     detailStatWritePeriod = dsPeriod_1;
 
 485 else if (detailStatPeriodStr == "1/2")
 
 487     detailStatWritePeriod = dsPeriod_1_2;
 
 490 else if (detailStatPeriodStr == "1/4")
 
 492     detailStatWritePeriod = dsPeriod_1_4;
 
 495 else if (detailStatPeriodStr == "1/6")
 
 497     detailStatWritePeriod = dsPeriod_1_6;
 
 503 //-----------------------------------------------------------------------------