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