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 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
124 printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
125 SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
126 settings->logger("%s", buf);
128 //-----------------------------------------------------------------------------
129 int SETTINGS_IMPL::ReadSettings()
131 const char * requiredOptions[] = {
137 "DetailStatWritePeriod",
143 "WriteFreeMbTraffCost",
146 int storeModulesCount = 0;
147 modulesSettings.clear();
149 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
150 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
151 conf.setRequiredOptionNames(requiredOptions);
152 std::string confFile = confDir + "/stargazer.conf";
154 if(conf.setContent(confFile.c_str()) != 0)
156 strError = "Cannot read file " + confFile;
160 const DOTCONFDocumentNode * node = conf.getFirstNode();
164 if (strcasecmp(node->getName(), "ScriptDir") == 0)
166 scriptsDir = node->getValue(0);
169 if (strcasecmp(node->getName(), "LogFile") == 0)
171 logFile = node->getValue(0);
174 if (strcasecmp(node->getName(), "PIDFile") == 0)
176 pidFile = node->getValue(0);
179 if (strcasecmp(node->getName(), "ModulesPath") == 0)
181 modulesPath = node->getValue(0);
184 if (strcasecmp(node->getName(), "Rules") == 0)
186 rules = node->getValue(0);
189 if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
193 detailStatWritePeriod = toPeriod(node->getValue(0));
195 catch (const Error& error)
197 strError = error.what();
202 if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
204 if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
206 strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
211 if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
213 if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
215 strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
220 if (strcasecmp(node->getName(), "ExecutersNum") == 0)
222 if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
224 strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
229 if (strcasecmp(node->getName(), "DayFee") == 0)
231 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
233 strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
238 if (strcasecmp(node->getName(), "FullFee") == 0)
240 if (ParseYesNo(node->getValue(0), &fullFee) != 0)
242 strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
247 if (strcasecmp(node->getName(), "DayResetTraff") == 0)
249 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
251 strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
256 if (strcasecmp(node->getName(), "SpreadFee") == 0)
258 if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
260 strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
265 if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
267 if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
269 strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
274 if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
276 if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
278 strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
283 if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
285 if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
287 strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
292 if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
294 if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
296 strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
301 if (strcasecmp(node->getName(), "MonitorDir") == 0)
303 monitorDir = node->getValue(0);
307 if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
313 if (strcasecmp(node->getName(), "MessageTimeout") == 0)
315 if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
317 strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
322 if (strcasecmp(node->getName(), "FeeChargeType") == 0)
324 if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
326 strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
331 if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
333 if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
335 strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
340 if (strcasecmp(node->getName(), "DirNames") == 0)
342 const DOTCONFDocumentNode * child = node->getChildNode();
345 const DOTCONFDocumentNode * dirNameNode;
346 dirName.reserve(DIR_NUM);
347 for (int i = 0; i < DIR_NUM; i++)
350 sprintf(strDirName, "DirName%d", i);
351 dirNameNode = conf.findNode(strDirName, node);
352 if (dirNameNode && dirNameNode->getValue(0))
354 dirName[i] = dirNameNode->getValue(0);
360 if (strcasecmp(node->getName(), "StoreModule") == 0)
362 if (node->getValue(1))
364 strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
368 if (storeModulesCount)
370 strError = "Should be only one StoreModule.";
375 if (node->getValue(0) == NULL)
377 strError = "No module name in the StoreModule section.";
380 storeModuleSettings.moduleName = node->getValue(0);
381 storeModuleSettings.moduleParams = toPVS(*node);
384 if (strcasecmp(node->getName(), "Modules") == 0)
386 if (node->getValue(0))
388 strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
391 const DOTCONFDocumentNode * child = node->getChildNode();
394 if (strcasecmp(child->getName(), "Module") != 0)
396 child = child->getNextNode();
400 if (child->getValue(0) == NULL)
402 strError = "No module name in the Module section.";
406 modulesSettings.push_back(MODULE_SETTINGS(child->getValue(0), toPVS(*child)));
408 child = child->getNextNode();
412 if (strcasecmp(node->getName(), "ScriptParams") == 0)
414 for (int i = 0; node->getValue(i) != NULL; ++i)
416 scriptParams.push_back(node->getValue(i));
419 node = node->getNextNode();
424 //-----------------------------------------------------------------------------