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