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