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