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