]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp
Merge remote-tracking branch 'github/master'
[stg.git] / projects / stargazer / plugins / configuration / sgconfig / stgconfig.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  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21 #include "stgconfig.h"
22
23 #include "stg/common.h"
24
25 #include <algorithm>
26 #include <csignal>
27 #include <cstring>
28 #include <cerrno>
29
30 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
33 bool STG_CONFIG_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
34 {
35     STG::ParamValue pv;
36     std::vector<STG::ParamValue>::const_iterator pvi;
37     ///////////////////////////
38     pv.param = "Port";
39     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
40     if (pvi == s.moduleParams.end() || pvi->value.empty())
41         {
42         errorStr = "Parameter \'Port\' is not found.";
43         printfd(__FILE__, "%s\n", errorStr.c_str());
44         return false;
45         }
46     int p;
47     if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
48         {
49         errorStr = "Parameter \'Port\' should be an integral value in range (2, 65535). Actual value: '" + pvi->value[0] + "'.";
50         printfd(__FILE__, "%s\n", errorStr.c_str());
51         return false;
52         }
53     m_port = static_cast<uint16_t>(p);
54
55     pv.param = "BindAddress";
56     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
57     if (pvi != s.moduleParams.end() && !pvi->value.empty())
58         m_bindAddress = pvi->value[0];
59
60     return true;
61 }
62 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
64 //-----------------------------------------------------------------------------
65 extern "C" STG::Plugin * GetPlugin()
66 {
67     static STG_CONFIG plugin;
68     return &plugin;
69 }
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
73 STG_CONFIG::STG_CONFIG()
74     : nonstop(false),
75       isRunning(false),
76       logger(STG::PluginLogger::get("conf_sg")),
77       config(logger)
78 {
79 }
80 //-----------------------------------------------------------------------------
81 int STG_CONFIG::ParseSettings()
82 {
83     if (stgConfigSettings.ParseSettings(settings))
84         return 0;
85     errorStr = stgConfigSettings.GetStrError();
86     return -1;
87 }
88 //-----------------------------------------------------------------------------
89 int STG_CONFIG::Start()
90 {
91     if (isRunning)
92         return 0;
93
94     nonstop = true;
95
96     config.SetPort(stgConfigSettings.GetPort());
97     config.SetBindAddress(stgConfigSettings.GetBindAddress());
98
99     if (config.Prepare())
100     {
101         errorStr = config.GetStrError();
102         return -1;
103     }
104
105     if (pthread_create(&thread, NULL, Run, this))
106     {
107         errorStr = std::string("Cannot create thread: '") + strerror(errno) + "'.";
108         printfd(__FILE__, "%s\n", errorStr.c_str());
109         logger(errorStr);
110         return -1;
111     }
112
113     return 0;
114 }
115 //-----------------------------------------------------------------------------
116 int STG_CONFIG::Stop()
117 {
118     if (!isRunning)
119         return 0;
120
121     config.Stop();
122
123     //5 seconds to thread stops itself
124     for (size_t i = 0; i < 25; ++i)
125     {
126         if (!isRunning)
127             break;
128
129         struct timespec ts = {0, 200000000};
130         nanosleep(&ts, NULL);
131     }
132
133     if (isRunning)
134         return -1;
135
136     return 0;
137 }
138 //-----------------------------------------------------------------------------
139 void * STG_CONFIG::Run(void * d)
140 {
141     sigset_t signalSet;
142     sigfillset(&signalSet);
143     pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
144
145     STG_CONFIG & stgConf = *static_cast<STG_CONFIG *>(d);
146     stgConf.isRunning = true;
147
148     stgConf.config.Run();
149
150     stgConf.isRunning = false;
151
152     return NULL;
153 }