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 disableSessionLog(false),
119 logger(GetStgLogger())
121 filterParamsLog.push_back("*");
123 //-----------------------------------------------------------------------------
124 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
127 modulesPath(rval.modulesPath),
128 dirName(rval.dirName),
129 confDir(rval.confDir),
130 scriptsDir(rval.scriptsDir),
132 logFile(rval.logFile),
133 pidFile(rval.pidFile),
134 monitorDir(rval.monitorDir),
135 monitoring(rval.monitoring),
136 detailStatWritePeriod(rval.detailStatWritePeriod),
137 statWritePeriod(rval.statWritePeriod),
138 stgExecMsgKey(rval.stgExecMsgKey),
139 executersNum(rval.executersNum),
140 fullFee(rval.fullFee),
142 dayResetTraff(rval.dayResetTraff),
143 spreadFee(rval.spreadFee),
144 freeMbAllowInet(rval.freeMbAllowInet),
145 dayFeeIsLastDay(rval.dayFeeIsLastDay),
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 writeFreeMbTraffCost = rhs.writeFreeMbTraffCost;
182 showFeeInCash = rhs.showFeeInCash;
183 messageTimeout = rhs.messageTimeout;
184 feeChargeType = rhs.feeChargeType;
185 reconnectOnTariffChange = rhs.reconnectOnTariffChange;
186 disableSessionLog = rhs.disableSessionLog;
187 filterParamsLog = rhs.filterParamsLog;
189 modulesSettings = rhs.modulesSettings;
190 storeModuleSettings = rhs.storeModuleSettings;
193 //-----------------------------------------------------------------------------
194 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
196 printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
197 SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
198 settings->logger("%s", buf);
200 //-----------------------------------------------------------------------------
201 int SETTINGS_IMPL::ReadSettings()
203 const char * requiredOptions[] = {
209 "DetailStatWritePeriod",
215 "WriteFreeMbTraffCost",
218 int storeModulesCount = 0;
219 modulesSettings.clear();
221 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
222 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
223 conf.setRequiredOptionNames(requiredOptions);
224 std::string confFile = confDir + "/stargazer.conf";
226 if(conf.setContent(confFile.c_str()) != 0)
228 strError = "Cannot read file " + confFile;
232 const DOTCONFDocumentNode * node = conf.getFirstNode();
236 if (strcasecmp(node->getName(), "ScriptDir") == 0)
238 scriptsDir = node->getValue(0);
241 if (strcasecmp(node->getName(), "LogFile") == 0)
243 logFile = node->getValue(0);
246 if (strcasecmp(node->getName(), "PIDFile") == 0)
248 pidFile = node->getValue(0);
251 if (strcasecmp(node->getName(), "ModulesPath") == 0)
253 modulesPath = node->getValue(0);
256 if (strcasecmp(node->getName(), "Rules") == 0)
258 rules = node->getValue(0);
261 if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
265 detailStatWritePeriod = toPeriod(node->getValue(0));
267 catch (const Error& error)
269 strError = error.what();
274 if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
276 if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
278 strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
283 if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
285 if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
287 strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
292 if (strcasecmp(node->getName(), "ExecutersNum") == 0)
294 if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
296 strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
301 if (strcasecmp(node->getName(), "DayFee") == 0)
303 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
305 strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
310 if (strcasecmp(node->getName(), "FullFee") == 0)
312 if (ParseYesNo(node->getValue(0), &fullFee) != 0)
314 strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
319 if (strcasecmp(node->getName(), "DayResetTraff") == 0)
321 if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
323 strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
328 if (strcasecmp(node->getName(), "SpreadFee") == 0)
330 if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
332 strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
337 if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
339 if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
341 strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
346 if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
348 if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
350 strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
355 if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
357 if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
359 strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
364 if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
366 if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
368 strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
373 if (strcasecmp(node->getName(), "MonitorDir") == 0)
375 monitorDir = node->getValue(0);
379 if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
385 if (strcasecmp(node->getName(), "MessageTimeout") == 0)
387 if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
389 strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
394 if (strcasecmp(node->getName(), "FeeChargeType") == 0)
396 if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
398 strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
403 if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
405 if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
407 strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
412 if (strcasecmp(node->getName(), "DisableSessionLog") == 0)
414 if (ParseYesNo(node->getValue(0), &disableSessionLog) != 0)
416 strError = "Incorrect DisableSessionLog value: \'" + std::string(node->getValue(0)) + "\'";
421 if (strcasecmp(node->getName(), "FilterParamsLog") == 0)
423 filterParamsLog.clear();
424 for (int i = 0; node->getValue(i) != NULL; ++i)
425 filterParamsLog.push_back(node->getValue(i));
428 if (strcasecmp(node->getName(), "DirNames") == 0)
430 const DOTCONFDocumentNode * child = node->getChildNode();
433 const DOTCONFDocumentNode * dirNameNode;
434 dirName.reserve(DIR_NUM);
435 for (int i = 0; i < DIR_NUM; i++)
438 sprintf(strDirName, "DirName%d", i);
439 dirNameNode = conf.findNode(strDirName, node);
440 if (dirNameNode && dirNameNode->getValue(0))
442 dirName[i] = dirNameNode->getValue(0);
448 if (strcasecmp(node->getName(), "StoreModule") == 0)
450 if (node->getValue(1))
452 strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
456 if (storeModulesCount)
458 strError = "Should be only one StoreModule.";
463 if (node->getValue(0) == NULL)
465 strError = "No module name in the StoreModule section.";
468 storeModuleSettings.moduleName = node->getValue(0);
469 storeModuleSettings.moduleParams = toPVS(*node);
472 if (strcasecmp(node->getName(), "Modules") == 0)
474 if (node->getValue(0))
476 strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
479 const DOTCONFDocumentNode * child = node->getChildNode();
482 if (strcasecmp(child->getName(), "Module") != 0)
484 child = child->getNextNode();
488 if (child->getValue(0) == NULL)
490 strError = "No module name in the Module section.";
494 modulesSettings.push_back(MODULE_SETTINGS(child->getValue(0), toPVS(*child)));
496 child = child->getNextNode();
500 if (strcasecmp(node->getName(), "ScriptParams") == 0)
502 for (int i = 0; node->getValue(i) != NULL; ++i)
503 scriptParams.push_back(node->getValue(i));
505 node = node->getNextNode();
510 //-----------------------------------------------------------------------------