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"
26 #include "stg/const.h"
32 using STG::SettingsImpl;
33 using STG::ParamValue;
38 struct Error : public std::runtime_error
40 explicit Error(const std::string& message) : runtime_error(message) {}
43 std::vector<std::string> toValues(const DOTCONFDocumentNode& node)
45 std::vector<std::string> values;
48 const char* value = NULL;
49 while ((value = node.getValue(i++)) != NULL)
50 values.push_back(value);
55 std::vector<ParamValue> toPVS(const DOTCONFDocumentNode& node)
57 std::vector<ParamValue> pvs;
59 const DOTCONFDocumentNode* child = node.getChildNode();
62 if (child->getName() == NULL)
65 if (child->getChildNode() == NULL)
66 pvs.push_back(ParamValue(child->getName(), toValues(*child)));
68 pvs.push_back(ParamValue(child->getName(), toValues(*child), toPVS(*child)));
70 child = child->getNextNode();
76 unsigned toPeriod(const char* value)
79 throw Error("No detail stat period value.");
81 std::string period(value);
83 return STG::dsPeriod_1;
84 else if (period == "1/2")
85 return STG::dsPeriod_1_2;
86 else if (period == "1/4")
87 return STG::dsPeriod_1_4;
88 else if (period == "1/6")
89 return STG::dsPeriod_1_6;
91 throw Error("Invalid detail stat period value: '" + period + "'. Should be one of '1', '1/2', '1/4' or '1/6'.");
94 void errorCallback(void* /*data*/, const char* buf)
96 printfd(__FILE__, "SettingsImpl::errorCallback() - %s\n", buf);
97 STG::Logger::get()("%s", buf);
102 //-----------------------------------------------------------------------------
103 SettingsImpl::SettingsImpl(const std::string & cd)
104 : modulesPath("/usr/lib/stg"),
106 confDir(cd.empty() ? "/etc/stargazer" : cd),
108 rules(confDir + "/rules"),
109 logFile("/var/log/stargazer.log"),
110 pidFile("/var/run/stargazer.pid"),
111 monitorDir("/var/stargazer/monitoring"),
113 detailStatWritePeriod(dsPeriod_1_6),
121 freeMbAllowInet(false),
122 dayFeeIsLastDay(false),
124 writeFreeMbTraffCost(false),
128 reconnectOnTariffChange(false),
129 disableSessionLog(false)
131 filterParamsLog.push_back("*");
133 //-----------------------------------------------------------------------------
134 int SettingsImpl::ReadSettings()
136 const char * requiredOptions[] = {
142 "DetailStatWritePeriod",
148 "WriteFreeMbTraffCost",
151 int storeModulesCount = 0;
152 modulesSettings.clear();
154 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
155 conf.setErrorCallback(errorCallback, nullptr);
156 conf.setRequiredOptionNames(requiredOptions);
157 std::string confFile = confDir + "/stargazer.conf";
159 if(conf.setContent(confFile.c_str()) != 0)
161 strError = "Cannot read file " + confFile;
165 auto node = conf.getFirstNode();
169 if (strcasecmp(node->getName(), "ScriptDir") == 0)
171 scriptsDir = node->getValue(0);
174 if (strcasecmp(node->getName(), "LogFile") == 0)
176 logFile = node->getValue(0);
179 if (strcasecmp(node->getName(), "PIDFile") == 0)
181 pidFile = node->getValue(0);
184 if (strcasecmp(node->getName(), "ModulesPath") == 0)
186 modulesPath = node->getValue(0);
189 if (strcasecmp(node->getName(), "Rules") == 0)
191 rules = node->getValue(0);
194 if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
198 detailStatWritePeriod = toPeriod(node->getValue(0));
200 catch (const Error& error)
202 strError = error.what();
207 if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
209 if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
211 strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
216 if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
218 if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
220 strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
225 if (strcasecmp(node->getName(), "ExecutersNum") == 0)
227 if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
229 strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
234 if (strcasecmp(node->getName(), "DayFee") == 0)
236 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
238 strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
243 if (strcasecmp(node->getName(), "FullFee") == 0)
245 if (ParseYesNo(node->getValue(0), &fullFee) != 0)
247 strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
252 if (strcasecmp(node->getName(), "DayResetTraff") == 0)
254 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
256 strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
261 if (strcasecmp(node->getName(), "SpreadFee") == 0)
263 if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
265 strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
270 if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
272 if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
274 strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
279 if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
281 if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
283 strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
288 if (strcasecmp(node->getName(), "StopOnError") == 0)
290 if (ParseYesNo(node->getValue(0), &stopOnError) != 0)
292 strError = "Incorrect StopOnError value: \'" + std::string(node->getValue(0)) + "\'";
297 if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
299 if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
301 strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
306 if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
308 if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
310 strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
315 if (strcasecmp(node->getName(), "MonitorDir") == 0)
317 monitorDir = node->getValue(0);
321 if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
327 if (strcasecmp(node->getName(), "MessageTimeout") == 0)
329 if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
331 strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
336 if (strcasecmp(node->getName(), "FeeChargeType") == 0)
338 if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
340 strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
345 if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
347 if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
349 strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
354 if (strcasecmp(node->getName(), "DisableSessionLog") == 0)
356 if (ParseYesNo(node->getValue(0), &disableSessionLog) != 0)
358 strError = "Incorrect DisableSessionLog value: \'" + std::string(node->getValue(0)) + "\'";
363 if (strcasecmp(node->getName(), "FilterParamsLog") == 0)
365 filterParamsLog.clear();
366 for (int i = 0; node->getValue(i) != NULL; ++i)
367 filterParamsLog.push_back(node->getValue(i));
370 if (strcasecmp(node->getName(), "DirNames") == 0)
372 const DOTCONFDocumentNode * child = node->getChildNode();
375 const DOTCONFDocumentNode * dirNameNode;
376 dirName.reserve(DIR_NUM);
377 for (int i = 0; i < DIR_NUM; i++)
380 sprintf(strDirName, "DirName%d", i);
381 dirNameNode = conf.findNode(strDirName, node);
382 if (dirNameNode && dirNameNode->getValue(0))
384 dirName[i] = dirNameNode->getValue(0);
390 if (strcasecmp(node->getName(), "StoreModule") == 0)
392 if (node->getValue(1))
394 strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
398 if (storeModulesCount)
400 strError = "Should be only one StoreModule.";
405 if (node->getValue(0) == NULL)
407 strError = "No module name in the StoreModule section.";
410 storeModuleSettings.moduleName = node->getValue(0);
411 storeModuleSettings.moduleParams = toPVS(*node);
414 if (strcasecmp(node->getName(), "Modules") == 0)
416 if (node->getValue(0))
418 strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
421 const DOTCONFDocumentNode * child = node->getChildNode();
424 if (strcasecmp(child->getName(), "Module") != 0)
426 child = child->getNextNode();
430 if (child->getValue(0) == NULL)
432 strError = "No module name in the Module section.";
436 modulesSettings.push_back(ModuleSettings(child->getValue(0), toPVS(*child)));
438 child = child->getNextNode();
442 if (strcasecmp(node->getName(), "ScriptParams") == 0)
444 for (int i = 0; node->getValue(i) != NULL; ++i)
445 scriptParams.push_back(node->getValue(i));
447 node = node->getNextNode();
452 //-----------------------------------------------------------------------------