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 "stg/logger.h"
 
  36 #include "stg/dotconfpp.h"
 
  37 #include "settings_impl.h"
 
  41 //-----------------------------------------------------------------------------
 
  42 SETTINGS_IMPL::SETTINGS_IMPL()
 
  44       modulesPath("/usr/lib/stg"),
 
  46       confDir("/etc/stargazer"),
 
  47       scriptsDir("/etc/stargazer"),
 
  48       rules("/etc/stargazer/rules"),
 
  49       logFile("/var/log/stargazer.log"),
 
  50       pidFile("/var/run/stargazer.pid"),
 
  51       monitorDir("/var/stargazer/monitoring"),
 
  53       detailStatWritePeriod(dsPeriod_1_6),
 
  61       freeMbAllowInet(false),
 
  62       dayFeeIsLastDay(false),
 
  63       writeFreeMbTraffCost(false),
 
  68       storeModuleSettings(),
 
  69       logger(GetStgLogger())
 
  72 //-----------------------------------------------------------------------------
 
  73 SETTINGS_IMPL::SETTINGS_IMPL(const std::string & cd)
 
  75       modulesPath("/usr/lib/stg"),
 
  80       logFile("/var/log/stargazer.log"),
 
  81       pidFile("/var/run/stargazer.pid"),
 
  82       monitorDir("/var/stargazer/monitoring"),
 
  84       detailStatWritePeriod(dsPeriod_1_6),
 
  92       freeMbAllowInet(false),
 
  93       dayFeeIsLastDay(false),
 
  94       writeFreeMbTraffCost(false),
 
  99       storeModuleSettings(),
 
 100       logger(GetStgLogger())
 
 103 //-----------------------------------------------------------------------------
 
 104 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
 
 106       modulesPath(rval.modulesPath),
 
 107       dirName(rval.dirName),
 
 108       confDir(rval.confDir),
 
 109       scriptsDir(rval.scriptsDir),
 
 111       logFile(rval.logFile),
 
 112       pidFile(rval.pidFile),
 
 113       monitorDir(rval.monitorDir),
 
 114       monitoring(rval.monitoring),
 
 115       detailStatWritePeriod(rval.detailStatWritePeriod),
 
 116       statWritePeriod(rval.statWritePeriod),
 
 117       stgExecMsgKey(rval.stgExecMsgKey),
 
 118       executersNum(rval.executersNum),
 
 119       fullFee(rval.fullFee),
 
 121       dayResetTraff(rval.dayResetTraff),
 
 122       spreadFee(rval.spreadFee),
 
 123       freeMbAllowInet(rval.freeMbAllowInet),
 
 124       dayFeeIsLastDay(rval.dayFeeIsLastDay),
 
 125       writeFreeMbTraffCost(rval.writeFreeMbTraffCost),
 
 126       showFeeInCash(rval.showFeeInCash),
 
 127       messageTimeout(rval.messageTimeout),
 
 128       feeChargeType(rval.feeChargeType),
 
 129       modulesSettings(rval.modulesSettings),
 
 130       storeModuleSettings(rval.storeModuleSettings),
 
 131       logger(GetStgLogger())
 
 134 //-----------------------------------------------------------------------------
 
 135 int SETTINGS_IMPL::ParseYesNo(const string & value, bool * val)
 
 137 if (0 == strcasecmp(value.c_str(), "yes"))
 
 142 if (0 == strcasecmp(value.c_str(), "no"))
 
 148 strError = "Incorrect value \'" + value + "\'.";
 
 151 //-----------------------------------------------------------------------------
 
 152 int SETTINGS_IMPL::ParseInt(const string & value, int * val)
 
 154 if (str2x<int>(value, *val))
 
 156     strError = "Cannot convert \'" + value + "\' to integer.";
 
 161 //-----------------------------------------------------------------------------
 
 162 int SETTINGS_IMPL::ParseUnsigned(const string & value, unsigned * val)
 
 164 if (str2x<unsigned>(value, *val))
 
 166     strError = "Cannot convert \'" + value + "\' to unsigned integer.";
 
 171 //-----------------------------------------------------------------------------
 
 172 int SETTINGS_IMPL::ParseIntInRange(const string & value, int min, int max, int * val)
 
 174 if (ParseInt(value, val) != 0)
 
 177 if (*val < min || *val > max)
 
 179     strError = "Value \'" + value + "\' out of range.";
 
 185 //-----------------------------------------------------------------------------
 
 186 int SETTINGS_IMPL::ParseUnsignedInRange(const string & value, unsigned min, unsigned max, unsigned * val)
 
 188 if (ParseUnsigned(value, val) != 0)
 
 191 if (*val < min || *val > max)
 
 193     strError = "Value \'" + value + "\' out of range.";
 
 199 //-----------------------------------------------------------------------------
 
 200 int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, vector<PARAM_VALUE> * params)
 
 202 const DOTCONFDocumentNode * childNode;
 
 206 pv.param = node->getName();
 
 208 if (node->getValue(1))
 
 210     strError = "Unexpected value \'" + string(node->getValue(1)) + "\'.";
 
 214 value = node->getValue(0);
 
 218     strError = "Module name expected.";
 
 222 childNode = node->getChildNode();
 
 225     pv.param = childNode->getName();
 
 227     while ((value = childNode->getValue(i++)) != NULL)
 
 229         pv.value.push_back(value);
 
 231     params->push_back(pv);
 
 233     childNode = childNode->getNextNode();
 
 238 //-----------------------------------------------------------------------------
 
 239 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
 
 241     printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
 
 242     SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
 
 243     settings->logger("%s", buf);
 
 245 //-----------------------------------------------------------------------------
 
 246 int SETTINGS_IMPL::ReadSettings()
 
 248 const char * requiredOptions[] = {
 
 254     "DetailStatWritePeriod",
 
 260     "WriteFreeMbTraffCost",
 
 263 int storeModulesCount = 0;
 
 264 modulesSettings.clear();
 
 266 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
 
 267 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
 
 268 conf.setRequiredOptionNames(requiredOptions);
 
 269 string confFile = confDir + "/stargazer.conf";
 
 271 if(conf.setContent(confFile.c_str()) != 0)
 
 273     strError = "Cannot read file " + confFile;
 
 277 const DOTCONFDocumentNode * node = conf.getFirstNode();
 
 281     if (strcasecmp(node->getName(), "ScriptDir") == 0)
 
 283         scriptsDir = node->getValue(0);
 
 286     if (strcasecmp(node->getName(), "LogFile") == 0)
 
 288         logFile = node->getValue(0);
 
 291     if (strcasecmp(node->getName(), "PIDFile") == 0)
 
 293         pidFile = node->getValue(0);
 
 296     if (strcasecmp(node->getName(), "ModulesPath") == 0)
 
 298         modulesPath = node->getValue(0);
 
 301     if (strcasecmp(node->getName(), "Rules") == 0)
 
 303         rules = node->getValue(0);
 
 306     if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
 
 308         if (ParseDetailStatWritePeriod(node->getValue(0)) != 0)
 
 310             strError = "Incorrect DetailStatWritePeriod value: \'" + string(node->getValue(0)) + "\'";
 
 315     if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
 
 317         if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
 
 319             strError = "Incorrect StatWritePeriod value: \'" + string(node->getValue(0)) + "\'";
 
 324     if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
 
 326         if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
 
 328             strError = "Incorrect ExecMsgKey value: \'" + string(node->getValue(0)) + "\'";
 
 333     if (strcasecmp(node->getName(), "ExecutersNum") == 0)
 
 335         if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
 
 337             strError = "Incorrect ExecutersNum value: \'" + string(node->getValue(0)) + "\'";
 
 342     if (strcasecmp(node->getName(), "DayFee") == 0)
 
 344         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
 
 346             strError = "Incorrect DayFee value: \'" + string(node->getValue(0)) + "\'";
 
 351     if (strcasecmp(node->getName(), "FullFee") == 0)
 
 353         if (ParseYesNo(node->getValue(0), &fullFee) != 0)
 
 355             strError = "Incorrect FullFee value: \'" + string(node->getValue(0)) + "\'";
 
 360     if (strcasecmp(node->getName(), "DayResetTraff") == 0)
 
 362         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
 
 364             strError = "Incorrect DayResetTraff value: \'" + string(node->getValue(0)) + "\'";
 
 369     if (strcasecmp(node->getName(), "SpreadFee") == 0)
 
 371         if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
 
 373             strError = "Incorrect SpreadFee value: \'" + string(node->getValue(0)) + "\'";
 
 378     if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
 
 380         if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
 
 382             strError = "Incorrect FreeMbAllowInet value: \'" + string(node->getValue(0)) + "\'";
 
 387     if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
 
 389         if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
 
 391             strError = "Incorrect DayFeeIsLastDay value: \'" + string(node->getValue(0)) + "\'";
 
 396     if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
 
 398         if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
 
 400             strError = "Incorrect WriteFreeMbTraffCost value: \'" + string(node->getValue(0)) + "\'";
 
 405     if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
 
 407         if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
 
 409             strError = "Incorrect ShowFeeInCash value: \'" + string(node->getValue(0)) + "\'";
 
 414     if (strcasecmp(node->getName(), "MonitorDir") == 0)
 
 416         monitorDir = node->getValue(0);
 
 420         if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
 
 426     if (strcasecmp(node->getName(), "MessageTimeout") == 0)
 
 428         if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
 
 430             strError = "Incorrect MessageTimeout value: \'" + string(node->getValue(0)) + "\'";
 
 435     if (strcasecmp(node->getName(), "FeeChargeType") == 0)
 
 437         if (ParseUnsignedInRange(node->getValue(0), 0, 2, &feeChargeType) != 0)
 
 439             strError = "Incorrect FeeChargeType value: \'" + string(node->getValue(0)) + "\'";
 
 444     if (strcasecmp(node->getName(), "DirNames") == 0)
 
 446         const DOTCONFDocumentNode * child = node->getChildNode();
 
 449             const DOTCONFDocumentNode * dirNameNode;
 
 450             dirName.reserve(DIR_NUM);
 
 451             for (int i = 0; i < DIR_NUM; i++)
 
 454                 sprintf(strDirName, "DirName%d", i);
 
 455                 dirNameNode = conf.findNode(strDirName, node);
 
 456                 if (dirNameNode && dirNameNode->getValue(0))
 
 458                     dirName[i] = dirNameNode->getValue(0);
 
 464     if (strcasecmp(node->getName(), "StoreModule") == 0)
 
 466         if (node->getValue(1))
 
 468             strError = "Unexpected \'" + string(node->getValue(1)) + "\'.";
 
 472         if (storeModulesCount)
 
 474             strError = "Should be only one StoreModule.";
 
 479         storeModuleSettings.moduleName = node->getValue(0);
 
 480         ParseModuleSettings(node, &storeModuleSettings.moduleParams);
 
 483     if (strcasecmp(node->getName(), "Modules") == 0)
 
 485         if (node->getValue(0))
 
 487             strError = "Unexpected \'" + string(node->getValue(0)) + "\'.";
 
 490         const DOTCONFDocumentNode * child = node->getChildNode();
 
 493             if (strcasecmp(child->getName(), "Module") != 0)
 
 495                 child = child->getNextNode();
 
 498             MODULE_SETTINGS modSettings;
 
 499             modSettings.moduleParams.clear();
 
 500             modSettings.moduleName = child->getValue();
 
 502             ParseModuleSettings(child, &modSettings.moduleParams);
 
 504             modulesSettings.push_back(modSettings);
 
 506             child = child->getNextNode();
 
 510     node = node->getNextNode();
 
 515 //-----------------------------------------------------------------------------
 
 516 int SETTINGS_IMPL::ParseDetailStatWritePeriod(const string & detailStatPeriodStr)
 
 518 if (detailStatPeriodStr == "1")
 
 520     detailStatWritePeriod = dsPeriod_1;
 
 523 else if (detailStatPeriodStr == "1/2")
 
 525     detailStatWritePeriod = dsPeriod_1_2;
 
 528 else if (detailStatPeriodStr == "1/4")
 
 530     detailStatWritePeriod = dsPeriod_1_4;
 
 533 else if (detailStatPeriodStr == "1/6")
 
 535     detailStatWritePeriod = dsPeriod_1_6;
 
 541 //-----------------------------------------------------------------------------