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