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