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