]> git.stg.codes - stg.git/blobdiff - projects/stargazer/plugins/other/rscript/rscript.cpp
Update README.
[stg.git] / projects / stargazer / plugins / other / rscript / rscript.cpp
index 8b0e2054a984154961eeb1e31dffbd54ff6fe96e..36e84be832cc1a7c68cfadd2095238840730dfe1 100644 (file)
 
 extern volatile time_t stgTime;
 
+namespace RS = STG::RS;
 using RS::REMOTE_SCRIPT;
 
-namespace {
-
-template<typename T>
-struct USER_IS
-{
-    explicit USER_IS(RS::UserPtr u) : user(u) {}
-    bool operator()(const T & notifier) { return notifier.GetUser() == user; }
-
-    RS::UserPtr user;
-};
-
-} // namespace anonymous
-
 extern "C" STG::Plugin* GetPlugin()
 {
     static REMOTE_SCRIPT plugin;
@@ -74,22 +62,21 @@ RS::SETTINGS::SETTINGS()
 {
 }
 //-----------------------------------------------------------------------------
-int RS::SETTINGS::ParseSettings(const STG::ModuleSettings & s)
+int RS::SETTINGS::ParseSettings(const ModuleSettings & s)
 {
 int p;
-STG::ParamValue pv;
-std::vector<STG::ParamValue>::const_iterator pvi;
+ParamValue pv;
 netRouters.clear();
 ///////////////////////////
 pv.param = "Port";
-pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+auto pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 if (pvi == s.moduleParams.end() || pvi->value.empty())
     {
     errorStr = "Parameter \'Port\' not found.";
     printfd(__FILE__, "Parameter 'Port' not found\n");
     return -1;
     }
-if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
+if (ParseIntInRange(pvi->value[0], 2, 65535, &p) != 0)
     {
     errorStr = "Cannot parse parameter \'Port\': " + errorStr;
     printfd(__FILE__, "Cannot parse parameter 'Port'\n");
@@ -106,7 +93,7 @@ if (pvi == s.moduleParams.end() || pvi->value.empty())
     return -1;
     }
 
-if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
+if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod) != 0)
     {
     errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
     printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
@@ -146,13 +133,9 @@ subnetFile = pvi->value[0];
 NRMapParser nrMapParser;
 
 if (!nrMapParser.ReadFile(subnetFile))
-    {
     netRouters = nrMapParser.GetMap();
-    }
 else
-    {
-        STG::PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
-    }
+    PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
 
 return 0;
 }
@@ -163,15 +146,9 @@ REMOTE_SCRIPT::REMOTE_SCRIPT()
     : sendPeriod(15),
       halfPeriod(8),
       isRunning(false),
-      users(NULL),
+      users(nullptr),
       sock(0),
-      onAddUserNotifier(*this),
-      onDelUserNotifier(*this),
-      logger(STG::PluginLogger::get("rscript"))
-{
-}
-//-----------------------------------------------------------------------------
-REMOTE_SCRIPT::~REMOTE_SCRIPT()
+      logger(PluginLogger::get("rscript"))
 {
 }
 //-----------------------------------------------------------------------------
@@ -179,7 +156,7 @@ void REMOTE_SCRIPT::Run(std::stop_token token)
 {
 sigset_t signalSet;
 sigfillset(&signalSet);
-pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+pthread_sigmask(SIG_BLOCK, &signalSet, nullptr);
 
 isRunning = true;
 
@@ -194,8 +171,8 @@ isRunning = false;
 //-----------------------------------------------------------------------------
 int REMOTE_SCRIPT::ParseSettings()
 {
-int ret = rsSettings.ParseSettings(settings);
-if (ret)
+auto ret = rsSettings.ParseSettings(settings);
+if (ret != 0)
     errorStr = rsSettings.GetStrError();
 
 sendPeriod = rsSettings.GetSendPeriod();
@@ -210,23 +187,17 @@ netRouters = rsSettings.GetSubnetsMap();
 
 InitEncrypt(rsSettings.GetPassword());
 
-users->AddNotifierUserAdd(&onAddUserNotifier);
-users->AddNotifierUserDel(&onDelUserNotifier);
+m_onAddUserConn = users->onAdd([this](auto user){ AddUser(user); });
+m_onDelUserConn = users->onDel([this](auto user){ DelUser(user); });
 
 if (GetUsers())
-    {
     return -1;
-    }
 
 if (PrepareNet())
-    {
     return -1;
-    }
 
 if (!isRunning)
-    {
-    m_thread = std::jthread([this](auto token){ Run(token); });
-    }
+    m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
 
 errorStr = "";
 return 0;
@@ -240,10 +211,10 @@ if (!IsRunning())
 m_thread.request_stop();
 
 std::for_each(
-        authorizedUsers.begin(),
-        authorizedUsers.end(),
-        DisconnectUser(*this)
-        );
+    authorizedUsers.begin(),
+    authorizedUsers.end(),
+    [this](auto& kv){ Send(kv.second, true); }
+);
 
 FinalizeNet();
 
@@ -253,23 +224,22 @@ if (isRunning)
     for (int i = 0; i < 25 && isRunning; i++)
         {
         struct timespec ts = {0, 200000000};
-        nanosleep(&ts, NULL);
+        nanosleep(&ts, nullptr);
         }
     }
 
-users->DelNotifierUserDel(&onDelUserNotifier);
-users->DelNotifierUserAdd(&onAddUserNotifier);
-
 if (isRunning)
     {
     logger("Cannot stop thread.");
     m_thread.detach();
     }
+else
+    m_thread.join();
 
 return 0;
 }
 //-----------------------------------------------------------------------------
-int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
+int REMOTE_SCRIPT::Reload(const ModuleSettings & /*ms*/)
 {
 NRMapParser nrMapParser;
 
@@ -323,7 +293,7 @@ void REMOTE_SCRIPT::PeriodicSend()
 {
 std::lock_guard lock(m_mutex);
 
-std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
+auto it = authorizedUsers.begin();
 while (it != authorizedUsers.end())
     {
     if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
@@ -391,19 +361,16 @@ RS::PACKET_TAIL packetTail;
 
 memset(packetTail.padding, 0, sizeof(packetTail.padding));
 memcpy(packetTail.magic, RS_ID, sizeof(RS_ID));
-std::vector<std::string>::const_iterator it;
 std::string params;
-for(it = rsSettings.GetUserParams().begin();
-    it != rsSettings.GetUserParams().end();
-    ++it)
+for (const auto& param : rsSettings.GetUserParams())
     {
-    std::string parameter(rsu.user->GetParamValue(it->c_str()));
-    if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
+    auto value = rsu.user->GetParamValue(param);
+    if (params.length() + value.length() > RS_PARAMS_LEN - 1)
     {
-        logger("Script params string length %d exceeds the limit of %d symbols.", params.length() + parameter.length(), RS_PARAMS_LEN);
+        logger("Script params string length %d exceeds the limit of %d symbols.", params.length() + value.length(), RS_PARAMS_LEN);
         break;
     }
-    params += parameter + " ";
+    params += value + " ";
     }
 strncpy(reinterpret_cast<char*>(packetTail.params), params.c_str(), RS_PARAMS_LEN);
 packetTail.params[RS_PARAMS_LEN - 1] = 0;
@@ -435,7 +402,7 @@ for (const auto& ip : rsu.routers)
     sendAddr.sin_port = htons(rsSettings.GetPort());
     sendAddr.sin_addr.s_addr = ip;
 
-    return sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr*>(&sendAddr), sizeof(sendAddr));
+    return sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr*>(&sendAddr), sizeof(sendAddr)) > 0;
 }
 
 return false;
@@ -472,10 +439,8 @@ UserPtr u;
 int h = users->OpenSearch();
 assert(h && "USERS::OpenSearch is always correct");
 
-while (!users->SearchNext(h, &u))
-    {
+while (users->SearchNext(h, &u) != 0)
     SetUserNotifiers(u);
-    }
 
 users->CloseSearch(h);
 return false;
@@ -484,32 +449,26 @@ return false;
 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
 {
 std::lock_guard lock(m_mutex);
-for (size_t i = 0; i < netRouters.size(); ++i)
-    {
-    if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
-        {
-        return netRouters[i].routers;
-        }
-    }
-return std::vector<uint32_t>();
+for (auto& nr : netRouters)
+    if ((ip & nr.subnetMask) == (nr.subnetIP & nr.subnetMask))
+        return nr.routers;
+return {};
 }
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::SetUserNotifiers(UserPtr u)
 {
-ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
-connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
+    m_conns.emplace_back(
+        u->GetID(),
+        u->afterCurrIPChange([this, u](auto, auto newVal){ addDelUser(u, newVal != 0); }),
+        u->afterConnectedChange([this, u](auto, auto newVal){ addDelUser(u, newVal); })
+    );
 }
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::UnSetUserNotifiers(UserPtr u)
 {
-ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
-                                    ipNotifierList.end(),
-                                    USER_IS<IP_NOTIFIER>(u)),
-                     ipNotifierList.end());
-connNotifierList.erase(std::remove_if(connNotifierList.begin(),
-                                      connNotifierList.end(),
-                                      USER_IS<CONNECTED_NOTIFIER>(u)),
-                       connNotifierList.end());
+    m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+                  [u](const auto& c){ return std::get<0>(c) == u->GetID(); }),
+                  m_conns.end());
 
 }
 //-----------------------------------------------------------------------------
@@ -525,7 +484,7 @@ authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
 void REMOTE_SCRIPT::DelRSU(UserPtr user)
 {
 std::lock_guard lock(m_mutex);
-std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
+auto it = authorizedUsers.begin();
 while (it != authorizedUsers.end())
     {
     if (it->second.user == user)
@@ -536,9 +495,7 @@ while (it != authorizedUsers.end())
         }
     ++it;
     }
-/*const std::map<uint32_t, RS::USER>::iterator it(
-        authorizedUsers.find(user->GetCurrIP())
-        );
+/*const auto it = authorizedUsers.find(user->GetCurrIP());
 if (it != authorizedUsers.end())
     {
     Send(it->second, true);
@@ -546,20 +503,12 @@ if (it != authorizedUsers.end())
     }*/
 }
 //-----------------------------------------------------------------------------
-void RS::IP_NOTIFIER::Notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
-{
-if (newValue)
-    rs.AddRSU(user);
-else
-    rs.DelRSU(user);
-}
-//-----------------------------------------------------------------------------
-void RS::CONNECTED_NOTIFIER::Notify(const bool & /*oldValue*/, const bool & newValue)
+void REMOTE_SCRIPT::addDelUser(UserPtr user, bool toAdd)
 {
-if (newValue)
-    rs.AddRSU(user);
-else
-    rs.DelRSU(user);
+    if (toAdd)
+        AddRSU(user);
+    else
+        DelRSU(user);
 }
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::InitEncrypt(const std::string & password) const