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