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