]> git.stg.codes - stg.git/commitdiff
Finished new implementation of sgconfig plugin.
authorMaxim Mamontov <faust.madf@gmail.com>
Mon, 22 Sep 2014 20:28:31 +0000 (23:28 +0300)
committerMaxim Mamontov <faust.madf@gmail.com>
Fri, 9 Jan 2015 21:33:57 +0000 (23:33 +0200)
13 files changed:
projects/stargazer/plugins/configuration/sgconfig/Makefile
projects/stargazer/plugins/configuration/sgconfig/configproto.cpp
projects/stargazer/plugins/configuration/sgconfig/configproto.h
projects/stargazer/plugins/configuration/sgconfig/conn.cpp
projects/stargazer/plugins/configuration/sgconfig/conn.h
projects/stargazer/plugins/configuration/sgconfig/parser.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_admins.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_server_info.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_server_info.h
projects/stargazer/plugins/configuration/sgconfig/parser_tariffs.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_users.cpp
projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp
projects/stargazer/plugins/configuration/sgconfig/stgconfig.h

index 3f6f24a618f34f99c306f60f8e40db2af98ce7dc..40a5c534c9e933a5b44eb1c11628eff82642e011 100644 (file)
@@ -15,7 +15,8 @@ SRCS = ./stgconfig.cpp \
        ./parser_users.cpp \
        ./parser_message.cpp \
        ./parser_auth_by.cpp \
        ./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)
 
 LIBS += -lexpat \
        $(LIB_THREAD)
index 7052ecc2d394d4fd3ad88abe98ca9bca56837365..d9f87eca5884786abaffca61a9c5ef621cdb05b8 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <algorithm>
 #include <functional>
 
 #include <algorithm>
 #include <functional>
+#include <vector>
 #include <csignal>
 #include <cstring>
 #include <cerrno>
 #include <csignal>
 #include <cstring>
 #include <cerrno>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
+#include <netdb.h>
 
 namespace SP = STG::PARSER;
 
 
 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),
 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),
       m_running(false),
       m_stopped(true),
       m_logger(l),
@@ -83,7 +64,9 @@ CONFIGPROTO::CONFIGPROTO(PLUGIN_LOGGER & l)
 
 CONFIGPROTO::~CONFIGPROTO()
 {
 
 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()
 }
 
 int CONFIGPROTO::Prepare()
@@ -105,11 +88,6 @@ int CONFIGPROTO::Prepare()
         return -1;
     }
 
         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)
     int dummy = 1;
 
     if (setsockopt(m_listenSocket, SOL_SOCKET, SO_REUSEADDR, &dummy, 4) != 0)
@@ -119,12 +97,8 @@ int CONFIGPROTO::Prepare()
         return -1;
     }
 
         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;
         return -1;
-    }
 
     if (listen(m_listenSocket, 64) == -1) // TODO: backlog length
     {
 
     if (listen(m_listenSocket, 64) == -1) // TODO: backlog length
     {
@@ -177,19 +151,57 @@ void CONFIGPROTO::Run()
         if (res < 0)
         {
             m_errorStr = std::string("'select' is failed: '") + strerror(errno) + "'.";
         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)
             m_logger(m_errorStr);
             break;
         }
         if (!m_running)
             break;
         if (res > 0)
+        {
+            printfd(__FILE__, "Something happend - received %d events.\n", res);
             HandleEvents(fds);
             HandleEvents(fds);
+        }
 
         CleanupConns();
     }
     m_stopped = true;
 }
 
 
         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);
 void CONFIGPROTO::RegisterParsers()
 {
     assert(m_settings != NULL);
@@ -227,26 +239,40 @@ void CONFIGPROTO::RegisterParsers()
 int CONFIGPROTO::MaxFD() const
 {
     int maxFD = m_listenSocket;
 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
 {
     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()
 {
 }
 
 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());
     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)
 }
 
 void CONFIGPROTO::HandleEvents(const fd_set & fds)
@@ -255,14 +281,20 @@ void CONFIGPROTO::HandleEvents(const fd_set & fds)
         AcceptConnection();
     else
     {
         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()
 {
     }
 }
 
 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);
     struct sockaddr_in outerAddr;
     socklen_t outerAddrLen(sizeof(outerAddr));
     int sock = accept(m_listenSocket, reinterpret_cast<sockaddr *>(&outerAddr), &outerAddrLen);
@@ -270,7 +302,7 @@ void CONFIGPROTO::AcceptConnection()
     if (sock < 0)
     {
         m_errorStr = std::string("Failed to accept connection: '") + strerror(errno) + "'.";
     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;
     }
         m_logger(m_errorStr);
         return;
     }
@@ -280,7 +312,7 @@ void CONFIGPROTO::AcceptConnection()
     try
     {
         m_conns.push_back(new STG::Conn(m_registry, *m_admins, sock, outerAddr));
     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)
     {
     }
     catch (const STG::Conn::Error & error)
     {
index 6e296836ac8d27730a2b1610fd9ce7564abccacc..2119bc675214c22aae0eb2f1c3589f659e592c81 100644 (file)
@@ -28,7 +28,7 @@
 #include "stg/os_int.h"
 
 #include <string>
 #include "stg/os_int.h"
 
 #include <string>
-#include <vector>
+#include <deque>
 
 #include <sys/select.h>
 #include <sys/types.h>
 
 #include <sys/select.h>
 #include <sys/types.h>
@@ -54,6 +54,7 @@ public:
     ~CONFIGPROTO();
 
     void            SetPort(uint16_t port) { m_port = port; }
     ~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; }
     void            SetSettings(const SETTINGS * settings) { m_settings = settings; }
     void            SetAdmins(ADMINS * admins) { m_admins = admins; }
     void            SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
@@ -76,6 +77,7 @@ private:
     STORE *          m_store;
 
     uint16_t         m_port;
     STORE *          m_store;
 
     uint16_t         m_port;
+    std::string      m_bindAddress;
     bool             m_running;
     bool             m_stopped;
     PLUGIN_LOGGER &  m_logger;
     bool             m_running;
     bool             m_stopped;
     PLUGIN_LOGGER &  m_logger;
@@ -84,7 +86,9 @@ private:
     std::string      m_errorStr;
 
     BASE_PARSER::REGISTRY m_registry;
     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();
 
 
     void RegisterParsers();
 
index 1d5d0afff29a024bec91fcc6291ec02d1486729c..abcc677b34916619eea4811c8c8144102ba0d399 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <cassert>
 #include <cstring>
 
 #include <cassert>
 #include <cstring>
+#include <cerrno>
 
 #include <unistd.h>
 #include <sys/socket.h>
 
 #include <unistd.h>
 #include <sys/socket.h>
@@ -64,28 +65,6 @@ Conn::Conn(const BASE_PARSER::REGISTRY & registry,
     XML_ParserReset(m_xmlParser, NULL);
     XML_SetElementHandler(m_xmlParser, ParseXMLStart, ParseXMLEnd);
     XML_SetUserData(m_xmlParser, this);
     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()
 }
 
 Conn::~Conn()
@@ -101,6 +80,15 @@ bool Conn::Read()
     ssize_t res = read(m_sock, m_buffer, m_bufferSize);
     if (res < 0)
     {
     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;
     }
         // TODO: log it
         return false;
     }
@@ -129,6 +117,7 @@ BASE_PARSER * Conn::GetParser(const std::string & tag) const
 
 bool Conn::HandleBuffer(size_t size)
 {
 
 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 (m_state == DATA)
         return HandleData(size);
 
@@ -150,7 +139,8 @@ bool Conn::HandleHeader()
 {
     if (strncmp(m_header, STG_HEADER, sizeof(m_header)) != 0)
     {
 {
     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;
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -158,14 +148,15 @@ bool Conn::HandleHeader()
     m_state = LOGIN;
     m_buffer = m_login;
     m_bufferSize = sizeof(m_login);
     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.
     {
 }
 
 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;
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -174,7 +165,7 @@ bool Conn::HandleLogin()
     m_state = CRYPTO_LOGIN;
     m_buffer = m_cryptoLogin;
     m_bufferSize = sizeof(m_cryptoLogin);
     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()
 }
 
 bool Conn::HandleCryptoLogin()
@@ -186,7 +177,8 @@ bool Conn::HandleCryptoLogin()
 
     if (strncmp(m_login, login, sizeof(login)) != 0)
     {
 
     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;
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -196,7 +188,7 @@ bool Conn::HandleCryptoLogin()
     m_buffer = m_data;
     m_bufferSize = sizeof(m_data);
     m_stream = new STG::DECRYPT_STREAM(m_admin->GetPassword(), DataCallback, &m_dataState);
     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)
 }
 
 bool Conn::HandleData(size_t size)
@@ -210,15 +202,20 @@ bool Conn::DataCallback(const void * block, size_t size, void * data)
     assert(data != NULL);
     DataState& state = *static_cast<DataState *>(data);
 
     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
     {
         // 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);
                   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;
     }
 
         return false;
     }
 
@@ -246,10 +243,13 @@ void Conn::ParseXMLStart(void * data, const char * el, const char ** attr)
 
     if (conn.m_parser == NULL)
     {
 
     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;
     }
         // 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);
 }
 
     conn.m_parser->Start(data, el, attr);
 }
@@ -272,7 +272,12 @@ void Conn::ParseXMLEnd(void * data, const char * el)
 bool Conn::WriteResponse()
 {
     STG::ENCRYPT_STREAM stream(m_admin->GetPassword(), WriteCallback, this);
 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();
 }
     stream.Put(answer.c_str(), answer.length() + 1 /* including \0 */, true /* final */);
     return stream.IsOk();
 }
index 7825d4f9ec2eb54711c4a38deff3db1622e933fb..8f76b7e94635b672f241341b97ba539638384f61 100644 (file)
@@ -95,9 +95,9 @@ class Conn
 
         void * m_buffer;
         size_t m_bufferSize;
 
         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;
 
         char m_data[1024];
         STG::DECRYPT_STREAM * m_stream;
 
index b984adf63e62758295d728126522ce7b99bbdfa1..0371798197d287aaf4d8e5f778b0efdbcf4e1944 100644 (file)
@@ -35,7 +35,7 @@ int BASE_PARSER::Start(void *, const char * el, const char **)
 //-----------------------------------------------------------------------------
 int BASE_PARSER::End(void *, const char * el)
 {
 //-----------------------------------------------------------------------------
 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;
     {
         if (strcasecmp(el, m_tag.c_str()) != 0)
             return -1;
index d9b6cfc9054adae2797fcdbaa1f7c76b44a0e4cf..740d86a7d3f83b29d9ab67b0f4ccebc629b4b769 100644 (file)
@@ -45,9 +45,7 @@ void GET_ADMINS::CreateAnswer()
         return;
     }
 
         return;
     }
 
-    m_answer.clear();
-
-    m_answer += GetOpenTag();
+    m_answer = "<Admins>";
     ADMIN_CONF ac;
     int h = m_admins.OpenSearch();
 
     ADMIN_CONF ac;
     int h = m_admins.OpenSearch();
 
@@ -63,7 +61,7 @@ void GET_ADMINS::CreateAnswer()
         m_answer += "<admin login=\"" + ac.login + "\" priv=\"" + x2str(p) + "\"/>";
     }
     m_admins.CloseSearch(h);
         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)
 }
 
 int DEL_ADMIN::Start(void *, const char * el, const char ** attr)
index 299b520c4ae1d3882f7abfb17689424f24ef81e6..0cb215d0afcde4d8072fb5eeb9f415965c460ea2 100644 (file)
@@ -21,6 +21,9 @@
 
 #include "parser_server_info.h"
 
 
 #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"
 #include "stg/common.h"
 #include "stg/version.h"
 #include "stg/const.h"
@@ -44,16 +47,16 @@ void GET_SERVER_INFO::CreateAnswer()
                        utsn.machine + " " +
                        utsn.nodename;
 
                        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++)
 
     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();
 }
 }
index cc71c73a47d4c0df1346b742d84ce4c9c3c15674..1b76659f82c9f2b164d00856828b7e90e5035ccb 100644 (file)
@@ -25,6 +25,9 @@
 #include "parser.h"
 
 class ADMIN;
 #include "parser.h"
 
 class ADMIN;
+class SETTINGS;
+class USERS;
+class TARIFFS;
 
 namespace STG
 {
 
 namespace STG
 {
index 5088ee9dbe4397e3966c88a8d271c9afb1d6b5b4..4763e97fd47a945411acd6d0ad382cf0ed27bbfa 100644 (file)
@@ -81,7 +81,7 @@ bool String2AOS(const std::string & source, A & array, size_t size, RESETABLE<F>
 
 void GET_TARIFFS::CreateAnswer()
 {
 
 void GET_TARIFFS::CreateAnswer()
 {
-    m_answer = GetOpenTag();
+    m_answer = "<Tariffs>";
 
     std::list<TARIFF_DATA> dataList;
     m_tariffs.GetTariffsData(&dataList);
 
     std::list<TARIFF_DATA> dataList;
     m_tariffs.GetTariffsData(&dataList);
@@ -110,7 +110,7 @@ void GET_TARIFFS::CreateAnswer()
                   "</tariff>";
         }
 
                   "</tariff>";
         }
 
-    m_answer += GetCloseTag();
+    m_answer += "</Tariffs>";
 }
 
 int ADD_TARIFF::Start(void *, const char * el, const char ** attr)
 }
 
 int ADD_TARIFF::Start(void *, const char * el, const char ** attr)
index c9a2e3d38fac40a5eb3aaf38250073a5eafd7d22..f596bfbfd9f0fc87d4a6109ccb3ed8b4170f73ee 100644 (file)
@@ -177,7 +177,10 @@ std::string UserToXML(const USER & user, bool loginInStart, bool showPass, time_
 int GET_USERS::Start(void *, const char * el, const char ** attr)
 {
     if (strcasecmp(el, m_tag.c_str()) != 0)
 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;
         return -1;
+    }
 
     while (attr && *attr && *(attr + 1))
     {
 
     while (attr && *attr && *(attr + 1))
     {
@@ -195,9 +198,9 @@ void GET_USERS::CreateAnswer()
     assert(h);
 
     if (m_lastUserUpdateTime > 0)
     assert(h);
 
     if (m_lastUserUpdateTime > 0)
-        m_answer = "<" + m_tag + " LastUpdate=\"" + x2str(time(NULL)) + "\">";
+        m_answer = "<Users LastUpdate=\"" + x2str(time(NULL)) + "\">";
     else
     else
-        m_answer = GetOpenTag();
+        m_answer = "<Users>";
 
     USER_PTR u;
 
 
     USER_PTR u;
 
@@ -206,7 +209,7 @@ void GET_USERS::CreateAnswer()
 
     m_users.CloseSearch(h);
 
 
     m_users.CloseSearch(h);
 
-    m_answer += GetCloseTag();
+    m_answer += "</Users>";
 }
 
 int GET_USER::Start(void *, const char * el, const char ** attr)
 }
 
 int GET_USER::Start(void *, const char * el, const char ** attr)
@@ -226,7 +229,7 @@ void GET_USER::CreateAnswer()
     CONST_USER_PTR u;
 
     if (m_users.FindByName(m_login, &u))
     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);
 }
     else
         m_answer = UserToXML(*u, false, m_currAdmin.GetPriv()->userConf || m_currAdmin.GetPriv()->userPasswd);
 }
index 88ccfd851e72a48af802317e4f6d3e370668d5e0..ca2dd4405e8594bbcff11abe20eb53143cc14524 100644 (file)
@@ -25,8 +25,8 @@
 
 #include <algorithm>
 #include <csignal>
 
 #include <algorithm>
 #include <csignal>
-
-#include <unistd.h>
+#include <cstring>
+#include <cerrno>
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -35,29 +35,34 @@ static PLUGIN_CREATOR<STG_CONFIG> stgc;
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-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;
 }
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 }
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -70,86 +75,83 @@ return stgc.GetPlugin();
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 STG_CONFIG::STG_CONFIG()
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 STG_CONFIG::STG_CONFIG()
-    : errorStr(),
-      stgConfigSettings(),
-      thread(),
-      nonstop(false),
+    : nonstop(false),
       isRunning(false),
       logger(GetPluginLogger(GetStgLogger(), "conf_sg")),
       isRunning(false),
       logger(GetPluginLogger(GetStgLogger(), "conf_sg")),
-      config(logger),
-      settings()
+      config(logger)
 {
 }
 //-----------------------------------------------------------------------------
 int STG_CONFIG::ParseSettings()
 {
 {
 }
 //-----------------------------------------------------------------------------
 int STG_CONFIG::ParseSettings()
 {
-int ret = stgConfigSettings.ParseSettings(settings);
-if (ret)
+    if (stgConfigSettings.ParseSettings(settings))
+        return 0;
     errorStr = stgConfigSettings.GetStrError();
     errorStr = stgConfigSettings.GetStrError();
-return ret;
+    return -1;
 }
 //-----------------------------------------------------------------------------
 int STG_CONFIG::Start()
 {
 }
 //-----------------------------------------------------------------------------
 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()
 {
 }
 //-----------------------------------------------------------------------------
 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)
 {
 }
 //-----------------------------------------------------------------------------
 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;
 }
 }
-//-----------------------------------------------------------------------------
index 0e344e816cf135e2f21e6275a45f0426429bf57f..287c3813a87a109473aa7c21565eb4888b7d6906 100644 (file)
 
 #include <pthread.h>
 
 
 #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;
 };
 //-----------------------------------------------------------------------------
 
 };
 //-----------------------------------------------------------------------------