]> git.stg.codes - stg.git/blob - projects/stargazer/settings_impl.cpp
Ticket 26. The Reload() function declaration added.
[stg.git] / projects / stargazer / settings_impl.cpp
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Date: 27.10.2002
19  */
20
21 /*
22  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
23  */
24
25 /*
26 $Revision: 1.45 $
27 $Date: 2010/08/19 13:42:30 $
28 $Author: faust $
29 */
30
31 #include <cstring>
32 #include <cerrno>
33 #include <string>
34
35 #include "stg/logger.h"
36 #include "stg/dotconfpp.h"
37 #include "settings_impl.h"
38
39 //-----------------------------------------------------------------------------
40 SETTINGS_IMPL::SETTINGS_IMPL(const std::string & cd)
41     : modulesPath("/usr/lib/stg"),
42       dirName(DIR_NUM),
43       confDir(cd.empty() ? "/etc/stargazer" : cd),
44       scriptsDir(confDir),
45       rules(confDir + "/rules"),
46       logFile("/var/log/stargazer.log"),
47       pidFile("/var/run/stargazer.pid"),
48       monitorDir("/var/stargazer/monitoring"),
49       monitoring(false),
50       detailStatWritePeriod(dsPeriod_1_6),
51       statWritePeriod(10),
52       stgExecMsgKey(5555),
53       executersNum(1),
54       fullFee(false),
55       dayFee(0),
56       dayResetTraff(0),
57       spreadFee(false),
58       freeMbAllowInet(false),
59       dayFeeIsLastDay(false),
60       writeFreeMbTraffCost(false),
61       showFeeInCash(true),
62       messageTimeout(0),
63       feeChargeType(0),
64       reconnectOnTariffChange(false),
65       logger(GetStgLogger())
66 {
67 }
68 //-----------------------------------------------------------------------------
69 SETTINGS_IMPL::SETTINGS_IMPL(const SETTINGS_IMPL & rval)
70     : SETTINGS(),
71       strError(),
72       modulesPath(rval.modulesPath),
73       dirName(rval.dirName),
74       confDir(rval.confDir),
75       scriptsDir(rval.scriptsDir),
76       rules(rval.rules),
77       logFile(rval.logFile),
78       pidFile(rval.pidFile),
79       monitorDir(rval.monitorDir),
80       monitoring(rval.monitoring),
81       detailStatWritePeriod(rval.detailStatWritePeriod),
82       statWritePeriod(rval.statWritePeriod),
83       stgExecMsgKey(rval.stgExecMsgKey),
84       executersNum(rval.executersNum),
85       fullFee(rval.fullFee),
86       dayFee(rval.dayFee),
87       dayResetTraff(rval.dayResetTraff),
88       spreadFee(rval.spreadFee),
89       freeMbAllowInet(rval.freeMbAllowInet),
90       dayFeeIsLastDay(rval.dayFeeIsLastDay),
91       writeFreeMbTraffCost(rval.writeFreeMbTraffCost),
92       showFeeInCash(rval.showFeeInCash),
93       messageTimeout(rval.messageTimeout),
94       feeChargeType(rval.feeChargeType),
95       reconnectOnTariffChange(rval.reconnectOnTariffChange),
96       modulesSettings(rval.modulesSettings),
97       storeModuleSettings(rval.storeModuleSettings),
98       logger(GetStgLogger())
99 {
100 }
101 //-----------------------------------------------------------------------------
102 SETTINGS_IMPL & SETTINGS_IMPL::operator=(const SETTINGS_IMPL & set)
103 {
104     if (&set == this)
105         return *this;
106
107     modulesPath = set.modulesPath;
108     dirName = set.dirName;
109     confDir = set.confDir;
110     scriptsDir = set.scriptsDir;
111     rules = set.rules;
112     logFile = set.logFile;
113     pidFile = set.pidFile;
114     monitorDir = set.monitorDir;
115     scriptParams = set.scriptParams;
116     monitoring = set.monitoring;
117     detailStatWritePeriod = set.detailStatWritePeriod;
118     statWritePeriod = set.statWritePeriod;
119     stgExecMsgKey = set.stgExecMsgKey;
120     executersNum = set.executersNum;
121     fullFee = set.fullFee;
122     dayFee = set.dayFee;
123     dayResetTraff = set.dayResetTraff;
124     spreadFee = set.spreadFee;
125     freeMbAllowInet = set.freeMbAllowInet;
126     dayFeeIsLastDay = set.dayFeeIsLastDay;
127     writeFreeMbTraffCost = set.writeFreeMbTraffCost;
128     showFeeInCash = set.showFeeInCash;
129     messageTimeout = set.messageTimeout;
130     feeChargeType = set.feeChargeType;
131     reconnectOnTariffChange = set.reconnectOnTariffChange;
132
133     modulesSettings = set.modulesSettings;
134     storeModuleSettings = set.storeModuleSettings;
135     return *this;
136 }
137 //-----------------------------------------------------------------------------
138 int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, std::vector<PARAM_VALUE> * params)
139 {
140 const DOTCONFDocumentNode * childNode;
141 PARAM_VALUE pv;
142 const char * value;
143
144 pv.param = node->getName();
145
146 if (node->getValue(1))
147     {
148     strError = "Unexpected value \'" + std::string(node->getValue(1)) + "\'.";
149     return -1;
150     }
151
152 value = node->getValue(0);
153
154 if (!value)
155     {
156     strError = "Module name expected.";
157     return -1;
158     }
159
160 childNode = node->getChildNode();
161 while (childNode)
162     {
163     pv.param = childNode->getName();
164     int i = 0;
165     while ((value = childNode->getValue(i++)) != NULL)
166         {
167         pv.value.push_back(value);
168         }
169     params->push_back(pv);
170     pv.value.clear();
171     childNode = childNode->getNextNode();
172     }
173
174 return 0;
175 }
176 //-----------------------------------------------------------------------------
177 void SETTINGS_IMPL::ErrorCallback(void * data, const char * buf)
178 {
179     printfd(__FILE__, "SETTINGS_IMPL::ErrorCallback() - %s\n", buf);
180     SETTINGS_IMPL * settings = static_cast<SETTINGS_IMPL *>(data);
181     settings->logger("%s", buf);
182 }
183 //-----------------------------------------------------------------------------
184 int SETTINGS_IMPL::ReadSettings()
185 {
186 const char * requiredOptions[] = {
187     "ModulesPath",
188     "Modules",
189     "StoreModule",
190     "Rules",
191     "LogFile",
192     "DetailStatWritePeriod",
193     "DayFee",
194     "DayResetTraff",
195     "SpreadFee",
196     "FreeMbAllowInet",
197     "DayFeeIsLastDay",
198     "WriteFreeMbTraffCost",
199     NULL
200     };
201 int storeModulesCount = 0;
202 modulesSettings.clear();
203
204 DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
205 conf.setErrorCallback(SETTINGS_IMPL::ErrorCallback, this);
206 conf.setRequiredOptionNames(requiredOptions);
207 std::string confFile = confDir + "/stargazer.conf";
208
209 if(conf.setContent(confFile.c_str()) != 0)
210     {
211     strError = "Cannot read file " + confFile;
212     return -1;
213     }
214
215 const DOTCONFDocumentNode * node = conf.getFirstNode();
216
217 while (node)
218     {
219     if (strcasecmp(node->getName(), "ScriptDir") == 0)
220         {
221         scriptsDir = node->getValue(0);
222         }
223
224     if (strcasecmp(node->getName(), "LogFile") == 0)
225         {
226         logFile = node->getValue(0);
227         }
228
229     if (strcasecmp(node->getName(), "PIDFile") == 0)
230         {
231         pidFile = node->getValue(0);
232         }
233
234     if (strcasecmp(node->getName(), "ModulesPath") == 0)
235         {
236         modulesPath = node->getValue(0);
237         }
238
239     if (strcasecmp(node->getName(), "Rules") == 0)
240         {
241         rules = node->getValue(0);
242         }
243
244     if (strcasecmp(node->getName(), "DetailStatWritePeriod") == 0)
245         {
246         if (ParseDetailStatWritePeriod(node->getValue(0)) != 0)
247             {
248             strError = "Incorrect DetailStatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
249             return -1;
250             }
251         }
252
253     if (strcasecmp(node->getName(), "StatWritePeriod") == 0)
254         {
255         if (ParseUnsignedInRange(node->getValue(0), 1, 1440, &statWritePeriod) != 0)
256             {
257             strError = "Incorrect StatWritePeriod value: \'" + std::string(node->getValue(0)) + "\'";
258             return -1;
259             }
260         }
261
262     if (strcasecmp(node->getName(), "ExecMsgKey") == 0)
263         {
264         if (ParseInt(node->getValue(0), &stgExecMsgKey) != 0)
265             {
266             strError = "Incorrect ExecMsgKey value: \'" + std::string(node->getValue(0)) + "\'";
267             return -1;
268             }
269         }
270
271     if (strcasecmp(node->getName(), "ExecutersNum") == 0)
272         {
273         if (ParseUnsignedInRange(node->getValue(0), 1, 1024, &executersNum) != 0)
274             {
275             strError = "Incorrect ExecutersNum value: \'" + std::string(node->getValue(0)) + "\'";
276             return -1;
277             }
278         }
279
280     if (strcasecmp(node->getName(), "DayFee") == 0)
281         {
282         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayFee) != 0)
283             {
284             strError = "Incorrect DayFee value: \'" + std::string(node->getValue(0)) + "\'";
285             return -1;
286             }
287         }
288
289     if (strcasecmp(node->getName(), "FullFee") == 0)
290         {
291         if (ParseYesNo(node->getValue(0), &fullFee) != 0)
292             {
293             strError = "Incorrect FullFee value: \'" + std::string(node->getValue(0)) + "\'";
294             return -1;
295             }
296         }
297
298     if (strcasecmp(node->getName(), "DayResetTraff") == 0)
299         {
300         if (ParseUnsignedInRange(node->getValue(0), 0, 31, &dayResetTraff) != 0)
301             {
302             strError = "Incorrect DayResetTraff value: \'" + std::string(node->getValue(0)) + "\'";
303             return -1;
304             }
305         }
306
307     if (strcasecmp(node->getName(), "SpreadFee") == 0)
308         {
309         if (ParseYesNo(node->getValue(0), &spreadFee) != 0)
310             {
311             strError = "Incorrect SpreadFee value: \'" + std::string(node->getValue(0)) + "\'";
312             return -1;
313             }
314         }
315
316     if (strcasecmp(node->getName(), "FreeMbAllowInet") == 0)
317         {
318         if (ParseYesNo(node->getValue(0), &freeMbAllowInet) != 0)
319             {
320             strError = "Incorrect FreeMbAllowInet value: \'" + std::string(node->getValue(0)) + "\'";
321             return -1;
322             }
323         }
324
325     if (strcasecmp(node->getName(), "DayFeeIsLastDay") == 0)
326         {
327         if (ParseYesNo(node->getValue(0), &dayFeeIsLastDay) != 0)
328             {
329             strError = "Incorrect DayFeeIsLastDay value: \'" + std::string(node->getValue(0)) + "\'";
330             return -1;
331             }
332         }
333
334     if (strcasecmp(node->getName(), "WriteFreeMbTraffCost") == 0)
335         {
336         if (ParseYesNo(node->getValue(0), &writeFreeMbTraffCost) != 0)
337             {
338             strError = "Incorrect WriteFreeMbTraffCost value: \'" + std::string(node->getValue(0)) + "\'";
339             return -1;
340             }
341         }
342
343     if (strcasecmp(node->getName(), "ShowFeeInCash") == 0)
344         {
345         if (ParseYesNo(node->getValue(0), &showFeeInCash) != 0)
346             {
347             strError = "Incorrect ShowFeeInCash value: \'" + std::string(node->getValue(0)) + "\'";
348             return -1;
349             }
350         }
351
352     if (strcasecmp(node->getName(), "MonitorDir") == 0)
353         {
354         monitorDir = node->getValue(0);
355         struct stat stat;
356         monitoring = false;
357
358         if (!lstat(monitorDir.c_str(), &stat) && S_ISDIR(stat.st_mode))
359             {
360             monitoring = true;
361             }
362         }
363
364     if (strcasecmp(node->getName(), "MessageTimeout") == 0)
365         {
366         if (ParseUnsigned(node->getValue(0), &messageTimeout) != 0)
367             {
368             strError = "Incorrect MessageTimeout value: \'" + std::string(node->getValue(0)) + "\'";
369             return -1;
370             }
371         }
372
373     if (strcasecmp(node->getName(), "FeeChargeType") == 0)
374         {
375         if (ParseUnsignedInRange(node->getValue(0), 0, 3, &feeChargeType) != 0)
376             {
377             strError = "Incorrect FeeChargeType value: \'" + std::string(node->getValue(0)) + "\'";
378             return -1;
379             }
380         }
381
382     if (strcasecmp(node->getName(), "ReconnectOnTariffChange") == 0)
383         {
384         if (ParseYesNo(node->getValue(0), &reconnectOnTariffChange) != 0)
385             {
386             strError = "Incorrect ReconnectOnTariffChange value: \'" + std::string(node->getValue(0)) + "\'";
387             return -1;
388             }
389         }
390
391     if (strcasecmp(node->getName(), "DirNames") == 0)
392         {
393         const DOTCONFDocumentNode * child = node->getChildNode();
394         if (child)
395             {
396             const DOTCONFDocumentNode * dirNameNode;
397             dirName.reserve(DIR_NUM);
398             for (int i = 0; i < DIR_NUM; i++)
399                 {
400                 char strDirName[12];
401                 sprintf(strDirName, "DirName%d", i);
402                 dirNameNode = conf.findNode(strDirName, node);
403                 if (dirNameNode && dirNameNode->getValue(0))
404                     {
405                     dirName[i] = dirNameNode->getValue(0);
406                     }
407                 }
408             }
409         }
410
411     if (strcasecmp(node->getName(), "StoreModule") == 0)
412         {
413         if (node->getValue(1))
414             {
415             strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
416             return -1;
417             }
418
419         if (storeModulesCount)
420             {
421             strError = "Should be only one StoreModule.";
422             return -1;
423             }
424         storeModulesCount++;
425
426         storeModuleSettings.moduleName = node->getValue(0);
427         ParseModuleSettings(node, &storeModuleSettings.moduleParams);
428         }
429
430     if (strcasecmp(node->getName(), "Modules") == 0)
431         {
432         if (node->getValue(0))
433             {
434             strError = "Unexpected \'" + std::string(node->getValue(0)) + "\'.";
435             return -1;
436             }
437         const DOTCONFDocumentNode * child = node->getChildNode();
438         while (child)
439             {
440             if (strcasecmp(child->getName(), "Module") != 0)
441                 {
442                 child = child->getNextNode();
443                 continue;
444                 }
445             MODULE_SETTINGS modSettings;
446             modSettings.moduleParams.clear();
447             modSettings.moduleName = child->getValue();
448
449             ParseModuleSettings(child, &modSettings.moduleParams);
450
451             modulesSettings.push_back(modSettings);
452
453             child = child->getNextNode();
454             }
455         }
456
457     if (strcasecmp(node->getName(), "ScriptParams") == 0)
458         {
459         for (int i = 0; node->getValue(i) != NULL; ++i)
460             {
461             scriptParams.push_back(node->getValue(i));
462             }
463         }
464     node = node->getNextNode();
465     }
466
467 return 0;
468 }
469 //-----------------------------------------------------------------------------
470 int SETTINGS_IMPL::ParseDetailStatWritePeriod(const std::string & detailStatPeriodStr)
471 {
472 if (detailStatPeriodStr == "1")
473     {
474     detailStatWritePeriod = dsPeriod_1;
475     return 0;
476     }
477 else if (detailStatPeriodStr == "1/2")
478     {
479     detailStatWritePeriod = dsPeriod_1_2;
480     return 0;
481     }
482 else if (detailStatPeriodStr == "1/4")
483     {
484     detailStatWritePeriod = dsPeriod_1_4;
485     return 0;
486     }
487 else if (detailStatPeriodStr == "1/6")
488     {
489     detailStatWritePeriod = dsPeriod_1_6;
490     return 0;
491     }
492
493 return -1;
494 }
495 //-----------------------------------------------------------------------------