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