./parser_users.cpp \
./parser_message.cpp \
./parser_auth_by.cpp \
- ./parser_user_info.cpp
+ ./parser_user_info.cpp \
+ ./parser_server_info.cpp
LIBS += -lexpat \
$(LIB_THREAD)
#include <algorithm>
#include <functional>
+#include <vector>
#include <csignal>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
-#include <arpa/inet.h>
+#include <netdb.h>
namespace SP = STG::PARSER;
-namespace
-{
-
-struct IsFinished : public std::unary_function<STG::Conn *, bool>
-{
- result_type operator()(const argument_type & arg)
- {
- return (arg->IsDone() && !arg->IsKeepAlive()) || !arg->IsOk();
- }
-};
-
-struct RemoveConn : public std::unary_function<STG::Conn *, void>
-{
- result_type operator()(const argument_type & arg)
- {
- delete arg;
- }
-};
-
-}
-
CONFIGPROTO::CONFIGPROTO(PLUGIN_LOGGER & l)
: m_settings(NULL),
m_admins(NULL),
m_tariffs(NULL),
m_users(NULL),
m_port(0),
+ m_bindAddress("0.0.0.0"),
m_running(false),
m_stopped(true),
m_logger(l),
CONFIGPROTO::~CONFIGPROTO()
{
- std::for_each(m_conns.begin(), m_conns.end(), RemoveConn());
+ std::deque<STG::Conn *>::iterator it;
+ for (it = m_conns.begin(); it != m_conns.end(); ++it)
+ delete *it;
}
int CONFIGPROTO::Prepare()
return -1;
}
- struct sockaddr_in listenAddr;
- listenAddr.sin_family = PF_INET;
- listenAddr.sin_port = htons(m_port);
- listenAddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // TODO: arbitrary address
-
int dummy = 1;
if (setsockopt(m_listenSocket, SOL_SOCKET, SO_REUSEADDR, &dummy, 4) != 0)
return -1;
}
- if (bind(m_listenSocket, reinterpret_cast<sockaddr *>(&listenAddr), sizeof(listenAddr)) == -1)
- {
- m_errorStr = std::string("Cannot bind listen socket: '") + strerror(errno) + "'.";
- m_logger(m_errorStr);
+ if (!Bind())
return -1;
- }
if (listen(m_listenSocket, 64) == -1) // TODO: backlog length
{
if (res < 0)
{
m_errorStr = std::string("'select' is failed: '") + strerror(errno) + "'.";
+ printfd(__FILE__, "%s\n", m_errorStr.c_str());
m_logger(m_errorStr);
break;
}
if (!m_running)
break;
if (res > 0)
+ {
+ printfd(__FILE__, "Something happend - received %d events.\n", res);
HandleEvents(fds);
+ }
CleanupConns();
}
m_stopped = true;
}
+bool CONFIGPROTO::Bind()
+{
+ const hostent * he = gethostbyname(m_bindAddress.c_str());
+ if (he == NULL)
+ {
+ m_errorStr = "Failed to resolve name '" + m_bindAddress + "': '" + hstrerror(h_errno) + "'.";
+ printfd(__FILE__, "%s\n", m_errorStr.c_str());
+ m_logger(m_errorStr);
+ return false;
+ }
+
+ char ** ptr = he->h_addr_list;
+ while (*ptr != NULL)
+ {
+ struct sockaddr_in listenAddr;
+ listenAddr.sin_family = PF_INET;
+ listenAddr.sin_port = htons(m_port);
+ listenAddr.sin_addr.s_addr = *reinterpret_cast<in_addr_t *>(*ptr);
+
+ printfd(__FILE__, "Trying to bind to %s:%d\n", inet_ntostring(listenAddr.sin_addr.s_addr).c_str(), m_port);
+
+ if (bind(m_listenSocket, reinterpret_cast<sockaddr *>(&listenAddr), sizeof(listenAddr)) == 0)
+ return true;
+
+ m_errorStr = std::string("Cannot bind listen socket: '") + strerror(errno) + "'.";
+ printfd(__FILE__, "%s\n", m_errorStr.c_str());
+ m_logger(m_errorStr);
+
+ ++ptr;
+ }
+
+ return false;
+}
+
void CONFIGPROTO::RegisterParsers()
{
assert(m_settings != NULL);
int CONFIGPROTO::MaxFD() const
{
int maxFD = m_listenSocket;
- for (size_t i = 0; i < m_conns.size(); ++i)
- if (maxFD < m_conns[i]->Sock())
- maxFD = m_conns[i]->Sock();
+ std::deque<STG::Conn *>::const_iterator it;
+ for (it = m_conns.begin(); it != m_conns.end(); ++it)
+ if (maxFD < (*it)->Sock())
+ maxFD = (*it)->Sock();
return maxFD;
}
void CONFIGPROTO::BuildFDSet(fd_set & fds) const
{
- for (size_t i = 0; i < m_conns.size(); ++i)
- FD_SET(m_conns[i]->Sock(), &fds);
+ printfd(__FILE__, "Building fd set for %d connections.\n", m_conns.size());
+ FD_ZERO(&fds);
+ FD_SET(m_listenSocket, &fds);
+ std::deque<STG::Conn *>::const_iterator it;
+ for (it = m_conns.begin(); it != m_conns.end(); ++it)
+ FD_SET((*it)->Sock(), &fds);
}
void CONFIGPROTO::CleanupConns()
{
- std::vector<STG::Conn *>::iterator pos;
- pos = std::remove_if(m_conns.begin(), m_conns.end(), IsFinished());
- if (pos == m_conns.end())
- return;
- std::for_each(pos, m_conns.end(), RemoveConn());
+ size_t old = m_conns.size();
+
+ std::deque<STG::Conn *>::iterator pos;
+ for (pos = m_conns.begin(); pos != m_conns.end(); ++pos)
+ if (((*pos)->IsDone() && !(*pos)->IsKeepAlive()) || !(*pos)->IsOk())
+ {
+ delete *pos;
+ *pos = NULL;
+ }
+
+ pos = std::remove(m_conns.begin(), m_conns.end(), static_cast<STG::Conn *>(NULL));
m_conns.erase(pos, m_conns.end());
+
+ if (m_conns.size() < old)
+ printfd(__FILE__, "Cleaned up %d connections.\n", old - m_conns.size());
}
void CONFIGPROTO::HandleEvents(const fd_set & fds)
AcceptConnection();
else
{
- for (size_t i = 0; i < m_conns.size(); ++i)
- if (FD_ISSET(m_conns[i]->Sock(), &fds))
- m_conns[i]->Read();
+ std::deque<STG::Conn *>::iterator it;
+ for (it = m_conns.begin(); it != m_conns.end(); ++it)
+ if (FD_ISSET((*it)->Sock(), &fds))
+ {
+ printfd(__FILE__, "Reading data from %s:%d.\n", inet_ntostring((*it)->IP()).c_str(), (*it)->Port());
+ (*it)->Read();
+ }
}
}
void CONFIGPROTO::AcceptConnection()
{
+ printfd(__FILE__, "Accepting new connection.\n");
+
struct sockaddr_in outerAddr;
socklen_t outerAddrLen(sizeof(outerAddr));
int sock = accept(m_listenSocket, reinterpret_cast<sockaddr *>(&outerAddr), &outerAddrLen);
if (sock < 0)
{
m_errorStr = std::string("Failed to accept connection: '") + strerror(errno) + "'.";
- printfd(__FILE__, "%s", m_errorStr.c_str());
+ printfd(__FILE__, "%s\n", m_errorStr.c_str());
m_logger(m_errorStr);
return;
}
try
{
m_conns.push_back(new STG::Conn(m_registry, *m_admins, sock, outerAddr));
- printfd(__FILE__, "New connection from %s:%d\n", inet_ntostring(m_conns.back()->IP()).c_str(), m_conns.back()->Port());
+ printfd(__FILE__, "New connection from %s:%d. Total connections: %d\n", inet_ntostring(m_conns.back()->IP()).c_str(), m_conns.back()->Port(), m_conns.size());
}
catch (const STG::Conn::Error & error)
{
#include "stg/os_int.h"
#include <string>
-#include <vector>
+#include <deque>
#include <sys/select.h>
#include <sys/types.h>
~CONFIGPROTO();
void SetPort(uint16_t port) { m_port = port; }
+ void SetBindAddress(const std::string & address) { m_bindAddress = address; }
void SetSettings(const SETTINGS * settings) { m_settings = settings; }
void SetAdmins(ADMINS * admins) { m_admins = admins; }
void SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
STORE * m_store;
uint16_t m_port;
+ std::string m_bindAddress;
bool m_running;
bool m_stopped;
PLUGIN_LOGGER & m_logger;
std::string m_errorStr;
BASE_PARSER::REGISTRY m_registry;
- std::vector<STG::Conn *> m_conns;
+ std::deque<STG::Conn *> m_conns;
+
+ bool Bind();
void RegisterParsers();
#include <cassert>
#include <cstring>
+#include <cerrno>
#include <unistd.h>
#include <sys/socket.h>
XML_ParserReset(m_xmlParser, NULL);
XML_SetElementHandler(m_xmlParser, ParseXMLStart, ParseXMLEnd);
XML_SetUserData(m_xmlParser, this);
-
- /*m_parsers.push_back(new STG::PARSER::GET_SERVER_INFO(m_settings, m_users, m_tariffs));
-
- m_parsers.push_back(new PARSER_GET_USERS);
- m_parsers.push_back(new PARSER_GET_USER);
- m_parsers.push_back(new PARSER_CHG_USER);
- m_parsers.push_back(new PARSER_ADD_USER);
- m_parsers.push_back(new PARSER_DEL_USER);
- m_parsers.push_back(new PARSER_CHECK_USER);
- m_parsers.push_back(new PARSER_SEND_MESSAGE);
- m_parsers.push_back(new PARSER_AUTH_BY);
- m_parsers.push_back(new PARSER_USER_INFO);
-
- m_parsers.push_back(new PARSER_GET_TARIFFS);
- m_parsers.push_back(new PARSER_ADD_TARIFF);
- m_parsers.push_back(new PARSER_DEL_TARIFF);
- m_parsers.push_back(new PARSER_CHG_TARIFF);
-
- m_parsers.push_back(new PARSER_GET_ADMINS);
- m_parsers.push_back(new PARSER_CHG_ADMIN);
- m_parsers.push_back(new PARSER_DEL_ADMIN);
- m_parsers.push_back(new PARSER_ADD_ADMIN);*/
}
Conn::~Conn()
ssize_t res = read(m_sock, m_buffer, m_bufferSize);
if (res < 0)
{
+ printfd(__FILE__, "Failed to read data from %s:%d: '%s'.\n", inet_ntostring(IP()).c_str(), Port(), strerror(errno));
+ m_state = ERROR;
+ // TODO: log it
+ return false;
+ }
+ if (res == 0 && m_state != DATA) // EOF is ok for data.
+ {
+ printfd(__FILE__, "Failed to read data from %s:%d: 'EOF'.\n", inet_ntostring(IP()).c_str(), Port());
+ m_state = ERROR;
// TODO: log it
return false;
}
bool Conn::HandleBuffer(size_t size)
{
+ printfd(__FILE__, "Got %d bytes. State: %s.\n", size, (m_state == DATA ? "DATA" : (m_state == HEADER ? "HEADER" : (m_state == LOGIN ? "LOGIN" : (m_state == CRYPTO_LOGIN ? "CRYPTO_LOGIN" : (m_state == DONE ? "DONE" : "ERROR"))))));
if (m_state == DATA)
return HandleData(size);
{
if (strncmp(m_header, STG_HEADER, sizeof(m_header)) != 0)
{
- WriteAnswer(ERR_HEADER, sizeof(ERR_HEADER));
+ printfd(__FILE__, "Wrong header from %s:%d.\n", inet_ntostring(IP()).c_str(), Port());
+ WriteAnswer(ERR_HEADER, sizeof(ERR_HEADER) - 1); // Without \0
// TODO: log it
m_state = ERROR;
return false;
m_state = LOGIN;
m_buffer = m_login;
m_bufferSize = sizeof(m_login);
- return WriteAnswer(OK_HEADER, sizeof(OK_HEADER));
+ return WriteAnswer(OK_HEADER, sizeof(OK_HEADER) - 1); // Without \0
}
bool Conn::HandleLogin()
{
if (m_admins.Find(m_login, &m_admin)) // ADMINS::Find returns true on error.
{
- WriteAnswer(ERR_LOGIN, sizeof(ERR_LOGIN));
+ printfd(__FILE__, "Wrong login ('%s') from %s:%d.\n", m_login, inet_ntostring(IP()).c_str(), Port());
+ WriteAnswer(ERR_LOGIN, sizeof(ERR_LOGIN) - 1); // Without \0
// TODO: log it
m_state = ERROR;
return false;
m_state = CRYPTO_LOGIN;
m_buffer = m_cryptoLogin;
m_bufferSize = sizeof(m_cryptoLogin);
- return WriteAnswer(OK_LOGIN, sizeof(OK_LOGIN));
+ return WriteAnswer(OK_LOGIN, sizeof(OK_LOGIN) - 1); // Without \0
}
bool Conn::HandleCryptoLogin()
if (strncmp(m_login, login, sizeof(login)) != 0)
{
- WriteAnswer(ERR_LOGINS, sizeof(ERR_LOGINS));
+ printfd(__FILE__, "Wrong password from %s:%d: '%s' != '%s'.\n", inet_ntostring(IP()).c_str(), Port(), login, m_login);
+ WriteAnswer(ERR_LOGINS, sizeof(ERR_LOGINS) - 1); // Without \0
// TODO: log it
m_state = ERROR;
return false;
m_buffer = m_data;
m_bufferSize = sizeof(m_data);
m_stream = new STG::DECRYPT_STREAM(m_admin->GetPassword(), DataCallback, &m_dataState);
- return WriteAnswer(OK_LOGINS, sizeof(OK_LOGINS));
+ return WriteAnswer(OK_LOGINS, sizeof(OK_LOGINS) - 1); // Without \0
}
bool Conn::HandleData(size_t size)
assert(data != NULL);
DataState& state = *static_cast<DataState *>(data);
- if (XML_Parse(state.conn.m_xmlParser,
- static_cast<const char *>(block),
- size, state.final) == XML_STATUS_ERROR)
+ const char * xml = static_cast<const char *>(block);
+ size_t length = strnlen(xml, size);
+
+ state.final = state.final || length < size || size == 0;
+
+ if (XML_Parse(state.conn.m_xmlParser, xml, length, state.final) == XML_STATUS_ERROR)
{
// TODO: log it
- printfd(__FILE__, "XML parse error at line %d, %d: %s. Is final: %d",
+ printfd(__FILE__, "XML parse error at line %d, %d: %s. Is final: %d\n",
static_cast<int>(XML_GetCurrentLineNumber(state.conn.m_xmlParser)),
static_cast<int>(XML_GetCurrentColumnNumber(state.conn.m_xmlParser)),
XML_ErrorString(XML_GetErrorCode(state.conn.m_xmlParser)), (int)state.final);
+ printfd(__FILE__, "Data block: '%s' of size %d\n", xml, length);
+ state.conn.m_state = ERROR;
return false;
}
if (conn.m_parser == NULL)
{
+ printfd(__FILE__, "Failed to find a suitable parser for '%s'.\n", el);
// TODO: log it
conn.m_state = ERROR;
return;
}
+ else
+ printfd(__FILE__, "Using parser '%s'.\n", conn.m_parser->GetTag().c_str());
conn.m_parser->Start(data, el, attr);
}
bool Conn::WriteResponse()
{
STG::ENCRYPT_STREAM stream(m_admin->GetPassword(), WriteCallback, this);
- const std::string & answer = m_parser->GetAnswer();
+ std::string answer;
+ if (m_parser != NULL)
+ answer = m_parser->GetAnswer();
+ else
+ answer = "<Error result=\"Unknown command.\"/>";
+ printfd(__FILE__, "Writing %d bytes of answer: '%s'\n", answer.length(), answer.c_str());
stream.Put(answer.c_str(), answer.length() + 1 /* including \0 */, true /* final */);
return stream.IsOk();
}
void * m_buffer;
size_t m_bufferSize;
- char m_header[sizeof(STG_HEADER)];
- char m_login[ADM_LOGIN_LEN + 1];
- char m_cryptoLogin[ADM_LOGIN_LEN + 1];
+ char m_header[sizeof(STG_HEADER) - 1]; // Without \0
+ char m_login[ADM_LOGIN_LEN]; // Without \0
+ char m_cryptoLogin[ADM_LOGIN_LEN]; // Without \0
char m_data[1024];
STG::DECRYPT_STREAM * m_stream;
//-----------------------------------------------------------------------------
int BASE_PARSER::End(void *, const char * el)
{
- if (m_depth == 1)
+ if (m_depth < 2)
{
if (strcasecmp(el, m_tag.c_str()) != 0)
return -1;
return;
}
- m_answer.clear();
-
- m_answer += GetOpenTag();
+ m_answer = "<Admins>";
ADMIN_CONF ac;
int h = m_admins.OpenSearch();
m_answer += "<admin login=\"" + ac.login + "\" priv=\"" + x2str(p) + "\"/>";
}
m_admins.CloseSearch(h);
- m_answer += GetCloseTag();
+ m_answer += "</Admins>";
}
int DEL_ADMIN::Start(void *, const char * el, const char ** attr)
#include "parser_server_info.h"
+#include "stg/settings.h"
+#include "stg/users.h"
+#include "stg/tariffs.h"
#include "stg/common.h"
#include "stg/version.h"
#include "stg/const.h"
utsn.machine + " " +
utsn.nodename;
- answer = GetOpenTag() + "<version value=\"" + SERVER_VERSION + "\"/>" +
- "<tariff_num value=\"" + x2str(tariffs.Count()) + "\"/>" +
- "<tariff value=\"2\"/>" +
- "<user_num value=\"" + x2str(users.Count()) + "\"/>" +
- "<uname value=\"" + name + "\"/>" +
- "<dir_num value=\"" + x2str(DIR_NUM) + "\"/>" +
- "<day_fee value=\"" + x2str(settings.GetDayFee()) + "\"/>";
+ m_answer = GetOpenTag() + "<version value=\"" + SERVER_VERSION + "\"/>" +
+ "<tariff_num value=\"" + x2str(m_tariffs.Count()) + "\"/>" +
+ "<tariff value=\"2\"/>" +
+ "<user_num value=\"" + x2str(m_users.Count()) + "\"/>" +
+ "<uname value=\"" + name + "\"/>" +
+ "<dir_num value=\"" + x2str(DIR_NUM) + "\"/>" +
+ "<day_fee value=\"" + x2str(m_settings.GetDayFee()) + "\"/>";
for (size_t i = 0; i< DIR_NUM; i++)
- answer += "<dir_name_" + x2str(i) + " value=\"" + Encode12str(settings.GetDirName(i)) + "\"/>";
+ m_answer += "<dir_name_" + x2str(i) + " value=\"" + Encode12str(m_settings.GetDirName(i)) + "\"/>";
- answer += GetCloseTag();
+ m_answer += GetCloseTag();
}
#include "parser.h"
class ADMIN;
+class SETTINGS;
+class USERS;
+class TARIFFS;
namespace STG
{
void GET_TARIFFS::CreateAnswer()
{
- m_answer = GetOpenTag();
+ m_answer = "<Tariffs>";
std::list<TARIFF_DATA> dataList;
m_tariffs.GetTariffsData(&dataList);
"</tariff>";
}
- m_answer += GetCloseTag();
+ m_answer += "</Tariffs>";
}
int ADD_TARIFF::Start(void *, const char * el, const char ** attr)
int GET_USERS::Start(void *, const char * el, const char ** attr)
{
if (strcasecmp(el, m_tag.c_str()) != 0)
+ {
+ printfd(__FILE__, "Got wrong tag: '%s' instead of '%s'\n", el, m_tag.c_str());
return -1;
+ }
while (attr && *attr && *(attr + 1))
{
assert(h);
if (m_lastUserUpdateTime > 0)
- m_answer = "<" + m_tag + " LastUpdate=\"" + x2str(time(NULL)) + "\">";
+ m_answer = "<Users LastUpdate=\"" + x2str(time(NULL)) + "\">";
else
- m_answer = GetOpenTag();
+ m_answer = "<Users>";
USER_PTR u;
m_users.CloseSearch(h);
- m_answer += GetCloseTag();
+ m_answer += "</Users>";
}
int GET_USER::Start(void *, const char * el, const char ** attr)
CONST_USER_PTR u;
if (m_users.FindByName(m_login, &u))
- m_answer = "<" + m_tag + " result=\"error\" reason=\"User not found.\"/>";
+ m_answer = "<User result=\"error\" reason=\"User not found.\"/>";
else
m_answer = UserToXML(*u, false, m_currAdmin.GetPriv()->userConf || m_currAdmin.GetPriv()->userPasswd);
}
#include <algorithm>
#include <csignal>
-
-#include <unistd.h>
+#include <cstring>
+#include <cerrno>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-int STG_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
+bool STG_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
-int p;
-PARAM_VALUE pv;
-std::vector<PARAM_VALUE>::const_iterator pvi;
-///////////////////////////
-pv.param = "Port";
-pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
-if (pvi == s.moduleParams.end())
- {
- errorStr = "Parameter \'Port\' not found.";
- printfd(__FILE__, "Parameter 'Port' not found\n");
- return -1;
- }
-if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
- {
- errorStr = "Cannot parse parameter \'Port\': " + errorStr;
- printfd(__FILE__, "%s\n", errorStr.c_str());
- return -1;
- }
-port = static_cast<uint16_t>(p);
-
-return 0;
+ PARAM_VALUE pv;
+ std::vector<PARAM_VALUE>::const_iterator pvi;
+ ///////////////////////////
+ pv.param = "Port";
+ pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+ if (pvi == s.moduleParams.end())
+ {
+ errorStr = "Parameter \'Port\' is not found.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return false;
+ }
+ int p;
+ if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
+ {
+ errorStr = "Parameter \'Port\' should be an integral value in range (2, 65535). Actual value: '" + pvi->value[0] + "'.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return false;
+ }
+ m_port = static_cast<uint16_t>(p);
+
+ pv.param = "BindAddress";
+ pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+ if (pvi != s.moduleParams.end())
+ m_bindAddress = pvi->value[0];
+
+ return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
STG_CONFIG::STG_CONFIG()
- : errorStr(),
- stgConfigSettings(),
- thread(),
- nonstop(false),
+ : nonstop(false),
isRunning(false),
logger(GetPluginLogger(GetStgLogger(), "conf_sg")),
- config(logger),
- settings()
+ config(logger)
{
}
//-----------------------------------------------------------------------------
int STG_CONFIG::ParseSettings()
{
-int ret = stgConfigSettings.ParseSettings(settings);
-if (ret)
+ if (stgConfigSettings.ParseSettings(settings))
+ return 0;
errorStr = stgConfigSettings.GetStrError();
-return ret;
+ return -1;
}
//-----------------------------------------------------------------------------
int STG_CONFIG::Start()
{
-if (isRunning)
- return 0;
+ if (isRunning)
+ return 0;
-nonstop = true;
+ nonstop = true;
-config.SetPort(stgConfigSettings.GetPort());
+ config.SetPort(stgConfigSettings.GetPort());
+ config.SetBindAddress(stgConfigSettings.GetBindAddress());
-if (config.Prepare())
+ if (config.Prepare())
{
- errorStr = config.GetStrError();
- return -1;
+ errorStr = config.GetStrError();
+ return -1;
}
-if (pthread_create(&thread, NULL, Run, this))
+ if (pthread_create(&thread, NULL, Run, this))
{
- errorStr = "Cannot create thread.";
- printfd(__FILE__, "Cannot create thread\n");
- logger("Cannot create thread.");
- return -1;
+ errorStr = std::string("Cannot create thread: '") + strerror(errno) + "'.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ logger(errorStr);
+ return -1;
}
-errorStr = "";
-return 0;
+
+ return 0;
}
//-----------------------------------------------------------------------------
int STG_CONFIG::Stop()
{
-if (!isRunning)
- return 0;
+ if (!isRunning)
+ return 0;
-config.Stop();
+ config.Stop();
-//5 seconds to thread stops itself
-for (int i = 0; i < 25; i++)
+ //5 seconds to thread stops itself
+ for (size_t i = 0; i < 25; ++i)
{
- if (!isRunning)
- break;
+ if (!isRunning)
+ break;
- struct timespec ts = {0, 200000000};
- nanosleep(&ts, NULL);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
-if (isRunning)
- return -1;
+ if (isRunning)
+ return -1;
-return 0;
+ return 0;
}
//-----------------------------------------------------------------------------
void * STG_CONFIG::Run(void * d)
{
-sigset_t signalSet;
-sigfillset(&signalSet);
-pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+ sigset_t signalSet;
+ sigfillset(&signalSet);
+ pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-STG_CONFIG * stgConf = static_cast<STG_CONFIG *>(d);
-stgConf->isRunning = true;
+ STG_CONFIG & stgConf = *static_cast<STG_CONFIG *>(d);
+ stgConf.isRunning = true;
-stgConf->config.Run();
+ stgConf.config.Run();
-stgConf->isRunning = false;
-return NULL;
+ stgConf.isRunning = false;
+
+ return NULL;
}
-//-----------------------------------------------------------------------------
#include <pthread.h>
-class STG_CONFIG_SETTINGS {
-public:
- STG_CONFIG_SETTINGS() : errorStr(), port(0) {}
- virtual ~STG_CONFIG_SETTINGS() {}
- const std::string & GetStrError() const { return errorStr; }
- int ParseSettings(const MODULE_SETTINGS & s);
- uint16_t GetPort() const { return port; }
-private:
- std::string errorStr;
- uint16_t port;
+class STG_CONFIG_SETTINGS
+{
+ public:
+ STG_CONFIG_SETTINGS() : m_port(0), m_bindAddress("0.0.0.0") {}
+ virtual ~STG_CONFIG_SETTINGS() {}
+ const std::string & GetStrError() const { return errorStr; }
+ bool ParseSettings(const MODULE_SETTINGS & s);
+ uint16_t GetPort() const { return m_port; }
+ const std::string & GetBindAddress() const { return m_bindAddress; }
+ private:
+ std::string errorStr;
+ uint16_t m_port;
+ std::string m_bindAddress;
};
-//-----------------------------------------------------------------------------
-class STG_CONFIG : public PLUGIN {
-public:
- STG_CONFIG();
- virtual ~STG_CONFIG(){}
- void SetUsers(USERS * users) { config.SetUsers(users); }
- void SetTariffs(TARIFFS * tariffs) { config.SetTariffs(tariffs); }
- void SetAdmins(ADMINS * admins) { config.SetAdmins(admins); }
- void SetStore(STORE * store) { config.SetStore(store); }
- void SetStgSettings(const SETTINGS * s) { config.SetSettings(s); }
- void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
- int ParseSettings();
+class STG_CONFIG : public PLUGIN
+{
+ public:
+ STG_CONFIG();
+
+ void SetUsers(USERS * users) { config.SetUsers(users); }
+ void SetTariffs(TARIFFS * tariffs) { config.SetTariffs(tariffs); }
+ void SetAdmins(ADMINS * admins) { config.SetAdmins(admins); }
+ void SetStore(STORE * store) { config.SetStore(store); }
+ void SetStgSettings(const SETTINGS * s) { config.SetSettings(s); }
+ void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
+ int ParseSettings();
- int Start();
- int Stop();
- int Reload() { return 0; }
- bool IsRunning() { return isRunning; }
+ int Start();
+ int Stop();
+ int Reload() { return 0; }
+ bool IsRunning() { return isRunning; }
- const std::string & GetStrError() const { return errorStr; }
- std::string GetVersion() const { return "Stg Configurator v. 2.0"; }
- uint16_t GetStartPosition() const { return 20; }
- uint16_t GetStopPosition() const { return 20; }
+ const std::string & GetStrError() const { return errorStr; }
+ std::string GetVersion() const { return "Stg Configurator v. 2.0"; }
+ uint16_t GetStartPosition() const { return 20; }
+ uint16_t GetStopPosition() const { return 20; }
-private:
- STG_CONFIG(const STG_CONFIG & rvalue);
- STG_CONFIG & operator=(const STG_CONFIG & rvalue);
+ private:
+ STG_CONFIG(const STG_CONFIG & rvalue);
+ STG_CONFIG & operator=(const STG_CONFIG & rvalue);
- static void * Run(void *);
+ static void * Run(void *);
- mutable std::string errorStr;
- STG_CONFIG_SETTINGS stgConfigSettings;
- pthread_t thread;
- bool nonstop;
- bool isRunning;
- PLUGIN_LOGGER logger;
- CONFIGPROTO config;
- MODULE_SETTINGS settings;
+ mutable std::string errorStr;
+ STG_CONFIG_SETTINGS stgConfigSettings;
+ pthread_t thread;
+ bool nonstop;
+ bool isRunning;
+ PLUGIN_LOGGER logger;
+ CONFIGPROTO config;
+ MODULE_SETTINGS settings;
};
//-----------------------------------------------------------------------------