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