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),
114 writeFreeMbTraffCost(false),
118 reconnectOnTariffChange(false),
119 disableSessionLog(false),
120 logger(GetStgLogger())
122 filterParamsLog.push_back("*");
124 //-----------------------------------------------------------------------------
125 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
126 : modulesPath(rval.modulesPath),
127 dirName(rval.dirName),
128 confDir(rval.confDir),
129 scriptsDir(rval.scriptsDir),
131 logFile(rval.logFile),
132 pidFile(rval.pidFile),
133 monitorDir(rval.monitorDir),
134 monitoring(rval.monitoring),
135 detailStatWritePeriod(rval.detailStatWritePeriod),
136 statWritePeriod(rval.statWritePeriod),
137 stgExecMsgKey(rval.stgExecMsgKey),
138 executersNum(rval.executersNum),
139 fullFee(rval.fullFee),
141 dayResetTraff(rval.dayResetTraff),
142 spreadFee(rval.spreadFee),
143 freeMbAllowInet(rval.freeMbAllowInet),
144 dayFeeIsLastDay(rval.dayFeeIsLastDay),
145 stopOnError(rval.stopOnError),
146 writeFreeMbTraffCost(rval.writeFreeMbTraffCost),
147 showFeeInCash(rval.showFeeInCash),
148 messageTimeout(rval.messageTimeout),
149 feeChargeType(rval.feeChargeType),
150 reconnectOnTariffChange(rval.reconnectOnTariffChange),
151 disableSessionLog(rval.disableSessionLog),
152 filterParamsLog(rval.filterParamsLog),
153 modulesSettings(rval.modulesSettings),
154 storeModuleSettings(rval.storeModuleSettings),
155 logger(GetStgLogger())
158 //-----------------------------------------------------------------------------
159 SETTINGS_IMPL & SETTINGS_IMPL::operator=(const SETTINGS_IMPL & rhs)
161 modulesPath = rhs.modulesPath;
162 dirName = rhs.dirName;
163 confDir = rhs.confDir;
164 scriptsDir = rhs.scriptsDir;
166 logFile = rhs.logFile;
167 pidFile = rhs.pidFile;
168 monitorDir = rhs.monitorDir;
169 scriptParams = rhs.scriptParams;
170 monitoring = rhs.monitoring;
171 detailStatWritePeriod = rhs.detailStatWritePeriod;
172 statWritePeriod = rhs.statWritePeriod;
173 stgExecMsgKey = rhs.stgExecMsgKey;
174 executersNum = rhs.executersNum;
175 fullFee = rhs.fullFee;
177 dayResetTraff = rhs.dayResetTraff;
178 spreadFee = rhs.spreadFee;
179 freeMbAllowInet = rhs.freeMbAllowInet;
180 dayFeeIsLastDay = rhs.dayFeeIsLastDay;
181 stopOnError = rhs.stopOnError;
182 writeFreeMbTraffCost = rhs.writeFreeMbTraffCost;
183 showFeeInCash = rhs.showFeeInCash;
184 messageTimeout = rhs.messageTimeout;
185 feeChargeType = rhs.feeChargeType;
186 reconnectOnTariffChange = rhs.reconnectOnTariffChange;
187 disableSessionLog = rhs.disableSessionLog;
188 filterParamsLog = rhs.filterParamsLog;
190 modulesSettings = rhs.modulesSettings;
191 storeModuleSettings = rhs.storeModuleSettings;
194 //-----------------------------------------------------------------------------
195 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
197 printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
198 SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
199 settings->logger("%s", buf);
201 //-----------------------------------------------------------------------------
202 int SETTINGS_IMPL::ReadSettings()
204 const char * requiredOptions[] = {
210 "DetailStatWritePeriod",
216 "WriteFreeMbTraffCost",
219 int storeModulesCount = 0;
220 modulesSettings.clear();
222 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
223 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
224 conf.setRequiredOptionNames(requiredOptions);
225 std::string confFile = confDir + "/stargazer.conf";
227 if(conf.setContent(confFile.c_str()) != 0)
229 strError = "Cannot read file " + confFile;
233 const DOTCONFDocumentNode * node = conf.getFirstNode();
237 if (strcasecmp(node->getName(), "ScriptDir") == 0)
239 scriptsDir = node->getValue(0);
242 if (strcasecmp(node->getName(), "LogFile") == 0)
244 logFile = node->getValue(0);
247 if (strcasecmp(node->getName(), "PIDFile") == 0)
249 pidFile = node->getValue(0);
252 if (strcasecmp(node->getName(), "ModulesPath") == 0)
254 modulesPath = node->getValue(0);
257 if (strcasecmp(node->getName(), "Rules") == 0)
259 rules = node->getValue(0);
262 if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
266 detailStatWritePeriod = toPeriod(node->getValue(0));
268 catch (const Error& error)
270 strError = error.what();
275 if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
277 if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
279 strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
284 if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
286 if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
288 strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
293 if (strcasecmp(node->getName(), "ExecutersNum") == 0)
295 if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
297 strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
302 if (strcasecmp(node->getName(), "DayFee") == 0)
304 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
306 strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
311 if (strcasecmp(node->getName(), "FullFee") == 0)
313 if (ParseYesNo(node->getValue(0), &fullFee) != 0)
315 strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
320 if (strcasecmp(node->getName(), "DayResetTraff") == 0)
322 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
324 strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
329 if (strcasecmp(node->getName(), "SpreadFee") == 0)
331 if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
333 strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
338 if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
340 if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
342 strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
347 if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
349 if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
351 strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
356 if (strcasecmp(node->getName(), "StopOnError") == 0)
358 if (ParseYesNo(node->getValue(0), &stopOnError) != 0)
360 strError = "Incorrect StopOnError value: \'" + std::string(node->getValue(0)) + "\'";
365 if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
367 if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
369 strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
374 if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
376 if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
378 strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
383 if (strcasecmp(node->getName(), "MonitorDir") == 0)
385 monitorDir = node->getValue(0);
389 if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
395 if (strcasecmp(node->getName(), "MessageTimeout") == 0)
397 if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
399 strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
404 if (strcasecmp(node->getName(), "FeeChargeType") == 0)
406 if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
408 strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
413 if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
415 if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
417 strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
422 if (strcasecmp(node->getName(), "DisableSessionLog") == 0)
424 if (ParseYesNo(node->getValue(0), &disableSessionLog) != 0)
426 strError = "Incorrect DisableSessionLog value: \'" + std::string(node->getValue(0)) + "\'";
431 if (strcasecmp(node->getName(), "FilterParamsLog") == 0)
433 filterParamsLog.clear();
434 for (int i = 0; node->getValue(i) != NULL; ++i)
435 filterParamsLog.push_back(node->getValue(i));
438 if (strcasecmp(node->getName(), "DirNames") == 0)
440 const DOTCONFDocumentNode * child = node->getChildNode();
443 const DOTCONFDocumentNode * dirNameNode;
444 dirName.reserve(DIR_NUM);
445 for (int i = 0; i < DIR_NUM; i++)
448 sprintf(strDirName, "DirName%d", i);
449 dirNameNode = conf.findNode(strDirName, node);
450 if (dirNameNode && dirNameNode->getValue(0))
452 dirName[i] = dirNameNode->getValue(0);
458 if (strcasecmp(node->getName(), "StoreModule") == 0)
460 if (node->getValue(1))
462 strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
466 if (storeModulesCount)
468 strError = "Should be only one StoreModule.";
473 if (node->getValue(0) == NULL)
475 strError = "No module name in the StoreModule section.";
478 storeModuleSettings.moduleName = node->getValue(0);
479 storeModuleSettings.moduleParams = toPVS(*node);
482 if (strcasecmp(node->getName(), "Modules") == 0)
484 if (node->getValue(0))
486 strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
489 const DOTCONFDocumentNode * child = node->getChildNode();
492 if (strcasecmp(child->getName(), "Module") != 0)
494 child = child->getNextNode();
498 if (child->getValue(0) == NULL)
500 strError = "No module name in the Module section.";
504 modulesSettings.push_back(MODULE_SETTINGS(child->getValue(0), toPVS(*child)));
506 child = child->getNextNode();
510 if (strcasecmp(node->getName(), "ScriptParams") == 0)
512 for (int i = 0; node->getValue(i) != NULL; ++i)
513 scriptParams.push_back(node->getValue(i));
515 node = node->getNextNode();
520 //-----------------------------------------------------------------------------