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