]> git.stg.codes - stg.git/blobdiff - projects/stargazer/plugins/configuration/sgconfig/conn.cpp
Implemented parser registry.
[stg.git] / projects / stargazer / plugins / configuration / sgconfig / conn.cpp
index 718e7c565af929dfd9359d65ee56d263fc9e7b7b..1d5d0afff29a024bec91fcc6291ec02d1486729c 100644 (file)
 
 #include "conn.h"
 
-#include "parser.h"
-
-#include "parser_server_info.h"
-#include "parser_admins.h"
-#include "parser_tariffs.h"
-#include "parser_users.h"
-#include "parser_message.h"
-#include "parser_auth_by.h"
-#include "parser_user_info.h"
-
-#include "stg/settings.h"
 #include "stg/admins.h"
-#include "stg/users.h"
-#include "stg/tariffs.h"
 #include "stg/admin.h"
 #include "stg/blowfish.h"
 #include "stg/bfstream.h"
 #include "stg/common.h"
 
 #include <cassert>
+#include <cstring>
 
 #include <unistd.h>
 #include <sys/socket.h>
@@ -54,15 +42,10 @@ const char Conn::ERR_LOGIN[] = "ERLG";
 const char Conn::OK_LOGINS[] = "OKLS";
 const char Conn::ERR_LOGINS[] = "ERLS";
 
-Conn::Conn(const SETTINGS & settings,
-           ADMINS & admins,
-           USERS & users,
-           TARIFFS & tariffs,
-           int sock, const sockaddr_in& addr)
-    : m_settings(settings),
+Conn::Conn(const BASE_PARSER::REGISTRY & registry,
+           ADMINS & admins, int sock, const sockaddr_in& addr)
+    : m_registry(registry),
       m_admins(admins),
-      m_users(users),
-      m_tariffs(tariffs),
       m_admin(NULL),
       m_sock(sock),
       m_addr(addr),
@@ -110,9 +93,6 @@ Conn::~Conn()
     shutdown(m_sock, SHUT_RDWR);
     close(m_sock);
 
-    /*std::map<std::string, BASE_PARSER *>::iterator it(m_parsers.begin());
-    for (; it != m_parsers.end(); ++it)
-        delete it->second;*/
     XML_ParserFree(m_xmlParser);
 }
 
@@ -128,19 +108,23 @@ bool Conn::Read()
     return HandleBuffer(res);
 }
 
-BASE_PARSER * Conn::GetParser(const std::string & tag)
+bool Conn::WriteAnswer(const void* buffer, size_t size)
 {
-    if (strcasecmp(tag.c_str(), "getserverinfo") == 0)
-        return new STG::PARSER::GET_SERVER_INFO(*m_admin, m_settings, m_users, m_tariffs);
-    if (strcasecmp(tag.c_str(), "getadmins") == 0)
-        return new STG::PARSER::GET_ADMINS(*m_admin, m_admins);
-    if (strcasecmp(tag.c_str(), "addadmin") == 0)
-        return new STG::PARSER::ADD_ADMIN(*m_admin, m_admins);
-    if (strcasecmp(tag.c_str(), "deladmin") == 0)
-        return new STG::PARSER::DEL_ADMIN(*m_admin, m_admins);
-    if (strcasecmp(tag.c_str(), "chgadmin") == 0)
-        return new STG::PARSER::CHG_ADMIN(*m_admin, m_admins);
-    return NULL;
+    ssize_t res = write(m_sock, buffer, size);
+    if (res < 0)
+    {
+        // TODO: log it
+        return false;
+    }
+    return true;
+}
+
+BASE_PARSER * Conn::GetParser(const std::string & tag) const
+{
+    BASE_PARSER::REGISTRY::const_iterator it = m_registry.find(tag);
+    if (it == m_registry.end())
+        return NULL;
+    return it->second->create(*m_admin);
 }
 
 bool Conn::HandleBuffer(size_t size)
@@ -166,6 +150,7 @@ bool Conn::HandleHeader()
 {
     if (strncmp(m_header, STG_HEADER, sizeof(m_header)) != 0)
     {
+        WriteAnswer(ERR_HEADER, sizeof(ERR_HEADER));
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -173,13 +158,14 @@ bool Conn::HandleHeader()
     m_state = LOGIN;
     m_buffer = m_login;
     m_bufferSize = sizeof(m_login);
-    return true;
+    return WriteAnswer(OK_HEADER, sizeof(OK_HEADER));
 }
 
 bool Conn::HandleLogin()
 {
     if (m_admins.Find(m_login, &m_admin)) // ADMINS::Find returns true on error.
     {
+        WriteAnswer(ERR_LOGIN, sizeof(ERR_LOGIN));
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -188,7 +174,7 @@ bool Conn::HandleLogin()
     m_state = CRYPTO_LOGIN;
     m_buffer = m_cryptoLogin;
     m_bufferSize = sizeof(m_cryptoLogin);
-    return true;
+    return WriteAnswer(OK_LOGIN, sizeof(OK_LOGIN));
 }
 
 bool Conn::HandleCryptoLogin()
@@ -200,6 +186,7 @@ bool Conn::HandleCryptoLogin()
 
     if (strncmp(m_login, login, sizeof(login)) != 0)
     {
+        WriteAnswer(ERR_LOGINS, sizeof(ERR_LOGINS));
         // TODO: log it
         m_state = ERROR;
         return false;
@@ -209,7 +196,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);
-    return true;
+    return WriteAnswer(OK_LOGINS, sizeof(OK_LOGINS));
 }
 
 bool Conn::HandleData(size_t size)
@@ -235,6 +222,17 @@ bool Conn::DataCallback(const void * block, size_t size, void * data)
         return false;
     }
 
+    if (state.final)
+    {
+        if (!state.conn.WriteResponse())
+        {
+            // TODO: log it
+            state.conn.m_state = ERROR;
+            return false;
+        }
+        state.conn.m_state = DONE;
+    }
+
     return true;
 }
 
@@ -270,3 +268,18 @@ void Conn::ParseXMLEnd(void * data, const char * el)
 
     conn.m_parser->End(data, el);
 }
+
+bool Conn::WriteResponse()
+{
+    STG::ENCRYPT_STREAM stream(m_admin->GetPassword(), WriteCallback, this);
+    const std::string & answer = m_parser->GetAnswer();
+    stream.Put(answer.c_str(), answer.length() + 1 /* including \0 */, true /* final */);
+    return stream.IsOk();
+}
+
+bool Conn::WriteCallback(const void * block, size_t size, void * data)
+{
+    assert(data != NULL);
+    Conn & conn = *static_cast<Conn *>(data);
+    return WriteAll(conn.m_sock, block, size);;
+}