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
18 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
21 #include "settings_impl.h"
23 #include "stg/logger.h"
24 #include "stg/dotconfpp.h"
25 #include "stg/common.h"
34 struct Error : public std::runtime_error
36 Error(const std::string& message) : runtime_error(message) {}
39 std::vector<std::string> toValues(const DOTCONFDocumentNode& node)
41 std::vector<std::string> values;
44 const char* value = NULL;
45 while ((value = node.getValue(i++)) != NULL)
46 values.push_back(value);
51 std::vector<PARAM_VALUE> toPVS(const DOTCONFDocumentNode& node)
53 std::vector<PARAM_VALUE> pvs;
55 const DOTCONFDocumentNode* child = node.getChildNode();
58 if (child->getName() == NULL)
61 if (child->getChildNode() == NULL)
62 pvs.push_back(PARAM_VALUE(child->getName(), toValues(*child)));
64 pvs.push_back(PARAM_VALUE(child->getName(), toValues(*child), toPVS(*child)));
66 child = child->getNextNode();
72 unsigned toPeriod(const char* value)
75 throw Error("No detail stat period value.");
77 std::string period(value);
80 else if (period == "1/2")
82 else if (period == "1/4")
84 else if (period == "1/6")
87 throw Error("Invalid detail stat period value: '" + period + "'. Should be one of '1', '1/2', '1/4' or '1/6'.");
92 //-----------------------------------------------------------------------------
93 SETTINGS_IMPL::SETTINGS_IMPL(const std::string & cd)
94 : modulesPath("/usr/lib/stg"),
96 confDir(cd.empty() ? "/etc/stargazer" : cd),
98 rules(confDir + "/rules"),
99 logFile("/var/log/stargazer.log"),
100 pidFile("/var/run/stargazer.pid"),
101 monitorDir("/var/stargazer/monitoring"),
103 detailStatWritePeriod(dsPeriod_1_6),
111 freeMbAllowInet(false),
112 dayFeeIsLastDay(false),
113 writeFreeMbTraffCost(false),
117 reconnectOnTariffChange(false),
118 logger(GetStgLogger())
121 //-----------------------------------------------------------------------------
122 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
125 modulesPath(rval.modulesPath),
126 dirName(rval.dirName),
127 confDir(rval.confDir),
128 scriptsDir(rval.scriptsDir),
130 logFile(rval.logFile),
131 pidFile(rval.pidFile),
132 monitorDir(rval.monitorDir),
133 monitoring(rval.monitoring),
134 detailStatWritePeriod(rval.detailStatWritePeriod),
135 statWritePeriod(rval.statWritePeriod),
136 stgExecMsgKey(rval.stgExecMsgKey),
137 executersNum(rval.executersNum),
138 fullFee(rval.fullFee),
140 dayResetTraff(rval.dayResetTraff),
141 spreadFee(rval.spreadFee),
142 freeMbAllowInet(rval.freeMbAllowInet),
143 dayFeeIsLastDay(rval.dayFeeIsLastDay),
144 writeFreeMbTraffCost(rval.writeFreeMbTraffCost),
145 showFeeInCash(rval.showFeeInCash),
146 messageTimeout(rval.messageTimeout),
147 feeChargeType(rval.feeChargeType),
148 reconnectOnTariffChange(rval.reconnectOnTariffChange),
149 modulesSettings(rval.modulesSettings),
150 storeModuleSettings(rval.storeModuleSettings),
151 logger(GetStgLogger())
154 //-----------------------------------------------------------------------------
155 SETTINGS_IMPL & SETTINGS_IMPL::operator=(const SETTINGS_IMPL & rhs)
157 modulesPath = rhs.modulesPath;
158 dirName = rhs.dirName;
159 confDir = rhs.confDir;
160 scriptsDir = rhs.scriptsDir;
162 logFile = rhs.logFile;
163 pidFile = rhs.pidFile;
164 monitorDir = rhs.monitorDir;
165 scriptParams = rhs.scriptParams;
166 monitoring = rhs.monitoring;
167 detailStatWritePeriod = rhs.detailStatWritePeriod;
168 statWritePeriod = rhs.statWritePeriod;
169 stgExecMsgKey = rhs.stgExecMsgKey;
170 executersNum = rhs.executersNum;
171 fullFee = rhs.fullFee;
173 dayResetTraff = rhs.dayResetTraff;
174 spreadFee = rhs.spreadFee;
175 freeMbAllowInet = rhs.freeMbAllowInet;
176 dayFeeIsLastDay = rhs.dayFeeIsLastDay;
177 writeFreeMbTraffCost = rhs.writeFreeMbTraffCost;
178 showFeeInCash = rhs.showFeeInCash;
179 messageTimeout = rhs.messageTimeout;
180 feeChargeType = rhs.feeChargeType;
181 reconnectOnTariffChange = rhs.reconnectOnTariffChange;
183 modulesSettings = rhs.modulesSettings;
184 storeModuleSettings = rhs.storeModuleSettings;
187 //-----------------------------------------------------------------------------
188 int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, std::vector<PARAM_VALUE> * params)
190 const DOTCONFDocumentNode * childNode;
194 pv.param = node->getName();
196 if (node->getValue(1))
198 strError = "Unexpected value \'" + std::string(node->getValue(1)) + "\'.";
202 value = node->getValue(0);
206 strError = "Module name expected.";
210 childNode = node->getChildNode();
213 pv.param = childNode->getName();
215 while ((value = childNode->getValue(i++)) != NULL)
217 pv.value.push_back(value);
219 params->push_back(pv);
221 childNode = childNode->getNextNode();
226 //-----------------------------------------------------------------------------
227 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
229 printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
230 SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
231 settings->logger("%s", buf);
233 //-----------------------------------------------------------------------------
234 int SETTINGS_IMPL::ReadSettings()
236 const char * requiredOptions[] = {
242 "DetailStatWritePeriod",
248 "WriteFreeMbTraffCost",
251 int storeModulesCount = 0;
252 modulesSettings.clear();
254 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
255 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
256 conf.setRequiredOptionNames(requiredOptions);
257 std::string confFile = confDir + "/stargazer.conf";
259 if(conf.setContent(confFile.c_str()) != 0)
261 strError = "Cannot read file " + confFile;
265 const DOTCONFDocumentNode * node = conf.getFirstNode();
269 if (strcasecmp(node->getName(), "ScriptDir") == 0)
271 scriptsDir = node->getValue(0);
274 if (strcasecmp(node->getName(), "LogFile") == 0)
276 logFile = node->getValue(0);
279 if (strcasecmp(node->getName(), "PIDFile") == 0)
281 pidFile = node->getValue(0);
284 if (strcasecmp(node->getName(), "ModulesPath") == 0)
286 modulesPath = node->getValue(0);
289 if (strcasecmp(node->getName(), "Rules") == 0)
291 rules = node->getValue(0);
294 if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
298 detailStatWritePeriod = toPeriod(node->getValue(0));
300 catch (const Error& error)
302 strError = error.what();
307 if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
309 if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
311 strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
316 if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
318 if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
320 strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
325 if (strcasecmp(node->getName(), "ExecutersNum") == 0)
327 if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
329 strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
334 if (strcasecmp(node->getName(), "DayFee") == 0)
336 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
338 strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
343 if (strcasecmp(node->getName(), "FullFee") == 0)
345 if (ParseYesNo(node->getValue(0), &fullFee) != 0)
347 strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
352 if (strcasecmp(node->getName(), "DayResetTraff") == 0)
354 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
356 strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
361 if (strcasecmp(node->getName(), "SpreadFee") == 0)
363 if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
365 strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
370 if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
372 if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
374 strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
379 if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
381 if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
383 strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
388 if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
390 if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
392 strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
397 if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
399 if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
401 strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
406 if (strcasecmp(node->getName(), "MonitorDir") == 0)
408 monitorDir = node->getValue(0);
412 if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
418 if (strcasecmp(node->getName(), "MessageTimeout") == 0)
420 if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
422 strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
427 if (strcasecmp(node->getName(), "FeeChargeType") == 0)
429 if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
431 strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
436 if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
438 if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
440 strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
445 if (strcasecmp(node->getName(), "DirNames") == 0)
447 const DOTCONFDocumentNode * child = node->getChildNode();
450 const DOTCONFDocumentNode * dirNameNode;
451 dirName.reserve(DIR_NUM);
452 for (int i = 0; i < DIR_NUM; i++)
455 sprintf(strDirName, "DirName%d", i);
456 dirNameNode = conf.findNode(strDirName, node);
457 if (dirNameNode && dirNameNode->getValue(0))
459 dirName[i] = dirNameNode->getValue(0);
465 if (strcasecmp(node->getName(), "StoreModule") == 0)
467 if (node->getValue(1))
469 strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
473 if (storeModulesCount)
475 strError = "Should be only one StoreModule.";
480 if (node->getValue(0) == NULL)
482 strError = "No module name in the StoreModule section.";
485 storeModuleSettings.moduleName = node->getValue(0);
486 storeModuleSettings.moduleParams = toPVS(*node);
489 if (strcasecmp(node->getName(), "Modules") == 0)
491 if (node->getValue(0))
493 strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
496 const DOTCONFDocumentNode * child = node->getChildNode();
499 if (strcasecmp(child->getName(), "Module") != 0)
501 child = child->getNextNode();
505 if (child->getValue(0) == NULL)
507 strError = "No module name in the Module section.";
511 modulesSettings.push_back(MODULE_SETTINGS(child->getValue(0), toPVS(*child)));
513 child = child->getNextNode();
517 if (strcasecmp(node->getName(), "ScriptParams") == 0)
519 for (int i = 0; node->getValue(i) != NULL; ++i)
521 scriptParams.push_back(node->getValue(i));
524 node = node->getNextNode();
529 //-----------------------------------------------------------------------------