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